@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.mjs CHANGED
@@ -308,10 +308,10 @@ function readInjected(value) {
308
308
  }
309
309
  function getDaemonBuildInfo() {
310
310
  if (cached) return cached;
311
- const commit = readInjected(true ? "38ede5a48ea8a2e21b5ea014880b9af37c6e3537" : void 0) ?? "unknown";
312
- const commitShort = readInjected(true ? "38ede5a4" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
313
- const version = readInjected(true ? "0.9.82-rc.328" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
314
- const builtAt = readInjected(true ? "2026-06-19T13:57:32.496Z" : void 0);
311
+ const commit = readInjected(true ? "9277ba79593a0feae0e17de0204856825a199ebe" : void 0) ?? "unknown";
312
+ const commitShort = readInjected(true ? "9277ba79" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
313
+ const version = readInjected(true ? "0.9.82-rc.329" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
314
+ const builtAt = readInjected(true ? "2026-06-19T15:56:44.269Z" : void 0);
315
315
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
316
316
  return cached;
317
317
  }
@@ -322,6 +322,247 @@ var init_build_info = __esm({
322
322
  }
323
323
  });
324
324
 
325
+ // src/git/change-impact-config.ts
326
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
327
+ import { join } from "path";
328
+ import * as yaml from "js-yaml";
329
+ function isRecord(value) {
330
+ return !!value && typeof value === "object" && !Array.isArray(value);
331
+ }
332
+ function isStringArray(value) {
333
+ return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
334
+ }
335
+ function validateTarget(value, key, errors) {
336
+ if (!isRecord(value)) {
337
+ errors.push(`impactTargets.${key} must be an object`);
338
+ return void 0;
339
+ }
340
+ const { recommendedCommand } = value;
341
+ if (typeof recommendedCommand !== "string" || !recommendedCommand.length) {
342
+ errors.push(`impactTargets.${key}.recommendedCommand must be a non-empty string`);
343
+ return void 0;
344
+ }
345
+ for (const k of Object.keys(value)) {
346
+ if (k !== "recommendedCommand") errors.push(`impactTargets.${key}.${k} is not a recognized field (only recommendedCommand)`);
347
+ }
348
+ return { recommendedCommand };
349
+ }
350
+ function validateChangeImpactConfig(raw, source = "inline") {
351
+ const errors = [];
352
+ if (!isRecord(raw)) {
353
+ return { valid: false, errors: [`${source}: config must be an object`] };
354
+ }
355
+ const config = {};
356
+ if (raw.daemonRuntimePackages !== void 0) {
357
+ if (isStringArray(raw.daemonRuntimePackages)) config.daemonRuntimePackages = [...raw.daemonRuntimePackages];
358
+ else errors.push("daemonRuntimePackages must be an array of non-empty strings");
359
+ }
360
+ if (raw.webOnlyPackages !== void 0) {
361
+ if (isStringArray(raw.webOnlyPackages)) config.webOnlyPackages = [...raw.webOnlyPackages];
362
+ else errors.push("webOnlyPackages must be an array of non-empty strings");
363
+ }
364
+ if (raw.nonRuntimeRootFilePatterns !== void 0) {
365
+ if (isStringArray(raw.nonRuntimeRootFilePatterns)) config.nonRuntimeRootFilePatterns = [...raw.nonRuntimeRootFilePatterns];
366
+ else errors.push("nonRuntimeRootFilePatterns must be an array of non-empty strings");
367
+ }
368
+ if (raw.impactTargets !== void 0) {
369
+ if (!isRecord(raw.impactTargets)) {
370
+ errors.push("impactTargets must be an object");
371
+ } else {
372
+ const targets = {};
373
+ for (const key of Object.keys(raw.impactTargets)) {
374
+ if (key !== "daemon" && key !== "web" && key !== "none") {
375
+ errors.push(`impactTargets.${key} is not a recognized impact kind (daemon|web|none)`);
376
+ continue;
377
+ }
378
+ const target = validateTarget(raw.impactTargets[key], key, errors);
379
+ if (target) targets[key] = target;
380
+ }
381
+ if (Object.keys(targets).length) config.impactTargets = targets;
382
+ }
383
+ }
384
+ for (const key of Object.keys(raw)) {
385
+ if (!["daemonRuntimePackages", "webOnlyPackages", "nonRuntimeRootFilePatterns", "impactTargets"].includes(key)) {
386
+ errors.push(`unknown config key '${key}'`);
387
+ }
388
+ }
389
+ return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
390
+ }
391
+ function parseConfigText(path42, text) {
392
+ if (/\.json$/i.test(path42)) return JSON.parse(text);
393
+ return yaml.load(text);
394
+ }
395
+ function loadChangeImpactConfig(repoRoot) {
396
+ for (const relative5 of CHANGE_IMPACT_CONFIG_LOCATIONS) {
397
+ const configPath = join(repoRoot, relative5);
398
+ if (!existsSync(configPath)) continue;
399
+ try {
400
+ const text = readFileSync(configPath, "utf-8");
401
+ let mtimeMs = 0;
402
+ try {
403
+ mtimeMs = statSync(configPath).mtimeMs;
404
+ } catch {
405
+ mtimeMs = text.length;
406
+ }
407
+ const parsed = parseConfigText(configPath, text);
408
+ const validation = validateChangeImpactConfig(parsed, relative5);
409
+ if (!validation.valid) {
410
+ return {
411
+ source: relative5,
412
+ sourceType: "invalid",
413
+ path: configPath,
414
+ error: validation.errors.join("; "),
415
+ sourceKey: `invalid:${configPath}:${mtimeMs}`
416
+ };
417
+ }
418
+ return {
419
+ config: validation.config,
420
+ source: relative5,
421
+ sourceType: "repo_file",
422
+ path: configPath,
423
+ sourceKey: `file:${configPath}:${mtimeMs}`
424
+ };
425
+ } catch (error) {
426
+ return {
427
+ source: relative5,
428
+ sourceType: "invalid",
429
+ path: configPath,
430
+ error: error?.message || String(error),
431
+ sourceKey: `error:${configPath}`
432
+ };
433
+ }
434
+ }
435
+ return {
436
+ source: "unavailable",
437
+ sourceType: "unavailable",
438
+ error: `No change-impact config found. Checked: ${CHANGE_IMPACT_CONFIG_LOCATIONS.join(", ")}`,
439
+ sourceKey: "unavailable"
440
+ };
441
+ }
442
+ function globToRegExp(pattern) {
443
+ let out = "";
444
+ for (let i = 0; i < pattern.length; i++) {
445
+ const ch = pattern[i];
446
+ if (ch === "*") {
447
+ if (pattern[i + 1] === "*") {
448
+ out += ".*";
449
+ i++;
450
+ if (pattern[i + 1] === "/") i++;
451
+ } else {
452
+ out += "[^/]*";
453
+ }
454
+ } else if (ch === "?") {
455
+ out += "[^/]";
456
+ } else if (".+^${}()|[]\\".includes(ch)) {
457
+ out += "\\" + ch;
458
+ } else {
459
+ out += ch;
460
+ }
461
+ }
462
+ return new RegExp(`^${out}$`);
463
+ }
464
+ function listPackageDirs(packagesRoot) {
465
+ try {
466
+ return readdirSync(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
467
+ } catch {
468
+ return [];
469
+ }
470
+ }
471
+ function suggestChangeImpactConfig(repoRoot) {
472
+ const notes = [];
473
+ const daemon = /* @__PURE__ */ new Set();
474
+ const web = /* @__PURE__ */ new Set();
475
+ const unclassified = [];
476
+ const roots = ["packages", join("oss", "packages")];
477
+ for (const rel of roots) {
478
+ const packagesRoot = join(repoRoot, rel);
479
+ if (!existsSync(packagesRoot)) continue;
480
+ for (const name of listPackageDirs(packagesRoot)) {
481
+ if (/(^web[-.]|[-.]web$)/i.test(name) || /dashboard|frontend|ui$/i.test(name)) {
482
+ web.add(name);
483
+ } else {
484
+ daemon.add(name);
485
+ }
486
+ }
487
+ }
488
+ const daemonRuntimePackages = [...daemon].sort();
489
+ const webOnlyPackages = [...web].sort();
490
+ if (!daemonRuntimePackages.length && !webOnlyPackages.length) {
491
+ notes.push("No packages/ or oss/packages/ directories found \u2014 defaulting to an empty draft you should fill in by hand.");
492
+ } else {
493
+ if (daemonRuntimePackages.length) notes.push(`Classified ${daemonRuntimePackages.length} package(s) as daemon-runtime (change \u2192 rebuild/redeploy + restart).`);
494
+ if (webOnlyPackages.length) notes.push(`Classified ${webOnlyPackages.length} web-* package(s) as web-only (change \u2192 web redeploy, no daemon restart).`);
495
+ notes.push("Heuristic only: confirm each package actually matches its bucket before saving.");
496
+ }
497
+ const nonRuntimeRootFilePatterns = [
498
+ "*.md",
499
+ "docs/**",
500
+ "LICENSE",
501
+ "LICENSE.*",
502
+ ".gitignore"
503
+ ];
504
+ notes.push("nonRuntimeRootFilePatterns lists root files that demonstrably cannot change daemon runtime behavior; extend with your repo markers.");
505
+ const suggestedConfig = {
506
+ ...daemonRuntimePackages.length ? { daemonRuntimePackages } : {},
507
+ ...webOnlyPackages.length ? { webOnlyPackages } : {},
508
+ nonRuntimeRootFilePatterns,
509
+ impactTargets: {
510
+ daemon: { recommendedCommand: "rebuild + redeploy the daemon, then restart it" },
511
+ web: { recommendedCommand: "redeploy the web app (no daemon restart required)" },
512
+ none: { recommendedCommand: "no action required" }
513
+ }
514
+ };
515
+ return {
516
+ suggestedConfig,
517
+ notes,
518
+ discoveredPackages: { daemon: daemonRuntimePackages, web: webOnlyPackages, unclassified }
519
+ };
520
+ }
521
+ var CHANGE_IMPACT_CONFIG_LOCATIONS, CHANGE_IMPACT_CONFIG_SCHEMA;
522
+ var init_change_impact_config = __esm({
523
+ "src/git/change-impact-config.ts"() {
524
+ "use strict";
525
+ CHANGE_IMPACT_CONFIG_LOCATIONS = [
526
+ ".adhdev/change-impact.json",
527
+ ".adhdev/change-impact.yaml",
528
+ ".adhdev/change-impact.yml",
529
+ ".adhdev/repo-mesh-change-impact.json",
530
+ ".adhdev/repo-mesh-change-impact.yaml",
531
+ ".adhdev/repo-mesh-change-impact.yml"
532
+ ];
533
+ CHANGE_IMPACT_CONFIG_SCHEMA = {
534
+ $schema: "https://json-schema.org/draft/2020-12/schema",
535
+ title: "ADHDev Change Impact Config",
536
+ type: "object",
537
+ additionalProperties: false,
538
+ properties: {
539
+ daemonRuntimePackages: { type: "array", items: { type: "string", minLength: 1 } },
540
+ webOnlyPackages: { type: "array", items: { type: "string", minLength: 1 } },
541
+ nonRuntimeRootFilePatterns: { type: "array", items: { type: "string", minLength: 1 } },
542
+ impactTargets: {
543
+ type: "object",
544
+ additionalProperties: false,
545
+ properties: {
546
+ daemon: { $ref: "#/$defs/target" },
547
+ web: { $ref: "#/$defs/target" },
548
+ none: { $ref: "#/$defs/target" }
549
+ }
550
+ }
551
+ },
552
+ $defs: {
553
+ target: {
554
+ type: "object",
555
+ additionalProperties: false,
556
+ required: ["recommendedCommand"],
557
+ properties: {
558
+ recommendedCommand: { type: "string", minLength: 1 }
559
+ }
560
+ }
561
+ }
562
+ };
563
+ }
564
+ });
565
+
325
566
  // src/git/git-status.ts
326
567
  function isTransientGitFailure(error) {
327
568
  return error.reason === "timeout" || error.reason === "git_command_failed";
@@ -397,16 +638,34 @@ async function collectGitRepoStatus(repo, includeSubmodules, lastCheckedAt, opti
397
638
  ...daemonBuildBehind ? { daemonBuildBehind } : {}
398
639
  };
399
640
  }
400
- function isNonRuntimeRootFile(file) {
641
+ function resolveChangeImpactPolicy(config) {
642
+ const daemonRuntimePackages = new Set(
643
+ config?.daemonRuntimePackages && config.daemonRuntimePackages.length ? config.daemonRuntimePackages : DEFAULT_DAEMON_RUNTIME_PACKAGES
644
+ );
645
+ const webOnlyPackages = new Set(
646
+ config?.webOnlyPackages && config.webOnlyPackages.length ? config.webOnlyPackages : DEFAULT_WEB_ONLY_PACKAGES
647
+ );
648
+ const nonRuntimeRootFilePatterns = (config?.nonRuntimeRootFilePatterns || []).map(globToRegExp);
649
+ const impactTargets = {
650
+ daemon: config?.impactTargets?.daemon ?? DEFAULT_IMPACT_TARGETS.daemon,
651
+ web: config?.impactTargets?.web ?? DEFAULT_IMPACT_TARGETS.web,
652
+ none: config?.impactTargets?.none ?? DEFAULT_IMPACT_TARGETS.none
653
+ };
654
+ return { daemonRuntimePackages, webOnlyPackages, nonRuntimeRootFilePatterns, impactTargets };
655
+ }
656
+ function isNonRuntimeRootFile(file, policy) {
401
657
  const base = file.slice(file.lastIndexOf("/") + 1);
402
658
  if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
403
659
  if (/(?:^|\/)docs\//i.test(file)) return true;
404
660
  if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
405
661
  return true;
406
662
  }
663
+ for (const re of policy.nonRuntimeRootFilePatterns) {
664
+ if (re.test(file)) return true;
665
+ }
407
666
  return false;
408
667
  }
409
- async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
668
+ async function classifyDaemonBuildChange(repoPath, buildCommit, options, policy) {
410
669
  try {
411
670
  const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
412
671
  const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
@@ -418,21 +677,47 @@ async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
418
677
  for (const file of files) {
419
678
  const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
420
679
  if (!match) {
421
- if (!isNonRuntimeRootFile(file)) sawRuntimeAmbiguousNonPackage = true;
680
+ if (!isNonRuntimeRootFile(file, policy)) sawRuntimeAmbiguousNonPackage = true;
422
681
  continue;
423
682
  }
424
683
  pkgs.add(match[1]);
425
684
  }
426
685
  const affectedPackages = [...pkgs].sort();
427
- const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
686
+ const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
428
687
  return { isDaemonAffecting: !allBenign, affectedPackages };
429
688
  } catch {
430
689
  return { isDaemonAffecting: true, affectedPackages: [] };
431
690
  }
432
691
  }
692
+ function resolveChangeImpactConfigForRepo(repoRoot, options) {
693
+ if (options.changeImpactConfig === null) {
694
+ return { config: null, sourceKey: "forced-default" };
695
+ }
696
+ if (options.changeImpactConfig !== void 0) {
697
+ let key = "injected";
698
+ try {
699
+ key = `injected:${JSON.stringify(options.changeImpactConfig)}`;
700
+ } catch {
701
+ }
702
+ return { config: options.changeImpactConfig, sourceKey: key };
703
+ }
704
+ if (!repoRoot) {
705
+ return { config: null, sourceKey: "no-repo-root" };
706
+ }
707
+ const loaded = loadChangeImpactConfig(repoRoot);
708
+ const cached2 = changeImpactConfigCache.get(repoRoot);
709
+ if (cached2 && cached2.sourceKey === loaded.sourceKey) {
710
+ return { config: cached2.config, sourceKey: loaded.sourceKey };
711
+ }
712
+ const config = loaded.sourceType === "repo_file" ? loaded.config ?? null : null;
713
+ changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config });
714
+ return { config, sourceKey: loaded.sourceKey };
715
+ }
433
716
  async function detectDaemonBuildBehind(repo, submodules, options) {
434
717
  const build = options.daemonBuildInfo ?? getDaemonBuildInfo();
435
718
  if (!build.commit || build.commit === "unknown") return void 0;
719
+ const { config, sourceKey: configKey } = resolveChangeImpactConfigForRepo(repo.repoRoot, options);
720
+ const policy = resolveChangeImpactPolicy(config);
436
721
  const scopes = [
437
722
  { scope: "root", repoPath: repo.repoRoot || repo.workspace }
438
723
  ];
@@ -446,11 +731,15 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
446
731
  const head = headResult.stdout.trim();
447
732
  if (!head || head === build.commit) continue;
448
733
  await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
449
- const { isDaemonAffecting, affectedPackages } = await classifyDaemonBuildChange(
450
- repoPath,
451
- build.commit,
452
- options
453
- );
734
+ const evalKey = `${repoPath}\0${build.commit}\0${head}\0${configKey}`;
735
+ let evaluated = changeImpactEvalCache.get(evalKey);
736
+ if (!evaluated) {
737
+ evaluated = await classifyDaemonBuildChange(repoPath, build.commit, options, policy);
738
+ changeImpactEvalCache.set(evalKey, evaluated);
739
+ }
740
+ const { isDaemonAffecting, affectedPackages } = evaluated;
741
+ const kind = isDaemonAffecting ? "daemon" : affectedPackages.length > 0 ? "web" : "none";
742
+ const target = policy.impactTargets[kind];
454
743
  const scopeLabel = scope === "root" ? "workspace" : scope;
455
744
  const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
456
745
  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.`;
@@ -461,6 +750,8 @@ async function detectDaemonBuildBehind(repo, submodules, options) {
461
750
  scope,
462
751
  isDaemonAffecting,
463
752
  ...affectedPackages && affectedPackages.length > 0 ? { affectedPackages } : {},
753
+ recommendedAction: kind,
754
+ recommendedCommand: target.recommendedCommand,
464
755
  warning
465
756
  };
466
757
  } catch {
@@ -724,14 +1015,17 @@ async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
724
1015
  submodule.error = formatGitError(error);
725
1016
  }
726
1017
  }
727
- var lastKnownGoodStatus, DAEMON_RUNTIME_PACKAGES, WEB_ONLY_PACKAGES;
1018
+ var lastKnownGoodStatus, changeImpactEvalCache, changeImpactConfigCache, DEFAULT_DAEMON_RUNTIME_PACKAGES, DEFAULT_WEB_ONLY_PACKAGES, DEFAULT_IMPACT_TARGETS;
728
1019
  var init_git_status = __esm({
729
1020
  "src/git/git-status.ts"() {
730
1021
  "use strict";
731
1022
  init_git_executor();
732
1023
  init_build_info();
1024
+ init_change_impact_config();
733
1025
  lastKnownGoodStatus = /* @__PURE__ */ new Map();
734
- DAEMON_RUNTIME_PACKAGES = /* @__PURE__ */ new Set([
1026
+ changeImpactEvalCache = /* @__PURE__ */ new Map();
1027
+ changeImpactConfigCache = /* @__PURE__ */ new Map();
1028
+ DEFAULT_DAEMON_RUNTIME_PACKAGES = [
735
1029
  "daemon-core",
736
1030
  "daemon-standalone",
737
1031
  "session-host-core",
@@ -741,13 +1035,24 @@ var init_git_status = __esm({
741
1035
  "terminal-mux-cli",
742
1036
  "ghostty-vt-node",
743
1037
  "mcp-server"
744
- ]);
745
- WEB_ONLY_PACKAGES = /* @__PURE__ */ new Set([
1038
+ ];
1039
+ DEFAULT_WEB_ONLY_PACKAGES = [
746
1040
  "web-core",
747
1041
  "web-standalone",
748
1042
  "web-devconsole",
749
1043
  "terminal-render-web"
750
- ]);
1044
+ ];
1045
+ DEFAULT_IMPACT_TARGETS = {
1046
+ daemon: {
1047
+ recommendedCommand: "Redeploy + restart the daemon (a local dist rebuild alone does not update a cloud daemon)."
1048
+ },
1049
+ web: {
1050
+ recommendedCommand: "Redeploy the web app (no daemon restart required)."
1051
+ },
1052
+ none: {
1053
+ recommendedCommand: "No action required."
1054
+ }
1055
+ };
751
1056
  }
752
1057
  });
753
1058
 
@@ -1035,7 +1340,7 @@ __export(git_worktree_exports, {
1035
1340
  });
1036
1341
  import * as path4 from "path";
1037
1342
  import { mkdir } from "fs/promises";
1038
- import { existsSync } from "fs";
1343
+ import { existsSync as existsSync2 } from "fs";
1039
1344
  import { execFile as execFile2 } from "child_process";
1040
1345
  import { promisify as promisify2 } from "util";
1041
1346
  function resolveWorktreePath(repoRoot, meshName, branch) {
@@ -1047,7 +1352,7 @@ function resolveWorktreePath(repoRoot, meshName, branch) {
1047
1352
  async function createWorktree(opts) {
1048
1353
  const { repoRoot, branch, baseBranch, meshName } = opts;
1049
1354
  const targetDir = opts.targetDir || resolveWorktreePath(repoRoot, meshName, branch);
1050
- if (existsSync(targetDir)) {
1355
+ if (existsSync2(targetDir)) {
1051
1356
  throw new Error(`Worktree target directory already exists: ${targetDir}`);
1052
1357
  }
1053
1358
  await mkdir(path4.dirname(targetDir), { recursive: true });
@@ -1066,7 +1371,7 @@ async function createWorktree(opts) {
1066
1371
  } catch (error) {
1067
1372
  const stderr = typeof error.stderr === "string" ? error.stderr : "";
1068
1373
  if (/already exists/i.test(stderr)) {
1069
- if (existsSync(targetDir)) {
1374
+ if (existsSync2(targetDir)) {
1070
1375
  throw new Error(`Worktree target directory was created concurrently: ${targetDir}`);
1071
1376
  }
1072
1377
  throw new Error(`Branch '${branch}' already exists or is checked out in another worktree`);
@@ -1080,7 +1385,7 @@ async function createWorktree(opts) {
1080
1385
  };
1081
1386
  }
1082
1387
  async function removeWorktree(repoRoot, worktreePath, opts = {}) {
1083
- if (!existsSync(worktreePath)) {
1388
+ if (!existsSync2(worktreePath)) {
1084
1389
  await pruneWorktrees(repoRoot);
1085
1390
  return { success: true, removedPath: worktreePath };
1086
1391
  }
@@ -1214,8 +1519,8 @@ __export(config_exports, {
1214
1519
  updateConfig: () => updateConfig
1215
1520
  });
1216
1521
  import { homedir } from "os";
1217
- import { join as join2 } from "path";
1218
- import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync, chmodSync } from "fs";
1522
+ import { join as join3 } from "path";
1523
+ import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync2, writeFileSync, chmodSync } from "fs";
1219
1524
  import { randomUUID } from "crypto";
1220
1525
  function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
1221
1526
  if (providerSourceMode === "normal" || providerSourceMode === "no-upstream") {
@@ -1310,25 +1615,25 @@ function ensureMachineId(config) {
1310
1615
  }
1311
1616
  function getConfigDir() {
1312
1617
  const override = process.env.ADHDEV_CONFIG_DIR;
1313
- const dir = override && override.trim() ? override.trim() : join2(homedir(), ".adhdev");
1314
- if (!existsSync2(dir)) {
1618
+ const dir = override && override.trim() ? override.trim() : join3(homedir(), ".adhdev");
1619
+ if (!existsSync3(dir)) {
1315
1620
  mkdirSync(dir, { recursive: true });
1316
1621
  }
1317
1622
  return dir;
1318
1623
  }
1319
1624
  function getDaemonDataDir() {
1320
- const dir = join2(getConfigDir(), "daemon");
1321
- if (!existsSync2(dir)) {
1625
+ const dir = join3(getConfigDir(), "daemon");
1626
+ if (!existsSync3(dir)) {
1322
1627
  mkdirSync(dir, { recursive: true });
1323
1628
  }
1324
1629
  return dir;
1325
1630
  }
1326
1631
  function getConfigPath() {
1327
- return join2(getConfigDir(), "config.json");
1632
+ return join3(getConfigDir(), "config.json");
1328
1633
  }
1329
1634
  function migrateStateToStateFile(raw) {
1330
- const statePath = join2(getConfigDir(), "state.json");
1331
- if (existsSync2(statePath)) return;
1635
+ const statePath = join3(getConfigDir(), "state.json");
1636
+ if (existsSync3(statePath)) return;
1332
1637
  const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1333
1638
  const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
1334
1639
  const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
@@ -1352,7 +1657,7 @@ function migrateStateToStateFile(raw) {
1352
1657
  }
1353
1658
  function loadConfig() {
1354
1659
  const configPath = getConfigPath();
1355
- if (!existsSync2(configPath)) {
1660
+ if (!existsSync3(configPath)) {
1356
1661
  const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1357
1662
  try {
1358
1663
  saveConfig(initialized.config);
@@ -1361,7 +1666,7 @@ function loadConfig() {
1361
1666
  return initialized.config;
1362
1667
  }
1363
1668
  try {
1364
- const raw = readFileSync(configPath, "utf-8");
1669
+ const raw = readFileSync2(configPath, "utf-8");
1365
1670
  const parsed = JSON.parse(raw);
1366
1671
  migrateStateToStateFile(parsed);
1367
1672
  const normalizedInput = normalizeConfig(parsed);
@@ -1383,7 +1688,7 @@ function saveConfig(config) {
1383
1688
  const configPath = getConfigPath();
1384
1689
  const dir = getConfigDir();
1385
1690
  const normalized = normalizeConfig(config);
1386
- if (!existsSync2(dir)) {
1691
+ if (!existsSync3(dir)) {
1387
1692
  mkdirSync(dir, { recursive: true, mode: 448 });
1388
1693
  }
1389
1694
  writeFileSync(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
@@ -1535,17 +1840,17 @@ __export(mesh_config_exports, {
1535
1840
  updateMesh: () => updateMesh,
1536
1841
  updateNode: () => updateNode
1537
1842
  });
1538
- import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
1539
- import { join as join4 } from "path";
1843
+ import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
1844
+ import { join as join5 } from "path";
1540
1845
  import { createHash, randomBytes, randomUUID as randomUUID3 } from "crypto";
1541
1846
  function getMeshConfigPath() {
1542
- return join4(getConfigDir(), "meshes.json");
1847
+ return join5(getConfigDir(), "meshes.json");
1543
1848
  }
1544
1849
  function loadMeshConfig() {
1545
1850
  const path42 = getMeshConfigPath();
1546
- if (!existsSync4(path42)) return { meshes: [] };
1851
+ if (!existsSync5(path42)) return { meshes: [] };
1547
1852
  try {
1548
- const raw = JSON.parse(readFileSync2(path42, "utf-8"));
1853
+ const raw = JSON.parse(readFileSync3(path42, "utf-8"));
1549
1854
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
1550
1855
  const config = raw;
1551
1856
  const migrated = migrateLoadedMeshConfig(config);
@@ -2248,8 +2553,8 @@ __export(mesh_ledger_exports, {
2248
2553
  readLedgerSlice: () => readLedgerSlice,
2249
2554
  readLedgerSliceFromStore: () => readLedgerSliceFromStore
2250
2555
  });
2251
- import { appendFileSync, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync4, statSync as statSync2, renameSync, writeFileSync as writeFileSync3 } from "fs";
2252
- import { join as join6 } from "path";
2556
+ import { appendFileSync, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync5, statSync as statSync3, renameSync, writeFileSync as writeFileSync3 } from "fs";
2557
+ import { join as join7 } from "path";
2253
2558
  import { randomUUID as randomUUID4 } from "crypto";
2254
2559
  import { EventEmitter } from "events";
2255
2560
  function isIntentionalCleanupStopEntry(entry) {
@@ -2258,35 +2563,35 @@ function isIntentionalCleanupStopEntry(entry) {
2258
2563
  return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
2259
2564
  }
2260
2565
  function getLedgerDir() {
2261
- const dir = join6(getConfigDir(), LEDGER_DIR_NAME);
2262
- if (!existsSync5(dir)) {
2566
+ const dir = join7(getConfigDir(), LEDGER_DIR_NAME);
2567
+ if (!existsSync6(dir)) {
2263
2568
  mkdirSync3(dir, { recursive: true, mode: 448 });
2264
2569
  }
2265
2570
  return dir;
2266
2571
  }
2267
2572
  function getLedgerPath(meshId) {
2268
2573
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2269
- return join6(getLedgerDir(), `${safe}.jsonl`);
2574
+ return join7(getLedgerDir(), `${safe}.jsonl`);
2270
2575
  }
2271
2576
  function getRotatedPath(meshId, index) {
2272
2577
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2273
- return join6(getLedgerDir(), `${safe}.${index}.jsonl`);
2578
+ return join7(getLedgerDir(), `${safe}.${index}.jsonl`);
2274
2579
  }
2275
2580
  function getArchivePath(meshId) {
2276
2581
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2277
- return join6(getLedgerDir(), `${safe}.archive.jsonl`);
2582
+ return join7(getLedgerDir(), `${safe}.archive.jsonl`);
2278
2583
  }
2279
2584
  function getRotatedArchivePath(meshId, index) {
2280
2585
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2281
- return join6(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
2586
+ return join7(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
2282
2587
  }
2283
2588
  function getArchivedCountsPath(meshId) {
2284
2589
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2285
- return join6(getLedgerDir(), `${safe}.archived-counts.json`);
2590
+ return join7(getLedgerDir(), `${safe}.archived-counts.json`);
2286
2591
  }
2287
2592
  function rotateArchiveFile(meshId, archivePath) {
2288
2593
  let index = 1;
2289
- while (existsSync5(getRotatedArchivePath(meshId, index))) {
2594
+ while (existsSync6(getRotatedArchivePath(meshId, index))) {
2290
2595
  index++;
2291
2596
  if (index > 5) break;
2292
2597
  }
@@ -2300,9 +2605,9 @@ function rotateArchiveFile(meshId, archivePath) {
2300
2605
  }
2301
2606
  function readArchivedCounts(meshId) {
2302
2607
  const path42 = getArchivedCountsPath(meshId);
2303
- if (!existsSync5(path42)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2608
+ if (!existsSync6(path42)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2304
2609
  try {
2305
- return JSON.parse(readFileSync4(path42, "utf-8"));
2610
+ return JSON.parse(readFileSync5(path42, "utf-8"));
2306
2611
  } catch {
2307
2612
  return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
2308
2613
  }
@@ -2341,7 +2646,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
2341
2646
  }
2342
2647
  function compactLedger(meshId) {
2343
2648
  const filePath = getLedgerPath(meshId);
2344
- if (!existsSync5(filePath)) return { archivedCount: 0, retainedCount: 0 };
2649
+ if (!existsSync6(filePath)) return { archivedCount: 0, retainedCount: 0 };
2345
2650
  const cutoff = Date.now() - ARCHIVE_TERMINAL_OLDER_THAN_MS;
2346
2651
  const entries = readLedgerEntries(meshId);
2347
2652
  const keep = [];
@@ -2356,7 +2661,7 @@ function compactLedger(meshId) {
2356
2661
  if (archive.length === 0) return { archivedCount: 0, retainedCount: keep.length };
2357
2662
  const archivePath = getArchivePath(meshId);
2358
2663
  try {
2359
- if (existsSync5(archivePath) && statSync2(archivePath).size > 50 * 1024 * 1024) {
2664
+ if (existsSync6(archivePath) && statSync3(archivePath).size > 50 * 1024 * 1024) {
2360
2665
  rotateArchiveFile(meshId, archivePath);
2361
2666
  }
2362
2667
  const archiveLines = archive.map((e) => JSON.stringify(e)).join("\n") + "\n";
@@ -2506,9 +2811,9 @@ function appendLedgerEntry(meshId, partial) {
2506
2811
  ...partial
2507
2812
  };
2508
2813
  const filePath = getLedgerPath(meshId);
2509
- if (existsSync5(filePath)) {
2814
+ if (existsSync6(filePath)) {
2510
2815
  try {
2511
- const stat2 = statSync2(filePath);
2816
+ const stat2 = statSync3(filePath);
2512
2817
  if (stat2.size >= MAX_FILE_SIZE_BYTES) {
2513
2818
  rotateLedgerFile(meshId, filePath);
2514
2819
  } else if (stat2.size >= COMPACT_THRESHOLD_BYTES) {
@@ -2604,10 +2909,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
2604
2909
  }
2605
2910
  function readLedgerFile(meshId) {
2606
2911
  const filePath = getLedgerPath(meshId);
2607
- if (!existsSync5(filePath)) return [];
2912
+ if (!existsSync6(filePath)) return [];
2608
2913
  let content;
2609
2914
  try {
2610
- content = readFileSync4(filePath, "utf-8");
2915
+ content = readFileSync5(filePath, "utf-8");
2611
2916
  } catch {
2612
2917
  return [];
2613
2918
  }
@@ -2868,7 +3173,7 @@ function getSessionRecoveryContext(meshId, opts) {
2868
3173
  }
2869
3174
  function rotateLedgerFile(meshId, currentPath) {
2870
3175
  let index = 1;
2871
- while (existsSync5(getRotatedPath(meshId, index))) {
3176
+ while (existsSync6(getRotatedPath(meshId, index))) {
2872
3177
  index++;
2873
3178
  if (index > 10) break;
2874
3179
  }
@@ -3539,8 +3844,8 @@ var init_mesh_work_queue = __esm({
3539
3844
  });
3540
3845
 
3541
3846
  // src/mesh/mesh-runtime-store.ts
3542
- import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync5, renameSync as renameSync2, statSync as statSync3 } from "fs";
3543
- import { dirname as dirname2, join as join7 } from "path";
3847
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, statSync as statSync4 } from "fs";
3848
+ import { dirname as dirname2, join as join8 } from "path";
3544
3849
  import { createRequire } from "module";
3545
3850
  function loadDatabaseCtor() {
3546
3851
  if (DatabaseCtor) return DatabaseCtor;
@@ -3552,19 +3857,19 @@ function safeMeshId(meshId) {
3552
3857
  return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
3553
3858
  }
3554
3859
  function legacyQueuePath(meshId) {
3555
- return join7(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
3860
+ return join8(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
3556
3861
  }
3557
3862
  function meshRuntimeStorePath() {
3558
3863
  const dir = getLedgerDir();
3559
- const nextPath = join7(dir, "mesh-runtime.db");
3560
- if (existsSync6(nextPath)) return nextPath;
3561
- const legacyPath = join7(dir, "beads.db");
3562
- if (!existsSync6(legacyPath)) return nextPath;
3864
+ const nextPath = join8(dir, "mesh-runtime.db");
3865
+ if (existsSync7(nextPath)) return nextPath;
3866
+ const legacyPath = join8(dir, "beads.db");
3867
+ if (!existsSync7(legacyPath)) return nextPath;
3563
3868
  try {
3564
3869
  renameSync2(legacyPath, nextPath);
3565
3870
  for (const suffix of ["-wal", "-shm"]) {
3566
3871
  const legacyCompanion = `${legacyPath}${suffix}`;
3567
- if (existsSync6(legacyCompanion)) {
3872
+ if (existsSync7(legacyCompanion)) {
3568
3873
  renameSync2(legacyCompanion, `${nextPath}${suffix}`);
3569
3874
  }
3570
3875
  }
@@ -3590,7 +3895,7 @@ var init_mesh_runtime_store = __esm({
3590
3895
  // 50 MB
3591
3896
  constructor(dbPath) {
3592
3897
  const dir = dirname2(dbPath);
3593
- if (!existsSync6(dir)) mkdirSync4(dir, { recursive: true });
3898
+ if (!existsSync7(dir)) mkdirSync4(dir, { recursive: true });
3594
3899
  this.dbPath = dbPath;
3595
3900
  this.db = new (loadDatabaseCtor())(dbPath);
3596
3901
  this.db.pragma("journal_mode = WAL");
@@ -3845,8 +4150,8 @@ var init_mesh_runtime_store = __esm({
3845
4150
  this.walWriteCounter = 0;
3846
4151
  try {
3847
4152
  const walPath = `${this.dbPath}-wal`;
3848
- if (!existsSync6(walPath)) return;
3849
- const size = statSync3(walPath).size;
4153
+ if (!existsSync7(walPath)) return;
4154
+ const size = statSync4(walPath).size;
3850
4155
  if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
3851
4156
  process.stderr.write(
3852
4157
  `[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
@@ -3862,9 +4167,9 @@ var init_mesh_runtime_store = __esm({
3862
4167
  const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
3863
4168
  if (count.count > 0) return;
3864
4169
  const path42 = legacyQueuePath(meshId);
3865
- if (!existsSync6(path42)) return;
4170
+ if (!existsSync7(path42)) return;
3866
4171
  try {
3867
- const entries = JSON.parse(readFileSync5(path42, "utf-8"));
4172
+ const entries = JSON.parse(readFileSync6(path42, "utf-8"));
3868
4173
  if (!Array.isArray(entries)) return;
3869
4174
  const insert = this.db.prepare(`
3870
4175
  INSERT OR REPLACE INTO mesh_queue (
@@ -5705,10 +6010,10 @@ __export(mesh_coordinator_exports, {
5705
6010
  stripCoordinatorWrapperFile: () => stripCoordinatorWrapperFile
5706
6011
  });
5707
6012
  import { createHash as createHash2 } from "crypto";
5708
- import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
6013
+ import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
5709
6014
  import * as os4 from "os";
5710
6015
  import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
5711
- import { basename as basename2, isAbsolute as isAbsolute4, join as join9, resolve as resolve7 } from "path";
6016
+ import { basename as basename2, isAbsolute as isAbsolute4, join as join10, resolve as resolve7 } from "path";
5712
6017
  function isHermesProvider(provider, cliType) {
5713
6018
  const type = cliType?.trim() || provider?.type?.trim() || "";
5714
6019
  return type === HERMES_CLI_TYPE;
@@ -5728,7 +6033,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
5728
6033
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
5729
6034
  };
5730
6035
  }
5731
- const configPath = join9(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
6036
+ const configPath = join10(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
5732
6037
  if (!configPath.trim()) {
5733
6038
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
5734
6039
  }
@@ -5875,14 +6180,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
5875
6180
  const key = `${meshId || "mesh"}
5876
6181
  ${resolve7(workspace || os4.tmpdir())}`;
5877
6182
  const hash = createHash2("sha256").update(key).digest("hex").slice(0, 16);
5878
- return join9(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
6183
+ return join10(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
5879
6184
  }
5880
6185
  function resolveMcpConfigPath(configPath, workspace) {
5881
6186
  const trimmed = configPath.trim();
5882
6187
  if (trimmed === "~") return os4.homedir();
5883
- if (trimmed.startsWith("~/")) return join9(os4.homedir(), trimmed.slice(2));
6188
+ if (trimmed.startsWith("~/")) return join10(os4.homedir(), trimmed.slice(2));
5884
6189
  if (isAbsolute4(trimmed)) return trimmed;
5885
- return join9(workspace, trimmed);
6190
+ return join10(workspace, trimmed);
5886
6191
  }
5887
6192
  function resolveAdhdevMcpServerLaunch(options) {
5888
6193
  const directEntryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
@@ -5953,7 +6258,7 @@ function applyInjectionRule(systemPrompt, injection, ctx) {
5953
6258
  }
5954
6259
  case "context_file": {
5955
6260
  if (!injection.path) return {};
5956
- const target = isAbsolute4(injection.path) ? injection.path : join9(ctx.workspace, injection.path);
6261
+ const target = isAbsolute4(injection.path) ? injection.path : join10(ctx.workspace, injection.path);
5957
6262
  const wrapper = injection.wrapper && injection.wrapper.includes("{prompt}") ? injection.wrapper : "{prompt}";
5958
6263
  const managedNote = "> _Managed by adhdev mesh coordinator \u2014 do not hand-edit this block. Changes inside the sentinels are overwritten on next coordinator launch._";
5959
6264
  const promptWithNote = `${managedNote}
@@ -5962,8 +6267,8 @@ ${systemPrompt}`;
5962
6267
  const rendered = wrapper.replace(/\{prompt\}/g, promptWithNote);
5963
6268
  const sentinel = wrapper.split("{prompt}")[0].trim();
5964
6269
  try {
5965
- if (existsSync8(target)) {
5966
- const existing = readFileSync6(target, "utf-8");
6270
+ if (existsSync9(target)) {
6271
+ const existing = readFileSync7(target, "utf-8");
5967
6272
  if (sentinel && existing.includes(sentinel)) {
5968
6273
  const closing = wrapper.split("{prompt}")[1]?.trim();
5969
6274
  const safeOpen = sentinel.replace(/[.+^${}()|[\]\\]/g, "\\$&");
@@ -5993,8 +6298,8 @@ function stripCoordinatorWrapperFile(filePath) {
5993
6298
  const OPEN = "<!-- adhdev-mesh-coordinator-prompt -->";
5994
6299
  const CLOSE = "<!-- /adhdev-mesh-coordinator-prompt -->";
5995
6300
  try {
5996
- if (!existsSync8(filePath)) return;
5997
- const existing = readFileSync6(filePath, "utf-8");
6301
+ if (!existsSync9(filePath)) return;
6302
+ const existing = readFileSync7(filePath, "utf-8");
5998
6303
  const openIdx = existing.indexOf(OPEN);
5999
6304
  if (openIdx < 0) return;
6000
6305
  const closeIdx = existing.indexOf(CLOSE, openIdx);
@@ -7428,8 +7733,8 @@ function formatCompletionMetadata(event) {
7428
7733
  function buildMeshSystemMessage(args) {
7429
7734
  const metadata = formatCompletionMetadata(args.metadataEvent);
7430
7735
  if (args.event === "agent:generating_completed") {
7431
- if (args.metadataEvent.source === "long_generating_reconciliation") {
7432
- 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.`;
7736
+ if (args.metadataEvent.source === "no_progress_reconciliation") {
7737
+ 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.`;
7433
7738
  }
7434
7739
  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.";
7435
7740
  return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. This completion came from the agent status event path;${reviewNote}`;
@@ -7468,7 +7773,7 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
7468
7773
  }
7469
7774
  return `[System] ${args.nodeLabel} has stopped${metadata}. Use mesh_read_chat once if you need to inspect its last output.`;
7470
7775
  }
7471
- if (args.event === "monitor:long_generating") {
7776
+ if (args.event === "monitor:no_progress") {
7472
7777
  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.`;
7473
7778
  }
7474
7779
  if (args.event === "worktree_bootstrap_complete") {
@@ -7546,8 +7851,8 @@ var init_mesh_events_utils = __esm({
7546
7851
  });
7547
7852
 
7548
7853
  // src/mesh/mesh-events-pending.ts
7549
- import { appendFileSync as appendFileSync2, existsSync as existsSync12, readFileSync as readFileSync10, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
7550
- import { join as join13 } from "path";
7854
+ import { appendFileSync as appendFileSync2, existsSync as existsSync13, readFileSync as readFileSync11, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
7855
+ import { join as join14 } from "path";
7551
7856
  import { randomUUID as randomUUID7 } from "crypto";
7552
7857
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
7553
7858
  const raw = Array.isArray(coordinatorDaemonId) ? coordinatorDaemonId : coordinatorDaemonId != null ? [coordinatorDaemonId] : [];
@@ -7610,9 +7915,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
7610
7915
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
7611
7916
  if (coordinatorDaemonId) {
7612
7917
  const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
7613
- return join13(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
7918
+ return join14(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
7614
7919
  }
7615
- return join13(getLedgerDir(), `${safe}.pending-events.jsonl`);
7920
+ return join14(getLedgerDir(), `${safe}.pending-events.jsonl`);
7616
7921
  }
7617
7922
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7618
7923
  if (!meshId) return [];
@@ -7621,9 +7926,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
7621
7926
  const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
7622
7927
  const events = [];
7623
7928
  for (const path42 of paths) {
7624
- if (!existsSync12(path42)) continue;
7929
+ if (!existsSync13(path42)) continue;
7625
7930
  try {
7626
- const raw = readFileSync10(path42, "utf-8");
7931
+ const raw = readFileSync11(path42, "utf-8");
7627
7932
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
7628
7933
  try {
7629
7934
  return [JSON.parse(line)];
@@ -7698,9 +8003,9 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
7698
8003
  }
7699
8004
  function trimPendingEventsIfNeeded(path42) {
7700
8005
  try {
7701
- if (!existsSync12(path42)) return;
7702
- if (statSync5(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
7703
- const lines = readFileSync10(path42, "utf-8").split("\n").filter(Boolean);
8006
+ if (!existsSync13(path42)) return;
8007
+ if (statSync6(path42).size <= MAX_PENDING_EVENTS_BYTES) return;
8008
+ const lines = readFileSync11(path42, "utf-8").split("\n").filter(Boolean);
7704
8009
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
7705
8010
  writeFileSync6(path42, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
7706
8011
  } catch {
@@ -7746,7 +8051,7 @@ function atomicDrainFile(path42) {
7746
8051
  return null;
7747
8052
  }
7748
8053
  try {
7749
- const content = readFileSync10(tmpPath, "utf-8");
8054
+ const content = readFileSync11(tmpPath, "utf-8");
7750
8055
  try {
7751
8056
  unlinkSync2(tmpPath);
7752
8057
  } catch {
@@ -7769,7 +8074,7 @@ function selectiveDrainFile(path42, predicate) {
7769
8074
  }
7770
8075
  let content;
7771
8076
  try {
7772
- content = readFileSync10(tmpPath, "utf-8");
8077
+ content = readFileSync11(tmpPath, "utf-8");
7773
8078
  } catch {
7774
8079
  try {
7775
8080
  unlinkSync2(tmpPath);
@@ -7800,7 +8105,7 @@ function selectiveDrainFile(path42, predicate) {
7800
8105
  unlinkSync2(tmpPath);
7801
8106
  } catch {
7802
8107
  try {
7803
- if (existsSync12(tmpPath) && !existsSync12(path42)) renameSync4(tmpPath, path42);
8108
+ if (existsSync13(tmpPath) && !existsSync13(path42)) renameSync4(tmpPath, path42);
7804
8109
  } catch {
7805
8110
  }
7806
8111
  return [];
@@ -7894,7 +8199,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
7894
8199
  }
7895
8200
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
7896
8201
  for (const path42 of paths) {
7897
- if (existsSync12(path42)) try {
8202
+ if (existsSync13(path42)) try {
7898
8203
  unlinkSync2(path42);
7899
8204
  } catch {
7900
8205
  }
@@ -8258,7 +8563,7 @@ function reconcileDirectDispatchCompletionFromTranscript(args) {
8258
8563
  });
8259
8564
  return { reconciled: true, kind, workerResult, ledgerEntryId: entry.id };
8260
8565
  }
8261
- function buildLongGeneratingCompletionReconciliation(args) {
8566
+ function buildNoProgressCompletionReconciliation(args) {
8262
8567
  const sessionId = resolveEventSessionId(args.metadataEvent, args.sourceInstanceId);
8263
8568
  const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
8264
8569
  const providerType = readNonEmptyString2(args.metadataEvent.providerType);
@@ -8277,8 +8582,8 @@ function buildLongGeneratingCompletionReconciliation(args) {
8277
8582
  providerType,
8278
8583
  providerSessionId,
8279
8584
  finalSummary,
8280
- source: "long_generating_reconciliation",
8281
- reconciledFromEvent: "monitor:long_generating",
8585
+ source: "no_progress_reconciliation",
8586
+ reconciledFromEvent: "monitor:no_progress",
8282
8587
  timestamp: args.metadataEvent.timestamp ?? Date.now(),
8283
8588
  completionDiagnostic: {
8284
8589
  ...completionDiagnostic || {},
@@ -8294,7 +8599,7 @@ function buildLongGeneratingCompletionReconciliation(args) {
8294
8599
  if (!terminal) return null;
8295
8600
  return {
8296
8601
  ...args.metadataEvent,
8297
- source: "long_generating_terminal_ledger_suppression",
8602
+ source: "no_progress_terminal_ledger_suppression",
8298
8603
  terminalLedgerKind: terminal.kind,
8299
8604
  terminalLedgerAt: terminal.timestamp
8300
8605
  };
@@ -8717,7 +9022,7 @@ var init_provider_cli_shared = __esm({
8717
9022
  import { exec } from "child_process";
8718
9023
  import * as os6 from "os";
8719
9024
  import * as path11 from "path";
8720
- import { existsSync as existsSync13 } from "fs";
9025
+ import { existsSync as existsSync14 } from "fs";
8721
9026
  function parseVersion(raw) {
8722
9027
  const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
8723
9028
  return match ? match[1] : raw.split("\n")[0].slice(0, 100);
@@ -8741,7 +9046,7 @@ function resolveCommandPath(command) {
8741
9046
  if (isExplicitCommandPath(trimmed)) {
8742
9047
  const expanded = expandHome(trimmed);
8743
9048
  const candidate = path11.isAbsolute(expanded) ? expanded : path11.resolve(expanded);
8744
- return existsSync13(candidate) ? candidate : null;
9049
+ return existsSync14(candidate) ? candidate : null;
8745
9050
  }
8746
9051
  return null;
8747
9052
  }
@@ -8751,7 +9056,7 @@ async function resolveDetectionPath(command, whichCmd) {
8751
9056
  const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
8752
9057
  if (whichResult) return whichResult.split("\n")[0];
8753
9058
  const resolved = findBinary(command);
8754
- if (path11.isAbsolute(resolved) && existsSync13(resolved)) return resolved;
9059
+ if (path11.isAbsolute(resolved) && existsSync14(resolved)) return resolved;
8755
9060
  return null;
8756
9061
  }
8757
9062
  function execAsync(cmd, timeoutMs = 5e3) {
@@ -9096,7 +9401,7 @@ var init_mesh_unresolved_forward_outbox = __esm({
9096
9401
  });
9097
9402
 
9098
9403
  // src/mesh/mesh-events-coordinator.ts
9099
- import { existsSync as existsSync14 } from "fs";
9404
+ import { existsSync as existsSync15 } from "fs";
9100
9405
  function resolveCoordinatorDrainDaemonIds(components) {
9101
9406
  const ids = /* @__PURE__ */ new Set();
9102
9407
  const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
@@ -9148,7 +9453,7 @@ function hasRecentIntentionalCleanupStop(meshId, sessionId, nodeId) {
9148
9453
  return false;
9149
9454
  }
9150
9455
  function shouldSuppressIntentionalCleanupStop(args) {
9151
- if (args.event !== "agent:stopped" && args.event !== "monitor:long_generating") return false;
9456
+ if (args.event !== "agent:stopped" && args.event !== "monitor:no_progress") return false;
9152
9457
  if (isIntentionalCleanupStopMetadata(args.metadataEvent)) return true;
9153
9458
  return hasRecentIntentionalCleanupStop(args.meshId, args.sessionId, args.nodeId);
9154
9459
  }
@@ -9364,7 +9669,7 @@ function resolveAutoFastForwardPolicy(mesh) {
9364
9669
  function sessionStateLooksActive(state) {
9365
9670
  const status = readNonEmptyString2(state?.status).toLowerCase();
9366
9671
  const chatStatus = readNonEmptyString2(state?.activeChat?.status).toLowerCase();
9367
- const active = /* @__PURE__ */ new Set(["generating", "streaming", "long_generating", "working", "starting", "waiting_approval"]);
9672
+ const active = /* @__PURE__ */ new Set(["generating", "streaming", "no_progress", "long_generating", "working", "starting", "waiting_approval"]);
9368
9673
  return active.has(status) || active.has(chatStatus);
9369
9674
  }
9370
9675
  function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
@@ -9884,7 +10189,7 @@ async function maybeAutoFastForwardIdleNode(components, args) {
9884
10189
  const node = mesh?.nodes?.find((candidate) => meshNodeIdMatches(candidate, args.nodeId));
9885
10190
  const workspace = readNonEmptyString2(node?.workspace);
9886
10191
  if (!workspace) return;
9887
- if (!existsSync14(workspace)) return;
10192
+ if (!existsSync15(workspace)) return;
9888
10193
  const policy = resolveAutoFastForwardPolicy(mesh);
9889
10194
  if (!policy.enabled) return;
9890
10195
  if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
@@ -9978,24 +10283,24 @@ function injectMeshSystemMessage(components, args) {
9978
10283
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
9979
10284
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
9980
10285
  }
9981
- if (args.event === "monitor:long_generating") {
9982
- const reconciledCompletion = buildLongGeneratingCompletionReconciliation({
10286
+ if (args.event === "monitor:no_progress") {
10287
+ const reconciledCompletion = buildNoProgressCompletionReconciliation({
9983
10288
  meshId: args.meshId,
9984
10289
  nodeId: args.nodeId,
9985
10290
  nodeLabel: args.nodeLabel,
9986
10291
  metadataEvent: args.metadataEvent,
9987
10292
  sourceInstanceId: args.sourceInstanceId
9988
10293
  });
9989
- if (reconciledCompletion?.source === "long_generating_reconciliation") {
9990
- LOG.info("MeshEvents", `Reconciled long-generating monitor to completion for session ${eventSessionId || "(unknown session)"}`);
10294
+ if (reconciledCompletion?.source === "no_progress_reconciliation") {
10295
+ LOG.info("MeshEvents", `Reconciled no-progress monitor to completion for session ${eventSessionId || "(unknown session)"}`);
9991
10296
  return injectMeshSystemMessage(components, {
9992
10297
  ...args,
9993
10298
  event: "agent:generating_completed",
9994
10299
  metadataEvent: reconciledCompletion
9995
10300
  });
9996
10301
  }
9997
- if (reconciledCompletion?.source === "long_generating_terminal_ledger_suppression") {
9998
- LOG.info("MeshEvents", `Suppressed long-generating monitor because terminal ledger evidence already exists for session ${eventSessionId || "(unknown session)"}`);
10302
+ if (reconciledCompletion?.source === "no_progress_terminal_ledger_suppression") {
10303
+ LOG.info("MeshEvents", `Suppressed no-progress monitor because terminal ledger evidence already exists for session ${eventSessionId || "(unknown session)"}`);
9999
10304
  return {
10000
10305
  success: true,
10001
10306
  forwarded: 0,
@@ -10037,7 +10342,7 @@ function injectMeshSystemMessage(components, args) {
10037
10342
  const terminalFinalSummary = readNonEmptyString2(terminal.payload.finalSummary);
10038
10343
  const eventProviderSessionId = readNonEmptyString2(args.metadataEvent.providerSessionId);
10039
10344
  const eventFinalSummary = readNonEmptyString2(args.metadataEvent.finalSummary);
10040
- if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "long_generating_reconciliation") {
10345
+ if (terminalProviderSessionId && terminalProviderSessionId === eventProviderSessionId || terminalFinalSummary && terminalFinalSummary === eventFinalSummary || args.metadataEvent.source === "no_progress_reconciliation") {
10041
10346
  LOG.info("MeshEvents", `Suppressed duplicate completion with existing terminal ledger evidence for mesh ${args.meshId} session ${eventSessionId}`);
10042
10347
  return { success: true, forwarded: 0, suppressed: true, duplicateCompletion: true, terminalLedgerEvidence: true };
10043
10348
  }
@@ -10515,7 +10820,7 @@ var init_mesh_events_coordinator = __esm({
10515
10820
  "agent:waiting_approval",
10516
10821
  "agent:stopped",
10517
10822
  "agent:ready",
10518
- "monitor:long_generating",
10823
+ "monitor:no_progress",
10519
10824
  "refine:accepted",
10520
10825
  "refine:completed",
10521
10826
  "refine:failed",
@@ -10526,7 +10831,7 @@ var init_mesh_events_coordinator = __esm({
10526
10831
  "agent:generating_completed": "task_completed",
10527
10832
  "agent:waiting_approval": "task_approval_needed",
10528
10833
  "agent:stopped": "task_failed",
10529
- "monitor:long_generating": "task_stalled"
10834
+ "monitor:no_progress": "task_stalled"
10530
10835
  };
10531
10836
  MESH_FORCE_INJECT_EVENTS = /* @__PURE__ */ new Set([
10532
10837
  "agent:generating_completed",
@@ -12661,7 +12966,7 @@ var init_terminal_screen = __esm({
12661
12966
 
12662
12967
  // src/cli-adapters/resolve-executable.ts
12663
12968
  import { execFileSync } from "child_process";
12664
- import { existsSync as existsSync21 } from "fs";
12969
+ import { existsSync as existsSync22 } from "fs";
12665
12970
  import * as path18 from "path";
12666
12971
  function resolveWin32GlobalBin(trimmed) {
12667
12972
  if (path18.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\")) {
@@ -12677,7 +12982,7 @@ function resolveWin32GlobalBin(trimmed) {
12677
12982
  if (!dir) continue;
12678
12983
  for (const ext of WIN_EXEC_EXT) {
12679
12984
  const full = path18.join(dir, trimmed + ext);
12680
- if (existsSync21(full)) return full;
12985
+ if (existsSync22(full)) return full;
12681
12986
  }
12682
12987
  }
12683
12988
  return null;
@@ -12686,7 +12991,7 @@ function resolveWin32Executable(command) {
12686
12991
  if (process.platform !== "win32") return command;
12687
12992
  const trimmed = (command || "").trim();
12688
12993
  if (!trimmed) return command;
12689
- if (path18.isAbsolute(trimmed) && existsSync21(trimmed)) return trimmed;
12994
+ if (path18.isAbsolute(trimmed) && existsSync22(trimmed)) return trimmed;
12690
12995
  try {
12691
12996
  const out = execFileSync("where", [trimmed], {
12692
12997
  encoding: "utf8",
@@ -15672,7 +15977,7 @@ ${lastSnapshot}`;
15672
15977
  };
15673
15978
  if (parsedSessionStatus === "idle" && hasFinalAssistant(parsedStatusBeforeSend)) return null;
15674
15979
  if (this.engine.currentStatus === "generating") return "current_status_generating";
15675
- if (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating") {
15980
+ if (parsedSessionStatus === "generating" || parsedSessionStatus === "no_progress" || parsedSessionStatus === "long_generating") {
15676
15981
  const parsedModal = parsedStatusBeforeSend?.activeModal ?? parsedStatusBeforeSend?.modal ?? null;
15677
15982
  const parsedHasActionableModal = Boolean(
15678
15983
  parsedModal && Array.isArray(parsedModal.buttons) && parsedModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim())
@@ -15749,7 +16054,7 @@ ${lastSnapshot}`;
15749
16054
  }
15750
16055
  if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.engine.currentStatus})`);
15751
16056
  const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
15752
- if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
16057
+ if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "no_progress" || parsedSessionStatus === "long_generating")) {
15753
16058
  const parsedModal = parsedStatusBeforeSend?.activeModal ?? parsedStatusBeforeSend?.modal ?? null;
15754
16059
  const parsedHasActionableModal = Boolean(
15755
16060
  parsedModal && Array.isArray(parsedModal.buttons) && parsedModal.buttons.some((candidate) => typeof candidate === "string" && candidate.trim())
@@ -17612,6 +17917,7 @@ init_repo_mesh_types();
17612
17917
  // src/git/index.ts
17613
17918
  init_git_executor();
17614
17919
  init_git_status();
17920
+ init_change_impact_config();
17615
17921
  init_git_diff();
17616
17922
 
17617
17923
  // src/git/git-summary.ts
@@ -18906,17 +19212,17 @@ init_mesh_review_inbox();
18906
19212
 
18907
19213
  // src/mesh/coordinator-registry.ts
18908
19214
  init_config();
18909
- import { join as join10 } from "path";
18910
- import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
19215
+ import { join as join11 } from "path";
19216
+ import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
18911
19217
  var _registry = /* @__PURE__ */ new Map();
18912
19218
  function getRegistryPath() {
18913
- return join10(getDaemonDataDir(), "mesh-coordinators.json");
19219
+ return join11(getDaemonDataDir(), "mesh-coordinators.json");
18914
19220
  }
18915
19221
  function loadMeshCoordinatorRegistry() {
18916
19222
  const path42 = getRegistryPath();
18917
- if (!existsSync9(path42)) return;
19223
+ if (!existsSync10(path42)) return;
18918
19224
  try {
18919
- const raw = JSON.parse(readFileSync7(path42, "utf-8"));
19225
+ const raw = JSON.parse(readFileSync8(path42, "utf-8"));
18920
19226
  if (!Array.isArray(raw)) return;
18921
19227
  _registry.clear();
18922
19228
  for (const entry of raw) {
@@ -18964,9 +19270,9 @@ function listCoordinatorsForWorkspace(workspace) {
18964
19270
  }
18965
19271
 
18966
19272
  // src/mesh/refine-config.ts
18967
- import { existsSync as existsSync10, readFileSync as readFileSync8 } from "fs";
18968
- import { join as join11 } from "path";
18969
- import * as yaml from "js-yaml";
19273
+ import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
19274
+ import { join as join12 } from "path";
19275
+ import * as yaml2 from "js-yaml";
18970
19276
  var MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
18971
19277
  var MESH_REFINE_CONFIG_LOCATIONS = [
18972
19278
  ".adhdev/refine.json",
@@ -19107,7 +19413,7 @@ function normalizeMeshCommandConfig(entry, source) {
19107
19413
  }
19108
19414
  };
19109
19415
  }
19110
- var isRecord = isMeshConfigRecord;
19416
+ var isRecord2 = isMeshConfigRecord;
19111
19417
  function validateMeshRefineConfig(config, source = "inline") {
19112
19418
  const errors = [];
19113
19419
  const bootstrapCommands = [];
@@ -19115,14 +19421,14 @@ function validateMeshRefineConfig(config, source = "inline") {
19115
19421
  const rejectedCommands = [];
19116
19422
  const deprecationWarnings = [];
19117
19423
  let bootstrapMode = "inherit";
19118
- if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19424
+ if (!isRecord2(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19119
19425
  if (config.version !== 1) errors.push("version must be 1");
19120
19426
  if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
19121
19427
  errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
19122
19428
  }
19123
19429
  const validation = config.validation;
19124
- if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
19125
- const rawBootstrapMode = isRecord(validation) ? validation.bootstrap : void 0;
19430
+ if (validation !== void 0 && !isRecord2(validation)) errors.push("validation must be an object");
19431
+ const rawBootstrapMode = isRecord2(validation) ? validation.bootstrap : void 0;
19126
19432
  if (rawBootstrapMode !== void 0) {
19127
19433
  if (rawBootstrapMode === "inherit" || rawBootstrapMode === "skip") {
19128
19434
  bootstrapMode = rawBootstrapMode;
@@ -19130,8 +19436,8 @@ function validateMeshRefineConfig(config, source = "inline") {
19130
19436
  errors.push("validation.bootstrap must be 'inherit' or 'skip' when provided");
19131
19437
  }
19132
19438
  }
19133
- const rawCommands = isRecord(validation) ? validation.commands : void 0;
19134
- const rawBootstrapCommands = isRecord(validation) ? validation.bootstrapCommands : void 0;
19439
+ const rawCommands = isRecord2(validation) ? validation.commands : void 0;
19440
+ const rawBootstrapCommands = isRecord2(validation) ? validation.bootstrapCommands : void 0;
19135
19441
  if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
19136
19442
  if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
19137
19443
  if (Array.isArray(rawBootstrapCommands) && rawBootstrapCommands.length > 0) {
@@ -19154,9 +19460,9 @@ function validateMeshRefineConfig(config, source = "inline") {
19154
19460
  if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
19155
19461
  return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
19156
19462
  }
19157
- function parseConfigText(path42, text) {
19463
+ function parseConfigText2(path42, text) {
19158
19464
  if (/\.json$/i.test(path42)) return JSON.parse(text);
19159
- return yaml.load(text);
19465
+ return yaml2.load(text);
19160
19466
  }
19161
19467
  function loadMeshRefineConfig(mesh, workspace) {
19162
19468
  const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
@@ -19167,10 +19473,10 @@ function loadMeshRefineConfig(mesh, workspace) {
19167
19473
  return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
19168
19474
  }
19169
19475
  for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
19170
- const configPath = join11(workspace, relative5);
19171
- if (!existsSync10(configPath)) continue;
19476
+ const configPath = join12(workspace, relative5);
19477
+ if (!existsSync11(configPath)) continue;
19172
19478
  try {
19173
- const parsed = parseConfigText(configPath, readFileSync8(configPath, "utf-8"));
19479
+ const parsed = parseConfigText2(configPath, readFileSync9(configPath, "utf-8"));
19174
19480
  const validation = validateMeshRefineConfig(parsed, relative5);
19175
19481
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
19176
19482
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -19186,20 +19492,20 @@ function loadMeshRefineConfig(mesh, workspace) {
19186
19492
  }
19187
19493
  function readPackageScripts(workspace) {
19188
19494
  try {
19189
- const parsed = JSON.parse(readFileSync8(join11(workspace, "package.json"), "utf-8"));
19190
- return isRecord(parsed?.scripts) ? parsed.scripts : {};
19495
+ const parsed = JSON.parse(readFileSync9(join12(workspace, "package.json"), "utf-8"));
19496
+ return isRecord2(parsed?.scripts) ? parsed.scripts : {};
19191
19497
  } catch {
19192
19498
  return {};
19193
19499
  }
19194
19500
  }
19195
19501
  function collectProjectContextSuggestions(mesh) {
19196
19502
  const commands = mesh?.projectContext?.commands;
19197
- if (!isRecord(commands)) return [];
19503
+ if (!isRecord2(commands)) return [];
19198
19504
  const suggestions = [];
19199
19505
  for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
19200
19506
  const entries = Array.isArray(commands[category]) ? commands[category] : [];
19201
19507
  for (const entry of entries) {
19202
- if (isRecord(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
19508
+ if (isRecord2(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
19203
19509
  }
19204
19510
  }
19205
19511
  return suggestions;
@@ -19263,12 +19569,12 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
19263
19569
  }
19264
19570
 
19265
19571
  // src/mesh/worktree-bootstrap-config.ts
19266
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "fs";
19267
- import { join as join12, resolve as pathResolve } from "path";
19572
+ import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
19573
+ import { join as join13, resolve as pathResolve } from "path";
19268
19574
  import { execFile as execFile3 } from "child_process";
19269
19575
  import { createHash as createHash3 } from "crypto";
19270
19576
  import { promisify as promisify3 } from "util";
19271
- import * as yaml2 from "js-yaml";
19577
+ import * as yaml3 from "js-yaml";
19272
19578
  var MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS = [
19273
19579
  ".adhdev/worktree_bootstrap.json",
19274
19580
  ".adhdev/worktree_bootstrap.yaml",
@@ -19313,9 +19619,9 @@ var MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA = {
19313
19619
  var DEFAULT_TIMEOUT_MS2 = 12e4;
19314
19620
  var DEFAULT_OUTPUT_LIMIT_BYTES = 128 * 1024;
19315
19621
  var OUTPUT_SUMMARY_CHARS = 2e3;
19316
- function parseConfigText2(path42, text) {
19622
+ function parseConfigText3(path42, text) {
19317
19623
  if (/\.json$/i.test(path42)) return JSON.parse(text);
19318
- return yaml2.load(text);
19624
+ return yaml3.load(text);
19319
19625
  }
19320
19626
  function truncateOutput(value) {
19321
19627
  const text = typeof value === "string" ? value : value == null ? "" : String(value);
@@ -19355,10 +19661,10 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19355
19661
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
19356
19662
  }
19357
19663
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
19358
- const configPath = join12(workspace, relative5);
19359
- if (!existsSync11(configPath)) continue;
19664
+ const configPath = join13(workspace, relative5);
19665
+ if (!existsSync12(configPath)) continue;
19360
19666
  try {
19361
- const parsed = parseConfigText2(configPath, readFileSync9(configPath, "utf-8"));
19667
+ const parsed = parseConfigText3(configPath, readFileSync10(configPath, "utf-8"));
19362
19668
  const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
19363
19669
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
19364
19670
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -19371,9 +19677,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
19371
19677
  function computeStaleInputsDigest(workspace, staleInputs) {
19372
19678
  const digest = {};
19373
19679
  for (const relative5 of staleInputs ?? []) {
19374
- const filePath = join12(workspace, relative5);
19680
+ const filePath = join13(workspace, relative5);
19375
19681
  try {
19376
- digest[relative5] = createHash3("sha256").update(readFileSync9(filePath)).digest("hex");
19682
+ digest[relative5] = createHash3("sha256").update(readFileSync10(filePath)).digest("hex");
19377
19683
  } catch {
19378
19684
  digest[relative5] = "absent";
19379
19685
  }
@@ -19443,10 +19749,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
19443
19749
  staleInputs: loaded.config.staleInputs
19444
19750
  };
19445
19751
  const staleInputPaths = loaded.config.staleInputs ?? [];
19446
- const initiallyAbsent = staleInputPaths.filter((p) => !existsSync11(join12(workspace, p)));
19752
+ const initiallyAbsent = staleInputPaths.filter((p) => !existsSync12(join13(workspace, p)));
19447
19753
  for (const command of validation.commands) {
19448
19754
  if (initiallyAbsent.length > 0) {
19449
- const appearedNow = initiallyAbsent.filter((p) => existsSync11(join12(workspace, p)));
19755
+ const appearedNow = initiallyAbsent.filter((p) => existsSync12(join13(workspace, p)));
19450
19756
  if (appearedNow.length > 0) {
19451
19757
  state.status = "stale";
19452
19758
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -19694,8 +20000,8 @@ var P2pRelayFailureError = class extends Error {
19694
20000
 
19695
20001
  // src/config/state-store.ts
19696
20002
  init_config();
19697
- import { existsSync as existsSync15, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
19698
- import { join as join16 } from "path";
20003
+ import { existsSync as existsSync16, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "fs";
20004
+ import { join as join17 } from "path";
19699
20005
  var DEFAULT_STATE = {
19700
20006
  recentActivity: [],
19701
20007
  savedProviderSessions: [],
@@ -19708,7 +20014,7 @@ function isPlainObject2(value) {
19708
20014
  return !!value && typeof value === "object" && !Array.isArray(value);
19709
20015
  }
19710
20016
  function getStatePath() {
19711
- return join16(getConfigDir(), "state.json");
20017
+ return join17(getConfigDir(), "state.json");
19712
20018
  }
19713
20019
  function normalizeState(raw) {
19714
20020
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -19744,11 +20050,11 @@ function normalizeState(raw) {
19744
20050
  }
19745
20051
  function loadState() {
19746
20052
  const statePath = getStatePath();
19747
- if (!existsSync15(statePath)) {
20053
+ if (!existsSync16(statePath)) {
19748
20054
  return { ...DEFAULT_STATE };
19749
20055
  }
19750
20056
  try {
19751
- const raw = readFileSync11(statePath, "utf-8");
20057
+ const raw = readFileSync12(statePath, "utf-8");
19752
20058
  return normalizeState(JSON.parse(raw));
19753
20059
  } catch {
19754
20060
  return { ...DEFAULT_STATE };
@@ -19766,7 +20072,7 @@ function resetState() {
19766
20072
  // src/detection/ide-detector.ts
19767
20073
  import { exec as exec2 } from "child_process";
19768
20074
  import { promisify as promisify4 } from "util";
19769
- import { existsSync as existsSync17, statSync as statSync7 } from "fs";
20075
+ import { existsSync as existsSync18, statSync as statSync8 } from "fs";
19770
20076
  import { platform as platform3, homedir as homedir8 } from "os";
19771
20077
  import * as path13 from "path";
19772
20078
 
@@ -19847,7 +20153,7 @@ function findCliCommand(command) {
19847
20153
  if (path13.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~")) {
19848
20154
  const candidate = trimmed.startsWith("~") ? path13.join(homedir8(), trimmed.slice(1)) : trimmed;
19849
20155
  const resolved = path13.isAbsolute(candidate) ? candidate : path13.resolve(candidate);
19850
- return existsSync17(resolved) ? resolved : null;
20156
+ return existsSync18(resolved) ? resolved : null;
19851
20157
  }
19852
20158
  const isWin = platform3() === "win32";
19853
20159
  const paths = (process.env.PATH || "").split(isWin ? ";" : ":");
@@ -19857,8 +20163,8 @@ function findCliCommand(command) {
19857
20163
  for (const ext of exes) {
19858
20164
  const fullPath = path13.join(p, trimmed + ext);
19859
20165
  try {
19860
- if (existsSync17(fullPath)) {
19861
- const stat2 = statSync7(fullPath);
20166
+ if (existsSync18(fullPath)) {
20167
+ const stat2 = statSync8(fullPath);
19862
20168
  if (stat2.isFile() && (isWin || stat2.mode & 73)) {
19863
20169
  return fullPath;
19864
20170
  }
@@ -19876,9 +20182,9 @@ function checkPathExists(paths) {
19876
20182
  if (normalized.includes("*")) {
19877
20183
  const username = home.split(/[\\/]/).pop() || "";
19878
20184
  const resolved = normalized.replace("*", username);
19879
- if (existsSync17(resolved)) return resolved;
20185
+ if (existsSync18(resolved)) return resolved;
19880
20186
  } else {
19881
- if (existsSync17(normalized)) return normalized;
20187
+ if (existsSync18(normalized)) return normalized;
19882
20188
  }
19883
20189
  }
19884
20190
  return null;
@@ -19892,7 +20198,7 @@ async function detectIDEs(providerLoader) {
19892
20198
  let resolvedCli = cliPath;
19893
20199
  if (!resolvedCli && appPath && os30 === "darwin") {
19894
20200
  const bundledCli = `${appPath}/Contents/Resources/app/bin/${def.cli}`;
19895
- if (existsSync17(bundledCli)) resolvedCli = bundledCli;
20201
+ if (existsSync18(bundledCli)) resolvedCli = bundledCli;
19896
20202
  }
19897
20203
  if (!resolvedCli && appPath && os30 === "win32") {
19898
20204
  const { dirname: dirname17 } = await import("path");
@@ -19905,7 +20211,7 @@ async function detectIDEs(providerLoader) {
19905
20211
  `${appDir}\\\\resources\\\\app\\\\bin\\\\${def.cli}.cmd`
19906
20212
  ];
19907
20213
  for (const c of candidates) {
19908
- if (existsSync17(c)) {
20214
+ if (existsSync18(c)) {
19909
20215
  resolvedCli = c;
19910
20216
  break;
19911
20217
  }
@@ -21450,8 +21756,8 @@ init_contracts();
21450
21756
  // src/providers/status-monitor.ts
21451
21757
  var DEFAULT_MONITOR_CONFIG = {
21452
21758
  approvalAlert: true,
21453
- longGeneratingAlert: true,
21454
- longGeneratingThresholdSec: 180,
21759
+ noProgressAlert: true,
21760
+ noProgressThresholdSec: 180,
21455
21761
  // 3 minutes
21456
21762
  alertCooldownSec: 60
21457
21763
  // 1 minute cooldown
@@ -21460,7 +21766,7 @@ var StatusMonitor = class {
21460
21766
  config;
21461
21767
  lastAlertTime = /* @__PURE__ */ new Map();
21462
21768
  generatingStartTimes = /* @__PURE__ */ new Map();
21463
- longGeneratingAlerted = /* @__PURE__ */ new Map();
21769
+ noProgressAlerted = /* @__PURE__ */ new Map();
21464
21770
  lastProgressFingerprint = /* @__PURE__ */ new Map();
21465
21771
  lastProgressChangeAt = /* @__PURE__ */ new Map();
21466
21772
  constructor(config) {
@@ -21478,7 +21784,7 @@ var StatusMonitor = class {
21478
21784
  * Check status transition → return notification event array.
21479
21785
  * Called from each onTick() or detectStatusTransition().
21480
21786
  */
21481
- check(agentKey, status, now, progressFingerprint) {
21787
+ check(agentKey, status, now, progressFingerprint, approvalPending) {
21482
21788
  const events = [];
21483
21789
  if (this.config.approvalAlert && status === "waiting_approval") {
21484
21790
  if (this.shouldAlert(agentKey + ":approval", now)) {
@@ -21491,9 +21797,16 @@ var StatusMonitor = class {
21491
21797
  }
21492
21798
  }
21493
21799
  if (status === "generating" || status === "streaming") {
21800
+ if (approvalPending) {
21801
+ this.generatingStartTimes.set(agentKey, now);
21802
+ this.lastProgressFingerprint.set(agentKey, progressFingerprint ?? "");
21803
+ this.lastProgressChangeAt.set(agentKey, now);
21804
+ this.noProgressAlerted.set(agentKey, false);
21805
+ return events;
21806
+ }
21494
21807
  if (!this.generatingStartTimes.has(agentKey)) {
21495
21808
  this.generatingStartTimes.set(agentKey, now);
21496
- this.longGeneratingAlerted.set(agentKey, false);
21809
+ this.noProgressAlerted.set(agentKey, false);
21497
21810
  const initialFingerprint = progressFingerprint ?? "";
21498
21811
  this.lastProgressFingerprint.set(agentKey, initialFingerprint);
21499
21812
  this.lastProgressChangeAt.set(agentKey, now);
@@ -21503,17 +21816,17 @@ var StatusMonitor = class {
21503
21816
  if (previousFingerprint !== currentFingerprint) {
21504
21817
  this.lastProgressFingerprint.set(agentKey, currentFingerprint);
21505
21818
  this.lastProgressChangeAt.set(agentKey, now);
21506
- this.longGeneratingAlerted.set(agentKey, false);
21819
+ this.noProgressAlerted.set(agentKey, false);
21507
21820
  }
21508
- if (this.config.longGeneratingAlert) {
21821
+ if (this.config.noProgressAlert) {
21509
21822
  const progressChangedAt = this.lastProgressChangeAt.get(agentKey) || this.generatingStartTimes.get(agentKey);
21510
21823
  const elapsedSec = Math.round((now - progressChangedAt) / 1e3);
21511
- const alreadyAlerted = this.longGeneratingAlerted.get(agentKey) === true;
21512
- if (elapsedSec > this.config.longGeneratingThresholdSec && !alreadyAlerted) {
21513
- if (this.shouldAlert(agentKey + ":long_gen", now)) {
21514
- this.longGeneratingAlerted.set(agentKey, true);
21824
+ const alreadyAlerted = this.noProgressAlerted.get(agentKey) === true;
21825
+ if (elapsedSec > this.config.noProgressThresholdSec && !alreadyAlerted) {
21826
+ if (this.shouldAlert(agentKey + ":no_progress", now)) {
21827
+ this.noProgressAlerted.set(agentKey, true);
21515
21828
  events.push({
21516
- type: "monitor:long_generating",
21829
+ type: "monitor:no_progress",
21517
21830
  agentKey,
21518
21831
  elapsedSec,
21519
21832
  timestamp: now,
@@ -21524,7 +21837,7 @@ var StatusMonitor = class {
21524
21837
  }
21525
21838
  } else {
21526
21839
  this.generatingStartTimes.delete(agentKey);
21527
- this.longGeneratingAlerted.delete(agentKey);
21840
+ this.noProgressAlerted.delete(agentKey);
21528
21841
  this.lastProgressFingerprint.delete(agentKey);
21529
21842
  this.lastProgressChangeAt.delete(agentKey);
21530
21843
  }
@@ -21543,7 +21856,7 @@ var StatusMonitor = class {
21543
21856
  reset(agentKey) {
21544
21857
  if (agentKey) {
21545
21858
  this.generatingStartTimes.delete(agentKey);
21546
- this.longGeneratingAlerted.delete(agentKey);
21859
+ this.noProgressAlerted.delete(agentKey);
21547
21860
  this.lastProgressFingerprint.delete(agentKey);
21548
21861
  this.lastProgressChangeAt.delete(agentKey);
21549
21862
  for (const k of this.lastAlertTime.keys()) {
@@ -21551,7 +21864,7 @@ var StatusMonitor = class {
21551
21864
  }
21552
21865
  } else {
21553
21866
  this.generatingStartTimes.clear();
21554
- this.longGeneratingAlerted.clear();
21867
+ this.noProgressAlerted.clear();
21555
21868
  this.lastProgressFingerprint.clear();
21556
21869
  this.lastProgressChangeAt.clear();
21557
21870
  this.lastAlertTime.clear();
@@ -23374,8 +23687,8 @@ var ExtensionProviderInstance = class {
23374
23687
  this.settings = context.settings || {};
23375
23688
  this.monitor.updateConfig({
23376
23689
  approvalAlert: this.settings.approvalAlert !== false,
23377
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
23378
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
23690
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
23691
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
23379
23692
  });
23380
23693
  }
23381
23694
  async onTick() {
@@ -23466,8 +23779,8 @@ var ExtensionProviderInstance = class {
23466
23779
  this.settings = { ...this.settings, ...newSettings };
23467
23780
  this.monitor.updateConfig({
23468
23781
  approvalAlert: this.settings.approvalAlert !== false,
23469
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
23470
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
23782
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
23783
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
23471
23784
  });
23472
23785
  }
23473
23786
  /** Query UUID instanceId */
@@ -23527,7 +23840,8 @@ var ExtensionProviderInstance = class {
23527
23840
  phase: agentStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
23528
23841
  });
23529
23842
  const agentKey = `${this.type}:ext`;
23530
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
23843
+ const approvalPending = agentStatus === "waiting_approval";
23844
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint, approvalPending);
23531
23845
  for (const me of monitorEvents) {
23532
23846
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
23533
23847
  }
@@ -23742,7 +24056,7 @@ init_contracts();
23742
24056
  var CHAT_CONTRACT_VERSION_V1 = "1.0";
23743
24057
 
23744
24058
  // src/providers/read-chat-contract.ts
23745
- var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "long_generating"];
24059
+ var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "no_progress", "long_generating"];
23746
24060
  var VALID_ROLES = ["user", "assistant", "system", "human"];
23747
24061
  var VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
23748
24062
  var VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
@@ -24009,8 +24323,8 @@ var IdeProviderInstance = class {
24009
24323
  this.settings = context.settings || {};
24010
24324
  this.monitor.updateConfig({
24011
24325
  approvalAlert: this.settings.approvalAlert !== false,
24012
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
24013
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24326
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24327
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
24014
24328
  });
24015
24329
  }
24016
24330
  async onTick() {
@@ -24137,8 +24451,8 @@ var IdeProviderInstance = class {
24137
24451
  this.settings = { ...this.settings, ...newSettings };
24138
24452
  this.monitor.updateConfig({
24139
24453
  approvalAlert: this.settings.approvalAlert !== false,
24140
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
24141
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
24454
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
24455
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
24142
24456
  });
24143
24457
  }
24144
24458
  // ─── Extension manage ─────────────────────────────
@@ -24269,7 +24583,7 @@ var IdeProviderInstance = class {
24269
24583
  const persistedMessages = chat.messages || messages;
24270
24584
  if (persistedMessages.length > 0) {
24271
24585
  let toSave = persistedMessages;
24272
- if (chat.status === "generating" || chat.status === "long_generating") {
24586
+ if (chat.status === "generating" || chat.status === "no_progress" || chat.status === "long_generating") {
24273
24587
  const lastIdx = toSave.length - 1;
24274
24588
  if (lastIdx >= 0 && toSave[lastIdx].role === "assistant") {
24275
24589
  toSave = toSave.slice(0, lastIdx);
@@ -24339,7 +24653,8 @@ var IdeProviderInstance = class {
24339
24653
  if (rawAgentStatus === "waiting_approval" && autoApproveActive && !this.autoApproveBusy) {
24340
24654
  this.autoApproveViaScript(chatData);
24341
24655
  }
24342
- const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint);
24656
+ const approvalPending = rawAgentStatus === "waiting_approval";
24657
+ const monitorEvents = this.monitor.check(agentKey, agentStatus, now, progressFingerprint, approvalPending);
24343
24658
  for (const me of monitorEvents) {
24344
24659
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
24345
24660
  }
@@ -26896,7 +27211,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
26896
27211
  }
26897
27212
  }
26898
27213
  function isGeneratingLikeStatus(status) {
26899
- return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
27214
+ return status === "generating" || status === "streaming" || status === "no_progress" || status === "long_generating" || status === "starting";
26900
27215
  }
26901
27216
  function hasVisibleAssistantMessage(messages) {
26902
27217
  if (!Array.isArray(messages)) return false;
@@ -30932,7 +31247,7 @@ init_config();
30932
31247
  import * as os19 from "os";
30933
31248
  import * as path26 from "path";
30934
31249
  import * as crypto5 from "crypto";
30935
- import { existsSync as existsSync26, mkdirSync as mkdirSync12, writeFileSync as writeFileSync15 } from "fs";
31250
+ import { existsSync as existsSync27, mkdirSync as mkdirSync12, writeFileSync as writeFileSync15 } from "fs";
30936
31251
  import { execFileSync as execFileSync2 } from "child_process";
30937
31252
  import chalk from "chalk";
30938
31253
 
@@ -33574,7 +33889,7 @@ function hasNonEmptyCliModalButtons(activeModal) {
33574
33889
  return Array.isArray(buttons) && buttons.some((button) => String(button || "").trim().length > 0);
33575
33890
  }
33576
33891
  function isCliGeneratingLikeStatus(status) {
33577
- return status === "generating" || status === "streaming" || status === "long_generating" || status === "starting";
33892
+ return status === "generating" || status === "streaming" || status === "no_progress" || status === "long_generating" || status === "starting";
33578
33893
  }
33579
33894
  function buildCliStructuredInputPrompt(input, options = {}) {
33580
33895
  const promptParts = [];
@@ -33776,8 +34091,8 @@ var CliProviderInstance = class _CliProviderInstance {
33776
34091
  this.adapter.updateRuntimeSettings?.(this.settings);
33777
34092
  this.monitor.updateConfig({
33778
34093
  approvalAlert: this.settings.approvalAlert !== false,
33779
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
33780
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
34094
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
34095
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
33781
34096
  });
33782
34097
  if (context.serverConn) {
33783
34098
  this.adapter.setServerConn(context.serverConn);
@@ -33924,7 +34239,7 @@ var CliProviderInstance = class _CliProviderInstance {
33924
34239
  if (parsedMessages.length > 0) {
33925
34240
  const shouldSkipReplayPersist = this.suppressIdleHistoryReplay && adapterStatus.status === "idle" && parsedStatus?.status === "idle";
33926
34241
  let messagesToSave = parsedMessages;
33927
- if (!suppressStaleParsedBusyStatus && (parsedChatStatus === "generating" || parsedChatStatus === "long_generating")) {
34242
+ if (!suppressStaleParsedBusyStatus && (parsedChatStatus === "generating" || parsedChatStatus === "no_progress" || parsedChatStatus === "long_generating")) {
33928
34243
  const lastIdx = messagesToSave.length - 1;
33929
34244
  if (lastIdx >= 0 && messagesToSave[lastIdx]?.role === "assistant") {
33930
34245
  messagesToSave = messagesToSave.slice(0, lastIdx);
@@ -34052,8 +34367,8 @@ var CliProviderInstance = class _CliProviderInstance {
34052
34367
  this.adapter.updateRuntimeSettings?.(this.settings);
34053
34368
  this.monitor.updateConfig({
34054
34369
  approvalAlert: this.settings.approvalAlert !== false,
34055
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
34056
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
34370
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
34371
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
34057
34372
  });
34058
34373
  }
34059
34374
  /**
@@ -34785,10 +35100,11 @@ var CliProviderInstance = class _CliProviderInstance {
34785
35100
  phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
34786
35101
  });
34787
35102
  const agentKey = `${this.type}:cli`;
34788
- const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
35103
+ const approvalPending = rawStatus === "waiting_approval";
35104
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint, approvalPending);
34789
35105
  const monitorParsedStatus = parsedStatus;
34790
35106
  for (const me of monitorEvents) {
34791
- if (me.type === "monitor:long_generating" && this.completionHasFinalAssistantMessage(monitorParsedStatus?.messages) && !this.hasAdapterPendingResponse() && !hasNonEmptyCliModalButtons(monitorParsedStatus?.activeModal ?? monitorParsedStatus?.modal)) {
35107
+ if (me.type === "monitor:no_progress" && this.completionHasFinalAssistantMessage(monitorParsedStatus?.messages) && !this.hasAdapterPendingResponse() && !hasNonEmptyCliModalButtons(monitorParsedStatus?.activeModal ?? monitorParsedStatus?.modal)) {
34792
35108
  this.pushEvent({
34793
35109
  event: "agent:generating_completed",
34794
35110
  chatTitle,
@@ -34799,7 +35115,7 @@ var CliProviderInstance = class _CliProviderInstance {
34799
35115
  providerType: this.type,
34800
35116
  sessionId: this.instanceId,
34801
35117
  providerSessionId: this.providerSessionId || null,
34802
- reconciliationReason: "long_generating_monitor_final_summary",
35118
+ reconciliationReason: "no_progress_monitor_final_summary",
34803
35119
  finalAssistantPresent: true
34804
35120
  }
34805
35121
  });
@@ -35481,8 +35797,8 @@ var AcpProviderInstance = class {
35481
35797
  this.settings = context.settings || {};
35482
35798
  this.monitor.updateConfig({
35483
35799
  approvalAlert: this.settings.approvalAlert !== false,
35484
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
35485
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
35800
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
35801
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
35486
35802
  });
35487
35803
  await this.spawnAgent();
35488
35804
  }
@@ -35778,8 +36094,8 @@ var AcpProviderInstance = class {
35778
36094
  this.settings = { ...this.settings, ...newSettings };
35779
36095
  this.monitor.updateConfig({
35780
36096
  approvalAlert: this.settings.approvalAlert !== false,
35781
- longGeneratingAlert: this.settings.longGeneratingAlert !== false,
35782
- longGeneratingThresholdSec: this.settings.longGeneratingThresholdSec || 180
36097
+ noProgressAlert: (this.settings.noProgressAlert ?? this.settings.longGeneratingAlert) !== false,
36098
+ noProgressThresholdSec: this.settings.noProgressThresholdSec ?? this.settings.longGeneratingThresholdSec ?? 180
35783
36099
  });
35784
36100
  this.log.info(`[${this.type}] Settings updated: ${Object.keys(newSettings).join(", ")}`);
35785
36101
  }
@@ -36486,7 +36802,8 @@ ${rawInput}` : rawInput;
36486
36802
  this.lastStatus = newStatus;
36487
36803
  }
36488
36804
  const agentKey = `${this.type}:acp`;
36489
- const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint);
36805
+ const approvalPending = newStatus === "waiting_approval";
36806
+ const monitorEvents = this.monitor.check(agentKey, newStatus, now, progressFingerprint, approvalPending);
36490
36807
  for (const me of monitorEvents) {
36491
36808
  this.pushEvent({ event: me.type, agentKey: me.agentKey, message: me.message, elapsedSec: me.elapsedSec, timestamp: me.timestamp });
36492
36809
  }
@@ -36548,7 +36865,7 @@ function commandExists(command) {
36548
36865
  const trimmed = command.trim();
36549
36866
  if (!trimmed) return false;
36550
36867
  if (isExplicitCommand(trimmed)) {
36551
- return existsSync26(expandExecutable(trimmed));
36868
+ return existsSync27(expandExecutable(trimmed));
36552
36869
  }
36553
36870
  try {
36554
36871
  execFileSync2(process.platform === "win32" ? "where" : "which", [trimmed], {
@@ -36560,7 +36877,7 @@ function commandExists(command) {
36560
36877
  return false;
36561
36878
  }
36562
36879
  }
36563
- var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "long_generating"]);
36880
+ var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "no_progress", "long_generating"]);
36564
36881
  var ZERO_MESSAGE_STARTING_SEND_WAIT_MS = 2e3;
36565
36882
  function normalizeAgentStatus(value) {
36566
36883
  return typeof value === "string" ? value.trim().toLowerCase() : "";
@@ -41425,6 +41742,7 @@ function getAvailableIdeIds() {
41425
41742
  init_config();
41426
41743
  init_cli_detector();
41427
41744
  init_git_status();
41745
+ init_change_impact_config();
41428
41746
  init_dist();
41429
41747
  init_logger();
41430
41748
 
@@ -41574,7 +41892,7 @@ cleanOldFiles();
41574
41892
 
41575
41893
  // src/commands/router.ts
41576
41894
  init_logger();
41577
- import * as yaml3 from "js-yaml";
41895
+ import * as yaml4 from "js-yaml";
41578
41896
 
41579
41897
  // src/logging/log-tail-reader.ts
41580
41898
  init_logger();
@@ -41875,7 +42193,7 @@ function orderMeshRefineBatchNodes(changeAreas) {
41875
42193
 
41876
42194
  // src/mesh/preview-freshness.ts
41877
42195
  import { execFileSync as execFileSync4 } from "child_process";
41878
- import { existsSync as existsSync35, readFileSync as readFileSync26 } from "fs";
42196
+ import { existsSync as existsSync36, readFileSync as readFileSync27 } from "fs";
41879
42197
  import { resolve as resolve19 } from "path";
41880
42198
  var PREVIEW_DEPLOY_RECORD = ".adhdev/preview-deploy.json";
41881
42199
  function runGit2(repoRoot, args) {
@@ -41892,9 +42210,9 @@ function runGit2(repoRoot, args) {
41892
42210
  }
41893
42211
  function readRecord6(repoRoot) {
41894
42212
  const path42 = resolve19(repoRoot, PREVIEW_DEPLOY_RECORD);
41895
- if (!existsSync35(path42)) return null;
42213
+ if (!existsSync36(path42)) return null;
41896
42214
  try {
41897
- const parsed = JSON.parse(readFileSync26(path42, "utf8"));
42215
+ const parsed = JSON.parse(readFileSync27(path42, "utf8"));
41898
42216
  return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
41899
42217
  } catch {
41900
42218
  return null;
@@ -41959,8 +42277,8 @@ function buildPreviewFreshness(repoRoot) {
41959
42277
  init_mesh_refine_status();
41960
42278
 
41961
42279
  // src/mesh/mesh-init.ts
41962
- import { existsSync as existsSync36, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
41963
- import { dirname as dirname10, join as join39 } from "path";
42280
+ import { existsSync as existsSync37, mkdirSync as mkdirSync15, writeFileSync as writeFileSync17 } from "fs";
42281
+ import { dirname as dirname10, join as join40 } from "path";
41964
42282
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
41965
42283
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
41966
42284
  var CANDIDATE_STALE_INPUTS = [
@@ -41974,7 +42292,7 @@ var CANDIDATE_STALE_INPUTS = [
41974
42292
  "requirements.txt"
41975
42293
  ];
41976
42294
  function writeConfigFile(workspace, relativePath, config) {
41977
- const target = join39(workspace, relativePath);
42295
+ const target = join40(workspace, relativePath);
41978
42296
  mkdirSync15(dirname10(target), { recursive: true });
41979
42297
  writeFileSync17(target, `${JSON.stringify(config, null, 2)}
41980
42298
  `, "utf-8");
@@ -41982,14 +42300,14 @@ function writeConfigFile(workspace, relativePath, config) {
41982
42300
  }
41983
42301
  function suggestMeshWorktreeBootstrapConfig(workspace) {
41984
42302
  const commands = [];
41985
- const hasPackageJson = existsSync36(join39(workspace, "package.json"));
41986
- const hasNpmLock = existsSync36(join39(workspace, "package-lock.json"));
42303
+ const hasPackageJson = existsSync37(join40(workspace, "package.json"));
42304
+ const hasNpmLock = existsSync37(join40(workspace, "package-lock.json"));
41987
42305
  if (hasPackageJson) {
41988
42306
  commands.push(
41989
42307
  hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
41990
42308
  );
41991
42309
  }
41992
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync36(join39(workspace, relative5)));
42310
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync37(join40(workspace, relative5)));
41993
42311
  if (!commands.length) {
41994
42312
  return { commands, staleInputs };
41995
42313
  }
@@ -42057,7 +42375,7 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
42057
42375
  }
42058
42376
  function applyConfigSuggestion(input) {
42059
42377
  const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
42060
- const absolute = join39(workspace, relativePath);
42378
+ const absolute = join40(workspace, relativePath);
42061
42379
  if (existing !== void 0 && !overwrite) {
42062
42380
  return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
42063
42381
  }
@@ -44856,7 +45174,7 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
44856
45174
  return summary;
44857
45175
  }
44858
45176
  function loadYamlModule() {
44859
- return yaml3;
45177
+ return yaml4;
44860
45178
  }
44861
45179
  function getMcpServersKey(format) {
44862
45180
  return format === "hermes_config_yaml" ? "mcp_servers" : "mcpServers";
@@ -48598,6 +48916,42 @@ ${hintLines.join("\n")}` : "",
48598
48916
  note: "Suggestions are heuristic scaffold only; Refinery will not execute them until saved into repo mesh/refine config."
48599
48917
  };
48600
48918
  }
48919
+ case "get_mesh_change_impact_config_schema": {
48920
+ return {
48921
+ success: true,
48922
+ schema: CHANGE_IMPACT_CONFIG_SCHEMA,
48923
+ locations: CHANGE_IMPACT_CONFIG_LOCATIONS,
48924
+ sourceOfTruth: "repo change-impact config",
48925
+ heuristicRole: "suggestions_only_not_execution_path",
48926
+ 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."
48927
+ };
48928
+ }
48929
+ case "validate_mesh_change_impact_config": {
48930
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
48931
+ if (args?.config !== void 0) {
48932
+ const validation = validateChangeImpactConfig(args.config, "inline");
48933
+ return { success: validation.valid, source: "inline", sourceType: "mesh_policy", ...validation };
48934
+ }
48935
+ const loaded = loadChangeImpactConfig(workspace);
48936
+ if (loaded.sourceType === "repo_file") {
48937
+ const validation = validateChangeImpactConfig(loaded.config, loaded.source);
48938
+ return { success: validation.valid, ...loaded, ...validation };
48939
+ }
48940
+ return {
48941
+ success: false,
48942
+ ...loaded,
48943
+ valid: false,
48944
+ errors: [loaded.error || "repo change-impact config unavailable"]
48945
+ };
48946
+ }
48947
+ case "suggest_mesh_change_impact_config": {
48948
+ const workspace = typeof args?.workspace === "string" ? args.workspace : process.cwd();
48949
+ return {
48950
+ success: true,
48951
+ ...suggestChangeImpactConfig(workspace),
48952
+ 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."
48953
+ };
48954
+ }
48601
48955
  case "mesh_init": {
48602
48956
  const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
48603
48957
  const mesh = args?.inlineMesh || {};
@@ -49514,7 +49868,7 @@ ${ptyResult.output.slice(-2e3)}`);
49514
49868
  workspace
49515
49869
  };
49516
49870
  }
49517
- const { existsSync: existsSync45, readFileSync: readFileSync36, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
49871
+ const { existsSync: existsSync46, readFileSync: readFileSync37, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
49518
49872
  const { dirname: dirname17 } = await import("path");
49519
49873
  const mcpConfigPath = coordinatorSetup.configPath;
49520
49874
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -49557,14 +49911,14 @@ ${ptyResult.output.slice(-2e3)}`);
49557
49911
  if (hermesManualFallback) return returnManualFallback(message);
49558
49912
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
49559
49913
  }
49560
- const hadExistingMcpConfig = existsSync45(mcpConfigPath);
49914
+ const hadExistingMcpConfig = existsSync46(mcpConfigPath);
49561
49915
  let existingMcpConfig = hermesBaseConfig?.config || {};
49562
49916
  if (hermesBaseConfig) {
49563
49917
  copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname17(mcpConfigPath));
49564
49918
  }
49565
49919
  if (hadExistingMcpConfig) {
49566
49920
  try {
49567
- const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync36(mcpConfigPath, "utf-8"), configFormat);
49921
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync37(mcpConfigPath, "utf-8"), configFormat);
49568
49922
  const existingCoordinatorConfig = hermesManualFallback ? stripHermesCoordinatorTempModelProviderOverrides(parsedExistingMcpConfig) : parsedExistingMcpConfig;
49569
49923
  existingMcpConfig = { ...existingMcpConfig, ...existingCoordinatorConfig };
49570
49924
  copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
@@ -50063,7 +50417,7 @@ ${ptyResult.output.slice(-2e3)}`);
50063
50417
  const { deriveMeshReviewInboxItems: deriveMeshReviewInboxItems2 } = await Promise.resolve().then(() => (init_mesh_review_inbox(), mesh_review_inbox_exports));
50064
50418
  const { readLedgerEntries: readLedgerEntries2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
50065
50419
  const { getGitDiffSummary: getGitDiffSummary2 } = await Promise.resolve().then(() => (init_git_diff(), git_diff_exports));
50066
- const { existsSync: existsSync45 } = await import("fs");
50420
+ const { existsSync: existsSync46 } = await import("fs");
50067
50421
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
50068
50422
  const mesh = meshRecord?.mesh;
50069
50423
  if (!mesh) return { success: false, error: "Mesh not found" };
@@ -50082,7 +50436,7 @@ ${ptyResult.output.slice(-2e3)}`);
50082
50436
  const derivation = deriveMeshReviewInboxItems2({ nodes: nodeStatuses, ledgerEntries });
50083
50437
  for (const item of derivation.items) {
50084
50438
  const workspace = item.workspace;
50085
- if (!workspace || !existsSync45(workspace)) continue;
50439
+ if (!workspace || !existsSync46(workspace)) continue;
50086
50440
  const baseRef = item.defaultBranch ? `origin/${item.defaultBranch}` : "origin/main";
50087
50441
  try {
50088
50442
  const diffResult = await getGitDiffSummary2(workspace, { baseRef, maxFiles: 100 });
@@ -50256,7 +50610,7 @@ var DaemonStatusReporter = class {
50256
50610
  case "agent:waiting_approval":
50257
50611
  case "agent:generating_completed":
50258
50612
  case "agent:stopped":
50259
- case "monitor:long_generating":
50613
+ case "monitor:no_progress":
50260
50614
  return value;
50261
50615
  default:
50262
50616
  return null;
@@ -50801,7 +51155,7 @@ var ProviderStreamAdapter = class {
50801
51155
  }
50802
51156
  const validated = validateReadChatResultPayload(data, `${this.agentType} readChat`);
50803
51157
  const validatedStatus = validated.status;
50804
- const streamStatus = validatedStatus === "generating" || validatedStatus === "long_generating" ? "streaming" : validatedStatus;
51158
+ const streamStatus = validatedStatus === "generating" || validatedStatus === "no_progress" || validatedStatus === "long_generating" ? "streaming" : validatedStatus;
50805
51159
  const state = {
50806
51160
  agentType: this.agentType,
50807
51161
  agentName: this.agentName,
@@ -58641,12 +58995,12 @@ init_parse_session();
58641
58995
 
58642
58996
  // src/providers/sdk/v1/fixture-tooling/replay.ts
58643
58997
  init_provider_cli_shared();
58644
- import { readFileSync as readFileSync34 } from "fs";
58998
+ import { readFileSync as readFileSync35 } from "fs";
58645
58999
  import { dirname as dirname15, resolve as resolve22 } from "path";
58646
59000
 
58647
59001
  // src/providers/sdk/v1/validators/taint.ts
58648
- import { readFileSync as readFileSync35, existsSync as existsSync44 } from "fs";
58649
- import { resolve as resolve23, dirname as dirname16, join as join46 } from "path";
59002
+ import { readFileSync as readFileSync36, existsSync as existsSync45 } from "fs";
59003
+ import { resolve as resolve23, dirname as dirname16, join as join47 } from "path";
58650
59004
 
58651
59005
  // src/providers/sdk/v1/validators/index.ts
58652
59006
  init_manifest();
@@ -58726,6 +59080,8 @@ export {
58726
59080
  AcpProviderInstance,
58727
59081
  AgentStreamPoller,
58728
59082
  BUILTIN_CHAT_MESSAGE_KINDS,
59083
+ CHANGE_IMPACT_CONFIG_LOCATIONS,
59084
+ CHANGE_IMPACT_CONFIG_SCHEMA,
58729
59085
  CHAT_MESSAGE_ACTIVITY_SOURCES,
58730
59086
  CHAT_MESSAGE_AUDIENCES,
58731
59087
  CHAT_MESSAGE_INTERNAL_SOURCES,
@@ -58916,6 +59272,7 @@ export {
58916
59272
  getSessionHostSurfaceKind,
58917
59273
  getSessionRecoveryContext,
58918
59274
  getWorkspaceState,
59275
+ globToRegExp,
58919
59276
  handleGitCommand,
58920
59277
  hasCdpManager,
58921
59278
  hasPendingDependents,
@@ -58949,6 +59306,7 @@ export {
58949
59306
  listMeshMissionSummaries,
58950
59307
  listMeshes,
58951
59308
  listWorktrees,
59309
+ loadChangeImpactConfig,
58952
59310
  loadConfig,
58953
59311
  loadMeshCoordinatorRegistry,
58954
59312
  loadMeshRefineConfig,
@@ -59043,6 +59401,7 @@ export {
59043
59401
  spawnDetachedDaemonUpgradeHelper,
59044
59402
  startDaemonDevSupport,
59045
59403
  startLocalIpcServer,
59404
+ suggestChangeImpactConfig,
59046
59405
  suggestMeshRefineConfig,
59047
59406
  summarizeGitStatus,
59048
59407
  summarizeMeshAsyncRefineJobs,
@@ -59059,6 +59418,7 @@ export {
59059
59418
  updateTaskStatus,
59060
59419
  upsertMeshMission,
59061
59420
  upsertSavedProviderSession,
59421
+ validateChangeImpactConfig,
59062
59422
  validateCliProviderManifest,
59063
59423
  validateFsmSpec,
59064
59424
  validateMeshRefineConfig,