omp-fabric 1.25.9 → 1.25.11
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/CHANGELOG.md +14 -0
- package/dist/agents/worktree-paths.d.ts +2 -2
- package/dist/agents/worktree-paths.d.ts.map +1 -1
- package/dist/chunks/{chunk-YAI5SCIE.js → chunk-7A7AWSK2.js} +62 -50
- package/dist/chunks/chunk-7A7AWSK2.js.map +7 -0
- package/dist/chunks/{chunk-BMSAIMFB.js → chunk-YRX5MA7T.js} +2 -2
- package/dist/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-runtime-state.js +4 -2
- package/dist/fabric-runtime-state.js.map +2 -2
- package/dist/residency/host.js +2 -2
- package/dist/residency/omp-entry.js +2 -2
- package/dist/topology/participant-directory.d.ts.map +1 -1
- package/docs/agents.md +1 -1
- package/docs/configuration.md +1 -1
- package/package.json +1 -1
- package/dist/chunks/chunk-YAI5SCIE.js.map +0 -7
- /package/dist/chunks/{chunk-BMSAIMFB.js.map → chunk-YRX5MA7T.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.25.11
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Outside a Git repository the `.git/info/exclude` step from 1.25.10 still ran `git rev-parse` on every session start and discarded the failure, and it ran unawaited, so a session or test could tear down its directory while that `git` child still held it (`EBUSY` on Windows CI). Fabric now looks for a `.git` entry first and skips plain directories without spawning `git` (0.02 ms against about 2 ms), and the step is awaited. 1.25.10 was tagged but never published, because that race failed its release gate.
|
|
8
|
+
|
|
9
|
+
## 1.25.10
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fabric's per-project state under `.omp/fabric/` (the mesh and the MCP descriptor cache) made repositories without an `.omp/` ignore rule show `?? .omp/`. Only managed worktrees were excluded, and only once an agent created one. Every session now adds `**/.omp/fabric/` to the repository's local `.git/info/exclude`, once, from whatever subdirectory it starts in; the old `.omp/fabric/worktrees/` rule was anchored to the repository root and missed a session started below it. Tracked ignore files are never edited, and OMP's own `.omp/` files (plans, `lsp.json`) are left alone.
|
|
14
|
+
- A peer whose host lease lapsed showed up to other sessions as `Peer <session>` without its label. The listing falls back to the legacy session record when a host lease expires, and that record's reader dropped the label its writer stores. On Windows CI a slow refresh published an already-expired lease, which is why `peer-labels` failed intermittently there.
|
|
15
|
+
- The `matchLimit` note on a grep cut short by `limit` now says the host takes matches from each file in turn, so `skip` cannot reach the rest of a file the limit cut, and suggests pointing `path` at one file.
|
|
16
|
+
|
|
3
17
|
## 1.25.9
|
|
4
18
|
|
|
5
19
|
### Changed
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const
|
|
1
|
+
export declare const FABRIC_STATE_EXCLUDE = "**/.omp/fabric/";
|
|
2
2
|
export declare const fabricWorktreePath: (gitRoot: string, id: string) => string;
|
|
3
3
|
export declare const isFabricWorktreePath: (worktree: string, id: string) => boolean;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const ensureFabricStateExclude: (directory: string) => Promise<void>;
|
|
5
5
|
//# sourceMappingURL=worktree-paths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worktree-paths.d.ts","sourceRoot":"","sources":["../../src/agents/worktree-paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"worktree-paths.d.ts","sourceRoot":"","sources":["../../src/agents/worktree-paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,IAAI,MAAM,KAAG,MACZ,CAAC;AAEtD,eAAO,MAAM,oBAAoB,GAAI,UAAU,MAAM,EAAE,IAAI,MAAM,KAAG,OASnE,CAAC;AAYF,eAAO,MAAM,wBAAwB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,IAAI,CAmB9E,CAAC"}
|
|
@@ -861,11 +861,52 @@ var lifecycleSubscriptionFromValue = (value) => {
|
|
|
861
861
|
return value;
|
|
862
862
|
};
|
|
863
863
|
|
|
864
|
+
// src/agents/worktree-paths.ts
|
|
865
|
+
import fs2 from "node:fs";
|
|
866
|
+
import path4 from "node:path";
|
|
867
|
+
var FABRIC_WORKTREE_SEGMENTS = [".omp", "fabric", "worktrees"];
|
|
868
|
+
var FABRIC_STATE_EXCLUDE = "**/.omp/fabric/";
|
|
869
|
+
var fabricWorktreePath = (gitRoot, id) => path4.join(gitRoot, ...FABRIC_WORKTREE_SEGMENTS, id);
|
|
870
|
+
var isFabricWorktreePath = (worktree, id) => {
|
|
871
|
+
const parts = worktree.split(/[\\/]/).filter(Boolean);
|
|
872
|
+
return parts.length >= 4 && parts.at(-1) === id && parts.at(-2) === "worktrees" && parts.at(-3) === "fabric" && parts.at(-4) === ".omp";
|
|
873
|
+
};
|
|
874
|
+
var insideGitRepository = (directory) => {
|
|
875
|
+
let current = path4.resolve(directory);
|
|
876
|
+
while (true) {
|
|
877
|
+
if (fs2.existsSync(path4.join(current, ".git"))) return true;
|
|
878
|
+
const parent = path4.dirname(current);
|
|
879
|
+
if (parent === current) return false;
|
|
880
|
+
current = parent;
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
var ensureFabricStateExclude = async (directory) => {
|
|
884
|
+
if (!insideGitRepository(directory)) return;
|
|
885
|
+
const located = await executeFile("git", ["rev-parse", "--git-path", "info/exclude"], {
|
|
886
|
+
cwd: directory,
|
|
887
|
+
timeoutMs: 1e4
|
|
888
|
+
});
|
|
889
|
+
const excludePath = path4.resolve(directory, located.stdout.trim());
|
|
890
|
+
fs2.mkdirSync(path4.dirname(excludePath), { recursive: true });
|
|
891
|
+
let current = "";
|
|
892
|
+
try {
|
|
893
|
+
current = fs2.readFileSync(excludePath, "utf8");
|
|
894
|
+
} catch (error) {
|
|
895
|
+
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
896
|
+
if (code !== "ENOENT") throw error;
|
|
897
|
+
}
|
|
898
|
+
const lines = current.split(/\r?\n/);
|
|
899
|
+
if (lines.some((line) => line.trim() === FABRIC_STATE_EXCLUDE)) return;
|
|
900
|
+
const prefix = current.length === 0 || current.endsWith("\n") ? "" : "\n";
|
|
901
|
+
fs2.appendFileSync(excludePath, `${prefix}${FABRIC_STATE_EXCLUDE}
|
|
902
|
+
`);
|
|
903
|
+
};
|
|
904
|
+
|
|
864
905
|
// src/agents/budget-ledger.ts
|
|
865
906
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
866
|
-
import
|
|
907
|
+
import fs3 from "node:fs";
|
|
867
908
|
import os from "node:os";
|
|
868
|
-
import
|
|
909
|
+
import path5 from "node:path";
|
|
869
910
|
var ENV_BUDGET = "OMP_FABRIC_BUDGET";
|
|
870
911
|
var ENV_BUDGET_FILE = "OMP_FABRIC_BUDGET_FILE";
|
|
871
912
|
var ENV_BUDGET_ID = "OMP_FABRIC_BUDGET_ID";
|
|
@@ -881,9 +922,9 @@ function activeBudgetState() {
|
|
|
881
922
|
return { budget, file, id: process.env[ENV_BUDGET_ID] ?? "" };
|
|
882
923
|
}
|
|
883
924
|
function initBudgetLedger(budget) {
|
|
884
|
-
const directory =
|
|
885
|
-
const file =
|
|
886
|
-
|
|
925
|
+
const directory = fs3.mkdtempSync(path5.join(os.tmpdir(), "omp-fabric-budget-"));
|
|
926
|
+
const file = path5.join(directory, "cost.jsonl");
|
|
927
|
+
fs3.writeFileSync(file, "", { mode: 384 });
|
|
887
928
|
const id = randomUUID2().replaceAll("-", "").slice(0, 16);
|
|
888
929
|
process.env[ENV_BUDGET] = String(budget);
|
|
889
930
|
process.env[ENV_BUDGET_FILE] = file;
|
|
@@ -905,7 +946,7 @@ function readBudgetLedger(file) {
|
|
|
905
946
|
let tokens = 0;
|
|
906
947
|
let raw;
|
|
907
948
|
try {
|
|
908
|
-
raw =
|
|
949
|
+
raw = fs3.readFileSync(file, "utf8");
|
|
909
950
|
} catch {
|
|
910
951
|
return { cost, tokens };
|
|
911
952
|
}
|
|
@@ -922,7 +963,7 @@ function readBudgetLedger(file) {
|
|
|
922
963
|
}
|
|
923
964
|
function appendBudgetLedger(file, entry) {
|
|
924
965
|
try {
|
|
925
|
-
|
|
966
|
+
fs3.appendFileSync(file, `${JSON.stringify(entry)}
|
|
926
967
|
`);
|
|
927
968
|
} catch {
|
|
928
969
|
}
|
|
@@ -986,11 +1027,11 @@ var Semaphore = class {
|
|
|
986
1027
|
};
|
|
987
1028
|
|
|
988
1029
|
// src/agents/rm.ts
|
|
989
|
-
import
|
|
1030
|
+
import fs4 from "node:fs";
|
|
990
1031
|
var RETRYABLE_RM_CODES = /* @__PURE__ */ new Set(["ENOTEMPTY", "EBUSY", "EPERM", "EMFILE"]);
|
|
991
1032
|
var RM_RETRY_BACKOFF_MS = 5;
|
|
992
1033
|
var RM_MAX_ATTEMPTS = 5;
|
|
993
|
-
var defaultRemove = (target, options) =>
|
|
1034
|
+
var defaultRemove = (target, options) => fs4.promises.rm(target, options);
|
|
994
1035
|
var removeTree = async (target, rm = defaultRemove) => {
|
|
995
1036
|
for (let attempt = 0; attempt < RM_MAX_ATTEMPTS; attempt++) {
|
|
996
1037
|
try {
|
|
@@ -1301,8 +1342,8 @@ import fs6 from "node:fs";
|
|
|
1301
1342
|
import path7 from "node:path";
|
|
1302
1343
|
|
|
1303
1344
|
// src/agents/cow-clone.ts
|
|
1304
|
-
import
|
|
1305
|
-
import
|
|
1345
|
+
import fs5 from "node:fs";
|
|
1346
|
+
import path6 from "node:path";
|
|
1306
1347
|
var CLONE_SKIP_PREFIXES = [".git", ".omp/fabric/worktrees"];
|
|
1307
1348
|
var CowUnavailableError = class extends Error {
|
|
1308
1349
|
constructor(message, options) {
|
|
@@ -1318,11 +1359,11 @@ var isCowUnavailable = (error) => {
|
|
|
1318
1359
|
};
|
|
1319
1360
|
var cloneEntry = async (from, to) => {
|
|
1320
1361
|
try {
|
|
1321
|
-
await
|
|
1362
|
+
await fs5.promises.cp(from, to, {
|
|
1322
1363
|
recursive: true,
|
|
1323
1364
|
verbatimSymlinks: true,
|
|
1324
1365
|
force: false,
|
|
1325
|
-
mode:
|
|
1366
|
+
mode: fs5.constants.COPYFILE_FICLONE_FORCE
|
|
1326
1367
|
});
|
|
1327
1368
|
} catch (error) {
|
|
1328
1369
|
if (isCowUnavailable(error)) {
|
|
@@ -1342,13 +1383,13 @@ var hasNestedSkip = (rel, prefixes) => {
|
|
|
1342
1383
|
return prefixes.some((prefix) => prefix.startsWith(`${value}/`));
|
|
1343
1384
|
};
|
|
1344
1385
|
var cloneLevel = async (source, dest, relBase, prefixes) => {
|
|
1345
|
-
await
|
|
1346
|
-
const entries = await
|
|
1386
|
+
await fs5.promises.mkdir(dest, { recursive: true });
|
|
1387
|
+
const entries = await fs5.promises.readdir(source, { withFileTypes: true });
|
|
1347
1388
|
for (const entry of entries) {
|
|
1348
1389
|
const rel = relBase ? `${relBase}/${entry.name}` : entry.name;
|
|
1349
1390
|
if (skipped(rel, prefixes)) continue;
|
|
1350
|
-
const from =
|
|
1351
|
-
const to =
|
|
1391
|
+
const from = path6.join(source, entry.name);
|
|
1392
|
+
const to = path6.join(dest, entry.name);
|
|
1352
1393
|
if (entry.isDirectory() && !entry.isSymbolicLink() && hasNestedSkip(rel, prefixes)) {
|
|
1353
1394
|
await cloneLevel(from, to, rel, prefixes);
|
|
1354
1395
|
continue;
|
|
@@ -1361,42 +1402,11 @@ var cloneTree = async (source, dest, prefixes = CLONE_SKIP_PREFIXES) => {
|
|
|
1361
1402
|
await cloneLevel(source, dest, "", prefixes);
|
|
1362
1403
|
};
|
|
1363
1404
|
|
|
1364
|
-
// src/agents/worktree-paths.ts
|
|
1365
|
-
import fs5 from "node:fs";
|
|
1366
|
-
import path6 from "node:path";
|
|
1367
|
-
var FABRIC_WORKTREE_SEGMENTS = [".omp", "fabric", "worktrees"];
|
|
1368
|
-
var FABRIC_WORKTREE_EXCLUDE = ".omp/fabric/worktrees/";
|
|
1369
|
-
var fabricWorktreePath = (gitRoot, id) => path6.join(gitRoot, ...FABRIC_WORKTREE_SEGMENTS, id);
|
|
1370
|
-
var isFabricWorktreePath = (worktree, id) => {
|
|
1371
|
-
const parts = worktree.split(/[\\/]/).filter(Boolean);
|
|
1372
|
-
return parts.length >= 4 && parts.at(-1) === id && parts.at(-2) === "worktrees" && parts.at(-3) === "fabric" && parts.at(-4) === ".omp";
|
|
1373
|
-
};
|
|
1374
|
-
var ensureWorktreeExclude = async (gitRoot) => {
|
|
1375
|
-
const located = await executeFile("git", ["rev-parse", "--git-path", "info/exclude"], {
|
|
1376
|
-
cwd: gitRoot,
|
|
1377
|
-
timeoutMs: 1e4
|
|
1378
|
-
});
|
|
1379
|
-
const excludePath = path6.resolve(gitRoot, located.stdout.trim());
|
|
1380
|
-
fs5.mkdirSync(path6.dirname(excludePath), { recursive: true });
|
|
1381
|
-
let current = "";
|
|
1382
|
-
try {
|
|
1383
|
-
current = fs5.readFileSync(excludePath, "utf8");
|
|
1384
|
-
} catch (error) {
|
|
1385
|
-
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
1386
|
-
if (code !== "ENOENT") throw error;
|
|
1387
|
-
}
|
|
1388
|
-
const lines = current.split(/\r?\n/);
|
|
1389
|
-
if (lines.some((line) => line.trim() === FABRIC_WORKTREE_EXCLUDE)) return;
|
|
1390
|
-
const prefix = current.length === 0 || current.endsWith("\n") ? "" : "\n";
|
|
1391
|
-
fs5.appendFileSync(excludePath, `${prefix}${FABRIC_WORKTREE_EXCLUDE}
|
|
1392
|
-
`);
|
|
1393
|
-
};
|
|
1394
|
-
|
|
1395
1405
|
// src/agents/clone-first-worktree.ts
|
|
1396
1406
|
var addCloneFirstWorktree = async (options) => {
|
|
1397
1407
|
const dest = options.dest;
|
|
1398
1408
|
if (isFabricWorktreePath(dest, path7.basename(dest))) {
|
|
1399
|
-
await
|
|
1409
|
+
await ensureFabricStateExclude(options.gitRoot);
|
|
1400
1410
|
}
|
|
1401
1411
|
fs6.mkdirSync(path7.dirname(dest), { recursive: true });
|
|
1402
1412
|
const args = ["worktree", "add", "--no-checkout"];
|
|
@@ -6254,6 +6264,7 @@ var legacyRootFromEntry = (entry, localRootId, now) => {
|
|
|
6254
6264
|
ownerHostId: value.id,
|
|
6255
6265
|
ownerIdentityId: value.id,
|
|
6256
6266
|
name: typeof value.name === "string" ? value.name : "main",
|
|
6267
|
+
...typeof value.label === "string" && value.label ? { label: value.label } : {},
|
|
6257
6268
|
status: value.status,
|
|
6258
6269
|
runner: "omp",
|
|
6259
6270
|
transport: "host",
|
|
@@ -6768,6 +6779,7 @@ export {
|
|
|
6768
6779
|
isFabricLifecycleEventType,
|
|
6769
6780
|
lifecycleSourceIdentity,
|
|
6770
6781
|
isFabricWorktreePath,
|
|
6782
|
+
ensureFabricStateExclude,
|
|
6771
6783
|
addCloneFirstWorktree,
|
|
6772
6784
|
useBudgetLedger,
|
|
6773
6785
|
effectiveAgentTimeoutMs,
|
|
@@ -6784,4 +6796,4 @@ export {
|
|
|
6784
6796
|
agentParticipantRecords,
|
|
6785
6797
|
actorParticipantRecord
|
|
6786
6798
|
};
|
|
6787
|
-
//# sourceMappingURL=chunk-
|
|
6799
|
+
//# sourceMappingURL=chunk-7A7AWSK2.js.map
|