@adhdev/daemon-standalone 0.9.82-rc.407 → 0.9.82-rc.408

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30127,10 +30127,10 @@ var require_dist3 = __commonJS({
30127
30127
  }
30128
30128
  function getDaemonBuildInfo() {
30129
30129
  if (cached2) return cached2;
30130
- const commit = readInjected(true ? "bfd7d9b1d38a7d1f4709fbad2627c56b5a1ae342" : void 0) ?? "unknown";
30131
- const commitShort = readInjected(true ? "bfd7d9b1" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30132
- const version2 = readInjected(true ? "0.9.82-rc.407" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30133
- const builtAt = readInjected(true ? "2026-06-28T06:12:42.391Z" : void 0);
30130
+ const commit = readInjected(true ? "b6de7b335f9b6b6bfb202135c2ae017429182efa" : void 0) ?? "unknown";
30131
+ const commitShort = readInjected(true ? "b6de7b33" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30132
+ const version2 = readInjected(true ? "0.9.82-rc.408" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30133
+ const builtAt = readInjected(true ? "2026-06-28T07:54:01.430Z" : void 0);
30134
30134
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
30135
30135
  return cached2;
30136
30136
  }
@@ -30383,6 +30383,11 @@ var require_dist3 = __commonJS({
30383
30383
  };
30384
30384
  }
30385
30385
  });
30386
+ function statusCacheKey(workspace, options) {
30387
+ const includeSubmodules = options.includeSubmodules !== false;
30388
+ const refreshUpstream = options.refreshUpstream === true;
30389
+ return `${workspace}\0sub=${includeSubmodules ? 1 : 0}\0up=${refreshUpstream ? 1 : 0}`;
30390
+ }
30386
30391
  function isTransientGitFailure(error48) {
30387
30392
  return error48.reason === "timeout" || error48.reason === "git_command_failed";
30388
30393
  }
@@ -30390,15 +30395,22 @@ var require_dist3 = __commonJS({
30390
30395
  const lastCheckedAt = Date.now();
30391
30396
  const includeSubmodules = options.includeSubmodules !== false;
30392
30397
  const effectiveOptions = options.timeoutMs === void 0 ? { ...options, timeoutMs: GIT_STATUS_TIMEOUT_MS } : options;
30398
+ const cacheKey = statusCacheKey(workspace, options);
30399
+ if (!options.forceFresh) {
30400
+ const cached3 = lastKnownGoodStatus.get(cacheKey);
30401
+ if (cached3 && lastCheckedAt - cached3.cachedAt < GIT_STATUS_CACHE_TTL_MS) {
30402
+ return cached3.status;
30403
+ }
30404
+ }
30393
30405
  try {
30394
30406
  const repo = await resolveGitRepository(workspace, effectiveOptions);
30395
30407
  const status = await collectGitRepoStatus(repo, includeSubmodules, lastCheckedAt, effectiveOptions);
30396
- lastKnownGoodStatus.set(workspace, status);
30408
+ lastKnownGoodStatus.set(cacheKey, { status, cachedAt: lastCheckedAt });
30397
30409
  return status;
30398
30410
  } catch (error48) {
30399
30411
  const gitError = error48 instanceof GitCommandError ? error48 : new GitCommandError("git_command_failed", "Failed to read Git status", { cause: error48 });
30400
30412
  if (isTransientGitFailure(gitError)) {
30401
- const cached3 = lastKnownGoodStatus.get(workspace);
30413
+ const cached3 = lastKnownGoodStatus.get(cacheKey)?.status;
30402
30414
  if (cached3) {
30403
30415
  return {
30404
30416
  ...cached3,
@@ -30417,19 +30429,25 @@ var require_dist3 = __commonJS({
30417
30429
  let upstreamProbe = getInitialUpstreamProbe(parsed);
30418
30430
  if (options.refreshUpstream) {
30419
30431
  upstreamProbe = await refreshTrackedUpstream(repo, parsed, options);
30420
- if (upstreamProbe.upstreamStatus === "fresh") {
30432
+ if (upstreamProbe.upstreamStatus === "fresh" && upstreamProbe.didFetch) {
30421
30433
  parsed = await readPorcelainStatus(repo, options);
30422
30434
  }
30423
30435
  }
30424
30436
  const head = await readHead(repo, options);
30425
30437
  const stashCount = await readStashCount(repo, options);
30426
30438
  let submodules;
30439
+ let submoduleHeadOids = /* @__PURE__ */ new Map();
30427
30440
  if (includeSubmodules) {
30428
- submodules = await getSubmoduleStatuses(repo, options);
30441
+ const subResult = await getSubmoduleStatuses(repo, options);
30442
+ submodules = subResult.submodules;
30443
+ submoduleHeadOids = subResult.headOidByPath;
30429
30444
  }
30430
30445
  const submoduleDirty = (submodules || []).some((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error);
30431
30446
  const dirty = parsed.staged + parsed.modified + parsed.untracked + parsed.deleted + parsed.renamed > 0 || parsed.conflictFiles.length > 0 || stashCount > 0 || submoduleDirty;
30432
- const daemonBuildBehind = await detectDaemonBuildBehind(repo, submodules, options);
30447
+ const daemonBuildBehind = await detectDaemonBuildBehind(repo, submodules, options, {
30448
+ rootHeadOid: parsed.headOid,
30449
+ submoduleHeadOids
30450
+ });
30433
30451
  return {
30434
30452
  workspace: repo.workspace,
30435
30453
  repoRoot: repo.repoRoot,
@@ -30532,25 +30550,50 @@ var require_dist3 = __commonJS({
30532
30550
  changeImpactConfigCache.set(repoRoot, { sourceKey: loaded.sourceKey, config: config2 });
30533
30551
  return { config: config2, sourceKey: loaded.sourceKey };
30534
30552
  }
30535
- async function detectDaemonBuildBehind(repo, submodules, options) {
30553
+ async function detectDaemonBuildBehind(repo, submodules, options, headOids = { rootHeadOid: null, submoduleHeadOids: /* @__PURE__ */ new Map() }) {
30536
30554
  const build = options.daemonBuildInfo ?? getDaemonBuildInfo();
30537
30555
  if (!build.commit || build.commit === "unknown") return void 0;
30538
30556
  const { config: config2, sourceKey: configKey } = resolveChangeImpactConfigForRepo(repo.repoRoot, options);
30539
30557
  const policy = resolveChangeImpactPolicy(config2);
30540
30558
  const scopes = [
30541
- { scope: "root", repoPath: repo.repoRoot || repo.workspace }
30559
+ { scope: "root", repoPath: repo.repoRoot || repo.workspace, knownHeadOid: headOids.rootHeadOid }
30542
30560
  ];
30543
30561
  for (const sub of submodules || []) {
30544
- if (sub.repoPath && !sub.error) scopes.push({ scope: sub.path, repoPath: sub.repoPath });
30562
+ if (sub.repoPath && !sub.error) {
30563
+ scopes.push({ scope: sub.path, repoPath: sub.repoPath, knownHeadOid: headOids.submoduleHeadOids.get(sub.path) ?? null });
30564
+ }
30545
30565
  }
30546
- for (const { scope, repoPath } of scopes) {
30566
+ for (const { scope, repoPath, knownHeadOid } of scopes) {
30547
30567
  try {
30548
- await runGit(repoPath, ["cat-file", "-e", `${build.commit}^{commit}`], options);
30549
- const headResult = await runGit(repoPath, ["rev-parse", "HEAD"], options);
30550
- const head = headResult.stdout.trim();
30551
- if (!head || head === build.commit) continue;
30552
- await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
30568
+ let head = knownHeadOid;
30569
+ const ancestryKey = head ? `${repoPath}::${build.commit}::${head}` : null;
30570
+ if (ancestryKey) {
30571
+ const cachedVerdict = buildBehindAncestryCache.get(ancestryKey);
30572
+ if (cachedVerdict === false) continue;
30573
+ if (cachedVerdict === void 0) {
30574
+ if (head === build.commit) {
30575
+ buildBehindAncestryCache.set(ancestryKey, false);
30576
+ continue;
30577
+ }
30578
+ await runGit(repoPath, ["cat-file", "-e", `${build.commit}^{commit}`], options);
30579
+ try {
30580
+ await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
30581
+ } catch {
30582
+ buildBehindAncestryCache.set(ancestryKey, false);
30583
+ continue;
30584
+ }
30585
+ buildBehindAncestryCache.set(ancestryKey, true);
30586
+ }
30587
+ } else {
30588
+ await runGit(repoPath, ["cat-file", "-e", `${build.commit}^{commit}`], options);
30589
+ const headResult = await runGit(repoPath, ["rev-parse", "HEAD"], options);
30590
+ head = headResult.stdout.trim();
30591
+ if (!head || head === build.commit) continue;
30592
+ await runGit(repoPath, ["merge-base", "--is-ancestor", build.commit, "HEAD"], options);
30593
+ buildBehindAncestryCache.set(`${repoPath}::${build.commit}::${head}`, true);
30594
+ }
30553
30595
  const evalKey = `${repoPath}\0${build.commit}\0${head}\0${configKey}`;
30596
+ if (!head) continue;
30554
30597
  let evaluated = changeImpactEvalCache.get(evalKey);
30555
30598
  if (!evaluated) {
30556
30599
  evaluated = await classifyDaemonBuildChange(repoPath, build.commit, options, policy);
@@ -30592,6 +30635,15 @@ var require_dist3 = __commonJS({
30592
30635
  if (!parsed.upstream || !parsed.branch) {
30593
30636
  return { upstreamStatus: "no_upstream" };
30594
30637
  }
30638
+ const now = Date.now();
30639
+ const lastFetch = upstreamFetchedAt.get(repo.workspace);
30640
+ if (!options.forceFresh && lastFetch !== void 0 && now - lastFetch < GIT_FETCH_THROTTLE_MS) {
30641
+ return {
30642
+ upstreamStatus: "fresh",
30643
+ upstreamFetchedAt: lastFetch,
30644
+ didFetch: false
30645
+ };
30646
+ }
30595
30647
  const remoteName = await readBranchRemote(repo, parsed.branch, options) ?? inferRemoteName(parsed.upstream);
30596
30648
  if (!remoteName) {
30597
30649
  return {
@@ -30601,9 +30653,12 @@ var require_dist3 = __commonJS({
30601
30653
  }
30602
30654
  try {
30603
30655
  await runGit(repo, ["fetch", "--quiet", "--prune", "--no-tags", remoteName], options);
30656
+ const fetchedAt = Date.now();
30657
+ upstreamFetchedAt.set(repo.workspace, fetchedAt);
30604
30658
  return {
30605
30659
  upstreamStatus: "fresh",
30606
- upstreamFetchedAt: Date.now()
30660
+ upstreamFetchedAt: fetchedAt,
30661
+ didFetch: true
30607
30662
  };
30608
30663
  } catch (error48) {
30609
30664
  return {
@@ -30636,6 +30691,7 @@ var require_dist3 = __commonJS({
30636
30691
  function parsePorcelainV2Status(output) {
30637
30692
  const parsed = {
30638
30693
  branch: null,
30694
+ headOid: null,
30639
30695
  upstream: null,
30640
30696
  ahead: 0,
30641
30697
  behind: 0,
@@ -30648,6 +30704,11 @@ var require_dist3 = __commonJS({
30648
30704
  };
30649
30705
  for (const line of output.split("\n")) {
30650
30706
  if (!line) continue;
30707
+ if (line.startsWith("# branch.oid ")) {
30708
+ const oid = line.slice("# branch.oid ".length).trim();
30709
+ parsed.headOid = oid && oid !== "(initial)" && /^[0-9a-f]{7,64}$/.test(oid) ? oid : null;
30710
+ continue;
30711
+ }
30651
30712
  if (line.startsWith("# branch.head ")) {
30652
30713
  const branch = line.slice("# branch.head ".length).trim();
30653
30714
  parsed.branch = branch && branch !== "(detached)" ? branch : null;
@@ -30745,25 +30806,27 @@ var require_dist3 = __commonJS({
30745
30806
  };
30746
30807
  }
30747
30808
  async function getSubmoduleStatuses(repo, options) {
30748
- if (!repo.repoRoot) return [];
30809
+ if (!repo.repoRoot) return { submodules: [], headOidByPath: /* @__PURE__ */ new Map() };
30749
30810
  try {
30750
- const submodules = await deriveSubmoduleGitlinkStatuses(repo, options);
30811
+ const { submodules, headOidByPath } = await deriveSubmoduleGitlinkStatuses(repo, options);
30751
30812
  await Promise.all(submodules.map((submodule) => enrichSubmoduleWorktreeStatus(repo, submodule, options)));
30752
- return submodules;
30813
+ return { submodules, headOidByPath };
30753
30814
  } catch {
30754
- return [];
30815
+ return { submodules: [], headOidByPath: /* @__PURE__ */ new Map() };
30755
30816
  }
30756
30817
  }
30757
30818
  async function deriveSubmoduleGitlinkStatuses(repo, options) {
30758
- if (!repo.repoRoot) return [];
30819
+ if (!repo.repoRoot) return { submodules: [], headOidByPath: /* @__PURE__ */ new Map() };
30759
30820
  const paths = await readSubmodulePaths(repo, options);
30760
30821
  const ignoreSet = new Set(options.submoduleIgnorePaths || []);
30761
30822
  const lastCheckedAt = Date.now();
30823
+ const headOidByPath = /* @__PURE__ */ new Map();
30762
30824
  const entries = await Promise.all(
30763
30825
  paths.filter((path43) => !ignoreSet.has(path43)).map(async (path43) => {
30764
30826
  const repoPath = repo.repoRoot + "/" + path43;
30765
30827
  const expected = await readGitlinkExpectedSha(repo, path43, options);
30766
30828
  const actual = await readSubmoduleHeadSha(repo, repoPath, options);
30829
+ if (actual) headOidByPath.set(path43, actual);
30767
30830
  const outOfSync = actual === null ? true : expected !== null && expected !== actual;
30768
30831
  return {
30769
30832
  path: path43,
@@ -30777,7 +30840,7 @@ var require_dist3 = __commonJS({
30777
30840
  };
30778
30841
  })
30779
30842
  );
30780
- return entries;
30843
+ return { submodules: entries, headOidByPath };
30781
30844
  }
30782
30845
  async function readSubmodulePaths(repo, options) {
30783
30846
  if (!repo.repoRoot) return [];
@@ -30834,9 +30897,13 @@ var require_dist3 = __commonJS({
30834
30897
  submodule.error = formatGitError(error48);
30835
30898
  }
30836
30899
  }
30900
+ var GIT_STATUS_CACHE_TTL_MS;
30837
30901
  var lastKnownGoodStatus;
30838
30902
  var changeImpactEvalCache;
30839
30903
  var changeImpactConfigCache;
30904
+ var buildBehindAncestryCache;
30905
+ var GIT_FETCH_THROTTLE_MS;
30906
+ var upstreamFetchedAt;
30840
30907
  var DEFAULT_DAEMON_RUNTIME_PACKAGES;
30841
30908
  var DEFAULT_WEB_ONLY_PACKAGES;
30842
30909
  var DEFAULT_IMPACT_TARGETS;
@@ -30846,9 +30913,13 @@ var require_dist3 = __commonJS({
30846
30913
  init_git_executor();
30847
30914
  init_build_info();
30848
30915
  init_change_impact_config();
30916
+ GIT_STATUS_CACHE_TTL_MS = 1500;
30849
30917
  lastKnownGoodStatus = /* @__PURE__ */ new Map();
30850
30918
  changeImpactEvalCache = /* @__PURE__ */ new Map();
30851
30919
  changeImpactConfigCache = /* @__PURE__ */ new Map();
30920
+ buildBehindAncestryCache = /* @__PURE__ */ new Map();
30921
+ GIT_FETCH_THROTTLE_MS = 3e4;
30922
+ upstreamFetchedAt = /* @__PURE__ */ new Map();
30852
30923
  DEFAULT_DAEMON_RUNTIME_PACKAGES = [
30853
30924
  "daemon-core",
30854
30925
  "daemon-standalone",
@@ -32733,7 +32804,7 @@ ${error48.message || ""}`;
32733
32804
  const repoRoot = readString3(status.repoRoot, status.repo_root, node.repoRoot, node.repo_root, status.workspace, node.workspace) || void 0;
32734
32805
  const submodules = readGitSubmodules(status.submodules, repoRoot);
32735
32806
  const upstreamStatus = readString3(status.upstreamStatus, status.upstream_status);
32736
- const upstreamFetchedAt = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
32807
+ const upstreamFetchedAt2 = readNumber(status.upstreamFetchedAt, status.upstream_fetched_at);
32737
32808
  const upstreamFetchError = readString3(status.upstreamFetchError, status.upstream_fetch_error);
32738
32809
  const error48 = readString3(status.error);
32739
32810
  const staged = readNumber(status.staged) ?? 0;
@@ -32750,7 +32821,7 @@ ${error48.message || ""}`;
32750
32821
  headMessage: readString3(status.headMessage) ?? null,
32751
32822
  upstream: readString3(status.upstream) ?? null,
32752
32823
  upstreamStatus: upstreamStatus ?? "unchecked",
32753
- ...upstreamFetchedAt !== void 0 ? { upstreamFetchedAt } : {},
32824
+ ...upstreamFetchedAt2 !== void 0 ? { upstreamFetchedAt: upstreamFetchedAt2 } : {},
32754
32825
  ...upstreamFetchError ? { upstreamFetchError } : {},
32755
32826
  ahead: readNumber(status.ahead) ?? 0,
32756
32827
  behind: readNumber(status.behind) ?? 0,
@@ -34457,6 +34528,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34457
34528
  getQueue: () => getQueue,
34458
34529
  hasPendingDependents: () => hasPendingDependents,
34459
34530
  insertDirectDispatch: () => insertDirectDispatch,
34531
+ isTaskReadonly: () => isTaskReadonly,
34460
34532
  markStaleDirectDispatches: () => markStaleDirectDispatches,
34461
34533
  nodeSatisfiesRequiredTags: () => nodeSatisfiesRequiredTags,
34462
34534
  normalizeMeshCapabilityTags: () => normalizeMeshCapabilityTags,
@@ -34472,6 +34544,10 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34472
34544
  updateTaskStatus: () => updateTaskStatus,
34473
34545
  validateMeshTaskModeRequest: () => validateMeshTaskModeRequest
34474
34546
  });
34547
+ function isTaskReadonly(task) {
34548
+ if (!task) return false;
34549
+ return task.readonly === true || task.taskMode === "live_debug_readonly";
34550
+ }
34475
34551
  function hasNegationBefore(text, matchIndex) {
34476
34552
  const before = text.slice(0, matchIndex);
34477
34553
  const clauseStart = Math.max(
@@ -34657,13 +34733,11 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34657
34733
  const normalized = value.trim();
34658
34734
  return MESH_TASK_MODES.includes(normalized) ? normalized : void 0;
34659
34735
  }
34660
- function validateMeshTaskModeRequest(mode, message) {
34736
+ function validateMeshTaskModeRequest(mode, message, readonly2) {
34661
34737
  const taskMode = normalizeMeshTaskMode(mode);
34662
- if (!taskMode) {
34663
- return { valid: true, violations: [] };
34664
- }
34665
- if (taskMode !== "live_debug_readonly") {
34666
- return { valid: true, taskMode, violations: [] };
34738
+ const isReadonly = isTaskReadonly({ readonly: readonly2, taskMode });
34739
+ if (!isReadonly) {
34740
+ return taskMode ? { valid: true, taskMode, violations: [] } : { valid: true, violations: [] };
34667
34741
  }
34668
34742
  const text = message || "";
34669
34743
  const violations = LIVE_DEBUG_READONLY_FORBIDDEN.filter((rule) => patternHasRealMutation(rule.pattern, text)).map((rule) => rule.label);
@@ -34790,7 +34864,8 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34790
34864
  }
34791
34865
  function enqueueTask(meshId, message, opts) {
34792
34866
  requireMeshHostQueueOwner(opts);
34793
- const modeValidation = validateMeshTaskModeRequest(opts?.taskMode, message);
34867
+ const readonly2 = opts?.readonly === true;
34868
+ const modeValidation = validateMeshTaskModeRequest(opts?.taskMode, message, readonly2);
34794
34869
  if (!modeValidation.valid) {
34795
34870
  throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
34796
34871
  }
@@ -34814,6 +34889,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34814
34889
  message,
34815
34890
  status: "pending",
34816
34891
  taskMode: modeValidation.taskMode,
34892
+ ...readonly2 ? { readonly: true } : {},
34817
34893
  targetNodeId: opts?.targetNodeId,
34818
34894
  targetSessionId: opts?.targetSessionId,
34819
34895
  requiredTags: resolvedRequiredTags,
@@ -34832,7 +34908,8 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34832
34908
  if (!missionId) return null;
34833
34909
  const taskId = typeof opts.id === "string" ? opts.id.trim() : "";
34834
34910
  if (!taskId) return null;
34835
- const modeValidation = validateMeshTaskModeRequest(opts.taskMode, message);
34911
+ const readonly2 = opts.readonly === true;
34912
+ const modeValidation = validateMeshTaskModeRequest(opts.taskMode, message, readonly2);
34836
34913
  if (!modeValidation.valid) {
34837
34914
  throw new Error(`live_debug_readonly_guardrail_violation: forbidden operations (${modeValidation.violations.join(", ")})`);
34838
34915
  }
@@ -34847,6 +34924,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34847
34924
  message,
34848
34925
  status: "assigned",
34849
34926
  ...modeValidation.taskMode ? { taskMode: modeValidation.taskMode } : {},
34927
+ ...readonly2 ? { readonly: true } : {},
34850
34928
  missionId,
34851
34929
  ...opts.assignedNodeId ? { targetNodeId: opts.assignedNodeId, assignedNodeId: opts.assignedNodeId } : {},
34852
34930
  ...opts.assignedSessionId ? { targetSessionId: opts.assignedSessionId, assignedSessionId: opts.assignedSessionId } : {},
@@ -35839,7 +35917,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
35839
35917
  return deps.every((depId) => depStatus.get(depId) === "completed");
35840
35918
  };
35841
35919
  const nodeConflictAllows = (candidate) => {
35842
- if (candidate.taskMode === "live_debug_readonly") return true;
35920
+ if (isTaskReadonly(candidate)) return true;
35843
35921
  return !nodeBusy;
35844
35922
  };
35845
35923
  const nodeIsWorktree = opts?.nodeIsWorktree === true;
@@ -39069,7 +39147,7 @@ ${rendered}`, "utf-8");
39069
39147
  "use strict";
39070
39148
  init_git_status();
39071
39149
  init_git_executor();
39072
- STATUS_OPTIONS = { refreshUpstream: true, includeSubmodules: true, timeoutMs: 15e3 };
39150
+ STATUS_OPTIONS = { refreshUpstream: true, includeSubmodules: true, timeoutMs: 15e3, forceFresh: true };
39073
39151
  }
39074
39152
  });
39075
39153
  function readString6(value) {
@@ -39468,9 +39546,6 @@ ${rendered}`, "utf-8");
39468
39546
  __export2(mesh_scheduling_runtime_exports, {
39469
39547
  buildMeshSchedulingRuntime: () => buildMeshSchedulingRuntime
39470
39548
  });
39471
- function isReadonly(task) {
39472
- return task.taskMode === "live_debug_readonly";
39473
- }
39474
39549
  function isAssigned(task) {
39475
39550
  return task.status === "assigned";
39476
39551
  }
@@ -39479,8 +39554,8 @@ ${rendered}`, "utf-8");
39479
39554
  const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
39480
39555
  const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
39481
39556
  const assignedTasks = (Array.isArray(queue) ? queue : []).filter(isAssigned);
39482
- const activeWriteAssigned = assignedTasks.filter((t) => !isReadonly(t)).length;
39483
- const activeReadonlyAssigned = assignedTasks.filter(isReadonly).length;
39557
+ const activeWriteAssigned = assignedTasks.filter((t) => !isTaskReadonly(t)).length;
39558
+ const activeReadonlyAssigned = assignedTasks.filter(isTaskReadonly).length;
39484
39559
  const globalWriteCapReached = activeWriteAssigned >= maxParallelTasks;
39485
39560
  const globalReadonlyCapReached = activeReadonlyAssigned >= maxReadonlyParallelTasks;
39486
39561
  const writeAssignedByNode = /* @__PURE__ */ new Map();
@@ -39490,7 +39565,7 @@ ${rendered}`, "utf-8");
39490
39565
  const nodeId = typeof task.assignedNodeId === "string" ? task.assignedNodeId.trim() : "";
39491
39566
  if (!nodeId) continue;
39492
39567
  assignedByNode.set(nodeId, (assignedByNode.get(nodeId) ?? 0) + 1);
39493
- if (!isReadonly(task)) {
39568
+ if (!isTaskReadonly(task)) {
39494
39569
  writeAssignedByNode.set(nodeId, (writeAssignedByNode.get(nodeId) ?? 0) + 1);
39495
39570
  }
39496
39571
  const provider = typeof task.assignedProviderType === "string" ? task.assignedProviderType : "";
@@ -39563,6 +39638,7 @@ ${rendered}`, "utf-8");
39563
39638
  "use strict";
39564
39639
  init_repo_mesh_types();
39565
39640
  init_dist();
39641
+ init_mesh_work_queue();
39566
39642
  }
39567
39643
  });
39568
39644
  function readNonEmptyString2(value) {
@@ -41970,10 +42046,10 @@ Next step: ${nextStep}`;
41970
42046
  return { mode: "remote", daemonId, coordinatorDaemonId };
41971
42047
  }
41972
42048
  function activeWriteAssignedCount(meshId) {
41973
- return getQueue(meshId, { status: ["assigned"] }).filter((task) => task.taskMode !== "live_debug_readonly").length;
42049
+ return getQueue(meshId, { status: ["assigned"] }).filter((task) => !isTaskReadonly(task)).length;
41974
42050
  }
41975
42051
  function activeReadonlyAssignedCount(meshId) {
41976
- return getQueue(meshId, { status: ["assigned"] }).filter((task) => task.taskMode === "live_debug_readonly").length;
42052
+ return getQueue(meshId, { status: ["assigned"] }).filter(isTaskReadonly).length;
41977
42053
  }
41978
42054
  function nodeHasActiveAssignment(meshId, nodeId) {
41979
42055
  return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedNodeId === nodeId);
@@ -42149,8 +42225,8 @@ Next step: ${nextStep}`;
42149
42225
  );
42150
42226
  const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks, schedulingOverride?.readonlyMultiplier);
42151
42227
  for (const task of pending) {
42152
- const isReadonly2 = task.taskMode === "live_debug_readonly";
42153
- if (isReadonly2) {
42228
+ const isReadonly = isTaskReadonly(task);
42229
+ if (isReadonly) {
42154
42230
  if (activeReadonlyAssignedCount(meshId) >= maxReadonlyParallelTasks) {
42155
42231
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "max_readonly_parallel_tasks_reached" });
42156
42232
  continue;
@@ -42232,7 +42308,7 @@ Next step: ${nextStep}`;
42232
42308
  sweepExpiredCooldowns();
42233
42309
  continue;
42234
42310
  }
42235
- if (task.taskMode !== "live_debug_readonly" && nodeHasActiveAssignment(meshId, nodeId)) {
42311
+ if (!isTaskReadonly(task) && nodeHasActiveAssignment(meshId, nodeId)) {
42236
42312
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "node_has_active_assignment", nodeId });
42237
42313
  continue;
42238
42314
  }
@@ -42996,6 +43072,9 @@ Next step: ${nextStep}`;
42996
43072
  const code = "code" in error48 ? error48.code : void 0;
42997
43073
  return code === "MODULE_NOT_FOUND" && message.includes(ref);
42998
43074
  }
43075
+ function runtimeTriplet() {
43076
+ return `${process.platform}-${process.arch}-node${process.versions.modules}`;
43077
+ }
42999
43078
  function normalizeBinding(mod, ref) {
43000
43079
  const binding = mod?.default?.createTerminal ? mod.default : mod?.createTerminal ? mod : null;
43001
43080
  if (!binding) {
@@ -43030,7 +43109,7 @@ Next step: ${nextStep}`;
43030
43109
  }
43031
43110
  cachedBinding = null;
43032
43111
  cachedBindingError = new Error(
43033
- `ghostty-vt binding unavailable (${errors.join("; ") || "no candidates tried"})`
43112
+ `ghostty-vt binding unavailable for runtime ${runtimeTriplet()} (${errors.join("; ") || "no candidates tried"})`
43034
43113
  );
43035
43114
  throw cachedBindingError;
43036
43115
  }
@@ -46212,11 +46291,8 @@ ${cleanBody}`;
46212
46291
  }
46213
46292
  return def;
46214
46293
  }
46215
- function resolveMinIdleSettleMs() {
46216
- return resolveTunedReconcileMs("MESH_INFLIGHT_MIN_IDLE_SETTLE_MS", 16e3, 0, 12e4);
46217
- }
46218
- function resolveAckedTurnSettleMs() {
46219
- return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_TURN_SETTLE_MS", 2e4, 0, 18e4);
46294
+ function resolveAckedDeathDeadlineMs() {
46295
+ return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
46220
46296
  }
46221
46297
  function inFlightSynthKey(meshId, taskId) {
46222
46298
  return `${meshId}::${taskId}`;
@@ -46827,9 +46903,9 @@ ${cleanBody}`;
46827
46903
  const activeTaskKeys = new Set(
46828
46904
  dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
46829
46905
  );
46830
- for (const key of inFlightIdleObservationCounts.keys()) {
46906
+ for (const key of inFlightAckedHoldState.keys()) {
46831
46907
  if (key.startsWith(`${mesh.id}::`) && !activeTaskKeys.has(key)) {
46832
- inFlightIdleObservationCounts.delete(key);
46908
+ inFlightAckedHoldState.delete(key);
46833
46909
  }
46834
46910
  }
46835
46911
  const dispatchMeshCommand = components.dispatchMeshCommand;
@@ -46850,49 +46926,61 @@ ${cleanBody}`;
46850
46926
  ...node?.workspace ? { workspace: node.workspace } : {},
46851
46927
  ...providerType ? { agentType: providerType, providerType } : {}
46852
46928
  };
46929
+ const synthKey = inFlightSynthKey(mesh.id, taskId);
46930
+ const isAcked = dispatch.status === "acked";
46853
46931
  let payload = null;
46932
+ let readFailed = false;
46854
46933
  try {
46855
46934
  if (isLocalNode) {
46856
46935
  const result = await components.commandHandler.handle("read_chat", readArgs);
46857
- if (result && result.success === false) continue;
46858
- payload = unwrapReadChatPayload(result);
46936
+ if (result && result.success === false) {
46937
+ readFailed = true;
46938
+ } else {
46939
+ payload = unwrapReadChatPayload(result);
46940
+ }
46859
46941
  } else if (dispatchMeshCommand) {
46860
46942
  const result = await dispatchMeshCommand(nodeDaemonId, "read_chat", readArgs);
46861
46943
  payload = unwrapReadChatPayload(result);
46862
- if (payload && payload.success === false) continue;
46944
+ if (payload && payload.success === false) {
46945
+ payload = null;
46946
+ readFailed = true;
46947
+ }
46863
46948
  } else {
46864
46949
  continue;
46865
46950
  }
46866
46951
  } catch {
46952
+ readFailed = true;
46953
+ }
46954
+ if (!payload && !readFailed) continue;
46955
+ if (readFailed || !payload) {
46956
+ if (isAcked) {
46957
+ const prior = inFlightAckedHoldState.get(synthKey);
46958
+ const failures = (prior?.consecutiveReadFailures ?? 0) + 1;
46959
+ const liveConfirmedSinceAck = prior?.liveConfirmedSinceAck ?? false;
46960
+ inFlightAckedHoldState.set(synthKey, { liveConfirmedSinceAck, consecutiveReadFailures: failures });
46961
+ if (liveConfirmedSinceAck && failures >= ACKED_DEATH_CONSECUTIVE_READ_FAILURES) {
46962
+ LOG2.warn("MeshReconcile", `Acked-hold death signal: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read_chat failed ${failures}x consecutively after a live-confirmed ack \u2014 worker session presumed gone mid-turn; releasing the indefinite synth hold to the stranded-reclaim / orphan-prune nets`);
46963
+ }
46964
+ }
46867
46965
  continue;
46868
46966
  }
46869
- if (!payload) continue;
46870
- const synthKey = inFlightSynthKey(mesh.id, taskId);
46967
+ inFlightAckedHoldState.set(synthKey, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
46871
46968
  const nowMs = Date.now();
46872
46969
  if (readChatPayloadStatus(payload) !== "idle") {
46873
- inFlightIdleObservationCounts.delete(synthKey);
46874
46970
  continue;
46875
46971
  }
46876
- if (dispatch.status === "acked") {
46877
- const prior = inFlightIdleObservationCounts.get(synthKey);
46878
- const firstIdleAtMs = prior?.firstIdleAtMs ?? nowMs;
46879
- const idleStreak = (prior?.count ?? 0) + 1;
46880
- inFlightIdleObservationCounts.set(synthKey, { count: idleStreak, firstIdleAtMs });
46881
- const idleSettleMs = nowMs - firstIdleAtMs;
46882
- const minIdleSettleMs = resolveMinIdleSettleMs();
46883
- const ackedTurnSettleMs = resolveAckedTurnSettleMs();
46972
+ if (isAcked) {
46884
46973
  const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
46885
46974
  const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
46886
- const tickGuardMet = idleStreak >= REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH;
46887
- const settleGuardMet = idleSettleMs >= minIdleSettleMs;
46888
- const ackGuardMet = sinceAckMs >= ackedTurnSettleMs;
46889
- if (!tickGuardMet || !settleGuardMet || !ackGuardMet) {
46890
- LOG2.info("MeshReconcile", `In-flight synth hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) idle ${idleStreak}/${REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH} tick(s), settle ${Math.round(idleSettleMs / 1e3)}s/${Math.round(minIdleSettleMs / 1e3)}s, since-ack ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"}/${Math.round(ackedTurnSettleMs / 1e3)}s \u2014 deferring completion synth until the worker's turn genuinely settles (guards against a mid-turn idle window pre-empting the real completion)`);
46975
+ const deathDeadlineMs = resolveAckedDeathDeadlineMs();
46976
+ if (sinceAckMs < deathDeadlineMs) {
46977
+ LOG2.info("MeshReconcile", `Acked-hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${Number.isFinite(sinceAckMs) ? Math.round(sinceAckMs / 1e3) + "s" : "\u221E"} since the generating_started ack \u2014 HOLDING synth indefinitely (worker is alive and will emit; a later real emit is idempotent). Death backstop fires at ${Math.round(deathDeadlineMs / 1e3)}s or on consecutive read failures.`);
46891
46978
  continue;
46892
46979
  }
46980
+ LOG2.warn("MeshReconcile", `Acked-hold death deadline reached: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) still idle ${Math.round(sinceAckMs / 1e3)}s after the ack (deadline ${Math.round(deathDeadlineMs / 1e3)}s) \u2014 synthesizing the missing completion as a notification-loss net (a real emit, if it ever lands, no-ops idempotently).`);
46893
46981
  }
46894
46982
  if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
46895
- inFlightIdleObservationCounts.delete(synthKey);
46983
+ inFlightAckedHoldState.delete(synthKey);
46896
46984
  LOG2.info("MeshReconcile", `Worker-emit priority: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) has a real terminal completion already queued \u2014 yielding synth to the worker's own emit`);
46897
46985
  continue;
46898
46986
  }
@@ -46914,7 +47002,7 @@ ${cleanBody}`;
46914
47002
  }
46915
47003
  const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
46916
47004
  if (reprobeStatus && reprobeStatus !== "idle") {
46917
- inFlightIdleObservationCounts.delete(synthKey);
47005
+ inFlightAckedHoldState.delete(synthKey);
46918
47006
  LOG2.info("MeshReconcile", `Live re-probe defer: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read '${reprobeStatus}' at synth-commit time \u2014 worker resumed generating; deferring synth to a later tick`);
46919
47007
  continue;
46920
47008
  }
@@ -47058,8 +47146,8 @@ ${cleanBody}`;
47058
47146
  }
47059
47147
  var DEFAULT_RECONCILE_INTERVAL_MS;
47060
47148
  var DEFAULT_AUTO_PRUNE_MIN_AGE_MS;
47061
- var REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH;
47062
- var inFlightIdleObservationCounts;
47149
+ var ACKED_DEATH_CONSECUTIVE_READ_FAILURES;
47150
+ var inFlightAckedHoldState;
47063
47151
  var coordinatorModalParkState;
47064
47152
  var heldEventLedgerRecorded;
47065
47153
  var ASSIGNED_STRANDED_DEADLINE_MS;
@@ -47087,8 +47175,8 @@ ${cleanBody}`;
47087
47175
  init_chat_message_normalization();
47088
47176
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
47089
47177
  DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
47090
- REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH = 2;
47091
- inFlightIdleObservationCounts = /* @__PURE__ */ new Map();
47178
+ ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
47179
+ inFlightAckedHoldState = /* @__PURE__ */ new Map();
47092
47180
  coordinatorModalParkState = /* @__PURE__ */ new Map();
47093
47181
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
47094
47182
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
@@ -52979,6 +53067,7 @@ ${lastSnapshot}`;
52979
53067
  isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
52980
53068
  isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
52981
53069
  isSetupComplete: () => isSetupComplete,
53070
+ isTaskReadonly: () => isTaskReadonly,
52982
53071
  isUserFacingChatMessage: () => isUserFacingChatMessage,
52983
53072
  killIdeProcess: () => killIdeProcess,
52984
53073
  launchIDE: () => launchIDE,
@@ -54056,7 +54145,7 @@ ${lastSnapshot}`;
54056
54145
  async function gitCheckpoint(workspace, message, includeUntracked) {
54057
54146
  const repo = await resolveGitRepository(workspace);
54058
54147
  const repoRoot = repo.repoRoot;
54059
- const statusResult = await getGitRepoStatus(workspace);
54148
+ const statusResult = await getGitRepoStatus(workspace, { forceFresh: true });
54060
54149
  if (statusResult.hasConflicts) {
54061
54150
  throw new GitCommandError("conflict", "Repository has conflicts \u2014 resolve before checkpointing");
54062
54151
  }
@@ -82590,7 +82679,10 @@ ${mergeTreeErr?.stderr || ""}`;
82590
82679
  const preStatus = await getGitRepoStatus(repoRoot, {
82591
82680
  includeSubmodules: true,
82592
82681
  submoduleIgnorePaths: options.submoduleIgnorePaths,
82593
- timeoutMs: 15e3
82682
+ timeoutMs: 15e3,
82683
+ // Decision path — the out-of-sync submodule set drives a mutating `submodule
82684
+ // update`. Must not act on a TTL-cached status; bypass the C1 cache.
82685
+ forceFresh: true
82594
82686
  });
82595
82687
  const outOfSyncPaths = (preStatus.submodules || []).filter((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error).map((submodule) => submodule.path);
82596
82688
  const updatePaths = [.../* @__PURE__ */ new Set([...changedGitlinkPaths, ...outOfSyncPaths])].sort();
@@ -82619,7 +82711,10 @@ ${mergeTreeErr?.stderr || ""}`;
82619
82711
  const postStatus = await getGitRepoStatus(repoRoot, {
82620
82712
  includeSubmodules: true,
82621
82713
  submoduleIgnorePaths: options.submoduleIgnorePaths,
82622
- timeoutMs: 15e3
82714
+ timeoutMs: 15e3,
82715
+ // Re-read AFTER `submodule update` mutated the tree — MUST be fresh, never the
82716
+ // cached preStatus from moments ago (which would falsely report still-dirty).
82717
+ forceFresh: true
82623
82718
  });
82624
82719
  const remaining = (postStatus.submodules || []).filter((submodule) => updatePaths.includes(submodule.path) && (submodule.dirty || submodule.outOfSync || !!submodule.error));
82625
82720
  return {