@adhdev/daemon-core 0.9.82-rc.510 → 0.9.82-rc.511

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
@@ -412,10 +412,10 @@ function readInjected(value) {
412
412
  }
413
413
  function getDaemonBuildInfo() {
414
414
  if (cached) return cached;
415
- const commit = readInjected(true ? "9e16d8626cae0095e7ccc7dbea08afcd9505473a" : void 0) ?? "unknown";
416
- const commitShort = readInjected(true ? "9e16d862" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
417
- const version = readInjected(true ? "0.9.82-rc.510" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
418
- const builtAt = readInjected(true ? "2026-07-13T03:02:22.024Z" : void 0);
415
+ const commit = readInjected(true ? "a03f7d21a28e2337a5b4520ff313ca69d776691d" : void 0) ?? "unknown";
416
+ const commitShort = readInjected(true ? "a03f7d21" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
417
+ const version = readInjected(true ? "0.9.82-rc.511" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
418
+ const builtAt = readInjected(true ? "2026-07-13T05:19:31.486Z" : void 0);
419
419
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
420
420
  return cached;
421
421
  }
@@ -668,6 +668,7 @@ var init_change_impact_config = __esm({
668
668
  });
669
669
 
670
670
  // src/git/git-status.ts
671
+ import { join as join2 } from "path";
671
672
  function statusCacheKey(workspace, options) {
672
673
  const includeSubmodules = options.includeSubmodules !== false;
673
674
  const refreshUpstream = options.refreshUpstream === true;
@@ -789,21 +790,21 @@ function isNonRuntimeRootFile(file, policy) {
789
790
  }
790
791
  function classifyChangedFileList(files, policy) {
791
792
  if (files.length === 0) {
792
- return { isDaemonAffecting: true, affectedPackages: [] };
793
+ return { isDaemonAffecting: true, affectedPackages: [], ambiguousNonPackageFiles: [] };
793
794
  }
794
795
  const pkgs = /* @__PURE__ */ new Set();
795
- let sawRuntimeAmbiguousNonPackage = false;
796
+ const ambiguousNonPackageFiles = [];
796
797
  for (const file of files) {
797
798
  const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
798
799
  if (!match) {
799
- if (!isNonRuntimeRootFile(file, policy)) sawRuntimeAmbiguousNonPackage = true;
800
+ if (!isNonRuntimeRootFile(file, policy)) ambiguousNonPackageFiles.push(file);
800
801
  continue;
801
802
  }
802
803
  pkgs.add(match[1]);
803
804
  }
804
805
  const affectedPackages = [...pkgs].sort();
805
- const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
806
- return { isDaemonAffecting: !allBenign, affectedPackages };
806
+ const allBenign = ambiguousNonPackageFiles.length === 0 && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
807
+ return { isDaemonAffecting: !allBenign, affectedPackages, ambiguousNonPackageFiles };
807
808
  }
808
809
  async function classifyDaemonBuildChange(repoPath, buildCommit, options, policy) {
809
810
  try {
@@ -820,7 +821,82 @@ async function classifyChangedPackages(repoPath, fromRef, toRef, options = {}) {
820
821
  const policy = resolveChangeImpactPolicy(config);
821
822
  const diff = await runGit(repoPath, ["diff", "--name-only", `${fromRef}..${toRef}`], options);
822
823
  const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
823
- return classifyChangedFileList(files, policy);
824
+ const rootVerdict = classifyChangedFileList(files, policy);
825
+ return refineVerdictThroughSubmodules(repoPath, fromRef, toRef, options, policy, rootVerdict);
826
+ }
827
+ async function refineVerdictThroughSubmodules(repoPath, fromRef, toRef, options, policy, rootVerdict) {
828
+ const strip = ({ isDaemonAffecting, affectedPackages }) => ({ isDaemonAffecting, affectedPackages });
829
+ const ambiguous = rootVerdict.ambiguousNonPackageFiles;
830
+ if (ambiguous.length === 0) return strip(rootVerdict);
831
+ let submodulePaths;
832
+ try {
833
+ submodulePaths = await listSubmodulePaths(repoPath, options);
834
+ } catch {
835
+ return strip(rootVerdict);
836
+ }
837
+ if (ambiguous.length === 0 || !ambiguous.every((f) => submodulePaths.has(f))) {
838
+ return strip(rootVerdict);
839
+ }
840
+ const submoduleAffectedPackages = [];
841
+ for (const subPath of ambiguous) {
842
+ let range;
843
+ try {
844
+ range = await resolveSubmoduleGitlinkRange(repoPath, fromRef, toRef, subPath, options);
845
+ } catch {
846
+ return strip(rootVerdict);
847
+ }
848
+ let subVerdict;
849
+ try {
850
+ subVerdict = await classifyChangedPackages(join2(repoPath, subPath), range.from, range.to, {
851
+ ...options,
852
+ // Do not force the root's injected config onto the submodule — let it resolve
853
+ // its own .adhdev/change-impact.* (or fall back to defaults).
854
+ changeImpactConfig: void 0
855
+ });
856
+ } catch {
857
+ return strip(rootVerdict);
858
+ }
859
+ if (subVerdict.isDaemonAffecting) {
860
+ return {
861
+ isDaemonAffecting: true,
862
+ affectedPackages: [.../* @__PURE__ */ new Set([...rootVerdict.affectedPackages, ...subVerdict.affectedPackages])].sort()
863
+ };
864
+ }
865
+ submoduleAffectedPackages.push(...subVerdict.affectedPackages);
866
+ }
867
+ const rootPackagesBenign = rootVerdict.affectedPackages.every(
868
+ (p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p)
869
+ );
870
+ return {
871
+ isDaemonAffecting: !rootPackagesBenign,
872
+ affectedPackages: [.../* @__PURE__ */ new Set([...rootVerdict.affectedPackages, ...submoduleAffectedPackages])].sort()
873
+ };
874
+ }
875
+ async function listSubmodulePaths(repoPath, options) {
876
+ const res = await runGit(repoPath, ["config", "-f", ".gitmodules", "--get-regexp", "path"], options);
877
+ const paths = /* @__PURE__ */ new Set();
878
+ for (const line of res.stdout.split("\n")) {
879
+ const trimmed = line.trim();
880
+ if (!trimmed) continue;
881
+ const idx = trimmed.indexOf(" ");
882
+ if (idx === -1) continue;
883
+ const p = trimmed.slice(idx + 1).trim();
884
+ if (p) paths.add(p);
885
+ }
886
+ return paths;
887
+ }
888
+ async function resolveSubmoduleGitlinkRange(repoPath, fromRef, toRef, subPath, options) {
889
+ const res = await runGit(repoPath, ["diff", `${fromRef}..${toRef}`, "--", subPath], options);
890
+ let from = "";
891
+ let to = "";
892
+ for (const line of res.stdout.split("\n")) {
893
+ const m = line.match(/^([+-])Subproject commit ([0-9a-f]{7,40})/);
894
+ if (!m) continue;
895
+ if (m[1] === "-") from = m[2];
896
+ else to = m[2];
897
+ }
898
+ if (!from || !to) throw new Error(`no gitlink range for submodule ${subPath}`);
899
+ return { from, to };
824
900
  }
825
901
  function resolveChangeImpactConfigForRepo(repoRoot, options) {
826
902
  if (options.changeImpactConfig === null) {
@@ -1532,7 +1608,7 @@ __export(config_exports, {
1532
1608
  updateConfig: () => updateConfig
1533
1609
  });
1534
1610
  import { homedir } from "os";
1535
- import { join as join2 } from "path";
1611
+ import { join as join3 } from "path";
1536
1612
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync, chmodSync } from "fs";
1537
1613
  import { randomUUID } from "crypto";
1538
1614
  function resolveProviderSourceMode(providerSourceMode, legacyDisableUpstream) {
@@ -1630,24 +1706,24 @@ function ensureMachineId(config) {
1630
1706
  }
1631
1707
  function getConfigDir() {
1632
1708
  const override = process.env.ADHDEV_CONFIG_DIR;
1633
- const dir = override && override.trim() ? override.trim() : join2(homedir(), ".adhdev");
1709
+ const dir = override && override.trim() ? override.trim() : join3(homedir(), ".adhdev");
1634
1710
  if (!existsSync2(dir)) {
1635
1711
  mkdirSync(dir, { recursive: true });
1636
1712
  }
1637
1713
  return dir;
1638
1714
  }
1639
1715
  function getDaemonDataDir() {
1640
- const dir = join2(getConfigDir(), "daemon");
1716
+ const dir = join3(getConfigDir(), "daemon");
1641
1717
  if (!existsSync2(dir)) {
1642
1718
  mkdirSync(dir, { recursive: true });
1643
1719
  }
1644
1720
  return dir;
1645
1721
  }
1646
1722
  function getConfigPath() {
1647
- return join2(getConfigDir(), "config.json");
1723
+ return join3(getConfigDir(), "config.json");
1648
1724
  }
1649
1725
  function migrateStateToStateFile(raw) {
1650
- const statePath = join2(getConfigDir(), "state.json");
1726
+ const statePath = join3(getConfigDir(), "state.json");
1651
1727
  if (existsSync2(statePath)) return;
1652
1728
  const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1653
1729
  const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
@@ -3048,10 +3124,10 @@ __export(mesh_config_exports, {
3048
3124
  updateNode: () => updateNode
3049
3125
  });
3050
3126
  import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
3051
- import { join as join5 } from "path";
3127
+ import { join as join6 } from "path";
3052
3128
  import { randomBytes, randomUUID as randomUUID3 } from "crypto";
3053
3129
  function getMeshConfigPath() {
3054
- return join5(getConfigDir(), "meshes.json");
3130
+ return join6(getConfigDir(), "meshes.json");
3055
3131
  }
3056
3132
  function loadMeshConfig() {
3057
3133
  const path45 = getMeshConfigPath();
@@ -4631,7 +4707,7 @@ __export(mesh_ledger_exports, {
4631
4707
  tombstoneOperatingNote: () => tombstoneOperatingNote
4632
4708
  });
4633
4709
  import { appendFileSync, existsSync as existsSync7, mkdirSync as mkdirSync4, readFileSync as readFileSync5, statSync as statSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
4634
- import { join as join8 } from "path";
4710
+ import { join as join9 } from "path";
4635
4711
  import { randomUUID as randomUUID4 } from "crypto";
4636
4712
  import { EventEmitter } from "events";
4637
4713
  function isIntentionalCleanupStopEntry(entry) {
@@ -4640,7 +4716,7 @@ function isIntentionalCleanupStopEntry(entry) {
4640
4716
  return payload.intentional === true && (payload.reason === "operator_cleanup" || payload.intentionalStopReason === "operator_cleanup" || payload.source === "mesh_cleanup_sessions" || payload.source === "mesh_remove_node");
4641
4717
  }
4642
4718
  function getLedgerDir() {
4643
- const dir = join8(getConfigDir(), LEDGER_DIR_NAME);
4719
+ const dir = join9(getConfigDir(), LEDGER_DIR_NAME);
4644
4720
  if (!existsSync7(dir)) {
4645
4721
  mkdirSync4(dir, { recursive: true, mode: 448 });
4646
4722
  }
@@ -4648,23 +4724,23 @@ function getLedgerDir() {
4648
4724
  }
4649
4725
  function getLedgerPath(meshId) {
4650
4726
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
4651
- return join8(getLedgerDir(), `${safe}.jsonl`);
4727
+ return join9(getLedgerDir(), `${safe}.jsonl`);
4652
4728
  }
4653
4729
  function getRotatedPath(meshId, index) {
4654
4730
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
4655
- return join8(getLedgerDir(), `${safe}.${index}.jsonl`);
4731
+ return join9(getLedgerDir(), `${safe}.${index}.jsonl`);
4656
4732
  }
4657
4733
  function getArchivePath(meshId) {
4658
4734
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
4659
- return join8(getLedgerDir(), `${safe}.archive.jsonl`);
4735
+ return join9(getLedgerDir(), `${safe}.archive.jsonl`);
4660
4736
  }
4661
4737
  function getRotatedArchivePath(meshId, index) {
4662
4738
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
4663
- return join8(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
4739
+ return join9(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
4664
4740
  }
4665
4741
  function getArchivedCountsPath(meshId) {
4666
4742
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
4667
- return join8(getLedgerDir(), `${safe}.archived-counts.json`);
4743
+ return join9(getLedgerDir(), `${safe}.archived-counts.json`);
4668
4744
  }
4669
4745
  function rotateArchiveFile(meshId, archivePath) {
4670
4746
  let index = 1;
@@ -6508,7 +6584,7 @@ var init_mesh_work_queue = __esm({
6508
6584
 
6509
6585
  // src/mesh/mesh-runtime-store.ts
6510
6586
  import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, statSync as statSync5, unlinkSync as unlinkSync2 } from "fs";
6511
- import { dirname as dirname2, join as join9 } from "path";
6587
+ import { dirname as dirname2, join as join10 } from "path";
6512
6588
  function loadDatabaseCtor() {
6513
6589
  if (DatabaseCtor) return DatabaseCtor;
6514
6590
  DatabaseCtor = loadBetterSqlite3();
@@ -6518,11 +6594,11 @@ function safeMeshId(meshId) {
6518
6594
  return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
6519
6595
  }
6520
6596
  function legacyQueuePath(meshId) {
6521
- return join9(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
6597
+ return join10(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
6522
6598
  }
6523
6599
  function cleanupStrayRootRuntimeDb(canonicalPath) {
6524
6600
  try {
6525
- const strayPath = join9(getConfigDir(), "mesh-runtime.db");
6601
+ const strayPath = join10(getConfigDir(), "mesh-runtime.db");
6526
6602
  if (strayPath === canonicalPath) return;
6527
6603
  if (!existsSync8(strayPath)) return;
6528
6604
  if (statSync5(strayPath).size !== 0) return;
@@ -6540,10 +6616,10 @@ function cleanupStrayRootRuntimeDb(canonicalPath) {
6540
6616
  }
6541
6617
  function meshRuntimeStorePath() {
6542
6618
  const dir = getLedgerDir();
6543
- const nextPath = join9(dir, "mesh-runtime.db");
6619
+ const nextPath = join10(dir, "mesh-runtime.db");
6544
6620
  cleanupStrayRootRuntimeDb(nextPath);
6545
6621
  if (existsSync8(nextPath)) return nextPath;
6546
- const legacyPath = join9(dir, "beads.db");
6622
+ const legacyPath = join10(dir, "beads.db");
6547
6623
  if (!existsSync8(legacyPath)) return nextPath;
6548
6624
  try {
6549
6625
  renameSync3(legacyPath, nextPath);
@@ -8656,7 +8732,7 @@ var init_mesh_events_utils = __esm({
8656
8732
 
8657
8733
  // src/mesh/mesh-events-pending.ts
8658
8734
  import { appendFileSync as appendFileSync2, existsSync as existsSync9, readFileSync as readFileSync7, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync4 } from "fs";
8659
- import { join as join10 } from "path";
8735
+ import { join as join11 } from "path";
8660
8736
  import { randomUUID as randomUUID7 } from "crypto";
8661
8737
  function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
8662
8738
  return expandDaemonIdForms(coordinatorDaemonId);
@@ -8879,9 +8955,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
8879
8955
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
8880
8956
  if (coordinatorDaemonId) {
8881
8957
  const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
8882
- return join10(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
8958
+ return join11(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
8883
8959
  }
8884
- return join10(getLedgerDir(), `${safe}.pending-events.jsonl`);
8960
+ return join11(getLedgerDir(), `${safe}.pending-events.jsonl`);
8885
8961
  }
8886
8962
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
8887
8963
  if (!meshId) return [];
@@ -10158,7 +10234,7 @@ __export(mesh_coordinator_exports, {
10158
10234
  import { existsSync as existsSync10, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
10159
10235
  import * as os4 from "os";
10160
10236
  import { DEFAULT_SESSION_HOST_COLS, DEFAULT_SESSION_HOST_ROWS } from "@adhdev/session-host-core";
10161
- import { basename as basename2, isAbsolute as isAbsolute4, join as join11, resolve as resolve7 } from "path";
10237
+ import { basename as basename2, isAbsolute as isAbsolute4, join as join12, resolve as resolve7 } from "path";
10162
10238
  function isHermesProvider(provider, cliType) {
10163
10239
  const type = cliType?.trim() || provider?.type?.trim() || "";
10164
10240
  return type === HERMES_CLI_TYPE;
@@ -10178,7 +10254,7 @@ function resolveHermesMeshCoordinatorSetup(options) {
10178
10254
  reason: "Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode"
10179
10255
  };
10180
10256
  }
10181
- const configPath = join11(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
10257
+ const configPath = join12(resolveHermesCoordinatorHome(options.meshId, options.workspace), "config.yaml");
10182
10258
  if (!configPath.trim()) {
10183
10259
  return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace);
10184
10260
  }
@@ -10325,14 +10401,14 @@ function resolveHermesCoordinatorHome(meshId, workspace) {
10325
10401
  const key2 = `${meshId || "mesh"}
10326
10402
  ${resolve7(workspace || os4.tmpdir())}`;
10327
10403
  const hash = shortHash(key2);
10328
- return join11(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
10404
+ return join12(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
10329
10405
  }
10330
10406
  function resolveMcpConfigPath(configPath, workspace) {
10331
10407
  const trimmed = configPath.trim();
10332
10408
  if (trimmed === "~") return os4.homedir();
10333
- if (trimmed.startsWith("~/")) return join11(os4.homedir(), trimmed.slice(2));
10409
+ if (trimmed.startsWith("~/")) return join12(os4.homedir(), trimmed.slice(2));
10334
10410
  if (isAbsolute4(trimmed)) return trimmed;
10335
- return join11(workspace, trimmed);
10411
+ return join12(workspace, trimmed);
10336
10412
  }
10337
10413
  function resolveAdhdevMcpServerLaunch(options) {
10338
10414
  const directEntryPath = resolveAdhdevMcpEntryPath(options.adhdevMcpEntryPath);
@@ -10403,7 +10479,7 @@ function applyInjectionRule(systemPrompt, injection, ctx) {
10403
10479
  }
10404
10480
  case "context_file": {
10405
10481
  if (!injection.path) return {};
10406
- const target = isAbsolute4(injection.path) ? injection.path : join11(ctx.workspace, injection.path);
10482
+ const target = isAbsolute4(injection.path) ? injection.path : join12(ctx.workspace, injection.path);
10407
10483
  const wrapper = injection.wrapper && injection.wrapper.includes("{prompt}") ? injection.wrapper : "{prompt}";
10408
10484
  const managedNote = "> _Managed by adhdev mesh coordinator \u2014 do not hand-edit this block. Changes inside the sentinels are overwritten on next coordinator launch._";
10409
10485
  const promptWithNote = `${managedNote}
@@ -10547,10 +10623,10 @@ var init_mesh_coordinator = __esm({
10547
10623
  });
10548
10624
 
10549
10625
  // src/mesh/coordinator-registry.ts
10550
- import { join as join12 } from "path";
10626
+ import { join as join13 } from "path";
10551
10627
  import { existsSync as existsSync11, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
10552
10628
  function getRegistryPath() {
10553
- return join12(getDaemonDataDir(), "mesh-coordinators.json");
10629
+ return join13(getDaemonDataDir(), "mesh-coordinators.json");
10554
10630
  }
10555
10631
  function loadMeshCoordinatorRegistry() {
10556
10632
  const path45 = getRegistryPath();
@@ -10613,7 +10689,7 @@ var init_coordinator_registry = __esm({
10613
10689
 
10614
10690
  // src/mesh/refine-config.ts
10615
10691
  import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
10616
- import { join as join13 } from "path";
10692
+ import { join as join14 } from "path";
10617
10693
  import * as yaml2 from "js-yaml";
10618
10694
  function isMeshConfigRecord(value) {
10619
10695
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -10741,7 +10817,7 @@ function loadMeshRefineConfig(mesh, workspace) {
10741
10817
  return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
10742
10818
  }
10743
10819
  for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
10744
- const configPath = join13(workspace, relative5);
10820
+ const configPath = join14(workspace, relative5);
10745
10821
  if (!existsSync12(configPath)) continue;
10746
10822
  try {
10747
10823
  const parsed = parseConfigText2(configPath, readFileSync10(configPath, "utf-8"));
@@ -10760,7 +10836,7 @@ function loadMeshRefineConfig(mesh, workspace) {
10760
10836
  }
10761
10837
  function readPackageScripts(workspace) {
10762
10838
  try {
10763
- const parsed = JSON.parse(readFileSync10(join13(workspace, "package.json"), "utf-8"));
10839
+ const parsed = JSON.parse(readFileSync10(join14(workspace, "package.json"), "utf-8"));
10764
10840
  return isRecord2(parsed?.scripts) ? parsed.scripts : {};
10765
10841
  } catch {
10766
10842
  return {};
@@ -11035,7 +11111,7 @@ __export(worktree_bootstrap_config_exports, {
11035
11111
  validateMeshWorktreeBootstrapConfig: () => validateMeshWorktreeBootstrapConfig
11036
11112
  });
11037
11113
  import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
11038
- import { join as join15, resolve as pathResolve } from "path";
11114
+ import { join as join16, resolve as pathResolve } from "path";
11039
11115
  import { execFile as execFile3, execFileSync as execFileSync2 } from "child_process";
11040
11116
  import { createHash as createHash2 } from "crypto";
11041
11117
  import { promisify as promisify3 } from "util";
@@ -11217,7 +11293,7 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
11217
11293
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
11218
11294
  }
11219
11295
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
11220
- const configPath = join15(workspace, relative5);
11296
+ const configPath = join16(workspace, relative5);
11221
11297
  if (!existsSync14(configPath)) continue;
11222
11298
  try {
11223
11299
  const parsed = parseConfigText3(configPath, readFileSync11(configPath, "utf-8"));
@@ -11233,7 +11309,7 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
11233
11309
  function computeStaleInputsDigest(workspace, staleInputs) {
11234
11310
  const digest = {};
11235
11311
  for (const relative5 of staleInputs ?? []) {
11236
- const filePath = join15(workspace, relative5);
11312
+ const filePath = join16(workspace, relative5);
11237
11313
  try {
11238
11314
  digest[relative5] = createHash2("sha256").update(readFileSync11(filePath)).digest("hex");
11239
11315
  } catch {
@@ -11306,10 +11382,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
11306
11382
  staleInputs: loaded.config.staleInputs
11307
11383
  };
11308
11384
  const staleInputPaths = loaded.config.staleInputs ?? [];
11309
- const initiallyAbsent = staleInputPaths.filter((p) => !existsSync14(join15(workspace, p)));
11385
+ const initiallyAbsent = staleInputPaths.filter((p) => !existsSync14(join16(workspace, p)));
11310
11386
  for (const command of validation.commands) {
11311
11387
  if (initiallyAbsent.length > 0) {
11312
- const appearedNow = initiallyAbsent.filter((p) => existsSync14(join15(workspace, p)));
11388
+ const appearedNow = initiallyAbsent.filter((p) => existsSync14(join16(workspace, p)));
11313
11389
  if (appearedNow.length > 0) {
11314
11390
  state.status = "stale";
11315
11391
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -11446,7 +11522,7 @@ __export(mesh_json_config_exports, {
11446
11522
  serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold
11447
11523
  });
11448
11524
  import { existsSync as existsSync15, readFileSync as readFileSync12 } from "fs";
11449
- import { join as join16 } from "path";
11525
+ import { join as join17 } from "path";
11450
11526
  import * as yaml4 from "js-yaml";
11451
11527
  function isRecord3(value) {
11452
11528
  return !!value && typeof value === "object" && !Array.isArray(value);
@@ -11518,7 +11594,7 @@ function loadRepoMeshJsonConfig(workspace) {
11518
11594
  if (cwd && cwd !== ws) bases.push(cwd);
11519
11595
  for (const base of bases) {
11520
11596
  for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
11521
- const configPath = join16(base, relative5);
11597
+ const configPath = join17(base, relative5);
11522
11598
  if (!existsSync15(configPath)) continue;
11523
11599
  try {
11524
11600
  const parsed = parseConfigText4(configPath, readFileSync12(configPath, "utf-8"));
@@ -12748,14 +12824,19 @@ function maybeInjectIdleActiveMissionReminder(meshId, coordinator, policy, now =
12748
12824
  if (policy?.idleActiveMissionReminder === false) return false;
12749
12825
  const activeMissions = getMeshMissions(meshId, ["active"]);
12750
12826
  if (activeMissions.length === 0) return false;
12827
+ const ledgerEntries = readLedgerEntries(meshId, { tail: 200 });
12751
12828
  const summary = buildMeshActiveWork({
12752
12829
  meshId,
12753
12830
  queue: getQueue(meshId),
12754
12831
  directDispatches: getActiveDirectDispatches(meshId),
12755
- ledgerEntries: readLedgerEntries(meshId, { tail: 200 }),
12832
+ ledgerEntries,
12756
12833
  now
12757
12834
  }).summary;
12758
12835
  if (summary.totalActiveCount !== 0 || summary.generatingCount !== 0) return false;
12836
+ const activeRefineJobs = summarizeMeshAsyncRefineJobs(
12837
+ buildMeshAsyncRefineJobs({ meshId, ledgerEntries })
12838
+ ).activeJobs;
12839
+ if (activeRefineJobs.length > 0) return false;
12759
12840
  const store = MeshRuntimeStore.getInstance();
12760
12841
  const hash = missionSetHash(activeMissions);
12761
12842
  const last = store.getIdleReminderState(meshId);
@@ -12785,6 +12866,7 @@ var init_mesh_idle_reminder = __esm({
12785
12866
  init_mesh_work_queue();
12786
12867
  init_mesh_ledger();
12787
12868
  init_mesh_active_work();
12869
+ init_mesh_refine_status();
12788
12870
  IDLE_REMINDER_DEBOUNCE_MS = 3e5;
12789
12871
  MISSION_LIST_CAP = 10;
12790
12872
  }
@@ -17259,12 +17341,12 @@ var init_mesh_unresolved_forward_outbox = __esm({
17259
17341
 
17260
17342
  // src/config/state-store.ts
17261
17343
  import { existsSync as existsSync19, readFileSync as readFileSync13, writeFileSync as writeFileSync7 } from "fs";
17262
- import { join as join19 } from "path";
17344
+ import { join as join20 } from "path";
17263
17345
  function isPlainObject2(value) {
17264
17346
  return !!value && typeof value === "object" && !Array.isArray(value);
17265
17347
  }
17266
17348
  function getStatePath() {
17267
- return join19(getConfigDir(), "state.json");
17349
+ return join20(getConfigDir(), "state.json");
17268
17350
  }
17269
17351
  function normalizeState(raw) {
17270
17352
  const parsed = isPlainObject2(raw) ? raw : {};
@@ -19582,6 +19664,17 @@ var init_snapshot = __esm({
19582
19664
  });
19583
19665
 
19584
19666
  // src/mesh/mesh-event-forwarding.ts
19667
+ function bootstrapQueueTaskCountsAsHandled(task, bootstrapNodeId, nowMs) {
19668
+ if (!meshNodeIdMatches({ id: task.targetNodeId }, bootstrapNodeId)) return false;
19669
+ if (task.status === "assigned") return true;
19670
+ const al = task.autoLaunch;
19671
+ if (!al) return true;
19672
+ if (al.status === "started" || al.status === "completed") {
19673
+ const launchedAtMs = Date.parse(al.updatedAt);
19674
+ return Number.isFinite(launchedAtMs) && nowMs - launchedAtMs < AUTO_LAUNCH_AWAIT_CLAIM_MS;
19675
+ }
19676
+ return true;
19677
+ }
19585
19678
  function resolveCoordinatorDrainDaemonIds(components) {
19586
19679
  const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
19587
19680
  const machineId = readNonEmptyString2(loadConfig().machineId);
@@ -20295,7 +20388,8 @@ function injectMeshSystemMessage(components, args) {
20295
20388
  }
20296
20389
  if (args.event === "worktree_bootstrap_complete" && bootstrapNodeId) {
20297
20390
  try {
20298
- worktreeHasQueuedTask = getQueue(args.meshId, { status: ["pending", "assigned"] }).some((task) => meshNodeIdMatches({ id: task.targetNodeId }, bootstrapNodeId));
20391
+ const nowMs = Date.now();
20392
+ worktreeHasQueuedTask = getQueue(args.meshId, { status: ["pending", "assigned"] }).some((task) => bootstrapQueueTaskCountsAsHandled(task, bootstrapNodeId, nowMs));
20299
20393
  } catch (e) {
20300
20394
  LOG.warn("MeshQueue", `Failed to check queued task for ${bootstrapNodeId} (mesh ${args.meshId}): ${e?.message || e}`);
20301
20395
  }
@@ -42586,7 +42680,11 @@ var FsmDriver = class {
42586
42680
  if (!rule) return null;
42587
42681
  const hay = sectionText(sections, rule.section, fullScreen);
42588
42682
  const minCount = rule.min_count ?? 2;
42589
- const buttons = extractButtonsFromRule(rule, hay);
42683
+ let buttons = extractButtonsFromRule(rule, hay);
42684
+ if (buttons.length < minCount && rule.section) {
42685
+ const whole = extractButtonsFromRule(rule, fullScreen);
42686
+ if (whole.length >= minCount) buttons = whole;
42687
+ }
42590
42688
  if (buttons.length < minCount) return null;
42591
42689
  const title = this.deriveTitle(state, sections, fullScreen);
42592
42690
  return { title, buttons };
@@ -55686,11 +55784,11 @@ var meshCrudHandlers = {
55686
55784
  MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
55687
55785
  } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
55688
55786
  const { mkdirSync: mkdirSync22, writeFileSync: writeFileSync24 } = await import("fs");
55689
- const { dirname: dirname17, join: join51 } = await import("path");
55787
+ const { dirname: dirname17, join: join52 } = await import("path");
55690
55788
  const scaffold = buildMeshJsonConfigScaffold2(mesh);
55691
55789
  const scaffoldJson = serializeMeshJsonConfigScaffold2(scaffold);
55692
55790
  const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
55693
- const absolutePath = join51(workspace, relativePath);
55791
+ const absolutePath = join52(workspace, relativePath);
55694
55792
  const validation = normalizeRepoMeshDeclarativeConfig2(scaffold);
55695
55793
  if (!validation.valid) {
55696
55794
  return { success: false, meshId, error: `invalid mesh.json scaffold: ${validation.errors.join("; ")}` };
@@ -56760,7 +56858,7 @@ init_worktree_bootstrap_config();
56760
56858
  init_change_impact_config();
56761
56859
  init_mesh_config();
56762
56860
  import { existsSync as existsSync39, mkdirSync as mkdirSync15, writeFileSync as writeFileSync18 } from "fs";
56763
- import { dirname as dirname11, join as join42 } from "path";
56861
+ import { dirname as dirname11, join as join43 } from "path";
56764
56862
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
56765
56863
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
56766
56864
  var MESH_INIT_CHANGE_IMPACT_CONFIG_PATH = CHANGE_IMPACT_CONFIG_LOCATIONS[0];
@@ -56775,7 +56873,7 @@ var CANDIDATE_STALE_INPUTS = [
56775
56873
  "requirements.txt"
56776
56874
  ];
56777
56875
  function writeConfigFile(workspace, relativePath, config) {
56778
- const target = join42(workspace, relativePath);
56876
+ const target = join43(workspace, relativePath);
56779
56877
  mkdirSync15(dirname11(target), { recursive: true });
56780
56878
  writeFileSync18(target, `${JSON.stringify(config, null, 2)}
56781
56879
  `, "utf-8");
@@ -56783,14 +56881,14 @@ function writeConfigFile(workspace, relativePath, config) {
56783
56881
  }
56784
56882
  function suggestMeshWorktreeBootstrapConfig(workspace) {
56785
56883
  const commands = [];
56786
- const hasPackageJson = existsSync39(join42(workspace, "package.json"));
56787
- const hasNpmLock = existsSync39(join42(workspace, "package-lock.json"));
56884
+ const hasPackageJson = existsSync39(join43(workspace, "package.json"));
56885
+ const hasNpmLock = existsSync39(join43(workspace, "package-lock.json"));
56788
56886
  if (hasPackageJson) {
56789
56887
  commands.push(
56790
56888
  hasNpmLock ? { command: "npm", args: ["ci"] } : { command: "npm", args: ["install"] }
56791
56889
  );
56792
56890
  }
56793
- const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync39(join42(workspace, relative5)));
56891
+ const staleInputs = CANDIDATE_STALE_INPUTS.filter((relative5) => existsSync39(join43(workspace, relative5)));
56794
56892
  if (!commands.length) {
56795
56893
  return { commands, staleInputs };
56796
56894
  }
@@ -56889,7 +56987,7 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
56889
56987
  }
56890
56988
  function applyConfigSuggestion(input) {
56891
56989
  const { workspace, relativePath, existing, suggestedConfig, validate, write, overwrite } = input;
56892
- const absolute = join42(workspace, relativePath);
56990
+ const absolute = join43(workspace, relativePath);
56893
56991
  if (existing !== void 0 && !overwrite) {
56894
56992
  return { path: absolute, relativePath, written: false, skippedReason: "already_exists", config: existing };
56895
56993
  }
@@ -70789,7 +70887,7 @@ import { dirname as dirname15, resolve as resolve23 } from "path";
70789
70887
 
70790
70888
  // src/providers/sdk/v1/validators/taint.ts
70791
70889
  import { readFileSync as readFileSync41, existsSync as existsSync54 } from "fs";
70792
- import { resolve as resolve24, dirname as dirname16, join as join50 } from "path";
70890
+ import { resolve as resolve24, dirname as dirname16, join as join51 } from "path";
70793
70891
 
70794
70892
  // src/providers/sdk/v1/validators/index.ts
70795
70893
  init_manifest();