@adhdev/daemon-core 0.9.82-rc.357 → 0.9.82-rc.359

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
@@ -311,10 +311,10 @@ function readInjected(value) {
311
311
  }
312
312
  function getDaemonBuildInfo() {
313
313
  if (cached) return cached;
314
- const commit = readInjected(true ? "37b9d1d9e10336707dbc0861a96d5bcc55cc015e" : void 0) ?? "unknown";
315
- const commitShort = readInjected(true ? "37b9d1d9" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
- const version = readInjected(true ? "0.9.82-rc.357" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
- const builtAt = readInjected(true ? "2026-06-23T00:25:21.599Z" : void 0);
314
+ const commit = readInjected(true ? "56a1f2a986ab2c2bb7888189d9b027d6067f2317" : void 0) ?? "unknown";
315
+ const commitShort = readInjected(true ? "56a1f2a9" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
316
+ const version = readInjected(true ? "0.9.82-rc.359" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
317
+ const builtAt = readInjected(true ? "2026-06-23T05:03:11.133Z" : void 0);
318
318
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
319
319
  return cached;
320
320
  }
@@ -13012,9 +13012,7 @@ function isLocalAutoLaunchNode(node) {
13012
13012
  const machineId = readNonEmptyString2(node?.machineId);
13013
13013
  const appConfig = loadConfig();
13014
13014
  const localMachineId = readNonEmptyString2(appConfig.machineId) || readNonEmptyString2(appConfig.registeredMachineId);
13015
- const cloudDaemonId = localMachineId ? `daemon_${localMachineId}` : "";
13016
- const standaloneDaemonId = localMachineId ? `standalone_${localMachineId}` : "";
13017
- const daemonMatchesLocal = !daemonId || daemonId === cloudDaemonId || daemonId === standaloneDaemonId;
13015
+ const daemonMatchesLocal = !daemonId || daemonIdsEquivalent(daemonId, localMachineId);
13018
13016
  const machineMatchesLocal = !machineId || !!localMachineId && machineId === localMachineId;
13019
13017
  if (node?.isLocalWorktree === true) {
13020
13018
  return daemonMatchesLocal && machineMatchesLocal;
@@ -13748,7 +13746,7 @@ function injectMeshSystemMessage(components, args) {
13748
13746
  occurredAt: occurredAtMs != null ? new Date(occurredAtMs).toISOString() : void 0,
13749
13747
  taskId: eventTaskId
13750
13748
  });
13751
- const leaveDirectDispatchActive = !task && opts?.tentativeIfDirect === true;
13749
+ const leaveDirectDispatchActive = !task && opts?.tentativeIfDirect === true || !eventTaskId && !sessionHasActiveAssignment(args.meshId, sessionId);
13752
13750
  if (!leaveDirectDispatchActive) {
13753
13751
  updateDirectDispatchStatus(args.meshId, sessionId, outcome, eventTaskId);
13754
13752
  }
@@ -13847,7 +13845,9 @@ function injectMeshSystemMessage(components, args) {
13847
13845
  }
13848
13846
  if (sessionId) {
13849
13847
  const startedTaskId = readNonEmptyString2(args.metadataEvent.taskId) || void 0;
13850
- updateDirectDispatchStatus(args.meshId, sessionId, "acked", startedTaskId);
13848
+ if (startedTaskId || sessionHasActiveAssignment(args.meshId, sessionId)) {
13849
+ updateDirectDispatchStatus(args.meshId, sessionId, "acked", startedTaskId);
13850
+ }
13851
13851
  const activeDeliveries = (() => {
13852
13852
  try {
13853
13853
  return MeshRuntimeStore.getInstance().getActiveSessionDeliveries(args.meshId, sessionId);
@@ -13948,7 +13948,7 @@ function injectMeshSystemMessage(components, args) {
13948
13948
  targetNodeId: autoNodeId
13949
13949
  });
13950
13950
  LOG.info("MeshRecovery", `Auto-requeued failed task: ${task.id} for node ${autoNodeId}`);
13951
- const node = mesh?.nodes.find((n) => n.id === autoNodeId);
13951
+ const node = mesh?.nodes.find((n) => meshNodeIdMatches(n, autoNodeId));
13952
13952
  if (node) {
13953
13953
  components.cliManager.handleCliCommand("launch_cli", {
13954
13954
  cliType: recoveryContext.failedProviderType,
@@ -14677,7 +14677,7 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
14677
14677
  for (const node of mesh.nodes) {
14678
14678
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14679
14679
  if (!nodeDaemonId) continue;
14680
- if (localDaemonId && nodeDaemonId === localDaemonId) continue;
14680
+ if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) continue;
14681
14681
  if (candidateDaemonIds.includes(nodeDaemonId)) continue;
14682
14682
  for (const pendingEventArgs of pulls) {
14683
14683
  let events;
@@ -14734,7 +14734,7 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
14734
14734
  if (!sessionId || !nodeId || !taskId) continue;
14735
14735
  const node = nodeById.get(nodeId);
14736
14736
  const nodeDaemonId = readNonEmptyString2(node?.daemonId);
14737
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || localDaemonId !== void 0 && nodeDaemonId === localDaemonId || !!components.instanceManager.getInstance(sessionId);
14737
+ const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId) || !!components.instanceManager.getInstance(sessionId);
14738
14738
  const providerType = readNonEmptyString2(dispatch.providerType);
14739
14739
  const readArgs = {
14740
14740
  sessionId,
@@ -14809,7 +14809,7 @@ async function collectLiveNodesWithSessions(components, mesh, selfIds, localDaem
14809
14809
  const dispatchMeshCommand = components.dispatchMeshCommand;
14810
14810
  return Promise.all(mesh.nodes.map(async (node) => {
14811
14811
  const nodeDaemonId = readNonEmptyString2(node.daemonId);
14812
- const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || localDaemonId !== void 0 && nodeDaemonId === localDaemonId;
14812
+ const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || daemonIdsEquivalent(nodeDaemonId, localDaemonId);
14813
14813
  let statusResult;
14814
14814
  try {
14815
14815
  if (isLocalNode) {
@@ -19535,6 +19535,7 @@ __export(evaluator_exports, {
19535
19535
  evaluateCondition: () => evaluateCondition,
19536
19536
  extractButtonsFromRule: () => extractButtonsFromRule,
19537
19537
  extractTitle: () => extractTitle,
19538
+ lastContiguousNumberedBlock: () => lastContiguousNumberedBlock,
19538
19539
  resolveSections: () => resolveSections,
19539
19540
  sectionText: () => sectionText
19540
19541
  });
@@ -19775,7 +19776,6 @@ function extractButtonsFromRule(rule, hay) {
19775
19776
  label += " " + next.trim();
19776
19777
  j += 1;
19777
19778
  }
19778
- if (buttons.some((b) => b.index === idx)) continue;
19779
19779
  const key = keyTemplate.replace(/\{index\}/g, String(idx));
19780
19780
  buttons.push({ index: idx, label, key, current });
19781
19781
  i = j - 1;
@@ -19787,13 +19787,22 @@ function extractButtonsFromRule(rule, hay) {
19787
19787
  const idx = Number(m[1]);
19788
19788
  const label = String(m[2] ?? "").trim();
19789
19789
  if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
19790
- if (buttons.some((b) => b.index === idx)) continue;
19791
19790
  const key = keyTemplate.replace(/\{index\}/g, String(idx));
19792
19791
  buttons.push({ index: idx, label, key, current: hasCursorMarker(m[0]) });
19793
19792
  }
19794
19793
  }
19795
- buttons.sort((a, b) => a.index - b.index);
19796
- return buttons;
19794
+ const block2 = lastContiguousNumberedBlock(buttons);
19795
+ block2.sort((a, b) => a.index - b.index);
19796
+ return block2;
19797
+ }
19798
+ function lastContiguousNumberedBlock(entries) {
19799
+ if (entries.length <= 1) return entries.slice();
19800
+ let start = entries.length - 1;
19801
+ for (let i = entries.length - 1; i > 0; i -= 1) {
19802
+ if (entries[i - 1].index === entries[i].index - 1) start = i - 1;
19803
+ else break;
19804
+ }
19805
+ return entries.slice(start);
19797
19806
  }
19798
19807
  function hasCursorMarker(text) {
19799
19808
  return /^\s*[❯›>]/.test(text);
@@ -33848,6 +33857,9 @@ function collectStableSizes(when, sizes) {
33848
33857
  }
33849
33858
  }
33850
33859
 
33860
+ // src/providers/spec/cli-adapter.ts
33861
+ init_evaluator();
33862
+
33851
33863
  // src/providers/spec/native-history-executor.ts
33852
33864
  init_logger();
33853
33865
  init_load_better_sqlite3();
@@ -35062,21 +35074,19 @@ var SpecCliAdapter = class _SpecCliAdapter {
35062
35074
  const ec = action.extract_choices;
35063
35075
  if (!ec?.pattern) return [];
35064
35076
  const text = this.readScreenSectionText(ec.section);
35065
- const out = [];
35066
- const seen = /* @__PURE__ */ new Set();
35077
+ const all = [];
35067
35078
  for (const rawLine of text.split("\n")) {
35068
35079
  const line = rawLine.replace(/\r$/, "");
35069
35080
  const m = new RegExp(ec.pattern, ec.flags ?? "").exec(line);
35070
35081
  if (!m) continue;
35071
35082
  const idx = Number(m[1]);
35072
- if (!Number.isFinite(idx) || seen.has(idx)) continue;
35083
+ if (!Number.isFinite(idx) || idx <= 0) continue;
35073
35084
  const label = (m[2] ?? "").replace(/\s+/g, " ").trim();
35074
35085
  if (!label) continue;
35075
35086
  const current = /^\s*[❯›>]/.test(line) || /[✔✓●]\s*$/.test(label);
35076
- seen.add(idx);
35077
- out.push({ index: idx, label, current });
35087
+ all.push({ index: idx, label, current });
35078
35088
  }
35079
- return out;
35089
+ return lastContiguousNumberedBlock(all);
35080
35090
  }
35081
35091
  /** Live text of a named screen section (or the whole screen when no
35082
35092
  * section is named), resolved from the driver's current sections. */
@@ -44497,6 +44507,7 @@ function buildInstallEnvWithNodeOnPath(baseEnv = process.env) {
44497
44507
  const pathKey = Object.keys(env).find((k) => k.toLowerCase() === "path") || "PATH";
44498
44508
  const current = env[pathKey] || "";
44499
44509
  env[pathKey] = current ? `${nodeBinDir};${current}` : nodeBinDir;
44510
+ env.ADHDEV_BOOTSTRAP = "1";
44500
44511
  return env;
44501
44512
  }
44502
44513
  function getNpmExecOptions(platform10 = process.platform) {
@@ -44606,6 +44617,94 @@ async function stopSessionHostProcesses(appName) {
44606
44617
  await waitForPidExit(killedPid, 15e3);
44607
44618
  }
44608
44619
  }
44620
+ var LOCKED_NATIVE_ADDON_BASENAMES = ["conpty.node", "ghostty-vt.dll"];
44621
+ function listForeignNativeAddonHolders(packageRoot) {
44622
+ if (process.platform !== "win32" || !packageRoot) return [];
44623
+ const rootLower = packageRoot.replace(/\//g, "\\").replace(/'/g, "''").toLowerCase();
44624
+ const endsWithChecks = LOCKED_NATIVE_ADDON_BASENAMES.map((name) => `$lf.EndsWith('${name}')`).join(" -or ");
44625
+ const script = [
44626
+ `$root = '${rootLower}'`,
44627
+ `Get-Process node -ErrorAction SilentlyContinue | ForEach-Object {`,
44628
+ ` $p = $_`,
44629
+ ` try {`,
44630
+ ` foreach ($m in $p.Modules) {`,
44631
+ ` $fn = $m.FileName`,
44632
+ ` if ($fn) {`,
44633
+ ` $lf = $fn.ToLower()`,
44634
+ ` if ($lf.StartsWith($root) -and (${endsWithChecks})) { $p.Id; break }`,
44635
+ ` }`,
44636
+ ` }`,
44637
+ ` } catch {}`,
44638
+ `}`
44639
+ ].join("\n");
44640
+ let out = "";
44641
+ try {
44642
+ out = String(execFileSync5("powershell.exe", [
44643
+ "-NoProfile",
44644
+ "-NonInteractive",
44645
+ "-ExecutionPolicy",
44646
+ "Bypass",
44647
+ "-Command",
44648
+ script
44649
+ ], { encoding: "utf8", timeout: 8e3, stdio: ["ignore", "pipe", "ignore"], windowsHide: true })).trim();
44650
+ } catch {
44651
+ return [];
44652
+ }
44653
+ const selfPid = process.pid;
44654
+ const seen = /* @__PURE__ */ new Set();
44655
+ const holders = [];
44656
+ for (const line of out.split(/\r?\n/)) {
44657
+ const pid = Number.parseInt(line.trim(), 10);
44658
+ if (!Number.isFinite(pid) || pid <= 0 || pid === selfPid || seen.has(pid)) continue;
44659
+ seen.add(pid);
44660
+ holders.push({ pid, commandLine: getProcessCommandLine(pid) });
44661
+ }
44662
+ return holders;
44663
+ }
44664
+ async function stopForeignNativeAddonHolders(packageRoot, options = {}) {
44665
+ if (process.platform !== "win32" || !packageRoot) return [];
44666
+ const parentPid = Number.isFinite(options.parentPid) ? Number(options.parentPid) : -1;
44667
+ const holders = listForeignNativeAddonHolders(packageRoot);
44668
+ const results = [];
44669
+ for (const holder of holders) {
44670
+ if (holder.pid === parentPid) continue;
44671
+ appendUpgradeLog(
44672
+ `Foreign native-addon holder found: pid ${holder.pid}${holder.commandLine ? ` \u2014 ${holder.commandLine}` : ""}`
44673
+ );
44674
+ const killed = killPid(holder.pid);
44675
+ if (killed) {
44676
+ await waitForPidExit(holder.pid, 15e3);
44677
+ appendUpgradeLog(`Terminated foreign native-addon holder pid ${holder.pid}`);
44678
+ } else {
44679
+ appendUpgradeLog(`Failed to terminate foreign native-addon holder pid ${holder.pid}`);
44680
+ }
44681
+ results.push({ ...holder, killed });
44682
+ }
44683
+ return results;
44684
+ }
44685
+ function getUpgradeFailureNoticePath() {
44686
+ const home = os27.homedir();
44687
+ const dir = path36.join(home, ".adhdev");
44688
+ try {
44689
+ fs25.mkdirSync(dir, { recursive: true });
44690
+ } catch {
44691
+ }
44692
+ return path36.join(dir, "daemon-upgrade-last-error.txt");
44693
+ }
44694
+ function buildManualRecoveryCommand(installCommand) {
44695
+ return [installCommand.command, ...installCommand.args].map((part) => /\s/.test(part) ? `"${part}"` : part).join(" ");
44696
+ }
44697
+ function emitUpgradeFailureNotice(lines) {
44698
+ const body = lines.join("\n");
44699
+ appendUpgradeLog(`Upgrade blocked \u2014 user action required:
44700
+ ${body}`);
44701
+ try {
44702
+ fs25.writeFileSync(getUpgradeFailureNoticePath(), `[${(/* @__PURE__ */ new Date()).toISOString()}]
44703
+ ${body}
44704
+ `, "utf8");
44705
+ } catch {
44706
+ }
44707
+ }
44609
44708
  function isRetriableInstallLockError(error) {
44610
44709
  const code = error?.code;
44611
44710
  if (code === "EBUSY" || code === "EPERM") return true;
@@ -44692,6 +44791,7 @@ async function runDaemonUpgradeHelper(payload) {
44692
44791
  }
44693
44792
  await stopSessionHostProcesses(sessionHostAppName);
44694
44793
  removeDaemonPidFile();
44794
+ await stopForeignNativeAddonHolders(installCommand.surface.packageRoot, { parentPid: payload.parentPid });
44695
44795
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
44696
44796
  const spec = `${payload.packageName}@${payload.targetVersion || "latest"}`;
44697
44797
  appendUpgradeLog(`Installing ${spec}`);
@@ -44713,11 +44813,30 @@ async function runDaemonUpgradeHelper(payload) {
44713
44813
  break;
44714
44814
  } catch (error) {
44715
44815
  if (attempt < maxInstallAttempts && isRetriableInstallLockError(error)) {
44716
- appendUpgradeLog(`Install attempt ${attempt} hit a file lock (${error?.code || "lock"}); cleaning staging and retrying after backoff`);
44816
+ appendUpgradeLog(`Install attempt ${attempt} hit a file lock (${error?.code || "lock"}); clearing holders + staging and retrying after backoff`);
44817
+ await stopForeignNativeAddonHolders(installCommand.surface.packageRoot, { parentPid: payload.parentPid });
44717
44818
  cleanupStaleGlobalInstallDirs(payload.packageName, installCommand.surface);
44718
44819
  await new Promise((resolve24) => setTimeout(resolve24, attempt * 1500));
44719
44820
  continue;
44720
44821
  }
44822
+ if (isRetriableInstallLockError(error)) {
44823
+ const blockers = listForeignNativeAddonHolders(installCommand.surface.packageRoot);
44824
+ const notice = [
44825
+ `adhdev ${spec} could not be installed: a file lock (${error?.code || "EBUSY/EPERM"}) is blocking the native addon.`
44826
+ ];
44827
+ if (blockers.length > 0) {
44828
+ notice.push("Processes still holding the lock:");
44829
+ for (const b of blockers) {
44830
+ notice.push(` pid ${b.pid}${b.commandLine ? ` \u2014 ${b.commandLine}` : ""}`);
44831
+ }
44832
+ notice.push("To recover, stop them and reinstall:");
44833
+ notice.push(` Stop-Process -Id ${blockers.map((b) => b.pid).join(",")} -Force`);
44834
+ } else {
44835
+ notice.push("To recover, reinstall manually:");
44836
+ }
44837
+ notice.push(` ${buildManualRecoveryCommand(installCommand)}`);
44838
+ emitUpgradeFailureNotice(notice);
44839
+ }
44721
44840
  throw error;
44722
44841
  }
44723
44842
  }
@@ -47384,7 +47503,7 @@ var DaemonCommandRouter = class {
47384
47503
  return sanitizedInlineMesh;
47385
47504
  }
47386
47505
  async getMeshForCommand(meshId, inlineMesh, options) {
47387
- const preferInline = options?.preferInline === true;
47506
+ const preferInline = options?.preferInline !== false;
47388
47507
  if (preferInline) {
47389
47508
  const cached4 = this.getCachedInlineMesh(meshId);
47390
47509
  if (cached4) {
@@ -51743,7 +51862,7 @@ ${ptyResult.output.slice(-2e3)}`);
51743
51862
  workspace
51744
51863
  };
51745
51864
  }
51746
- const { existsSync: existsSync46, readFileSync: readFileSync37, writeFileSync: writeFileSync23, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
51865
+ const { existsSync: existsSync46, readFileSync: readFileSync37, writeFileSync: writeFileSync24, copyFileSync: copyFileSync4, mkdirSync: mkdirSync21 } = await import("fs");
51747
51866
  const { dirname: dirname17 } = await import("path");
51748
51867
  const mcpConfigPath = coordinatorSetup.configPath;
51749
51868
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
@@ -51816,7 +51935,7 @@ ${ptyResult.output.slice(-2e3)}`);
51816
51935
  }
51817
51936
  };
51818
51937
  try {
51819
- writeFileSync23(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
51938
+ writeFileSync24(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), "utf-8");
51820
51939
  } catch (error) {
51821
51940
  const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
51822
51941
  LOG.error("MeshCoordinator", message);