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.
- package/README.md +1 -0
- 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/capture/catalog.d.ts +3 -0
- package/dist/capture/catalog.d.ts.map +1 -1
- package/dist/chunks/{chunk-PAAXKXWT.js → chunk-2AF5ANEB.js} +16 -2
- package/dist/chunks/chunk-2AF5ANEB.js.map +7 -0
- package/dist/chunks/{chunk-QXB75FLD.js → chunk-2E3CAABA.js} +8 -1
- package/dist/chunks/chunk-2E3CAABA.js.map +7 -0
- package/dist/chunks/{chunk-6ZKYQW33.js → chunk-3QPTSKDG.js} +139 -29
- package/dist/chunks/chunk-3QPTSKDG.js.map +7 -0
- package/dist/chunks/{chunk-BT6UELLP.js → chunk-DUIHQAIZ.js} +2 -2
- package/dist/chunks/{chunk-6BBFFEPO.js → chunk-DYEOFQ64.js} +15 -1
- package/dist/chunks/{chunk-6BBFFEPO.js.map → chunk-DYEOFQ64.js.map} +2 -2
- package/dist/chunks/{chunk-F2GKEXGI.js → chunk-PFF3X7OO.js} +272 -146
- package/dist/chunks/chunk-PFF3X7OO.js.map +7 -0
- package/dist/chunks/{fabric-runtime-state-VCLWTB55.js → fabric-runtime-state-H2NCRJWK.js} +797 -191
- package/dist/chunks/fabric-runtime-state-H2NCRJWK.js.map +7 -0
- package/dist/chunks/{settings-VEXI347I.js → settings-FUL3U3N4.js} +2 -2
- package/dist/commands/fabric.d.ts.map +1 -1
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/core/action-registry.d.ts +1 -0
- package/dist/core/action-registry.d.ts.map +1 -1
- package/dist/core/action-registry.js +1 -1
- package/dist/fabric-runtime-state.d.ts +2 -0
- package/dist/fabric-runtime-state.d.ts.map +1 -1
- package/dist/fabric-state.d.ts +1 -0
- package/dist/fabric-state.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +218 -8
- package/dist/index.js.map +3 -3
- package/dist/providers/arg-normalization.d.ts +3 -0
- package/dist/providers/arg-normalization.d.ts.map +1 -1
- package/dist/providers/memory-provider.js +1 -1
- package/dist/providers/pi-tools-provider.d.ts.map +1 -1
- package/dist/repairs/active.d.ts +7 -0
- package/dist/repairs/active.d.ts.map +1 -0
- package/dist/repairs/apply.d.ts +7 -0
- package/dist/repairs/apply.d.ts.map +1 -0
- package/dist/repairs/catalog-digest.d.ts +5 -0
- package/dist/repairs/catalog-digest.d.ts.map +1 -0
- package/dist/repairs/classify.d.ts +10 -0
- package/dist/repairs/classify.d.ts.map +1 -0
- package/dist/repairs/compiler.d.ts +32 -0
- package/dist/repairs/compiler.d.ts.map +1 -0
- package/dist/repairs/promote.d.ts +4 -0
- package/dist/repairs/promote.d.ts.map +1 -0
- package/dist/repairs/store.d.ts +9 -0
- package/dist/repairs/store.d.ts.map +1 -0
- package/dist/repairs/types.d.ts +49 -0
- package/dist/repairs/types.d.ts.map +1 -0
- package/dist/residency/client.d.ts.map +1 -1
- package/dist/residency/host.js +3 -3
- package/dist/residency/pi-entry.js +3 -3
- package/dist/speculation/store.d.ts +11 -7
- package/dist/speculation/store.d.ts.map +1 -1
- package/dist/speculation/types.d.ts +2 -1
- package/dist/speculation/types.d.ts.map +1 -1
- package/docs/agents.md +1 -1
- package/docs/architecture.md +3 -1
- package/docs/configuration.md +4 -0
- package/docs/interface.md +1 -0
- package/docs/repairs.md +57 -0
- package/package.json +1 -1
- package/skills/fabric-exec/references/agents.md +3 -3
- package/dist/chunks/chunk-6ZKYQW33.js.map +0 -7
- package/dist/chunks/chunk-F2GKEXGI.js.map +0 -7
- package/dist/chunks/chunk-PAAXKXWT.js.map +0 -7
- package/dist/chunks/chunk-QXB75FLD.js.map +0 -7
- package/dist/chunks/fabric-runtime-state-VCLWTB55.js.map +0 -7
- /package/dist/chunks/{chunk-BT6UELLP.js.map → chunk-DUIHQAIZ.js.map} +0 -0
- /package/dist/chunks/{settings-VEXI347I.js.map → settings-FUL3U3N4.js.map} +0 -0
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
} from "./chunk-IGVDD2HT.js";
|
|
8
8
|
import {
|
|
9
9
|
MemoryProvider,
|
|
10
|
-
actionArgNormalizer
|
|
11
|
-
|
|
10
|
+
actionArgNormalizer,
|
|
11
|
+
uniqueDeclaredKeyForSpelling
|
|
12
|
+
} from "./chunk-DYEOFQ64.js";
|
|
12
13
|
import "./chunk-BOIV6E3C.js";
|
|
13
14
|
import "./chunk-NNFA2OIC.js";
|
|
14
15
|
import "./chunk-E3V22XGU.js";
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
repairFabricGuestCode,
|
|
32
33
|
resolveFabricIdentity,
|
|
33
34
|
runFabricHandoffAtBoundary
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-2AF5ANEB.js";
|
|
35
36
|
import {
|
|
36
37
|
AgentTranscriptReader,
|
|
37
38
|
MAX_WRITE_DIFF_BYTES,
|
|
@@ -40,8 +41,11 @@ import {
|
|
|
40
41
|
writeContentForPreview
|
|
41
42
|
} from "./chunk-5XQA7QX2.js";
|
|
42
43
|
import {
|
|
43
|
-
ActionRegistry
|
|
44
|
-
|
|
44
|
+
ActionRegistry,
|
|
45
|
+
clearActiveRepairCompiler,
|
|
46
|
+
repairActionName,
|
|
47
|
+
setActiveRepairCompiler
|
|
48
|
+
} from "./chunk-3QPTSKDG.js";
|
|
45
49
|
import {
|
|
46
50
|
formatFabricEffectConflict
|
|
47
51
|
} from "./chunk-LMAVZN7J.js";
|
|
@@ -69,15 +73,17 @@ import {
|
|
|
69
73
|
ParticipantDirectory,
|
|
70
74
|
actorDeliveryNotice,
|
|
71
75
|
actorParticipantRecord,
|
|
76
|
+
addCloneFirstWorktree,
|
|
72
77
|
agentParticipantRecords,
|
|
73
78
|
effectiveAgentTimeoutMs,
|
|
74
79
|
isFabricLifecycleEventType,
|
|
80
|
+
isFabricWorktreePath,
|
|
75
81
|
lifecycleSourceIdentity,
|
|
76
82
|
resolveActorDeliveryPolicy,
|
|
77
83
|
resolveAgentCwd,
|
|
78
84
|
resolvePiBinary,
|
|
79
85
|
validateAgentCwdRequest
|
|
80
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-PFF3X7OO.js";
|
|
81
87
|
import "./chunk-PM5I335G.js";
|
|
82
88
|
import "./chunk-VPPIJRNZ.js";
|
|
83
89
|
import {
|
|
@@ -100,7 +106,7 @@ import {
|
|
|
100
106
|
MIN_AGENT_TIMEOUT_MS,
|
|
101
107
|
loadFabricConfig,
|
|
102
108
|
resolveFabricModel
|
|
103
|
-
} from "./chunk-
|
|
109
|
+
} from "./chunk-2E3CAABA.js";
|
|
104
110
|
import {
|
|
105
111
|
isFabricThinking
|
|
106
112
|
} from "./chunk-7B55UIZL.js";
|
|
@@ -149,7 +155,7 @@ import {
|
|
|
149
155
|
} from "./chunk-IDTQ2B5W.js";
|
|
150
156
|
|
|
151
157
|
// src/fabric-runtime-state.ts
|
|
152
|
-
import
|
|
158
|
+
import path16 from "node:path";
|
|
153
159
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
154
160
|
|
|
155
161
|
// src/actors/global-registry.ts
|
|
@@ -2196,10 +2202,10 @@ var FabricComponentSupervisor = class {
|
|
|
2196
2202
|
adjacent.set(edge.from, targets);
|
|
2197
2203
|
}
|
|
2198
2204
|
const cycles = /* @__PURE__ */ new Map();
|
|
2199
|
-
const visit = (node,
|
|
2205
|
+
const visit = (node, path17, positions) => {
|
|
2200
2206
|
const position = positions.get(node);
|
|
2201
2207
|
if (position !== void 0) {
|
|
2202
|
-
const cycle =
|
|
2208
|
+
const cycle = path17.slice(position);
|
|
2203
2209
|
const rotations = cycle.map((_, index) => [
|
|
2204
2210
|
...cycle.slice(index),
|
|
2205
2211
|
...cycle.slice(0, index)
|
|
@@ -2209,10 +2215,10 @@ var FabricComponentSupervisor = class {
|
|
|
2209
2215
|
cycles.set(canonical.join("\0"), canonical);
|
|
2210
2216
|
return;
|
|
2211
2217
|
}
|
|
2212
|
-
if (
|
|
2213
|
-
const nextPositions = new Map(positions).set(node,
|
|
2218
|
+
if (path17.length > this.#components.size) return;
|
|
2219
|
+
const nextPositions = new Map(positions).set(node, path17.length);
|
|
2214
2220
|
for (const target of adjacent.get(node) ?? []) {
|
|
2215
|
-
visit(target, [...
|
|
2221
|
+
visit(target, [...path17, node], nextPositions);
|
|
2216
2222
|
}
|
|
2217
2223
|
};
|
|
2218
2224
|
for (const id of this.#components.keys()) visit(id, [], /* @__PURE__ */ new Map());
|
|
@@ -3324,6 +3330,473 @@ var FabricExecutionService = class {
|
|
|
3324
3330
|
}
|
|
3325
3331
|
};
|
|
3326
3332
|
|
|
3333
|
+
// src/repairs/apply.ts
|
|
3334
|
+
var strictDeclaredPropertyNames = (schema) => {
|
|
3335
|
+
if (schema.type !== "object" || schema.additionalProperties !== false || schema.patternProperties !== void 0) {
|
|
3336
|
+
return void 0;
|
|
3337
|
+
}
|
|
3338
|
+
const properties = schema.properties;
|
|
3339
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) return void 0;
|
|
3340
|
+
return Object.keys(properties);
|
|
3341
|
+
};
|
|
3342
|
+
var applyKeyAliasRepairs = (ref, args, repairs, schema) => {
|
|
3343
|
+
const declared = strictDeclaredPropertyNames(schema);
|
|
3344
|
+
if (!declared) return { args, changed: false };
|
|
3345
|
+
const declaredSet = new Set(declared);
|
|
3346
|
+
const applicable = repairs.filter(
|
|
3347
|
+
(repair) => repair.kind === "keyAlias" && repair.ref === ref && repair.from in args && repair.from !== repair.to && !declaredSet.has(repair.from) && declaredSet.has(repair.to) && uniqueDeclaredKeyForSpelling(repair.from, declared) === repair.to
|
|
3348
|
+
);
|
|
3349
|
+
const sourceCountByTarget = /* @__PURE__ */ new Map();
|
|
3350
|
+
for (const repair of applicable) {
|
|
3351
|
+
sourceCountByTarget.set(repair.to, (sourceCountByTarget.get(repair.to) ?? 0) + 1);
|
|
3352
|
+
}
|
|
3353
|
+
let out = args;
|
|
3354
|
+
let changed = false;
|
|
3355
|
+
for (const repair of applicable) {
|
|
3356
|
+
const canonicalPresent = repair.to in args;
|
|
3357
|
+
if (!canonicalPresent && sourceCountByTarget.get(repair.to) !== 1) continue;
|
|
3358
|
+
if (out === args) out = { ...args };
|
|
3359
|
+
if (!(repair.to in out)) out[repair.to] = out[repair.from];
|
|
3360
|
+
delete out[repair.from];
|
|
3361
|
+
changed = true;
|
|
3362
|
+
}
|
|
3363
|
+
return { args: out, changed };
|
|
3364
|
+
};
|
|
3365
|
+
var applyActionAliasRepairs = (provider, actionName, repairs, declared) => {
|
|
3366
|
+
if (declared.includes(actionName)) return void 0;
|
|
3367
|
+
const liveTarget = repairActionName(declared, actionName).repaired;
|
|
3368
|
+
if (!liveTarget) return void 0;
|
|
3369
|
+
for (const repair of repairs) {
|
|
3370
|
+
if (repair.kind !== "actionAlias") continue;
|
|
3371
|
+
if (repair.provider !== provider) continue;
|
|
3372
|
+
if (repair.from !== actionName) continue;
|
|
3373
|
+
if (repair.to !== liveTarget) continue;
|
|
3374
|
+
return repair.to;
|
|
3375
|
+
}
|
|
3376
|
+
return void 0;
|
|
3377
|
+
};
|
|
3378
|
+
var applyCatalogArgRepairs = (ref, args, repairs, schema) => applyKeyAliasRepairs(ref, args, repairs, schema);
|
|
3379
|
+
|
|
3380
|
+
// src/repairs/catalog-digest.ts
|
|
3381
|
+
var catalogDigestFromSurface = (surface) => stableJsonHash({
|
|
3382
|
+
v: 1,
|
|
3383
|
+
providers: [...surface.providers].sort(),
|
|
3384
|
+
captured: [...surface.capturedTools].sort()
|
|
3385
|
+
});
|
|
3386
|
+
|
|
3387
|
+
// src/repairs/promote.ts
|
|
3388
|
+
var keyAliasCandidate = (ref, extraKeys, declared) => {
|
|
3389
|
+
if (extraKeys.length !== 1) return void 0;
|
|
3390
|
+
const from = extraKeys[0];
|
|
3391
|
+
const to = uniqueDeclaredKeyForSpelling(from, declared);
|
|
3392
|
+
if (!to) return void 0;
|
|
3393
|
+
return { kind: "keyAlias", ref, from, to };
|
|
3394
|
+
};
|
|
3395
|
+
var actionAliasCandidate = (provider, actionName, declared) => {
|
|
3396
|
+
const repair = repairActionName(declared, actionName);
|
|
3397
|
+
if (!repair.repaired || repair.repaired === actionName) return void 0;
|
|
3398
|
+
return {
|
|
3399
|
+
kind: "actionAlias",
|
|
3400
|
+
provider,
|
|
3401
|
+
from: actionName,
|
|
3402
|
+
to: repair.repaired
|
|
3403
|
+
};
|
|
3404
|
+
};
|
|
3405
|
+
|
|
3406
|
+
// src/repairs/store.ts
|
|
3407
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
3408
|
+
import fs2 from "node:fs";
|
|
3409
|
+
import path2 from "node:path";
|
|
3410
|
+
|
|
3411
|
+
// src/repairs/types.ts
|
|
3412
|
+
var REPAIR_TABLE_VERSION = 1;
|
|
3413
|
+
var MAX_CATALOG_REPAIRS = 256;
|
|
3414
|
+
var repairIdentity = (repair) => {
|
|
3415
|
+
if (repair.kind === "keyAlias") {
|
|
3416
|
+
return `keyAlias:${repair.ref}:${repair.from}:${repair.to}`;
|
|
3417
|
+
}
|
|
3418
|
+
return `actionAlias:${repair.provider}:${repair.from}:${repair.to}`;
|
|
3419
|
+
};
|
|
3420
|
+
var emptyRepairTable = (catalogDigest, now = (/* @__PURE__ */ new Date()).toISOString()) => ({
|
|
3421
|
+
version: REPAIR_TABLE_VERSION,
|
|
3422
|
+
catalogDigest,
|
|
3423
|
+
repairs: [],
|
|
3424
|
+
createdAt: now,
|
|
3425
|
+
updatedAt: now
|
|
3426
|
+
});
|
|
3427
|
+
|
|
3428
|
+
// src/repairs/store.ts
|
|
3429
|
+
var REPAIR_LOCK_ATTEMPTS = 50;
|
|
3430
|
+
var REPAIR_LOCK_DELAY_MS = 5;
|
|
3431
|
+
var REPAIR_STALE_LOCK_MS = 3e4;
|
|
3432
|
+
var repairsDirectory = (agentDir) => path2.join(agentDir, "fabric", "repairs");
|
|
3433
|
+
var currentPath = (directory) => path2.join(directory, "current.json");
|
|
3434
|
+
var lockPath = (directory) => path2.join(directory, "current.lock");
|
|
3435
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3436
|
+
var errorCode = (error) => isRecord(error) && typeof error.code === "string" ? error.code : void 0;
|
|
3437
|
+
var sleepSync = (() => {
|
|
3438
|
+
try {
|
|
3439
|
+
const buffer = new Int32Array(new SharedArrayBuffer(4));
|
|
3440
|
+
return (ms) => {
|
|
3441
|
+
Atomics.wait(buffer, 0, 0, ms);
|
|
3442
|
+
};
|
|
3443
|
+
} catch {
|
|
3444
|
+
return () => void 0;
|
|
3445
|
+
}
|
|
3446
|
+
})();
|
|
3447
|
+
var parseRepair = (value) => {
|
|
3448
|
+
if (!isRecord(value) || typeof value.kind !== "string") return void 0;
|
|
3449
|
+
if (value.kind === "keyAlias") {
|
|
3450
|
+
if (typeof value.ref !== "string" || typeof value.from !== "string" || typeof value.to !== "string" || !value.ref.trim() || !value.from.trim() || !value.to.trim()) {
|
|
3451
|
+
return void 0;
|
|
3452
|
+
}
|
|
3453
|
+
return { kind: "keyAlias", ref: value.ref.trim(), from: value.from.trim(), to: value.to.trim() };
|
|
3454
|
+
}
|
|
3455
|
+
if (value.kind === "actionAlias") {
|
|
3456
|
+
if (typeof value.provider !== "string" || typeof value.from !== "string" || typeof value.to !== "string" || !value.provider.trim() || !value.from.trim() || !value.to.trim()) {
|
|
3457
|
+
return void 0;
|
|
3458
|
+
}
|
|
3459
|
+
return {
|
|
3460
|
+
kind: "actionAlias",
|
|
3461
|
+
provider: value.provider.trim(),
|
|
3462
|
+
from: value.from.trim(),
|
|
3463
|
+
to: value.to.trim()
|
|
3464
|
+
};
|
|
3465
|
+
}
|
|
3466
|
+
return "skip";
|
|
3467
|
+
};
|
|
3468
|
+
var parseRepairTable = (value) => {
|
|
3469
|
+
if (!isRecord(value) || value.version !== REPAIR_TABLE_VERSION) return void 0;
|
|
3470
|
+
if (typeof value.catalogDigest !== "string" || !value.catalogDigest.trim()) return void 0;
|
|
3471
|
+
if (!Array.isArray(value.repairs) || value.repairs.length > MAX_CATALOG_REPAIRS) return void 0;
|
|
3472
|
+
const repairs = [];
|
|
3473
|
+
const identities = /* @__PURE__ */ new Set();
|
|
3474
|
+
for (const entry of value.repairs) {
|
|
3475
|
+
const parsed = parseRepair(entry);
|
|
3476
|
+
if (parsed === "skip") continue;
|
|
3477
|
+
if (!parsed) return void 0;
|
|
3478
|
+
const identity = repairIdentity(parsed);
|
|
3479
|
+
if (identities.has(identity)) continue;
|
|
3480
|
+
identities.add(identity);
|
|
3481
|
+
repairs.push(parsed);
|
|
3482
|
+
}
|
|
3483
|
+
if (typeof value.createdAt !== "string" || typeof value.updatedAt !== "string") return void 0;
|
|
3484
|
+
return {
|
|
3485
|
+
version: REPAIR_TABLE_VERSION,
|
|
3486
|
+
catalogDigest: value.catalogDigest.trim(),
|
|
3487
|
+
repairs,
|
|
3488
|
+
createdAt: value.createdAt,
|
|
3489
|
+
updatedAt: value.updatedAt
|
|
3490
|
+
};
|
|
3491
|
+
};
|
|
3492
|
+
var errorText = (error) => (error instanceof Error ? error.message : String(error)).slice(0, 200);
|
|
3493
|
+
var writeTable = (file, table) => {
|
|
3494
|
+
writeJsonAtomic(file, table, { space: 2, newline: true, mode: 384, dirMode: 448 });
|
|
3495
|
+
};
|
|
3496
|
+
var processAlive = (pid) => {
|
|
3497
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return false;
|
|
3498
|
+
try {
|
|
3499
|
+
process.kill(pid, 0);
|
|
3500
|
+
return true;
|
|
3501
|
+
} catch {
|
|
3502
|
+
return false;
|
|
3503
|
+
}
|
|
3504
|
+
};
|
|
3505
|
+
var reapStaleLock = (lock, verify) => {
|
|
3506
|
+
const claim = `${lock}.reap-${process.pid}-${randomUUID2()}`;
|
|
3507
|
+
try {
|
|
3508
|
+
fs2.renameSync(lock, claim);
|
|
3509
|
+
} catch {
|
|
3510
|
+
return false;
|
|
3511
|
+
}
|
|
3512
|
+
if (!verify(claim)) {
|
|
3513
|
+
try {
|
|
3514
|
+
fs2.renameSync(claim, lock);
|
|
3515
|
+
} catch {
|
|
3516
|
+
if (verify(claim)) fs2.rmSync(claim, { recursive: true, force: true });
|
|
3517
|
+
}
|
|
3518
|
+
return false;
|
|
3519
|
+
}
|
|
3520
|
+
fs2.rmSync(claim, { recursive: true, force: true });
|
|
3521
|
+
return true;
|
|
3522
|
+
};
|
|
3523
|
+
var withRepairLock = (directory, operation) => {
|
|
3524
|
+
fs2.mkdirSync(directory, { recursive: true, mode: 448 });
|
|
3525
|
+
const lock = lockPath(directory);
|
|
3526
|
+
const ownerPath = path2.join(lock, "owner");
|
|
3527
|
+
const token = randomUUID2();
|
|
3528
|
+
let acquired = false;
|
|
3529
|
+
for (let attempt = 0; attempt < REPAIR_LOCK_ATTEMPTS; attempt++) {
|
|
3530
|
+
try {
|
|
3531
|
+
fs2.mkdirSync(lock, { mode: 448 });
|
|
3532
|
+
try {
|
|
3533
|
+
fs2.writeFileSync(ownerPath, `${token}
|
|
3534
|
+
${process.pid}
|
|
3535
|
+
${Date.now()}
|
|
3536
|
+
`, {
|
|
3537
|
+
encoding: "utf8",
|
|
3538
|
+
mode: 384
|
|
3539
|
+
});
|
|
3540
|
+
} catch (error) {
|
|
3541
|
+
fs2.rmSync(lock, { recursive: true, force: true });
|
|
3542
|
+
throw error;
|
|
3543
|
+
}
|
|
3544
|
+
acquired = true;
|
|
3545
|
+
break;
|
|
3546
|
+
} catch (error) {
|
|
3547
|
+
if (errorCode(error) !== "EEXIST") throw error;
|
|
3548
|
+
try {
|
|
3549
|
+
const firstOwner = fs2.readFileSync(ownerPath, "utf8");
|
|
3550
|
+
const [, pidText, createdText] = firstOwner.trim().split("\n");
|
|
3551
|
+
const stale = Date.now() - Number(createdText) > REPAIR_STALE_LOCK_MS;
|
|
3552
|
+
if (stale && !processAlive(Number(pidText))) {
|
|
3553
|
+
const secondOwner = fs2.readFileSync(ownerPath, "utf8");
|
|
3554
|
+
if (secondOwner === firstOwner && reapStaleLock(lock, (claimed) => {
|
|
3555
|
+
try {
|
|
3556
|
+
const owner = fs2.readFileSync(path2.join(claimed, "owner"), "utf8");
|
|
3557
|
+
const [, pid, created] = owner.trim().split("\n");
|
|
3558
|
+
return Date.now() - Number(created) > REPAIR_STALE_LOCK_MS && !processAlive(Number(pid));
|
|
3559
|
+
} catch {
|
|
3560
|
+
return false;
|
|
3561
|
+
}
|
|
3562
|
+
})) {
|
|
3563
|
+
continue;
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3566
|
+
} catch {
|
|
3567
|
+
try {
|
|
3568
|
+
const first = fs2.statSync(lock);
|
|
3569
|
+
if (Date.now() - first.mtimeMs > REPAIR_STALE_LOCK_MS && reapStaleLock(lock, (claimed) => {
|
|
3570
|
+
try {
|
|
3571
|
+
return Date.now() - fs2.statSync(claimed).mtimeMs > REPAIR_STALE_LOCK_MS;
|
|
3572
|
+
} catch {
|
|
3573
|
+
return false;
|
|
3574
|
+
}
|
|
3575
|
+
})) {
|
|
3576
|
+
continue;
|
|
3577
|
+
}
|
|
3578
|
+
} catch {
|
|
3579
|
+
}
|
|
3580
|
+
}
|
|
3581
|
+
if (attempt === REPAIR_LOCK_ATTEMPTS - 1) break;
|
|
3582
|
+
sleepSync(REPAIR_LOCK_DELAY_MS);
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
if (!acquired) throw new Error("Timed out waiting for the Fabric repair table lock");
|
|
3586
|
+
try {
|
|
3587
|
+
return operation();
|
|
3588
|
+
} finally {
|
|
3589
|
+
try {
|
|
3590
|
+
const owner = fs2.readFileSync(ownerPath, "utf8");
|
|
3591
|
+
if (owner.startsWith(`${token}
|
|
3592
|
+
`)) {
|
|
3593
|
+
fs2.rmSync(lock, { recursive: true, force: true });
|
|
3594
|
+
}
|
|
3595
|
+
} catch {
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
};
|
|
3599
|
+
var loadRepairTable = (directory, catalogDigest) => {
|
|
3600
|
+
const file = currentPath(directory);
|
|
3601
|
+
let raw;
|
|
3602
|
+
try {
|
|
3603
|
+
raw = fs2.readFileSync(file, "utf8");
|
|
3604
|
+
} catch (error) {
|
|
3605
|
+
if (errorCode(error) === "ENOENT") return { table: emptyRepairTable(catalogDigest) };
|
|
3606
|
+
return {
|
|
3607
|
+
table: emptyRepairTable(catalogDigest),
|
|
3608
|
+
error: `repair table is unreadable: ${errorText(error)}`
|
|
3609
|
+
};
|
|
3610
|
+
}
|
|
3611
|
+
let parsed;
|
|
3612
|
+
try {
|
|
3613
|
+
parsed = JSON.parse(raw);
|
|
3614
|
+
} catch {
|
|
3615
|
+
return { table: emptyRepairTable(catalogDigest), error: "repair table is malformed JSON" };
|
|
3616
|
+
}
|
|
3617
|
+
const table = parseRepairTable(parsed);
|
|
3618
|
+
if (!table) {
|
|
3619
|
+
return { table: emptyRepairTable(catalogDigest), error: "repair table is invalid" };
|
|
3620
|
+
}
|
|
3621
|
+
if (table.catalogDigest !== catalogDigest) return { table: emptyRepairTable(catalogDigest) };
|
|
3622
|
+
return { table };
|
|
3623
|
+
};
|
|
3624
|
+
var saveRepairTable = (directory, table) => withRepairLock(directory, () => {
|
|
3625
|
+
const loaded = loadRepairTable(directory, table.catalogDigest);
|
|
3626
|
+
if (loaded.error) throw new Error(loaded.error);
|
|
3627
|
+
const persisted = loaded.table;
|
|
3628
|
+
const repairs = [];
|
|
3629
|
+
const identities = /* @__PURE__ */ new Set();
|
|
3630
|
+
for (const repair of [...persisted.repairs, ...table.repairs]) {
|
|
3631
|
+
const identity = repairIdentity(repair);
|
|
3632
|
+
if (identities.has(identity)) continue;
|
|
3633
|
+
if (repairs.length >= MAX_CATALOG_REPAIRS) break;
|
|
3634
|
+
identities.add(identity);
|
|
3635
|
+
repairs.push(repair);
|
|
3636
|
+
}
|
|
3637
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3638
|
+
const merged = {
|
|
3639
|
+
version: REPAIR_TABLE_VERSION,
|
|
3640
|
+
catalogDigest: table.catalogDigest,
|
|
3641
|
+
repairs,
|
|
3642
|
+
createdAt: persisted.repairs.length > 0 ? persisted.createdAt : table.createdAt,
|
|
3643
|
+
updatedAt: now
|
|
3644
|
+
};
|
|
3645
|
+
writeTable(currentPath(directory), merged);
|
|
3646
|
+
return merged;
|
|
3647
|
+
});
|
|
3648
|
+
|
|
3649
|
+
// src/repairs/compiler.ts
|
|
3650
|
+
var errorMessage3 = (error) => (error instanceof Error ? error.message : String(error)).slice(0, 240);
|
|
3651
|
+
var RepairCompiler = class {
|
|
3652
|
+
directory;
|
|
3653
|
+
enabled;
|
|
3654
|
+
#digest = "";
|
|
3655
|
+
#table;
|
|
3656
|
+
#counts = /* @__PURE__ */ new Map();
|
|
3657
|
+
#applyHits = 0;
|
|
3658
|
+
#invocationErrors = 0;
|
|
3659
|
+
#effectDropped = 0;
|
|
3660
|
+
#storeError;
|
|
3661
|
+
constructor(options) {
|
|
3662
|
+
this.directory = repairsDirectory(options.agentDir);
|
|
3663
|
+
this.enabled = options.enabled !== false;
|
|
3664
|
+
this.#table = emptyRepairTable("");
|
|
3665
|
+
}
|
|
3666
|
+
get catalogDigest() {
|
|
3667
|
+
return this.#digest;
|
|
3668
|
+
}
|
|
3669
|
+
get repairs() {
|
|
3670
|
+
return this.#table.repairs;
|
|
3671
|
+
}
|
|
3672
|
+
setCatalogSurface(surface) {
|
|
3673
|
+
const digest3 = catalogDigestFromSurface(surface);
|
|
3674
|
+
if (digest3 === this.#digest && this.#table.catalogDigest === digest3) return;
|
|
3675
|
+
this.#digest = digest3;
|
|
3676
|
+
if (!this.enabled) {
|
|
3677
|
+
this.#table = emptyRepairTable(digest3);
|
|
3678
|
+
this.#storeError = void 0;
|
|
3679
|
+
} else {
|
|
3680
|
+
const loaded = loadRepairTable(this.directory, digest3);
|
|
3681
|
+
this.#table = loaded.table;
|
|
3682
|
+
this.#storeError = loaded.error;
|
|
3683
|
+
}
|
|
3684
|
+
this.#counts.clear();
|
|
3685
|
+
}
|
|
3686
|
+
observe(classification, options) {
|
|
3687
|
+
if (classification.stage === "effect") {
|
|
3688
|
+
this.#effectDropped += 1;
|
|
3689
|
+
return void 0;
|
|
3690
|
+
}
|
|
3691
|
+
if (options?.countError !== false) this.#invocationErrors += 1;
|
|
3692
|
+
const existing = this.#counts.get(classification.fingerprint);
|
|
3693
|
+
const candidate = classification.candidate ?? existing?.candidate;
|
|
3694
|
+
const next = {
|
|
3695
|
+
stage: classification.stage,
|
|
3696
|
+
count: (existing?.count ?? 0) + 1,
|
|
3697
|
+
...candidate ? { candidate } : {}
|
|
3698
|
+
};
|
|
3699
|
+
this.#counts.set(classification.fingerprint, next);
|
|
3700
|
+
if (!this.enabled || !next.candidate) return void 0;
|
|
3701
|
+
return this.#promote(next.candidate);
|
|
3702
|
+
}
|
|
3703
|
+
recordInvocationError() {
|
|
3704
|
+
this.#invocationErrors += 1;
|
|
3705
|
+
}
|
|
3706
|
+
observeInvalidArgs(ref, args, declared, message2, options) {
|
|
3707
|
+
const extra = options?.extraKeys ?? Object.keys(args).filter((key) => !declared.includes(key));
|
|
3708
|
+
const candidate = keyAliasCandidate(ref, extra, declared);
|
|
3709
|
+
return this.observe(
|
|
3710
|
+
{
|
|
3711
|
+
stage: "invocation_args",
|
|
3712
|
+
fingerprint: extra[0] ? `args:${ref}:${extra[0]}` : `args:${ref}:${message2.slice(0, 80)}`,
|
|
3713
|
+
...candidate ? { candidate } : {}
|
|
3714
|
+
},
|
|
3715
|
+
options
|
|
3716
|
+
);
|
|
3717
|
+
}
|
|
3718
|
+
observeUnknownAction(provider, actionName, declared, options) {
|
|
3719
|
+
const candidate = actionAliasCandidate(provider, actionName, declared);
|
|
3720
|
+
return this.observe(
|
|
3721
|
+
{
|
|
3722
|
+
stage: "invocation_unknown_action",
|
|
3723
|
+
fingerprint: `unknown:${provider}.${actionName}`,
|
|
3724
|
+
...candidate ? { candidate } : {}
|
|
3725
|
+
},
|
|
3726
|
+
options
|
|
3727
|
+
);
|
|
3728
|
+
}
|
|
3729
|
+
applyArgs(ref, args, schema) {
|
|
3730
|
+
if (!this.enabled || this.#table.repairs.length === 0) return args;
|
|
3731
|
+
const result = applyCatalogArgRepairs(ref, args, this.#table.repairs, schema);
|
|
3732
|
+
if (result.changed) this.#applyHits += 1;
|
|
3733
|
+
return result.args;
|
|
3734
|
+
}
|
|
3735
|
+
applyActionName(provider, actionName, declared) {
|
|
3736
|
+
if (!this.enabled || this.#table.repairs.length === 0) return actionName;
|
|
3737
|
+
const repaired = applyActionAliasRepairs(
|
|
3738
|
+
provider,
|
|
3739
|
+
actionName,
|
|
3740
|
+
this.#table.repairs,
|
|
3741
|
+
declared
|
|
3742
|
+
);
|
|
3743
|
+
if (repaired && repaired !== actionName) {
|
|
3744
|
+
this.#applyHits += 1;
|
|
3745
|
+
return repaired;
|
|
3746
|
+
}
|
|
3747
|
+
return actionName;
|
|
3748
|
+
}
|
|
3749
|
+
status() {
|
|
3750
|
+
const fingerprints = [...this.#counts.entries()].map(([fingerprint, state]) => ({
|
|
3751
|
+
fingerprint,
|
|
3752
|
+
stage: state.stage,
|
|
3753
|
+
count: state.count
|
|
3754
|
+
})).sort((left, right) => right.count - left.count || left.fingerprint.localeCompare(right.fingerprint)).slice(0, 20);
|
|
3755
|
+
return {
|
|
3756
|
+
enabled: this.enabled,
|
|
3757
|
+
catalogDigest: this.#digest,
|
|
3758
|
+
repairCount: this.#table.repairs.length,
|
|
3759
|
+
applyHits: this.#applyHits,
|
|
3760
|
+
invocationErrors: this.#invocationErrors,
|
|
3761
|
+
effectDropped: this.#effectDropped,
|
|
3762
|
+
...this.#storeError ? { storeError: this.#storeError } : {},
|
|
3763
|
+
fingerprints,
|
|
3764
|
+
repairs: [...this.#table.repairs]
|
|
3765
|
+
};
|
|
3766
|
+
}
|
|
3767
|
+
#promote(candidate) {
|
|
3768
|
+
if (!this.#digest) return void 0;
|
|
3769
|
+
const identity = repairIdentity(candidate);
|
|
3770
|
+
if (this.#table.repairs.some((repair) => repairIdentity(repair) === identity)) {
|
|
3771
|
+
if (this.#storeError) this.#persist(this.#table);
|
|
3772
|
+
return void 0;
|
|
3773
|
+
}
|
|
3774
|
+
if (this.#table.repairs.length >= MAX_CATALOG_REPAIRS) return void 0;
|
|
3775
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3776
|
+
const next = {
|
|
3777
|
+
...this.#table,
|
|
3778
|
+
catalogDigest: this.#digest || this.#table.catalogDigest,
|
|
3779
|
+
repairs: [...this.#table.repairs, candidate],
|
|
3780
|
+
updatedAt: now,
|
|
3781
|
+
createdAt: this.#table.createdAt || now
|
|
3782
|
+
};
|
|
3783
|
+
const saved = this.#persist(next);
|
|
3784
|
+
if (!saved) return candidate;
|
|
3785
|
+
return saved.repairs.some((repair) => repairIdentity(repair) === identity) ? candidate : void 0;
|
|
3786
|
+
}
|
|
3787
|
+
#persist(table) {
|
|
3788
|
+
try {
|
|
3789
|
+
this.#table = saveRepairTable(this.directory, table);
|
|
3790
|
+
this.#storeError = void 0;
|
|
3791
|
+
return this.#table;
|
|
3792
|
+
} catch (error) {
|
|
3793
|
+
this.#table = table;
|
|
3794
|
+
this.#storeError = errorMessage3(error);
|
|
3795
|
+
return void 0;
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
};
|
|
3799
|
+
|
|
3327
3800
|
// src/speculation/eligibility.ts
|
|
3328
3801
|
var TIER_A_SPECULATION_REFS = /* @__PURE__ */ new Set([
|
|
3329
3802
|
"pi.read",
|
|
@@ -3365,11 +3838,11 @@ var isSpeculationEligible = (action, mcpAllowlist) => {
|
|
|
3365
3838
|
};
|
|
3366
3839
|
|
|
3367
3840
|
// src/speculation/freshness.ts
|
|
3368
|
-
import
|
|
3369
|
-
import
|
|
3841
|
+
import fs3 from "node:fs";
|
|
3842
|
+
import path3 from "node:path";
|
|
3370
3843
|
var statSignature = (filePath) => {
|
|
3371
3844
|
try {
|
|
3372
|
-
const stats =
|
|
3845
|
+
const stats = fs3.statSync(filePath);
|
|
3373
3846
|
return { mtimeMs: stats.mtimeMs, size: stats.size };
|
|
3374
3847
|
} catch (error) {
|
|
3375
3848
|
const code = error instanceof Error && "code" in error ? error.code : void 0;
|
|
@@ -3380,7 +3853,7 @@ var signatureEquals = (left, right) => left === "missing" || right === "missing"
|
|
|
3380
3853
|
var readFreshness = (args, cwd) => {
|
|
3381
3854
|
const target = args.path;
|
|
3382
3855
|
if (typeof target !== "string" || target.length === 0) return void 0;
|
|
3383
|
-
const resolved =
|
|
3856
|
+
const resolved = path3.resolve(cwd, target);
|
|
3384
3857
|
const snapshot = statSignature(resolved);
|
|
3385
3858
|
if (snapshot === "error") return void 0;
|
|
3386
3859
|
return () => {
|
|
@@ -3423,23 +3896,24 @@ var FabricSpeculationStore = class _FabricSpeculationStore {
|
|
|
3423
3896
|
bumpEpoch() {
|
|
3424
3897
|
this.#epoch += 1;
|
|
3425
3898
|
}
|
|
3426
|
-
static key(parentToolCallId, ref, preparedArgs) {
|
|
3899
|
+
static key(parentToolCallId, ref, preparedArgs, bindingToken) {
|
|
3427
3900
|
return `${parentToolCallId}
|
|
3428
3901
|
${ref}
|
|
3429
|
-
${stableJsonHash(preparedArgs)}
|
|
3902
|
+
${stableJsonHash(preparedArgs)}
|
|
3903
|
+
${bindingToken}`;
|
|
3430
3904
|
}
|
|
3431
3905
|
/**
|
|
3432
3906
|
* Register and start a speculative invocation. Returns false when at
|
|
3433
3907
|
* capacity; the candidate is dropped silently (a miss costs nothing, the
|
|
3434
3908
|
* real call executes normally later).
|
|
3435
3909
|
*/
|
|
3436
|
-
launch(parentToolCallId, ref, preparedArgs, execute, freshness, replay) {
|
|
3910
|
+
launch(parentToolCallId, ref, preparedArgs, execute, freshness, replay, bindingToken) {
|
|
3437
3911
|
this.#sweepExpired(Date.now());
|
|
3438
3912
|
if (this.#entries.size >= this.#maxEntries || this.#inFlightCount() >= this.#maxConcurrent) {
|
|
3439
3913
|
this.#stats.skipped += 1;
|
|
3440
3914
|
return false;
|
|
3441
3915
|
}
|
|
3442
|
-
const key = _FabricSpeculationStore.key(parentToolCallId, ref, preparedArgs);
|
|
3916
|
+
const key = _FabricSpeculationStore.key(parentToolCallId, ref, preparedArgs, bindingToken);
|
|
3443
3917
|
if (this.#entries.has(key)) {
|
|
3444
3918
|
this.#stats.skipped += 1;
|
|
3445
3919
|
return false;
|
|
@@ -3463,8 +3937,8 @@ ${stableJsonHash(preparedArgs)}`;
|
|
|
3463
3937
|
this.#stats.launched += 1;
|
|
3464
3938
|
return true;
|
|
3465
3939
|
}
|
|
3466
|
-
async tryServe(parentToolCallId, ref, preparedArgs) {
|
|
3467
|
-
const key = _FabricSpeculationStore.key(parentToolCallId, ref, preparedArgs);
|
|
3940
|
+
async tryServe(parentToolCallId, ref, preparedArgs, bindingToken) {
|
|
3941
|
+
const key = _FabricSpeculationStore.key(parentToolCallId, ref, preparedArgs, bindingToken);
|
|
3468
3942
|
const entry = this.#entries.get(key);
|
|
3469
3943
|
if (!entry || entry.parentToolCallId !== parentToolCallId) {
|
|
3470
3944
|
return { hit: false, reason: "absent" };
|
|
@@ -3789,12 +4263,12 @@ var LifecycleDeliveryScheduler = class {
|
|
|
3789
4263
|
|
|
3790
4264
|
// src/core/model-usage.ts
|
|
3791
4265
|
import { readFileSync } from "node:fs";
|
|
3792
|
-
import
|
|
4266
|
+
import path4 from "node:path";
|
|
3793
4267
|
var MODEL_USAGE_FILENAME = "pi-model-sort.json";
|
|
3794
4268
|
var loadModelUsage = (agentDir = resolveAgentDir()) => {
|
|
3795
4269
|
try {
|
|
3796
4270
|
const raw = JSON.parse(
|
|
3797
|
-
readFileSync(
|
|
4271
|
+
readFileSync(path4.join(agentDir, "extensions", MODEL_USAGE_FILENAME), "utf8")
|
|
3798
4272
|
);
|
|
3799
4273
|
const lastUsed = raw?.lastUsed;
|
|
3800
4274
|
if (typeof lastUsed !== "object" || lastUsed === null) return {};
|
|
@@ -4467,10 +4941,9 @@ var AGENTS_ACTION_DESCRIPTORS = [
|
|
|
4467
4941
|
];
|
|
4468
4942
|
|
|
4469
4943
|
// src/residency/client.ts
|
|
4470
|
-
import { randomUUID as
|
|
4471
|
-
import
|
|
4472
|
-
import
|
|
4473
|
-
import path4 from "node:path";
|
|
4944
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
4945
|
+
import fs4 from "node:fs";
|
|
4946
|
+
import path5 from "node:path";
|
|
4474
4947
|
import { fileURLToPath } from "node:url";
|
|
4475
4948
|
var STARTUP_TIMEOUT_MS = 3e4;
|
|
4476
4949
|
var COMMAND_TIMEOUT_MS = 3e4;
|
|
@@ -4482,7 +4955,7 @@ var atomicWrite2 = (filePath, value) => {
|
|
|
4482
4955
|
};
|
|
4483
4956
|
var readJson = (filePath) => {
|
|
4484
4957
|
try {
|
|
4485
|
-
return JSON.parse(
|
|
4958
|
+
return JSON.parse(fs4.readFileSync(filePath, "utf8"));
|
|
4486
4959
|
} catch {
|
|
4487
4960
|
return void 0;
|
|
4488
4961
|
}
|
|
@@ -4490,7 +4963,7 @@ var readJson = (filePath) => {
|
|
|
4490
4963
|
var terminal = (status) => status === "completed" || status === "failed" || status === "stopped" || status === "timed_out";
|
|
4491
4964
|
var samePath = (left, right) => {
|
|
4492
4965
|
try {
|
|
4493
|
-
return
|
|
4966
|
+
return path5.relative(fs4.realpathSync.native(left), fs4.realpathSync.native(right)) === "";
|
|
4494
4967
|
} catch {
|
|
4495
4968
|
return false;
|
|
4496
4969
|
}
|
|
@@ -4519,12 +4992,12 @@ var ResidencyClient = class {
|
|
|
4519
4992
|
constructor(options) {
|
|
4520
4993
|
this.options = options;
|
|
4521
4994
|
this.hostId = residentHostId(options.config.rootId);
|
|
4522
|
-
this.#configPath =
|
|
4523
|
-
this.#ownerPath =
|
|
4524
|
-
this.#errorPath =
|
|
4525
|
-
this.#requestsPath =
|
|
4526
|
-
this.#responsesPath =
|
|
4527
|
-
this.#agentsPath =
|
|
4995
|
+
this.#configPath = path5.join(options.config.residencyRoot, "config.json");
|
|
4996
|
+
this.#ownerPath = path5.join(options.config.residencyRoot, "owner.json");
|
|
4997
|
+
this.#errorPath = path5.join(options.config.residencyRoot, "error.json");
|
|
4998
|
+
this.#requestsPath = path5.join(options.config.residencyRoot, "requests");
|
|
4999
|
+
this.#responsesPath = path5.join(options.config.residencyRoot, "responses");
|
|
5000
|
+
this.#agentsPath = path5.join(options.config.residencyRoot, "agents");
|
|
4528
5001
|
this.#deliveryPrefix = residentDeliveryPrefix(options.config.rootId);
|
|
4529
5002
|
this.#hostPath = options.hostPath ?? fileURLToPath(new URL("./launcher.js", import.meta.url));
|
|
4530
5003
|
}
|
|
@@ -4562,7 +5035,7 @@ var ResidencyClient = class {
|
|
|
4562
5035
|
if (serialized === this.#modelGuidanceJson) return;
|
|
4563
5036
|
this.#modelGuidanceJson = serialized;
|
|
4564
5037
|
this.options.config.modelGuidance = snapshot;
|
|
4565
|
-
if (
|
|
5038
|
+
if (fs4.existsSync(this.options.config.residencyRoot)) {
|
|
4566
5039
|
atomicWrite2(this.#configPath, this.options.config);
|
|
4567
5040
|
}
|
|
4568
5041
|
}
|
|
@@ -4571,7 +5044,7 @@ var ResidencyClient = class {
|
|
|
4571
5044
|
atomicWrite2(this.#configPath, this.options.config);
|
|
4572
5045
|
const existing = this.#liveOwner();
|
|
4573
5046
|
if (existing) return existing;
|
|
4574
|
-
|
|
5047
|
+
fs4.rmSync(this.#errorPath, { force: true });
|
|
4575
5048
|
await spawnDetached(
|
|
4576
5049
|
this.#hostPath,
|
|
4577
5050
|
["--config", this.#configPath],
|
|
@@ -4589,7 +5062,7 @@ var ResidencyClient = class {
|
|
|
4589
5062
|
}
|
|
4590
5063
|
const readIfPresent = (name) => {
|
|
4591
5064
|
try {
|
|
4592
|
-
return
|
|
5065
|
+
return fs4.readFileSync(path5.join(this.options.config.residencyRoot, name), "utf8").trim();
|
|
4593
5066
|
} catch {
|
|
4594
5067
|
return "";
|
|
4595
5068
|
}
|
|
@@ -4616,7 +5089,7 @@ var ResidencyClient = class {
|
|
|
4616
5089
|
{
|
|
4617
5090
|
format: RESIDENT_HOST_FORMAT,
|
|
4618
5091
|
operation: "spawn",
|
|
4619
|
-
requestId:
|
|
5092
|
+
requestId: randomUUID3(),
|
|
4620
5093
|
rootId: this.options.config.rootId,
|
|
4621
5094
|
request: { ...resolvedRequest, residency: "durable" },
|
|
4622
5095
|
createdAt: Date.now()
|
|
@@ -4628,18 +5101,18 @@ var ResidencyClient = class {
|
|
|
4628
5101
|
return response.handle;
|
|
4629
5102
|
}
|
|
4630
5103
|
hasAgent(id) {
|
|
4631
|
-
return AGENT_ID_PATTERN.test(id) &&
|
|
5104
|
+
return AGENT_ID_PATTERN.test(id) && fs4.existsSync(this.#metadataPath(id));
|
|
4632
5105
|
}
|
|
4633
5106
|
statusAgent(id) {
|
|
4634
5107
|
const metadata = this.#metadata(id);
|
|
4635
5108
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
4636
|
-
const record = readJson(
|
|
5109
|
+
const record = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
4637
5110
|
if (!record || record.id !== metadata.id) return structuredClone(metadata.handle);
|
|
4638
5111
|
return {
|
|
4639
5112
|
...record,
|
|
4640
5113
|
cwd: metadata.handle.cwd,
|
|
4641
5114
|
residency: "durable",
|
|
4642
|
-
logFile:
|
|
5115
|
+
logFile: path5.join(metadata.runDirectory, "events.jsonl"),
|
|
4643
5116
|
...metadata.handle.sessionId ? { sessionId: metadata.handle.sessionId } : {},
|
|
4644
5117
|
...metadata.handle.attachCommand ? { attachCommand: metadata.handle.attachCommand } : {}
|
|
4645
5118
|
};
|
|
@@ -4647,7 +5120,7 @@ var ResidencyClient = class {
|
|
|
4647
5120
|
listAgents() {
|
|
4648
5121
|
let entries;
|
|
4649
5122
|
try {
|
|
4650
|
-
entries =
|
|
5123
|
+
entries = fs4.readdirSync(this.#agentsPath);
|
|
4651
5124
|
} catch {
|
|
4652
5125
|
return [];
|
|
4653
5126
|
}
|
|
@@ -4664,7 +5137,7 @@ var ResidencyClient = class {
|
|
|
4664
5137
|
await this.#command({
|
|
4665
5138
|
format: RESIDENT_HOST_FORMAT,
|
|
4666
5139
|
operation: "foreground",
|
|
4667
|
-
requestId:
|
|
5140
|
+
requestId: randomUUID3(),
|
|
4668
5141
|
rootId: this.options.config.rootId,
|
|
4669
5142
|
id,
|
|
4670
5143
|
createdAt: Date.now()
|
|
@@ -4680,9 +5153,9 @@ var ResidencyClient = class {
|
|
|
4680
5153
|
readAgentLog(id, options = {}) {
|
|
4681
5154
|
const metadata = this.#metadata(id);
|
|
4682
5155
|
if (!metadata) throw new Error(`Unknown durable Fabric agent: ${id}`);
|
|
4683
|
-
const logFile =
|
|
5156
|
+
const logFile = path5.join(metadata.runDirectory, "events.jsonl");
|
|
4684
5157
|
const page = readJsonlPage(logFile, Math.max(1, Math.min(options.lines ?? 200, 5e3)), options.before);
|
|
4685
|
-
const status = readJson(
|
|
5158
|
+
const status = readJson(path5.join(metadata.runDirectory, "status.json"));
|
|
4686
5159
|
return {
|
|
4687
5160
|
id,
|
|
4688
5161
|
runDirectory: metadata.runDirectory,
|
|
@@ -4698,7 +5171,7 @@ var ResidencyClient = class {
|
|
|
4698
5171
|
await this.#command({
|
|
4699
5172
|
format: RESIDENT_HOST_FORMAT,
|
|
4700
5173
|
operation: "removeActor",
|
|
4701
|
-
requestId:
|
|
5174
|
+
requestId: randomUUID3(),
|
|
4702
5175
|
rootId: this.options.config.rootId,
|
|
4703
5176
|
id,
|
|
4704
5177
|
createdAt: Date.now()
|
|
@@ -4714,7 +5187,7 @@ var ResidencyClient = class {
|
|
|
4714
5187
|
response = await this.#command({
|
|
4715
5188
|
format: RESIDENT_HOST_FORMAT,
|
|
4716
5189
|
operation: "cleanup",
|
|
4717
|
-
requestId:
|
|
5190
|
+
requestId: randomUUID3(),
|
|
4718
5191
|
rootId: this.options.config.rootId,
|
|
4719
5192
|
id,
|
|
4720
5193
|
deleteBranch,
|
|
@@ -4752,19 +5225,19 @@ var ResidencyClient = class {
|
|
|
4752
5225
|
} else if (deleteBranch) {
|
|
4753
5226
|
throw new Error(`Durable Fabric agent ${metadata.id} has no worktree branch to delete`);
|
|
4754
5227
|
}
|
|
4755
|
-
|
|
4756
|
-
|
|
5228
|
+
fs4.rmSync(metadata.runDirectory, { recursive: true, force: true });
|
|
5229
|
+
fs4.rmSync(this.#metadataPath(metadata.id), { force: true });
|
|
4757
5230
|
return { cleaned: true };
|
|
4758
5231
|
}
|
|
4759
5232
|
async #command(command, signal) {
|
|
4760
|
-
const responsePath =
|
|
4761
|
-
atomicWrite2(
|
|
5233
|
+
const responsePath = path5.join(this.#responsesPath, `${command.requestId}.json`);
|
|
5234
|
+
atomicWrite2(path5.join(this.#requestsPath, `${command.requestId}.json`), command);
|
|
4762
5235
|
const deadline = Date.now() + COMMAND_TIMEOUT_MS;
|
|
4763
5236
|
while (Date.now() < deadline) {
|
|
4764
5237
|
if (signal?.aborted) throw new Error("Fabric residency request was aborted");
|
|
4765
5238
|
const response = readJson(responsePath);
|
|
4766
5239
|
if (response?.format === RESIDENT_HOST_FORMAT && response.requestId === command.requestId) {
|
|
4767
|
-
|
|
5240
|
+
fs4.rmSync(responsePath, { force: true });
|
|
4768
5241
|
if (!response.ok) throw new Error(response.error ?? "Fabric resident host rejected request");
|
|
4769
5242
|
return response;
|
|
4770
5243
|
}
|
|
@@ -4786,15 +5259,15 @@ var ResidencyClient = class {
|
|
|
4786
5259
|
throw new Error(`Timed out publishing durable Fabric ${kind} ${id} from ${this.hostId}`);
|
|
4787
5260
|
}
|
|
4788
5261
|
#metadataPath(id) {
|
|
4789
|
-
return
|
|
5262
|
+
return path5.join(this.#agentsPath, `${id}.json`);
|
|
4790
5263
|
}
|
|
4791
5264
|
#metadata(id) {
|
|
4792
5265
|
if (!AGENT_ID_PATTERN.test(id)) return void 0;
|
|
4793
5266
|
const metadata = readJson(this.#metadataPath(id));
|
|
4794
|
-
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" ||
|
|
5267
|
+
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" || path5.resolve(metadata.runDirectory) !== path5.resolve(this.options.config.residencyRoot, "runs", id)) {
|
|
4795
5268
|
return void 0;
|
|
4796
5269
|
}
|
|
4797
|
-
if (metadata.handle.worktree &&
|
|
5270
|
+
if (metadata.handle.worktree && !isFabricWorktreePath(metadata.handle.worktree, id)) {
|
|
4798
5271
|
return void 0;
|
|
4799
5272
|
}
|
|
4800
5273
|
if (metadata.handle.branch && (!metadata.handle.branch.startsWith("pi-fabric/") || !metadata.handle.branch.endsWith(`-${id.slice(0, 8)}`))) {
|
|
@@ -6098,16 +6571,16 @@ var AgentsProvider = class {
|
|
|
6098
6571
|
};
|
|
6099
6572
|
|
|
6100
6573
|
// src/providers/captured-tools-provider.ts
|
|
6101
|
-
import
|
|
6574
|
+
import path6 from "node:path";
|
|
6102
6575
|
var textFromContent2 = (content) => content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
|
|
6103
6576
|
var sourceLabel = (sourceInfo) => {
|
|
6104
6577
|
if (sourceInfo.path.startsWith("<")) return sourceInfo.source;
|
|
6105
6578
|
const segments = sourceInfo.path.split(/[\\/]/);
|
|
6106
6579
|
const packageSegment = [...segments].reverse().find((segment) => segment.startsWith("pi-"));
|
|
6107
6580
|
if (packageSegment) return packageSegment;
|
|
6108
|
-
const filename =
|
|
6581
|
+
const filename = path6.basename(sourceInfo.path).replace(/\.[^.]+$/, "");
|
|
6109
6582
|
if (filename && filename !== "index") return filename;
|
|
6110
|
-
return
|
|
6583
|
+
return path6.basename(path6.dirname(sourceInfo.path)) || sourceInfo.source;
|
|
6111
6584
|
};
|
|
6112
6585
|
var capturedToolNamespace = (entry) => `extension:${sourceLabel(entry.sourceInfo)}`;
|
|
6113
6586
|
var descriptorFrom = (entry) => ({
|
|
@@ -6484,35 +6957,35 @@ var ComponentsProvider = class {
|
|
|
6484
6957
|
};
|
|
6485
6958
|
|
|
6486
6959
|
// src/providers/mcp-descriptor-cache.ts
|
|
6487
|
-
import
|
|
6960
|
+
import fs5 from "node:fs/promises";
|
|
6488
6961
|
import fsSync from "node:fs";
|
|
6489
|
-
import
|
|
6490
|
-
import
|
|
6962
|
+
import os from "node:os";
|
|
6963
|
+
import path7 from "node:path";
|
|
6491
6964
|
var MCP_DESCRIPTOR_CACHE_VERSION = 1;
|
|
6492
6965
|
var expandHome = (input) => {
|
|
6493
6966
|
if (!input.startsWith("~")) return input;
|
|
6494
|
-
const home =
|
|
6967
|
+
const home = os.homedir();
|
|
6495
6968
|
if (input === "~") return home;
|
|
6496
6969
|
if (input.startsWith("~/") || input.startsWith("~\\")) {
|
|
6497
|
-
return
|
|
6970
|
+
return path7.join(home, input.slice(2));
|
|
6498
6971
|
}
|
|
6499
6972
|
return input;
|
|
6500
6973
|
};
|
|
6501
|
-
var legacyMcporterDir = () =>
|
|
6974
|
+
var legacyMcporterDir = () => path7.join(os.homedir(), ".mcporter");
|
|
6502
6975
|
var mcporterConfigDir = () => {
|
|
6503
6976
|
const raw = process.env.XDG_CONFIG_HOME;
|
|
6504
6977
|
if (raw && raw.trim().length > 0) {
|
|
6505
6978
|
const resolved = expandHome(raw.trim());
|
|
6506
|
-
if (
|
|
6979
|
+
if (path7.isAbsolute(resolved)) return path7.join(resolved, "mcporter");
|
|
6507
6980
|
}
|
|
6508
6981
|
return legacyMcporterDir();
|
|
6509
6982
|
};
|
|
6510
6983
|
var mcporterConfigCandidates = () => {
|
|
6511
6984
|
const base = mcporterConfigDir();
|
|
6512
|
-
const candidates = [
|
|
6985
|
+
const candidates = [path7.join(base, "mcporter.json"), path7.join(base, "mcporter.jsonc")];
|
|
6513
6986
|
const legacy = legacyMcporterDir();
|
|
6514
6987
|
if (base !== legacy) {
|
|
6515
|
-
candidates.push(
|
|
6988
|
+
candidates.push(path7.join(legacy, "mcporter.json"), path7.join(legacy, "mcporter.jsonc"));
|
|
6516
6989
|
}
|
|
6517
6990
|
return candidates;
|
|
6518
6991
|
};
|
|
@@ -6527,12 +7000,12 @@ var pathExists = (filePath) => {
|
|
|
6527
7000
|
var mcpConfigLayerPaths = (rootDir, configPath) => {
|
|
6528
7001
|
const explicitRaw = configPath ?? process.env.MCPORTER_CONFIG;
|
|
6529
7002
|
if (explicitRaw && explicitRaw.trim().length > 0) {
|
|
6530
|
-
return [
|
|
7003
|
+
return [path7.resolve(expandHome(explicitRaw.trim()))];
|
|
6531
7004
|
}
|
|
6532
7005
|
const paths = [];
|
|
6533
7006
|
const home = mcporterConfigCandidates().find(pathExists);
|
|
6534
7007
|
if (home) paths.push(home);
|
|
6535
|
-
const projectPath =
|
|
7008
|
+
const projectPath = path7.resolve(rootDir, "config", "mcporter.json");
|
|
6536
7009
|
if (pathExists(projectPath)) paths.push(projectPath);
|
|
6537
7010
|
return paths;
|
|
6538
7011
|
};
|
|
@@ -6540,7 +7013,7 @@ var statConfigLayers = async (rootDir, configPath) => {
|
|
|
6540
7013
|
const stats = await Promise.all(
|
|
6541
7014
|
mcpConfigLayerPaths(rootDir, configPath).map(async (layerPath) => {
|
|
6542
7015
|
try {
|
|
6543
|
-
const stat2 = await
|
|
7016
|
+
const stat2 = await fs5.stat(layerPath);
|
|
6544
7017
|
return { path: layerPath, mtimeMs: stat2.mtimeMs, size: stat2.size };
|
|
6545
7018
|
} catch {
|
|
6546
7019
|
return void 0;
|
|
@@ -6554,11 +7027,11 @@ var sameConfigLayers = (left, right) => left.length === right.length && left.eve
|
|
|
6554
7027
|
return other !== void 0 && layer.path === other.path && layer.size === other.size && Math.abs(layer.mtimeMs - other.mtimeMs) <= 1;
|
|
6555
7028
|
});
|
|
6556
7029
|
var hashServerDefinition = (definition) => stableJsonHash(definition);
|
|
6557
|
-
var
|
|
7030
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6558
7031
|
var parseCachedServer = (value) => {
|
|
6559
|
-
if (!
|
|
7032
|
+
if (!isRecord2(value)) return void 0;
|
|
6560
7033
|
const tools = Array.isArray(value.tools) ? value.tools.filter(
|
|
6561
|
-
(tool) =>
|
|
7034
|
+
(tool) => isRecord2(tool) && typeof tool.name === "string"
|
|
6562
7035
|
) : void 0;
|
|
6563
7036
|
if (typeof value.definitionHash !== "string" || tools === void 0) return void 0;
|
|
6564
7037
|
return {
|
|
@@ -6571,10 +7044,10 @@ var parseCachedServer = (value) => {
|
|
|
6571
7044
|
};
|
|
6572
7045
|
};
|
|
6573
7046
|
var parseCacheFile = (value) => {
|
|
6574
|
-
if (!
|
|
6575
|
-
if (!Array.isArray(value.layers) || !
|
|
7047
|
+
if (!isRecord2(value) || value.version !== MCP_DESCRIPTOR_CACHE_VERSION) return void 0;
|
|
7048
|
+
if (!Array.isArray(value.layers) || !isRecord2(value.servers)) return void 0;
|
|
6576
7049
|
const layers = value.layers.filter(
|
|
6577
|
-
(layer) =>
|
|
7050
|
+
(layer) => isRecord2(layer) && typeof layer.path === "string" && typeof layer.mtimeMs === "number" && typeof layer.size === "number"
|
|
6578
7051
|
);
|
|
6579
7052
|
return {
|
|
6580
7053
|
version: MCP_DESCRIPTOR_CACHE_VERSION,
|
|
@@ -6590,7 +7063,7 @@ var McpDescriptorCacheStore = class {
|
|
|
6590
7063
|
}
|
|
6591
7064
|
async load() {
|
|
6592
7065
|
try {
|
|
6593
|
-
const raw = await
|
|
7066
|
+
const raw = await fs5.readFile(this.filePath, "utf8");
|
|
6594
7067
|
return parseCacheFile(JSON.parse(raw));
|
|
6595
7068
|
} catch {
|
|
6596
7069
|
return void 0;
|
|
@@ -6599,24 +7072,24 @@ var McpDescriptorCacheStore = class {
|
|
|
6599
7072
|
// Atomic-ish write: temp file then rename, so a concurrent reader either
|
|
6600
7073
|
// sees the previous cache or the next one, never a torn document.
|
|
6601
7074
|
async save(file) {
|
|
6602
|
-
const directory =
|
|
6603
|
-
await
|
|
6604
|
-
const tempPath =
|
|
7075
|
+
const directory = path7.dirname(this.filePath);
|
|
7076
|
+
await fs5.mkdir(directory, { recursive: true });
|
|
7077
|
+
const tempPath = path7.join(
|
|
6605
7078
|
directory,
|
|
6606
7079
|
`.mcp-cache-${process.pid}-${Date.now()}-${tempCounter++}.tmp`
|
|
6607
7080
|
);
|
|
6608
|
-
await
|
|
7081
|
+
await fs5.writeFile(tempPath, JSON.stringify(file, null, 2));
|
|
6609
7082
|
try {
|
|
6610
|
-
await
|
|
7083
|
+
await fs5.rename(tempPath, this.filePath);
|
|
6611
7084
|
} catch (error) {
|
|
6612
|
-
await
|
|
7085
|
+
await fs5.rm(tempPath, { force: true }).catch(() => void 0);
|
|
6613
7086
|
throw error;
|
|
6614
7087
|
}
|
|
6615
7088
|
}
|
|
6616
7089
|
};
|
|
6617
7090
|
|
|
6618
7091
|
// src/providers/mcp-provider.ts
|
|
6619
|
-
import
|
|
7092
|
+
import path8 from "node:path";
|
|
6620
7093
|
var TOOL_METADATA_TTL_MS = 6e4;
|
|
6621
7094
|
var REVALIDATE_CONCURRENCY = 3;
|
|
6622
7095
|
var REVALIDATE_SERVER_TIMEOUT_MS = 2e4;
|
|
@@ -7248,7 +7721,7 @@ var McpProvider = class {
|
|
|
7248
7721
|
kind: "stdio",
|
|
7249
7722
|
command: args.command,
|
|
7250
7723
|
args: commandArgs,
|
|
7251
|
-
cwd:
|
|
7724
|
+
cwd: path8.resolve(this.cwd, typeof args.cwd === "string" ? args.cwd : ".")
|
|
7252
7725
|
},
|
|
7253
7726
|
...env ? { env } : {}
|
|
7254
7727
|
};
|
|
@@ -7615,7 +8088,7 @@ var MeshProvider = class {
|
|
|
7615
8088
|
|
|
7616
8089
|
// src/providers/pi-tools-provider.ts
|
|
7617
8090
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
7618
|
-
import
|
|
8091
|
+
import path11 from "node:path";
|
|
7619
8092
|
import {
|
|
7620
8093
|
createBashToolDefinition as createBashToolDefinition2,
|
|
7621
8094
|
createEditToolDefinition,
|
|
@@ -7625,9 +8098,102 @@ import {
|
|
|
7625
8098
|
createReadToolDefinition
|
|
7626
8099
|
} from "@earendil-works/pi-coding-agent";
|
|
7627
8100
|
|
|
8101
|
+
// src/agents/bash-worktree-add.ts
|
|
8102
|
+
import fs6 from "node:fs";
|
|
8103
|
+
import path9 from "node:path";
|
|
8104
|
+
var BARE_SAFE = /^[A-Za-z0-9_./:@%+=,-]+$/;
|
|
8105
|
+
var parseGitWorktreeAdd = (command) => {
|
|
8106
|
+
const trimmed = command.trim();
|
|
8107
|
+
if (!trimmed || /[|&;()\n]/.test(trimmed)) return void 0;
|
|
8108
|
+
const tokens = trimmed.split(/\s+/);
|
|
8109
|
+
if (tokens[0] !== "git") return void 0;
|
|
8110
|
+
if (tokens.some((token) => !BARE_SAFE.test(token))) return void 0;
|
|
8111
|
+
let index = 1;
|
|
8112
|
+
let gitCwd;
|
|
8113
|
+
if (tokens[index] === "-C") {
|
|
8114
|
+
gitCwd = tokens[index + 1];
|
|
8115
|
+
if (!gitCwd) return void 0;
|
|
8116
|
+
index += 2;
|
|
8117
|
+
}
|
|
8118
|
+
if (tokens[index] !== "worktree" || tokens[index + 1] !== "add") return void 0;
|
|
8119
|
+
index += 2;
|
|
8120
|
+
let branch;
|
|
8121
|
+
let detach = false;
|
|
8122
|
+
let quiet = false;
|
|
8123
|
+
let flagsEnded = false;
|
|
8124
|
+
const positionals = [];
|
|
8125
|
+
while (index < tokens.length) {
|
|
8126
|
+
const token = tokens[index++];
|
|
8127
|
+
if (token === void 0) break;
|
|
8128
|
+
if (!flagsEnded && token === "--") {
|
|
8129
|
+
flagsEnded = true;
|
|
8130
|
+
continue;
|
|
8131
|
+
}
|
|
8132
|
+
if (!flagsEnded && (token === "-b" || token === "-B")) {
|
|
8133
|
+
if (branch) return void 0;
|
|
8134
|
+
const name = tokens[index++];
|
|
8135
|
+
if (!name) return void 0;
|
|
8136
|
+
branch = { flag: token, name };
|
|
8137
|
+
continue;
|
|
8138
|
+
}
|
|
8139
|
+
if (!flagsEnded && (token === "--detach" || token === "-d")) {
|
|
8140
|
+
detach = true;
|
|
8141
|
+
continue;
|
|
8142
|
+
}
|
|
8143
|
+
if (!flagsEnded && (token === "-q" || token === "--quiet")) {
|
|
8144
|
+
quiet = true;
|
|
8145
|
+
continue;
|
|
8146
|
+
}
|
|
8147
|
+
if (!flagsEnded && token.startsWith("-")) return void 0;
|
|
8148
|
+
positionals.push(token);
|
|
8149
|
+
}
|
|
8150
|
+
if (detach && branch) return void 0;
|
|
8151
|
+
if (positionals.length < 1 || positionals.length > 2) return void 0;
|
|
8152
|
+
return {
|
|
8153
|
+
...gitCwd ? { gitCwd } : {},
|
|
8154
|
+
...branch ? { branch } : {},
|
|
8155
|
+
detach,
|
|
8156
|
+
quiet,
|
|
8157
|
+
dest: positionals[0],
|
|
8158
|
+
...positionals[1] ? { startPoint: positionals[1] } : {}
|
|
8159
|
+
};
|
|
8160
|
+
};
|
|
8161
|
+
var tryExecuteGitWorktreeAdd = async (args, sessionCwd) => {
|
|
8162
|
+
const command = args.command;
|
|
8163
|
+
if (typeof command !== "string") return void 0;
|
|
8164
|
+
const parsed = parseGitWorktreeAdd(command);
|
|
8165
|
+
if (!parsed) return void 0;
|
|
8166
|
+
const gitCwd = parsed.gitCwd ? path9.resolve(sessionCwd, parsed.gitCwd) : typeof args.cwd === "string" ? args.cwd : sessionCwd;
|
|
8167
|
+
const dest = path9.resolve(gitCwd, parsed.dest);
|
|
8168
|
+
let gitRoot;
|
|
8169
|
+
try {
|
|
8170
|
+
const root = await executeFile("git", ["rev-parse", "--show-toplevel"], {
|
|
8171
|
+
cwd: gitCwd,
|
|
8172
|
+
timeoutMs: 1e4
|
|
8173
|
+
});
|
|
8174
|
+
const output = root.stdout.trim();
|
|
8175
|
+
if (!output) return void 0;
|
|
8176
|
+
gitRoot = fs6.realpathSync(output);
|
|
8177
|
+
} catch {
|
|
8178
|
+
return void 0;
|
|
8179
|
+
}
|
|
8180
|
+
const result = await addCloneFirstWorktree({
|
|
8181
|
+
gitRoot,
|
|
8182
|
+
dest,
|
|
8183
|
+
...parsed.branch ? { branch: parsed.branch } : {},
|
|
8184
|
+
detach: parsed.detach,
|
|
8185
|
+
quiet: parsed.quiet,
|
|
8186
|
+
...parsed.startPoint ? { startPoint: parsed.startPoint } : {}
|
|
8187
|
+
});
|
|
8188
|
+
return {
|
|
8189
|
+
content: [{ type: "text", text: result.message || `Preparing worktree (${dest})` }],
|
|
8190
|
+
details: { exitCode: 0, cloned: result.cloned }
|
|
8191
|
+
};
|
|
8192
|
+
};
|
|
8193
|
+
|
|
7628
8194
|
// src/providers/pi-bash-cwd.ts
|
|
7629
8195
|
import { accessSync, constants, statSync } from "node:fs";
|
|
7630
|
-
import
|
|
8196
|
+
import path10 from "node:path";
|
|
7631
8197
|
import { createBashToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
7632
8198
|
import { Type as Type2 } from "typebox";
|
|
7633
8199
|
var PI_BASH_CWD_KEY = "cwd";
|
|
@@ -7637,7 +8203,7 @@ var resolvePiBashCwd = (sessionCwd, requested) => {
|
|
|
7637
8203
|
`Invalid pi.bash cwd ${JSON.stringify(requested)}: path must be a non-empty string`
|
|
7638
8204
|
);
|
|
7639
8205
|
}
|
|
7640
|
-
const resolved =
|
|
8206
|
+
const resolved = path10.isAbsolute(requested) ? path10.resolve(requested) : path10.resolve(sessionCwd, requested);
|
|
7641
8207
|
try {
|
|
7642
8208
|
if (!statSync(resolved).isDirectory()) throw new Error("path is not a directory");
|
|
7643
8209
|
accessSync(resolved, constants.R_OK | constants.X_OK);
|
|
@@ -7653,9 +8219,9 @@ var CWD_PROPERTY = Type2.Optional(
|
|
|
7653
8219
|
description: "Execution directory for this command; relative paths resolve from the session cwd."
|
|
7654
8220
|
})
|
|
7655
8221
|
);
|
|
7656
|
-
var
|
|
8222
|
+
var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7657
8223
|
var withBashCwdSchema = (schema) => {
|
|
7658
|
-
if (!
|
|
8224
|
+
if (!isRecord3(schema) || !isRecord3(schema.properties)) return schema;
|
|
7659
8225
|
if (Object.hasOwn(schema.properties, PI_BASH_CWD_KEY)) return schema;
|
|
7660
8226
|
const { type: _type, properties, required, ...rest } = schema;
|
|
7661
8227
|
return Type2.Object(
|
|
@@ -7736,14 +8302,14 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
7736
8302
|
return {
|
|
7737
8303
|
...original,
|
|
7738
8304
|
async execute(_toolCallId, params, signal) {
|
|
7739
|
-
const { path:
|
|
7740
|
-
const absolutePath = resolvePreviewPath(
|
|
8305
|
+
const { path: path17, content } = params;
|
|
8306
|
+
const absolutePath = resolvePreviewPath(path17, cwd);
|
|
7741
8307
|
return withFileMutationQueue(absolutePath, async () => {
|
|
7742
8308
|
const throwIfAborted2 = () => {
|
|
7743
8309
|
if (signal?.aborted) throw new Error("Operation aborted");
|
|
7744
8310
|
};
|
|
7745
8311
|
throwIfAborted2();
|
|
7746
|
-
const before = await readExistingFileForPreview(
|
|
8312
|
+
const before = await readExistingFileForPreview(path17, cwd, content);
|
|
7747
8313
|
throwIfAborted2();
|
|
7748
8314
|
await mkdir(dirname(absolutePath), { recursive: true });
|
|
7749
8315
|
throwIfAborted2();
|
|
@@ -7753,7 +8319,7 @@ var createPreviewWriteToolDefinition = (cwd) => {
|
|
|
7753
8319
|
content: [
|
|
7754
8320
|
{
|
|
7755
8321
|
type: "text",
|
|
7756
|
-
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${
|
|
8322
|
+
text: `Successfully wrote ${Buffer.byteLength(content, "utf8")} bytes to ${path17}`
|
|
7757
8323
|
}
|
|
7758
8324
|
],
|
|
7759
8325
|
details: { codePreviewBeforeWrite: before }
|
|
@@ -7787,7 +8353,7 @@ var expandReplaceAllEdit = (cwd, args, allForEveryEdit) => {
|
|
|
7787
8353
|
}
|
|
7788
8354
|
return { oldText, newText, all: allForEveryEdit || record.all === true };
|
|
7789
8355
|
});
|
|
7790
|
-
const resolvedPath =
|
|
8356
|
+
const resolvedPath = path11.resolve(
|
|
7791
8357
|
cwd,
|
|
7792
8358
|
filePath.startsWith("@") ? filePath.slice(1) : filePath
|
|
7793
8359
|
);
|
|
@@ -7929,6 +8495,13 @@ var PiToolsProvider = class {
|
|
|
7929
8495
|
async invoke(actionName, args, context) {
|
|
7930
8496
|
if (!(actionName in this.#tools)) throw new Error(`Unknown Pi tool: ${actionName}`);
|
|
7931
8497
|
const name = actionName;
|
|
8498
|
+
if (name === "bash") {
|
|
8499
|
+
const intercepted = await tryExecuteGitWorktreeAdd(args, this.#cwd);
|
|
8500
|
+
if (intercepted) {
|
|
8501
|
+
this.#attachPreview(name, intercepted, args, context);
|
|
8502
|
+
return this.#normalizeResult(name, intercepted, args);
|
|
8503
|
+
}
|
|
8504
|
+
}
|
|
7932
8505
|
if (this.#catalog?.get(name)) {
|
|
7933
8506
|
const result = await this.#capturedTools.invoke(name, args, context);
|
|
7934
8507
|
this.#attachReadMedia(name, result, context);
|
|
@@ -8148,9 +8721,9 @@ var PiToolsProvider = class {
|
|
|
8148
8721
|
|
|
8149
8722
|
// src/schema/controller.ts
|
|
8150
8723
|
import { spawn } from "node:child_process";
|
|
8151
|
-
import { createHash as createHash3, randomBytes, randomUUID as
|
|
8152
|
-
import
|
|
8153
|
-
import
|
|
8724
|
+
import { createHash as createHash3, randomBytes, randomUUID as randomUUID4 } from "node:crypto";
|
|
8725
|
+
import fs8 from "node:fs";
|
|
8726
|
+
import path13 from "node:path";
|
|
8154
8727
|
|
|
8155
8728
|
// src/schema/types.ts
|
|
8156
8729
|
var stateBinding = (head) => head ? { transitionId: head.transitionId, version: head.version, to: head.to } : null;
|
|
@@ -8158,8 +8731,8 @@ var stateBinding = (head) => head ? { transitionId: head.transitionId, version:
|
|
|
8158
8731
|
// src/schema/workspace.ts
|
|
8159
8732
|
import { execFileSync } from "node:child_process";
|
|
8160
8733
|
import { createHash as createHash2 } from "node:crypto";
|
|
8161
|
-
import
|
|
8162
|
-
import
|
|
8734
|
+
import fs7 from "node:fs";
|
|
8735
|
+
import path12 from "node:path";
|
|
8163
8736
|
var SNAPSHOT_MAX_FILES = 2e4;
|
|
8164
8737
|
var SNAPSHOT_MAX_BYTES = 512 * 1024 * 1024;
|
|
8165
8738
|
var FALLBACK_SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -8177,16 +8750,16 @@ var git = (cwd, args) => execFileSync("git", ["-C", cwd, ...args], {
|
|
|
8177
8750
|
stdio: ["ignore", "pipe", "ignore"]
|
|
8178
8751
|
});
|
|
8179
8752
|
var nulPaths = (buffer) => buffer.toString("utf8").split("\0").filter((item) => item.length > 0);
|
|
8180
|
-
var normalizeRelative = (value) => value.split(
|
|
8753
|
+
var normalizeRelative = (value) => value.split(path12.sep).join("/");
|
|
8181
8754
|
var isInside = (root, candidate) => {
|
|
8182
|
-
const relative =
|
|
8183
|
-
return relative === "" || !
|
|
8755
|
+
const relative = path12.relative(root, candidate);
|
|
8756
|
+
return relative === "" || !path12.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path12.sep}`);
|
|
8184
8757
|
};
|
|
8185
8758
|
var excluded = (absolute, exclusions) => exclusions.some((root) => isInside(root, absolute));
|
|
8186
8759
|
var entryDigest = (absolute) => {
|
|
8187
8760
|
let stat2;
|
|
8188
8761
|
try {
|
|
8189
|
-
stat2 =
|
|
8762
|
+
stat2 = fs7.lstatSync(absolute);
|
|
8190
8763
|
} catch (error) {
|
|
8191
8764
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
8192
8765
|
return { marker: "absent", bytes: 0 };
|
|
@@ -8194,24 +8767,24 @@ var entryDigest = (absolute) => {
|
|
|
8194
8767
|
throw error;
|
|
8195
8768
|
}
|
|
8196
8769
|
if (stat2.isSymbolicLink()) {
|
|
8197
|
-
return { marker: `symlink:${digest(
|
|
8770
|
+
return { marker: `symlink:${digest(fs7.readlinkSync(absolute))}`, bytes: 0 };
|
|
8198
8771
|
}
|
|
8199
8772
|
if (!stat2.isFile()) {
|
|
8200
8773
|
throw new Error(`Schema workspace snapshot does not support non-file entry: ${absolute}`);
|
|
8201
8774
|
}
|
|
8202
|
-
return { marker: `file:${stat2.mode & 511}:${digest(
|
|
8775
|
+
return { marker: `file:${stat2.mode & 511}:${digest(fs7.readFileSync(absolute))}`, bytes: stat2.size };
|
|
8203
8776
|
};
|
|
8204
8777
|
var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
8205
8778
|
const entries = {};
|
|
8206
8779
|
let bytes = 0;
|
|
8207
8780
|
const unique = [...new Set(paths)].sort((left, right) => left.localeCompare(right));
|
|
8208
8781
|
for (const relativeInput of unique) {
|
|
8209
|
-
const absolute =
|
|
8782
|
+
const absolute = path12.resolve(cwd, relativeInput);
|
|
8210
8783
|
if (!isInside(cwd, absolute) || excluded(absolute, exclusions)) continue;
|
|
8211
8784
|
if (Object.keys(entries).length >= SNAPSHOT_MAX_FILES) {
|
|
8212
8785
|
throw new Error(`Schema workspace snapshot exceeds ${SNAPSHOT_MAX_FILES} files`);
|
|
8213
8786
|
}
|
|
8214
|
-
const relative = normalizeRelative(
|
|
8787
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8215
8788
|
const entry = entryDigest(absolute);
|
|
8216
8789
|
bytes += entry.bytes;
|
|
8217
8790
|
if (bytes > SNAPSHOT_MAX_BYTES) {
|
|
@@ -8237,12 +8810,12 @@ var buildSnapshot = (cwd, paths, metadata, exclusions) => {
|
|
|
8237
8810
|
var fallbackPaths = (cwd, exclusions) => {
|
|
8238
8811
|
const paths = [];
|
|
8239
8812
|
const visit = (directory) => {
|
|
8240
|
-
const entries =
|
|
8813
|
+
const entries = fs7.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
|
|
8241
8814
|
for (const entry of entries) {
|
|
8242
8815
|
if (FALLBACK_SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
8243
|
-
const absolute =
|
|
8816
|
+
const absolute = path12.join(directory, entry.name);
|
|
8244
8817
|
if (excluded(absolute, exclusions)) continue;
|
|
8245
|
-
const relative = normalizeRelative(
|
|
8818
|
+
const relative = normalizeRelative(path12.relative(cwd, absolute));
|
|
8246
8819
|
if (entry.isDirectory()) visit(absolute);
|
|
8247
8820
|
else paths.push(relative);
|
|
8248
8821
|
if (paths.length > SNAPSHOT_MAX_FILES) {
|
|
@@ -8254,11 +8827,11 @@ var fallbackPaths = (cwd, exclusions) => {
|
|
|
8254
8827
|
return paths;
|
|
8255
8828
|
};
|
|
8256
8829
|
var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
8257
|
-
const cwd =
|
|
8830
|
+
const cwd = fs7.realpathSync(cwdInput);
|
|
8258
8831
|
const exclusions = excludedRoots.map((root) => {
|
|
8259
|
-
const absolute =
|
|
8832
|
+
const absolute = path12.resolve(root);
|
|
8260
8833
|
try {
|
|
8261
|
-
return
|
|
8834
|
+
return fs7.realpathSync(absolute);
|
|
8262
8835
|
} catch {
|
|
8263
8836
|
return absolute;
|
|
8264
8837
|
}
|
|
@@ -8294,29 +8867,29 @@ var snapshotWorkspace = (cwdInput, excludedRoots = []) => {
|
|
|
8294
8867
|
);
|
|
8295
8868
|
};
|
|
8296
8869
|
var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
8297
|
-
if (!requestedPath.trim() ||
|
|
8870
|
+
if (!requestedPath.trim() || path12.isAbsolute(requestedPath)) {
|
|
8298
8871
|
throw new Error(`Schema paths must be non-empty project-relative paths: ${requestedPath}`);
|
|
8299
8872
|
}
|
|
8300
|
-
const cwd =
|
|
8301
|
-
const absolute =
|
|
8873
|
+
const cwd = fs7.realpathSync(cwdInput);
|
|
8874
|
+
const absolute = path12.resolve(cwd, requestedPath);
|
|
8302
8875
|
if (!isInside(cwd, absolute) || absolute === cwd) {
|
|
8303
8876
|
throw new Error(`Schema path escapes the project workspace: ${requestedPath}`);
|
|
8304
8877
|
}
|
|
8305
|
-
const relativeParts =
|
|
8878
|
+
const relativeParts = path12.relative(cwd, absolute).split(path12.sep);
|
|
8306
8879
|
let cursor = cwd;
|
|
8307
8880
|
for (let index = 0; index < relativeParts.length; index++) {
|
|
8308
|
-
cursor =
|
|
8881
|
+
cursor = path12.join(cursor, relativeParts[index]);
|
|
8309
8882
|
let stat2;
|
|
8310
8883
|
try {
|
|
8311
|
-
stat2 =
|
|
8884
|
+
stat2 = fs7.lstatSync(cursor);
|
|
8312
8885
|
} catch (error) {
|
|
8313
8886
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
8314
8887
|
if (index !== relativeParts.length - 1 || !options.allowAbsent) {
|
|
8315
8888
|
throw new Error(`Schema path does not exist: ${requestedPath}`);
|
|
8316
8889
|
}
|
|
8317
|
-
const parentReal =
|
|
8890
|
+
const parentReal = fs7.realpathSync(path12.dirname(cursor));
|
|
8318
8891
|
if (!isInside(cwd, parentReal)) throw new Error(`Schema path parent escapes the workspace: ${requestedPath}`);
|
|
8319
|
-
return { absolute, relative: normalizeRelative(
|
|
8892
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: false };
|
|
8320
8893
|
}
|
|
8321
8894
|
throw error;
|
|
8322
8895
|
}
|
|
@@ -8328,9 +8901,9 @@ var resolveWorkspaceFile = (cwdInput, requestedPath, options) => {
|
|
|
8328
8901
|
throw new Error(`Schema transaction paths must name regular files: ${requestedPath}`);
|
|
8329
8902
|
}
|
|
8330
8903
|
}
|
|
8331
|
-
return { absolute, relative: normalizeRelative(
|
|
8904
|
+
return { absolute, relative: normalizeRelative(path12.relative(cwd, absolute)), exists: true };
|
|
8332
8905
|
};
|
|
8333
|
-
var sha256File = (absolute) => `sha256:${digest(
|
|
8906
|
+
var sha256File = (absolute) => `sha256:${digest(fs7.readFileSync(absolute))}`;
|
|
8334
8907
|
|
|
8335
8908
|
// src/schema/controller.ts
|
|
8336
8909
|
var SCHEMA_TOPIC = "fabric.schema";
|
|
@@ -8340,7 +8913,7 @@ var CERTIFICATE_PREFIX = "schema/certificate/";
|
|
|
8340
8913
|
var OUTPUT_LIMIT = 64 * 1024;
|
|
8341
8914
|
var hashToken = (token) => createHash3("sha256").update(token).digest("hex");
|
|
8342
8915
|
var sameBinding = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
8343
|
-
var
|
|
8916
|
+
var errorMessage4 = (error) => error instanceof Error ? error.message : String(error);
|
|
8344
8917
|
var atomicJsonWrite = (filePath, value) => {
|
|
8345
8918
|
writeJsonAtomic(filePath, value, { newline: true });
|
|
8346
8919
|
};
|
|
@@ -8378,9 +8951,9 @@ var SchemaController = class {
|
|
|
8378
8951
|
this.mesh = mesh;
|
|
8379
8952
|
this.identity = identity;
|
|
8380
8953
|
this.state = state;
|
|
8381
|
-
this.cwd =
|
|
8382
|
-
this.#journalRoot =
|
|
8383
|
-
this.#lockPath =
|
|
8954
|
+
this.cwd = fs8.realpathSync(cwd);
|
|
8955
|
+
this.#journalRoot = path13.join(mesh.root, "schema-transactions");
|
|
8956
|
+
this.#lockPath = path13.join(this.#journalRoot, ".commit.lock");
|
|
8384
8957
|
this.#recoverJournals();
|
|
8385
8958
|
}
|
|
8386
8959
|
#activeHypotheses = /* @__PURE__ */ new Map();
|
|
@@ -8436,7 +9009,7 @@ var SchemaController = class {
|
|
|
8436
9009
|
const generation = this.#generation();
|
|
8437
9010
|
const now = Date.now();
|
|
8438
9011
|
const record = {
|
|
8439
|
-
id:
|
|
9012
|
+
id: randomUUID4(),
|
|
8440
9013
|
label: input.label,
|
|
8441
9014
|
summary: input.summary,
|
|
8442
9015
|
evidence: input.evidence,
|
|
@@ -8476,7 +9049,7 @@ var SchemaController = class {
|
|
|
8476
9049
|
try {
|
|
8477
9050
|
before = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
8478
9051
|
} catch (error) {
|
|
8479
|
-
return this.#failedVerification(record, [], `workspace snapshot failed: ${
|
|
9052
|
+
return this.#failedVerification(record, [], `workspace snapshot failed: ${errorMessage4(error)}`);
|
|
8480
9053
|
}
|
|
8481
9054
|
const currentState = stateBinding(this.state?.getHead() ?? null);
|
|
8482
9055
|
if (!sameBinding(record.state, currentState)) {
|
|
@@ -8493,7 +9066,7 @@ var SchemaController = class {
|
|
|
8493
9066
|
try {
|
|
8494
9067
|
after = snapshotWorkspace(this.cwd, [this.mesh.root]);
|
|
8495
9068
|
} catch (error) {
|
|
8496
|
-
return this.#failedVerification(record, results, `post-evidence snapshot failed: ${
|
|
9069
|
+
return this.#failedVerification(record, results, `post-evidence snapshot failed: ${errorMessage4(error)}`);
|
|
8497
9070
|
}
|
|
8498
9071
|
const allConfirmed = results.length > 0 && results.every((result) => result.status === "confirmed");
|
|
8499
9072
|
if (!allConfirmed || before.fingerprint !== after.fingerprint) {
|
|
@@ -8578,8 +9151,8 @@ var SchemaController = class {
|
|
|
8578
9151
|
}
|
|
8579
9152
|
this.#assertPayloadBound(input);
|
|
8580
9153
|
const release = this.#acquireCommitLock();
|
|
8581
|
-
const transactionId =
|
|
8582
|
-
const journalPath =
|
|
9154
|
+
const transactionId = randomUUID4();
|
|
9155
|
+
const journalPath = path13.join(this.#journalRoot, `${transactionId}.json`);
|
|
8583
9156
|
let journal;
|
|
8584
9157
|
let consumed = false;
|
|
8585
9158
|
let committed = false;
|
|
@@ -8619,14 +9192,14 @@ var SchemaController = class {
|
|
|
8619
9192
|
before.push({ path: resolved.relative, absolute: resolved.absolute, existed: false });
|
|
8620
9193
|
continue;
|
|
8621
9194
|
}
|
|
8622
|
-
const content =
|
|
9195
|
+
const content = fs8.readFileSync(resolved.absolute);
|
|
8623
9196
|
beforeBytes += content.byteLength;
|
|
8624
9197
|
before.push({
|
|
8625
9198
|
path: resolved.relative,
|
|
8626
9199
|
absolute: resolved.absolute,
|
|
8627
9200
|
existed: true,
|
|
8628
9201
|
content: content.toString("base64"),
|
|
8629
|
-
mode:
|
|
9202
|
+
mode: fs8.statSync(resolved.absolute).mode & 511
|
|
8630
9203
|
});
|
|
8631
9204
|
}
|
|
8632
9205
|
if (payloadBytes + beforeBytes > this.config.maxBytes) {
|
|
@@ -8690,7 +9263,7 @@ var SchemaController = class {
|
|
|
8690
9263
|
this.cwd
|
|
8691
9264
|
) : null;
|
|
8692
9265
|
} catch (error) {
|
|
8693
|
-
stateTransition = { error:
|
|
9266
|
+
stateTransition = { error: errorMessage4(error) };
|
|
8694
9267
|
}
|
|
8695
9268
|
try {
|
|
8696
9269
|
await this.mesh.put({
|
|
@@ -8736,18 +9309,18 @@ var SchemaController = class {
|
|
|
8736
9309
|
const outcome = rollbackError ? "quarantined" : "rolled_back";
|
|
8737
9310
|
if (journal) {
|
|
8738
9311
|
journal.status = outcome;
|
|
8739
|
-
journal.error = rollbackError ? `${
|
|
9312
|
+
journal.error = rollbackError ? `${errorMessage4(error)}; rollback failed: ${rollbackError}` : errorMessage4(error);
|
|
8740
9313
|
try {
|
|
8741
9314
|
atomicJsonWrite(journalPath, journal);
|
|
8742
9315
|
} catch {
|
|
8743
9316
|
}
|
|
8744
9317
|
}
|
|
8745
|
-
await this.#recordFailedOutcome(outcome, transactionId,
|
|
9318
|
+
await this.#recordFailedOutcome(outcome, transactionId, errorMessage4(error), rollbackError);
|
|
8746
9319
|
context.update(`Schema transaction ${outcome}`);
|
|
8747
9320
|
return {
|
|
8748
9321
|
outcome,
|
|
8749
9322
|
transactionId,
|
|
8750
|
-
error:
|
|
9323
|
+
error: errorMessage4(error),
|
|
8751
9324
|
...rollbackError ? { rollbackError } : {}
|
|
8752
9325
|
};
|
|
8753
9326
|
} finally {
|
|
@@ -8870,7 +9443,7 @@ var SchemaController = class {
|
|
|
8870
9443
|
observedSha256: sha256File(resolved.absolute)
|
|
8871
9444
|
});
|
|
8872
9445
|
} else if (item.kind === "file_contains") {
|
|
8873
|
-
const confirmed =
|
|
9446
|
+
const confirmed = fs8.readFileSync(resolved.absolute, "utf8").includes(item.literal);
|
|
8874
9447
|
results.push({
|
|
8875
9448
|
evidence: item,
|
|
8876
9449
|
status: confirmed ? "confirmed" : "nonconfirmed",
|
|
@@ -8887,7 +9460,7 @@ var SchemaController = class {
|
|
|
8887
9460
|
});
|
|
8888
9461
|
}
|
|
8889
9462
|
} catch (error) {
|
|
8890
|
-
results.push({ evidence: item, status: "error", detail:
|
|
9463
|
+
results.push({ evidence: item, status: "error", detail: errorMessage4(error) });
|
|
8891
9464
|
}
|
|
8892
9465
|
}
|
|
8893
9466
|
return results;
|
|
@@ -8911,7 +9484,7 @@ var SchemaController = class {
|
|
|
8911
9484
|
...signal ? { signal } : {}
|
|
8912
9485
|
});
|
|
8913
9486
|
} catch (error) {
|
|
8914
|
-
resolve2({ evidence, status: "error", detail:
|
|
9487
|
+
resolve2({ evidence, status: "error", detail: errorMessage4(error), exitCode: null });
|
|
8915
9488
|
return;
|
|
8916
9489
|
}
|
|
8917
9490
|
const append = (chunk) => {
|
|
@@ -8941,22 +9514,22 @@ var SchemaController = class {
|
|
|
8941
9514
|
throw new Error(`Schema precondition SHA-256 mismatch: ${operation.path}`);
|
|
8942
9515
|
}
|
|
8943
9516
|
}
|
|
8944
|
-
|
|
9517
|
+
fs8.writeFileSync(resolved.absolute, operation.content, "utf8");
|
|
8945
9518
|
return;
|
|
8946
9519
|
}
|
|
8947
9520
|
if (sha256File(resolved.absolute) !== operation.expectedSha256) {
|
|
8948
9521
|
throw new Error(`Schema precondition SHA-256 mismatch: ${operation.path}`);
|
|
8949
9522
|
}
|
|
8950
9523
|
if (operation.kind === "delete") {
|
|
8951
|
-
|
|
9524
|
+
fs8.unlinkSync(resolved.absolute);
|
|
8952
9525
|
return;
|
|
8953
9526
|
}
|
|
8954
|
-
const content =
|
|
9527
|
+
const content = fs8.readFileSync(resolved.absolute, "utf8");
|
|
8955
9528
|
const first = content.indexOf(operation.oldText);
|
|
8956
9529
|
if (first < 0 || content.indexOf(operation.oldText, first + operation.oldText.length) >= 0) {
|
|
8957
9530
|
throw new Error(`Schema edit requires oldText to occur exactly once: ${operation.path}`);
|
|
8958
9531
|
}
|
|
8959
|
-
|
|
9532
|
+
fs8.writeFileSync(resolved.absolute, `${content.slice(0, first)}${operation.newText}${content.slice(first + operation.oldText.length)}`, "utf8");
|
|
8960
9533
|
}
|
|
8961
9534
|
#assertNoOutsideDrift(before, after, declared) {
|
|
8962
9535
|
if (before.git !== after.git || before.head !== after.head || before.indexDigest !== after.indexDigest) {
|
|
@@ -8976,13 +9549,13 @@ var SchemaController = class {
|
|
|
8976
9549
|
try {
|
|
8977
9550
|
const resolved = resolveWorkspaceFile(this.cwd, image.path, { allowAbsent: true });
|
|
8978
9551
|
if (!image.existed) {
|
|
8979
|
-
if (resolved.exists)
|
|
9552
|
+
if (resolved.exists) fs8.unlinkSync(resolved.absolute);
|
|
8980
9553
|
} else {
|
|
8981
|
-
|
|
8982
|
-
if (image.mode !== void 0)
|
|
9554
|
+
fs8.writeFileSync(resolved.absolute, Buffer.from(image.content ?? "", "base64"));
|
|
9555
|
+
if (image.mode !== void 0) fs8.chmodSync(resolved.absolute, image.mode);
|
|
8983
9556
|
}
|
|
8984
9557
|
} catch (error) {
|
|
8985
|
-
errors.push(`${image.path}: ${
|
|
9558
|
+
errors.push(`${image.path}: ${errorMessage4(error)}`);
|
|
8986
9559
|
}
|
|
8987
9560
|
}
|
|
8988
9561
|
return errors.length > 0 ? errors.join("; ") : void 0;
|
|
@@ -9027,25 +9600,25 @@ var SchemaController = class {
|
|
|
9027
9600
|
return this.mesh.publish({ topic: SCHEMA_TOPIC, kind, from: this.identity, data });
|
|
9028
9601
|
}
|
|
9029
9602
|
#acquireCommitLock() {
|
|
9030
|
-
|
|
9603
|
+
fs8.mkdirSync(this.#journalRoot, { recursive: true, mode: 448 });
|
|
9031
9604
|
try {
|
|
9032
|
-
const descriptor =
|
|
9033
|
-
|
|
9605
|
+
const descriptor = fs8.openSync(this.#lockPath, "wx", 384);
|
|
9606
|
+
fs8.writeFileSync(descriptor, `${process.pid}
|
|
9034
9607
|
${Date.now()}
|
|
9035
9608
|
`);
|
|
9036
|
-
|
|
9609
|
+
fs8.closeSync(descriptor);
|
|
9037
9610
|
} catch (error) {
|
|
9038
9611
|
if (error instanceof Error && "code" in error && error.code === "EEXIST") {
|
|
9039
9612
|
throw new Error("Another Schema transaction is in progress");
|
|
9040
9613
|
}
|
|
9041
9614
|
throw error;
|
|
9042
9615
|
}
|
|
9043
|
-
return () =>
|
|
9616
|
+
return () => fs8.rmSync(this.#lockPath, { force: true });
|
|
9044
9617
|
}
|
|
9045
9618
|
#recoverJournals() {
|
|
9046
|
-
|
|
9619
|
+
fs8.mkdirSync(this.#journalRoot, { recursive: true, mode: 448 });
|
|
9047
9620
|
try {
|
|
9048
|
-
const [pidText] =
|
|
9621
|
+
const [pidText] = fs8.readFileSync(this.#lockPath, "utf8").split("\n");
|
|
9049
9622
|
const pid = Number(pidText);
|
|
9050
9623
|
if (Number.isSafeInteger(pid) && pid > 0) {
|
|
9051
9624
|
try {
|
|
@@ -9054,15 +9627,15 @@ ${Date.now()}
|
|
|
9054
9627
|
} catch {
|
|
9055
9628
|
}
|
|
9056
9629
|
}
|
|
9057
|
-
|
|
9630
|
+
fs8.rmSync(this.#lockPath, { force: true });
|
|
9058
9631
|
} catch (error) {
|
|
9059
9632
|
if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) throw error;
|
|
9060
9633
|
}
|
|
9061
|
-
for (const name of
|
|
9634
|
+
for (const name of fs8.readdirSync(this.#journalRoot)) {
|
|
9062
9635
|
if (!name.endsWith(".json")) continue;
|
|
9063
|
-
const filePath =
|
|
9636
|
+
const filePath = path13.join(this.#journalRoot, name);
|
|
9064
9637
|
try {
|
|
9065
|
-
const journal = JSON.parse(
|
|
9638
|
+
const journal = JSON.parse(fs8.readFileSync(filePath, "utf8"));
|
|
9066
9639
|
if (journal.format !== 1 || journal.status !== "applying" || !Array.isArray(journal.before)) continue;
|
|
9067
9640
|
const workspace = this.#workspaceEntry()?.value;
|
|
9068
9641
|
if (workspace?.lastOutcome === "committed" && workspace.lastTransactionId === journal.id) {
|
|
@@ -9314,11 +9887,11 @@ var SchemaProvider = class {
|
|
|
9314
9887
|
|
|
9315
9888
|
// src/state/store.ts
|
|
9316
9889
|
import { createHash as createHash5 } from "node:crypto";
|
|
9317
|
-
import
|
|
9890
|
+
import path15 from "node:path";
|
|
9318
9891
|
|
|
9319
9892
|
// src/state/complexity.ts
|
|
9320
|
-
import
|
|
9321
|
-
import
|
|
9893
|
+
import fs9 from "node:fs";
|
|
9894
|
+
import path14 from "node:path";
|
|
9322
9895
|
var isWordStart = (character) => character !== void 0 && (character >= "a" && character <= "z" || character >= "A" && character <= "Z" || character === "_" || character === "$");
|
|
9323
9896
|
var isWordPart = (character) => isWordStart(character) || character !== void 0 && character >= "0" && character <= "9";
|
|
9324
9897
|
var regularExpressionPrefixWords = /* @__PURE__ */ new Set([
|
|
@@ -9550,7 +10123,7 @@ var languageComplexities = [
|
|
|
9550
10123
|
typeScriptJavaScriptComplexity
|
|
9551
10124
|
];
|
|
9552
10125
|
var complexityForFile = (file, languages = languageComplexities) => {
|
|
9553
|
-
const extension =
|
|
10126
|
+
const extension = path14.extname(file).toLowerCase();
|
|
9554
10127
|
return languages.find((language) => language.extensions.includes(extension));
|
|
9555
10128
|
};
|
|
9556
10129
|
var countFileComplexity = (file) => {
|
|
@@ -9559,7 +10132,7 @@ var countFileComplexity = (file) => {
|
|
|
9559
10132
|
return {
|
|
9560
10133
|
file,
|
|
9561
10134
|
language: language.language,
|
|
9562
|
-
count: language.count(
|
|
10135
|
+
count: language.count(fs9.readFileSync(file, "utf8"))
|
|
9563
10136
|
};
|
|
9564
10137
|
};
|
|
9565
10138
|
|
|
@@ -9567,7 +10140,7 @@ var countFileComplexity = (file) => {
|
|
|
9567
10140
|
import { spawn as spawn2 } from "node:child_process";
|
|
9568
10141
|
import { createHash as createHash4 } from "node:crypto";
|
|
9569
10142
|
var COMMAND_OUTPUT_MAX_BYTES = 32 * 1024;
|
|
9570
|
-
var
|
|
10143
|
+
var errorMessage5 = (error) => error instanceof Error ? error.message : String(error);
|
|
9571
10144
|
var truncateUtf8 = (value, maxBytes) => {
|
|
9572
10145
|
const bytes = Buffer.from(value, "utf8");
|
|
9573
10146
|
if (bytes.length <= maxBytes) return { value, omittedBytes: 0 };
|
|
@@ -9693,12 +10266,12 @@ var runCommand = (command, options) => new Promise((resolve2) => {
|
|
|
9693
10266
|
windowsHide: true
|
|
9694
10267
|
});
|
|
9695
10268
|
} catch (error) {
|
|
9696
|
-
finish("error", null,
|
|
10269
|
+
finish("error", null, errorMessage5(error));
|
|
9697
10270
|
return;
|
|
9698
10271
|
}
|
|
9699
10272
|
child.stdout?.on("data", collect);
|
|
9700
10273
|
child.stderr?.on("data", collect);
|
|
9701
|
-
child.once("error", (error) => finish("error", null,
|
|
10274
|
+
child.once("error", (error) => finish("error", null, errorMessage5(error)));
|
|
9702
10275
|
child.once("close", (code) => {
|
|
9703
10276
|
void (async () => {
|
|
9704
10277
|
if (termination) await termination;
|
|
@@ -9742,7 +10315,7 @@ var EVENT_ROLLBACK_LIMIT = 8;
|
|
|
9742
10315
|
var TRANSITION_PROTOCOL_VERSION = 1;
|
|
9743
10316
|
var DURABLE_HEAD_PROTOCOL_VERSION = 2;
|
|
9744
10317
|
var HEAD_COMMIT_PROOF_VERSION = 1;
|
|
9745
|
-
var
|
|
10318
|
+
var errorMessage6 = (error) => error instanceof Error ? error.message : String(error);
|
|
9746
10319
|
var isCasError = (error) => error instanceof Error && /compare-and-swap failed/.test(error.message);
|
|
9747
10320
|
var toStringArray = (value) => {
|
|
9748
10321
|
if (!Array.isArray(value)) return void 0;
|
|
@@ -9761,9 +10334,9 @@ var truncateUtf82 = (value, maxBytes) => {
|
|
|
9761
10334
|
const bounded = bytes.subarray(0, end).toString("utf8");
|
|
9762
10335
|
return { value: bounded, omittedBytes: bytes.length - end };
|
|
9763
10336
|
};
|
|
9764
|
-
var boundedError = (error) => truncateUtf82(
|
|
10337
|
+
var boundedError = (error) => truncateUtf82(errorMessage6(error), REPORT_TEXT_MAX_BYTES).value;
|
|
9765
10338
|
var casActualVersion = (error) => {
|
|
9766
|
-
const match =
|
|
10339
|
+
const match = errorMessage6(error).match(/found (\d+)$/);
|
|
9767
10340
|
return match ? Number(match[1]) : void 0;
|
|
9768
10341
|
};
|
|
9769
10342
|
var toComplexityRecord = (value) => {
|
|
@@ -10219,7 +10792,7 @@ var StateStore = class {
|
|
|
10219
10792
|
protocolVersion: TRANSITION_PROTOCOL_VERSION,
|
|
10220
10793
|
phase: "rejected",
|
|
10221
10794
|
transitionId: event.id,
|
|
10222
|
-
error: truncateUtf82(
|
|
10795
|
+
error: truncateUtf82(errorMessage6(error), EVENT_TEXT_MAX_BYTES).value,
|
|
10223
10796
|
rollback: {
|
|
10224
10797
|
restored: rollback.errors.length === 0,
|
|
10225
10798
|
deleted: deletedChunks[index],
|
|
@@ -10441,7 +11014,7 @@ var StateStore = class {
|
|
|
10441
11014
|
const files = [];
|
|
10442
11015
|
let netDelta = 0;
|
|
10443
11016
|
for (const file of this.normalizeComplexityFiles(requestedFiles, input.cwd)) {
|
|
10444
|
-
const measured = countFileComplexity(
|
|
11017
|
+
const measured = countFileComplexity(path15.resolve(input.cwd, file));
|
|
10445
11018
|
if (!measured) {
|
|
10446
11019
|
files.push({ file, supported: false });
|
|
10447
11020
|
continue;
|
|
@@ -10468,7 +11041,7 @@ var StateStore = class {
|
|
|
10468
11041
|
const updates = [];
|
|
10469
11042
|
let netDelta = 0;
|
|
10470
11043
|
for (const file of this.normalizeComplexityFiles(files, cwd)) {
|
|
10471
|
-
const measured = countFileComplexity(
|
|
11044
|
+
const measured = countFileComplexity(path15.resolve(cwd, file));
|
|
10472
11045
|
if (!measured) {
|
|
10473
11046
|
deltas.push({ file, supported: false });
|
|
10474
11047
|
continue;
|
|
@@ -10518,11 +11091,11 @@ var StateStore = class {
|
|
|
10518
11091
|
const normalized = /* @__PURE__ */ new Set();
|
|
10519
11092
|
for (const file of files) {
|
|
10520
11093
|
if (!file.trim()) continue;
|
|
10521
|
-
const relative =
|
|
10522
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
11094
|
+
const relative = path15.relative(cwd, path15.resolve(cwd, file));
|
|
11095
|
+
if (relative === ".." || relative.startsWith(`..${path15.sep}`) || path15.isAbsolute(relative)) {
|
|
10523
11096
|
throw new Error(`State complexity file must be inside the project cwd: ${file}`);
|
|
10524
11097
|
}
|
|
10525
|
-
normalized.add(relative.split(
|
|
11098
|
+
normalized.add(relative.split(path15.sep).join("/"));
|
|
10526
11099
|
}
|
|
10527
11100
|
return [...normalized];
|
|
10528
11101
|
}
|
|
@@ -11187,6 +11760,7 @@ var FabricRuntimeState = class {
|
|
|
11187
11760
|
#mcpProvider;
|
|
11188
11761
|
#config;
|
|
11189
11762
|
#execution;
|
|
11763
|
+
#repairs;
|
|
11190
11764
|
#speculationStore;
|
|
11191
11765
|
#speculationTap;
|
|
11192
11766
|
#agents;
|
|
@@ -11296,7 +11870,8 @@ var FabricRuntimeState = class {
|
|
|
11296
11870
|
nestedToolCallId: "fabric-speculation",
|
|
11297
11871
|
extensionContext: context,
|
|
11298
11872
|
update() {
|
|
11299
|
-
}
|
|
11873
|
+
},
|
|
11874
|
+
...this.#sessionCapabilityLease?.view ? { capabilityView: this.#sessionCapabilityLease.view } : {}
|
|
11300
11875
|
};
|
|
11301
11876
|
const speculation = await registry.speculate(
|
|
11302
11877
|
candidate.ref,
|
|
@@ -11311,7 +11886,8 @@ var FabricRuntimeState = class {
|
|
|
11311
11886
|
speculation.preparedArgs,
|
|
11312
11887
|
speculation.execute,
|
|
11313
11888
|
createFreshnessChecker(candidate.ref, speculation.preparedArgs, context.cwd),
|
|
11314
|
-
replay
|
|
11889
|
+
replay,
|
|
11890
|
+
speculation.bindingToken
|
|
11315
11891
|
);
|
|
11316
11892
|
}
|
|
11317
11893
|
get registry() {
|
|
@@ -11375,6 +11951,10 @@ var FabricRuntimeState = class {
|
|
|
11375
11951
|
if (!this.#compact) throw new Error("Pi Fabric has not initialized");
|
|
11376
11952
|
return this.#compact;
|
|
11377
11953
|
}
|
|
11954
|
+
get repairs() {
|
|
11955
|
+
if (!this.#repairs) throw new Error("Pi Fabric has not initialized");
|
|
11956
|
+
return this.#repairs;
|
|
11957
|
+
}
|
|
11378
11958
|
async initialize(context, bootstrapConfig) {
|
|
11379
11959
|
this.#suppressResidentGuidanceSync = true;
|
|
11380
11960
|
try {
|
|
@@ -11404,9 +11984,11 @@ var FabricRuntimeState = class {
|
|
|
11404
11984
|
new FabricToolResultProxy(() => this.capturedTools.runner)
|
|
11405
11985
|
);
|
|
11406
11986
|
this.#wireSpeculation();
|
|
11407
|
-
this.#unsubscribeCapturedCatalog
|
|
11408
|
-
|
|
11409
|
-
|
|
11987
|
+
this.#unsubscribeCapturedCatalog?.();
|
|
11988
|
+
this.#unsubscribeCapturedCatalog = this.capturedTools.subscribe(() => {
|
|
11989
|
+
this.#registry?.notifyCatalogChanged("extensions");
|
|
11990
|
+
this.#refreshRepairCatalog();
|
|
11991
|
+
});
|
|
11410
11992
|
this.#componentSupervisor = new FabricComponentSupervisor(this.#registry, {
|
|
11411
11993
|
invocationContext: () => ({
|
|
11412
11994
|
cwd: context.cwd,
|
|
@@ -11468,7 +12050,7 @@ var FabricRuntimeState = class {
|
|
|
11468
12050
|
create: () => new McpProvider(context.cwd, this.#config.mcp, {
|
|
11469
12051
|
...this.#config.mcp.cache.enabled ? {
|
|
11470
12052
|
cache: new McpDescriptorCacheStore(
|
|
11471
|
-
|
|
12053
|
+
path16.join(
|
|
11472
12054
|
process.env.PI_FABRIC_PROJECT_ROOT ?? context.cwd,
|
|
11473
12055
|
".pi",
|
|
11474
12056
|
"fabric",
|
|
@@ -11512,7 +12094,7 @@ var FabricRuntimeState = class {
|
|
|
11512
12094
|
this.#mainAgent = mainAgent;
|
|
11513
12095
|
const projectRoot = process.env.PI_FABRIC_PROJECT_ROOT ?? context.cwd;
|
|
11514
12096
|
const configuredMeshRoot = this.#config.mesh.root;
|
|
11515
|
-
const meshRoot = process.env.PI_FABRIC_MESH_ROOT ?? (configuredMeshRoot ?
|
|
12097
|
+
const meshRoot = process.env.PI_FABRIC_MESH_ROOT ?? (configuredMeshRoot ? path16.resolve(projectRoot, configuredMeshRoot) : path16.join(projectRoot, ".pi", "fabric", "mesh"));
|
|
11516
12098
|
this.#mesh = new MeshStore(
|
|
11517
12099
|
meshRoot,
|
|
11518
12100
|
this.#config.mesh.maxEventBytes,
|
|
@@ -11630,7 +12212,7 @@ var FabricRuntimeState = class {
|
|
|
11630
12212
|
return participant ? participant.ownerHostId === hostId : void 0;
|
|
11631
12213
|
};
|
|
11632
12214
|
const lineageAlive = (rootId) => this.#participants?.get(rootId) !== void 0;
|
|
11633
|
-
const persistentActorRoot = this.#config.mesh.actorScope === "session" ?
|
|
12215
|
+
const persistentActorRoot = this.#config.mesh.actorScope === "session" ? path16.join(meshRoot, "actors", sessionId) : path16.join(meshRoot, "actors");
|
|
11634
12216
|
const acquireActorCapabilityView = (requirements, signal) => this.#registry.acquireCapabilityView(requirements, {
|
|
11635
12217
|
cwd: context.cwd,
|
|
11636
12218
|
signal,
|
|
@@ -11690,7 +12272,10 @@ ${escapeXmlText(text)}
|
|
|
11690
12272
|
acquireCapabilityView: acquireActorCapabilityView
|
|
11691
12273
|
}
|
|
11692
12274
|
);
|
|
11693
|
-
this.#registry.subscribeProviderChanges(() =>
|
|
12275
|
+
this.#registry.subscribeProviderChanges(() => {
|
|
12276
|
+
this.#actors?.retryCapabilityWaiters();
|
|
12277
|
+
this.#refreshRepairCatalog();
|
|
12278
|
+
});
|
|
11694
12279
|
this.#lifecycle = new LifecycleBroker(
|
|
11695
12280
|
this.#mesh,
|
|
11696
12281
|
identity,
|
|
@@ -11878,6 +12463,12 @@ ${escapeXmlText(text)}
|
|
|
11878
12463
|
this.#sessionCapabilityLease = lease;
|
|
11879
12464
|
this.#execution.setCapabilityView(lease.view);
|
|
11880
12465
|
}
|
|
12466
|
+
this.#repairs = new RepairCompiler({
|
|
12467
|
+
agentDir: resolveAgentDir(),
|
|
12468
|
+
enabled: this.#config.repairs.enabled
|
|
12469
|
+
});
|
|
12470
|
+
this.#refreshRepairCatalog();
|
|
12471
|
+
setActiveRepairCompiler(this.#repairs);
|
|
11881
12472
|
}
|
|
11882
12473
|
async ensure(context) {
|
|
11883
12474
|
if (!this.initialized || this.#cwd !== context.cwd) await this.initialize(context);
|
|
@@ -12086,6 +12677,7 @@ ${escapeXmlText(text)}
|
|
|
12086
12677
|
}
|
|
12087
12678
|
async shutdown() {
|
|
12088
12679
|
this.#suppressResidentGuidanceSync = true;
|
|
12680
|
+
this.#deactivateRepairs();
|
|
12089
12681
|
await this.#participants?.quiesce().catch(() => void 0);
|
|
12090
12682
|
await this.#componentLoader?.close();
|
|
12091
12683
|
await Promise.allSettled([...this.#componentTransitionPublications]);
|
|
@@ -12149,7 +12741,21 @@ ${escapeXmlText(text)}
|
|
|
12149
12741
|
} catch {
|
|
12150
12742
|
}
|
|
12151
12743
|
}
|
|
12744
|
+
#refreshRepairCatalog() {
|
|
12745
|
+
if (!this.#repairs || !this.#registry) return;
|
|
12746
|
+
if (this.capturedTools.suspended) return;
|
|
12747
|
+
this.#repairs.setCatalogSurface({
|
|
12748
|
+
providers: this.#registry.providers().map((provider) => provider.name),
|
|
12749
|
+
capturedTools: this.capturedTools.list().map((entry) => entry.name)
|
|
12750
|
+
});
|
|
12751
|
+
}
|
|
12752
|
+
#deactivateRepairs() {
|
|
12753
|
+
const repairs = this.#repairs;
|
|
12754
|
+
this.#repairs = void 0;
|
|
12755
|
+
clearActiveRepairCompiler(repairs);
|
|
12756
|
+
}
|
|
12152
12757
|
async #closeInternal() {
|
|
12758
|
+
this.#deactivateRepairs();
|
|
12153
12759
|
if (!this.#registry) return;
|
|
12154
12760
|
await this.#participants?.quiesce().catch(() => void 0);
|
|
12155
12761
|
await this.#componentLoader?.close();
|
|
@@ -12249,4 +12855,4 @@ var deepAssign = (target, source) => {
|
|
|
12249
12855
|
export {
|
|
12250
12856
|
FabricRuntimeState
|
|
12251
12857
|
};
|
|
12252
|
-
//# sourceMappingURL=fabric-runtime-state-
|
|
12858
|
+
//# sourceMappingURL=fabric-runtime-state-H2NCRJWK.js.map
|