pi-fabric 0.76.2 → 0.78.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 (80) hide show
  1. package/README.md +1 -0
  2. package/dist/agents/bash-worktree-add.d.ts +24 -0
  3. package/dist/agents/bash-worktree-add.d.ts.map +1 -0
  4. package/dist/agents/clone-first-worktree.d.ts +17 -0
  5. package/dist/agents/clone-first-worktree.d.ts.map +1 -0
  6. package/dist/agents/cow-clone.d.ts +8 -0
  7. package/dist/agents/cow-clone.d.ts.map +1 -0
  8. package/dist/agents/worktree-manager.d.ts.map +1 -1
  9. package/dist/agents/worktree-paths.d.ts +5 -0
  10. package/dist/agents/worktree-paths.d.ts.map +1 -0
  11. package/dist/capture/catalog.d.ts +3 -0
  12. package/dist/capture/catalog.d.ts.map +1 -1
  13. package/dist/chunks/{chunk-PAAXKXWT.js → chunk-2AF5ANEB.js} +16 -2
  14. package/dist/chunks/chunk-2AF5ANEB.js.map +7 -0
  15. package/dist/chunks/{chunk-QXB75FLD.js → chunk-2E3CAABA.js} +8 -1
  16. package/dist/chunks/chunk-2E3CAABA.js.map +7 -0
  17. package/dist/chunks/{chunk-6ZKYQW33.js → chunk-3QPTSKDG.js} +139 -29
  18. package/dist/chunks/chunk-3QPTSKDG.js.map +7 -0
  19. package/dist/chunks/{chunk-BT6UELLP.js → chunk-DUIHQAIZ.js} +2 -2
  20. package/dist/chunks/{chunk-6BBFFEPO.js → chunk-DYEOFQ64.js} +15 -1
  21. package/dist/chunks/{chunk-6BBFFEPO.js.map → chunk-DYEOFQ64.js.map} +2 -2
  22. package/dist/chunks/{chunk-F2GKEXGI.js → chunk-PFF3X7OO.js} +272 -146
  23. package/dist/chunks/chunk-PFF3X7OO.js.map +7 -0
  24. package/dist/chunks/{fabric-runtime-state-VCLWTB55.js → fabric-runtime-state-H2NCRJWK.js} +797 -191
  25. package/dist/chunks/fabric-runtime-state-H2NCRJWK.js.map +7 -0
  26. package/dist/chunks/{settings-VEXI347I.js → settings-FUL3U3N4.js} +2 -2
  27. package/dist/commands/fabric.d.ts.map +1 -1
  28. package/dist/config.d.ts +4 -0
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/core/action-registry.d.ts +1 -0
  31. package/dist/core/action-registry.d.ts.map +1 -1
  32. package/dist/core/action-registry.js +1 -1
  33. package/dist/fabric-runtime-state.d.ts +2 -0
  34. package/dist/fabric-runtime-state.d.ts.map +1 -1
  35. package/dist/fabric-state.d.ts +1 -0
  36. package/dist/fabric-state.d.ts.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +218 -8
  39. package/dist/index.js.map +3 -3
  40. package/dist/providers/arg-normalization.d.ts +3 -0
  41. package/dist/providers/arg-normalization.d.ts.map +1 -1
  42. package/dist/providers/memory-provider.js +1 -1
  43. package/dist/providers/pi-tools-provider.d.ts.map +1 -1
  44. package/dist/repairs/active.d.ts +7 -0
  45. package/dist/repairs/active.d.ts.map +1 -0
  46. package/dist/repairs/apply.d.ts +7 -0
  47. package/dist/repairs/apply.d.ts.map +1 -0
  48. package/dist/repairs/catalog-digest.d.ts +5 -0
  49. package/dist/repairs/catalog-digest.d.ts.map +1 -0
  50. package/dist/repairs/classify.d.ts +10 -0
  51. package/dist/repairs/classify.d.ts.map +1 -0
  52. package/dist/repairs/compiler.d.ts +32 -0
  53. package/dist/repairs/compiler.d.ts.map +1 -0
  54. package/dist/repairs/promote.d.ts +4 -0
  55. package/dist/repairs/promote.d.ts.map +1 -0
  56. package/dist/repairs/store.d.ts +9 -0
  57. package/dist/repairs/store.d.ts.map +1 -0
  58. package/dist/repairs/types.d.ts +49 -0
  59. package/dist/repairs/types.d.ts.map +1 -0
  60. package/dist/residency/client.d.ts.map +1 -1
  61. package/dist/residency/host.js +3 -3
  62. package/dist/residency/pi-entry.js +3 -3
  63. package/dist/speculation/store.d.ts +11 -7
  64. package/dist/speculation/store.d.ts.map +1 -1
  65. package/dist/speculation/types.d.ts +2 -1
  66. package/dist/speculation/types.d.ts.map +1 -1
  67. package/docs/agents.md +1 -1
  68. package/docs/architecture.md +3 -1
  69. package/docs/configuration.md +4 -0
  70. package/docs/interface.md +1 -0
  71. package/docs/repairs.md +57 -0
  72. package/package.json +1 -1
  73. package/skills/fabric-exec/references/agents.md +3 -3
  74. package/dist/chunks/chunk-6ZKYQW33.js.map +0 -7
  75. package/dist/chunks/chunk-F2GKEXGI.js.map +0 -7
  76. package/dist/chunks/chunk-PAAXKXWT.js.map +0 -7
  77. package/dist/chunks/chunk-QXB75FLD.js.map +0 -7
  78. package/dist/chunks/fabric-runtime-state-VCLWTB55.js.map +0 -7
  79. /package/dist/chunks/{chunk-BT6UELLP.js.map → chunk-DUIHQAIZ.js.map} +0 -0
  80. /package/dist/chunks/{settings-VEXI347I.js.map → settings-FUL3U3N4.js.map} +0 -0
@@ -27,7 +27,7 @@ import {
27
27
  DEFAULT_FABRIC_CONFIG,
28
28
  MAX_AGENT_TIMEOUT_MS,
29
29
  MIN_AGENT_TIMEOUT_MS
30
- } from "./chunk-QXB75FLD.js";
30
+ } from "./chunk-2E3CAABA.js";
31
31
  import {
32
32
  isFabricThinking
33
33
  } from "./chunk-7B55UIZL.js";
