@adhdev/daemon-core 0.9.82-rc.386 → 0.9.82-rc.388

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
@@ -378,10 +378,10 @@ function readInjected(value) {
378
378
  }
379
379
  function getDaemonBuildInfo() {
380
380
  if (cached) return cached;
381
- const commit = readInjected(true ? "fad1d175ca84a75f52bd0c1d88125fbb783ad241" : void 0) ?? "unknown";
382
- const commitShort = readInjected(true ? "fad1d175" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
- const version = readInjected(true ? "0.9.82-rc.386" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
- const builtAt = readInjected(true ? "2026-06-26T00:12:44.100Z" : void 0);
381
+ const commit = readInjected(true ? "9a3033a1679a8f914b9b40753006af02a09bc1b5" : void 0) ?? "unknown";
382
+ const commitShort = readInjected(true ? "9a3033a1" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
383
+ const version = readInjected(true ? "0.9.82-rc.388" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
384
+ const builtAt = readInjected(true ? "2026-06-26T03:26:15.684Z" : void 0);
385
385
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
386
386
  return cached;
387
387
  }
@@ -1408,6 +1408,7 @@ var init_git_diff = __esm({
1408
1408
  var git_worktree_exports = {};
1409
1409
  __export(git_worktree_exports, {
1410
1410
  createWorktree: () => createWorktree,
1411
+ deleteBranchRef: () => deleteBranchRef,
1411
1412
  listWorktrees: () => listWorktrees,
1412
1413
  parseWorktreeListOutput: () => parseWorktreeListOutput,
1413
1414
  removeWorktree: () => removeWorktree,
@@ -1555,6 +1556,53 @@ function parseWorktreeListOutput(output) {
1555
1556
  }
1556
1557
  return entries;
1557
1558
  }
1559
+ async function deleteBranchRef(repoRoot, branch, opts = {}) {
1560
+ const name = (branch || "").trim();
1561
+ if (!name) return { deleted: false, reason: "empty_branch_name" };
1562
+ try {
1563
+ await execFileAsync2("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${name}`], {
1564
+ cwd: repoRoot,
1565
+ encoding: "utf8",
1566
+ timeout: GIT_TIMEOUT_MS,
1567
+ maxBuffer: GIT_MAX_BUFFER,
1568
+ windowsHide: true
1569
+ });
1570
+ } catch {
1571
+ return { deleted: true, reason: "branch_ref_absent" };
1572
+ }
1573
+ try {
1574
+ await execFileAsync2("git", ["branch", "-d", name], {
1575
+ cwd: repoRoot,
1576
+ encoding: "utf8",
1577
+ timeout: GIT_TIMEOUT_MS,
1578
+ maxBuffer: GIT_MAX_BUFFER,
1579
+ windowsHide: true
1580
+ });
1581
+ return { deleted: true, reason: "safe_deleted_merged_branch" };
1582
+ } catch (error) {
1583
+ const stderr = typeof error?.stderr === "string" ? error.stderr : "";
1584
+ const notMerged = /not fully merged/i.test(stderr) || /not fully merged/i.test(String(error?.message || ""));
1585
+ if (!notMerged) {
1586
+ return { deleted: false, reason: `branch_delete_failed: ${stderr.trim() || error?.message || "unknown error"}` };
1587
+ }
1588
+ if (opts.safeDeleteOnly) {
1589
+ return { deleted: false, reason: "branch_not_merged_per_git_safe_delete_only" };
1590
+ }
1591
+ try {
1592
+ await execFileAsync2("git", ["branch", "-D", name], {
1593
+ cwd: repoRoot,
1594
+ encoding: "utf8",
1595
+ timeout: GIT_TIMEOUT_MS,
1596
+ maxBuffer: GIT_MAX_BUFFER,
1597
+ windowsHide: true
1598
+ });
1599
+ return { deleted: true, reason: "force_deleted_patch_equivalent_branch", forced: true };
1600
+ } catch (forceError) {
1601
+ const fErr = typeof forceError?.stderr === "string" ? forceError.stderr : forceError?.message;
1602
+ return { deleted: false, reason: `branch_force_delete_failed: ${String(fErr || "unknown error").trim()}` };
1603
+ }
1604
+ }
1605
+ }
1558
1606
  async function pruneWorktrees(repoRoot) {
1559
1607
  try {
1560
1608
  await execFileAsync2("git", ["worktree", "prune"], {
@@ -4415,6 +4463,12 @@ function isMutationKeywordInCommandContext(text, matchStart, matchEnd) {
4415
4463
  const linePrefix = text.slice(lineStart, matchStart);
4416
4464
  if (/^\s*[$>]\s/.test(text.slice(lineStart))) return true;
4417
4465
  if (/^\s*$/.test(linePrefix)) return true;
4466
+ let tokStart = matchStart;
4467
+ while (tokStart > lineStart && !/\s/.test(text[tokStart - 1])) tokStart--;
4468
+ const beforeToken = text.slice(lineStart, tokStart);
4469
+ const tokenLead = text.slice(tokStart, matchStart);
4470
+ const atCmdPos = /^\s*$/.test(beforeToken) || /(?:&&|\|\||\||;)\s*$/.test(beforeToken);
4471
+ if (atCmdPos && /^(?:\.\/|\.\.\/|~\/|\/)/.test(tokenLead)) return true;
4418
4472
  if (/(?:&&|\|\||\||;)\s*$/.test(linePrefix)) return true;
4419
4473
  if (/(?:^|[\s,])(?:then|run|first)\s+$/i.test(linePrefix)) return true;
4420
4474
  if (/,\s*$/.test(linePrefix)) return true;
@@ -4441,9 +4495,65 @@ function isInsideBackticksOrFence(text, matchStart, matchEnd) {
4441
4495
  }
4442
4496
  return inlineCount % 2 === 1;
4443
4497
  }
4498
+ function isInsidePathSegment(text, matchStart, matchEnd) {
4499
+ const prev = matchStart > 0 ? text[matchStart - 1] : "";
4500
+ const next = matchEnd < text.length ? text[matchEnd] : "";
4501
+ const isSep = (c) => c === "/" || c === "\\";
4502
+ const segChar = (c) => /[A-Za-z0-9._~-]/.test(c);
4503
+ const inPath = isSep(prev) && (next === "" || isSep(next) || segChar(next) || /\s/.test(next)) || isSep(next) && (prev === "" || isSep(prev) || segChar(prev) || /\s/.test(prev));
4504
+ if (!inPath) return false;
4505
+ const lineStart = text.lastIndexOf("\n", matchStart - 1) + 1;
4506
+ let tokStart = matchStart;
4507
+ while (tokStart > lineStart && !/\s/.test(text[tokStart - 1])) tokStart--;
4508
+ const linePrefixBeforeToken = text.slice(lineStart, tokStart);
4509
+ const tokenPrefix = text.slice(tokStart, matchStart);
4510
+ const atLineStart = /^\s*$/.test(linePrefixBeforeToken);
4511
+ const afterConnective = /(?:&&|\|\||\||;)\s*$/.test(linePrefixBeforeToken);
4512
+ const isRunPrefixPath = /^(?:\.\/|\.\.\/|~\/|\/)/.test(tokenPrefix);
4513
+ if ((atLineStart || afterConnective) && isRunPrefixPath) return false;
4514
+ return true;
4515
+ }
4516
+ function isInsideQuotedSpan(text, matchStart, matchEnd) {
4517
+ const pairs = [
4518
+ ["\u201C", "\u201D"],
4519
+ ["\u2018", "\u2019"],
4520
+ ["\u300C", "\u300D"],
4521
+ ["\u300E", "\u300F"],
4522
+ ["\u300A", "\u300B"]
4523
+ ];
4524
+ for (const [open, close] of pairs) {
4525
+ const openIdx = text.lastIndexOf(open, matchStart - 1);
4526
+ if (openIdx < 0) continue;
4527
+ if (text.indexOf(close, openIdx + open.length) >= matchEnd) return true;
4528
+ }
4529
+ const lineStart = text.lastIndexOf("\n", matchStart - 1) + 1;
4530
+ const lineEnd = (() => {
4531
+ const i = text.indexOf("\n", matchEnd);
4532
+ return i < 0 ? text.length : i;
4533
+ })();
4534
+ for (const q of ['"', "'"]) {
4535
+ let count = 0;
4536
+ for (let i = lineStart; i < matchStart; i++) if (text[i] === q) count++;
4537
+ if (count % 2 === 1 && text.indexOf(q, matchEnd) >= 0 && text.indexOf(q, matchEnd) < lineEnd) {
4538
+ if (q === '"') return true;
4539
+ let openPos = -1, c = 0;
4540
+ for (let i = lineStart; i < matchStart; i++) {
4541
+ if (text[i] === q) {
4542
+ c++;
4543
+ if (c % 2 === 1) openPos = i;
4544
+ }
4545
+ }
4546
+ const beforeOpen = openPos > lineStart ? text[openPos - 1] : " ";
4547
+ if (/[\s(\[{>]/.test(beforeOpen) || openPos === lineStart) return true;
4548
+ }
4549
+ }
4550
+ return false;
4551
+ }
4444
4552
  function isRealMutationMatch(text, matchStart, matchEnd) {
4445
4553
  if (hasNegationBefore(text, matchStart)) return false;
4446
4554
  if (hasTrailingNegation(text, matchEnd)) return false;
4555
+ if (isInsidePathSegment(text, matchStart, matchEnd)) return false;
4556
+ if (isInsideQuotedSpan(text, matchStart, matchEnd)) return false;
4447
4557
  return isMutationKeywordInCommandContext(text, matchStart, matchEnd);
4448
4558
  }
4449
4559
  function patternHasRealMutation(pattern, text) {
@@ -47221,13 +47331,16 @@ var meshCrudHandlers = {
47221
47331
  worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0,
47222
47332
  worktreeCleanupFallback: typeof worktreeCleanup?.fallback === "string" ? worktreeCleanup.fallback : void 0,
47223
47333
  forced: worktreeCleanup?.forced === true ? true : void 0,
47224
- forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0
47334
+ forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0,
47335
+ branchRefDeleted: typeof worktreeCleanup?.branchRefDeleted === "boolean" ? worktreeCleanup.branchRefDeleted : void 0,
47336
+ branchRefReason: typeof worktreeCleanup?.branchRefReason === "string" ? worktreeCleanup.branchRefReason : void 0
47225
47337
  }
47226
47338
  });
47227
47339
  } catch {
47228
47340
  }
47229
47341
  }
47230
47342
  const residueWarning = worktreeCleanup?.residue === true && typeof worktreeCleanup?.residueWarning === "string" ? worktreeCleanup.residueWarning : void 0;
47343
+ const branchRefWarning = typeof worktreeCleanup?.branchRefWarning === "string" ? worktreeCleanup.branchRefWarning : void 0;
47231
47344
  const skippedLiveSessionIds = Array.isArray(sessionCleanup?.skippedLiveSessionIds) ? sessionCleanup.skippedLiveSessionIds.filter((v) => typeof v === "string") : [];
47232
47345
  const orphanedSessionsRemaining = skippedLiveSessionIds.length > 0;
47233
47346
  const orphanNextAction = orphanedSessionsRemaining ? `Live session(s) [${skippedLiveSessionIds.join(", ")}] were skipped and still survive this node removal. Run mesh_cleanup_sessions with mode:'stop_and_delete' and sessionIds:[${skippedLiveSessionIds.map((id) => `'${id}'`).join(", ")}] to release them.` : void 0;
@@ -47235,6 +47348,7 @@ var meshCrudHandlers = {
47235
47348
  success: true,
47236
47349
  removed,
47237
47350
  ...residueWarning ? { residueWarning } : {},
47351
+ ...branchRefWarning ? { branchRefWarning } : {},
47238
47352
  ...sessionCleanup ? { sessionCleanup } : {},
47239
47353
  ...worktreeCleanup ? { worktreeCleanup } : {},
47240
47354
  ...orphanedSessionsRemaining ? { orphanedSessionsRemaining: true, nextAction: orphanNextAction } : {}
@@ -52504,16 +52618,50 @@ var DaemonCommandRouter = class {
52504
52618
  recoveryHint: "Inspect the worktree branch and mesh metadata before retrying cleanup."
52505
52619
  };
52506
52620
  }
52507
- const forceFallbackConvergence = args.force ? { allow: true, status: "force_override", source: "caller_force_flag" } : await this.getWorktreeForceCleanupConvergence({ repoRoot, workspace, node: args.node });
52621
+ const mergeConvergence = await this.getWorktreeForceCleanupConvergence({ repoRoot, workspace, node: args.node });
52622
+ const forceFallbackConvergence = args.force ? { allow: true, status: "force_override", source: "caller_force_flag" } : mergeConvergence;
52623
+ const deleteBranchIfMerged = async () => {
52624
+ const branch = String(args.node.worktreeBranch).trim();
52625
+ const status = mergeConvergence.allow ? mergeConvergence.status || "" : "";
52626
+ const MERGED_STATUSES = /* @__PURE__ */ new Set([
52627
+ "merged_to_main",
52628
+ "merged_pushed",
52629
+ "merged_to_default_ref",
52630
+ "cleanup_candidate"
52631
+ ]);
52632
+ const PATCH_EQUIV_STATUS = "patch_equivalent_to_default_ref";
52633
+ if (!branch) {
52634
+ return { branchRefDeleted: false, branchRefReason: "empty_branch_name" };
52635
+ }
52636
+ if (!mergeConvergence.allow || !MERGED_STATUSES.has(status) && status !== PATCH_EQUIV_STATUS) {
52637
+ return {
52638
+ branchRefDeleted: false,
52639
+ branchRefReason: `branch_not_merged_preserved: ${mergeConvergence.error || mergeConvergence.status || "convergence_unverified"}`,
52640
+ branchRefWarning: `Branch ref '${branch}' was preserved (not deleted) because it is not confirmed merged into the default ref \u2014 no work was lost. Merge it (or pass a verified branchConvergence final state) and re-run cleanup, or delete it manually after confirming.`
52641
+ };
52642
+ }
52643
+ const { deleteBranchRef: deleteBranchRef2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
52644
+ const res = await deleteBranchRef2(repoRoot, branch, { safeDeleteOnly: status !== PATCH_EQUIV_STATUS });
52645
+ return {
52646
+ branchRefDeleted: res.deleted,
52647
+ branchRefReason: res.reason,
52648
+ ...res.forced ? { branchRefForced: true } : {},
52649
+ ...res.deleted ? {} : {
52650
+ branchRefWarning: `Branch ref '${branch}' could not be deleted (${res.reason}); it was preserved so no work is lost.`
52651
+ }
52652
+ };
52653
+ };
52508
52654
  try {
52509
52655
  const result = await removeWorktree2(repoRoot, workspace, {
52510
52656
  requireClean: !args.force,
52511
52657
  allowSubmoduleForceFallback: forceFallbackConvergence.allow
52512
52658
  });
52659
+ const branchOutcome = await deleteBranchIfMerged();
52513
52660
  return {
52514
52661
  success: true,
52515
52662
  removedPath: result.removedPath,
52516
52663
  repoRoot,
52664
+ ...branchOutcome,
52517
52665
  ...result.fallback ? {
52518
52666
  fallback: result.fallback,
52519
52667
  forced: result.forced,
@@ -52546,10 +52694,12 @@ var DaemonCommandRouter = class {
52546
52694
  maxBuffer: GIT_MAX_BUFFER_CLEANUP,
52547
52695
  windowsHide: true
52548
52696
  });
52697
+ const branchOutcome = await deleteBranchIfMerged();
52549
52698
  return {
52550
52699
  success: true,
52551
52700
  removedPath: workspace,
52552
52701
  repoRoot,
52702
+ ...branchOutcome,
52553
52703
  fallback: "git_worktree_remove_submodule_deinit",
52554
52704
  forced: true,
52555
52705
  reason: "working_trees_containing_submodules",
@@ -52567,10 +52717,12 @@ var DaemonCommandRouter = class {
52567
52717
  });
52568
52718
  } catch {
52569
52719
  }
52720
+ const branchOutcome = await deleteBranchIfMerged();
52570
52721
  return {
52571
52722
  success: true,
52572
52723
  removedPath: workspace,
52573
52724
  repoRoot,
52725
+ ...branchOutcome,
52574
52726
  fallback: "fs_rm_worktree_prune",
52575
52727
  forced: true,
52576
52728
  reason: "working_trees_containing_submodules",