omp-fabric 1.25.9 → 1.25.12

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 (32) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/agents/worktree-paths.d.ts +2 -2
  3. package/dist/agents/worktree-paths.d.ts.map +1 -1
  4. package/dist/chunks/{chunk-YAI5SCIE.js → chunk-7A7AWSK2.js} +62 -50
  5. package/dist/chunks/chunk-7A7AWSK2.js.map +7 -0
  6. package/dist/chunks/{chunk-PIW2DEO2.js → chunk-JJ6DFMCK.js} +2 -2
  7. package/dist/chunks/{chunk-KLWNXXEI.js → chunk-LWHQR2JY.js} +9 -4
  8. package/dist/chunks/chunk-LWHQR2JY.js.map +7 -0
  9. package/dist/chunks/{chunk-BMSAIMFB.js → chunk-YRX5MA7T.js} +2 -2
  10. package/dist/core/action-registry.d.ts +1 -0
  11. package/dist/core/action-registry.d.ts.map +1 -1
  12. package/dist/core/action-registry.js +1 -1
  13. package/dist/core/system-guidance.d.ts.map +1 -1
  14. package/dist/execution-service.d.ts.map +1 -1
  15. package/dist/fabric-runtime-state.d.ts.map +1 -1
  16. package/dist/fabric-runtime-state.js +15 -6
  17. package/dist/fabric-runtime-state.js.map +2 -2
  18. package/dist/index.js +6 -4
  19. package/dist/index.js.map +2 -2
  20. package/dist/residency/host.js +2 -2
  21. package/dist/residency/omp-entry.js +2 -2
  22. package/dist/topology/participant-directory.d.ts.map +1 -1
  23. package/docs/agents.md +1 -1
  24. package/docs/architecture.md +1 -1
  25. package/docs/configuration.md +1 -1
  26. package/package.json +1 -1
  27. package/skills/fabric-exec/SKILL.md +1 -1
  28. package/skills/fabric-exec/references/mcp.md +1 -1
  29. package/dist/chunks/chunk-KLWNXXEI.js.map +0 -7
  30. package/dist/chunks/chunk-YAI5SCIE.js.map +0 -7
  31. /package/dist/chunks/{chunk-PIW2DEO2.js.map → chunk-JJ6DFMCK.js.map} +0 -0
  32. /package/dist/chunks/{chunk-BMSAIMFB.js.map → chunk-YRX5MA7T.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.25.12
4
+
5
+ ### Fixed
6
+
7
+ - An agent told to use its Paperclip tools called `mcp.paperclip.paperclipApiRequest`, got `Unknown Fabric action`, and fell back to raw `curl`. The kernel guidance said "call known MCP tools as `mcp.<sanitized_server>.<sanitized_tool>(args)`", but that surface covers only the servers Fabric pools through mcporter (the ones `mcp.$servers()` lists). MCP servers OMP loads itself, including the per-run server an adapter such as Paperclip injects, are captured tools and run as `extensions.mcp__<server>_<tool>(args)`. The guidance now names both paths, the extension roster's header shows the `extensions.mcp__…` form whenever it lists `mcp:<server>` groups, and the `fabric-exec` skill and architecture docs say the same.
8
+ - `tools.list()` stopped at its default limit of 100 without saying so. With 300 tools registered, the 61 Paperclip tools sat past that cut, so the agent's `tools.list()` search for them came back empty. A listing cut at its limit now adds a log line naming how many it returned, the total, and the `limit` that returns the rest.
9
+
10
+ ## 1.25.11
11
+
12
+ ### Fixed
13
+
14
+ - 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.
15
+
16
+ ## 1.25.10
17
+
18
+ ### Fixed
19
+
20
+ - 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.
21
+ - 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.
22
+ - 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.
23
+
3
24
  ## 1.25.9
4
25
 
5
26
  ### Changed
@@ -1,5 +1,5 @@
1
- export declare const FABRIC_WORKTREE_EXCLUDE = ".omp/fabric/worktrees/";
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 ensureWorktreeExclude: (gitRoot: string) => Promise<void>;
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,uBAAuB,2BAA2B,CAAC;AAEhE,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;AAEF,eAAO,MAAM,qBAAqB,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,IAAI,CAkBzE,CAAC"}
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 fs2 from "node:fs";
907
+ import fs3 from "node:fs";
867
908
  import os from "node:os";
868
- import path4 from "node:path";
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 = fs2.mkdtempSync(path4.join(os.tmpdir(), "omp-fabric-budget-"));
885
- const file = path4.join(directory, "cost.jsonl");
886
- fs2.writeFileSync(file, "", { mode: 384 });
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 = fs2.readFileSync(file, "utf8");
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
- fs2.appendFileSync(file, `${JSON.stringify(entry)}
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 fs3 from "node:fs";
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) => fs3.promises.rm(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 fs4 from "node:fs";
1305
- import path5 from "node:path";
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 fs4.promises.cp(from, to, {
1362
+ await fs5.promises.cp(from, to, {
1322
1363
  recursive: true,
1323
1364
  verbatimSymlinks: true,
1324
1365
  force: false,
1325
- mode: fs4.constants.COPYFILE_FICLONE_FORCE
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 fs4.promises.mkdir(dest, { recursive: true });
1346
- const entries = await fs4.promises.readdir(source, { withFileTypes: true });
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 = path5.join(source, entry.name);
1351
- const to = path5.join(dest, entry.name);
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 ensureWorktreeExclude(options.gitRoot);
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-YAI5SCIE.js.map
6799
+ //# sourceMappingURL=chunk-7A7AWSK2.js.map