@@ -905,9 +905,9 @@ function appendBudgetLedger(file, entry) {
905
905
 
906
906
  // src/agents/manager.ts
907
907
  import { randomUUID as randomUUID4 } from "node:crypto";
908
- import fs6 from "node:fs";
909
- import os4 from "node:os";
910
- import path7 from "node:path";
908
+ import fs9 from "node:fs";
909
+ import os3 from "node:os";
910
+ import path10 from "node:path";
911
911
  import { fileURLToPath } from "node:url";
912
912
 
913
913
  // src/agents/semaphore.ts
@@ -1267,13 +1267,137 @@ var TmuxTransport = class {
1267
1267
  };
1268
1268
 
1269
1269
  // src/agents/worktree-manager.ts
1270
+ import fs7 from "node:fs";
1271
+ import path7 from "node:path";
1272
+
1273
+ // src/agents/clone-first-worktree.ts
1274
+ import fs6 from "node:fs";
1275
+ import path6 from "node:path";
1276
+
1277
+ // src/agents/cow-clone.ts
1270
1278
  import fs4 from "node:fs";
1271
- import os2 from "node:os";
1272
1279
  import path4 from "node:path";
1280
+ var CLONE_SKIP_PREFIXES = [".git", ".pi/fabric/worktrees"];
1281
+ var CowUnavailableError = class extends Error {
1282
+ constructor(message, options) {
1283
+ super(message, options);
1284
+ this.name = "CowUnavailableError";
1285
+ }
1286
+ };
1287
+ var posixRel = (value) => value.replaceAll("\\", "/");
1288
+ var isCowUnavailable = (error) => {
1289
+ if (typeof error !== "object" || error === null || !("code" in error)) return false;
1290
+ const code = error.code;
1291
+ return code === "ENOTSUP" || code === "EOPNOTSUPP" || code === "EXDEV" || code === "ENOTSUPP";
1292
+ };
1293
+ var cloneEntry = async (from, to) => {
1294
+ try {
1295
+ await fs4.promises.cp(from, to, {
1296
+ recursive: true,
1297
+ verbatimSymlinks: true,
1298
+ force: false,
1299
+ mode: fs4.constants.COPYFILE_FICLONE_FORCE
1300
+ });
1301
+ } catch (error) {
1302
+ if (isCowUnavailable(error)) {
1303
+ throw new CowUnavailableError(`copy-on-write clone unavailable: ${from} -> ${to}`, {
1304
+ cause: error
1305
+ });
1306
+ }
1307
+ throw error;
1308
+ }
1309
+ };
1310
+ var skipped = (rel, prefixes) => {
1311
+ const value = posixRel(rel);
1312
+ return prefixes.some((prefix) => value === prefix || value.startsWith(`${prefix}/`));
1313
+ };
1314
+ var hasNestedSkip = (rel, prefixes) => {
1315
+ const value = posixRel(rel);
1316
+ return prefixes.some((prefix) => prefix.startsWith(`${value}/`));
1317
+ };
1318
+ var cloneLevel = async (source, dest, relBase, prefixes) => {
1319
+ await fs4.promises.mkdir(dest, { recursive: true });
1320
+ const entries = await fs4.promises.readdir(source, { withFileTypes: true });
1321
+ for (const entry of entries) {
1322
+ const rel = relBase ? `${relBase}/${entry.name}` : entry.name;
1323
+ if (skipped(rel, prefixes)) continue;
1324
+ const from = path4.join(source, entry.name);
1325
+ const to = path4.join(dest, entry.name);
1326
+ if (entry.isDirectory() && !entry.isSymbolicLink() && hasNestedSkip(rel, prefixes)) {
1327
+ await cloneLevel(from, to, rel, prefixes);
1328
+ continue;
1329
+ }
1330
+ if (!(entry.isFile() || entry.isDirectory() || entry.isSymbolicLink())) continue;
1331
+ await cloneEntry(from, to);
1332
+ }
1333
+ };
1334
+ var cloneTree = async (source, dest, prefixes = CLONE_SKIP_PREFIXES) => {
1335
+ await cloneLevel(source, dest, "", prefixes);
1336
+ };
1337
+
1338
+ // src/agents/worktree-paths.ts
1339
+ import fs5 from "node:fs";
1340
+ import path5 from "node:path";
1341
+ var FABRIC_WORKTREE_SEGMENTS = [".pi", "fabric", "worktrees"];
1342
+ var FABRIC_WORKTREE_EXCLUDE = ".pi/fabric/worktrees/";
1343
+ var fabricWorktreePath = (gitRoot, id) => path5.join(gitRoot, ...FABRIC_WORKTREE_SEGMENTS, id);
1344
+ var isFabricWorktreePath = (worktree, id) => {
1345
+ const parts = worktree.split(/[\\/]/).filter(Boolean);
1346
+ return parts.length >= 4 && parts.at(-1) === id && parts.at(-2) === "worktrees" && parts.at(-3) === "fabric" && parts.at(-4) === ".pi";
1347
+ };
1348
+ var ensureWorktreeExclude = async (gitRoot) => {
1349
+ const located = await executeFile("git", ["rev-parse", "--git-path", "info/exclude"], {
1350
+ cwd: gitRoot,
1351
+ timeoutMs: 1e4
1352
+ });
1353
+ const excludePath = path5.resolve(gitRoot, located.stdout.trim());
1354
+ fs5.mkdirSync(path5.dirname(excludePath), { recursive: true });
1355
+ let current = "";
1356
+ try {
1357
+ current = fs5.readFileSync(excludePath, "utf8");
1358
+ } catch (error) {
1359
+ const code = error instanceof Error && "code" in error ? error.code : void 0;
1360
+ if (code !== "ENOENT") throw error;
1361
+ }
1362
+ const lines = current.split(/\r?\n/);
1363
+ if (lines.some((line) => line.trim() === FABRIC_WORKTREE_EXCLUDE)) return;
1364
+ const prefix = current.length === 0 || current.endsWith("\n") ? "" : "\n";
1365
+ fs5.appendFileSync(excludePath, `${prefix}${FABRIC_WORKTREE_EXCLUDE}
1366
+ `);
1367
+ };
1368
+
1369
+ // src/agents/clone-first-worktree.ts
1370
+ var addCloneFirstWorktree = async (options) => {
1371
+ const dest = options.dest;
1372
+ if (isFabricWorktreePath(dest, path6.basename(dest))) {
1373
+ await ensureWorktreeExclude(options.gitRoot);
1374
+ }
1375
+ fs6.mkdirSync(path6.dirname(dest), { recursive: true });
1376
+ const args = ["worktree", "add", "--no-checkout"];
1377
+ if (options.quiet) args.push("-q");
1378
+ if (options.detach) args.push("--detach");
1379
+ if (options.branch) args.push(options.branch.flag, options.branch.name);
1380
+ args.push(dest);
1381
+ if (options.startPoint) args.push(options.startPoint);
1382
+ const added = await executeFile("git", args, { cwd: options.gitRoot, timeoutMs: 6e4 });
1383
+ let cloned = false;
1384
+ try {
1385
+ await cloneTree(options.gitRoot, dest, CLONE_SKIP_PREFIXES);
1386
+ cloned = true;
1387
+ } catch (error) {
1388
+ cloned = false;
1389
+ if (!(error instanceof CowUnavailableError) && !(error instanceof Error)) throw error;
1390
+ }
1391
+ await executeFile("git", ["reset", "--hard", "HEAD"], { cwd: dest, timeoutMs: 6e4 });
1392
+ await executeFile("git", ["clean", "-fd"], { cwd: dest, timeoutMs: 6e4 });
1393
+ return { cloned, message: added.stdout.trim() };
1394
+ };
1395
+
1396
+ // src/agents/worktree-manager.ts
1273
1397
  var safeLabel = (value) => value.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 30) || "agent";
1274
1398
  var isInside = (root, target) => {
1275
- const relative = path4.relative(root, target);
1276
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path4.sep}`) && !path4.isAbsolute(relative);
1399
+ const relative = path7.relative(root, target);
1400
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path7.sep}`) && !path7.isAbsolute(relative);
1277
1401
  };
1278
1402
  var worktreePrefixParts = (prefix) => {
1279
1403
  const parts = prefix.split(/[\\/]+/).filter(Boolean);
@@ -1291,27 +1415,27 @@ var WorktreeManager = class {
1291
1415
  ]);
1292
1416
  const output = root.stdout.trim();
1293
1417
  if (!output) throw new Error("Git did not return a worktree root");
1294
- gitRoot = fs4.realpathSync(output);
1418
+ gitRoot = fs7.realpathSync(output);
1295
1419
  sourcePrefix = prefix2.stdout.trim();
1296
1420
  } catch {
1297
1421
  throw new Error("Worktree isolation requires a Git repository");
1298
1422
  }
1299
1423
  const branch = `pi-fabric/${safeLabel(name)}-${id.slice(0, 8)}`;
