opencode-swarm 7.107.6 → 7.109.0

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.
Files changed (84) hide show
  1. package/.opencode/skills/clarify-spec/SKILL.md +15 -9
  2. package/.opencode/skills/critic-gate/SKILL.md +10 -4
  3. package/.opencode/skills/phase-wrap/SKILL.md +2 -2
  4. package/.opencode/skills/plan/SKILL.md +23 -11
  5. package/.opencode/skills/specify/SKILL.md +27 -9
  6. package/dist/cli/{capability-probe-wsjzcp48.js → capability-probe-sh9bwh39.js} +2 -1
  7. package/dist/cli/{config-doctor-kdq3vae4.js → config-doctor-q354tb2w.js} +2 -2
  8. package/dist/cli/core-vev13ej2.js +34 -0
  9. package/dist/cli/{curator-jpwvkpdv.js → curator-3efwdf9x.js} +25 -21
  10. package/dist/cli/{curator-drift-ed7p5mfy.js → curator-drift-169wgaxn.js} +4 -4
  11. package/dist/cli/curator-llm-factory-nttpcx4b.js +40 -0
  12. package/dist/cli/{dispatch-anmxxhen.js → dispatch-zr1xja4t.js} +2 -2
  13. package/dist/cli/{evidence-summary-service-6zsgw7x7.js → evidence-summary-service-j7jwf20f.js} +10 -8
  14. package/dist/cli/{gate-evidence-pgr7d942.js → gate-evidence-v6ds8rcp.js} +5 -4
  15. package/dist/cli/guardrail-explain-e85gbj0r.js +41 -0
  16. package/dist/cli/{guardrail-log-fjypsmek.js → guardrail-log-8mqqsssq.js} +4 -4
  17. package/dist/cli/hive-promoter-rc6z2x8f.js +48 -0
  18. package/dist/cli/{index-9b7qp18e.js → index-1cn967sa.js} +2 -2
  19. package/dist/cli/{index-h28wfp7n.js → index-1mjzvkzj.js} +29 -25
  20. package/dist/cli/{index-n1sptn1w.js → index-2nt4mq9n.js} +1 -1
  21. package/dist/cli/{index-57rthc1z.js → index-3e7jajwe.js} +2 -2
  22. package/dist/cli/{index-bq8kd9r9.js → index-5gnp8fyw.js} +3 -3
  23. package/dist/cli/index-5mkc2f9z.js +154 -0
  24. package/dist/cli/{index-0kxc7t16.js → index-6jng9c8t.js} +1 -1
  25. package/dist/cli/{index-b9v501fr.js → index-7xgqky26.js} +33 -5
  26. package/dist/cli/{index-4r5z8sgw.js → index-85bacexr.js} +2 -2
  27. package/dist/cli/{index-bpgqbwmf.js → index-9qxntjtx.js} +6 -6
  28. package/dist/cli/index-f1qyj61w.js +418 -0
  29. package/dist/cli/{index-wvxhynxq.js → index-fm7xz1ne.js} +1 -1
  30. package/dist/cli/{index-dfdg4ws5.js → index-fz1jgbvw.js} +6 -6
  31. package/dist/cli/{index-pchpahdf.js → index-h4c4rrwx.js} +20 -3
  32. package/dist/cli/{index-kxm3bdjh.js → index-mmny81g1.js} +6 -6
  33. package/dist/cli/{index-v4fcn4tr.js → index-q1exe2b3.js} +2 -198
  34. package/dist/cli/{index-57ymmh7h.js → index-r3j3458j.js} +4 -4
  35. package/dist/cli/{index-91j1sqzm.js → index-scww5b77.js} +47 -0
  36. package/dist/cli/{index-572t1qff.js → index-vb5t1kvs.js} +1477 -2045
  37. package/dist/cli/{index-3naa2ajc.js → index-vvk2g744.js} +10 -156
  38. package/dist/cli/{index-zej8cy0j.js → index-vx76tcxe.js} +1 -1
  39. package/dist/cli/{index-6h82c2h0.js → index-wfq4r95s.js} +1057 -193
  40. package/dist/cli/{index-xmarctsf.js → index-wg0665ft.js} +7 -7
  41. package/dist/cli/{index-4vsgp5a8.js → index-wj4jeavn.js} +1 -1
  42. package/dist/cli/index-wvrj16f0.js +206 -0
  43. package/dist/cli/index-x2q0gnt8.js +254 -0
  44. package/dist/cli/{index-xg18az81.js → index-yw8qpf51.js} +1 -1
  45. package/dist/cli/index.js +25 -21
  46. package/dist/cli/{knowledge-escalator-3sgwrgy9.js → knowledge-escalator-6v7sjprx.js} +8 -7
  47. package/dist/cli/{knowledge-events-kfc6xmkw.js → knowledge-events-6n3x3he2.js} +6 -5
  48. package/dist/cli/{knowledge-store-kyacem71.js → knowledge-store-exkw6yb1.js} +6 -5
  49. package/dist/cli/{knowledge-validator-ez3ws8ef.js → knowledge-validator-exymfcb9.js} +7 -6
  50. package/dist/cli/{pending-delegations-vfnpm8zt.js → pending-delegations-yyz3fcfn.js} +5 -4
  51. package/dist/cli/{pr-subscriptions-bpvazmsw.js → pr-subscriptions-vv8byxe6.js} +6 -5
  52. package/dist/cli/{schema-x0ekqzvs.js → schema-x17zmd03.js} +1 -1
  53. package/dist/cli/scope-persistence-6m5nsp1r.js +20 -0
  54. package/dist/cli/{skill-generator-x83re96d.js → skill-generator-mx9br4ty.js} +9 -8
  55. package/dist/commands/_shared/url-security.d.ts +13 -3
  56. package/dist/commands/close.d.ts +11 -0
  57. package/dist/commands/lanes.d.ts +35 -0
  58. package/dist/commands/registry.d.ts +9 -2
  59. package/dist/commands/sdd.d.ts +10 -0
  60. package/dist/config/schema.d.ts +102 -0
  61. package/dist/git/branch.d.ts +53 -7
  62. package/dist/git/index.d.ts +5 -1
  63. package/dist/git/pr.d.ts +35 -2
  64. package/dist/hooks/delegation-gate/worktree-isolation.d.ts +118 -2
  65. package/dist/hooks/delegation-gate/worktree-merge-status.d.ts +17 -0
  66. package/dist/hooks/init-orphan-recovery-advisory.d.ts +58 -0
  67. package/dist/hooks/init-orphan-recovery.d.ts +65 -0
  68. package/dist/index.js +452 -436
  69. package/dist/sandbox/executor.d.ts +11 -1
  70. package/dist/sandbox/linux/bubblewrap-executor.d.ts +3 -1
  71. package/dist/sandbox/macos/sandbox-exec-executor.d.ts +3 -1
  72. package/dist/sandbox/win32/native-sandbox-executor.d.ts +1 -1
  73. package/dist/sandbox/win32/restricted-environment-executor.d.ts +4 -1
  74. package/dist/sdd/effective-spec.d.ts +21 -0
  75. package/dist/turbo/lean/runner.d.ts +11 -20
  76. package/dist/turbo/lean/worktree.d.ts +9 -3
  77. package/dist/utils/bun-compat.d.ts +30 -0
  78. package/dist/worktree/core.d.ts +55 -0
  79. package/dist/worktree/merge.d.ts +5 -1
  80. package/dist/worktree/types.d.ts +38 -0
  81. package/package.json +1 -1
  82. package/dist/cli/curator-llm-factory-9y15npd5.js +0 -36
  83. package/dist/cli/guardrail-explain-jk0amzae.js +0 -37
  84. package/dist/cli/hive-promoter-j2krbdn9.js +0 -44
