@adhdev/daemon-standalone 0.9.82-rc.406 → 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 ? "1a663e37a08bce5e83cc14be4663d33ad60e81c9" : void 0) ?? "unknown";
30131
- const commitShort = readInjected(true ? "1a663e37" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30132
- const version2 = readInjected(true ? "0.9.82-rc.406" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30133
- const builtAt = readInjected(true ? "2026-06-28T04:52:54.674Z" : 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
  }
@@ -46204,6 +46283,17 @@ ${cleanBody}`;
46204
46283
  }
46205
46284
  return DEFAULT_RECONCILE_INTERVAL_MS;
46206
46285
  }
46286
+ function resolveTunedReconcileMs(envName, def, min, max) {
46287
+ const raw = readNonEmptyString2(process.env[envName]);
46288
+ if (raw) {
46289
+ const parsed = Number.parseInt(raw, 10);
46290
+ if (Number.isFinite(parsed) && parsed >= min && parsed <= max) return parsed;
46291
+ }
46292
+ return def;
46293
+ }
46294
+ function resolveAckedDeathDeadlineMs() {
46295
+ return resolveTunedReconcileMs("MESH_INFLIGHT_ACKED_DEATH_DEADLINE_MS", 8 * 6e4, 0, 60 * 6e4);
46296
+ }
46207
46297
  function inFlightSynthKey(meshId, taskId) {
46208
46298
  return `${meshId}::${taskId}`;
46209
46299
  }
@@ -46780,15 +46870,42 @@ ${cleanBody}`;
46780
46870
  function readChatPayloadStatus(payload) {
46781
46871
  return readNonEmptyString2(payload?.status).toLowerCase();
46782
46872
  }
46873
+ function realTerminalEmitPendingForTask(meshId, taskId) {
46874
+ let pending;
46875
+ try {
46876
+ pending = getPendingMeshCoordinatorEvents(meshId);
46877
+ } catch {
46878
+ return false;
46879
+ }
46880
+ return pending.some((e) => readNonEmptyString2(e.metadataEvent?.taskId) === taskId && (e.event === "agent:generating_completed" || e.event === "agent:stopped"));
46881
+ }
46882
+ async function reprobeWorkerStatus(components, args) {
46883
+ try {
46884
+ if (args.isLocalNode) {
46885
+ const r = await components.commandHandler.handle("read_chat", args.readArgs);
46886
+ if (r && r.success === false) return null;
46887
+ return readChatPayloadStatus(unwrapReadChatPayload(r));
46888
+ }
46889
+ if (components.dispatchMeshCommand) {
46890
+ const r = await components.dispatchMeshCommand(args.nodeDaemonId, "read_chat", args.readArgs);
46891
+ const p = unwrapReadChatPayload(r);
46892
+ if (p && p.success === false) return null;
46893
+ return readChatPayloadStatus(p);
46894
+ }
46895
+ } catch {
46896
+ return null;
46897
+ }
46898
+ return null;
46899
+ }
46783
46900
  async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
46784
46901
  const dispatches = getActiveDirectDispatches(mesh.id);
46785
46902
  if (dispatches.length === 0) return;
46786
46903
  const activeTaskKeys = new Set(
46787
46904
  dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
46788
46905
  );
46789
- for (const key of inFlightIdleObservationCounts.keys()) {
46906
+ for (const key of inFlightAckedHoldState.keys()) {
46790
46907
  if (key.startsWith(`${mesh.id}::`) && !activeTaskKeys.has(key)) {
46791
- inFlightIdleObservationCounts.delete(key);
46908
+ inFlightAckedHoldState.delete(key);
46792
46909
  }
46793
46910
  }
46794
46911
  const dispatchMeshCommand = components.dispatchMeshCommand;
@@ -46809,35 +46926,63 @@ ${cleanBody}`;
46809
46926
  ...node?.workspace ? { workspace: node.workspace } : {},
46810
46927
  ...providerType ? { agentType: providerType, providerType } : {}
46811
46928
  };
46929
+ const synthKey = inFlightSynthKey(mesh.id, taskId);
46930
+ const isAcked = dispatch.status === "acked";
46812
46931
  let payload = null;
46932
+ let readFailed = false;
46813
46933
  try {
46814
46934
  if (isLocalNode) {
46815
46935
  const result = await components.commandHandler.handle("read_chat", readArgs);
46816
- if (result && result.success === false) continue;
46817
- payload = unwrapReadChatPayload(result);
46936
+ if (result && result.success === false) {
46937
+ readFailed = true;
46938
+ } else {
46939
+ payload = unwrapReadChatPayload(result);
46940
+ }
46818
46941
  } else if (dispatchMeshCommand) {
46819
46942
  const result = await dispatchMeshCommand(nodeDaemonId, "read_chat", readArgs);
46820
46943
  payload = unwrapReadChatPayload(result);
46821
- if (payload && payload.success === false) continue;
46944
+ if (payload && payload.success === false) {
46945
+ payload = null;
46946
+ readFailed = true;
46947
+ }
46822
46948
  } else {
46823
46949
  continue;
46824
46950
  }
46825
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
+ }
46826
46965
  continue;
46827
46966
  }
46828
- if (!payload) continue;
46829
- const synthKey = inFlightSynthKey(mesh.id, taskId);
46967
+ inFlightAckedHoldState.set(synthKey, { liveConfirmedSinceAck: true, consecutiveReadFailures: 0 });
46968
+ const nowMs = Date.now();
46830
46969
  if (readChatPayloadStatus(payload) !== "idle") {
46831
- inFlightIdleObservationCounts.delete(synthKey);
46832
46970
  continue;
46833
46971
  }
46834
- if (dispatch.status === "acked") {
46835
- const idleStreak = (inFlightIdleObservationCounts.get(synthKey) ?? 0) + 1;
46836
- inFlightIdleObservationCounts.set(synthKey, idleStreak);
46837
- if (idleStreak < REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH) {
46838
- LOG2.info("MeshReconcile", `In-flight synth hold: task ${taskId} on node ${nodeId} (mesh ${mesh.id}) read idle ${idleStreak}/${REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH} consecutive tick(s) after generating_started \u2014 deferring completion synth until the idle settle is confirmed (guards against a mid-turn idle flicker pre-empting the real completion)`);
46972
+ if (isAcked) {
46973
+ const ackedAtMs = Date.parse(readNonEmptyString2(dispatch.updatedAt));
46974
+ const sinceAckMs = Number.isFinite(ackedAtMs) ? nowMs - ackedAtMs : Number.POSITIVE_INFINITY;
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.`);
46839
46978
  continue;
46840
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).`);
46981
+ }
46982
+ if (realTerminalEmitPendingForTask(mesh.id, taskId)) {
46983
+ inFlightAckedHoldState.delete(synthKey);
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`);
46985
+ continue;
46841
46986
  }
