@adhdev/daemon-standalone 0.9.82-rc.385 → 0.9.82-rc.387

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
@@ -30108,10 +30108,10 @@ var require_dist3 = __commonJS({
30108
30108
  }
30109
30109
  function getDaemonBuildInfo() {
30110
30110
  if (cached2) return cached2;
30111
- const commit = readInjected(true ? "3aa3e12839017da30b44a64ca6c20f0c9730fae2" : void 0) ?? "unknown";
30112
- const commitShort = readInjected(true ? "3aa3e128" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30113
- const version2 = readInjected(true ? "0.9.82-rc.385" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30114
- const builtAt = readInjected(true ? "2026-06-25T16:17:00.115Z" : void 0);
30111
+ const commit = readInjected(true ? "057d5def5d55af124dfe910ee9accdf244576c14" : void 0) ?? "unknown";
30112
+ const commitShort = readInjected(true ? "057d5def" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30113
+ const version2 = readInjected(true ? "0.9.82-rc.387" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30114
+ const builtAt = readInjected(true ? "2026-06-26T02:21:54.536Z" : void 0);
30115
30115
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
30116
30116
  return cached2;
30117
30117
  }
@@ -31142,6 +31142,7 @@ var require_dist3 = __commonJS({
31142
31142
  var git_worktree_exports = {};
31143
31143
  __export2(git_worktree_exports, {
31144
31144
  createWorktree: () => createWorktree,
31145
+ deleteBranchRef: () => deleteBranchRef,
31145
31146
  listWorktrees: () => listWorktrees,
31146
31147
  parseWorktreeListOutput: () => parseWorktreeListOutput,
31147
31148
  removeWorktree: () => removeWorktree,
@@ -31284,6 +31285,53 @@ ${error48.message || ""}`;
31284
31285
  }
31285
31286
  return entries;
31286
31287
  }
31288
+ async function deleteBranchRef(repoRoot, branch, opts = {}) {
31289
+ const name = (branch || "").trim();
31290
+ if (!name) return { deleted: false, reason: "empty_branch_name" };
31291
+ try {
31292
+ await execFileAsync2("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${name}`], {
31293
+ cwd: repoRoot,
31294
+ encoding: "utf8",
31295
+ timeout: GIT_TIMEOUT_MS,
31296
+ maxBuffer: GIT_MAX_BUFFER,
31297
+ windowsHide: true
31298
+ });
31299
+ } catch {
31300
+ return { deleted: true, reason: "branch_ref_absent" };
31301
+ }
31302
+ try {
31303
+ await execFileAsync2("git", ["branch", "-d", name], {
31304
+ cwd: repoRoot,
31305
+ encoding: "utf8",
31306
+ timeout: GIT_TIMEOUT_MS,
31307
+ maxBuffer: GIT_MAX_BUFFER,
31308
+ windowsHide: true
31309
+ });
31310
+ return { deleted: true, reason: "safe_deleted_merged_branch" };
31311
+ } catch (error48) {
31312
+ const stderr = typeof error48?.stderr === "string" ? error48.stderr : "";
31313
+ const notMerged = /not fully merged/i.test(stderr) || /not fully merged/i.test(String(error48?.message || ""));
31314
+ if (!notMerged) {
31315
+ return { deleted: false, reason: `branch_delete_failed: ${stderr.trim() || error48?.message || "unknown error"}` };
31316
+ }
31317
+ if (opts.safeDeleteOnly) {
31318
+ return { deleted: false, reason: "branch_not_merged_per_git_safe_delete_only" };
31319
+ }
31320
+ try {
31321
+ await execFileAsync2("git", ["branch", "-D", name], {
31322
+ cwd: repoRoot,
31323
+ encoding: "utf8",
31324
+ timeout: GIT_TIMEOUT_MS,
31325
+ maxBuffer: GIT_MAX_BUFFER,
31326
+ windowsHide: true
31327
+ });
31328
+ return { deleted: true, reason: "force_deleted_patch_equivalent_branch", forced: true };
31329
+ } catch (forceError) {
31330
+ const fErr = typeof forceError?.stderr === "string" ? forceError.stderr : forceError?.message;
31331
+ return { deleted: false, reason: `branch_force_delete_failed: ${String(fErr || "unknown error").trim()}` };
31332
+ }
31333
+ }
31334
+ }
31287
31335
  async function pruneWorktrees(repoRoot) {
31288
31336
  try {
31289
31337
  await execFileAsync2("git", ["worktree", "prune"], {
@@ -34189,6 +34237,12 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34189
34237
  const linePrefix = text.slice(lineStart, matchStart);
34190
34238
  if (/^\s*[$>]\s/.test(text.slice(lineStart))) return true;
34191
34239
  if (/^\s*$/.test(linePrefix)) return true;
34240
+ let tokStart = matchStart;
34241
+ while (tokStart > lineStart && !/\s/.test(text[tokStart - 1])) tokStart--;
34242
+ const beforeToken = text.slice(lineStart, tokStart);
34243
+ const tokenLead = text.slice(tokStart, matchStart);
34244
+ const atCmdPos = /^\s*$/.test(beforeToken) || /(?:&&|\|\||\||;)\s*$/.test(beforeToken);
34245
+ if (atCmdPos && /^(?:\.\/|\.\.\/|~\/|\/)/.test(tokenLead)) return true;
34192
34246
  if (/(?:&&|\|\||\||;)\s*$/.test(linePrefix)) return true;
34193
34247
  if (/(?:^|[\s,])(?:then|run|first)\s+$/i.test(linePrefix)) return true;
34194
34248
  if (/,\s*$/.test(linePrefix)) return true;
@@ -34215,9 +34269,65 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
34215
34269
  }
34216
34270
  return inlineCount % 2 === 1;
34217
34271
  }
34272
+ function isInsidePathSegment(text, matchStart, matchEnd) {
34273
+ const prev = matchStart > 0 ? text[matchStart - 1] : "";
34274
+ const next = matchEnd < text.length ? text[matchEnd] : "";
34275
+ const isSep = (c) => c === "/" || c === "\\";
34276
+ const segChar = (c) => /[A-Za-z0-9._~-]/.test(c);
34277
+ const inPath = isSep(prev) && (next === "" || isSep(next) || segChar(next) || /\s/.test(next)) || isSep(next) && (prev === "" || isSep(prev) || segChar(prev) || /\s/.test(prev));
34278
+ if (!inPath) return false;
34279
+ const lineStart = text.lastIndexOf("\n", matchStart - 1) + 1;
34280
+ let tokStart = matchStart;
34281
+ while (tokStart > lineStart && !/\s/.test(text[tokStart - 1])) tokStart--;
34282
+ const linePrefixBeforeToken = text.slice(lineStart, tokStart);
34283
+ const tokenPrefix = text.slice(tokStart, matchStart);
34284
+ const atLineStart = /^\s*$/.test(linePrefixBeforeToken);
34285
+ const afterConnective = /(?:&&|\|\||\||;)\s*$/.test(linePrefixBeforeToken);
34286
+ const isRunPrefixPath = /^(?:\.\/|\.\.\/|~\/|\/)/.test(tokenPrefix);
34287
+ if ((atLineStart || afterConnective) && isRunPrefixPath) return false;
34288
+ return true;
34289
+ }
34290
+ function isInsideQuotedSpan(text, matchStart, matchEnd) {
34291
+ const pairs = [
34292
+ ["\u201C", "\u201D"],
34293
+ ["\u2018", "\u2019"],
34294
+ ["\u300C", "\u300D"],
34295
+ ["\u300E", "\u300F"],
34296
+ ["\u300A", "\u300B"]
34297
+ ];
34298
+ for (const [open, close] of pairs) {
34299
+ const openIdx = text.lastIndexOf(open, matchStart - 1);
34300
+ if (openIdx < 0) continue;
34301
+ if (text.indexOf(close, openIdx + open.length) >= matchEnd) return true;
34302
+ }
34303
+ const lineStart = text.lastIndexOf("\n", matchStart - 1) + 1;
34304
+ const lineEnd = (() => {
34305
+ const i = text.indexOf("\n", matchEnd);
34306
+ return i < 0 ? text.length : i;
34307
+ })();
34308
+ for (const q of ['"', "'"]) {
34309
+ let count = 0;
34310
+ for (let i = lineStart; i < matchStart; i++) if (text[i] === q) count++;
34311
+ if (count % 2 === 1 && text.indexOf(q, matchEnd) >= 0 && text.indexOf(q, matchEnd) < lineEnd) {
34312
+ if (q === '"') return true;
34313
+ let openPos = -1, c = 0;
34314
+ for (let i = lineStart; i < matchStart; i++) {
34315
+ if (text[i] === q) {
34316
+ c++;
34317
+ if (c % 2 === 1) openPos = i;
34318
+ }
34319
+ }
34320
+ const beforeOpen = openPos > lineStart ? text[openPos - 1] : " ";
34321
+ if (/[\s(\[{>]/.test(beforeOpen) || openPos === lineStart) return true;
34322
+ }
34323
+ }
34324
+ return false;
34325
+ }
34218
34326
  function isRealMutationMatch(text, matchStart, matchEnd) {
34219
34327
  if (hasNegationBefore(text, matchStart)) return false;
34220
34328
  if (hasTrailingNegation(text, matchEnd)) return false;
34329
+ if (isInsidePathSegment(text, matchStart, matchEnd)) return false;
34330
+ if (isInsideQuotedSpan(text, matchStart, matchEnd)) return false;
34221
34331
  return isMutationKeywordInCommandContext(text, matchStart, matchEnd);
34222
34332
  }
34223
34333
  function patternHasRealMutation(pattern, text) {
@@ -65849,6 +65959,17 @@ ${body}
65849
65959
  hasIdleHoldPending() {
65850
65960
  return (this.lastFsmEval?.transitions ?? []).some((t) => !t.holdSatisfied && t.condResult);
65851
65961
  }
65962
+ /**
65963
+ * True once the machine has reached its first non-initial idle state (the
65964
+ * prompt is genuinely drawn — see maybeMarkReady). The cli-adapter surfaces
65965
+ * this on its idle status so CliProviderInstance can re-arm the queue-claim
65966
+ * agent:ready on the first genuine ready, independent of the boot-time
65967
+ * starting→idle one-shot (which is consumed too early for specs whose
65968
+ * initial state already reports idle).
65969
+ */
65970
+ hasSeenReady() {
65971
+ return this.readySeenOnce;
65972
+ }
65852
65973
  getCompletionIdleDebounceState() {
65853
65974
  const out = outgoingTransitions(this.spec, this.currentStateId);
65854
65975
  const toReady = this.lastFsmEval?.transitions.find((t, i) => {
@@ -67505,7 +67626,7 @@ ${body}
67505
67626
  if (state.status === "generating") {
67506
67627
  return { status: "generating", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
67507
67628
  }
67508
- return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
67629
+ return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, fsmReadySeen: this.driver.hasSeenReady?.() ?? false, ...sessionFields };
67509
67630
  }
67510
67631
  maybeRefreshNativeHistory() {
67511
67632
  }
@@ -68538,6 +68659,14 @@ ${body}
68538
68659
  context = null;
68539
68660
  events = [];
68540
68661
  lastStatus = "starting";
68662
+ // Idempotency guard for the queue-claim agent:ready event. agent:ready is the
68663
+ // sole signal the mesh coordinator's tryAssignQueueTask waits on to hand a
68664
+ // queued task to this worker. It is emitted in two places: the boot-time
68665
+ // starting→idle one-shot, and the readySeen re-arm below. This flag makes the
68666
+ // event fire AT MOST ONCE per session so a worker is never claimed twice and a
68667
+ // queued task is never double-dispatched/double-injected. Whichever path fires
68668
+ // first sets it; the other becomes a no-op.
68669
+ agentReadyEmitted = false;
68541
68670
  generatingStartedAt = 0;
68542
68671
  settings = {};
68543
68672
  monitor;
@@ -69618,6 +69747,17 @@ ${body}
69618
69747
  } catch {
69619
69748
  }
69620
69749
  }
69750
+ /**
69751
+ * Emit the queue-claim agent:ready event at most once per session. Both the
69752
+ * boot-time starting→idle one-shot and the fsmReadySeen re-arm call this; the
69753
+ * agentReadyEmitted guard ensures the second caller is a no-op so a worker is
69754
+ * never claimed twice and a queued task is never double-dispatched.
69755
+ */
69756
+ emitAgentReadyOnce(chatTitle, now) {
69757
+ if (this.agentReadyEmitted) return;
69758
+ this.agentReadyEmitted = true;
69759
+ this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
69760
+ }
69621
69761
  detectStatusTransition() {
69622
69762
  const now = Date.now();
69623
69763
  const adapterStatus = this.adapter.getStatus({ allowParse: false });
@@ -69770,7 +69910,7 @@ ${body}
69770
69910
  this.scheduleCompletedDebounceFlush(flushDelay);
69771
69911
  }
69772
69912
  } else if (newStatus === "idle" && this.lastStatus === "starting") {
69773
- this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
69913
+ this.emitAgentReadyOnce(chatTitle, now);
69774
69914
  } else if (newStatus === "error") {
69775
69915
  if (this.generatingDebounceTimer) {
69776
69916
  clearTimeout(this.generatingDebounceTimer);
@@ -69809,6 +69949,9 @@ ${body}
69809
69949
  }
69810
69950
  this.lastStatus = newStatus;
69811
69951
  }
69952
+ if (newStatus === "idle" && adapterStatus.fsmReadySeen === true && !this.agentReadyEmitted) {
69953
+ this.emitAgentReadyOnce(chatTitle, now);
69954
+ }
69812
69955
  this.applyProviderResponse(parsedStatus, {
69813
69956
  phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
69814
69957
  });
@@ -77137,13 +77280,16 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
77137
77280
  worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0,
77138
77281
  worktreeCleanupFallback: typeof worktreeCleanup?.fallback === "string" ? worktreeCleanup.fallback : void 0,
77139
77282
  forced: worktreeCleanup?.forced === true ? true : void 0,
77140
- forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0
77283
+ forceFallbackReason: typeof worktreeCleanup?.reason === "string" ? worktreeCleanup.reason : void 0,
77284
+ branchRefDeleted: typeof worktreeCleanup?.branchRefDeleted === "boolean" ? worktreeCleanup.branchRefDeleted : void 0,
77285
+ branchRefReason: typeof worktreeCleanup?.branchRefReason === "string" ? worktreeCleanup.branchRefReason : void 0
77141
77286
  }
77142
77287
  });
77143
77288
  } catch {
77144
77289
  }
77145
77290
  }
77146
77291
  const residueWarning = worktreeCleanup?.residue === true && typeof worktreeCleanup?.residueWarning === "string" ? worktreeCleanup.residueWarning : void 0;
77292
+ const branchRefWarning = typeof worktreeCleanup?.branchRefWarning === "string" ? worktreeCleanup.branchRefWarning : void 0;
77147
77293
  const skippedLiveSessionIds = Array.isArray(sessionCleanup?.skippedLiveSessionIds) ? sessionCleanup.skippedLiveSessionIds.filter((v) => typeof v === "string") : [];
77148
77294
  const orphanedSessionsRemaining = skippedLiveSessionIds.length > 0;
77149
77295
  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;
@@ -77151,6 +77297,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
77151
77297
  success: true,
77152
77298
  removed,
77153
77299
  ...residueWarning ? { residueWarning } : {},
77300
+ ...branchRefWarning ? { branchRefWarning } : {},
77154
77301
  ...sessionCleanup ? { sessionCleanup } : {},
77155
77302
  ...worktreeCleanup ? { worktreeCleanup } : {},
77156
77303
  ...orphanedSessionsRemaining ? { orphanedSessionsRemaining: true, nextAction: orphanNextAction } : {}
@@ -82376,16 +82523,50 @@ ${mergeTreeErr?.stderr || ""}`;
82376
82523
  recoveryHint: "Inspect the worktree branch and mesh metadata before retrying cleanup."
82377
82524
  };
82378
82525
  }
82379
- const forceFallbackConvergence = args.force ? { allow: true, status: "force_override", source: "caller_force_flag" } : await this.getWorktreeForceCleanupConvergence({ repoRoot, workspace, node: args.node });
82526
+ const mergeConvergence = await this.getWorktreeForceCleanupConvergence({ repoRoot, workspace, node: args.node });
82527
+ const forceFallbackConvergence = args.force ? { allow: true, status: "force_override", source: "caller_force_flag" } : mergeConvergence;
82528
+ const deleteBranchIfMerged = async () => {
82529
+ const branch = String(args.node.worktreeBranch).trim();
82530
+ const status = mergeConvergence.allow ? mergeConvergence.status || "" : "";
82531
+ const MERGED_STATUSES = /* @__PURE__ */ new Set([
82532
+ "merged_to_main",
82533
+ "merged_pushed",
82534
+ "merged_to_default_ref",
82535
+ "cleanup_candidate"
82536
+ ]);
82537
+ const PATCH_EQUIV_STATUS = "patch_equivalent_to_default_ref";
82538
+ if (!branch) {
82539
+ return { branchRefDeleted: false, branchRefReason: "empty_branch_name" };
82540
+ }
82541
+ if (!mergeConvergence.allow || !MERGED_STATUSES.has(status) && status !== PATCH_EQUIV_STATUS) {
82542
+ return {
82543
+ branchRefDeleted: false,
82544
+ branchRefReason: `branch_not_merged_preserved: ${mergeConvergence.error || mergeConvergence.status || "convergence_unverified"}`,
82545
+ 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.`
82546
+ };
82547
+ }
82548
+ const { deleteBranchRef: deleteBranchRef2 } = await Promise.resolve().then(() => (init_git_worktree(), git_worktree_exports));
82549
+ const res = await deleteBranchRef2(repoRoot, branch, { safeDeleteOnly: status !== PATCH_EQUIV_STATUS });
82550
+ return {
82551
+ branchRefDeleted: res.deleted,
82552
+ branchRefReason: res.reason,
82553
+ ...res.forced ? { branchRefForced: true } : {},
82554
+ ...res.deleted ? {} : {
82555
+ branchRefWarning: `Branch ref '${branch}' could not be deleted (${res.reason}); it was preserved so no work is lost.`
82556
+ }
82557
+ };
82558
+ };
82380
82559
  try {
82381
82560
  const result = await removeWorktree2(repoRoot, workspace, {
82382
82561
  requireClean: !args.force,
82383
82562
  allowSubmoduleForceFallback: forceFallbackConvergence.allow
82384
82563
  });
82564
+ const branchOutcome = await deleteBranchIfMerged();
82385
82565
  return {
82386
82566
  success: true,
82387
82567
  removedPath: result.removedPath,
82388
82568
  repoRoot,
82569
+ ...branchOutcome,
82389
82570
  ...result.fallback ? {
82390
82571
  fallback: result.fallback,
82391
82572
  forced: result.forced,
@@ -82418,10 +82599,12 @@ ${mergeTreeErr?.stderr || ""}`;
82418
82599
  maxBuffer: GIT_MAX_BUFFER_CLEANUP,
82419
82600
  windowsHide: true
82420
82601
  });
82602
+ const branchOutcome = await deleteBranchIfMerged();
82421
82603
  return {
82422
82604
  success: true,
82423
82605
  removedPath: workspace,
82424
82606
  repoRoot,
82607
+ ...branchOutcome,
82425
82608
  fallback: "git_worktree_remove_submodule_deinit",
82426
82609
  forced: true,
82427
82610
  reason: "working_trees_containing_submodules",
@@ -82439,10 +82622,12 @@ ${mergeTreeErr?.stderr || ""}`;
82439
82622
  });
82440
82623
  } catch {
82441
82624
  }
82625
+ const branchOutcome = await deleteBranchIfMerged();
82442
82626
  return {
82443
82627
  success: true,
82444
82628
  removedPath: workspace,
82445
82629
  repoRoot,
82630
+ ...branchOutcome,
82446
82631
  fallback: "fs_rm_worktree_prune",
82447
82632
  forced: true,
82448
82633
  reason: "working_trees_containing_submodules",