@@ -0,0 +1,418 @@
1
+ // @bun
2
+ import {
3
+ log
4
+ } from "./index-zgwm4ryv.js";
5
+ import {
6
+ bunSpawn
7
+ } from "./index-7xgqky26.js";
8
+ import {
9
+ __require
10
+ } from "./index-a76rekgs.js";
11
+
12
+ // src/worktree/core.ts
13
+ import * as fs from "fs";
14
+ import * as fsPromises from "fs/promises";
15
+ import * as os from "os";
16
+ import * as path from "path";
17
+ var _internals = {
18
+ bunSpawn,
19
+ platform: process.platform,
20
+ sleep: (ms) => new Promise((resolve2) => setTimeout(resolve2, ms)),
21
+ osTmpdir: () => os.tmpdir(),
22
+ getCoreLongPaths: async (directory) => {
23
+ const result = await runGit(["config", "core.longpaths"], directory);
24
+ if (result.exitCode !== 0) {
25
+ return;
26
+ }
27
+ const value = result.stdout.trim().toLowerCase();
28
+ return value === "" ? undefined : value;
29
+ },
30
+ fs: {
31
+ existsSync: fs.existsSync,
32
+ cp: fsPromises.cp,
33
+ cpSync: fs.cpSync,
34
+ symlinkSync: fs.symlinkSync
35
+ },
36
+ writeScopeToDisk: async (directory, taskId, files) => {
37
+ const { writeScopeToDisk: realWrite } = await import("./scope-persistence-6m5nsp1r.js");
38
+ return realWrite(directory, taskId, files);
39
+ },
40
+ writeLaneProfileToDisk: async (_worktreePath, _laneIndex, _envOverrides) => {
41
+ return writeLaneProfileToDiskReal(_worktreePath, _laneIndex, _envOverrides);
42
+ },
43
+ removeLaneProfileFromDisk: async (_worktreePath, _laneIndex) => {
44
+ return removeLaneProfileFromDiskReal(_worktreePath, _laneIndex);
45
+ },
46
+ removeWorktree
47
+ };
48
+ async function writeLaneProfileToDiskReal(worktreePath, laneIndex, envOverrides) {
49
+ const lines = [];
50
+ for (const [key, value] of Object.entries(envOverrides)) {
51
+ if (value === null)
52
+ continue;
53
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key))
54
+ continue;
55
+ if (value.includes(`
56
+ `) || value.includes("\r")) {
57
+ log("writeLaneProfileToDisk: skipping env var with newline in value", {
58
+ key
59
+ });
60
+ continue;
61
+ }
62
+ lines.push(`${key}=${value}`);
63
+ }
64
+ if (lines.length === 0)
65
+ return;
66
+ const lanesDir = path.join(worktreePath, ".swarm", "lanes");
67
+ await fs.promises.mkdir(lanesDir, { recursive: true });
68
+ const envPath = path.join(lanesDir, `${laneIndex}.env`);
69
+ await fs.promises.writeFile(envPath, `${lines.join(`
70
+ `)}
71
+ `, "utf-8");
72
+ }
73
+ async function removeLaneProfileFromDiskReal(worktreePath, laneIndex) {
74
+ const envPath = path.join(worktreePath, ".swarm", "lanes", `${laneIndex}.env`);
75
+ try {
76
+ await fs.promises.unlink(envPath);
77
+ } catch (err) {
78
+ if (err.code !== "ENOENT") {
79
+ console.warn(`[worktree] Failed to remove lane profile ${envPath}: ${err.message}`);
80
+ }
81
+ }
82
+ }
83
+ var WORKTREE_TIMEOUT_MS = 30000;
84
+ var WIN_PATH_BUDGET = 250;
85
+ async function runGit(args, cwd, timeoutMs = WORKTREE_TIMEOUT_MS) {
86
+ const proc = _internals.bunSpawn(["git", ...args], {
87
+ cwd,
88
+ timeout: timeoutMs,
89
+ stdin: "ignore",
90
+ stdout: "pipe",
91
+ stderr: "pipe",
92
+ env: { ...process.env, LC_ALL: "C" }
93
+ });
94
+ try {
95
+ const exitCode = await proc.exited;
96
+ const stdout = await proc.stdout.text();
97
+ const stderr = await proc.stderr.text();
98
+ return { exitCode, stdout, stderr };
99
+ } finally {
100
+ try {
101
+ proc.kill();
102
+ } catch {}
103
+ }
104
+ }
105
+ async function checkPathBudget(worktreeRoot, directory) {
106
+ if (_internals.platform !== "win32") {
107
+ return { ok: true };
108
+ }
109
+ let longPaths;
110
+ try {
111
+ longPaths = await _internals.getCoreLongPaths(directory);
112
+ } catch {}
113
+ if (longPaths === "true") {
114
+ return { ok: true };
115
+ }
116
+ const proc = _internals.bunSpawn(["git", "ls-files"], {
117
+ cwd: directory,
118
+ timeout: WORKTREE_TIMEOUT_MS,
119
+ stdin: "ignore",
120
+ stdout: "pipe",
121
+ stderr: "ignore",
122
+ env: { ...process.env, LC_ALL: "C" }
123
+ });
124
+ try {
125
+ const exitCode = await proc.exited;
126
+ const stdout = await proc.stdout.text();
127
+ if (exitCode !== 0 || stdout.trim().length === 0) {
128
+ return { ok: true };
129
+ }
130
+ const files = stdout.split(/\r?\n/);
131
+ let longest = 0;
132
+ for (const file of files) {
133
+ if (file.length > longest) {
134
+ longest = file.length;
135
+ }
136
+ }
137
+ const totalPathLength = worktreeRoot.length + 1 + longest;
138
+ if (totalPathLength >= WIN_PATH_BUDGET) {
139
+ return {
140
+ ok: false,
141
+ error: `Total path budget exceeded: worktree root "${worktreeRoot}" (${worktreeRoot.length} chars) + longest file "${files.find((f) => f.length === longest)}" (${longest} chars) = ${totalPathLength} chars (budget: ${WIN_PATH_BUDGET})`,
142
+ suggestion: "Set config.worktree_dir to a shorter absolute path, or let the auto-shorten feature relocate the worktree to the system temp directory."
143
+ };
144
+ }
145
+ return { ok: true };
146
+ } finally {
147
+ try {
148
+ proc.kill();
149
+ } catch {}
150
+ }
151
+ }
152
+ function shortenWorktreePath(_directory, sessionId, laneId) {
153
+ let tmp = _internals.osTmpdir();
154
+ try {
155
+ tmp = fs.realpathSync(tmp);
156
+ } catch {}
157
+ return path.join(tmp, "swwt", sessionId, laneId);
158
+ }
159
+ function makeWorktreeBranchName(sessionId, id, options) {
160
+ if (options.branchStyle === "legacy-lane" && options.purpose === "lane") {
161
+ return `swarm-lane/${sessionId}/${id}`;
162
+ }
163
+ return `swarm/${options.purpose}/${sessionId}/${id}`;
164
+ }
165
+ async function provisionWorktree(directory, id, sessionId, options) {
166
+ const branchName = makeWorktreeBranchName(sessionId, id, options);
167
+ let worktreePath = options.worktreeDir ? path.resolve(directory, options.worktreeDir, sessionId, id) : path.resolve(path.dirname(directory), ".swarm-worktrees", sessionId, id);
168
+ const budgetResult = await checkPathBudget(worktreePath, directory);
169
+ if (budgetResult.ok === false) {
170
+ if (options.worktreeDir) {
171
+ console.warn(`[swarm] Path budget warning: ${budgetResult.error} ${budgetResult.suggestion}`);
172
+ } else {
173
+ const shortPath = shortenWorktreePath(directory, sessionId, id);
174
+ const shortBudget = await checkPathBudget(shortPath, directory);
175
+ if (shortBudget.ok === false) {
176
+ return { error: budgetResult.error };
177
+ }
178
+ worktreePath = shortPath;
179
+ }
180
+ }
181
+ const checkResult = await runGit(["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`], directory);
182
+ if (checkResult.exitCode === 0) {
183
+ const listResult = await runGit(["worktree", "list", "--porcelain"], directory);
184
+ const normalizeGitPath = (p) => {
185
+ const lexical = p.replace(/\\/g, "/").replace(/\/+$/, "");
186
+ try {
187
+ return fs.realpathSync(p).replace(/\\/g, "/").replace(/\/+$/, "");
188
+ } catch {
189
+ return lexical;
190
+ }
191
+ };
192
+ const expectedPath = normalizeGitPath(worktreePath);
193
+ const entries = [];
194
+ let current = { path: "", branch: undefined };
195
+ if (listResult.exitCode !== 0) {
196
+ const raw = listResult.stderr.trim() || listResult.stdout.trim();
197
+ const bounded = raw.length > 500 ? `${raw.slice(0, 500)}... (truncated)` : raw;
198
+ return {
199
+ error: `worktree enumeration failed: ${bounded}`
200
+ };
201
+ }
202
+ for (const rawLine of listResult.stdout.split(`
203
+ `)) {
204
+ const line = rawLine.trim();
205
+ if (line.startsWith("worktree ")) {
206
+ if (current.path)
207
+ entries.push(current);
208
+ current = {
209
+ path: normalizeGitPath(line.slice("worktree ".length)),
210
+ branch: undefined
211
+ };
212
+ } else if (line.startsWith("branch ")) {
213
+ current.branch = line.slice("branch ".length);
214
+ }
215
+ }
216
+ if (current.path)
217
+ entries.push(current);
218
+ const branchIsActiveSomewhere = entries.some((e) => e.branch === `refs/heads/${branchName}`);
219
+ const expectedPathIsRegistered = entries.some((e) => e.path === expectedPath);
220
+ if (branchIsActiveSomewhere || expectedPathIsRegistered) {
221
+ return {
222
+ error: `Branch already exists and worktree is active: ${branchName} (owned by another session)`
223
+ };
224
+ }
225
+ console.warn(`[swarm] adopting existing branch ${branchName} (stale worktree)`);
226
+ const adoptResult = await runGit(["worktree", "add", "-f", worktreePath, branchName], directory);
227
+ if (adoptResult.exitCode !== 0) {
228
+ return {
229
+ error: `Failed to adopt existing worktree: ${adoptResult.stderr.trim() || adoptResult.stdout.trim()}`
230
+ };
231
+ }
232
+ return {
233
+ worktreePath,
234
+ branchName,
235
+ purpose: options.purpose,
236
+ id,
237
+ sessionId
238
+ };
239
+ }
240
+ const addResult = await runGit(["worktree", "add", "-b", branchName, worktreePath, "HEAD"], directory);
241
+ if (addResult.exitCode !== 0) {
242
+ return {
243
+ error: `Failed to create worktree: ${addResult.stderr.trim() || addResult.stdout.trim()}`
244
+ };
245
+ }
246
+ const strategy = options.depsStrategy ?? "skip";
247
+ if (strategy !== "skip") {
248
+ const hostDepDir = path.join(directory, "node_modules");
249
+ const laneDepDir = path.join(worktreePath, "node_modules");
250
+ if (_internals.fs.existsSync(hostDepDir)) {
251
+ try {
252
+ if (strategy === "copy") {
253
+ await _internals.fs.cp(hostDepDir, laneDepDir, {
254
+ recursive: true,
255
+ force: true
256
+ });
257
+ } else if (strategy === "link") {
258
+ const isWindows = _internals.platform === "win32";
259
+ _internals.fs.symlinkSync(hostDepDir, laneDepDir, isWindows ? "junction" : "dir");
260
+ }
261
+ } catch (e) {
262
+ console.warn(`[swarm] deps_strategy '${strategy}' preparation failed for ${id}: ${e instanceof Error ? e.message : String(e)}`);
263
+ }
264
+ } else {
265
+ return {
266
+ error: `WORKTREE_DEPS_STRATEGY_HOST_DIR_MISSING: deps_strategy ${strategy} requires node_modules at ${hostDepDir} but it does not exist`
267
+ };
268
+ }
269
+ }
270
+ if (options.scope?.taskId && Array.isArray(options.scope.files)) {
271
+ try {
272
+ await _internals.writeScopeToDisk(worktreePath, options.scope.taskId, options.scope.files);
273
+ } catch {}
274
+ }
275
+ if (options.laneProfile) {
276
+ try {
277
+ await _internals.writeLaneProfileToDisk(worktreePath, options.laneProfile.laneIndex, options.laneProfile.envOverrides);
278
+ } catch {}
279
+ }
280
+ return {
281
+ worktreePath,
282
+ branchName,
283
+ purpose: options.purpose,
284
+ id,
285
+ sessionId
286
+ };
287
+ }
288
+ async function removeWorktree(worktreePath, projectRoot) {
289
+ const isWindows = _internals.platform === "win32";
290
+ const MAX_RETRIES = 4;
291
+ const RETRY_DELAY_MS = 2000;
292
+ let lastError = "";
293
+ for (let attempt = 0;attempt < MAX_RETRIES; attempt++) {
294
+ const result = await runGit(["worktree", "remove", worktreePath], projectRoot);
295
+ if (result.exitCode === 0) {
296
+ return { success: true };
297
+ }
298
+ lastError = result.stderr.trim() || result.stdout.trim();
299
+ if (isWindows && (lastError.includes("EBUSY") || lastError.includes("EPERM")) && attempt < MAX_RETRIES - 1) {
300
+ await _internals.sleep(RETRY_DELAY_MS);
301
+ continue;
302
+ }
303
+ return { error: lastError };
304
+ }
305
+ return { error: lastError };
306
+ }
307
+ async function isCleanWorktree(worktreePath) {
308
+ const [statusResult, untrackedResult] = await Promise.all([
309
+ runGit(["status", "--porcelain"], worktreePath),
310
+ runGit(["ls-files", "--others", "--exclude-standard"], worktreePath)
311
+ ]);
312
+ if (statusResult.exitCode !== 0 || untrackedResult.exitCode !== 0) {
313
+ return false;
314
+ }
315
+ const hasChanges = statusResult.stdout.trim().length > 0;
316
+ const hasUntracked = untrackedResult.stdout.trim().length > 0;
317
+ return !hasChanges && !hasUntracked;
318
+ }
319
+ async function autoCommitDirty(worktreePath) {
320
+ const COMMIT_MESSAGE = "swarm-lane: auto-commit before cleanup";
321
+ const addResult = await runGit(["add", "-A"], worktreePath);
322
+ if (addResult.exitCode !== 0) {
323
+ return {
324
+ committed: false,
325
+ reason: `git add failed: ${addResult.stderr.trim() || addResult.stdout.trim()}`
326
+ };
327
+ }
328
+ const commitResult = await runGit(["commit", "-m", COMMIT_MESSAGE], worktreePath);
329
+ if (commitResult.exitCode !== 0) {
330
+ const stderr = commitResult.stderr.trim();
331
+ const stdout = commitResult.stdout.trim();
332
+ if (stderr.includes("nothing to commit") || stdout.includes("nothing to commit") || stderr.includes("nothing added to commit")) {
333
+ return { committed: false, reason: "Nothing to commit" };
334
+ }
335
+ return {
336
+ committed: false,
337
+ reason: `git commit failed: ${stderr || stdout}`
338
+ };
339
+ }
340
+ return { committed: true, message: COMMIT_MESSAGE };
341
+ }
342
+ var SAFE_CLEAN_PATTERNS = [
343
+ "dist/",
344
+ "build/",
345
+ ".turbo/",
346
+ "coverage/",
347
+ "node_modules/.cache/",
348
+ ".log",
349
+ ".tmp",
350
+ ".o",
351
+ ".pyc",
352
+ ".class"
353
+ ];
354
+ function isSafeToClean(candidatePath) {
355
+ const normalized = candidatePath.replace(/\\/g, "/").toLowerCase();
356
+ return SAFE_CLEAN_PATTERNS.some((pattern) => {
357
+ const p = pattern.toLowerCase();
358
+ if (p.endsWith("/")) {
359
+ return normalized.startsWith(p) || normalized.includes(`/${p}`);
360
+ }
361
+ return normalized.endsWith(p);
362
+ });
363
+ }
364
+ async function cleanUntrackedFiles(worktreePath) {
365
+ const dryRun = await runGit(["clean", "-fdn"], worktreePath);
366
+ if (dryRun.exitCode === 0) {
367
+ const candidates = dryRun.stdout.trim().split(`
368
+ `).map((line) => {
369
+ const match = line.match(/^Would remove (.+)$/);
370
+ return match ? match[1].trim() : "";
371
+ }).filter((p) => p.length > 0);
372
+ const unsafePaths = candidates.filter((p) => !isSafeToClean(p));
373
+ if (unsafePaths.length > 0) {
374
+ console.warn(`[swarm:cleanUntrackedFiles] Skipping clean \u2014 untracked source files detected: ${unsafePaths.join(", ")}`);
375
+ return {
376
+ cleaned: false,
377
+ error: "untracked source files detected \u2014 skipping clean to prevent data loss"
378
+ };
379
+ }
380
+ }
381
+ const result = await runGit(["clean", "-fd"], worktreePath);
382
+ if (result.exitCode !== 0) {
383
+ return {
384
+ cleaned: false,
385
+ error: result.stderr.trim() || result.stdout.trim()
386
+ };
387
+ }
388
+ return { cleaned: true };
389
+ }
390
+ async function assertCleanWorkingTree(directory) {
391
+ const [statusResult, untrackedResult] = await Promise.all([
392
+ runGit(["status", "--porcelain"], directory),
393
+ runGit(["ls-files", "--others", "--exclude-standard"], directory)
394
+ ]);
395
+ if (statusResult.exitCode !== 0) {
396
+ return {
397
+ clean: false,
398
+ error: `Unable to verify working tree cleanliness: ${statusResult.stderr.trim() || statusResult.stdout.trim()}`
399
+ };
400
+ }
401
+ if (untrackedResult.exitCode !== 0) {
402
+ return {
403
+ clean: false,
404
+ error: `Unable to verify working tree cleanliness: ${untrackedResult.stderr.trim() || untrackedResult.stdout.trim()}`
405
+ };
406
+ }
407
+ const hasChanges = statusResult.stdout.trim().length > 0;
408
+ const hasUntracked = untrackedResult.stdout.trim().length > 0;
409
+ if (hasChanges || hasUntracked) {
410
+ return {
411
+ clean: false,
412
+ error: "Working tree has uncommitted changes. Please commit or stash before provisioning worktrees. Run 'git status' for details."
413
+ };
414
+ }
415
+ return { clean: true };
416
+ }
417
+
418
+ export { _internals, writeLaneProfileToDiskReal, removeLaneProfileFromDiskReal, checkPathBudget, shortenWorktreePath, makeWorktreeBranchName, provisionWorktree, removeWorktree, isCleanWorktree, autoCommitDirty, cleanUntrackedFiles, assertCleanWorkingTree };
@@ -3,7 +3,7 @@ import {
3
3
  ALL_AGENT_NAMES,
4
4
  PluginConfigSchema,
5
5
  stripKnownSwarmPrefix
6
- } from "./index-pchpahdf.js";
6
+ } from "./index-h4c4rrwx.js";
7
7
  import {
8
8
  log
9
9
  } from "./index-zgwm4ryv.js";
@@ -6,20 +6,20 @@ import {
6
6
  resolveSwarmKnowledgePath,
7
7
  resolveSwarmRejectedPath,
8
8
  transactKnowledge
9
- } from "./index-xmarctsf.js";
9
+ } from "./index-wg0665ft.js";
10
10
  import {
11
11
  resolveKnowledgeStoreDir
12
- } from "./index-n1sptn1w.js";
13
- import {
14
- atomicWriteFile
15
- } from "./index-9b7qp18e.js";
12
+ } from "./index-2nt4mq9n.js";
16
13
  import {
17
14
  init_logger,
18
15
  warn
19
16
  } from "./index-zgwm4ryv.js";
