pi-fabric 0.76.2 → 0.77.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.
- package/dist/agents/bash-worktree-add.d.ts +24 -0
- package/dist/agents/bash-worktree-add.d.ts.map +1 -0
- package/dist/agents/clone-first-worktree.d.ts +17 -0
- package/dist/agents/clone-first-worktree.d.ts.map +1 -0
- package/dist/agents/cow-clone.d.ts +8 -0
- package/dist/agents/cow-clone.d.ts.map +1 -0
- package/dist/agents/worktree-manager.d.ts.map +1 -1
- package/dist/agents/worktree-paths.d.ts +5 -0
- package/dist/agents/worktree-paths.d.ts.map +1 -0
- package/dist/chunks/{chunk-F2GKEXGI.js → chunk-4DRVOAFY.js} +271 -145
- package/dist/chunks/chunk-4DRVOAFY.js.map +7 -0
- package/dist/chunks/{chunk-BT6UELLP.js → chunk-SBHF6CVR.js} +2 -2
- package/dist/chunks/{fabric-runtime-state-VCLWTB55.js → fabric-runtime-state-H7UA3DJC.js} +188 -87
- package/dist/chunks/fabric-runtime-state-H7UA3DJC.js.map +7 -0
- package/dist/index.js +1 -1
- package/dist/providers/pi-tools-provider.d.ts.map +1 -1
- package/dist/residency/client.d.ts.map +1 -1
- package/dist/residency/host.js +2 -2
- package/dist/residency/pi-entry.js +2 -2
- package/docs/agents.md +1 -1
- package/docs/architecture.md +1 -1
- package/package.json +1 -1
- package/skills/fabric-exec/references/agents.md +3 -3
- package/dist/chunks/chunk-F2GKEXGI.js.map +0 -7
- package/dist/chunks/fabric-runtime-state-VCLWTB55.js.map +0 -7
- /package/dist/chunks/{chunk-BT6UELLP.js.map → chunk-SBHF6CVR.js.map} +0 -0
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
agentParticipantRecords,
|
|
10
10
|
lifecycleSourceIdentity,
|
|
11
11
|
useBudgetLedger
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4DRVOAFY.js";
|
|
13
13
|
import {
|
|
14
14
|
parseFabricOwnedModelGuidance,
|
|
15
15
|
resolveFabricModelGuidance
|
|
@@ -662,4 +662,4 @@ if (isMain) {
|
|
|
662
662
|
export {
|
|
663
663
|
runResidentHostFromConfigPath
|
|
664
664
|
};
|
|
665
|
-
//# sourceMappingURL=chunk-
|
|
665
|
+
//# sourceMappingURL=chunk-SBHF6CVR.js.map
|
|
@@ -69,15 +69,17 @@ import {
|
|
|
69
69
|
ParticipantDirectory,
|
|
70
70
|
actorDeliveryNotice,
|
|
71
71
|
actorParticipantRecord,
|
|
72
|
+
addCloneFirstWorktree,
|
|
72
73
|
agentParticipantRecords,
|
|
73
74
|
effectiveAgentTimeoutMs,
|
|
74
75
|
isFabricLifecycleEventType,
|
|
76
|
+
isFabricWorktreePath,
|
|
75
77
|
lifecycleSourceIdentity,
|
|
76
78
|
resolveActorDeliveryPolicy,
|
|
77
79
|
resolveAgentCwd,
|
|
78
80
|
resolvePiBinary,
|
|
79
81
|
validateAgentCwdRequest
|
|
80
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-4DRVOAFY.js";
|
|
81
83
|
import "./chunk-PM5I335G.js";
|
|
82
84
|
import "./chunk-VPPIJRNZ.js";
|
|
83
85
|
import {
|
|
@@ -149,7 +151,7 @@ import {
|
|
|
149
151
|
} from "./chunk-IDTQ2B5W.js";
|
|
150
152
|
|
|
151
153
|
// src/fabric-runtime-state.ts
|
|
152
|
-
import
|
|
154
|
+
import path15 from "node:path";
|
|
153
155
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
154
156
|
|
|
155
157
|
// src/actors/global-registry.ts
|
|
@@ -2196,10 +2198,10 @@ var FabricComponentSupervisor = class {
|
|
|
2196
2198
|
adjacent.set(edge.from, targets);
|
|
2197
2199
|
}
|
|
2198
2200
|
const cycles = /* @__PURE__ */ new Map();
|
|
2199
|
-
const visit = (node,
|
|
2201
|
+
const visit = (node, path16, positions) => {
|
|
2200
2202
|
const position = positions.get(node);
|
|
2201
2203
|
if (position !== void 0) {
|
|
2202
|
-
const cycle =
|
|
2204
|
+
const cycle = path16.slice(position);
|
|
2203
2205
|
const rotations = cycle.map((_, index) => [
|
|
2204
2206
|
...cycle.slice(index),
|
|
2205
2207
|
...cycle.slice(0, index)
|
|
@@ -2209,10 +2211,10 @@ var FabricComponentSupervisor = class {
|
|
|
2209
2211
|
cycles.set(canonical.join("\0"), canonical);
|
|
2210
2212
|
return;
|
|
2211
2213
|
}
|
|
2212
|
-
if (
|
|
2213
|
-
const nextPositions = new Map(positions).set(node,
|
|
2214
|
+
if (path16.length > this.#components.size) return;
|
|
2215
|
+
const nextPositions = new Map(positions).set(node, path16.length);
|
|
2214
2216
|
for (const target of adjacent.get(node) ?? []) {
|
|
2215
|
-
visit(target, [...
|
|
2217
|
+
visit(target, [...path16, node], nextPositions);
|
|
2216
2218
|
}
|
|
2217
2219
|
};
|
|
2218
2220
|
for (const id of this.#components.keys()) visit(id, [], /* @__PURE__ */ new Map());
|
|
@@ -4469,7 +4471,6 @@ var AGENTS_ACTION_DESCRIPTORS = [
|
|
|
4469
4471
|
// src/residency/client.ts
|
|
4470
4472
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
4471
4473
|
import fs3 from "node:fs";
|
|
4472
|
-
import os from "node:os";
|
|
4473
4474
|
import path4 from "node:path";
|
|
4474
4475
|
import { fileURLToPath } from "node:url";
|
|
4475
4476
|
var STARTUP_TIMEOUT_MS = 3e4;
|
|
@@ -4794,7 +4795,7 @@ var ResidencyClient = class {
|
|
|
4794
4795
|
if (metadata?.format !== RESIDENT_HOST_FORMAT || metadata.rootId !== this.options.config.rootId || metadata.id !== id || metadata.handle.id !== id || metadata.worktreeGitRoot !== void 0 && typeof metadata.worktreeGitRoot !== "string" || path4.resolve(metadata.runDirectory) !== path4.resolve(this.options.config.residencyRoot, "runs", id)) {
|
|
4795
4796
|
return void 0;
|
|
4796
4797
|
}
|
|
4797
|
-
if (metadata.handle.worktree &&
|
|
4798
|
+
if (metadata.handle.worktree && !isFabricWorktreePath(metadata.handle.worktree, id)) {
|
|
4798
4799
|
return void 0;
|
|
4799
4800
|
}
|
|
4800
4801
|
if (metadata.handle.branch && (!metadata.handle.branch.startsWith("pi-fabric/") || !metadata.handle.branch.endsWith(`-${id.slice(0, 8)}`))) {
|
|
@@ -6486,19 +6487,19 @@ var ComponentsProvider = class {
|
|
|
6486
6487
|
// src/providers/mcp-descriptor-cache.ts
|
|
6487
6488
|
import fs4 from "node:fs/promises";
|
|
6488
6489
|
import fsSync from "node:fs";
|
|
6489
|
-
import
|
|
6490
|
+
import os from "node:os";
|
|
6490
6491
|
import path6 from "node:path";
|
|
6491
6492
|
var MCP_DESCRIPTOR_CACHE_VERSION = 1;
|
|
6492
6493
|
var expandHome = (input) => {
|
|
6493
6494
|
if (!input.startsWith("~")) return input;
|
|
6494
|
-
const home =
|
|
6495
|
+
const home = os.homedir();
|
|
6495
6496
|
if (input === "~") return home;
|
|
6496
6497
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
6497
6498
|
return path6.join(home, input.slice(2));
|
|
6498
6499
|
}
|
|
6499
6500
|
return input;
|
|
6500
6501
|
};
|
|
6501
|
-
var legacyMcporterDir = () => path6.join(
|
|
6502
|
+
var legacyMcporterDir = () => path6.join(os.homedir(), ".mcporter");
|
|
6502
6503
|
var mcporterConfigDir = () => {
|
|
6503
6504
|
const raw = process.env.XDG_CONFIG_HOME;
|
|
6504
6505
|
if (raw && raw.trim().length > 0) {
|
|
@@ -7615,7 +7616,7 @@ var MeshProvider = class {
|
|
|
7615
7616
|
|
|
7616
7617
|
// src/providers/pi-tools-provider.ts
|
|
7617
7618
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
7618
|
-
import
|
|
7619
|
+
import path10 from "node:path";
|
|
7619
7620
|
import {
|
|
7620
7621
|
createBashToolDefinition as createBashToolDefinition2,
|
|
7621
7622
|
createEditToolDefinition,
|
|
@@ -7625,9 +7626,102 @@ import {
|
|
|
7625
7626
|
createReadToolDefinition
|
|
7626
7627
|
} from "@earendil-works/pi-coding-agent";
|
|
7627
7628
|
|
|
7629
|
+
// src/agents/bash-worktree-add.ts
|
|
7630
|
+
import fs5 from "node:fs";
|
|
7631
|
+
import path8 from "node:path";
|
|
7632
|
+
var BARE_SAFE = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
7633
|
+
var parseGitWorktreeAdd = (command) => {
|
|
7634
|
+
const trimmed = command.trim();
|
|
7635
|
+
if (!trimmed || /[|&;()\n]/.test(trimmed)) return void 0;
|
|
7636
|
+
const tokens = trimmed.split(/\s+/);
|
|
7637
|
+
if (tokens[0] !== "git") return void 0;
|
|
7638
|
+
if (tokens.some((token) => !BARE_SAFE.test(token))) return void 0;
|
|
7639
|
+
let index = 1;
|
|
7640
|
+
let gitCwd;
|
|
7641
|
+
if (tokens[index] === "-C") {
|
|
7642
|
+
gitCwd = tokens[index + 1];
|
|
7643
|
+
if (!gitCwd) return void 0;
|
|
7644
|
+
index += 2;
|
|
7645
|
+
}
|
|
7646
|
+
if (tokens[index] !== "worktree" || tokens[index + 1] !== "add") return void 0;
|
|
7647
|
+
index += 2;
|
|
7648
|
+
let branch;
|
|
7649
|
+
let detach = false;
|
|
7650
|
+
let quiet = false;
|
|
7651
|
+
let flagsEnded = false;
|
|
7652
|
+
const positionals = [];
|
|
7653
|
+
while (index < tokens.length) {
|
|
7654
|
+
const token = tokens[index++];
|
|
7655
|
+
if (token === void 0) break;
|
|
7656
|
+
if (!flagsEnded && token === "--") {
|
|
7657
|
+
flagsEnded = true;
|
|
7658
|
+
continue;
|
|
7659
|
+
}
|
|
7660
|
+
if (!flagsEnded && (token === "-b" || token === "-B")) {
|
|
7661
|
+
if (branch) return void 0;
|
|
7662
|
+
const name = tokens[index++];
|
|
7663
|
+
if (!name) return void 0;
|
|
7664
|
+
branch = { flag: token, name };
|
|
7665
|
+
continue;
|
|
7666
|
+
}
|
|
7667
|
+
if (!flagsEnded && (token === "--detach" || token === "-d")) {
|
|
7668
|
+
detach = true;
|
|
7669
|
+
continue;
|
|
7670
|
+
}
|
|
7671
|
+
if (!flagsEnded && (token === "-q" || token === "--quiet")) {
|
|
7672
|
+
quiet = true;
|
|
7673
|
+
continue;
|
|
7674
|
+
}
|
|
7675
|
+
if (!flagsEnded && token.startsWith("-")) return void 0;
|
|
7676
|
+
positionals.push(token);
|
|
7677
|
+
}
|
|
7678
|
+
if (detach && branch) return void 0;
|
|
7679
|
+
if (positionals.length < 1 || positionals.length > 2) return void 0;
|
|
7680
|
+
return {
|
|
7681
|
+
...gitCwd ? { gitCwd } : {},
|
|
7682
|
+
...branch ? { branch } : {},
|
|
7683
|
+
detach,
|
|
7684
|
+
quiet,
|
|
7685
|
+
dest: positionals[0],
|
|
7686
|
+
...positionals[1] ? { startPoint: positionals[1] } : {}
|
|
7687
|
+
};
|
|
7688
|
+
};
|
|
7689
|
+
var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
7690
|
+
const command = args.command;
|
|
7691
|
+
if (typeof command !== "string") return void 0;
|
|
7692
|
+
const parsed = parseGitWorktreeAdd(command);
|
|
7693
|
+
if (!parsed) return void 0;
|
|
7694
|
+
const gitCwd = parsed.gitCwd ? path8.resolve(sessionCwd, parsed.gitCwd) : typeof args.cwd === "string" ? args.cwd : sessionCwd;
|
|
7695
|
+
const dest = path8.resolve(gitCwd, parsed.dest);
|
|
7696
|
+
let gitRoot;
|
|
7697
|
+
try {
|
|
7698
|
+
const root = await executeFile("git", ["rev-parse", "--show-toplevel"], {
|
|
7699
|
+
cwd: gitCwd,
|
|
7700
|
+
timeoutMs: 1e4
|
|
7701
|
+
});
|
|
7702
|
+
const output = root.stdout.trim();
|
|
7703
|
+
if (!output) return void 0;
|
|
7704
|
+
gitRoot = fs5.realpathSync(output);
|
|
7705
|
+
} catch {
|
|
7706
|
+
return void 0;
|
|
7707
|
+
}
|
|
7708
|
+
const result = await addCloneFirstWorktree({
|
|
7709
|
+
gitRoot,
|
|
7710
|
+
dest,
|
|
7711
|
+
...parsed.branch ? { branch: parsed.branch } : {},
|
|
7712
|
+
detach: parsed.detach,
|
|
7713
|
+
quiet: parsed.quiet,
|
|
7714
|
+
...parsed.startPoint ? { startPoint: parsed.startPoint } : {}
|
|
7715
|
+
});
|
|
7716
|
+
return {
|
|
7717
|
+
content: [{ type: "text", text: result.message || `Preparing worktree (${dest})` }],
|
|
7718
|
+
details: { exitCode: 0, cloned: result.cloned }
|
|
7719
|
+
};
|
|
7720
|
+
};
|
|
7721
|
+
|
|
7628
7722
|
// src/providers/pi-bash-cwd.ts
|
|
7629
7723
|
import { accessSync, constants, statSync } from "node:fs";
|
|
7630
|
-
import
|
|
7724
|
+
import path9 from "node:path";
|
|
7631
7725
|
import { createBashToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
7632
7726
|
import { Type as Type2 } from "typebox";
|
|
7633
7727
|
var PI_BASH_CWD_KEY = "cwd";
|
|
@@ -7637,7 +7731,7 @@ var resolvePiBashCwd = (sessionCwd, requested) => {
|
|
|
7637
7731
|
`Invalid pi.bash cwd ${JSON.stringify(requested)}: path must be a non-empty string`
|
|
7638
7732
|
);
|
|
7639
7733
|
}
|
|
7640
|
-
const resolved =
|
|
7734
|
+
const resolved = path9.isAbsolute(requested) ? path9.resolve(requested) : path9.resolve(sessionCwd, requested);
|
|
7641
7735
|
try {
|
|
7642
7736
|
if (!statSync(resolved).isDirectory()) throw new Error("path is not a directory");
|
|
7643
7737
|
accessSync(resolved, constants.R_OK | constants.X_OK);
|
|
@@ -7736,14 +7830,14 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
7736
7830
|
return {
|
|
7737
7831
|
...original,
|
|
7738
7832
|
async execute(_toolCallId, params, signal) {
|
|
7739
|
-
const { path:
|
|
7740
|
-
const absolutePath = resolvePreviewPath(
|
|
7833
|
+
const { path: path16, content } = params;
|
|
7834
|
+
const absolutePath = resolvePreviewPath(path16, cwd);
|
|
7741
7835
|
return withFileMutationQueue(absolutePath, async () => {
|
|
7742
7836
|
const throwIfAborted2 = () => {
|
|
7743
7837
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
7744
7838
|
};
|
|
7745
7839
|
throwIfAborted2();
|
|
7746
|
-
const before = await readExistingFileForPreview(
|
|
7840
|
+
const before = await readExistingFileForPreview(path16, cwd, content);
|
|
7747
7841
|
throwIfAborted2();
|
|
7748
7842
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
7749
7843
|
throwIfAborted2();
|
|
@@ -7753,7 +7847,7 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
7753
7847
|
content: [
|
|
7754
7848
|
{
|
|
7755
7849
|
type: "text",
|
|
7756
|
-
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${
|
|
7850
|
+
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${path16}`
|
|
7757
7851
|
}
|
|
7758
7852
|
],
|
|
7759
7853
|
details: { codePreviewBeforeWrite: before }
|
|
@@ -7787,7 +7881,7 @@ var expandReplaceAllEdit = (cwd, args, allForEveryEdit) => {
|
|
|
7787
7881
|
}
|
|
7788
7882
|
return { oldText, newText, all: allForEveryEdit || record.all === true };
|
|
7789
7883
|
});
|
|
7790
|
-
const resolvedPath =
|
|
7884
|
+
const resolvedPath = path10.resolve(
|
|
7791
7885
|
cwd,
|
|
7792
7886
|
filePath.startsWith("@") ? filePath.slice(1) : filePath
|
|
7793
7887
|
);
|
|
@@ -7929,6 +8023,13 @@ var PiToolsProvider = class {
|
|
|
7929
8023
|
async invoke(actionName, args, context) {
|
|
7930
8024
|
if (!(actionName in this.#tools)) throw new Error(`Unknown Pi tool: ${actionName}`);
|
|
7931
8025
|
const name = actionName;
|
|
8026
|
+
if (name === "bash") {
|
|
8027
|
+
const intercepted = await tryExecuteGitWorktreeAdd(args, this.#cwd);
|
|
8028
|
+
if (intercepted) {
|
|
8029
|
+
this.#attachPreview(name, intercepted, args, context);
|
|
8030
|
+
return this.#normalizeResult(name, intercepted, args);
|
|
8031
|
+
}
|
|
8032
|
+
}
|
|
7932
8033
|
if (this.#catalog?.get(name)) {
|
|
7933
8034
|
const result = await this.#capturedTools.invoke(name, args, context);
|
|
7934
8035
|
this.#attachReadMedia(name, result, context);
|
|
@@ -8149,8 +8250,8 @@ var PiToolsProvider = class {
|
|
|
8149
8250
|
// src/schema/controller.ts
|
|
8150
8251
|
import { spawn } from "node:child_process";
|
|
8151
8252
|
import { createHash as createHash3, randomBytes, randomUUID as randomUUID3 } from "node:crypto";
|
|
8152
|
-
import
|
|
8153
|
-
import
|
|
8253
|
+
import fs7 from "node:fs";
|
|
8254
|
+
import path12 from "node:path";
|
|
8154
8255
|
|
|
8155
8256
|
// src/schema/types.ts
|
|
8156
8257
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -8158,8 +8259,8 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
8158
8259
|
// src/schema/workspace.ts
|
|
8159
8260
|
import { execFileSync } from "node:child_process";
|
|
8160
8261
|
import { createHash as createHash2 } from "node:crypto";
|
|
8161
|
-
import
|
|
8162
|
-
import
|
|
8262
|
+
import fs6 from "node:fs";
|
|
8263
|
+
import path11 from "node:path";
|
|
8163
8264
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
8164
8265
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
8165
8266
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -8177,16 +8278,16 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
8177
8278
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8178
8279
|
});
|
|
8179
8280
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
8180
|
-
var normalizeRelative = (value) => value.split(
|
|
8281
|
+
var normalizeRelative = (value) => value.split(path11.sep).join("/");
|
|
8181
8282
|
var isInside = (root, candidate) => {
|
|
8182
|
-
const relative =
|
|
8183
|
-
return relative === "" || !
|
|
8283
|
+
const relative = path11.relative(root, candidate);
|
|
8284
|
+
return relative === "" || !path11.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path11.sep}`);
|
|
8184
8285
|
};
|
|
8185
8286
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
8186
8287
|
var entryDigest = (absolute) => {
|
|
8187
8288
|
let stat2;
|
|
8188
8289
|
try {
|
|
8189
|
-
stat2 =
|
|
8290
|
+
stat2 = fs6.lstatSync(absolute);
|
|
8190
8291
|
} catch (error) {
|
|
8191
8292
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
8192
8293
|
return { marker: "absent", bytes: 0 };
|
|
@@ -8194,24 +8295,24 @@ var entryDigest = (absolute) => {
|
|
|
8194
8295
|
throw error;
|
|
8195
8296
|
}
|
|
8196
8297
|
if (stat2.isSymbolicLink()) {
|
|
8197
|
-
return { marker: `symlink:${digest(
|
|
8298
|
+
return { marker: `symlink:${digest(fs6.readlinkSync(absolute))}`, bytes: 0 };
|
|
8198
8299
|
}
|
|
8199
8300
|
if (!stat2.isFile()) {
|
|
8200
8301
|
throw new Error(`Schema workspace snapshot does not support non-file entry: ${absolute}`);
|
|
8201
8302
|
}
|
|
8202
|
-
return { marker: `file:${stat2.mode & 511}:${digest(
|
|
8303
|
+
return { marker: `file:${stat2.mode & 511}:${digest(fs6.readFileSync(absolute))}`, bytes: stat2.size };
|
|
8203
8304
|
};
|
|
8204
8305
|
var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
8205
8306
|
const entries = {};
|
|
8206
8307
|
let bytes = 0;
|
|
8207
8308
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
8208
8309
|
for (const relativeInput of unique) {
|
|
8209
|
-
const absolute =
|
|
8310
|
+
const absolute = path11.resolve(cwd, relativeInput);
|
|
8210
8311
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
8211
8312
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
8212
8313
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
8213
8314
|
}
|
|
8214
|
-
const relative = normalizeRelative(
|
|
8315
|
+
const relative = normalizeRelative(path11.relative(cwd, absolute));
|
|
8215
8316
|
const entry = entryDigest(absolute);
|
|
8216
8317
|
bytes += entry.bytes;
|
|
8217
8318
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -8237,12 +8338,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
8237
8338
|
var fallbackPaths = (cwd, exclusions) => {
|
|
8238
8339
|
const paths = [];
|
|
8239
8340
|
const visit = (directory) => {
|
|
8240
|
-
const entries =
|
|
8341
|
+
const entries = fs6.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
8241
8342
|
for (const entry of entries) {
|
|
8242
8343
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
8243
|
-
const absolute =
|
|
8344
|
+
const absolute = path11.join(directory, entry.name);
|
|
8244
8345
|
if (excluded(absolute, exclusions)) continue;
|
|
8245
|
-
const relative = normalizeRelative(
|
|
8346
|
+
const relative = normalizeRelative(path11.relative(cwd, absolute));
|
|
8246
8347
|
if (entry.isDirectory()) visit(absolute);
|
|
8247
8348
|
else paths.push(relative);
|
|
8248
8349
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -8254,11 +8355,11 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8254
8355
|
return paths;
|
|
8255
8356
|
};
|
|
8256
8357
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
8257
|
-
const cwd =
|
|
8358
|
+
const cwd = fs6.realpathSync(cwdInput);
|
|
8258
8359
|
const exclusions = excludedRoots.map((root) => {
|
|
8259
|
-
const absolute =
|
|
8360
|
+
const absolute = path11.resolve(root);
|
|
8260
8361
|
try {
|
|
8261
|
-
return
|
|
8362
|
+
return fs6.realpathSync(absolute);
|
|
8262
8363
|
} catch {
|
|
8263
8364
|
return absolute;
|
|
8264
8365
|
}
|
|
@@ -8294,29 +8395,29 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
8294
8395
|
);
|
|
8295
8396
|
};
|
|
8296
8397
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
8297
|
-
if (!requestedPath.trim() ||
|
|
8398
|
+
if (!requestedPath.trim() || path11.isAbsolute(requestedPath)) {
|
|
8298
8399
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
8299
8400
|
}
|
|
8300
|
-
const cwd =
|
|
8301
|
-
const absolute =
|
|
8401
|
+
const cwd = fs6.realpathSync(cwdInput);
|
|
8402
|
+
const absolute = path11.resolve(cwd, requestedPath);
|
|
8302
8403
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
8303
8404
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
8304
8405
|
}
|
|
8305
|
-
const relativeParts =
|
|
8406
|
+
const relativeParts = path11.relative(cwd, absolute).split(path11.sep);
|
|
8306
8407
|
let cursor = cwd;
|
|
8307
8408
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
8308
|
-
cursor =
|
|
8409
|
+
cursor = path11.join(cursor, relativeParts[index]);
|
|
8309
8410
|
let stat2;
|
|
8310
8411
|
try {
|
|
8311
|
-
stat2 =
|
|
8412
|
+
stat2 = fs6.lstatSync(cursor);
|
|
8312
8413
|
} catch (error) {
|
|
8313
8414
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
8314
8415
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
8315
8416
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
8316
8417
|
}
|
|
8317
|
-
const parentReal =
|
|
8418
|
+
const parentReal = fs6.realpathSync(path11.dirname(cursor));
|
|
8318
8419
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
8319
|
-
return { absolute, relative: normalizeRelative(
|
|
8420
|
+
return { absolute, relative: normalizeRelative(path11.relative(cwd, absolute)), exists: false };
|
|
8320
8421
|
}
|
|
8321
8422
|
throw error;
|
|
8322
8423
|
}
|
|
@@ -8328,9 +8429,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
8328
8429
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
8329
8430
|
}
|
|
8330
8431
|
}
|
|
8331
|
-
return { absolute, relative: normalizeRelative(
|
|
8432
|
+
return { absolute, relative: normalizeRelative(path11.relative(cwd, absolute)), exists: true };
|
|
8332
8433
|
};
|
|
8333
|
-
var sha256File = (absolute) => `sha256:${digest(
|
|
8434
|
+
var sha256File = (absolute) => `sha256:${digest(fs6.readFileSync(absolute))}`;
|
|
8334
8435
|
|
|
8335
8436
|
// src/schema/controller.ts
|
|
8336
8437
|
var SCHEMA_TOPIC = "fabric.schema";
|
|
@@ -8378,9 +8479,9 @@ var SchemaController = class {
|
|
|
8378
8479
|
this.mesh = mesh;
|
|
8379
8480
|
this.identity = identity;
|
|
8380
8481
|
this.state = state;
|
|
8381
|
-
this.cwd =
|
|
8382
|
-
this.#journalRoot =
|
|
8383
|
-
this.#lockPath =
|
|
8482
|
+
this.cwd = fs7.realpathSync(cwd);
|
|
8483
|
+
this.#journalRoot = path12.join(mesh.root, "schema-transactions");
|
|
8484
|
+
this.#lockPath = path12.join(this.#journalRoot, ".commit.lock");
|
|
8384
8485
|
this.#recoverJournals();
|
|
8385
8486
|
}
|
|
8386
8487
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -8579,7 +8680,7 @@ var SchemaController = class {
|
|
|
8579
8680
|
this.#assertPayloadBound(input);
|
|
8580
8681
|
const release = this.#acquireCommitLock();
|
|
8581
8682
|
const transactionId = randomUUID3();
|
|
8582
|
-
const journalPath =
|
|
8683
|
+
const journalPath = path12.join(this.#journalRoot, `${transactionId}.json`);
|
|
8583
8684
|
let journal;
|
|
8584
8685
|
let consumed = false;
|
|
8585
8686
|
let committed = false;
|
|
@@ -8619,14 +8720,14 @@ var SchemaController = class {
|
|
|
8619
8720
|
before.push({ path: resolved.relative, absolute: resolved.absolute, existed: false });
|
|
8620
8721
|
continue;
|
|
8621
8722
|
}
|
|
8622
|
-
const content =
|
|
8723
|
+
const content = fs7.readFileSync(resolved.absolute);
|
|
8623
8724
|
beforeBytes += content.byteLength;
|
|
8624
8725
|
before.push({
|
|
8625
8726
|
path: resolved.relative,
|
|
8626
8727
|
absolute: resolved.absolute,
|
|
8627
8728
|
existed: true,
|
|
8628
8729
|
content: content.toString("base64"),
|
|
8629
|
-
mode:
|
|
8730
|
+
mode: fs7.statSync(resolved.absolute).mode & 511
|
|
8630
8731
|
});
|
|
8631
8732
|
}
|
|
8632
8733
|
if (payloadBytes + beforeBytes > this.config.maxBytes) {
|
|
@@ -8870,7 +8971,7 @@ var SchemaController = class {
|
|
|
8870
8971
|
observedSha256: sha256File(resolved.absolute)
|
|
8871
8972
|
});
|
|
8872
8973
|
} else if (item.kind === "file_contains") {
|
|
8873
|
-
const confirmed =
|
|
8974
|
+
const confirmed = fs7.readFileSync(resolved.absolute, "utf8").includes(item.literal);
|
|
8874
8975
|
results.push({
|
|
8875
8976
|
evidence: item,
|
|
8876
8977
|
status: confirmed ? "confirmed" : "nonconfirmed",
|
|
@@ -8941,22 +9042,22 @@ var SchemaController = class {
|
|
|
8941
9042
|
throw new Error(`Schema precondition SHA-256 mismatch: ${operation.path}`);
|
|
8942
9043
|
}
|
|
8943
9044
|
}
|
|
8944
|
-
|
|
9045
|
+
fs7.writeFileSync(resolved.absolute, operation.content, "utf8");
|
|
8945
9046
|
return;
|
|
8946
9047
|
}
|
|
8947
9048
|
if (sha256File(resolved.absolute) !== operation.expectedSha256) {
|
|
8948
9049
|
throw new Error(`Schema precondition SHA-256 mismatch: ${operation.path}`);
|
|
8949
9050
|
}
|
|
8950
9051
|
if (operation.kind === "delete") {
|
|
8951
|
-
|
|
9052
|
+
fs7.unlinkSync(resolved.absolute);
|
|
8952
9053
|
return;
|
|
8953
9054
|
}
|
|
8954
|
-
const content =
|
|
9055
|
+
const content = fs7.readFileSync(resolved.absolute, "utf8");
|
|
8955
9056
|
const first = content.indexOf(operation.oldText);
|
|
8956
9057
|
if (first < 0 || content.indexOf(operation.oldText, first + operation.oldText.length) >= 0) {
|
|
8957
9058
|
throw new Error(`Schema edit requires oldText to occur exactly once: ${operation.path}`);
|
|
8958
9059
|
}
|
|
8959
|
-
|
|
9060
|
+
fs7.writeFileSync(resolved.absolute, `${content.slice(0, first)}${operation.newText}${content.slice(first + operation.oldText.length)}`, "utf8");
|
|
8960
9061
|
}
|
|
8961
9062
|
#assertNoOutsideDrift(before, after, declared) {
|
|
8962
9063
|
if (before.git !== after.git || before.head !== after.head || before.indexDigest !== after.indexDigest) {
|
|
@@ -8976,10 +9077,10 @@ var SchemaController = class {
|
|
|
8976
9077
|
try {
|
|
8977
9078
|
const resolved = resolveWorkspaceFile(this.cwd, image.path, { allowAbsent: true });
|
|
8978
9079
|
if (!image.existed) {
|
|
8979
|
-
if (resolved.exists)
|
|
9080
|
+
if (resolved.exists) fs7.unlinkSync(resolved.absolute);
|
|
8980
9081
|
} else {
|
|
8981
|
-
|
|
8982
|
-
if (image.mode !== void 0)
|
|
9082
|
+
fs7.writeFileSync(resolved.absolute, Buffer.from(image.content ?? "", "base64"));
|
|
9083
|
+
if (image.mode !== void 0) fs7.chmodSync(resolved.absolute, image.mode);
|
|
8983
9084
|
}
|
|
8984
9085
|
} catch (error) {
|
|
8985
9086
|
errors.push(`${image.path}: ${errorMessage3(error)}`);
|
|
@@ -9027,25 +9128,25 @@ var SchemaController = class {
|
|
|
9027
9128
|
return this.mesh.publish({ topic: SCHEMA_TOPIC, kind, from: this.identity, data });
|
|
9028
9129
|
}
|
|
9029
9130
|
#acquireCommitLock() {
|
|
9030
|
-
|
|
9131
|
+
fs7.mkdirSync(this.#journalRoot, { recursive: true, mode: 448 });
|
|
9031
9132
|
try {
|
|
9032
|
-
const descriptor =
|
|
9033
|
-
|
|
9133
|
+
const descriptor = fs7.openSync(this.#lockPath, "wx", 384);
|
|
9134
|
+
fs7.writeFileSync(descriptor, `${process.pid}
|
|
9034
9135
|
${Date.now()}
|
|
9035
9136
|
`);
|
|
9036
|
-
|
|
9137
|
+
fs7.closeSync(descriptor);
|
|
9037
9138
|
} catch (error) {
|
|
9038
9139
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
9039
9140
|
throw new Error("Another Schema transaction is in progress");
|
|
9040
9141
|
}
|
|
9041
9142
|
throw error;
|
|
9042
9143
|
}
|
|
9043
|
-
return () =>
|
|
9144
|
+
return () => fs7.rmSync(this.#lockPath, { force: true });
|
|
9044
9145
|
}
|
|
9045
9146
|
#recoverJournals() {
|
|
9046
|
-
|
|
9147
|
+
fs7.mkdirSync(this.#journalRoot, { recursive: true, mode: 448 });
|
|
9047
9148
|
try {
|
|
9048
|
-
const [pidText] =
|
|
9149
|
+
const [pidText] = fs7.readFileSync(this.#lockPath, "utf8").split("\n");
|
|
9049
9150
|
const pid = Number(pidText);
|
|
9050
9151
|
if (Number.isSafeInteger(pid) && pid > 0) {
|
|
9051
9152
|
try {
|
|
@@ -9054,15 +9155,15 @@ ${Date.now()}
|
|
|
9054
9155
|
} catch {
|
|
9055
9156
|
}
|
|
9056
9157
|
}
|
|
9057
|
-
|
|
9158
|
+
fs7.rmSync(this.#lockPath, { force: true });
|
|
9058
9159
|
} catch (error) {
|
|
9059
9160
|
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) throw error;
|
|
9060
9161
|
}
|
|
9061
|
-
for (const name of
|
|
9162
|
+
for (const name of fs7.readdirSync(this.#journalRoot)) {
|
|
9062
9163
|
if (!name.endsWith(".json")) continue;
|
|
9063
|
-
const filePath =
|
|
9164
|
+
const filePath = path12.join(this.#journalRoot, name);
|
|
9064
9165
|
try {
|
|
9065
|
-
const journal = JSON.parse(
|
|
9166
|
+
const journal = JSON.parse(fs7.readFileSync(filePath, "utf8"));
|
|
9066
9167
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
9067
9168
|
const workspace = this.#workspaceEntry()?.value;
|
|
9068
9169
|
if (workspace?.lastOutcome === "committed" && workspace.lastTransactionId === journal.id) {
|
|
@@ -9314,11 +9415,11 @@ var SchemaProvider = class {
|
|
|
9314
9415
|
|
|
9315
9416
|
// src/state/store.ts
|
|
9316
9417
|
import { createHash as createHash5 } from "node:crypto";
|
|
9317
|
-
import
|
|
9418
|
+
import path14 from "node:path";
|
|
9318
9419
|
|
|
9319
9420
|
// src/state/complexity.ts
|
|
9320
|
-
import
|
|
9321
|
-
import
|
|
9421
|
+
import fs8 from "node:fs";
|
|
9422
|
+
import path13 from "node:path";
|
|
9322
9423
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
9323
9424
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
9324
9425
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -9550,7 +9651,7 @@ var languageComplexities = [
|
|
|
9550
9651
|
typeScriptJavaScriptComplexity
|
|
9551
9652
|
];
|
|
9552
9653
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
9553
|
-
const extension =
|
|
9654
|
+
const extension = path13.extname(file).toLowerCase();
|
|
9554
9655
|
return languages.find((language) => language.extensions.includes(extension));
|
|
9555
9656
|
};
|
|
9556
9657
|
var countFileComplexity = (file) => {
|
|
@@ -9559,7 +9660,7 @@ var countFileComplexity = (file) => {
|
|
|
9559
9660
|
return {
|
|
9560
9661
|
file,
|
|
9561
9662
|
language: language.language,
|
|
9562
|
-
count: language.count(
|
|
9663
|
+
count: language.count(fs8.readFileSync(file, "utf8"))
|
|
9563
9664
|
};
|
|
9564
9665
|
};
|
|
9565
9666
|
|
|
@@ -10441,7 +10542,7 @@ var StateStore = class {
|
|
|
10441
10542
|
const files = [];
|
|
10442
10543
|
let netDelta = 0;
|
|
10443
10544
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
10444
|
-
const measured = countFileComplexity(
|
|
10545
|
+
const measured = countFileComplexity(path14.resolve(input.cwd, file));
|
|
10445
10546
|
if (!measured) {
|
|
10446
10547
|
files.push({ file, supported: false });
|
|
10447
10548
|
continue;
|
|
@@ -10468,7 +10569,7 @@ var StateStore = class {
|
|
|
10468
10569
|
const updates = [];
|
|
10469
10570
|
let netDelta = 0;
|
|
10470
10571
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
10471
|
-
const measured = countFileComplexity(
|
|
10572
|
+
const measured = countFileComplexity(path14.resolve(cwd, file));
|
|
10472
10573
|
if (!measured) {
|
|
10473
10574
|
deltas.push({ file, supported: false });
|
|
10474
10575
|
continue;
|
|
@@ -10518,11 +10619,11 @@ var StateStore = class {
|
|
|
10518
10619
|
const normalized = /* @__PURE__ */ new Set();
|
|
10519
10620
|
for (const file of files) {
|
|
10520
10621
|
if (!file.trim()) continue;
|
|
10521
|
-
const relative =
|
|
10522
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
10622
|
+
const relative = path14.relative(cwd, path14.resolve(cwd, file));
|
|
10623
|
+
if (relative === ".." || relative.startsWith(`..${path14.sep}`) || path14.isAbsolute(relative)) {
|
|
10523
10624
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
10524
10625
|
}
|
|
10525
|
-
normalized.add(relative.split(
|
|
10626
|
+
normalized.add(relative.split(path14.sep).join("/"));
|
|
10526
10627
|
}
|
|
10527
10628
|
return [...normalized];
|
|
10528
10629
|
}
|
|
@@ -11468,7 +11569,7 @@ var FabricRuntimeState = class {
|
|
|
11468
11569
|
create: () => new McpProvider(context.cwd, this.#config.mcp, {
|
|
11469
11570
|
...this.#config.mcp.cache.enabled ? {
|
|
11470
11571
|
cache: new McpDescriptorCacheStore(
|
|
11471
|
-
|
|
11572
|
+
path15.join(
|
|
11472
11573
|
process.env.PI_FABRIC_PROJECT_ROOT ?? context.cwd,
|
|
11473
11574
|
".pi",
|
|
11474
11575
|
"fabric",
|
|
@@ -11512,7 +11613,7 @@ var FabricRuntimeState = class {
|
|
|
11512
11613
|
this.#mainAgent = mainAgent;
|
|
11513
11614
|
const projectRoot = process.env.PI_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
11514
11615
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
11515
|
-
const meshRoot = process.env.PI_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
11616
|
+
const meshRoot = process.env.PI_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path15.resolve(projectRoot, configuredMeshRoot) : path15.join(projectRoot, ".pi", "fabric", "mesh"));
|
|
11516
11617
|
this.#mesh = new MeshStore(
|
|
11517
11618
|
meshRoot,
|
|
11518
11619
|
this.#config.mesh.maxEventBytes,
|
|
@@ -11630,7 +11731,7 @@ var FabricRuntimeState = class {
|
|
|
11630
11731
|
return participant ? participant.ownerHostId === hostId : void 0;
|
|
11631
11732
|
};
|
|
11632
11733
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
11633
|
-
const persistentActorRoot = this.#config.mesh.actorScope === "session" ?
|
|
11734
|
+
const persistentActorRoot = this.#config.mesh.actorScope === "session" ? path15.join(meshRoot, "actors", sessionId) : path15.join(meshRoot, "actors");
|
|
11634
11735
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
11635
11736
|
cwd: context.cwd,
|
|
11636
11737
|
signal,
|
|
@@ -12249,4 +12350,4 @@ var deepAssign = (target, source) => {
|
|
|
12249
12350
|
export {
|
|
12250
12351
|
FabricRuntimeState
|
|
12251
12352
|
};
|
|
12252
|
-
//# sourceMappingURL=fabric-runtime-state-
|
|
12353
|
+
//# sourceMappingURL=fabric-runtime-state-H7UA3DJC.js.map
|