@coreplane/switchboard 1.260.4 → 1.260.5
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/assets/deploy/cloudflare/package.json +2 -2
- package/dist/assets/deploy/cloudflare-docs/package.json +1 -1
- package/dist/assets/deploy/cloudflare-memory/package.json +2 -2
- package/dist/assets/deploy/cloudflare-memory/worker.ts +205 -8
- package/dist/assets/deploy/cloudflare-resident/package.json +2 -2
- package/dist/assets/deploy/cloudflare-resident/worker.ts +124 -40
- package/dist/assets/deploy/cloudflare-sandbox/package.json +2 -2
- package/dist/assets/package-lock.json +712 -97
- package/dist/assets/package.json +4 -4
- package/dist/assets/source.json +3 -3
- package/dist/assets/src/core/budgets.ts +5 -0
- package/dist/assets/src/core/coordinator/contract.ts +5 -0
- package/dist/assets/src/core/coordinator/driver.ts +114 -25
- package/dist/assets/src/core/pipelineStanding.ts +2 -0
- package/dist/assets/src/core/plane/decide.ts +19 -2
- package/dist/assets/src/core/provider.ts +380 -0
- package/dist/assets/src/core/refusal.ts +1 -0
- package/dist/assets/src/core/runEvents.ts +8 -0
- package/dist/assets/src/core/runLedger/types.ts +10 -1
- package/dist/assets/src/core/runRecord.ts +31 -0
- package/dist/assets/src/core/ship/contract.ts +2 -0
- package/dist/assets/src/core/ship/coordinator.ts +487 -25
- package/dist/assets/src/core/types.ts +6 -0
- package/dist/assets/src/execution/residentRebind.ts +15 -0
- package/dist/assets/src/execution/residentReuse.ts +23 -2
- package/dist/assets/web/dist/.vite/manifest.json +67 -67
- package/dist/assets/web/dist/assets/{DeliveryPage-BaemWKW8.js → DeliveryPage-Cf1joUyA.js} +1 -1
- package/dist/assets/web/dist/assets/{HomePage-fgKQHLaO.js → HomePage-DZEAnCCv.js} +1 -1
- package/dist/assets/web/dist/assets/{PendingTurnRow-vuWiDzvz.js → PendingTurnRow-4B8JwETU.js} +1 -1
- package/dist/assets/web/dist/assets/{PlanePage-DXMJf8FB.js → PlanePage-CHU2szQs.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentDetailPage-DdC8yU_S.js → ResidentDetailPage-L5SRcN_O.js} +1 -1
- package/dist/assets/web/dist/assets/{ResidentsIndexPage-CSM-KODv.js → ResidentsIndexPage-BIFf8qyE.js} +1 -1
- package/dist/assets/web/dist/assets/RunFoldRow-DzPIshJx.js +1 -0
- package/dist/assets/web/dist/assets/{RunRoutePage-jo6NZxsP.js → RunRoutePage-Cru5IVux.js} +3 -3
- package/dist/assets/web/dist/assets/{RunsIndexPage-Dx1Y4sSq.js → RunsIndexPage-CBkdPAdj.js} +1 -1
- package/dist/assets/web/dist/assets/{ScheduledPage-BuB_NZyR.js → ScheduledPage-D_R55BDk.js} +1 -1
- package/dist/assets/web/dist/assets/{SettingsPage-Cn96jB6Q.js → SettingsPage-DlmZvAvf.js} +1 -1
- package/dist/assets/web/dist/assets/{SilentTurn-D2cJfpEq.js → SilentTurn-PWMDMbMG.js} +1 -1
- package/dist/assets/web/dist/assets/{StatusDot-DDHUCPVJ.js → StatusDot-Bq0mYMFo.js} +1 -1
- package/dist/assets/web/dist/assets/{Tooltip-B4VIHkAI.js → Tooltip-Bs6zd7yE.js} +1 -1
- package/dist/assets/web/dist/assets/{UnitRoutePage-C-2DfjLI.js → UnitRoutePage-BMGEZCvn.js} +1 -1
- package/dist/assets/web/dist/assets/budgets-0szUBIMv.js +1 -0
- package/dist/assets/web/dist/assets/{dist-Cf1CmCSK.js → dist-EkKVbIM-.js} +11 -11
- package/dist/assets/web/dist/assets/{indexRow-Dxg7C8s9.js → indexRow-5s3hNzZ9.js} +1 -1
- package/dist/assets/web/dist/assets/{main-DxPqaFu9.js → main-Disot0n_.js} +2 -2
- package/dist/assets/web/dist/assets/{sseReplay-BzoeVxZB.js → sseReplay-9gcMpylx.js} +1 -1
- package/dist/cli.js +1855 -401
- package/package.json +4 -4
- package/dist/assets/web/dist/assets/RunFoldRow-Csik3wD6.js +0 -1
- package/dist/assets/web/dist/assets/budgets-KNNkT4PZ.js +0 -1
|
@@ -96,8 +96,14 @@ import {
|
|
|
96
96
|
type ResidentLevelsDoc,
|
|
97
97
|
} from "./levels.js";
|
|
98
98
|
import { parseReadonly, planReadonlyAttach } from "../../src/execution/residentReadonly.js";
|
|
99
|
-
import { decideWorktree, parseReuse, type WorktreeFacts } from "../../src/execution/residentReuse.js";
|
|
100
99
|
import {
|
|
100
|
+
decideWorktree,
|
|
101
|
+
parseReuse,
|
|
102
|
+
replacementWorktreeCleanup,
|
|
103
|
+
type WorktreeFacts,
|
|
104
|
+
} from "../../src/execution/residentReuse.js";
|
|
105
|
+
import {
|
|
106
|
+
admitThreadDiskWithRollback,
|
|
101
107
|
boundByFor,
|
|
102
108
|
canReturnToDefault,
|
|
103
109
|
parseOwnPr,
|
|
@@ -1753,6 +1759,17 @@ async function threadWorktreePath(threadKey: string, ref: string): Promise<strin
|
|
|
1753
1759
|
return `${THREADS_DIR}/${slug(threadKey)}-${hash8}/${slug(ref)}`;
|
|
1754
1760
|
}
|
|
1755
1761
|
|
|
1762
|
+
/** Build a named-ref replacement beside the checkout the sticky row still
|
|
1763
|
+
* names. A slash-to-dash slug collision gets a ref hash so the provisional
|
|
1764
|
+
* clone can never overwrite the old checkout before the attach commits. */
|
|
1765
|
+
async function replacementWorktreePath(threadKey: string, ref: string, priorPath: string): Promise<string> {
|
|
1766
|
+
const desired = await threadWorktreePath(threadKey, ref);
|
|
1767
|
+
if (desired !== priorPath) return desired;
|
|
1768
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(ref));
|
|
1769
|
+
const hash8 = [...new Uint8Array(digest).slice(0, 4)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1770
|
+
return `${desired}-ref-${hash8}`;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1756
1773
|
/** Path confinement for /read and /write: conservative charset, no `..`
|
|
1757
1774
|
* segments, and the resolved absolute path must stay under the worktree
|
|
1758
1775
|
* root. Symlink tricks past this point are bounded by the OS layer — the
|
|
@@ -5397,20 +5414,27 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5397
5414
|
|
|
5398
5415
|
/** Storage-only allocation (atomic under the DO input gate: get → list →
|
|
5399
5416
|
* put touches nothing but this object's storage, so two concurrent
|
|
5400
|
-
* attaches cannot both claim the same user).
|
|
5401
|
-
*
|
|
5402
|
-
*
|
|
5417
|
+
* attaches cannot both claim the same user). A hint that names no branch
|
|
5418
|
+
* keeps the sticky ref. An explicit named ref records named authority even
|
|
5419
|
+
* when it matches the sticky ref; only a changed ref replaces the path. */
|
|
5403
5420
|
private async allocateThreadUser(
|
|
5404
5421
|
threadKey: string,
|
|
5405
5422
|
ref: string,
|
|
5406
5423
|
worktreePath: string,
|
|
5407
|
-
/** How
|
|
5424
|
+
/** How the requested ref was chosen (item 16). */
|
|
5408
5425
|
boundBy: BoundBy,
|
|
5426
|
+
/** An explicit named ref is authoritative; false is the sticky fallback. */
|
|
5427
|
+
replaceRef = false,
|
|
5409
5428
|
): Promise<{ binding: ThreadBinding; wrote: boolean } | ThreadErr> {
|
|
5410
5429
|
const key = threadBindingKey(threadKey);
|
|
5411
5430
|
const existing = await this.ctx.storage.get<ThreadBinding>(key);
|
|
5412
|
-
|
|
5413
|
-
const
|
|
5431
|
+
const replacingRef = existing !== undefined && replaceRef && existing.ref !== ref;
|
|
5432
|
+
const recordingNamedAuthority = existing !== undefined && replaceRef && existing.boundBy !== boundBy;
|
|
5433
|
+
const deferRefWrite = replacingRef && !existing.evicted && existing.user !== "";
|
|
5434
|
+
if (existing && !existing.evicted && existing.user && !replacingRef && !recordingNamedAuthority)
|
|
5435
|
+
return { binding: existing, wrote: false };
|
|
5436
|
+
const user =
|
|
5437
|
+
existing && !existing.evicted && existing.user ? existing.user : await this.findFreePoolUser(threadKey);
|
|
5414
5438
|
if (!user) {
|
|
5415
5439
|
return {
|
|
5416
5440
|
error: `user-pool-exhausted: all ${THREAD_USERS.length} thread users are allocated; wait for the inactivity sweep or evict a thread`,
|
|
@@ -5420,26 +5444,50 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5420
5444
|
const now = new Date(systemClock()).toISOString();
|
|
5421
5445
|
const binding: ThreadBinding = {
|
|
5422
5446
|
threadKey,
|
|
5423
|
-
ref: existing?.ref ?? ref,
|
|
5447
|
+
ref: replacingRef ? ref : (existing?.ref ?? ref),
|
|
5424
5448
|
user,
|
|
5425
|
-
worktreePath: existing?.worktreePath ?? worktreePath,
|
|
5449
|
+
worktreePath: replacingRef ? worktreePath : (existing?.worktreePath ?? worktreePath),
|
|
5426
5450
|
boundAt: existing?.boundAt ?? now,
|
|
5427
5451
|
lastAttachAt: now,
|
|
5428
5452
|
evicted: false,
|
|
5429
|
-
//
|
|
5430
|
-
//
|
|
5431
|
-
//
|
|
5453
|
+
// A named ref starts a new binding choice, so stale move/return records
|
|
5454
|
+
// do not make it look default-bound. The thread's pushed-branch memory
|
|
5455
|
+
// remains its history across every ref choice.
|
|
5432
5456
|
...(existing
|
|
5433
5457
|
? {
|
|
5434
|
-
...(
|
|
5435
|
-
|
|
5436
|
-
|
|
5458
|
+
...(replacingRef || recordingNamedAuthority
|
|
5459
|
+
? { boundBy }
|
|
5460
|
+
: {
|
|
5461
|
+
...(existing.boundBy !== undefined ? { boundBy: existing.boundBy } : {}),
|
|
5462
|
+
...(existing.rebound !== undefined ? { rebound: existing.rebound } : {}),
|
|
5463
|
+
...(existing.returned !== undefined ? { returned: existing.returned } : {}),
|
|
5464
|
+
}),
|
|
5437
5465
|
...(existing.ownBranches !== undefined ? { ownBranches: existing.ownBranches } : {}),
|
|
5438
5466
|
}
|
|
5439
5467
|
: { boundBy }),
|
|
5440
5468
|
};
|
|
5441
|
-
|
|
5442
|
-
|
|
5469
|
+
// A live existing binding already reserves this user. Its named-ref
|
|
5470
|
+
// replacement stays provisional until deps and credentials succeed;
|
|
5471
|
+
// keeping the old row here lets a failed attach discard the new checkout
|
|
5472
|
+
// without ever publishing a binding that did not complete. An evicted row
|
|
5473
|
+
// has no user reservation, so its fresh allocation is written and rolled
|
|
5474
|
+
// back through the ordinary path.
|
|
5475
|
+
if (!deferRefWrite) await this.ctx.storage.put(key, binding);
|
|
5476
|
+
return { binding, wrote: !deferRefWrite };
|
|
5477
|
+
}
|
|
5478
|
+
|
|
5479
|
+
/** Best-effort cleanup after a provisional named-ref replacement settles.
|
|
5480
|
+
* The binding and its surviving checkout already agree; a cleanup failure
|
|
5481
|
+
* leaves only an unreachable sibling for the thread's eventual eviction. */
|
|
5482
|
+
private async discardReplacedCheckout(threadKey: string, path: string): Promise<void> {
|
|
5483
|
+
try {
|
|
5484
|
+
const removed = await this.run(["rm", "-rf", path]);
|
|
5485
|
+
if (removed.exitCode !== 0) {
|
|
5486
|
+
console.log(`attach ${threadKey}: failed to discard replaced checkout ${path}: ${removed.stderr}`);
|
|
5487
|
+
}
|
|
5488
|
+
} catch (err) {
|
|
5489
|
+
console.log(`attach ${threadKey}: failed to discard replaced checkout ${path}: ${errMsg(err)}`);
|
|
5490
|
+
}
|
|
5443
5491
|
}
|
|
5444
5492
|
|
|
5445
5493
|
/** POST /attach: idempotent per-thread workspace materialization.
|
|
@@ -5612,24 +5660,20 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5612
5660
|
cause: "system",
|
|
5613
5661
|
};
|
|
5614
5662
|
|
|
5615
|
-
//
|
|
5616
|
-
//
|
|
5617
|
-
//
|
|
5618
|
-
//
|
|
5619
|
-
//
|
|
5620
|
-
//
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
const rebind =
|
|
5624
|
-
|
|
5625
|
-
reason.ownPr,
|
|
5626
|
-
reuse,
|
|
5627
|
-
facts.defaultRef,
|
|
5628
|
-
slug,
|
|
5629
|
-
);
|
|
5663
|
+
// A ref the request names is authoritative. The sticky binding is only a
|
|
5664
|
+
// fallback when the request names none (`refHint` absent, or the bot's
|
|
5665
|
+
// explicit by-default resolution). This keeps a re-issued coordinator
|
|
5666
|
+
// child on the branch its new spawn names instead of an earlier attempt's
|
|
5667
|
+
// branch. The own-PR move remains for callers that name no branch of their
|
|
5668
|
+
// own but carry the typed follow-up fact.
|
|
5669
|
+
const storedPrior = stored.get(threadBindingKey(threadKey)) as ThreadBinding | undefined;
|
|
5670
|
+
const namedRef = refHint !== null && !reason.refByDefault && reason.ownPr === null;
|
|
5671
|
+
const rebind = namedRef
|
|
5672
|
+
? { binding: storedPrior }
|
|
5673
|
+
: await this.rebindToOwnPr(storedPrior, reason.ownPr, reuse, facts.defaultRef, slug);
|
|
5630
5674
|
if ("error" in rebind) return rebind;
|
|
5631
5675
|
const prior = rebind.binding;
|
|
5632
|
-
const ref = prior?.ref ?? refHint;
|
|
5676
|
+
const ref = namedRef ? refHint : (prior?.ref ?? refHint);
|
|
5633
5677
|
if (!ref) {
|
|
5634
5678
|
// Name the default branch so the bot can bind to it (loudly) instead of
|
|
5635
5679
|
// asking the user when the message named no branch; the binding is still
|
|
@@ -5642,7 +5686,10 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5642
5686
|
cause: "request",
|
|
5643
5687
|
};
|
|
5644
5688
|
}
|
|
5645
|
-
const
|
|
5689
|
+
const replacingNamedRef = namedRef && prior !== undefined && prior.ref !== ref;
|
|
5690
|
+
const worktreePath = replacingNamedRef
|
|
5691
|
+
? await replacementWorktreePath(threadKey, ref, prior.worktreePath)
|
|
5692
|
+
: (prior?.worktreePath ?? (await threadWorktreePath(threadKey, ref)));
|
|
5646
5693
|
// Read-only vs writable (item 50): decided here, once, from the request
|
|
5647
5694
|
// and the prior binding's mode — the tested pure helper is the shipped code.
|
|
5648
5695
|
const mode = planReadonlyAttach({ readonly, prior, slug, mirrorDir: MIRROR_DIR });
|
|
@@ -5652,12 +5699,14 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5652
5699
|
ref,
|
|
5653
5700
|
worktreePath,
|
|
5654
5701
|
boundByFor({ refByDefault: reason.refByDefault, ref, defaultRef: facts.defaultRef }),
|
|
5702
|
+
namedRef,
|
|
5655
5703
|
);
|
|
5656
5704
|
if ("error" in alloc) return alloc;
|
|
5657
5705
|
const binding = alloc.binding;
|
|
5658
5706
|
// "Nothing created" on failure: a FRESH allocation (new binding or a
|
|
5659
5707
|
// re-allocation after eviction) is rolled back if the attach fails below,
|
|
5660
|
-
//
|
|
5708
|
+
// including a throw during disk admission, so a bogus refHint can neither
|
|
5709
|
+
// bind sticky garbage nor leak a pool user.
|
|
5661
5710
|
const rollback = async (): Promise<void> => {
|
|
5662
5711
|
if (!alloc.wrote) return;
|
|
5663
5712
|
if (prior) await this.ctx.storage.put(threadBindingKey(threadKey), prior);
|
|
@@ -5665,13 +5714,19 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5665
5714
|
};
|
|
5666
5715
|
|
|
5667
5716
|
// Disk admission (item 55): before the lock, since making room takes it.
|
|
5668
|
-
|
|
5717
|
+
// An evicted prior binding has already published its replacement to
|
|
5718
|
+
// reserve the user; keep that row provisional if admission itself throws.
|
|
5719
|
+
const admission = await admitThreadDiskWithRollback(
|
|
5720
|
+
() => this.admitThreadDisk({ threadKey, binding, facts, record }),
|
|
5721
|
+
rollback,
|
|
5722
|
+
);
|
|
5669
5723
|
if ("error" in admission) {
|
|
5670
5724
|
await rollback();
|
|
5671
5725
|
return admission;
|
|
5672
5726
|
}
|
|
5727
|
+
let attached: AttachOk | ThreadErr | undefined;
|
|
5673
5728
|
try {
|
|
5674
|
-
|
|
5729
|
+
attached = await this.attachThreadCreate({
|
|
5675
5730
|
threadKey,
|
|
5676
5731
|
refHint,
|
|
5677
5732
|
wantSha,
|
|
@@ -5683,11 +5738,22 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5683
5738
|
binding,
|
|
5684
5739
|
mode,
|
|
5685
5740
|
rollback,
|
|
5741
|
+
namedRef,
|
|
5742
|
+
refChanged: storedPrior !== undefined && storedPrior.ref !== binding.ref,
|
|
5686
5743
|
...(rebind.rebound !== undefined ? { rebound: rebind.rebound } : {}),
|
|
5687
5744
|
...(rebind.rebindRefused !== undefined ? { rebindRefused: rebind.rebindRefused } : {}),
|
|
5688
5745
|
});
|
|
5746
|
+
return attached;
|
|
5689
5747
|
} finally {
|
|
5690
5748
|
this.diskCommittedKiB -= admission.committedKiB;
|
|
5749
|
+
if (replacingNamedRef && prior !== undefined) {
|
|
5750
|
+
const discard = replacementWorktreeCleanup({
|
|
5751
|
+
priorPath: prior.worktreePath,
|
|
5752
|
+
replacementPath: binding.worktreePath,
|
|
5753
|
+
succeeded: attached !== undefined && !("error" in attached),
|
|
5754
|
+
});
|
|
5755
|
+
if (discard !== null) await this.discardReplacedCheckout(threadKey, discard);
|
|
5756
|
+
}
|
|
5691
5757
|
}
|
|
5692
5758
|
}
|
|
5693
5759
|
|
|
@@ -5903,6 +5969,10 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5903
5969
|
binding: ThreadBinding;
|
|
5904
5970
|
mode: ReturnType<typeof planReadonlyAttach>;
|
|
5905
5971
|
rollback: () => Promise<void>;
|
|
5972
|
+
/** This ask named the ref; a missing named branch may not fall back. */
|
|
5973
|
+
namedRef: boolean;
|
|
5974
|
+
/** The row moved to another ref before provisioning. */
|
|
5975
|
+
refChanged: boolean;
|
|
5906
5976
|
/** What `rebindToOwnPr` decided (item 16), for the answer. */
|
|
5907
5977
|
rebound?: Rebound;
|
|
5908
5978
|
rebindRefused?: RebindRefused;
|
|
@@ -5914,6 +5984,7 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5914
5984
|
// movement): everything after the lock — deps, credentials, the row's
|
|
5915
5985
|
// final write, the answer — then speaks of the returned binding.
|
|
5916
5986
|
let binding = input.binding;
|
|
5987
|
+
let refChanged = input.refChanged;
|
|
5917
5988
|
let returned: Returned | undefined;
|
|
5918
5989
|
|
|
5919
5990
|
// Command-level token mint — before the lock so mint latency
|
|
@@ -5954,7 +6025,7 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
5954
6025
|
// cycle's prune caught up. One predicate, read once here, drives the mint
|
|
5955
6026
|
// pre-check, the fetch under the lock and the return gate alike.
|
|
5956
6027
|
let want = wantShaForBinding({ boundRef: binding.ref, refHint, wantSha });
|
|
5957
|
-
const returnable = canReturnToDefault(binding, facts.defaultRef);
|
|
6028
|
+
const returnable = input.namedRef ? false : canReturnToDefault(binding, facts.defaultRef);
|
|
5958
6029
|
let fetchToken: string | null = token;
|
|
5959
6030
|
if (
|
|
5960
6031
|
!fetchToken &&
|
|
@@ -6022,6 +6093,7 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
6022
6093
|
// goes on there: the default is always in the mirror, and the
|
|
6023
6094
|
// worktree step below provisions the tree at its tip.
|
|
6024
6095
|
const back = await this.returnBindingToDefault(binding, facts.defaultRef);
|
|
6096
|
+
if (back.binding.ref !== binding.ref) refChanged = true;
|
|
6025
6097
|
binding = back.binding;
|
|
6026
6098
|
returned = back.returned;
|
|
6027
6099
|
want = wantShaForBinding({ boundRef: binding.ref, refHint, wantSha });
|
|
@@ -6058,6 +6130,7 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
6058
6130
|
const recreated = await this.ensureThreadWorktree(binding, sha, mode.originUrl, mode.modeSwitch, {
|
|
6059
6131
|
detached: target.kind === "sha",
|
|
6060
6132
|
reuse,
|
|
6133
|
+
refChanged,
|
|
6061
6134
|
});
|
|
6062
6135
|
return { sha, threadLockKey, recreated };
|
|
6063
6136
|
}, ATTACH_MUTEX_WAIT_MS);
|
|
@@ -6219,7 +6292,11 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
6219
6292
|
* expected commit it still holds (item 51) — the tree is checked out at
|
|
6220
6293
|
* that commit, detached, instead of at a branch. `reuse`: a resumed
|
|
6221
6294
|
* run's attach (item 66): keep the tree as it stands, or refuse. */
|
|
6222
|
-
opts: { detached: boolean; reuse: boolean } = {
|
|
6295
|
+
opts: { detached: boolean; reuse: boolean; refChanged: boolean } = {
|
|
6296
|
+
detached: false,
|
|
6297
|
+
reuse: false,
|
|
6298
|
+
refChanged: false,
|
|
6299
|
+
},
|
|
6223
6300
|
): Promise<boolean> {
|
|
6224
6301
|
const wt = binding.worktreePath;
|
|
6225
6302
|
const threadDir = parentDir(wt);
|
|
@@ -6256,7 +6333,14 @@ export class ResidentDO extends Sandbox<Env> {
|
|
|
6256
6333
|
}
|
|
6257
6334
|
}
|
|
6258
6335
|
}
|
|
6259
|
-
const decision = decideWorktree({
|
|
6336
|
+
const decision = decideWorktree({
|
|
6337
|
+
reuse: opts.reuse,
|
|
6338
|
+
modeSwitch,
|
|
6339
|
+
refChanged: opts.refChanged,
|
|
6340
|
+
sha,
|
|
6341
|
+
worktreePath: wt,
|
|
6342
|
+
facts,
|
|
6343
|
+
});
|
|
6260
6344
|
if (decision.kind === "refuse") throw new ReuseRefusedError(decision.why);
|
|
6261
6345
|
if (decision.kind === "reuse") return false;
|
|
6262
6346
|
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"@cloudflare/sandbox": "0.13.0-next.751.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@cloudflare/workers-types": "^5.
|
|
22
|
+
"@cloudflare/workers-types": "^5.20260914.1",
|
|
23
23
|
"typescript": "^5.9.3",
|
|
24
|
-
"wrangler": "^4.
|
|
24
|
+
"wrangler": "^4.131.2"
|
|
25
25
|
}
|
|
26
26
|
}
|