17
+ import {
18
+ atomicWriteFile
19
+ } from "./index-1cn967sa.js";
20
20
  import {
21
21
  require_proper_lockfile
22
- } from "./index-3naa2ajc.js";
22
+ } from "./index-vvk2g744.js";
23
23
  import {
24
24
  __toESM
25
25
  } from "./index-a76rekgs.js";
@@ -1956,7 +1956,16 @@ var WorktreeIsolationConfigSchema = exports_external.object({
1956
1956
  policy: exports_external.enum(["auto", "required", "disabled"]).default("auto"),
1957
1957
  merge_strategy: exports_external.enum(["merge", "rebase", "cherry-pick"]).default("merge"),
1958
1958
  worktree_dir: exports_external.string().optional(),
1959
- deps_strategy: exports_external.enum(["skip", "copy", "link"]).default("skip")
1959
+ deps_strategy: exports_external.enum(["skip", "copy", "link"]).default("skip"),
1960
+ serialization_release_after_dispatches: exports_external.number().int().positive().default(5),
1961
+ serialization_release_after_ms: exports_external.number().int().positive().default(60000),
1962
+ runtime_isolation: exports_external.object({
1963
+ enabled: exports_external.boolean().default(false),
1964
+ port_base: exports_external.number().int().nonnegative().max(65535).optional(),
1965
+ port_stride: exports_external.number().int().positive().default(1),
1966
+ env_overrides: exports_external.record(exports_external.string(), exports_external.string()).optional(),
1967
+ cache_redirects: exports_external.record(exports_external.string(), exports_external.string()).optional()
1968
+ }).optional()
1960
1969
  });