1300
- const parent = path4.join(os2.tmpdir(), "pi-fabric-worktrees");
1301
- fs4.mkdirSync(parent, { recursive: true });
1302
- const worktreePath = path4.join(parent, id);
1303
- await executeFile("git", ["worktree", "add", "-b", branch, worktreePath, "HEAD"], {
1304
- cwd: gitRoot,
1305
- timeoutMs: 6e4
1424
+ const worktreePath = fabricWorktreePath(gitRoot, id);
1425
+ await addCloneFirstWorktree({
1426
+ gitRoot,
1427
+ dest: worktreePath,
1428
+ branch: { flag: "-b", name: branch },
1429
+ startPoint: "HEAD"
1306
1430
  });
1307
- const canonicalWorktreePath = fs4.realpathSync(worktreePath);
1431
+ const canonicalWorktreePath = fs7.realpathSync(worktreePath);
1308
1432
  const prefix = preserveSourceSubdirectory ? worktreePrefixParts(sourcePrefix) : void 0;
1309
1433
  let effectiveCwd = canonicalWorktreePath;
1310
1434
  if (prefix && prefix.length > 0) {
1311
- const candidate = path4.resolve(canonicalWorktreePath, ...prefix);
1435
+ const candidate = path7.resolve(canonicalWorktreePath, ...prefix);
1312
1436
  try {
1313
- const canonicalCandidate = fs4.realpathSync(candidate);
1314
- if (fs4.statSync(canonicalCandidate).isDirectory() && isInside(canonicalWorktreePath, canonicalCandidate)) {
1437
+ const canonicalCandidate = fs7.realpathSync(candidate);
1438
+ if (fs7.statSync(canonicalCandidate).isDirectory() && isInside(canonicalWorktreePath, canonicalCandidate)) {
1315
1439
  effectiveCwd = canonicalCandidate;
1316
1440
  }
1317
1441
  } catch {
@@ -1343,15 +1467,15 @@ var WorktreeManager = class {
1343
1467
  };
1344
1468
 
1345
1469
  // src/storage/retention.ts
1346
- import fs5 from "node:fs";
1347
- import path5 from "node:path";
1470
+ import fs8 from "node:fs";
1471
+ import path8 from "node:path";
1348
1472
  var FABRIC_RUN_ROOT_PREFIX = "pi-fabric-runs-";
1349
1473
  var RUN_ROOT_OWNER_FILE = ".fabric-owner.json";
1350
1474
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "stopped", "timed_out"]);
1351
- var ownerPath = (root) => path5.join(root, RUN_ROOT_OWNER_FILE);
1475
+ var ownerPath = (root) => path8.join(root, RUN_ROOT_OWNER_FILE);
1352
1476
  var readJson = (filePath) => {
1353
1477
  try {
1354
- return JSON.parse(fs5.readFileSync(filePath, "utf8"));
1478
+ return JSON.parse(fs8.readFileSync(filePath, "utf8"));
1355
1479
  } catch {
1356
1480
  return void 0;
1357
1481
  }
@@ -1393,32 +1517,32 @@ var pruneClosedRunRoot = (root, orphanedTempRunRetentionMs, oneShotRunRetentionM
1393
1517
  const removed = [];
1394
1518
  let entries;
1395
1519
  try {
1396
- entries = fs5.readdirSync(root, { withFileTypes: true });
1520
+ entries = fs8.readdirSync(root, { withFileTypes: true });
1397
1521
  } catch {
1398
1522
  return removed;
1399
1523
  }
1400
1524
  for (const entry of entries) {
1401
1525
  if (!entry.isDirectory()) continue;
1402
- const runDirectory = path5.join(root, entry.name);
1403
- const record = readJson(path5.join(runDirectory, "status.json"));
1526
+ const runDirectory = path8.join(root, entry.name);
1527
+ const record = readJson(path8.join(runDirectory, "status.json"));
1404
1528
  if (!record?.status || !TERMINAL_STATUSES.has(record.status)) continue;
1405
1529
  let fallback = now;
1406
1530
  try {
1407
- fallback = fs5.statSync(runDirectory).mtimeMs;
1531
+ fallback = fs8.statSync(runDirectory).mtimeMs;
1408
1532
  } catch {
1409
1533
  }
1410
1534
  const retentionMs = record.actorId ? orphanedTempRunRetentionMs : oneShotRunRetentionMs;
1411
1535
  if (now - recordAgeReference(record, fallback) < retentionMs) continue;
1412
- fs5.rmSync(runDirectory, { recursive: true, force: true });
1536
+ fs8.rmSync(runDirectory, { recursive: true, force: true });
1413
1537
  removed.push(runDirectory);
1414
1538
  }
1415
1539
  return removed;
1416
1540
  };
1417
1541
  var removeIfEmpty = (root) => {
1418
1542
  try {
1419
- const remaining = fs5.readdirSync(root).filter((name) => name !== RUN_ROOT_OWNER_FILE);
1543
+ const remaining = fs8.readdirSync(root).filter((name) => name !== RUN_ROOT_OWNER_FILE);
1420
1544
  if (remaining.length > 0) return false;
1421
- fs5.rmSync(root, { recursive: true, force: true });
1545
+ fs8.rmSync(root, { recursive: true, force: true });
1422
1546
  return true;
1423
1547
  } catch {
1424
1548
  return false;
@@ -1429,19 +1553,19 @@ var sweepTempRunRoots = (options) => {
1429
1553
  const result = { removedRoots: [], removedRuns: [] };
1430
1554
  let entries;
1431
1555
  try {
1432
- entries = fs5.readdirSync(options.tempRoot, { withFileTypes: true });
1556
+ entries = fs8.readdirSync(options.tempRoot, { withFileTypes: true });
1433
1557
  } catch {
1434
1558
  return result;
1435
1559
  }
1436
1560
  for (const entry of entries) {
1437
1561
  if (!entry.isDirectory() || !entry.name.startsWith(FABRIC_RUN_ROOT_PREFIX)) continue;
1438
- const root = path5.join(options.tempRoot, entry.name);
1439
- if (options.currentRoot && path5.resolve(root) === path5.resolve(options.currentRoot)) continue;
1562
+ const root = path8.join(options.tempRoot, entry.name);
1563
+ if (options.currentRoot && path8.resolve(root) === path8.resolve(options.currentRoot)) continue;
1440
1564
  const owner = readJson(ownerPath(root));
1441
1565
  if (!owner) {
1442
1566
  try {
1443
- if (fs5.readdirSync(root).length === 0 && now - fs5.statSync(root).mtimeMs >= options.orphanedTempRunRetentionMs) {
1444
- fs5.rmSync(root, { recursive: true, force: true });
1567
+ if (fs8.readdirSync(root).length === 0 && now - fs8.statSync(root).mtimeMs >= options.orphanedTempRunRetentionMs) {
1568
+ fs8.rmSync(root, { recursive: true, force: true });
1445
1569
  result.removedRoots.push(root);
1446
1570
  }
1447
1571
  } catch {
@@ -1466,7 +1590,7 @@ var sweepTempRunRoots = (options) => {
1466
1590
  continue;
1467
1591
  }
1468
1592
  if (now - owner.orphanedAt < options.orphanedTempRunRetentionMs) continue;
1469
- fs5.rmSync(root, { recursive: true, force: true });
1593
+ fs8.rmSync(root, { recursive: true, force: true });
1470
1594
  result.removedRoots.push(root);
1471
1595
  }
1472
1596
  return result;
@@ -1476,44 +1600,44 @@ var pruneActorRunArchives = (options) => {
1476
1600
  const removed = [];
1477
1601
  let entries;
1478
1602
  try {
1479
- entries = fs5.readdirSync(options.runsDirectory, { withFileTypes: true });
1603
+ entries = fs8.readdirSync(options.runsDirectory, { withFileTypes: true });
1480
1604
  } catch {
1481
1605
  return removed;
1482
1606
  }
1483
1607
  for (const entry of entries) {
1484
1608
  if (!entry.isDirectory() || entry.name === options.latestRunId) continue;
1485
- const runDirectory = path5.join(options.runsDirectory, entry.name);
1486
- const record = readJson(path5.join(runDirectory, "status.json"));
1609
+ const runDirectory = path8.join(options.runsDirectory, entry.name);
1610
+ const record = readJson(path8.join(runDirectory, "status.json"));
1487
1611
  if (!record?.status || !TERMINAL_STATUSES.has(record.status)) continue;
1488
1612
  let fallback = now;
1489
1613
  try {
1490
- fallback = fs5.statSync(runDirectory).mtimeMs;
1614
+ fallback = fs8.statSync(runDirectory).mtimeMs;
1491
1615
  } catch {
1492
1616
  }
1493
1617
  if (now - recordAgeReference(record, fallback) < options.retentionMs) continue;
1494
- fs5.rmSync(runDirectory, { recursive: true, force: true });
1618
+ fs8.rmSync(runDirectory, { recursive: true, force: true });
1495
1619
  removed.push(runDirectory);
1496
1620
  }
1497
1621
  return removed;
1498
1622
  };
1499
1623
 
1500
1624
  // src/agents/session-export.ts
1501
- import os3 from "node:os";
1502
- import path6 from "node:path";
1625
+ import os2 from "node:os";
1626
+ import path9 from "node:path";
1503
1627
  var SESSION_EXPORT_ENV = "PI_FABRIC_AGENT_DIR";
1504
- var expandHome = (value) => value === "~" ? os3.homedir() : value.startsWith("~/") || value.startsWith(`~${path6.win32.sep}`) ? path6.join(os3.homedir(), value.slice(2)) : value;
1628
+ var expandHome = (value) => value === "~" ? os2.homedir() : value.startsWith("~/") || value.startsWith(`~${path9.win32.sep}`) ? path9.join(os2.homedir(), value.slice(2)) : value;
1505
1629
  var encodeSessionExportCwd = (cwd) => {
1506
- const absolute = path6.isAbsolute(cwd) || path6.win32.isAbsolute(cwd) ? cwd : path6.resolve(cwd);
1630
+ const absolute = path9.isAbsolute(cwd) || path9.win32.isAbsolute(cwd) ? cwd : path9.resolve(cwd);
1507
1631
  return `--${absolute.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
1508
1632
  };
1509
1633
  var resolveSessionExportDir = (config) => {
1510
1634
  if (!config.sessionExport) return void 0;
1511
- const raw = process.env[SESSION_EXPORT_ENV]?.trim() || config.sessionExportDir.trim() || path6.join(os3.homedir(), ".pi", "agent");
1635
+ const raw = process.env[SESSION_EXPORT_ENV]?.trim() || config.sessionExportDir.trim() || path9.join(os2.homedir(), ".pi", "agent");
1512
1636
  return expandHome(raw);
1513
1637
  };
1514
1638
  var sessionExportFileFor = (root, cwd, runId, at) => {
1515
1639
  const fileTimestamp = at.toISOString().replace(/[:.]/g, "-");
1516
- return path6.join(
1640
+ return path9.join(
1517
1641
  root,
1518
1642
  "sessions",
1519
1643
  ".fabric",
@@ -1558,11 +1682,11 @@ var resolveAgentCwd = (parentCwd, requestedCwd) => {
1558
1682
  if (typeof requested !== "string" || requested.trim().length === 0) {
1559
1683
  throw new Error(`Invalid Fabric agent cwd ${JSON.stringify(requested)}: path must not be empty`);
1560
1684
  }
1561
- const candidate = path7.isAbsolute(requested) ? requested : path7.resolve(parentCwd, requested);
1685
+ const candidate = path10.isAbsolute(requested) ? requested : path10.resolve(parentCwd, requested);
1562
1686
  try {
1563
- const canonical = fs6.realpathSync(candidate);
1564
- fs6.accessSync(canonical, fs6.constants.R_OK | fs6.constants.X_OK);
1565
- if (!fs6.statSync(canonical).isDirectory()) {
1687
+ const canonical = fs9.realpathSync(candidate);
1688
+ fs9.accessSync(canonical, fs9.constants.R_OK | fs9.constants.X_OK);
1689
+ if (!fs9.statSync(canonical).isDirectory()) {
1566
1690
  throw new Error("path is not a directory");
1567
1691
  }
1568
1692
  return canonical;
@@ -1581,7 +1705,7 @@ var retryablePiStartupError = (error) => typeof error === "string" && /\b(?:no|m
1581
1705
  var safeName = (value) => value.replace(/[\r\n\t]+/g, " ").trim().slice(0, MAX_NAME_LENGTH) || "Fabric agent";
1582
1706
  var readRecord = (filePath) => {
1583
1707
  try {
1584
- const parsed = JSON.parse(fs6.readFileSync(filePath, "utf8"));
1708
+ const parsed = JSON.parse(fs9.readFileSync(filePath, "utf8"));
1585
1709
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
1586
1710
  const record = parsed;
1587
1711
  return {
@@ -1621,24 +1745,24 @@ var compactUiRecord = (record) => {
1621
1745
  };
1622
1746
  var readNestedAgents = (runDirectory, depth = 0) => {
1623
1747
  if (depth >= 8) return [];
1624
- const nestedRoot = path7.join(runDirectory, "nested");
1748
+ const nestedRoot = path10.join(runDirectory, "nested");
1625
1749
  let entries;
1626
1750
  try {
1627
- entries = fs6.readdirSync(nestedRoot);
1751
+ entries = fs9.readdirSync(nestedRoot);
1628
1752
  } catch {
1629
1753
  return [];
1630
1754
  }
1631
1755
  const agents = [];
1632
1756
  for (const entry of entries.slice(0, 200)) {
1633
- const runDirectory2 = path7.join(nestedRoot, entry);
1634
- const record = readRecord(path7.join(runDirectory2, "status.json"));
1757
+ const runDirectory2 = path10.join(nestedRoot, entry);
1758
+ const record = readRecord(path10.join(runDirectory2, "status.json"));
1635
1759
  if (!record) continue;
1636
1760
  const nestedAgents = readNestedAgents(runDirectory2, depth + 1);
1637
1761
  const { logFile: _logFile, nestedAgents: _nestedAgents, ...safeRecord } = record;
1638
1762
  agents.push(
1639
1763
  compactUiRecord({
1640
1764
  ...safeRecord,
1641
- logFile: path7.join(runDirectory2, "events.jsonl"),
1765
+ logFile: path10.join(runDirectory2, "events.jsonl"),
1642
1766
  ...nestedAgents.length > 0 ? { nestedAgents } : {}
1643
1767
  })
1644
1768
  );
@@ -1646,7 +1770,7 @@ var readNestedAgents = (runDirectory, depth = 0) => {
1646
1770
  return agents;
1647
1771
  };
1648
1772
  var summarizeRunLog = (runDirectory, lines) => {
1649
- const page = readJsonlPage(path7.join(runDirectory, "events.jsonl"), lines);
1773
+ const page = readJsonlPage(path10.join(runDirectory, "events.jsonl"), lines);
1650
1774
  const summary = [];
1651
1775
  for (const entry of page.lines) {
1652
1776
  const parsed = entry.parsed;
@@ -1697,7 +1821,7 @@ var AgentManager = class {
1697
1821
  this.config = config;
1698
1822
  this.#semaphore = new Semaphore(config.maxConcurrent);
1699
1823
  this.#managedTempRoot = options.runRoot === void 0 && process.env.PI_FABRIC_RUN_ROOT === void 0;
1700
- this.#runRoot = options.runRoot ?? process.env.PI_FABRIC_RUN_ROOT ?? fs6.mkdtempSync(path7.join(os4.tmpdir(), "pi-fabric-runs-"));
1824
+ this.#runRoot = options.runRoot ?? process.env.PI_FABRIC_RUN_ROOT ?? fs9.mkdtempSync(path10.join(os3.tmpdir(), "pi-fabric-runs-"));
1701
1825
  this.#retention = options.retention ?? DEFAULT_FABRIC_CONFIG.retention;
1702
1826
  this.#workerPath = options.workerPath ?? fileURLToPath(new URL("../worker.js", import.meta.url));
1703
1827
  this.#fabricExtensionPath = options.fabricExtensionPath ?? fileURLToPath(new URL("../index.js", import.meta.url));
@@ -1729,7 +1853,7 @@ var AgentManager = class {
1729
1853
  if (this.#managedTempRoot) {
1730
1854
  markRunRootActive(this.#runRoot);
1731
1855
  sweepTempRunRoots({
1732
- tempRoot: os4.tmpdir(),
1856
+ tempRoot: os3.tmpdir(),
1733
1857
  currentRoot: this.#runRoot,
1734
1858
  orphanedTempRunRetentionMs: this.#retention.orphanedTempRunMs,
1735
1859
  oneShotRunRetentionMs: this.#retention.oneShotRunMs
@@ -1851,24 +1975,24 @@ var AgentManager = class {
1851
1975
  const release = await this.#semaphore.acquire(signal);
1852
1976
  const id = randomUUID4().replaceAll("-", "");
1853
1977
  const name = safeName(request.name ?? request.task.split("\n", 1)[0] ?? "Fabric agent");
1854
- const runDirectory = path7.join(this.#runRoot, id);
1855
- fs6.mkdirSync(runDirectory, { recursive: true });
1856
- const taskFile = path7.join(runDirectory, "task.txt");
1857
- const statusFile = path7.join(runDirectory, "status.json");
1858
- const lifecycleFile = path7.join(runDirectory, "lifecycle.jsonl");
1859
- const logFile = path7.join(runDirectory, "events.jsonl");
1860
- const steerFile = path7.join(runDirectory, "steer.jsonl");
1861
- const schemaFile = request.schema ? path7.join(runDirectory, "schema.json") : void 0;
1862
- const imagesFile = request.images && request.images.length > 0 ? path7.join(runDirectory, "images.json") : void 0;
1863
- fs6.writeFileSync(taskFile, request.task, { encoding: "utf8", mode: 384 });
1978
+ const runDirectory = path10.join(this.#runRoot, id);
1979
+ fs9.mkdirSync(runDirectory, { recursive: true });
1980
+ const taskFile = path10.join(runDirectory, "task.txt");
1981
+ const statusFile = path10.join(runDirectory, "status.json");
1982
+ const lifecycleFile = path10.join(runDirectory, "lifecycle.jsonl");
1983
+ const logFile = path10.join(runDirectory, "events.jsonl");
1984
+ const steerFile = path10.join(runDirectory, "steer.jsonl");
1985
+ const schemaFile = request.schema ? path10.join(runDirectory, "schema.json") : void 0;
1986
+ const imagesFile = request.images && request.images.length > 0 ? path10.join(runDirectory, "images.json") : void 0;
1987
+ fs9.writeFileSync(taskFile, request.task, { encoding: "utf8", mode: 384 });
1864
1988
  if (imagesFile) {
1865
- fs6.writeFileSync(imagesFile, JSON.stringify(request.images), {
1989
+ fs9.writeFileSync(imagesFile, JSON.stringify(request.images), {
1866
1990
  encoding: "utf8",
1867
1991
  mode: 384
1868
1992
  });
1869
1993
  }
1870
1994
  if (schemaFile) {
1871
- fs6.writeFileSync(schemaFile, JSON.stringify(request.schema, null, 2), {
1995
+ fs9.writeFileSync(schemaFile, JSON.stringify(request.schema, null, 2), {
1872
1996
  encoding: "utf8",
1873
1997
  mode: 384
1874
1998
  });
@@ -1891,7 +2015,7 @@ var AgentManager = class {
1891
2015
  const sessionFile = request.sessionSeed ? writeHandoffSession(
1892
2016
  request.sessionSeed,
1893
2017
  agentCwd,
1894
- path7.join(runDirectory, "handoff-session"),
2018
+ path10.join(runDirectory, "handoff-session"),
1895
2019
  request.thinkingTransfer,
1896
2020
  request.handoffCompact
1897
2021
  ) : request.sessionFile;
@@ -1968,7 +2092,7 @@ var AgentManager = class {
1968
2092
  ...this.#identityId ? ["--owner-identity-id", this.#identityId] : [],
1969
2093
  ...request.runnerSessionId ? ["--runner-session-id", request.runnerSessionId] : [],
1970
2094
  "--run-root",
1971
- path7.join(runDirectory, "nested"),
2095
+ path10.join(runDirectory, "nested"),
1972
2096
  "--steer-file",
1973
2097
  steerFile,
1974
2098
  ...schemaFile ? ["--schema-file", schemaFile] : [],
@@ -2156,15 +2280,15 @@ var AgentManager = class {
2156
2280
  this.#runs.delete(id);
2157
2281
  this.#pruneRetainedUiRecords();
2158
2282
  this.#invalidateUiList();
2159
- return { cleaned: cleaned || !fs6.existsSync(managed.runDirectory) };
2283
+ return { cleaned: cleaned || !fs9.existsSync(managed.runDirectory) };
2160
2284
  }
2161
2285
  readLog(id, opts = {}) {
2162
2286
  const managed = this.#requireRun(id);
2163
2287
  const runDirectory = managed.runDirectory;
2164
- const logFile = path7.join(runDirectory, "events.jsonl");
2288
+ const logFile = path10.join(runDirectory, "events.jsonl");
2165
2289
  const lines = Math.max(1, Math.min(opts.lines ?? 200, 5e3));
2166
2290
  const page = readJsonlPage(logFile, lines, opts.before);
2167
- const statusRecord = readRecord(path7.join(runDirectory, "status.json"));
2291
+ const statusRecord = readRecord(path10.join(runDirectory, "status.json"));
2168
2292
  return {
2169
2293
  id,
2170
2294
  runDirectory,
@@ -2225,10 +2349,10 @@ var AgentManager = class {
2225
2349
  `Fabric agent ${id} already finished (${record.status}); steering has no target`
2226
2350
  );
2227
2351
  }
2228
- const steerFile = path7.join(managed.runDirectory, "steer.jsonl");
2352
+ const steerFile = path10.join(managed.runDirectory, "steer.jsonl");
2229
2353
  const messageId = randomUUID4();
2230
2354
  const line = JSON.stringify({ ...entry, id: messageId, ts: Date.now() }) + "\n";
2231
- fs6.appendFileSync(steerFile, line, { encoding: "utf8", mode: 384 });
2355
+ fs9.appendFileSync(steerFile, line, { encoding: "utf8", mode: 384 });
2232
2356
  return { queued: true, messageId };
2233
2357
  }
2234
2358
  async close() {
@@ -2246,7 +2370,7 @@ var AgentManager = class {
2246
2370
  await removeTree(this.#runRoot);
2247
2371
  }
2248
2372
  if (this.#budgetOwned && this.#budget) {
2249
- await removeTree(path7.dirname(this.#budget.file));
2373
+ await removeTree(path10.dirname(this.#budget.file));
2250
2374
  clearOwnedBudgetEnv();
2251
2375
  }
2252
2376
  }
@@ -2260,7 +2384,7 @@ var AgentManager = class {
2260
2384
  if (this.#managedTempRoot) {
2261
2385
  heartbeatRunRoot(this.#runRoot, now);
2262
2386
  sweepTempRunRoots({
2263
- tempRoot: os4.tmpdir(),
2387
+ tempRoot: os3.tmpdir(),
2264
2388
  currentRoot: this.#runRoot,
2265
2389
  orphanedTempRunRetentionMs: this.#retention.orphanedTempRunMs,
2266
2390
  oneShotRunRetentionMs: this.#retention.oneShotRunMs,
@@ -2275,7 +2399,7 @@ var AgentManager = class {
2275
2399
  });
2276
2400
  for (const managed of expired) {
2277
2401
  await removeTree(managed.runDirectory).catch(() => void 0);
2278
- if (!fs6.existsSync(managed.runDirectory)) this.#runs.delete(managed.id);
2402
+ if (!fs9.existsSync(managed.runDirectory)) this.#runs.delete(managed.id);
2279
2403
  }
2280
2404
  if (expired.length > 0) {
2281
2405
  this.#pruneRetainedUiRecords();
@@ -2300,14 +2424,14 @@ var AgentManager = class {
2300
2424
  if (managed.settled || this.#closing || managed.abortSignal?.aborted) return false;
2301
2425
  managed.startupAttempts++;
2302
2426
  try {
2303
- fs6.rmSync(managed.statusFile, { force: true });
2427
+ fs9.rmSync(managed.statusFile, { force: true });
2304
2428
  managed.transport = await managed.adapter.launch(managed.launch);
2305
2429
  delete managed.latestRecord;
2306
2430
  delete managed.latestUiRecord;
2307
2431
  managed.lastLivenessCheckAt = 0;
2308
2432
  managed.lifecycleOffset = 0;
2309
2433
  managed.lifecycleRemainder = Buffer.alloc(0);
2310
- fs6.rmSync(managed.lifecycleFile, { force: true });
2434
+ fs9.rmSync(managed.lifecycleFile, { force: true });
2311
2435
  this.#invalidateUiList();
2312
2436
  return true;
2313
2437
  } catch (error) {
@@ -2407,7 +2531,7 @@ var AgentManager = class {
2407
2531
  if (managed.settled) return;
2408
2532
  this.#drainLifecycle(managed);
2409
2533
  managed.settled = true;
2410
- fs6.rmSync(path7.join(managed.runDirectory, "images.json"), { force: true });
2534
+ fs9.rmSync(path10.join(managed.runDirectory, "images.json"), { force: true });
2411
2535
  this.#emitLifecycle(managed, `run.${result.status}`, result.finishedAt ?? Date.now(), {
2412
2536
  status: result.status
2413
2537
  });
@@ -2448,7 +2572,7 @@ var AgentManager = class {
2448
2572
  #drainLifecycle(managed) {
2449
2573
  let content;
2450
2574
  try {
2451
- content = fs6.readFileSync(managed.lifecycleFile);
2575
+ content = fs9.readFileSync(managed.lifecycleFile);
2452
2576
  } catch {
2453
2577
  return;
2454
2578
  }
@@ -2639,7 +2763,7 @@ var AgentManager = class {
2639
2763
  // in the parent run until that parent is explicitly cleaned up.
2640
2764
  #nestedAgents(managed, force = false) {
2641
2765
  const now = Date.now();
2642
- const needsInitialDiscovery = managed.nestedSnapshot === void 0 && fs6.existsSync(path7.join(managed.runDirectory, "nested"));
2766
+ const needsInitialDiscovery = managed.nestedSnapshot === void 0 && fs9.existsSync(path10.join(managed.runDirectory, "nested"));
2643
2767
  if (!force && !needsInitialDiscovery && managed.nestedSnapshotAt !== void 0 && now - managed.nestedSnapshotAt < NESTED_SNAPSHOT_POLL_MS) {
2644
2768
  return managed.nestedSnapshot ? structuredClone(managed.nestedSnapshot) : [];
2645
2769
  }
@@ -2663,7 +2787,7 @@ var AgentManager = class {
2663
2787
  cwd: managed.cwd,
2664
2788
  runner: managed.runner,
2665
2789
  ...managed.residency === "durable" ? { residency: "durable" } : {},
2666
- logFile: path7.join(managed.runDirectory, "events.jsonl"),
2790
+ logFile: path10.join(managed.runDirectory, "events.jsonl"),
2667
2791
  ...nestedAgents.length > 0 ? { nestedAgents } : {},
2668
2792
  ...budget ? { budget } : {},
2669
2793
  ...managed.model ? { model: managed.model } : {},
@@ -2717,9 +2841,9 @@ var actorDeliveryNotice = (delivery, triggerTurn) => {
2717
2841
 
2718
2842
  // src/actors/manager.ts
2719
2843
  import { randomUUID as randomUUID6 } from "node:crypto";
2720
- import fs8 from "node:fs";
2721
- import os5 from "node:os";
2722
- import path9 from "node:path";
2844
+ import fs11 from "node:fs";
2845
+ import os4 from "node:os";
2846
+ import path12 from "node:path";
2723
2847
 
2724
2848
  // src/actors/predicate.ts
2725
2849
  var PREDICATE_VERSION = 1;
@@ -2790,8 +2914,8 @@ var evaluateActorValidWhile = async (source, facts) => {
2790
2914
 
2791
2915
  // src/actors/binding-store.ts
2792
2916
  import { createHash, randomUUID as randomUUID5 } from "node:crypto";
2793
- import fs7 from "node:fs";
2794
- import path8 from "node:path";
2917
+ import fs10 from "node:fs";
2918
+ import path11 from "node:path";
2795
2919
  var BINDING_LOCK_TIMEOUT_MS = 5e3;
2796
2920
  var BINDING_STALE_LOCK_MS = 3e4;
2797
2921
  var bindingFileName = (sessionId) => `${createHash("sha256").update(sessionId).digest("hex")}.json`;
@@ -2801,7 +2925,7 @@ var delay3 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2801
2925
  var ActorBindingStore = class {
2802
2926
  constructor(sessionId, root) {
2803
2927
  this.sessionId = sessionId;
2804
- this.filePath = root ? path8.join(root, "bindings", bindingFileName(sessionId)) : void 0;
2928
+ this.filePath = root ? path11.join(root, "bindings", bindingFileName(sessionId)) : void 0;
2805
2929
  this.#sync(true);
2806
2930
  }
2807
2931
  #bindings = /* @__PURE__ */ new Map();
@@ -2867,7 +2991,7 @@ var ActorBindingStore = class {
2867
2991
  if (!this.filePath) return bindings;
2868
2992
  let parsed;
2869
2993
  try {
2870
- parsed = JSON.parse(fs7.readFileSync(this.filePath, "utf8"));
2994
+ parsed = JSON.parse(fs10.readFileSync(this.filePath, "utf8"));
2871
2995
  } catch {
2872
2996
  return bindings;
2873
2997
  }
@@ -2908,7 +3032,7 @@ var ActorBindingStore = class {
2908
3032
  #currentFingerprint() {
2909
3033
  if (!this.filePath) return void 0;
2910
3034
  try {
2911
- const stat = fs7.statSync(this.filePath);
3035
+ const stat = fs10.statSync(this.filePath);
2912
3036
  return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`;
2913
3037
  } catch {
2914
3038
  return void 0;
@@ -2917,7 +3041,7 @@ var ActorBindingStore = class {
2917
3041
  async #withLock(operation) {
2918
3042
  if (!this.filePath) return operation();
2919
3043
  const lockPath = `${this.filePath}.lock`;
2920
- const ownerPath2 = path8.join(lockPath, "owner");
3044
+ const ownerPath2 = path11.join(lockPath, "owner");
2921
3045
  const deadline = Date.now() + BINDING_LOCK_TIMEOUT_MS;
2922
3046
  const token = randomUUID5();
2923
3047
  const processAlive3 = (pid) => {
@@ -2929,11 +3053,11 @@ var ActorBindingStore = class {
2929
3053
  return false;
2930
3054
  }
2931
3055
  };
2932
- fs7.mkdirSync(path8.dirname(this.filePath), { recursive: true, mode: 448 });
3056
+ fs10.mkdirSync(path11.dirname(this.filePath), { recursive: true, mode: 448 });
2933
3057
  while (true) {
2934
3058
  try {
2935
- fs7.mkdirSync(lockPath, { mode: 448 });
2936
- fs7.writeFileSync(ownerPath2, `${token}
3059
+ fs10.mkdirSync(lockPath, { mode: 448 });
3060
+ fs10.writeFileSync(ownerPath2, `${token}
2937
3061
  ${process.pid}
2938
3062
  ${Date.now()}
2939
3063
  `, {
@@ -2944,13 +3068,13 @@ ${Date.now()}
2944
3068
  } catch (error) {
2945
3069
  if (errorCode2(error) !== "EEXIST") throw error;
2946
3070
  try {
2947
- const firstOwner = fs7.readFileSync(ownerPath2, "utf8");
3071
+ const firstOwner = fs10.readFileSync(ownerPath2, "utf8");
2948
3072
  const [, pidText, createdText] = firstOwner.trim().split("\n");
2949
3073
  const stale = Date.now() - Number(createdText) > BINDING_STALE_LOCK_MS;
2950
3074
  if (stale && !processAlive3(Number(pidText))) {
2951
- const secondOwner = fs7.readFileSync(ownerPath2, "utf8");
3075
+ const secondOwner = fs10.readFileSync(ownerPath2, "utf8");
2952
3076
  if (secondOwner === firstOwner) {
2953
- fs7.rmSync(lockPath, { recursive: true, force: true });
3077
+ fs10.rmSync(lockPath, { recursive: true, force: true });
2954
3078
  continue;
2955
3079
  }
2956
3080
  }
@@ -2966,10 +3090,10 @@ ${Date.now()}
2966
3090
  return operation();
2967
3091
  } finally {
2968
3092
  try {
2969
- const owner = fs7.readFileSync(ownerPath2, "utf8");
3093
+ const owner = fs10.readFileSync(ownerPath2, "utf8");
2970
3094
  if (owner.startsWith(`${token}
2971
3095
  `)) {
2972
- fs7.rmSync(lockPath, { recursive: true, force: true });
3096
+ fs10.rmSync(lockPath, { recursive: true, force: true });
2973
3097
  }
2974
3098
  } catch {
2975
3099
  }
@@ -3065,7 +3189,7 @@ var atomicWrite2 = (filePath, value) => {
3065
3189
  };
3066
3190
  var readRunRecord = (filePath) => {
3067
3191
  try {
3068
- const parsed = JSON.parse(fs8.readFileSync(filePath, "utf8"));
3192
+ const parsed = JSON.parse(fs11.readFileSync(filePath, "utf8"));
3069
3193
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
3070
3194
  return parsed;
3071
3195
  } catch {
@@ -3109,7 +3233,7 @@ var ActorManager = class {
3109
3233
  this.meshConfig = meshConfig;
3110
3234
  this.agents = agents;
3111
3235
  this.onDeliver = onDeliver;
3112
- this.#actorRoot = options.actorRoot ?? fs8.mkdtempSync(path9.join(os5.tmpdir(), "pi-fabric-actors-"));
3236
+ this.#actorRoot = options.actorRoot ?? fs11.mkdtempSync(path12.join(os4.tmpdir(), "pi-fabric-actors-"));
3113
3237
  this.#persistent = options.persistent ?? false;
3114
3238
  this.#mainAgent = options.mainAgent;
3115
3239
  this.#canManageActor = options.canManageActor;
@@ -3118,7 +3242,7 @@ var ActorManager = class {
3118
3242
  this.#claimResidency = options.claimResidency;
3119
3243
  this.#rootId = options.rootId ?? identity.id;
3120
3244
  this.#meshCursorPath = options.meshCursorPath;
3121
- this.#registryPath = path9.join(this.#actorRoot, "actors.json");
3245
+ this.#registryPath = path12.join(this.#actorRoot, "actors.json");
3122
3246
  this.#bindings = new ActorBindingStore(
3123
3247
  sessionId,
3124
3248
  this.#persistent && meshConfig.enabled ? this.#actorRoot : void 0
@@ -3230,8 +3354,8 @@ var ActorManager = class {
3230
3354
  throw new Error("This Fabric host cannot commit actor capability requirements");
3231
3355
  }
3232
3356
  const id = randomUUID6().replaceAll("-", "");
3233
- const actorDirectory = path9.join(this.#actorRoot, id);
3234
- fs8.mkdirSync(actorDirectory, { recursive: true, mode: 448 });
3357
+ const actorDirectory = path12.join(this.#actorRoot, id);
3358
+ fs11.mkdirSync(actorDirectory, { recursive: true, mode: 448 });
3235
3359
  const actor = {
3236
3360
  id,
3237
3361
  name,
@@ -3255,7 +3379,7 @@ var ActorManager = class {
3255
3379
  requirements,
3256
3380
  ...request.validWhile ? { validWhile: structuredClone(request.validWhile) } : {},
3257
3381
  latestActivationSequence: 0,
3258
- sessionFile: path9.join(actorDirectory, "session.jsonl"),
3382
+ sessionFile: path12.join(actorDirectory, "session.jsonl"),
3259
3383
  queue: [],
3260
3384
  draining: false,
3261
3385
  messages: [],
@@ -3588,17 +3712,17 @@ var ActorManager = class {
3588
3712
  const type = opts.type ?? "session";
3589
3713
  const lines = Math.max(1, Math.min(opts.lines ?? 200, 5e3));
3590
3714
  const sessionFile = actor.sessionFile;
3591
- const logDir = path9.join(path9.dirname(sessionFile), "runs");
3715
+ const logDir = path12.join(path12.dirname(sessionFile), "runs");
3592
3716
  const sessionPage = type === "run" ? { lines: [], hasMore: false } : readJsonlPage(sessionFile, lines, opts.before);
3593
3717
  const session = sessionPage.lines;
3594
3718
  let run;
3595
3719
  if (type !== "session") {
3596
3720
  const targetRunId = opts.runId ?? actor.lastRunId;
3597
3721
  if (targetRunId) {
3598
- const runPath = path9.join(logDir, targetRunId);
3599
- if (fs8.existsSync(runPath)) {
3600
- const statusRecord = readRunRecord(path9.join(runPath, "status.json"));
3601
- const eventsFile = path9.join(runPath, "events.jsonl");
3722
+ const runPath = path12.join(logDir, targetRunId);
3723
+ if (fs11.existsSync(runPath)) {
3724
+ const statusRecord = readRunRecord(path12.join(runPath, "status.json"));
3725
+ const eventsFile = path12.join(runPath, "events.jsonl");
3602
3726
  const page = readJsonlPage(eventsFile, lines, opts.before);
3603
3727
  run = {
3604
3728
  runId: targetRunId,
@@ -3714,7 +3838,7 @@ var ActorManager = class {
3714
3838
  #readMeshCursor() {
3715
3839
  if (!this.#meshCursorPath) return void 0;
3716
3840
  try {
3717
- const value = JSON.parse(fs8.readFileSync(this.#meshCursorPath, "utf8"));
3841
+ const value = JSON.parse(fs11.readFileSync(this.#meshCursorPath, "utf8"));
3718
3842
  return value.format === 1 && typeof value.cursor === "number" && value.cursor >= 0 ? value.cursor : void 0;
3719
3843
  } catch {
3720
3844
  return void 0;
@@ -3815,7 +3939,7 @@ var ActorManager = class {
3815
3939
  await this.#bindings.delete(actor.id);
3816
3940
  this.#actors.delete(actor.id);
3817
3941
  this.#emitChange();
3818
- fs8.rmSync(path9.dirname(actor.sessionFile), { recursive: true, force: true });
3942
+ fs11.rmSync(path12.dirname(actor.sessionFile), { recursive: true, force: true });
3819
3943
  await this.#saveActors(/* @__PURE__ */ new Set([actor.id]));
3820
3944
  await this.mesh.delete({ key: this.#presenceKey(actor.id) }).catch(() => ({ deleted: false }));
3821
3945
  if (retainedRunId) await this.agents.cleanup(retainedRunId).catch(() => ({ cleaned: false }));
@@ -3858,7 +3982,7 @@ var ActorManager = class {
3858
3982
  await Promise.allSettled(
3859
3983
  [...this.#actors.values()].map((actor) => actor.drain ?? Promise.resolve())
3860
3984
  );
3861
- fs8.rmSync(this.#actorRoot, { recursive: true, force: true });
3985
+ fs11.rmSync(this.#actorRoot, { recursive: true, force: true });
3862
3986
  }
3863
3987
  #enqueue(actor, source, payload, options = {}) {
3864
3988
  const canManage = options.ownershipChecked ? this.#canManageCached(actor.id) : this.#canManage(actor.id);
@@ -4247,8 +4371,8 @@ var ActorManager = class {
4247
4371
  return;
4248
4372
  }
4249
4373
  try {
4250
- const watcher = fs8.watch(this.mesh.root, { persistent: false }, (_event, filename) => {
4251
- if (filename !== null && path9.basename(filename.toString()) !== "events.jsonl") return;
4374
+ const watcher = fs11.watch(this.mesh.root, { persistent: false }, (_event, filename) => {
4375
+ if (filename !== null && path12.basename(filename.toString()) !== "events.jsonl") return;
4252
4376
  this.#scheduleMeshPoll();
4253
4377
  });
4254
4378
  this.#meshWatcher = watcher;
@@ -4357,17 +4481,17 @@ var ActorManager = class {
4357
4481
  }
4358
4482
  async #retainRunLog(actor, runId) {
4359
4483
  const runDirectory = this.agents.runDirectory(runId);
4360
- if (!runDirectory || !fs8.existsSync(runDirectory)) return;
4361
- const dest = path9.join(path9.dirname(actor.sessionFile), "runs", runId);
4362
- fs8.mkdirSync(dest, { recursive: true, mode: 448 });
4484
+ if (!runDirectory || !fs11.existsSync(runDirectory)) return;
4485
+ const dest = path12.join(path12.dirname(actor.sessionFile), "runs", runId);
4486
+ fs11.mkdirSync(dest, { recursive: true, mode: 448 });
4363
4487
  for (const file of ["events.jsonl", "status.json", "task.txt"]) {
4364
- const src = path9.join(runDirectory, file);
4365
- if (fs8.existsSync(src)) fs8.copyFileSync(src, path9.join(dest, file));
4488
+ const src = path12.join(runDirectory, file);
4489
+ if (fs11.existsSync(src)) fs11.copyFileSync(src, path12.join(dest, file));
4366
4490
  }
4367
- const nested = path9.join(runDirectory, "nested");
4368
- if (fs8.existsSync(nested)) {
4491
+ const nested = path12.join(runDirectory, "nested");
4492
+ if (fs11.existsSync(nested)) {
4369
4493
  try {
4370
- fs8.cpSync(nested, path9.join(dest, "nested"), { recursive: true });
4494
+ fs11.cpSync(nested, path12.join(dest, "nested"), { recursive: true });
4371
4495
  } catch {
4372
4496
  }
4373
4497
  }
@@ -4375,7 +4499,7 @@ var ActorManager = class {
4375
4499
  }
4376
4500
  #pruneRetainedRuns(actor, now = Date.now()) {
4377
4501
  pruneActorRunArchives({
4378
- runsDirectory: path9.join(path9.dirname(actor.sessionFile), "runs"),
4502
+ runsDirectory: path12.join(path12.dirname(actor.sessionFile), "runs"),
4379
4503
  ...actor.lastRunId ? { latestRunId: actor.lastRunId } : {},
4380
4504
  retentionMs: this.#retention.actorRunArchiveMs,
4381
4505
  now
@@ -4389,9 +4513,9 @@ var ActorManager = class {
4389
4513
  }
4390
4514
  }
4391
4515
  #retainedRunIds(actor) {
4392
- const runsDir = path9.join(path9.dirname(actor.sessionFile), "runs");
4516
+ const runsDir = path12.join(path12.dirname(actor.sessionFile), "runs");
4393
4517
  try {
4394
- return fs8.readdirSync(runsDir).sort();
4518
+ return fs11.readdirSync(runsDir).sort();
4395
4519
  } catch {
4396
4520
  return [];
4397
4521
  }
@@ -4507,7 +4631,7 @@ var ActorManager = class {
4507
4631
  }
4508
4632
  #registryRecords() {
4509
4633
  try {
4510
- const parsed = JSON.parse(fs8.readFileSync(this.#registryPath, "utf8"));
4634
+ const parsed = JSON.parse(fs11.readFileSync(this.#registryPath, "utf8"));
4511
4635
  if (!Array.isArray(parsed.actors)) return [];
4512
4636
  return parsed.actors.flatMap(
4513
4637
  (record) => typeof record === "object" && record !== null && !Array.isArray(record) && typeof record.id === "string" ? [record] : []
@@ -4518,7 +4642,7 @@ var ActorManager = class {
4518
4642
  }
4519
4643
  async #withRegistryLock(operation) {
4520
4644
  const lockPath = `${this.#registryPath}.lock`;
4521
- const ownerPath2 = path9.join(lockPath, "owner");
4645
+ const ownerPath2 = path12.join(lockPath, "owner");
4522
4646
  const deadline = Date.now() + ACTOR_REGISTRY_LOCK_TIMEOUT_MS;
4523
4647
  const token = randomUUID6();
4524
4648
  const processAlive3 = (pid) => {
@@ -4530,11 +4654,11 @@ var ActorManager = class {
4530
4654
  return false;
4531
4655
  }
4532
4656
  };
4533
- fs8.mkdirSync(this.#actorRoot, { recursive: true, mode: 448 });
4657
+ fs11.mkdirSync(this.#actorRoot, { recursive: true, mode: 448 });
4534
4658
  while (true) {
4535
4659
  try {
4536
- fs8.mkdirSync(lockPath, { mode: 448 });
4537
- fs8.writeFileSync(ownerPath2, `${token}
4660
+ fs11.mkdirSync(lockPath, { mode: 448 });
4661
+ fs11.writeFileSync(ownerPath2, `${token}
4538
4662
  ${process.pid}
4539
4663
  ${Date.now()}
4540
4664
  `, {
@@ -4545,13 +4669,13 @@ ${Date.now()}
4545
4669
  } catch (error) {
4546
4670
  if (errorCode3(error) !== "EEXIST") throw error;
4547
4671
  try {
4548
- const firstOwner = fs8.readFileSync(ownerPath2, "utf8");
4672
+ const firstOwner = fs11.readFileSync(ownerPath2, "utf8");
4549
4673
  const [, pidText, createdText] = firstOwner.trim().split("\n");
4550
4674
  const stale = Date.now() - Number(createdText) > ACTOR_REGISTRY_STALE_LOCK_MS;
4551
4675
  if (stale && !processAlive3(Number(pidText))) {
4552
- const secondOwner = fs8.readFileSync(ownerPath2, "utf8");
4676
+ const secondOwner = fs11.readFileSync(ownerPath2, "utf8");
4553
4677
  if (secondOwner === firstOwner) {
4554
- fs8.rmSync(lockPath, { recursive: true, force: true });
4678
+ fs11.rmSync(lockPath, { recursive: true, force: true });
4555
4679
  continue;
4556
4680
  }
4557
4681
  }
@@ -4567,10 +4691,10 @@ ${Date.now()}
4567
4691
  return operation();
4568
4692
  } finally {
4569
4693
  try {
4570
- const owner = fs8.readFileSync(ownerPath2, "utf8");
4694
+ const owner = fs11.readFileSync(ownerPath2, "utf8");
4571
4695
  if (owner.startsWith(`${token}
4572
4696
  `)) {
4573
- fs8.rmSync(lockPath, { recursive: true, force: true });
4697
+ fs11.rmSync(lockPath, { recursive: true, force: true });
4574
4698
  }
4575
4699
  } catch {
4576
4700
  }
@@ -4598,7 +4722,7 @@ ${Date.now()}
4598
4722
  }
4599
4723
  #currentRegistryFingerprint() {
4600
4724
  try {
4601
- const stat = fs8.statSync(this.#registryPath);
4725
+ const stat = fs11.statSync(this.#registryPath);
4602
4726
  return `${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`;
4603
4727
  } catch {
4604
4728
  return void 0;
@@ -4643,7 +4767,7 @@ ${Date.now()}
4643
4767
  let added = 0;
4644
4768
  let parsed;
4645
4769
  try {
4646
- parsed = JSON.parse(fs8.readFileSync(this.#registryPath, "utf8"));
4770
+ parsed = JSON.parse(fs11.readFileSync(this.#registryPath, "utf8"));
4647
4771
  } catch (error) {
4648
4772
  if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
4649
4773
  return;
@@ -4704,7 +4828,7 @@ ${Date.now()}
4704
4828
  ...typeof record.capabilityDigest === "string" ? { capabilityDigest: record.capabilityDigest } : {},
4705
4829
  ...record.validWhile?.version === 1 && typeof record.validWhile.source === "string" ? { validWhile: record.validWhile } : {},
4706
4830
  latestActivationSequence: 0,
4707
- sessionFile: path9.join(this.#actorRoot, record.id, "session.jsonl"),
4831
+ sessionFile: path12.join(this.#actorRoot, record.id, "session.jsonl"),
4708
4832
  queue: [],
4709
4833
  draining: false,
4710
4834
  messages: [],
@@ -4789,7 +4913,7 @@ ${Date.now()}
4789
4913
  ...actor.lastRunId ? { lastRunId: actor.lastRunId } : {},
4790
4914
  ...actor.lastError ? { lastError: actor.lastError } : {},
4791
4915
  sessionFile: actor.sessionFile,
4792
- logDir: path9.join(path9.dirname(actor.sessionFile), "runs")
4916
+ logDir: path12.join(path12.dirname(actor.sessionFile), "runs")
4793
4917
  };
4794
4918
  }
4795
4919
  validateDirectMessage(message, data) {
@@ -6231,6 +6355,8 @@ export {
6231
6355
  FABRIC_LIFECYCLE_EVENTS,
6232
6356
  isFabricLifecycleEventType,
6233
6357
  lifecycleSourceIdentity,
6358
+ isFabricWorktreePath,
6359
+ addCloneFirstWorktree,
6234
6360
  useBudgetLedger,
6235
6361
  effectiveAgentTimeoutMs,
6236
6362
  validateAgentCwdRequest,
@@ -6245,4 +6371,4 @@ export {
6245
6371
  agentParticipantRecords,
6246
6372
  actorParticipantRecord
6247
6373
  };
6248
- //# sourceMappingURL=chunk-F2GKEXGI.js.map
6374
+ //# sourceMappingURL=chunk-PFF3X7OO.js.map