@adhdev/daemon-core 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/cli-adapter-types.d.ts +12 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +11 -0
- package/dist/git/git-worktree.d.ts +22 -0
- package/dist/index.js +193 -8
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +193 -8
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +8 -0
- package/dist/providers/spec/fsm-driver.d.ts +10 -0
- package/package.json +2 -2
- package/src/cli-adapter-types.ts +12 -0
- package/src/cli-adapters/provider-cli-shared.ts +11 -0
- package/src/commands/med-family/mesh-crud.ts +11 -0
- package/src/commands/router.ts +49 -2
- package/src/git/git-worktree.ts +68 -0
- package/src/mesh/mesh-work-queue.ts +110 -2
- package/src/providers/cli-provider-instance.ts +43 -1
- package/src/providers/spec/cli-adapter.ts +6 -1
- package/src/providers/spec/fsm-driver.ts +12 -0
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 ? "
|
|
382
|
-
const commitShort = readInjected(true ? "
|
|
383
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
384
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
381
|
+
const commit = readInjected(true ? "057d5def5d55af124dfe910ee9accdf244576c14" : void 0) ?? "unknown";
|
|
382
|
+
const commitShort = readInjected(true ? "057d5def" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
383
|
+
const version = readInjected(true ? "0.9.82-rc.387" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
384
|
+
const builtAt = readInjected(true ? "2026-06-26T02:21:27.575Z" : 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) {
|
|
@@ -35833,6 +35943,17 @@ var FsmDriver = class {
|
|
|
35833
35943
|
hasIdleHoldPending() {
|
|
35834
35944
|
return (this.lastFsmEval?.transitions ?? []).some((t) => !t.holdSatisfied && t.condResult);
|
|
35835
35945
|
}
|
|
35946
|
+
/**
|
|
35947
|
+
* True once the machine has reached its first non-initial idle state (the
|
|
35948
|
+
* prompt is genuinely drawn — see maybeMarkReady). The cli-adapter surfaces
|
|
35949
|
+
* this on its idle status so CliProviderInstance can re-arm the queue-claim
|
|
35950
|
+
* agent:ready on the first genuine ready, independent of the boot-time
|
|
35951
|
+
* starting→idle one-shot (which is consumed too early for specs whose
|
|
35952
|
+
* initial state already reports idle).
|
|
35953
|
+
*/
|
|
35954
|
+
hasSeenReady() {
|
|
35955
|
+
return this.readySeenOnce;
|
|
35956
|
+
}
|
|
35836
35957
|
getCompletionIdleDebounceState() {
|
|
35837
35958
|
const out = outgoingTransitions(this.spec, this.currentStateId);
|
|
35838
35959
|
const toReady = this.lastFsmEval?.transitions.find((t, i) => {
|
|
@@ -37499,7 +37620,7 @@ var SpecCliAdapter = class _SpecCliAdapter {
|
|
|
37499
37620
|
if (state.status === "generating") {
|
|
37500
37621
|
return { status: "generating", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
|
|
37501
37622
|
}
|
|
37502
|
-
return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, ...sessionFields };
|
|
37623
|
+
return { status: "idle", messages: [], activeModal: null, activeInteractivePrompt: this.activeInteractivePrompt, fsmReadySeen: this.driver.hasSeenReady?.() ?? false, ...sessionFields };
|
|
37503
37624
|
}
|
|
37504
37625
|
maybeRefreshNativeHistory() {
|
|
37505
37626
|
}
|
|
@@ -38544,6 +38665,14 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
38544
38665
|
context = null;
|
|
38545
38666
|
events = [];
|
|
38546
38667
|
lastStatus = "starting";
|
|
38668
|
+
// Idempotency guard for the queue-claim agent:ready event. agent:ready is the
|
|
38669
|
+
// sole signal the mesh coordinator's tryAssignQueueTask waits on to hand a
|
|
38670
|
+
// queued task to this worker. It is emitted in two places: the boot-time
|
|
38671
|
+
// starting→idle one-shot, and the readySeen re-arm below. This flag makes the
|
|
38672
|
+
// event fire AT MOST ONCE per session so a worker is never claimed twice and a
|
|
38673
|
+
// queued task is never double-dispatched/double-injected. Whichever path fires
|
|
38674
|
+
// first sets it; the other becomes a no-op.
|
|
38675
|
+
agentReadyEmitted = false;
|
|
38547
38676
|
generatingStartedAt = 0;
|
|
38548
38677
|
settings = {};
|
|
38549
38678
|
monitor;
|
|
@@ -39624,6 +39753,17 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
39624
39753
|
} catch {
|
|
39625
39754
|
}
|
|
39626
39755
|
}
|
|
39756
|
+
/**
|
|
39757
|
+
* Emit the queue-claim agent:ready event at most once per session. Both the
|
|
39758
|
+
* boot-time starting→idle one-shot and the fsmReadySeen re-arm call this; the
|
|
39759
|
+
* agentReadyEmitted guard ensures the second caller is a no-op so a worker is
|
|
39760
|
+
* never claimed twice and a queued task is never double-dispatched.
|
|
39761
|
+
*/
|
|
39762
|
+
emitAgentReadyOnce(chatTitle, now) {
|
|
39763
|
+
if (this.agentReadyEmitted) return;
|
|
39764
|
+
this.agentReadyEmitted = true;
|
|
39765
|
+
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|
|
39766
|
+
}
|
|
39627
39767
|
detectStatusTransition() {
|
|
39628
39768
|
const now = Date.now();
|
|
39629
39769
|
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
@@ -39776,7 +39916,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
39776
39916
|
this.scheduleCompletedDebounceFlush(flushDelay);
|
|
39777
39917
|
}
|
|
39778
39918
|
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
39779
|
-
this.
|
|
39919
|
+
this.emitAgentReadyOnce(chatTitle, now);
|
|
39780
39920
|
} else if (newStatus === "error") {
|
|
39781
39921
|
if (this.generatingDebounceTimer) {
|
|
39782
39922
|
clearTimeout(this.generatingDebounceTimer);
|
|
@@ -39815,6 +39955,9 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
39815
39955
|
}
|
|
39816
39956
|
this.lastStatus = newStatus;
|
|
39817
39957
|
}
|
|
39958
|
+
if (newStatus === "idle" && adapterStatus.fsmReadySeen === true && !this.agentReadyEmitted) {
|
|
39959
|
+
this.emitAgentReadyOnce(chatTitle, now);
|
|
39960
|
+
}
|
|
39818
39961
|
this.applyProviderResponse(parsedStatus, {
|
|
39819
39962
|
phase: newStatus === "idle" && (previousStatus === "generating" || previousStatus === "waiting_approval") ? "turn_completed" : "immediate"
|
|
39820
39963
|
});
|
|
@@ -47188,13 +47331,16 @@ var meshCrudHandlers = {
|
|
|
47188
47331
|
worktreeBranch: typeof node?.worktreeBranch === "string" ? node.worktreeBranch : void 0,
|
|
47189
47332
|
worktreeCleanupFallback: typeof worktreeCleanup?.fallback === "string" ? worktreeCleanup.fallback : void 0,
|
|
47190
47333
|
forced: worktreeCleanup?.forced === true ? true : void 0,
|
|
47191
|
-
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
|
|
47192
47337
|
}
|
|
47193
47338
|
});
|
|
47194
47339
|
} catch {
|
|
47195
47340
|
}
|
|
47196
47341
|
}
|
|
47197
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;
|
|
47198
47344
|
const skippedLiveSessionIds = Array.isArray(sessionCleanup?.skippedLiveSessionIds) ? sessionCleanup.skippedLiveSessionIds.filter((v) => typeof v === "string") : [];
|
|
47199
47345
|
const orphanedSessionsRemaining = skippedLiveSessionIds.length > 0;
|
|
47200
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;
|
|
@@ -47202,6 +47348,7 @@ var meshCrudHandlers = {
|
|
|
47202
47348
|
success: true,
|
|
47203
47349
|
removed,
|
|
47204
47350
|
...residueWarning ? { residueWarning } : {},
|
|
47351
|
+
...branchRefWarning ? { branchRefWarning } : {},
|
|
47205
47352
|
...sessionCleanup ? { sessionCleanup } : {},
|
|
47206
47353
|
...worktreeCleanup ? { worktreeCleanup } : {},
|
|
47207
47354
|
...orphanedSessionsRemaining ? { orphanedSessionsRemaining: true, nextAction: orphanNextAction } : {}
|
|
@@ -52471,16 +52618,50 @@ var DaemonCommandRouter = class {
|
|
|
52471
52618
|
recoveryHint: "Inspect the worktree branch and mesh metadata before retrying cleanup."
|
|
52472
52619
|
};
|
|
52473
52620
|
}
|
|
52474
|
-
const
|
|
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
|
+
};
|
|
52475
52654
|
try {
|
|
52476
52655
|
const result = await removeWorktree2(repoRoot, workspace, {
|
|
52477
52656
|
requireClean: !args.force,
|
|
52478
52657
|
allowSubmoduleForceFallback: forceFallbackConvergence.allow
|
|
52479
52658
|
});
|
|
52659
|
+
const branchOutcome = await deleteBranchIfMerged();
|
|
52480
52660
|
return {
|
|
52481
52661
|
success: true,
|
|
52482
52662
|
removedPath: result.removedPath,
|
|
52483
52663
|
repoRoot,
|
|
52664
|
+
...branchOutcome,
|
|
52484
52665
|
...result.fallback ? {
|
|
52485
52666
|
fallback: result.fallback,
|
|
52486
52667
|
forced: result.forced,
|
|
@@ -52513,10 +52694,12 @@ var DaemonCommandRouter = class {
|
|
|
52513
52694
|
maxBuffer: GIT_MAX_BUFFER_CLEANUP,
|
|
52514
52695
|
windowsHide: true
|
|
52515
52696
|
});
|
|
52697
|
+
const branchOutcome = await deleteBranchIfMerged();
|
|
52516
52698
|
return {
|
|
52517
52699
|
success: true,
|
|
52518
52700
|
removedPath: workspace,
|
|
52519
52701
|
repoRoot,
|
|
52702
|
+
...branchOutcome,
|
|
52520
52703
|
fallback: "git_worktree_remove_submodule_deinit",
|
|
52521
52704
|
forced: true,
|
|
52522
52705
|
reason: "working_trees_containing_submodules",
|
|
@@ -52534,10 +52717,12 @@ var DaemonCommandRouter = class {
|
|
|
52534
52717
|
});
|
|
52535
52718
|
} catch {
|
|
52536
52719
|
}
|
|
52720
|
+
const branchOutcome = await deleteBranchIfMerged();
|
|
52537
52721
|
return {
|
|
52538
52722
|
success: true,
|
|
52539
52723
|
removedPath: workspace,
|
|
52540
52724
|
repoRoot,
|
|
52725
|
+
...branchOutcome,
|
|
52541
52726
|
fallback: "fs_rm_worktree_prune",
|
|
52542
52727
|
forced: true,
|
|
52543
52728
|
reason: "working_trees_containing_submodules",
|