46842
46987
  const messages = Array.isArray(payload.messages) ? payload.messages : [];
46843
46988
  const evidence = extractFinalAssistantSummaryEvidence(messages);
@@ -46855,6 +47000,12 @@ ${cleanBody}`;
46855
47000
  }, `transcriptAt=${evidence.transcriptMessageAt} < dispatchedAt=${dispatch.dispatchedAt}`);
46856
47001
  continue;
46857
47002
  }
47003
+ const reprobeStatus = await reprobeWorkerStatus(components, { isLocalNode, nodeDaemonId, readArgs });
47004
+ if (reprobeStatus && reprobeStatus !== "idle") {
47005
+ inFlightAckedHoldState.delete(synthKey);
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`);
47007
+ continue;
47008
+ }
46858
47009
  const providerSessionId = readNonEmptyString2(payload.providerSessionId);
46859
47010
  const coordinatorDaemonId = selfIds.find((id) => !!id);
46860
47011
  try {
@@ -46995,8 +47146,8 @@ ${cleanBody}`;
46995
47146
  }
46996
47147
  var DEFAULT_RECONCILE_INTERVAL_MS;
46997
47148
  var DEFAULT_AUTO_PRUNE_MIN_AGE_MS;
46998
- var REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH;
46999
- var inFlightIdleObservationCounts;
47149
+ var ACKED_DEATH_CONSECUTIVE_READ_FAILURES;
47150
+ var inFlightAckedHoldState;
47000
47151
  var coordinatorModalParkState;
47001
47152
  var heldEventLedgerRecorded;
47002
47153
  var ASSIGNED_STRANDED_DEADLINE_MS;
@@ -47024,8 +47175,8 @@ ${cleanBody}`;
47024
47175
  init_chat_message_normalization();
47025
47176
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
47026
47177
  DEFAULT_AUTO_PRUNE_MIN_AGE_MS = 24 * 60 * 6e4;
47027
- REQUIRED_CONSECUTIVE_IDLE_TICKS_FOR_INFLIGHT_SYNTH = 2;
47028
- inFlightIdleObservationCounts = /* @__PURE__ */ new Map();
47178
+ ACKED_DEATH_CONSECUTIVE_READ_FAILURES = 3;
47179
+ inFlightAckedHoldState = /* @__PURE__ */ new Map();
47029
47180
  coordinatorModalParkState = /* @__PURE__ */ new Map();
47030
47181
  heldEventLedgerRecorded = /* @__PURE__ */ new Set();
47031
47182
  ASSIGNED_STRANDED_DEADLINE_MS = 5 * 6e4;
@@ -52916,6 +53067,7 @@ ${lastSnapshot}`;
52916
53067
  isSessionHostLiveRuntime: () => isSessionHostLiveRuntime,
52917
53068
  isSessionHostRecoverySnapshot: () => isSessionHostRecoverySnapshot,
52918
53069
  isSetupComplete: () => isSetupComplete,
53070
+ isTaskReadonly: () => isTaskReadonly,
52919
53071
  isUserFacingChatMessage: () => isUserFacingChatMessage,
52920
53072
  killIdeProcess: () => killIdeProcess,
52921
53073
  launchIDE: () => launchIDE,
@@ -53993,7 +54145,7 @@ ${lastSnapshot}`;
53993
54145
  async function gitCheckpoint(workspace, message, includeUntracked) {
53994
54146
  const repo = await resolveGitRepository(workspace);
53995
54147
  const repoRoot = repo.repoRoot;
53996
- const statusResult = await getGitRepoStatus(workspace);
54148
+ const statusResult = await getGitRepoStatus(workspace, { forceFresh: true });
53997
54149
  if (statusResult.hasConflicts) {
53998
54150
  throw new GitCommandError("conflict", "Repository has conflicts \u2014 resolve before checkpointing");
53999
54151
  }
@@ -82527,7 +82679,10 @@ ${mergeTreeErr?.stderr || ""}`;
82527
82679
  const preStatus = await getGitRepoStatus(repoRoot, {
82528
82680
  includeSubmodules: true,
82529
82681
  submoduleIgnorePaths: options.submoduleIgnorePaths,
82530
- 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
82531
82686
  });
82532
82687
  const outOfSyncPaths = (preStatus.submodules || []).filter((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error).map((submodule) => submodule.path);
82533
82688
  const updatePaths = [.../* @__PURE__ */ new Set([...changedGitlinkPaths, ...outOfSyncPaths])].sort();
@@ -82556,7 +82711,10 @@ ${mergeTreeErr?.stderr || ""}`;
82556
82711
  const postStatus = await getGitRepoStatus(repoRoot, {
82557
82712
  includeSubmodules: true,
82558
82713
  submoduleIgnorePaths: options.submoduleIgnorePaths,
82559
- 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
82560
82718
  });
82561
82719
  const remaining = (postStatus.submodules || []).filter((submodule) => updatePaths.includes(submodule.path) && (submodule.dirty || submodule.outOfSync || !!submodule.error));
82562
82720
  return {