1961
1970
  var LeanTurboConfigSchema = exports_external.object({
1962
1971
  max_parallel_coders: exports_external.number().int().min(1).max(6).default(4),
@@ -1967,9 +1976,17 @@ var LeanTurboConfigSchema = exports_external.object({
1967
1976
  phase_critic: exports_external.boolean().default(true),
1968
1977
  integrated_diff_required: exports_external.boolean().default(true),
1969
1978
  allow_docs_only_without_reviewer: exports_external.boolean().default(false),
1970
- worktree_isolation: exports_external.boolean().default(false),
1979
+ worktree_isolation: exports_external.boolean().default(true),
1971
1980
  merge_strategy: exports_external.enum(["merge", "rebase", "cherry-pick"]).default("merge").optional(),
1972
- worktree_dir: exports_external.string().optional()
1981
+ worktree_dir: exports_external.string().optional(),
1982
+ deps_strategy: exports_external.enum(["skip", "copy", "link"]).optional(),
1983
+ runtime_isolation: exports_external.object({
1984
+ enabled: exports_external.boolean().default(false),
1985
+ port_base: exports_external.number().int().nonnegative().max(65535).optional(),
1986
+ port_stride: exports_external.number().int().positive().default(1),
1987
+ env_overrides: exports_external.record(exports_external.string(), exports_external.string()).optional(),
1988
+ cache_redirects: exports_external.record(exports_external.string(), exports_external.string()).optional()
1989
+ }).optional()
1973
1990
  });
1974
1991
  var EpicConfigSchema = exports_external.object({
1975
1992
  cochange: exports_external.object({
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  resolveKnowledgeStoreDir
4
- } from "./index-n1sptn1w.js";
5
- import {
6
- atomicWriteFile
7
- } from "./index-9b7qp18e.js";
4
+ } from "./index-2nt4mq9n.js";
8
5
  import {
9
6
  init_logger,
10
7
  warn
11
8
  } from "./index-zgwm4ryv.js";
9
+ import {
10
+ atomicWriteFile
11
+ } from "./index-1cn967sa.js";
12
12
  import {
13
13
  require_proper_lockfile
14
- } from "./index-3naa2ajc.js";
14
+ } from "./index-vvk2g744.js";
15
15
  import {
16
16
  __require,
17
17
  __toESM
@@ -594,7 +594,7 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
594
594
  deltas.push({ id, delta });
595
595
  }
596
596
  if (deltas.length > 0) {
597
- const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-kyacem71.js");
597
+ const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-exkw6yb1.js");
598
598
  await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
599
599
  }
600
600
  return {