agentwheel 0.22.1 → 0.22.3
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 +17 -0
- package/dist/index.js +418 -161
- package/openpack.json +1 -1
- package/package.json +2 -1
- package/skills/agentwheel/SKILL.md +1 -1
- package/skills/agentwheel-discovery/SKILL.md +1 -1
package/dist/index.js
CHANGED
|
@@ -797,11 +797,11 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
|
|
|
797
797
|
onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
|
|
798
798
|
ensurePropertyComplete(offset + length);
|
|
799
799
|
},
|
|
800
|
-
onSeparator: (
|
|
800
|
+
onSeparator: (sep13, offset, length) => {
|
|
801
801
|
if (currentParent.type === "property") {
|
|
802
|
-
if (
|
|
802
|
+
if (sep13 === ":") {
|
|
803
803
|
currentParent.colonOffset = offset;
|
|
804
|
-
} else if (
|
|
804
|
+
} else if (sep13 === ",") {
|
|
805
805
|
ensurePropertyComplete(offset);
|
|
806
806
|
}
|
|
807
807
|
}
|
|
@@ -14730,14 +14730,14 @@ var init_artifact = __esm({
|
|
|
14730
14730
|
include: external_exports.string().min(1),
|
|
14731
14731
|
markers: external_exports.boolean().optional(),
|
|
14732
14732
|
optional: external_exports.boolean().optional()
|
|
14733
|
-
});
|
|
14733
|
+
}).strict();
|
|
14734
14734
|
packageCompositionRuleSchema = external_exports.object({
|
|
14735
14735
|
target: external_exports.string().min(1),
|
|
14736
14736
|
include: external_exports.string().min(1),
|
|
14737
14737
|
exclude: external_exports.array(external_exports.string().min(1)).optional(),
|
|
14738
14738
|
runtimes: external_exports.array(external_exports.string().min(1)).optional(),
|
|
14739
14739
|
markers: external_exports.boolean().optional()
|
|
14740
|
-
});
|
|
14740
|
+
}).strict();
|
|
14741
14741
|
packageSupersedesEntrySchema = external_exports.object({
|
|
14742
14742
|
package: external_exports.string().min(1),
|
|
14743
14743
|
selector: external_exports.string().min(1),
|
|
@@ -18513,7 +18513,7 @@ var init_fleet = __esm({
|
|
|
18513
18513
|
// src/mutation/repository.ts
|
|
18514
18514
|
import { createHash as createHash8 } from "crypto";
|
|
18515
18515
|
import { lstat as lstat3, readFile as readFile12, readlink, readdir as readdir5 } from "fs/promises";
|
|
18516
|
-
import { posix as posix4, relative as relative7, resolve as resolve15, sep as sep5 } from "path";
|
|
18516
|
+
import { dirname as dirname10, posix as posix4, relative as relative7, resolve as resolve15, sep as sep5 } from "path";
|
|
18517
18517
|
async function discoverGitRepository(start) {
|
|
18518
18518
|
const probe = await runProcess("git", ["-C", start, "rev-parse", "--show-toplevel"], { allowExitCodes: [0, 128] });
|
|
18519
18519
|
if (probe.exitCode !== 0) return void 0;
|
|
@@ -18540,6 +18540,9 @@ async function assertGitPreflight(repository) {
|
|
|
18540
18540
|
}
|
|
18541
18541
|
}
|
|
18542
18542
|
async function assertHeadLease(repositoryRoot, expectedHead, head, paths, provider) {
|
|
18543
|
+
return assertHeadLeaseWithRecovery(repositoryRoot, expectedHead, head, paths, provider, []);
|
|
18544
|
+
}
|
|
18545
|
+
async function assertHeadLeaseWithRecovery(repositoryRoot, expectedHead, head, paths, provider, recoveryPaths, terminalChanges = /* @__PURE__ */ new Map()) {
|
|
18543
18546
|
if (head === expectedHead) return;
|
|
18544
18547
|
if (provider?.headLease !== "path-scoped" || paths.length === 0) {
|
|
18545
18548
|
throw new Error(`Git HEAD lease mismatch: expected ${expectedHead}, found ${head}.`);
|
|
@@ -18575,10 +18578,65 @@ async function assertHeadLease(repositoryRoot, expectedHead, head, paths, provid
|
|
|
18575
18578
|
"-z",
|
|
18576
18579
|
commit
|
|
18577
18580
|
])).stdout);
|
|
18578
|
-
|
|
18579
|
-
|
|
18581
|
+
for (const path of touched) {
|
|
18582
|
+
if (!protectedPaths.some((protectedPath) => overlaps(path, protectedPath))) continue;
|
|
18583
|
+
if (terminalChanges.get(commit)?.has(path)) continue;
|
|
18584
|
+
const proof = recoveryPaths.find((entry) => entry.path === path && paths.includes(path));
|
|
18585
|
+
if (!proof || overlaps(path, ".agentwheel/config.json") || overlaps(path, ".syncwheel/manifest.json") || await gitPathMode(repositoryRoot, commit, path) !== "100644" || await hashHeadPath(repositoryRoot, expectedHead, path) !== proof.beforeSha256 || await hashHeadPath(repositoryRoot, commit, path) !== proof.afterSha256 || await hashHeadPath(repositoryRoot, head, path) !== proof.afterSha256 || await hashWorkingPath(repositoryRoot, path) !== proof.afterSha256) {
|
|
18586
|
+
throw new Error(`Git HEAD lease overlaps protected paths in intervening commit ${commit}.`);
|
|
18587
|
+
}
|
|
18588
|
+
}
|
|
18589
|
+
}
|
|
18590
|
+
}
|
|
18591
|
+
function overlaps(left, right) {
|
|
18592
|
+
return left === right || left.startsWith(`${right}/`) || right.startsWith(`${left}/`);
|
|
18593
|
+
}
|
|
18594
|
+
async function committedRecoveryPaths(repositoryRoot, expectedHead, head, declarations, receiptPaths, provider) {
|
|
18595
|
+
await verifyRevisionPaths(repositoryRoot, expectedHead, receiptPaths);
|
|
18596
|
+
const committed = [];
|
|
18597
|
+
for (const entry of receiptPaths) {
|
|
18598
|
+
if (!declarations.includes(entry.path)) throw new Error(`Recovery path was not declared: ${entry.path}.`);
|
|
18599
|
+
if (await hashHeadPath(repositoryRoot, head, entry.path) === entry.afterSha256 && entry.beforeSha256 !== entry.afterSha256) {
|
|
18600
|
+
await assertRecoveryFileIdentity(repositoryRoot, expectedHead, head, entry.path);
|
|
18601
|
+
committed.push(entry);
|
|
18602
|
+
}
|
|
18603
|
+
}
|
|
18604
|
+
await assertHeadLeaseWithRecovery(repositoryRoot, expectedHead, head, declarations, provider, committed);
|
|
18605
|
+
return committed;
|
|
18606
|
+
}
|
|
18607
|
+
async function verifyCompletedRecoveryPaths(repositoryRoot, expectedHead, declarations, savedPaths, provider, productCommitSha, productPaths, controlCommitSha) {
|
|
18608
|
+
const head = await currentHead(repositoryRoot);
|
|
18609
|
+
await verifyRevisionPaths(repositoryRoot, expectedHead, savedPaths);
|
|
18610
|
+
for (const entry of savedPaths) {
|
|
18611
|
+
await assertRecoveryFileIdentity(repositoryRoot, expectedHead, head, entry.path);
|
|
18612
|
+
if (await hashHeadPath(repositoryRoot, head, entry.path) !== entry.afterSha256) {
|
|
18613
|
+
throw new Error(`Committed recovery path changed during provider completion: ${entry.path}.`);
|
|
18580
18614
|
}
|
|
18581
18615
|
}
|
|
18616
|
+
const terminalChanges = /* @__PURE__ */ new Map();
|
|
18617
|
+
if (productCommitSha) terminalChanges.set(productCommitSha, new Set(productPaths));
|
|
18618
|
+
if (controlCommitSha) terminalChanges.set(controlCommitSha, /* @__PURE__ */ new Set([".syncwheel/manifest.json"]));
|
|
18619
|
+
await assertHeadLeaseWithRecovery(repositoryRoot, expectedHead, head, declarations, provider, savedPaths, terminalChanges);
|
|
18620
|
+
}
|
|
18621
|
+
async function gitPathMode(repositoryRoot, head, path) {
|
|
18622
|
+
const tree = (await runProcess("git", ["-C", repositoryRoot, "ls-tree", "-z", head, "--", path])).stdout.toString("utf8");
|
|
18623
|
+
const entry = tree.split("\0").find((value) => value.slice(value.indexOf(" ") + 1) === path);
|
|
18624
|
+
return entry?.split(" ")[0];
|
|
18625
|
+
}
|
|
18626
|
+
async function assertRecoveryFileIdentity(repositoryRoot, expectedHead, head, path) {
|
|
18627
|
+
if (await gitPathMode(repositoryRoot, expectedHead, path) !== "100644" || await gitPathMode(repositoryRoot, head, path) !== "100644") {
|
|
18628
|
+
throw new Error(`Recovery requires an existing regular non-executable Git file: ${path}.`);
|
|
18629
|
+
}
|
|
18630
|
+
const absolute = resolve15(repositoryRoot, ...path.split("/"));
|
|
18631
|
+
const stats = await lstat3(absolute);
|
|
18632
|
+
if (!stats.isFile() || (stats.mode & 73) !== 0) throw new Error(`Recovery file identity changed: ${path}.`);
|
|
18633
|
+
let ancestor = dirname10(absolute);
|
|
18634
|
+
while (true) {
|
|
18635
|
+
if ((await lstat3(ancestor)).isSymbolicLink()) throw new Error(`Recovery symlink ancestor is unsupported: ${path}.`);
|
|
18636
|
+
const parent = dirname10(ancestor);
|
|
18637
|
+
if (parent === ancestor) break;
|
|
18638
|
+
ancestor = parent;
|
|
18639
|
+
}
|
|
18582
18640
|
}
|
|
18583
18641
|
function isAgentwheelWritablePath(path) {
|
|
18584
18642
|
return /^\.agentwheel(?:\/|$)/u.test(path) || /^profiles\/[^/]+\/\.agentwheel(?:\/|$)/u.test(path);
|
|
@@ -19279,7 +19337,7 @@ var init_providers = __esm({
|
|
|
19279
19337
|
// src/mutation/coordinator.ts
|
|
19280
19338
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
19281
19339
|
import { homedir as homedir6 } from "os";
|
|
19282
|
-
import { dirname as
|
|
19340
|
+
import { dirname as dirname11, isAbsolute as isAbsolute12, relative as relative8, resolve as resolve17, sep as sep6 } from "path";
|
|
19283
19341
|
function dirtyRepositoryPaths(repositoryRoot, baseline, paths) {
|
|
19284
19342
|
const conflicts = /* @__PURE__ */ new Set();
|
|
19285
19343
|
for (const path of paths) {
|
|
@@ -19353,12 +19411,15 @@ async function resumeMutation(operationId, action) {
|
|
|
19353
19411
|
);
|
|
19354
19412
|
receipt = await updateMutationReceipt(receipt, { paths, status: "mutation-applied" });
|
|
19355
19413
|
}
|
|
19356
|
-
await
|
|
19414
|
+
const request = action === "recover" && receipt.runtimeJournals.length > 0 ? await recoveryProviderRequest(receipt, paths) : providerRequest(receipt, action, paths);
|
|
19415
|
+
await invokeRevisionProvider(provider, revisionProviderRequestSchema.parse({ ...request, action: "preflight" }), {
|
|
19357
19416
|
workspaceRoot: receipt.workspaceRoot
|
|
19358
19417
|
});
|
|
19359
|
-
|
|
19418
|
+
if (action === "recover") await verifyRecoveryProjection(receipt, request);
|
|
19419
|
+
const response = await invokeRevisionProvider(provider, request, {
|
|
19360
19420
|
workspaceRoot: receipt.workspaceRoot
|
|
19361
19421
|
});
|
|
19422
|
+
await verifyCompletedRecoveryProjection(receipt, request, response);
|
|
19362
19423
|
return updateMutationReceipt(receipt, {
|
|
19363
19424
|
status: receiptStatusForProvider(response.status),
|
|
19364
19425
|
providerResponse: response,
|
|
@@ -19401,17 +19462,19 @@ async function recoverMutationRuntime(operationId, options = {}) {
|
|
|
19401
19462
|
`Mutation '${receipt.operationId}' repository HEAD lease changed before runtime recovery.`
|
|
19402
19463
|
);
|
|
19403
19464
|
}
|
|
19404
|
-
await assertHeadLease(
|
|
19465
|
+
if (receipt.noCommit) await assertHeadLease(receipt.repositoryRoot, receipt.expectedHead, repository.head, [], receipt.provider);
|
|
19466
|
+
else await committedRecoveryPaths(
|
|
19405
19467
|
receipt.repositoryRoot,
|
|
19406
19468
|
receipt.expectedHead,
|
|
19407
19469
|
repository.head,
|
|
19408
|
-
|
|
19470
|
+
declarations,
|
|
19471
|
+
receipt.paths,
|
|
19409
19472
|
receipt.provider
|
|
19410
19473
|
);
|
|
19411
19474
|
await assertGitPreflight(repository);
|
|
19412
19475
|
await collectIntroducedPaths(receipt.repositoryRoot, receipt.expectedHead, baseline, declarations);
|
|
19413
19476
|
}
|
|
19414
|
-
mutation = GovernedMutation.activateExisting(receipt, baseline, lock);
|
|
19477
|
+
mutation = GovernedMutation.activateExisting(receipt, baseline, lock, options.beforeProviderCompletion);
|
|
19415
19478
|
const [{ recoverPendingApply: recoverPendingApply2 }, { readLinkedLocalApplyJournal: readLinkedLocalApplyJournal2 }] = await Promise.all([
|
|
19416
19479
|
Promise.resolve().then(() => (init_apply(), apply_exports)),
|
|
19417
19480
|
Promise.resolve().then(() => (init_transaction(), transaction_exports))
|
|
@@ -19523,7 +19586,7 @@ async function mutationPolicyForWorkspace(workspaceRoot, globalRoot = homedir6()
|
|
|
19523
19586
|
const globalConfig2 = await readWorkspaceConfig(globalRoot);
|
|
19524
19587
|
const global = globalConfig2.schemaVersion === 4 ? globalConfig2.mutationPolicy : void 0;
|
|
19525
19588
|
let existingRoot = resolve17(workspaceRoot);
|
|
19526
|
-
while (!await pathExists(existingRoot) &&
|
|
19589
|
+
while (!await pathExists(existingRoot) && dirname11(existingRoot) !== existingRoot) existingRoot = dirname11(existingRoot);
|
|
19527
19590
|
const owner = await resolveWorkspaceOwnershipScope(existingRoot, { globalRoot });
|
|
19528
19591
|
const fleetConfig = owner.fleetId ? await readWorkspaceConfig(owner.root) : void 0;
|
|
19529
19592
|
const fleet = fleetConfig?.schemaVersion === 4 ? fleetConfig.mutationPolicy : void 0;
|
|
@@ -19545,6 +19608,50 @@ function mergeMutationPolicies(global, scoped) {
|
|
|
19545
19608
|
revisioning
|
|
19546
19609
|
});
|
|
19547
19610
|
}
|
|
19611
|
+
async function recoveryProviderRequest(receipt, paths) {
|
|
19612
|
+
const request = providerRequest(receipt, "recover", paths);
|
|
19613
|
+
if (receipt.noCommit) return request;
|
|
19614
|
+
const head = await currentHead(request.repositoryRoot);
|
|
19615
|
+
const committed = await committedRecoveryPaths(
|
|
19616
|
+
request.repositoryRoot,
|
|
19617
|
+
request.expectedHead,
|
|
19618
|
+
head,
|
|
19619
|
+
readMutationPathDeclarations(receipt.operationId),
|
|
19620
|
+
paths,
|
|
19621
|
+
receipt.provider
|
|
19622
|
+
);
|
|
19623
|
+
if (committed.length === 0) return request;
|
|
19624
|
+
const saved = new Set(committed.map((entry) => entry.path));
|
|
19625
|
+
return revisionProviderRequestSchema.parse({
|
|
19626
|
+
...request,
|
|
19627
|
+
expectedHead: head,
|
|
19628
|
+
paths: paths.filter((entry) => !saved.has(entry.path))
|
|
19629
|
+
});
|
|
19630
|
+
}
|
|
19631
|
+
async function verifyCompletedRecoveryProjection(receipt, request, response) {
|
|
19632
|
+
if (request.expectedHead === receipt.expectedHead) return;
|
|
19633
|
+
if (response.action !== "recover" && response.action !== "finalize") throw new Error("Recovery requires a terminal provider response.");
|
|
19634
|
+
const remaining = new Set(request.paths.map((entry) => entry.path));
|
|
19635
|
+
await verifyCompletedRecoveryPaths(
|
|
19636
|
+
request.repositoryRoot,
|
|
19637
|
+
receipt.expectedHead,
|
|
19638
|
+
readMutationPathDeclarations(receipt.operationId),
|
|
19639
|
+
receipt.paths.filter((entry) => !remaining.has(entry.path)),
|
|
19640
|
+
receipt.provider,
|
|
19641
|
+
response.productCommitSha,
|
|
19642
|
+
request.paths.map((entry) => entry.path),
|
|
19643
|
+
response.controlCommitSha
|
|
19644
|
+
);
|
|
19645
|
+
}
|
|
19646
|
+
async function verifyRecoveryProjection(receipt, request) {
|
|
19647
|
+
if (request.expectedHead === receipt.expectedHead) return;
|
|
19648
|
+
if (await currentHead(request.repositoryRoot) !== request.expectedHead) throw new Error("Recovery projection HEAD changed.");
|
|
19649
|
+
const verified = await recoveryProviderRequest(receipt, receipt.paths);
|
|
19650
|
+
if (JSON.stringify(verified) !== JSON.stringify(request)) throw new Error("Recovery projection changed before provider completion.");
|
|
19651
|
+
const repository = await discoverGitRepository(request.repositoryRoot);
|
|
19652
|
+
if (!repository) throw new Error("Recovery repository disappeared.");
|
|
19653
|
+
await assertGitPreflight(repository);
|
|
19654
|
+
}
|
|
19548
19655
|
function providerRequest(receipt, action, paths) {
|
|
19549
19656
|
if (!receipt.repositoryRoot || !receipt.expectedHead || !receipt.provider) {
|
|
19550
19657
|
throw new Error(`Mutation '${receipt.operationId}' is missing revision provider request state.`);
|
|
@@ -19614,17 +19721,21 @@ var init_coordinator = __esm({
|
|
|
19614
19721
|
init_repository();
|
|
19615
19722
|
init_session_ownership();
|
|
19616
19723
|
GovernedMutation = class _GovernedMutation {
|
|
19617
|
-
constructor(policy, receipt, baseline, lock) {
|
|
19724
|
+
constructor(policy, receipt, baseline, lock, runtimeRecovery = false, beforeProviderCompletion) {
|
|
19618
19725
|
this.policy = policy;
|
|
19619
19726
|
this.receipt = receipt;
|
|
19620
19727
|
this.baseline = baseline;
|
|
19621
19728
|
this.lock = lock;
|
|
19729
|
+
this.runtimeRecovery = runtimeRecovery;
|
|
19730
|
+
this.beforeProviderCompletion = beforeProviderCompletion;
|
|
19622
19731
|
this.operationId = receipt.operationId;
|
|
19623
19732
|
}
|
|
19624
19733
|
policy;
|
|
19625
19734
|
receipt;
|
|
19626
19735
|
baseline;
|
|
19627
19736
|
lock;
|
|
19737
|
+
runtimeRecovery;
|
|
19738
|
+
beforeProviderCompletion;
|
|
19628
19739
|
operationId;
|
|
19629
19740
|
closed = false;
|
|
19630
19741
|
static async begin(options) {
|
|
@@ -19730,7 +19841,7 @@ var init_coordinator = __esm({
|
|
|
19730
19841
|
);
|
|
19731
19842
|
}
|
|
19732
19843
|
this.receipt = await updateMutationReceipt(this.receipt, { status: "handler-succeeded" });
|
|
19733
|
-
paths = await this.collectPaths();
|
|
19844
|
+
paths = await this.collectPaths(action === "recover" && this.runtimeRecovery);
|
|
19734
19845
|
this.receipt = await updateMutationReceipt(this.receipt, { paths, status: "mutation-applied" });
|
|
19735
19846
|
} catch (error46) {
|
|
19736
19847
|
this.receipt = await updateMutationReceipt(this.receipt, {
|
|
@@ -19748,12 +19859,16 @@ var init_coordinator = __esm({
|
|
|
19748
19859
|
return this.receipt;
|
|
19749
19860
|
}
|
|
19750
19861
|
const provider = this.policy.revisioning.provider;
|
|
19751
|
-
await
|
|
19862
|
+
const request = this.runtimeRecovery && action === "recover" ? await recoveryProviderRequest(this.receipt, paths) : providerRequest(this.receipt, action, paths);
|
|
19863
|
+
await invokeRevisionProvider(provider, revisionProviderRequestSchema.parse({ ...request, action: "preflight" }), {
|
|
19752
19864
|
workspaceRoot: this.receipt.workspaceRoot
|
|
19753
19865
|
});
|
|
19754
|
-
|
|
19866
|
+
if (this.runtimeRecovery) await verifyRecoveryProjection(this.receipt, request);
|
|
19867
|
+
await this.beforeProviderCompletion?.();
|
|
19868
|
+
const response = await invokeRevisionProvider(provider, request, {
|
|
19755
19869
|
workspaceRoot: this.receipt.workspaceRoot
|
|
19756
19870
|
});
|
|
19871
|
+
await verifyCompletedRecoveryProjection(this.receipt, request, response);
|
|
19757
19872
|
this.receipt = await updateMutationReceipt(this.receipt, {
|
|
19758
19873
|
status: receiptStatusForProvider(response.status),
|
|
19759
19874
|
providerResponse: response
|
|
@@ -19813,7 +19928,7 @@ var init_coordinator = __esm({
|
|
|
19813
19928
|
const runtimeJournals = upsertRuntimeJournal(this.receipt.runtimeJournals, existing, status);
|
|
19814
19929
|
this.receipt = await updateMutationReceipt(this.receipt, { runtimeJournals });
|
|
19815
19930
|
}
|
|
19816
|
-
static activateExisting(receipt, baseline, lock) {
|
|
19931
|
+
static activateExisting(receipt, baseline, lock, beforeProviderCompletion) {
|
|
19817
19932
|
if (receipt.revisionMode === "commit-after-verify" && !receipt.provider) {
|
|
19818
19933
|
throw new Error(`Mutation '${receipt.operationId}' is missing its revision provider recovery policy.`);
|
|
19819
19934
|
}
|
|
@@ -19831,24 +19946,41 @@ var init_coordinator = __esm({
|
|
|
19831
19946
|
journal: "required",
|
|
19832
19947
|
revisioning: { mode: "off" }
|
|
19833
19948
|
});
|
|
19834
|
-
const mutation = new _GovernedMutation(policy, receipt, baseline, lock);
|
|
19949
|
+
const mutation = new _GovernedMutation(policy, receipt, baseline, lock, true, beforeProviderCompletion);
|
|
19835
19950
|
activeMutation = mutation;
|
|
19836
19951
|
return mutation;
|
|
19837
19952
|
}
|
|
19838
|
-
async collectPaths() {
|
|
19953
|
+
async collectPaths(recover = false) {
|
|
19839
19954
|
if (!this.receipt.repositoryRoot || !this.receipt.expectedHead || !this.baseline) return [];
|
|
19840
19955
|
const declarations = [.../* @__PURE__ */ new Set([
|
|
19841
19956
|
...declaredMutationPaths(),
|
|
19842
19957
|
...readMutationPathDeclarations(this.receipt.operationId)
|
|
19843
19958
|
])].sort((a, b) => a.localeCompare(b));
|
|
19844
|
-
|
|
19959
|
+
const head = await currentHead(this.receipt.repositoryRoot);
|
|
19960
|
+
const committed = recover && !this.receipt.noCommit ? await committedRecoveryPaths(
|
|
19845
19961
|
this.receipt.repositoryRoot,
|
|
19846
19962
|
this.receipt.expectedHead,
|
|
19847
|
-
|
|
19963
|
+
head,
|
|
19964
|
+
declarations,
|
|
19965
|
+
this.receipt.paths,
|
|
19966
|
+
this.receipt.provider
|
|
19967
|
+
) : [];
|
|
19968
|
+
if (this.receipt.provider && !recover) await assertHeadLease(
|
|
19969
|
+
this.receipt.repositoryRoot,
|
|
19970
|
+
this.receipt.expectedHead,
|
|
19971
|
+
head,
|
|
19848
19972
|
this.receipt.noCommit ? [] : declarations,
|
|
19849
19973
|
this.receipt.provider
|
|
19850
19974
|
);
|
|
19851
|
-
|
|
19975
|
+
if (recover && this.receipt.noCommit) await assertHeadLease(
|
|
19976
|
+
this.receipt.repositoryRoot,
|
|
19977
|
+
this.receipt.expectedHead,
|
|
19978
|
+
head,
|
|
19979
|
+
[],
|
|
19980
|
+
this.receipt.provider
|
|
19981
|
+
);
|
|
19982
|
+
const introduced = await collectIntroducedPaths(this.receipt.repositoryRoot, this.receipt.expectedHead, this.baseline, declarations);
|
|
19983
|
+
return [...committed, ...introduced].sort((a, b) => a.path.localeCompare(b.path));
|
|
19852
19984
|
}
|
|
19853
19985
|
async close() {
|
|
19854
19986
|
if (this.closed) return;
|
|
@@ -19864,12 +19996,12 @@ var init_coordinator = __esm({
|
|
|
19864
19996
|
// src/transport/ownership-snapshot.ts
|
|
19865
19997
|
import { createHash as createHash10 } from "crypto";
|
|
19866
19998
|
import { lstat as lstat4, readdir as readdir6, readFile as readFile14 } from "fs/promises";
|
|
19867
|
-
import { dirname as
|
|
19999
|
+
import { dirname as dirname12, join as join14, relative as relative9, resolve as resolve18 } from "path";
|
|
19868
20000
|
async function assertSnapshotAncestors(path) {
|
|
19869
20001
|
let current = resolve18(path);
|
|
19870
20002
|
while (true) {
|
|
19871
20003
|
if ((await lstat4(current)).isSymbolicLink()) throw new Error(`Symlink path is unsupported: ${current}`);
|
|
19872
|
-
const parent =
|
|
20004
|
+
const parent = dirname12(current);
|
|
19873
20005
|
if (parent === current) return;
|
|
19874
20006
|
current = parent;
|
|
19875
20007
|
}
|
|
@@ -19935,7 +20067,7 @@ __export(transaction_exports, {
|
|
|
19935
20067
|
});
|
|
19936
20068
|
import { createHash as createHash11 } from "crypto";
|
|
19937
20069
|
import { cp as cp2, lstat as lstat5, mkdir as mkdir7, open as open4, rm as rm5, stat as stat4 } from "fs/promises";
|
|
19938
|
-
import { dirname as
|
|
20070
|
+
import { dirname as dirname13, join as join15, relative as relative10, resolve as resolve19, sep as sep7 } from "path";
|
|
19939
20071
|
async function assertNoSymlinkPath2(path) {
|
|
19940
20072
|
const absolute = resolve19(path);
|
|
19941
20073
|
let current = absolute;
|
|
@@ -19945,7 +20077,7 @@ async function assertNoSymlinkPath2(path) {
|
|
|
19945
20077
|
} catch (error46) {
|
|
19946
20078
|
if (error46.code !== "ENOENT") throw error46;
|
|
19947
20079
|
}
|
|
19948
|
-
const parent =
|
|
20080
|
+
const parent = dirname13(current);
|
|
19949
20081
|
if (parent === current) break;
|
|
19950
20082
|
current = parent;
|
|
19951
20083
|
}
|
|
@@ -20016,7 +20148,7 @@ async function syncMetadataPath(path, directoryOnly = false) {
|
|
|
20016
20148
|
await file2.close();
|
|
20017
20149
|
}
|
|
20018
20150
|
}
|
|
20019
|
-
const directory = await open4(directoryOnly ? path :
|
|
20151
|
+
const directory = await open4(directoryOnly ? path : dirname13(path), "r");
|
|
20020
20152
|
try {
|
|
20021
20153
|
await directory.sync();
|
|
20022
20154
|
} finally {
|
|
@@ -20166,7 +20298,7 @@ async function removeApplyJournal(targetRoot, adapter, transport = localTranspor
|
|
|
20166
20298
|
if (existing?.mutation) await beginResolveMutationRuntimeJournal(existing.mutation.operationId, path);
|
|
20167
20299
|
await transport.rm(applyJournalPath(targetRoot, adapter, scope));
|
|
20168
20300
|
await transport.rm(applyBackupDir(targetRoot, adapter, scope));
|
|
20169
|
-
if ((existing?.metadataAudit || existing?.metadataGuards) && transport.kind === "local") await syncMetadataPath(
|
|
20301
|
+
if ((existing?.metadataAudit || existing?.metadataGuards) && transport.kind === "local") await syncMetadataPath(dirname13(path), true);
|
|
20170
20302
|
if (existing?.mutation) await resolveMutationRuntimeJournal(existing.mutation.operationId, path);
|
|
20171
20303
|
}
|
|
20172
20304
|
async function abortApplyJournal(targetRoot, adapter, transport = localTransport, scope = {}) {
|
|
@@ -20317,7 +20449,7 @@ async function recordBackup(operation, index, targetRoot, adapter, transport = l
|
|
|
20317
20449
|
await transport.copyWithin(operation.destPath, backupPath, operation.kind);
|
|
20318
20450
|
} else {
|
|
20319
20451
|
await rm5(backupPath, { recursive: true, force: true });
|
|
20320
|
-
await mkdir7(
|
|
20452
|
+
await mkdir7(dirname13(backupPath), { recursive: true });
|
|
20321
20453
|
await cp2(operation.destPath, backupPath, { recursive: operation.kind === "dir", dereference: true });
|
|
20322
20454
|
}
|
|
20323
20455
|
return {
|
|
@@ -20415,20 +20547,54 @@ var init_transaction = __esm({
|
|
|
20415
20547
|
|
|
20416
20548
|
// src/install/toml-merge.ts
|
|
20417
20549
|
import { mkdir as mkdir8, readFile as readFile16, writeFile as writeFile8 } from "fs/promises";
|
|
20418
|
-
import {
|
|
20550
|
+
import { parse as parseToml } from "smol-toml";
|
|
20551
|
+
import { dirname as dirname14 } from "path";
|
|
20419
20552
|
async function mergeCodexTomlMcp(sourcePath, destPath) {
|
|
20420
20553
|
const source = JSON.parse(await readFile16(sourcePath, "utf8"));
|
|
20421
20554
|
const servers = extractMcpServers(source);
|
|
20422
20555
|
const current = await pathExists(destPath) ? await readFile16(destPath, "utf8") : "";
|
|
20423
20556
|
const withoutManaged = removeManagedMcpSections(current, Object.keys(servers));
|
|
20424
20557
|
const merged = appendMcpServers(withoutManaged, servers);
|
|
20425
|
-
await mkdir8(
|
|
20558
|
+
await mkdir8(dirname14(destPath), { recursive: true });
|
|
20426
20559
|
await writeFile8(destPath, merged, "utf8");
|
|
20427
20560
|
}
|
|
20428
20561
|
function mismatchedCodexTomlMcpServers(source, currentContent) {
|
|
20429
20562
|
const servers = extractMcpServers(source);
|
|
20430
20563
|
return Object.entries(servers).filter(([name, server]) => extractMcpServerBlock(currentContent, name) !== formatMcpServer(name, server)).map(([name]) => name);
|
|
20431
20564
|
}
|
|
20565
|
+
function mismatchedManagedCodexTomlMcpServers(source, currentContent) {
|
|
20566
|
+
const servers = extractMcpServers(source);
|
|
20567
|
+
let current;
|
|
20568
|
+
try {
|
|
20569
|
+
const parsed = parseToml(currentContent, { integersAsBigInt: "asNeeded" });
|
|
20570
|
+
current = isPlainRecord(parsed.mcp_servers) ? parsed.mcp_servers : void 0;
|
|
20571
|
+
} catch {
|
|
20572
|
+
return Object.keys(servers);
|
|
20573
|
+
}
|
|
20574
|
+
return Object.entries(servers).filter(([name, server]) => {
|
|
20575
|
+
try {
|
|
20576
|
+
const rendered = parseToml(formatMcpServer(name, server), { integersAsBigInt: "asNeeded" });
|
|
20577
|
+
const expected = isPlainRecord(rendered.mcp_servers) ? rendered.mcp_servers[name] : void 0;
|
|
20578
|
+
return !current || !Object.hasOwn(current, name) || !managedValueMatches(current[name], expected);
|
|
20579
|
+
} catch {
|
|
20580
|
+
return true;
|
|
20581
|
+
}
|
|
20582
|
+
}).map(([name]) => name);
|
|
20583
|
+
}
|
|
20584
|
+
function managedValueMatches(actual, expected) {
|
|
20585
|
+
if (Array.isArray(expected)) {
|
|
20586
|
+
return Array.isArray(actual) && actual.length === expected.length && expected.every((value, index) => managedValueMatches(actual[index], value));
|
|
20587
|
+
}
|
|
20588
|
+
if (isPlainRecord(expected)) {
|
|
20589
|
+
return isPlainRecord(actual) && Object.entries(expected).every(([key, value]) => Object.hasOwn(actual, key) && managedValueMatches(actual[key], value));
|
|
20590
|
+
}
|
|
20591
|
+
return actual === expected;
|
|
20592
|
+
}
|
|
20593
|
+
function isPlainRecord(value) {
|
|
20594
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
20595
|
+
const prototype = Object.getPrototypeOf(value);
|
|
20596
|
+
return prototype === null || prototype === Object.prototype;
|
|
20597
|
+
}
|
|
20432
20598
|
function extractMcpServers(source) {
|
|
20433
20599
|
const raw = isRecord2(source.mcpServers) ? source.mcpServers : source;
|
|
20434
20600
|
const servers = {};
|
|
@@ -20539,13 +20705,13 @@ var init_toml_merge = __esm({
|
|
|
20539
20705
|
|
|
20540
20706
|
// src/install/yaml-merge.ts
|
|
20541
20707
|
import { mkdir as mkdir9, readFile as readFile17, writeFile as writeFile9 } from "fs/promises";
|
|
20542
|
-
import { dirname as
|
|
20708
|
+
import { dirname as dirname15 } from "path";
|
|
20543
20709
|
import { parse as parse7, stringify } from "yaml";
|
|
20544
20710
|
async function mergeYamlFile(sourcePath, destPath) {
|
|
20545
20711
|
const source = parseYamlValue(await readFile17(sourcePath, "utf8"));
|
|
20546
20712
|
const current = await pathExists(destPath) ? parseYamlValue(await readFile17(destPath, "utf8")) : {};
|
|
20547
20713
|
const merged = deepMerge2(current, source);
|
|
20548
|
-
await mkdir9(
|
|
20714
|
+
await mkdir9(dirname15(destPath), { recursive: true });
|
|
20549
20715
|
await writeFile9(destPath, stringify(merged), "utf8");
|
|
20550
20716
|
}
|
|
20551
20717
|
function parseYamlValue(content) {
|
|
@@ -20604,7 +20770,7 @@ var init_yaml_merge = __esm({
|
|
|
20604
20770
|
|
|
20605
20771
|
// src/install/merge-removal.ts
|
|
20606
20772
|
import { mkdir as mkdir10, readFile as readFile18, writeFile as writeFile10 } from "fs/promises";
|
|
20607
|
-
import { dirname as
|
|
20773
|
+
import { dirname as dirname16 } from "path";
|
|
20608
20774
|
import { parse as parse8, stringify as stringify2 } from "yaml";
|
|
20609
20775
|
function assertExactMergeContribution(contribution, strategy, currentContent) {
|
|
20610
20776
|
if (strategy === "codex-toml-mcp") {
|
|
@@ -20617,8 +20783,18 @@ function assertExactMergeContribution(contribution, strategy, currentContent) {
|
|
|
20617
20783
|
throw new MergeAdoptionMismatchError(`exact merge contribution differs or is missing at ${mismatch}`);
|
|
20618
20784
|
}
|
|
20619
20785
|
}
|
|
20786
|
+
function assertManagedMergeContribution(contribution, strategy, currentContent) {
|
|
20787
|
+
if (strategy !== "codex-toml-mcp") {
|
|
20788
|
+
assertExactMergeContribution(contribution, strategy, currentContent);
|
|
20789
|
+
return;
|
|
20790
|
+
}
|
|
20791
|
+
const mismatched = mismatchedManagedCodexTomlMcpServers(contribution, currentContent);
|
|
20792
|
+
if (mismatched.length > 0) {
|
|
20793
|
+
throw new MergeAdoptionMismatchError(`managed MCP fields differ or are missing for ${mismatched.join(", ")}`);
|
|
20794
|
+
}
|
|
20795
|
+
}
|
|
20620
20796
|
async function assertMergedSourceContribution(sourcePath, strategy, currentContent) {
|
|
20621
|
-
|
|
20797
|
+
assertManagedMergeContribution(await readMergeSource(sourcePath, strategy), strategy, currentContent);
|
|
20622
20798
|
}
|
|
20623
20799
|
function assertExactMcpMergeContribution(removal, strategy, currentContent) {
|
|
20624
20800
|
if (strategy === "codex-toml-mcp") {
|
|
@@ -20679,7 +20855,7 @@ async function removeMergeContribution(destPath, strategy, removal) {
|
|
|
20679
20855
|
}
|
|
20680
20856
|
const current = parseMergeDestination(content, strategy);
|
|
20681
20857
|
removeIntroducedContent(current, removal);
|
|
20682
|
-
await mkdir10(
|
|
20858
|
+
await mkdir10(dirname16(destPath), { recursive: true });
|
|
20683
20859
|
await writeFile10(destPath, strategy === "yaml-deep" ? stringify2(current) : `${JSON.stringify(current, null, 2)}
|
|
20684
20860
|
`, "utf8");
|
|
20685
20861
|
}
|
|
@@ -20949,7 +21125,7 @@ var init_desired = __esm({
|
|
|
20949
21125
|
import { createHash as createHash12 } from "crypto";
|
|
20950
21126
|
import { mkdtemp as mkdtemp2, readFile as readFile19, realpath as realpath2, rm as rm6, writeFile as writeFile11 } from "fs/promises";
|
|
20951
21127
|
import { tmpdir as tmpdir3 } from "os";
|
|
20952
|
-
import { basename as basename2, dirname as
|
|
21128
|
+
import { basename as basename2, dirname as dirname17, join as join16, relative as relative11 } from "path";
|
|
20953
21129
|
function exactManagedInstructionBlockSnapshot(content, selector) {
|
|
20954
21130
|
const beginCount = [...content.matchAll(new RegExp(`<!-- BEGIN openpack:include ${escapeRegex2(selector)}(?=\\s|-->)`, "gu"))].length;
|
|
20955
21131
|
const endCount = [...content.matchAll(new RegExp(`<!-- END openpack:include ${escapeRegex2(selector)}(?=\\s|-->)`, "gu"))].length;
|
|
@@ -21132,7 +21308,7 @@ function assertCleanBlock(block, selector) {
|
|
|
21132
21308
|
}
|
|
21133
21309
|
}
|
|
21134
21310
|
function referencesAgentsMd(content, claudePath, agentsPath) {
|
|
21135
|
-
const claudeDir =
|
|
21311
|
+
const claudeDir = dirname17(claudePath);
|
|
21136
21312
|
for (const rawLine of content.split(/\r?\n/)) {
|
|
21137
21313
|
const line = rawLine.trim();
|
|
21138
21314
|
const atImport = /^@import\s+(.+)$/i.exec(line);
|
|
@@ -21142,7 +21318,7 @@ function referencesAgentsMd(content, claudePath, agentsPath) {
|
|
|
21142
21318
|
const cleaned = referenced.trim().replace(/^["']|["']$/g, "");
|
|
21143
21319
|
if (!/AGENTS\.md$/i.test(cleaned)) continue;
|
|
21144
21320
|
const candidate = cleaned.startsWith("/") ? cleaned : join16(claudeDir, cleaned);
|
|
21145
|
-
if (relative11(
|
|
21321
|
+
if (relative11(dirname17(agentsPath), candidate).replaceAll("\\", "/") === "AGENTS.md") return true;
|
|
21146
21322
|
if (candidate === agentsPath) return true;
|
|
21147
21323
|
}
|
|
21148
21324
|
return false;
|
|
@@ -21202,7 +21378,7 @@ import { execFile as execFile5 } from "child_process";
|
|
|
21202
21378
|
import { createHash as createHash13, randomUUID as randomUUID3 } from "crypto";
|
|
21203
21379
|
import { chmod as chmod3, link as link2, lstat as lstat6, mkdir as mkdir11, mkdtemp as mkdtemp3, open as open5, readFile as readFile20, rm as rm7, writeFile as writeFile12 } from "fs/promises";
|
|
21204
21380
|
import { tmpdir as tmpdir4 } from "os";
|
|
21205
|
-
import { basename as basename3, dirname as
|
|
21381
|
+
import { basename as basename3, dirname as dirname18, join as join17, resolve as resolve20 } from "path";
|
|
21206
21382
|
import { promisify as promisify5 } from "util";
|
|
21207
21383
|
async function applyInstallPlan(plan, sourceLock, options = {}) {
|
|
21208
21384
|
return applyPlanTransactionally(plan, { ...options, sourceLock });
|
|
@@ -21670,7 +21846,7 @@ async function createPrivateAuditDirectory(path) {
|
|
|
21670
21846
|
} catch (error46) {
|
|
21671
21847
|
if (error46.code !== "ENOENT") throw error46;
|
|
21672
21848
|
}
|
|
21673
|
-
await createPrivateAuditDirectory(
|
|
21849
|
+
await createPrivateAuditDirectory(dirname18(path));
|
|
21674
21850
|
try {
|
|
21675
21851
|
await mkdir11(path, { mode: 448 });
|
|
21676
21852
|
} catch (error46) {
|
|
@@ -21681,14 +21857,14 @@ async function createPrivateAuditDirectory(path) {
|
|
|
21681
21857
|
}
|
|
21682
21858
|
await chmod3(path, 448);
|
|
21683
21859
|
await syncMetadataPath(path, true);
|
|
21684
|
-
await syncMetadataPath(
|
|
21860
|
+
await syncMetadataPath(dirname18(path), true);
|
|
21685
21861
|
}
|
|
21686
21862
|
async function writeAuditFileExclusive(path, content, validateCallerPath) {
|
|
21687
21863
|
await assertNoSymlinkPath2(path);
|
|
21688
|
-
await createPrivateAuditDirectory(
|
|
21864
|
+
await createPrivateAuditDirectory(dirname18(path));
|
|
21689
21865
|
await assertNoSymlinkPath2(path);
|
|
21690
21866
|
await validateCallerPath();
|
|
21691
|
-
await syncMetadataPath(
|
|
21867
|
+
await syncMetadataPath(dirname18(dirname18(path)), true);
|
|
21692
21868
|
const temporary = `${path}.pending-${randomUUID3()}`;
|
|
21693
21869
|
try {
|
|
21694
21870
|
const handle = await open5(temporary, "wx", 384);
|
|
@@ -21704,7 +21880,7 @@ async function writeAuditFileExclusive(path, content, validateCallerPath) {
|
|
|
21704
21880
|
} catch (error46) {
|
|
21705
21881
|
if (error46.code !== "EEXIST" || await readFile20(path, "utf8") !== content) throw error46;
|
|
21706
21882
|
}
|
|
21707
|
-
const directory = await open5(
|
|
21883
|
+
const directory = await open5(dirname18(path), "r");
|
|
21708
21884
|
try {
|
|
21709
21885
|
await directory.sync();
|
|
21710
21886
|
} finally {
|
|
@@ -21813,7 +21989,9 @@ async function applyOperation(operation, context) {
|
|
|
21813
21989
|
if (!await transport.pathExists(operation.destPath)) {
|
|
21814
21990
|
throw new Error(`Merge skip destination disappeared after planning: ${operation.relativeDestPath}`);
|
|
21815
21991
|
}
|
|
21816
|
-
|
|
21992
|
+
const exactAdoption = operation.exactMergeAdoption === true || operation.reason === "force adopting exact unmanaged merge contribution" || operation.reason === "repairing exact incomplete merge ownership";
|
|
21993
|
+
const verify = exactAdoption ? assertExactMergeContribution : assertManagedMergeContribution;
|
|
21994
|
+
verify(operation.mergeRemoval, operation.mergeStrategy, await transport.readFile(operation.destPath));
|
|
21817
21995
|
verifiedCurrentHash = await transport.hashPath(operation.destPath);
|
|
21818
21996
|
} else if (!operation.semanticPlugin && !operation.programmaticOperation) {
|
|
21819
21997
|
if (!await transport.pathExists(operation.destPath)) {
|
|
@@ -22361,7 +22539,7 @@ async function validateOpenClawConfig(configPath, destPath, transport) {
|
|
|
22361
22539
|
if (!transport.execFile) {
|
|
22362
22540
|
throw new Error(`Cannot validate OpenClaw config over ${transport.description}: transport does not support command execution.`);
|
|
22363
22541
|
}
|
|
22364
|
-
const openClawHome =
|
|
22542
|
+
const openClawHome = dirname18(destPath);
|
|
22365
22543
|
const bundledBin = join17(openClawHome, "npm", "node_modules", ".bin", "openclaw");
|
|
22366
22544
|
const script = String.raw`
|
|
22367
22545
|
set -euo pipefail
|
|
@@ -22448,7 +22626,7 @@ import { createHash as createHash32 } from "crypto";
|
|
|
22448
22626
|
import { existsSync } from "fs";
|
|
22449
22627
|
import { mkdir as mkdir28, mkdtemp as mkdtemp6, readFile as readFile45, realpath as realpath4, rm as rm16, writeFile as writeFile24 } from "fs/promises";
|
|
22450
22628
|
import { homedir as homedir18, tmpdir as tmpdir7 } from "os";
|
|
22451
|
-
import { basename as basename24, dirname as
|
|
22629
|
+
import { basename as basename24, dirname as dirname42, isAbsolute as isAbsolute17, join as join66, relative as relative22, resolve as resolve48, sep as sep12 } from "path";
|
|
22452
22630
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
22453
22631
|
import { Command } from "commander";
|
|
22454
22632
|
|
|
@@ -22541,7 +22719,7 @@ import { basename as basename8, join as join28, relative as relative12 } from "p
|
|
|
22541
22719
|
// src/staging/codex-subagents.ts
|
|
22542
22720
|
init_fs();
|
|
22543
22721
|
import { mkdir as mkdir12, readFile as readFile21, writeFile as writeFile13 } from "fs/promises";
|
|
22544
|
-
import { basename as basename4, dirname as
|
|
22722
|
+
import { basename as basename4, dirname as dirname19, join as join18 } from "path";
|
|
22545
22723
|
import { parse as parseYaml } from "yaml";
|
|
22546
22724
|
var requiredCodexAgentFields = ["name", "description", "developer_instructions"];
|
|
22547
22725
|
async function renderCodexSubagents(artifacts, stageRoot, adapter) {
|
|
@@ -22587,7 +22765,7 @@ async function renderCodexSubagent(artifact, stageRoot) {
|
|
|
22587
22765
|
}
|
|
22588
22766
|
const markdown = await readFile21(markdownPath, "utf8");
|
|
22589
22767
|
const toml = markdownToCodexAgentToml(agentName, markdown);
|
|
22590
|
-
await mkdir12(
|
|
22768
|
+
await mkdir12(dirname19(renderedPath), { recursive: true });
|
|
22591
22769
|
await writeFile13(renderedPath, toml, "utf8");
|
|
22592
22770
|
return {
|
|
22593
22771
|
...artifact,
|
|
@@ -22670,7 +22848,7 @@ function escapeRegExp2(value) {
|
|
|
22670
22848
|
// src/staging/copilot-artifacts.ts
|
|
22671
22849
|
init_fs();
|
|
22672
22850
|
import { mkdir as mkdir13, readFile as readFile22, writeFile as writeFile14 } from "fs/promises";
|
|
22673
|
-
import { basename as basename5, dirname as
|
|
22851
|
+
import { basename as basename5, dirname as dirname20, join as join19 } from "path";
|
|
22674
22852
|
async function renderCopilotArtifacts(artifacts, stageRoot, adapter) {
|
|
22675
22853
|
if (adapter?.name !== "copilot") return artifacts;
|
|
22676
22854
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -22701,7 +22879,7 @@ async function renderCopilotSubagent(artifact, stageRoot) {
|
|
|
22701
22879
|
throw new Error(`Copilot subagent ${artifact.relativePath} must be a .md file or directory containing AGENTS.md.`);
|
|
22702
22880
|
}
|
|
22703
22881
|
const markdown = await readFile22(markdownPath, "utf8");
|
|
22704
|
-
await mkdir13(
|
|
22882
|
+
await mkdir13(dirname20(renderedPath), { recursive: true });
|
|
22705
22883
|
await writeFile14(renderedPath, ensureCopilotAgentDescription(agentName, markdown), "utf8");
|
|
22706
22884
|
return {
|
|
22707
22885
|
...artifact,
|
|
@@ -22757,7 +22935,7 @@ function yamlString(value) {
|
|
|
22757
22935
|
// src/staging/openclaw-subagents.ts
|
|
22758
22936
|
init_fs();
|
|
22759
22937
|
import { mkdir as mkdir14, readFile as readFile23, writeFile as writeFile15 } from "fs/promises";
|
|
22760
|
-
import { basename as basename6, dirname as
|
|
22938
|
+
import { basename as basename6, dirname as dirname21, join as join20 } from "path";
|
|
22761
22939
|
async function renderOpenClawSubagents(artifacts, stageRoot, adapter) {
|
|
22762
22940
|
if (adapter?.name !== "openclaw") return artifacts;
|
|
22763
22941
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -22791,10 +22969,10 @@ async function renderOpenClawSubagent(artifact, stageRoot) {
|
|
|
22791
22969
|
|
|
22792
22970
|
${parsed.description ?? `OpenClaw subagent ${agentId}.`}`;
|
|
22793
22971
|
const renderedPath = join20(stageRoot, ".agentwheel-rendered", "openclaw-subagents", agentId, "AGENTS.md");
|
|
22794
|
-
await mkdir14(
|
|
22972
|
+
await mkdir14(dirname21(renderedPath), { recursive: true });
|
|
22795
22973
|
await writeFile15(renderedPath, `${body}
|
|
22796
22974
|
`, "utf8");
|
|
22797
|
-
const renderedDir =
|
|
22975
|
+
const renderedDir = dirname21(renderedPath);
|
|
22798
22976
|
return {
|
|
22799
22977
|
...artifact,
|
|
22800
22978
|
name: agentId,
|
|
@@ -23690,6 +23868,7 @@ async function createPlanFromOperations(desiredOps, adapter, targetRoot, manifes
|
|
|
23690
23868
|
mergeCreatedDestination: existing2?.mergeCreatedDestination,
|
|
23691
23869
|
currentHash: currentHash2,
|
|
23692
23870
|
manifestHash: existing2?.hash,
|
|
23871
|
+
exactMergeAdoption: true,
|
|
23693
23872
|
reason: existing2 ? "repairing exact incomplete merge ownership" : "force adopting exact unmanaged merge contribution"
|
|
23694
23873
|
});
|
|
23695
23874
|
continue;
|
|
@@ -25344,7 +25523,7 @@ function errorMessage2(error46) {
|
|
|
25344
25523
|
|
|
25345
25524
|
// src/source/clawhub.ts
|
|
25346
25525
|
import { mkdir as mkdir15, rm as rm8, writeFile as writeFile16 } from "fs/promises";
|
|
25347
|
-
import { basename as basename10, dirname as
|
|
25526
|
+
import { basename as basename10, dirname as dirname22, join as join32, resolve as resolve22 } from "path";
|
|
25348
25527
|
|
|
25349
25528
|
// src/model/package.ts
|
|
25350
25529
|
init_main();
|
|
@@ -25917,7 +26096,7 @@ async function writeGeneratedPackage(root, packageInfo) {
|
|
|
25917
26096
|
};
|
|
25918
26097
|
const pluginPath = join32(root, "plugins", pluginId, "clawhub.json");
|
|
25919
26098
|
await rm8(root, { recursive: true, force: true });
|
|
25920
|
-
await mkdir15(
|
|
26099
|
+
await mkdir15(dirname22(pluginPath), { recursive: true });
|
|
25921
26100
|
await writeFile16(join32(root, "openpack.json"), `${JSON.stringify({
|
|
25922
26101
|
schemaVersion: CURRENT_OPENPACK_SCHEMA_VERSION,
|
|
25923
26102
|
name: `clawhub/${name}`,
|
|
@@ -25950,7 +26129,7 @@ function cachePathFor(packageName, cacheRoot) {
|
|
|
25950
26129
|
import { execFile as execFile6 } from "child_process";
|
|
25951
26130
|
import { mkdir as mkdir17, rename as rename6, rm as rm10, stat as stat7 } from "fs/promises";
|
|
25952
26131
|
import { homedir as homedir8 } from "os";
|
|
25953
|
-
import { basename as basename11, dirname as
|
|
26132
|
+
import { basename as basename11, dirname as dirname24, join as join35, resolve as resolve23, sep as sep8 } from "path";
|
|
25954
26133
|
import { promisify as promisify6 } from "util";
|
|
25955
26134
|
init_fs();
|
|
25956
26135
|
|
|
@@ -26033,7 +26212,7 @@ function isMissingFile(error46) {
|
|
|
26033
26212
|
init_fs();
|
|
26034
26213
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
26035
26214
|
import { mkdir as mkdir16, readdir as readdir9, readFile as readFile29, rm as rm9, stat as stat6, writeFile as writeFile17 } from "fs/promises";
|
|
26036
|
-
import { dirname as
|
|
26215
|
+
import { dirname as dirname23, join as join34 } from "path";
|
|
26037
26216
|
var snapshotNamePattern = /^(.*)-([0-9a-f]{12})$/i;
|
|
26038
26217
|
var leaseMarker = ".agentwheel-lease-";
|
|
26039
26218
|
async function pruneGitCache(cacheRoot, options = {}) {
|
|
@@ -26101,7 +26280,7 @@ async function removeGeneratedEntries(root, preserveGit) {
|
|
|
26101
26280
|
}
|
|
26102
26281
|
}
|
|
26103
26282
|
async function pruneGitCacheUnlocked(cacheRoot, options) {
|
|
26104
|
-
const referencedCommits = await referencedGraphLockCommits(join34(
|
|
26283
|
+
const referencedCommits = await referencedGraphLockCommits(join34(dirname23(cacheRoot), "locks"));
|
|
26105
26284
|
const entries = await readdir9(cacheRoot, { withFileTypes: true });
|
|
26106
26285
|
const groups = /* @__PURE__ */ new Map();
|
|
26107
26286
|
for (const entry of entries) {
|
|
@@ -26168,7 +26347,7 @@ async function walkGraphLocks(root, visit2) {
|
|
|
26168
26347
|
}
|
|
26169
26348
|
}
|
|
26170
26349
|
async function hasLiveSnapshotLease(snapshotPath, dryRun) {
|
|
26171
|
-
const directory =
|
|
26350
|
+
const directory = dirname23(snapshotPath);
|
|
26172
26351
|
const prefix = `${snapshotPath.slice(directory.length + 1)}${leaseMarker}`;
|
|
26173
26352
|
const entries = await readdir9(directory, { withFileTypes: true });
|
|
26174
26353
|
let live = false;
|
|
@@ -26307,7 +26486,7 @@ var GitSourceDriver = class {
|
|
|
26307
26486
|
async fetch(resolved) {
|
|
26308
26487
|
return withFilesystemLock(`${resolved.resolvedPath}.lock`, resolved.cacheLockTimeoutMs ?? 3e4, async () => {
|
|
26309
26488
|
const parsed = parseGitSource(resolved.source);
|
|
26310
|
-
const cacheRoot =
|
|
26489
|
+
const cacheRoot = dirname24(resolved.resolvedPath);
|
|
26311
26490
|
await mkdir17(cacheRoot, { recursive: true });
|
|
26312
26491
|
await assertOwnedByCurrentUser(cacheRoot);
|
|
26313
26492
|
if (await pathExists(resolved.resolvedPath)) await assertOwnedByCurrentUser(resolved.resolvedPath);
|
|
@@ -26402,9 +26581,9 @@ async function resolveCommit(checkoutPath, ref) {
|
|
|
26402
26581
|
throw lastError;
|
|
26403
26582
|
}
|
|
26404
26583
|
async function snapshotCommit(checkoutPath, commit) {
|
|
26405
|
-
const snapshotPath = join35(
|
|
26584
|
+
const snapshotPath = join35(dirname24(checkoutPath), `${basename11(checkoutPath)}-${commit.slice(0, 12)}`);
|
|
26406
26585
|
if (await pathExists(snapshotPath)) return snapshotPath;
|
|
26407
|
-
const tempPath = join35(
|
|
26586
|
+
const tempPath = join35(dirname24(checkoutPath), `${basename11(snapshotPath)}.tmp-${process.pid}-${Date.now()}`);
|
|
26408
26587
|
const tempIndexPath = `${tempPath}.index`;
|
|
26409
26588
|
await rm10(tempPath, { recursive: true, force: true });
|
|
26410
26589
|
await rm10(tempIndexPath, { force: true });
|
|
@@ -26442,7 +26621,7 @@ async function assertOwnedByCurrentUser(path) {
|
|
|
26442
26621
|
|
|
26443
26622
|
// src/source/mcp-registry.ts
|
|
26444
26623
|
import { mkdir as mkdir18, writeFile as writeFile18 } from "fs/promises";
|
|
26445
|
-
import { basename as basename12, dirname as
|
|
26624
|
+
import { basename as basename12, dirname as dirname25, join as join36, resolve as resolve24 } from "path";
|
|
26446
26625
|
init_fs();
|
|
26447
26626
|
var registryBaseUrl = "https://registry.modelcontextprotocol.io/v0.1";
|
|
26448
26627
|
var sourcePrefix2 = "mcp-registry:";
|
|
@@ -26550,7 +26729,7 @@ function isSafeHttpUrl(value) {
|
|
|
26550
26729
|
async function writeGeneratedPackage2(root, server) {
|
|
26551
26730
|
const serverId = installNameFor3(server.serverName);
|
|
26552
26731
|
const mcpPath = join36(root, "mcp", `${serverId}.json`);
|
|
26553
|
-
await mkdir18(
|
|
26732
|
+
await mkdir18(dirname25(mcpPath), { recursive: true });
|
|
26554
26733
|
await writeFile18(join36(root, "openpack.json"), `${JSON.stringify({
|
|
26555
26734
|
schemaVersion: CURRENT_OPENPACK_SCHEMA_VERSION,
|
|
26556
26735
|
name: `mcp-registry/${server.serverName}`,
|
|
@@ -26584,14 +26763,14 @@ import { createHash as createHash16, randomUUID as randomUUID5 } from "crypto";
|
|
|
26584
26763
|
import { execFile as execFile7 } from "child_process";
|
|
26585
26764
|
import { cp as cp3, mkdir as mkdir19, readFile as readFile30, rename as rename7, rm as rm11 } from "fs/promises";
|
|
26586
26765
|
import { homedir as homedir9 } from "os";
|
|
26587
|
-
import { basename as basename14, dirname as
|
|
26766
|
+
import { basename as basename14, dirname as dirname27, join as join38, resolve as resolve25 } from "path";
|
|
26588
26767
|
import { promisify as promisify7 } from "util";
|
|
26589
26768
|
import * as defaultSkillKit from "@skillkit/core";
|
|
26590
26769
|
|
|
26591
26770
|
// src/source/skill-artifacts.ts
|
|
26592
26771
|
init_fs();
|
|
26593
26772
|
import { readdir as readdir10, stat as stat8 } from "fs/promises";
|
|
26594
|
-
import { basename as basename13, dirname as
|
|
26773
|
+
import { basename as basename13, dirname as dirname26, extname as extname2, join as join37 } from "path";
|
|
26595
26774
|
async function artifactsFromSkillPaths(paths, packageName) {
|
|
26596
26775
|
const artifacts = [];
|
|
26597
26776
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -26628,7 +26807,7 @@ async function artifactFromSkillPath(item, packageName) {
|
|
|
26628
26807
|
};
|
|
26629
26808
|
}
|
|
26630
26809
|
if (stats.isFile() && basename13(item.path).toLowerCase() === "skill.md") {
|
|
26631
|
-
const dir =
|
|
26810
|
+
const dir = dirname26(item.path);
|
|
26632
26811
|
const name = sanitizeSkillName(item.name ?? basename13(dir));
|
|
26633
26812
|
return {
|
|
26634
26813
|
type: "skills",
|
|
@@ -26736,7 +26915,7 @@ var SkillKitSourceDriver = class {
|
|
|
26736
26915
|
sourceHash: await hashPath(resolved.resolvedPath)
|
|
26737
26916
|
};
|
|
26738
26917
|
}
|
|
26739
|
-
const specCachePath = cachePathFor4(spec,
|
|
26918
|
+
const specCachePath = cachePathFor4(spec, dirname27(dirname27(resolved.resolvedPath)));
|
|
26740
26919
|
const refIdentity = resolved.requestedRef ?? "default";
|
|
26741
26920
|
const lockPath = `${specCachePath}.ref-${createHash16("sha256").update(refIdentity).digest("hex")}.lock`;
|
|
26742
26921
|
const inflightKey = `${lockPath}\0${requestedCommit ?? "movable"}`;
|
|
@@ -26757,11 +26936,11 @@ var SkillKitSourceDriver = class {
|
|
|
26757
26936
|
throw new Error("SkillKit provider API unavailable or cannot resolve source. Expected @skillkit/core detectProvider().clone().");
|
|
26758
26937
|
}
|
|
26759
26938
|
const materialized = await withFilesystemLock(lockPath, resolved.cacheLockTimeoutMs ?? 3e4, async () => {
|
|
26760
|
-
const immutablePath = requestedCommit ? cachePathFor4(spec,
|
|
26939
|
+
const immutablePath = requestedCommit ? cachePathFor4(spec, dirname27(dirname27(specCachePath)), requestedCommit) : void 0;
|
|
26761
26940
|
if (immutablePath && await pathExists(immutablePath)) {
|
|
26762
26941
|
return { path: immutablePath, commit: requestedCommit, cacheIdentity: requestedCommit };
|
|
26763
26942
|
}
|
|
26764
|
-
await mkdir19(
|
|
26943
|
+
await mkdir19(dirname27(specCachePath), { recursive: true });
|
|
26765
26944
|
const candidatePath = `${specCachePath}.agentwheel-tmp-${process.pid}-${randomUUID5()}`;
|
|
26766
26945
|
const publishPath = `${candidatePath}.publish`;
|
|
26767
26946
|
let result;
|
|
@@ -26783,7 +26962,7 @@ var SkillKitSourceDriver = class {
|
|
|
26783
26962
|
`SkillKit provider resolved ${resolvedIdentity.commit ?? "non-Git content"} instead of requested commit ${requestedCommit}`
|
|
26784
26963
|
);
|
|
26785
26964
|
}
|
|
26786
|
-
const cachePath = cachePathFor4(spec,
|
|
26965
|
+
const cachePath = cachePathFor4(spec, dirname27(dirname27(specCachePath)), resolvedIdentity.cacheKey);
|
|
26787
26966
|
if (await pathExists(cachePath)) {
|
|
26788
26967
|
return { path: cachePath, commit: resolvedIdentity.commit, cacheIdentity: resolvedIdentity.cacheKey };
|
|
26789
26968
|
}
|
|
@@ -27054,7 +27233,7 @@ init_identify();
|
|
|
27054
27233
|
|
|
27055
27234
|
// src/staging/staging.ts
|
|
27056
27235
|
import { chmod as chmod4, cp as cp5, mkdir as mkdir22, mkdtemp as mkdtemp4, readdir as readdir13, stat as stat12 } from "fs/promises";
|
|
27057
|
-
import { basename as basename19, dirname as
|
|
27236
|
+
import { basename as basename19, dirname as dirname31, join as join43, relative as relative16, resolve as resolve29, sep as sep10 } from "path";
|
|
27058
27237
|
import { tmpdir as tmpdir5 } from "os";
|
|
27059
27238
|
init_fs();
|
|
27060
27239
|
|
|
@@ -27063,7 +27242,7 @@ init_artifact();
|
|
|
27063
27242
|
init_fs();
|
|
27064
27243
|
import { createHash as createHash17 } from "crypto";
|
|
27065
27244
|
import { readdir as readdir11, readFile as readFile31, stat as stat10, writeFile as writeFile19 } from "fs/promises";
|
|
27066
|
-
import { basename as basename16, dirname as
|
|
27245
|
+
import { basename as basename16, dirname as dirname28, extname as extname3, join as join40, relative as relative15, resolve as resolve28, sep as sep9 } from "path";
|
|
27067
27246
|
var includePattern = /<!--\s*openpack:include(\?)?\s+([^>]+?)\s*-->/g;
|
|
27068
27247
|
var escapedIncludePattern = /<!--\s*openpack\\:include(\?)?\s+([^>]+?)\s*-->/g;
|
|
27069
27248
|
var generatedPattern = /<!--\s*(?:BEGIN|END)\s+openpack:include\b/;
|
|
@@ -27082,7 +27261,8 @@ async function expandMarkdownIncludes(artifacts, packageRoot, options = {}) {
|
|
|
27082
27261
|
entry,
|
|
27083
27262
|
packageRoot,
|
|
27084
27263
|
artifactPaths,
|
|
27085
|
-
nodeId: options.nodeId
|
|
27264
|
+
nodeId: options.nodeId,
|
|
27265
|
+
packageName: options.packageName
|
|
27086
27266
|
}));
|
|
27087
27267
|
const externalEntries = isPrimaryMarkdownFile(artifact, file2) ? options.additionalComposeEntries?.(artifact) ?? [] : [];
|
|
27088
27268
|
const result = await expandFile(file2, packageRoot, [...localEntries, ...externalEntries], artifactPaths, options);
|
|
@@ -27114,12 +27294,13 @@ async function expandFile(file2, packageRoot, appendEntries, artifactPaths, opti
|
|
|
27114
27294
|
const expanded = await expandContent(raw, packageRoot, [owner], artifactPaths, options);
|
|
27115
27295
|
let content = expanded.content;
|
|
27116
27296
|
const composedFrom = [...expanded.composedFrom];
|
|
27117
|
-
const appliedComposeIdentities = /* @__PURE__ */ new
|
|
27297
|
+
const appliedComposeIdentities = /* @__PURE__ */ new Map();
|
|
27118
27298
|
for (const external of appendEntries) {
|
|
27119
27299
|
const { entry } = external;
|
|
27120
27300
|
const included = await expandInclude(entry.include, external.packageRoot, external.artifactPaths, {
|
|
27121
27301
|
...options,
|
|
27122
27302
|
nodeId: external.nodeId,
|
|
27303
|
+
packageName: external.packageName,
|
|
27123
27304
|
optional: entry.optional === true,
|
|
27124
27305
|
markers: entry.markers !== false,
|
|
27125
27306
|
chain: [owner]
|
|
@@ -27127,10 +27308,15 @@ async function expandFile(file2, packageRoot, appendEntries, artifactPaths, opti
|
|
|
27127
27308
|
if (!included) continue;
|
|
27128
27309
|
const markerMode = entry.markers === false ? "plain" : "markers";
|
|
27129
27310
|
const identity = `${markerMode}\0${included.identity}`;
|
|
27130
|
-
|
|
27131
|
-
|
|
27311
|
+
const previous = appliedComposeIdentities.get(identity);
|
|
27312
|
+
if (external.deduplicate && previous) {
|
|
27313
|
+
if (previous.hash !== included.hash) {
|
|
27314
|
+
throw new Error(`Conflicting OpenPack composition revisions for ${included.selector}: ${previous.selector} (${previous.hash}) and ${included.selector} (${included.hash}). Select one revision explicitly.`);
|
|
27315
|
+
}
|
|
27316
|
+
composedFrom.push(...included.composedFrom);
|
|
27317
|
+
continue;
|
|
27132
27318
|
}
|
|
27133
|
-
appliedComposeIdentities.
|
|
27319
|
+
appliedComposeIdentities.set(identity, { hash: included.hash, selector: included.selector });
|
|
27134
27320
|
content = `${content.trimEnd()}
|
|
27135
27321
|
|
|
27136
27322
|
${included.rendered}
|
|
@@ -27150,6 +27336,7 @@ async function expandContent(content, packageRoot, chain, artifactPaths, options
|
|
|
27150
27336
|
}
|
|
27151
27337
|
const composedFrom = [];
|
|
27152
27338
|
const replacements = [];
|
|
27339
|
+
const semanticReplacements = [];
|
|
27153
27340
|
for (const match of content.matchAll(includePattern)) {
|
|
27154
27341
|
const selector = cleanSelector(match[2] ?? "");
|
|
27155
27342
|
const included = await expandInclude(selector, packageRoot, artifactPaths, {
|
|
@@ -27163,13 +27350,14 @@ async function expandContent(content, packageRoot, chain, artifactPaths, options
|
|
|
27163
27350
|
end: (match.index ?? 0) + match[0].length,
|
|
27164
27351
|
value: included?.rendered ?? ""
|
|
27165
27352
|
});
|
|
27353
|
+
semanticReplacements.push({ start: match.index ?? 0, end: (match.index ?? 0) + match[0].length, value: included?.semanticContent ?? "" });
|
|
27166
27354
|
if (included) composedFrom.push(...included.composedFrom);
|
|
27167
27355
|
}
|
|
27168
27356
|
let expanded = applyReplacements(content, replacements);
|
|
27169
27357
|
expanded = expanded.replace(escapedIncludePattern, (_match, optional2, selector) => {
|
|
27170
27358
|
return `<!-- openpack:include${optional2 ?? ""} ${cleanSelector(selector)} -->`;
|
|
27171
27359
|
});
|
|
27172
|
-
return { content: expanded, composedFrom: uniqueComposedFrom(composedFrom) };
|
|
27360
|
+
return { content: expanded, semanticContent: applyReplacements(content, semanticReplacements), composedFrom: uniqueComposedFrom(composedFrom) };
|
|
27173
27361
|
}
|
|
27174
27362
|
async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
27175
27363
|
const parsed = parseOpenPackIncludeSelector(selector);
|
|
@@ -27178,6 +27366,7 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
|
27178
27366
|
let includePackageRoot = packageRoot;
|
|
27179
27367
|
let includeArtifactPaths = artifactPaths;
|
|
27180
27368
|
let includeNodeId = options.nodeId;
|
|
27369
|
+
let includePackageName = options.packageName;
|
|
27181
27370
|
let displaySelector = displaySelectorForInclude(parsed.selector, options.nodeId, options.originNodeId);
|
|
27182
27371
|
if (parsed.alias) {
|
|
27183
27372
|
if (!options.nodeId || !options.resolveCrossPackageInclude) {
|
|
@@ -27196,6 +27385,7 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
|
27196
27385
|
includePackageRoot = resolved.packageRoot;
|
|
27197
27386
|
includeArtifactPaths = resolved.artifactPaths;
|
|
27198
27387
|
includeNodeId = resolved.toNodeId;
|
|
27388
|
+
includePackageName = resolved.packageName;
|
|
27199
27389
|
displaySelector = `${resolved.toNodeId}:${parsed.selector}`;
|
|
27200
27390
|
} else {
|
|
27201
27391
|
sourcePath = artifactPaths.get(parsed.selector) ?? resolvePackageSelector(packageRoot, parsed.selector);
|
|
@@ -27215,13 +27405,14 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
|
27215
27405
|
const { optional: _optional2, markers: _markers, chain: _chain, ...childOptions } = options;
|
|
27216
27406
|
const expanded = await expandContent(raw, includePackageRoot, [...options.chain, displaySelector], includeArtifactPaths, {
|
|
27217
27407
|
...childOptions,
|
|
27218
|
-
nodeId: includeNodeId
|
|
27408
|
+
nodeId: includeNodeId,
|
|
27409
|
+
packageName: includePackageName
|
|
27219
27410
|
});
|
|
27220
27411
|
const contentHash = sha2563(expanded.content);
|
|
27221
|
-
const identity = `${includeNodeId ?? resolve28(includePackageRoot)}\0${parsed.selector}
|
|
27412
|
+
const identity = `${includePackageName ?? includeNodeId ?? resolve28(includePackageRoot)}\0${parsed.selector}`;
|
|
27222
27413
|
const ownEntry = { selector: displaySelector, hash: contentHash };
|
|
27223
27414
|
const composedFrom = uniqueComposedFrom([ownEntry, ...expanded.composedFrom]);
|
|
27224
|
-
if (!options.markers) return { rendered: expanded.content, composedFrom, identity };
|
|
27415
|
+
if (!options.markers) return { rendered: expanded.content, composedFrom, identity, hash: sha2563(expanded.semanticContent), selector: displaySelector, semanticContent: expanded.semanticContent };
|
|
27225
27416
|
return {
|
|
27226
27417
|
rendered: [
|
|
27227
27418
|
`<!-- BEGIN openpack:include ${displaySelector} sha256:${contentHash.slice(0, markerHashLength)} -->`,
|
|
@@ -27229,7 +27420,10 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
|
|
|
27229
27420
|
`<!-- END openpack:include ${displaySelector} -->`
|
|
27230
27421
|
].join("\n"),
|
|
27231
27422
|
composedFrom,
|
|
27232
|
-
identity
|
|
27423
|
+
identity,
|
|
27424
|
+
hash: sha2563(expanded.semanticContent),
|
|
27425
|
+
selector: displaySelector,
|
|
27426
|
+
semanticContent: expanded.semanticContent
|
|
27233
27427
|
};
|
|
27234
27428
|
}
|
|
27235
27429
|
function parseOpenPackIncludeSelector(selector) {
|
|
@@ -27303,11 +27497,11 @@ async function listMarkdownFiles(root) {
|
|
|
27303
27497
|
function composeEntriesForFile(artifact, file2) {
|
|
27304
27498
|
if (!artifact.compose?.length) return [];
|
|
27305
27499
|
if (artifact.kind === "file") return [resolve28(artifact.stagedPath ?? artifact.sourcePath), resolve28(file2)].every(Boolean) && resolve28(artifact.stagedPath ?? artifact.sourcePath) === resolve28(file2) ? artifact.compose : [];
|
|
27306
|
-
return basename16(file2) === "SKILL.md" &&
|
|
27500
|
+
return basename16(file2) === "SKILL.md" && dirname28(file2) === resolve28(artifact.stagedPath ?? artifact.sourcePath) ? artifact.compose : [];
|
|
27307
27501
|
}
|
|
27308
27502
|
function isPrimaryMarkdownFile(artifact, file2) {
|
|
27309
27503
|
if (artifact.kind === "file") return resolve28(artifact.stagedPath ?? artifact.sourcePath) === resolve28(file2);
|
|
27310
|
-
return basename16(file2) === "SKILL.md" &&
|
|
27504
|
+
return basename16(file2) === "SKILL.md" && dirname28(file2) === resolve28(artifact.stagedPath ?? artifact.sourcePath);
|
|
27311
27505
|
}
|
|
27312
27506
|
function orderedForExpansion(artifacts) {
|
|
27313
27507
|
return [...artifacts].sort((a, b) => Number(a.type === "fragments") - Number(b.type === "fragments"));
|
|
@@ -27355,7 +27549,7 @@ function artifactPathMap(artifacts) {
|
|
|
27355
27549
|
// src/staging/customize.ts
|
|
27356
27550
|
init_fs();
|
|
27357
27551
|
import { cp as cp4, mkdir as mkdir20, readdir as readdir12, readFile as readFile32, writeFile as writeFile20 } from "fs/promises";
|
|
27358
|
-
import { dirname as
|
|
27552
|
+
import { dirname as dirname29, join as join41 } from "path";
|
|
27359
27553
|
async function applyCustomizations(artifacts, options) {
|
|
27360
27554
|
let next = [...artifacts];
|
|
27361
27555
|
next = await applyReplacements2(next, options, "override", installableArtifactTypes());
|
|
@@ -27379,7 +27573,7 @@ async function applyInstructionOverlay(artifacts, options) {
|
|
|
27379
27573
|
const managed = await readFile32(artifact.stagedPath ?? artifact.sourcePath, "utf8");
|
|
27380
27574
|
const local = await readFile32(overlayPath, "utf8");
|
|
27381
27575
|
const composedPath = join41(options.stageRoot, ".agentwheel-composed", "instructions", "AGENTS.md");
|
|
27382
|
-
await mkdir20(
|
|
27576
|
+
await mkdir20(dirname29(composedPath), { recursive: true });
|
|
27383
27577
|
await writeFile20(
|
|
27384
27578
|
composedPath,
|
|
27385
27579
|
[
|
|
@@ -27452,7 +27646,7 @@ async function applyReplacements2(artifacts, options, channel, artifactTypes) {
|
|
|
27452
27646
|
const artifactKind = entry.isDirectory() ? "dir" : "file";
|
|
27453
27647
|
const existing = byKey.get(artifactMapKey);
|
|
27454
27648
|
const stagedPath = join41(options.stageRoot, ".agentwheel-composed", channel, type, entry.name);
|
|
27455
|
-
await mkdir20(
|
|
27649
|
+
await mkdir20(dirname29(stagedPath), { recursive: true });
|
|
27456
27650
|
await cp4(full, stagedPath, { recursive: artifactKind === "dir", dereference: true });
|
|
27457
27651
|
byKey.set(artifactMapKey, {
|
|
27458
27652
|
...existing,
|
|
@@ -27498,7 +27692,7 @@ async function sortedDirEntries2(path) {
|
|
|
27498
27692
|
// src/staging/claude-subagents.ts
|
|
27499
27693
|
init_fs();
|
|
27500
27694
|
import { mkdir as mkdir21, readFile as readFile33, writeFile as writeFile21 } from "fs/promises";
|
|
27501
|
-
import { basename as basename18, dirname as
|
|
27695
|
+
import { basename as basename18, dirname as dirname30, join as join42 } from "path";
|
|
27502
27696
|
async function renderClaudeSubagents(artifacts, stageRoot, adapter) {
|
|
27503
27697
|
if (adapter?.name !== "claude") return artifacts;
|
|
27504
27698
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -27529,7 +27723,7 @@ async function renderClaudeSubagent(artifact, stageRoot) {
|
|
|
27529
27723
|
}
|
|
27530
27724
|
const content = await readFile33(markdownPath, "utf8");
|
|
27531
27725
|
const renderedPath = join42(stageRoot, ".agentwheel-rendered", "claude-subagents", `${agentName}.md`);
|
|
27532
|
-
await mkdir21(
|
|
27726
|
+
await mkdir21(dirname30(renderedPath), { recursive: true });
|
|
27533
27727
|
await writeFile21(renderedPath, content.endsWith("\n") ? content : `${content}
|
|
27534
27728
|
`, "utf8");
|
|
27535
27729
|
return {
|
|
@@ -27572,7 +27766,7 @@ async function stageResolvedArtifactsRaw(resolved, artifacts, parentDir = tmpdir
|
|
|
27572
27766
|
await removeOnFailure(root, async () => {
|
|
27573
27767
|
for (const artifact of artifacts) {
|
|
27574
27768
|
const stagedPath = join43(root, artifact.relativePath);
|
|
27575
|
-
await mkdir22(
|
|
27769
|
+
await mkdir22(dirname31(stagedPath), { recursive: true });
|
|
27576
27770
|
await cp5(artifact.sourcePath, stagedPath, {
|
|
27577
27771
|
recursive: artifact.kind === "dir",
|
|
27578
27772
|
dereference: true,
|
|
@@ -27678,7 +27872,7 @@ async function copyAsset(asset, source, dest) {
|
|
|
27678
27872
|
throw new Error(`Asset include source is not a file or directory: ${source}`);
|
|
27679
27873
|
}
|
|
27680
27874
|
if (!asset.include?.length) {
|
|
27681
|
-
await mkdir22(
|
|
27875
|
+
await mkdir22(dirname31(dest), { recursive: true });
|
|
27682
27876
|
await cp5(source, dest, { recursive: true, dereference: true });
|
|
27683
27877
|
if (asset.mode === "copy") await normalizeCopiedModes(dest);
|
|
27684
27878
|
return;
|
|
@@ -27690,7 +27884,7 @@ async function copyAsset(asset, source, dest) {
|
|
|
27690
27884
|
}
|
|
27691
27885
|
}
|
|
27692
27886
|
async function copyAssetFile(source, dest, asset) {
|
|
27693
|
-
await mkdir22(
|
|
27887
|
+
await mkdir22(dirname31(dest), { recursive: true });
|
|
27694
27888
|
await cp5(source, dest, { dereference: true });
|
|
27695
27889
|
if (asset.mode === "copy") await chmod4(dest, 420);
|
|
27696
27890
|
}
|
|
@@ -27746,7 +27940,7 @@ init_adapter();
|
|
|
27746
27940
|
init_artifact();
|
|
27747
27941
|
init_workspace();
|
|
27748
27942
|
import { appendFile, cp as cp6, lstat as lstat7, mkdir as mkdir23, readdir as readdir15, rm as rm13 } from "fs/promises";
|
|
27749
|
-
import { dirname as
|
|
27943
|
+
import { dirname as dirname33, join as join46, relative as relative17 } from "path";
|
|
27750
27944
|
|
|
27751
27945
|
// src/resolve/graph.ts
|
|
27752
27946
|
import { createHash as createHash19 } from "crypto";
|
|
@@ -27884,7 +28078,7 @@ import { resolve as resolve31 } from "path";
|
|
|
27884
28078
|
// src/registry/client.ts
|
|
27885
28079
|
import { readFile as readFile35, rm as rm12, stat as stat13 } from "fs/promises";
|
|
27886
28080
|
import { homedir as homedir11 } from "os";
|
|
27887
|
-
import { dirname as
|
|
28081
|
+
import { dirname as dirname32, join as join44, resolve as resolve30 } from "path";
|
|
27888
28082
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
27889
28083
|
|
|
27890
28084
|
// src/model/registry.ts
|
|
@@ -28005,7 +28199,7 @@ var RegistryClient = class {
|
|
|
28005
28199
|
const stats = await stat13(fullPath);
|
|
28006
28200
|
return readFile35(stats.isDirectory() ? join44(fullPath, "index.json") : fullPath, "utf8");
|
|
28007
28201
|
}
|
|
28008
|
-
const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot: join44(
|
|
28202
|
+
const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot: join44(dirname32(this.cachePath), "registry-repos") }));
|
|
28009
28203
|
return readFile35(join44(resolved.resolvedPath, "index.json"), "utf8");
|
|
28010
28204
|
}
|
|
28011
28205
|
warnCompatibility(entries) {
|
|
@@ -29132,7 +29326,7 @@ init_declarations();
|
|
|
29132
29326
|
async function remember(workspaceRoot, runtime, text) {
|
|
29133
29327
|
const overlayPath = join46(workspaceRoot, ".agentwheel", "overlays", runtime, "instructions.local.md");
|
|
29134
29328
|
declareMutationPath(overlayPath);
|
|
29135
|
-
await mkdir23(
|
|
29329
|
+
await mkdir23(dirname33(overlayPath), { recursive: true });
|
|
29136
29330
|
await appendFile(overlayPath, `${text.trim()}
|
|
29137
29331
|
`, "utf8");
|
|
29138
29332
|
return { overlayPath };
|
|
@@ -29165,7 +29359,7 @@ async function ejectArtifact(workspaceRoot, item) {
|
|
|
29165
29359
|
} else {
|
|
29166
29360
|
declareMutationPath(ejectedPath);
|
|
29167
29361
|
}
|
|
29168
|
-
await mkdir23(
|
|
29362
|
+
await mkdir23(dirname33(ejectedPath), { recursive: true });
|
|
29169
29363
|
await rm13(ejectedPath, { recursive: true, force: true });
|
|
29170
29364
|
await cp6(sourcePath, ejectedPath, { recursive: artifact.kind === "dir", dereference: true });
|
|
29171
29365
|
return {
|
|
@@ -29284,7 +29478,7 @@ init_adapter();
|
|
|
29284
29478
|
init_graph_lock();
|
|
29285
29479
|
import { createHash as createHash21 } from "crypto";
|
|
29286
29480
|
import { mkdir as mkdir25, readdir as readdir16 } from "fs/promises";
|
|
29287
|
-
import { basename as basename21, dirname as
|
|
29481
|
+
import { basename as basename21, dirname as dirname35, join as join49, posix as posix7, resolve as resolve34 } from "path";
|
|
29288
29482
|
init_paths();
|
|
29289
29483
|
init_merge_removal();
|
|
29290
29484
|
init_transaction();
|
|
@@ -29497,6 +29691,7 @@ async function renderGraphIntoRoot(root, graph, targetContext) {
|
|
|
29497
29691
|
const compositionArtifacts = runtimeArtifacts;
|
|
29498
29692
|
const expandedArtifacts = await expandMarkdownIncludes(compositionArtifacts, staged.root, {
|
|
29499
29693
|
nodeId: rawNode.node.id,
|
|
29694
|
+
packageName: rawNode.node.name,
|
|
29500
29695
|
originNodeId: rawNode.node.id,
|
|
29501
29696
|
additionalComposeEntries: (artifact) => matchingCompositionEntries(
|
|
29502
29697
|
artifact,
|
|
@@ -29534,6 +29729,7 @@ async function renderGraphIntoRoot(root, graph, targetContext) {
|
|
|
29534
29729
|
includeEdges.set(`${includeEdge.fromNodeId}\0${includeEdge.alias}\0${includeEdge.toNodeId}\0${includeEdge.selector}\0${includeEdge.sourceHash}`, includeEdge);
|
|
29535
29730
|
return {
|
|
29536
29731
|
toNodeId: edge.to,
|
|
29732
|
+
packageName: target.rawNode.node.name,
|
|
29537
29733
|
packageRoot: target.root,
|
|
29538
29734
|
artifactPaths: target.artifactPaths,
|
|
29539
29735
|
sourcePath,
|
|
@@ -29621,6 +29817,7 @@ function matchingCompositionEntries(artifact, targetNodeId, runtime, rules) {
|
|
|
29621
29817
|
packageRoot: candidate.packageRoot,
|
|
29622
29818
|
artifactPaths: candidate.artifactPaths,
|
|
29623
29819
|
nodeId: candidate.ownerNodeId,
|
|
29820
|
+
packageName: candidate.ownerPackageName,
|
|
29624
29821
|
deduplicate: true
|
|
29625
29822
|
});
|
|
29626
29823
|
}
|
|
@@ -29969,7 +30166,7 @@ init_zod();
|
|
|
29969
30166
|
init_fs();
|
|
29970
30167
|
import { mkdir as mkdir24, readFile as readFile38 } from "fs/promises";
|
|
29971
30168
|
import { homedir as homedir13 } from "os";
|
|
29972
|
-
import { dirname as
|
|
30169
|
+
import { dirname as dirname34, join as join48 } from "path";
|
|
29973
30170
|
var trustStoreSchema = external_exports.object({
|
|
29974
30171
|
version: external_exports.literal(1),
|
|
29975
30172
|
acceptedSources: external_exports.array(external_exports.string().min(1)).default([])
|
|
@@ -30045,7 +30242,7 @@ async function readTrustStore(path) {
|
|
|
30045
30242
|
return trustStoreSchema.parse(JSON.parse(await readFile38(path, "utf8")));
|
|
30046
30243
|
}
|
|
30047
30244
|
async function writeTrustStore(path, store) {
|
|
30048
|
-
await mkdir24(
|
|
30245
|
+
await mkdir24(dirname34(path), { recursive: true });
|
|
30049
30246
|
await writeJsonAtomic(path, trustStoreSchema.parse(store));
|
|
30050
30247
|
}
|
|
30051
30248
|
function defaultTrustStorePath() {
|
|
@@ -30545,7 +30742,7 @@ async function discoverTargetApplyJournal(options) {
|
|
|
30545
30742
|
continue;
|
|
30546
30743
|
}
|
|
30547
30744
|
if (!journal.graphLockPath || !journal.graphLock || !journal.graphLockDigest) continue;
|
|
30548
|
-
if (resolve34(
|
|
30745
|
+
if (resolve34(dirname35(journal.graphLockPath)) !== resolve34(dirname35(options.graphLockPath))) continue;
|
|
30549
30746
|
if (options.transport.kind === "ssh") {
|
|
30550
30747
|
throw new Error(
|
|
30551
30748
|
`Legacy SSH apply journal at ${item.path} does not record its original endpoint; Agentwheel cannot prove endpoint identity, so the journal was preserved.`
|
|
@@ -30687,7 +30884,7 @@ async function resolvePriorTargetState(options) {
|
|
|
30687
30884
|
return {};
|
|
30688
30885
|
}
|
|
30689
30886
|
async function discoverLegacyStateCandidates(options) {
|
|
30690
|
-
const directory =
|
|
30887
|
+
const directory = dirname35(options.graphLockPath);
|
|
30691
30888
|
let names;
|
|
30692
30889
|
try {
|
|
30693
30890
|
names = await readdir16(directory);
|
|
@@ -30975,7 +31172,7 @@ function mcpServerNames(strategy, removal) {
|
|
|
30975
31172
|
return new Set(Object.keys(servers));
|
|
30976
31173
|
}
|
|
30977
31174
|
function globalConfigRoot(globalRoot) {
|
|
30978
|
-
return
|
|
31175
|
+
return dirname35(dirname35(globalWorkspaceConfigPath(globalRoot)));
|
|
30979
31176
|
}
|
|
30980
31177
|
function ownedByWorkspace(owner, desiredOwner, workspaceRoot, ownsSubWorkspaces) {
|
|
30981
31178
|
if (owner === desiredOwner) return true;
|
|
@@ -31123,7 +31320,7 @@ function targetLabel(target) {
|
|
|
31123
31320
|
init_workspace();
|
|
31124
31321
|
init_run_as_identity();
|
|
31125
31322
|
init_fs();
|
|
31126
|
-
import { basename as basename22, dirname as
|
|
31323
|
+
import { basename as basename22, dirname as dirname36, join as join50, resolve as resolve35 } from "path";
|
|
31127
31324
|
var runtimeMarkers = [
|
|
31128
31325
|
{ adapter: "openclaw", dirs: [".openclaw", ".clawdbot", ".moltbot"] },
|
|
31129
31326
|
{ adapter: "claude", dirs: [".claude"] },
|
|
@@ -31249,7 +31446,7 @@ async function detectRuntimeTargets(cwd = process.cwd(), adapterFilter) {
|
|
|
31249
31446
|
if (adapterFilter && marker.adapter !== adapterFilter) continue;
|
|
31250
31447
|
for (const dir of marker.dirs) {
|
|
31251
31448
|
if (basename22(root) === dir) {
|
|
31252
|
-
matches.push({ adapter: marker.adapter, targetRoot:
|
|
31449
|
+
matches.push({ adapter: marker.adapter, targetRoot: dirname36(root) });
|
|
31253
31450
|
} else if (await pathExists(join50(root, dir))) {
|
|
31254
31451
|
matches.push({ adapter: marker.adapter, targetRoot: root });
|
|
31255
31452
|
}
|
|
@@ -31296,7 +31493,7 @@ function dedupeTargets(matches) {
|
|
|
31296
31493
|
function runtimeScanRoot(request) {
|
|
31297
31494
|
const root = resolve35(request.targetRoot ?? request.cwd ?? process.cwd());
|
|
31298
31495
|
if (request.targetRoot) return root;
|
|
31299
|
-
return runtimeMarkers.some((marker) => marker.dirs.includes(basename22(root))) ?
|
|
31496
|
+
return runtimeMarkers.some((marker) => marker.dirs.includes(basename22(root))) ? dirname36(root) : root;
|
|
31300
31497
|
}
|
|
31301
31498
|
|
|
31302
31499
|
// src/lifecycle/profile.ts
|
|
@@ -31630,7 +31827,7 @@ init_selection();
|
|
|
31630
31827
|
// src/cli/update-check.ts
|
|
31631
31828
|
import { mkdir as mkdir26, readFile as readFile39, writeFile as writeFile22 } from "fs/promises";
|
|
31632
31829
|
import { homedir as homedir14 } from "os";
|
|
31633
|
-
import { dirname as
|
|
31830
|
+
import { dirname as dirname37, join as join51 } from "path";
|
|
31634
31831
|
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
31635
31832
|
var DEFAULT_TIMEOUT_MS = 300;
|
|
31636
31833
|
var REGISTRY_URL = "https://registry.npmjs.org/agentwheel";
|
|
@@ -31683,7 +31880,7 @@ async function readCache(path) {
|
|
|
31683
31880
|
}
|
|
31684
31881
|
}
|
|
31685
31882
|
async function writeCache(path, cache) {
|
|
31686
|
-
await mkdir26(
|
|
31883
|
+
await mkdir26(dirname37(path), { recursive: true });
|
|
31687
31884
|
await writeFile22(path, `${JSON.stringify(cache, null, 2)}
|
|
31688
31885
|
`, "utf8");
|
|
31689
31886
|
}
|
|
@@ -31919,11 +32116,11 @@ init_graph_lock();
|
|
|
31919
32116
|
|
|
31920
32117
|
// src/cli/version.ts
|
|
31921
32118
|
import { readFileSync as readFileSync2 } from "fs";
|
|
31922
|
-
import { dirname as
|
|
32119
|
+
import { dirname as dirname38, join as join54 } from "path";
|
|
31923
32120
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
31924
32121
|
var FALLBACK_VERSION = "0.0.0";
|
|
31925
32122
|
function resolveCliVersion() {
|
|
31926
|
-
let dir =
|
|
32123
|
+
let dir = dirname38(fileURLToPath3(import.meta.url));
|
|
31927
32124
|
while (true) {
|
|
31928
32125
|
try {
|
|
31929
32126
|
const pkg = JSON.parse(readFileSync2(join54(dir, "package.json"), "utf8"));
|
|
@@ -31932,7 +32129,7 @@ function resolveCliVersion() {
|
|
|
31932
32129
|
}
|
|
31933
32130
|
} catch {
|
|
31934
32131
|
}
|
|
31935
|
-
const parent =
|
|
32132
|
+
const parent = dirname38(dir);
|
|
31936
32133
|
if (parent === dir) return FALLBACK_VERSION;
|
|
31937
32134
|
dir = parent;
|
|
31938
32135
|
}
|
|
@@ -32841,7 +33038,7 @@ init_graph_lock();
|
|
|
32841
33038
|
init_manifest();
|
|
32842
33039
|
import { createHash as createHash26 } from "crypto";
|
|
32843
33040
|
import { lstat as lstat8, readdir as readdir17 } from "fs/promises";
|
|
32844
|
-
import { basename as basename23, dirname as
|
|
33041
|
+
import { basename as basename23, dirname as dirname39, join as join57, posix as posix8, relative as relative18, resolve as resolve42 } from "path";
|
|
32845
33042
|
async function inventoryHistoricalLocks(fleetRoot) {
|
|
32846
33043
|
const root = join57(fleetRoot, ".agentwheel", "locks");
|
|
32847
33044
|
const found = [];
|
|
@@ -32888,7 +33085,7 @@ async function planLegacyRecovery(input) {
|
|
|
32888
33085
|
const { graphPlan, installRoot, targetKey: targetKey2, adapter, installationType, historicalLocks, transport } = input;
|
|
32889
33086
|
assertCompleteGraphPlan(graphPlan);
|
|
32890
33087
|
const binding = {
|
|
32891
|
-
targetLockDir:
|
|
33088
|
+
targetLockDir: dirname39(graphPlan.graphLockPath),
|
|
32892
33089
|
stableLockPath: graphPlan.graphLockPath,
|
|
32893
33090
|
stableStateKey: graphPlan.plan.stateKey,
|
|
32894
33091
|
currentFingerprint: graphPlan.targetFingerprint,
|
|
@@ -33000,7 +33197,7 @@ function claimFor(item, entry, locks, binding) {
|
|
|
33000
33197
|
const evidence = [];
|
|
33001
33198
|
const owner = "workspaceOwner" in entry ? entry.workspaceOwner : legacyUnownedWorkspaceOwner;
|
|
33002
33199
|
const sameRoot = binding.transportKind === "ssh" ? posix8.normalize(item.manifest.targetRoot) === posix8.normalize(binding.installRoot) : resolve42(item.manifest.targetRoot) === resolve42(binding.installRoot);
|
|
33003
|
-
const inTargetDir = matches.filter((candidate) => resolve42(
|
|
33200
|
+
const inTargetDir = matches.filter((candidate) => resolve42(dirname39(candidate.path)) === resolve42(binding.targetLockDir));
|
|
33004
33201
|
const boundLocks = inTargetDir.filter((candidate) => lockBindsState(candidate, item, binding));
|
|
33005
33202
|
if (owner !== binding.expectedOwner) evidence.push("workspace owner differs from selected Fleet target");
|
|
33006
33203
|
if (item.manifest.version !== 2 || item.manifest.installationType !== binding.installationType) evidence.push("installation type differs or manifest is legacy v1");
|
|
@@ -35049,7 +35246,7 @@ init_fleet();
|
|
|
35049
35246
|
// src/lifecycle/fleet-normalize.ts
|
|
35050
35247
|
import { createHash as createHash31 } from "crypto";
|
|
35051
35248
|
import { homedir as homedir17 } from "os";
|
|
35052
|
-
import { dirname as
|
|
35249
|
+
import { dirname as dirname41, isAbsolute as isAbsolute16, join as join65, relative as relative21, resolve as resolve47 } from "path";
|
|
35053
35250
|
init_manifest2();
|
|
35054
35251
|
init_paths();
|
|
35055
35252
|
init_merge_removal();
|
|
@@ -35075,7 +35272,7 @@ init_caller_write_trust();
|
|
|
35075
35272
|
import { AsyncLocalStorage } from "async_hooks";
|
|
35076
35273
|
import { readFile as readLocalFile, readdir as readLocalDir, rm as removeLocal, mkdir as mkdir27, open as open6, rename as rename9 } from "fs/promises";
|
|
35077
35274
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
35078
|
-
import { dirname as
|
|
35275
|
+
import { dirname as dirname40, isAbsolute as isAbsolute15, relative as relative20, resolve as resolve46, sep as sep11 } from "path";
|
|
35079
35276
|
var contexts = new AsyncLocalStorage();
|
|
35080
35277
|
var inside = (root, path) => {
|
|
35081
35278
|
const rel = relative20(root, resolve46(path));
|
|
@@ -35137,7 +35334,7 @@ async function normalizationRemove(path, options) {
|
|
|
35137
35334
|
}
|
|
35138
35335
|
await assertNormalizationCallerWrite(path);
|
|
35139
35336
|
await removeLocal(path, options);
|
|
35140
|
-
if (normalizationIdentities().length) await syncMetadataPath(
|
|
35337
|
+
if (normalizationIdentities().length) await syncMetadataPath(dirname40(path), true);
|
|
35141
35338
|
}
|
|
35142
35339
|
async function normalizationWriteJson(path, data) {
|
|
35143
35340
|
const transport = normalizationTransport(path);
|
|
@@ -35151,7 +35348,7 @@ async function normalizationWriteJson(path, data) {
|
|
|
35151
35348
|
}
|
|
35152
35349
|
await assertNormalizationCallerWrite(path);
|
|
35153
35350
|
await assertNoSymlinkPath2(path);
|
|
35154
|
-
await mkdir27(
|
|
35351
|
+
await mkdir27(dirname40(path), { recursive: true, mode: 448 });
|
|
35155
35352
|
await assertNormalizationCallerWrite(path);
|
|
35156
35353
|
const temporary = `${path}.pending-${randomUUID8()}`;
|
|
35157
35354
|
try {
|
|
@@ -35165,8 +35362,8 @@ async function normalizationWriteJson(path, data) {
|
|
|
35165
35362
|
await file2.close();
|
|
35166
35363
|
}
|
|
35167
35364
|
await rename9(temporary, path);
|
|
35168
|
-
await syncMetadataPath(
|
|
35169
|
-
await syncMetadataPath(
|
|
35365
|
+
await syncMetadataPath(dirname40(path), true);
|
|
35366
|
+
await syncMetadataPath(dirname40(dirname40(path)), true);
|
|
35170
35367
|
} finally {
|
|
35171
35368
|
await removeLocal(temporary, { force: true });
|
|
35172
35369
|
}
|
|
@@ -36217,7 +36414,7 @@ async function releasedTargetStateForGraph(scope, graph, identityFleetId = scope
|
|
|
36217
36414
|
...current,
|
|
36218
36415
|
stateKey,
|
|
36219
36416
|
targetFingerprint,
|
|
36220
|
-
graphLockPath: join65(
|
|
36417
|
+
graphLockPath: join65(dirname41(graph.path), `${targetFingerprint}.graph-lock.json`),
|
|
36221
36418
|
manifestPath: installManifestPath(current.installRoot, current.adapter, {
|
|
36222
36419
|
installationType: current.installationType,
|
|
36223
36420
|
stateKey
|
|
@@ -37471,7 +37668,7 @@ ownershipCommand.command("recovery-plan").description("write a read-only per-pat
|
|
|
37471
37668
|
const adapter = await resolveAdapterForTarget(target, {});
|
|
37472
37669
|
const transport = transportForTarget(target);
|
|
37473
37670
|
const requestedReport = normalizeCliPath(options.report);
|
|
37474
|
-
const reportPath = join66(await realpath4(
|
|
37671
|
+
const reportPath = join66(await realpath4(dirname42(requestedReport)), basename24(requestedReport));
|
|
37475
37672
|
const reportInsideTarget = relative22(resolve48(target.targetRoot), reportPath);
|
|
37476
37673
|
if (reportInsideTarget === "" || !reportInsideTarget.startsWith("..") && !isAbsolute17(reportInsideTarget)) {
|
|
37477
37674
|
throw new Error("Recovery report must be outside the runtime target root.");
|
|
@@ -37499,20 +37696,43 @@ ownershipCommand.command("recovery-plan").description("write a read-only per-pat
|
|
|
37499
37696
|
console.log(JSON.stringify(report.counts));
|
|
37500
37697
|
});
|
|
37501
37698
|
});
|
|
37502
|
-
ownershipCommand.command("retire-stale").description("retire stale source-manifest ownership already covered by one Fleet manifest").requiredOption("--from-workspace-root <path>", "exact stale workspace owner root").option("--from-fleet-id <id>", "exact stale Fleet owner id for same-Fleet duplicate state").requiredOption("--to-workspace-root <path>", "registered destination Fleet root").requiredOption("--source-state-key <key>", "exact source install-manifest state key").option("--destination-state-key <key>", "exact Fleet-owned destination install-manifest state key (defaults to the stable target state)").
|
|
37699
|
+
ownershipCommand.command("retire-stale").description("retire stale source-manifest ownership already covered by one Fleet manifest").requiredOption("--from-workspace-root <path>", "exact stale workspace owner root").option("--from-fleet-id <id>", "exact stale Fleet owner id for same-Fleet duplicate state").requiredOption("--to-workspace-root <path>", "registered destination Fleet root").requiredOption("--source-state-key <key>", "exact source install-manifest state key").option("--destination-state-key <key>", "exact Fleet-owned destination install-manifest state key (defaults to the stable target state)").option("--to-fleet <id>", "registered destination Fleet owner, independent of target workspace scope").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet (also the destination owner unless --to-fleet is set)").option("--adapter <adapter>", "built-in adapter").option("-i, --installation-type <type>", "installation type (for example local or user)").option("--adapter-config <path>", "adapter JSON/JSONC file").option("--adapter-module <path>", "local programmatic adapter module").option("--allow-adapter-code", "allow loading local adapter code", false).option("-t, --target-root <path>", "runtime/project root").option("--agent <name>", "named destination Fleet agent").option("--profile <name>", "destination Fleet profile resolving to one target").option("--plan-digest <sha256>", "reviewed plan digest; required with --apply").option("--expected-source-revision <sha256>", "reviewed source manifest revision; required with --apply").option("--expected-destination-revision <sha256>", "reviewed destination manifest revision; required with --apply").option("--expected-inventory-revision <sha256>", "reviewed runtime manifest inventory revision; required with --apply").option("--abandon-incomplete-merge-owner", "explicitly retire incomplete legacy merge metadata without changing runtime bytes", false).option("--apply", "apply the exact reviewed metadata-only retirement", false).option("--json", "print the complete deterministic plan as JSON", false).action(async (options) => {
|
|
37503
37700
|
const normalizedOptions = normalizeRuntimeScopeOptions(options);
|
|
37504
|
-
const
|
|
37701
|
+
const destinationFleet = options.toFleet ?? options.fleet;
|
|
37702
|
+
if (!destinationFleet) throw new Error("Stale ownership retirement requires --to-fleet <id> or the legacy --fleet <id> scope.");
|
|
37703
|
+
const fleet = await showRegisteredFleet(destinationFleet);
|
|
37505
37704
|
const toWorkspaceRoot = normalizeCliPath(options.toWorkspaceRoot);
|
|
37506
37705
|
if (resolve48(fleet.root) !== resolve48(toWorkspaceRoot)) {
|
|
37507
|
-
throw new Error(`Destination Fleet '${
|
|
37706
|
+
throw new Error(`Destination Fleet '${destinationFleet}' is registered at ${fleet.root}, not ${toWorkspaceRoot}.`);
|
|
37707
|
+
}
|
|
37708
|
+
const assertDestinationWorkspace = async (workspaceRoot, fleetId) => {
|
|
37709
|
+
const fleetRoot = resolve48(fleet.root);
|
|
37710
|
+
const canonicalFleetRoot = await realpath4(fleetRoot);
|
|
37711
|
+
const within = (root, path) => {
|
|
37712
|
+
const suffix = relative22(root, path);
|
|
37713
|
+
return suffix === "" || suffix !== ".." && !suffix.startsWith(`..${sep12}`) && !isAbsolute17(suffix);
|
|
37714
|
+
};
|
|
37715
|
+
if (canonicalFleetRoot !== fleetRoot || fleetId !== void 0 && fleetId !== fleet.id || !within(fleetRoot, resolve48(workspaceRoot)) || !within(canonicalFleetRoot, await realpath4(workspaceRoot))) {
|
|
37716
|
+
throw new Error(`Resolved target workspace does not belong to destination Fleet '${fleet.id}'.`);
|
|
37717
|
+
}
|
|
37718
|
+
};
|
|
37719
|
+
if (options.toFleet) {
|
|
37720
|
+
await resolveWorkspaceScope({ fleet: fleet.id });
|
|
37721
|
+
if (normalizedOptions.targetRoot && !normalizedOptions.workspaceTargetDerived) {
|
|
37722
|
+
await assertDestinationWorkspace(normalizedOptions.targetRoot);
|
|
37723
|
+
}
|
|
37724
|
+
const scope = await resolveCliWorkspaceScope(normalizedOptions);
|
|
37725
|
+
await assertDestinationWorkspace(scope.root, scope.fleetId);
|
|
37508
37726
|
}
|
|
37509
37727
|
const targets = await resolveCliTargets(normalizedOptions);
|
|
37510
37728
|
if (targets.length !== 1) {
|
|
37511
37729
|
throw new Error(`Stale ownership retirement requires exactly one destination Fleet target, found ${targets.length}.`);
|
|
37512
37730
|
}
|
|
37513
37731
|
const target = targets[0];
|
|
37514
|
-
if (
|
|
37515
|
-
|
|
37732
|
+
if (options.toFleet) {
|
|
37733
|
+
await assertDestinationWorkspace(target.workspaceRoot, target.fleetId);
|
|
37734
|
+
} else if (target.fleetId !== fleet.id || resolve48(target.workspaceRoot) !== resolve48(fleet.root)) {
|
|
37735
|
+
throw new Error(`Resolved target does not belong to destination Fleet '${fleet.id}'.`);
|
|
37516
37736
|
}
|
|
37517
37737
|
const adapterOptions = adapterOptionsForTarget(target, normalizedOptions);
|
|
37518
37738
|
const adapter = await resolveAdapterForTarget(target, adapterOptions);
|
|
@@ -37536,7 +37756,8 @@ ownershipCommand.command("retire-stale").description("retire stale source-manife
|
|
|
37536
37756
|
transport: transportForTarget(target)
|
|
37537
37757
|
};
|
|
37538
37758
|
const result = options.apply ? await applyRetireStaleOwnership(request) : await planRetireStaleOwnership(request);
|
|
37539
|
-
const
|
|
37759
|
+
const workspaceArgs = options.toFleet ? options.fleet ? ["--fleet", options.fleet] : options.user ? ["--user"] : options.targetRoot ? [] : ["--local"] : ["--fleet", fleet.id];
|
|
37760
|
+
const targetArgs = options.profile ? ["--profile", options.profile] : target.agentName ? ["--agent", target.agentName] : ["--adapter", adapter.name, ...workspaceArgs.length ? [] : ["--target-root", target.targetRoot]];
|
|
37540
37761
|
const applyArgs = [
|
|
37541
37762
|
"agentwheel",
|
|
37542
37763
|
"ownership",
|
|
@@ -37550,8 +37771,9 @@ ownershipCommand.command("retire-stale").description("retire stale source-manife
|
|
|
37550
37771
|
request.sourceStateKey,
|
|
37551
37772
|
"--destination-state-key",
|
|
37552
37773
|
request.destinationStateKey,
|
|
37553
|
-
"--fleet",
|
|
37554
|
-
|
|
37774
|
+
...options.toFleet ? ["--to-fleet", request.toFleetId] : [],
|
|
37775
|
+
...workspaceArgs,
|
|
37776
|
+
...(options.profile || target.agentName) && options.targetRoot ? ["--target-root", normalizedOptions.targetRoot] : [],
|
|
37555
37777
|
...targetArgs,
|
|
37556
37778
|
"--installation-type",
|
|
37557
37779
|
installationType,
|
|
@@ -38791,13 +39013,23 @@ function preserveUnrelatedGraphPackages(current, previous, selectedCurrentNodeId
|
|
|
38791
39013
|
for (const root of selectedCurrentRoots) {
|
|
38792
39014
|
if (!previous.canonical.roots.some((candidate) => candidate.rootId === root.rootId)) roots.push(root);
|
|
38793
39015
|
}
|
|
39016
|
+
const preservedNodeIds = /* @__PURE__ */ new Set();
|
|
39017
|
+
if (selectedRootIds.size > 0) {
|
|
39018
|
+
for (const root of previous.canonical.roots) {
|
|
39019
|
+
if (!selectedRootIds.has(root.rootId)) {
|
|
39020
|
+
for (const id of graphRootClosure(previous, root.rootId)) preservedNodeIds.add(id);
|
|
39021
|
+
}
|
|
39022
|
+
}
|
|
39023
|
+
}
|
|
39024
|
+
const replacedOwners = new Set([...selectedPreviousNodeIds].filter((id) => !preservedNodeIds.has(id)));
|
|
39025
|
+
for (const id of selectedRootIds) replacedOwners.add(`workspace:${id}`);
|
|
38794
39026
|
const currentNodes = current.canonical.nodes.filter((node) => selectedCurrentNodeIds.has(node.id));
|
|
38795
|
-
const previousNodes = previous.canonical.nodes.filter((node) => !selectedPreviousNodeIds.has(node.id));
|
|
39027
|
+
const previousNodes = previous.canonical.nodes.filter((node) => !selectedPreviousNodeIds.has(node.id) || preservedNodeIds.has(node.id)).map((node) => ({ ...node, requiredBy: node.requiredBy.filter((owner) => !replacedOwners.has(owner)) }));
|
|
38796
39028
|
const selectedCurrentArtifacts = current.canonical.artifacts.filter((artifact) => selectedCurrentNodeIds.has(artifact.graphNodeId));
|
|
38797
|
-
const previousArtifacts = previous.canonical.artifacts.filter((artifact) => !selectedPreviousNodeIds.has(artifact.graphNodeId));
|
|
39029
|
+
const previousArtifacts = previous.canonical.artifacts.filter((artifact) => !selectedPreviousNodeIds.has(artifact.graphNodeId) || preservedNodeIds.has(artifact.graphNodeId)).map((artifact) => ({ ...artifact, owners: artifact.owners.filter((owner) => !replacedOwners.has(owner)) }));
|
|
38798
39030
|
const edgeTouchesSelected = (from, to) => selectedCurrentNodeIds.has(from) || selectedCurrentNodeIds.has(to);
|
|
38799
|
-
const previousEdge = (edge) => !selectedPreviousNodeIds.has(edge.from) && !selectedPreviousNodeIds.has(edge.to);
|
|
38800
|
-
const previousIncludeEdge = (edge) => !selectedPreviousNodeIds.has(edge.fromNodeId) && !selectedPreviousNodeIds.has(edge.toNodeId);
|
|
39031
|
+
const previousEdge = (edge) => preservedNodeIds.has(edge.from) || !selectedPreviousNodeIds.has(edge.from) && !selectedPreviousNodeIds.has(edge.to);
|
|
39032
|
+
const previousIncludeEdge = (edge) => preservedNodeIds.has(edge.fromNodeId) || !selectedPreviousNodeIds.has(edge.fromNodeId) && !selectedPreviousNodeIds.has(edge.toNodeId);
|
|
38801
39033
|
const selectedCurrentRootIds = new Set(selectedCurrentRoots.map((root) => root.graphNodeId));
|
|
38802
39034
|
const currentRootOrNode = (id) => selectedCurrentNodeIds.has(id) || selectedCurrentRootIds.has(id);
|
|
38803
39035
|
const previousRootOrNode = (id) => selectedPreviousNodeIds.has(id) || previous.canonical.roots.some((root) => selectedRootIds.has(root.rootId) && root.graphNodeId === id);
|
|
@@ -38806,28 +39038,38 @@ function preserveUnrelatedGraphPackages(current, previous, selectedCurrentNodeId
|
|
|
38806
39038
|
canonical: {
|
|
38807
39039
|
...current.canonical,
|
|
38808
39040
|
roots,
|
|
38809
|
-
nodes: [...currentNodes
|
|
38810
|
-
|
|
39041
|
+
nodes: uniqueBy([...currentNodes.map((node) => {
|
|
39042
|
+
const old = previousNodes.find((candidate) => candidate.id === node.id);
|
|
39043
|
+
return old ? {
|
|
39044
|
+
...node,
|
|
39045
|
+
requiredBy: sortedUniqueValues([...node.requiredBy, ...old.requiredBy]),
|
|
39046
|
+
selected: sortedUniqueValues([...node.selected, ...old.selected])
|
|
39047
|
+
} : node;
|
|
39048
|
+
}), ...previousNodes], (node) => node.id),
|
|
39049
|
+
edges: uniqueBy([
|
|
38811
39050
|
...current.canonical.edges.filter((edge) => edgeTouchesSelected(edge.from, edge.to)),
|
|
38812
39051
|
...previous.canonical.edges.filter(previousEdge)
|
|
38813
|
-
],
|
|
38814
|
-
includeEdges: [
|
|
39052
|
+
], (edge) => `${edge.from}\0${edge.alias}\0${edge.to}`),
|
|
39053
|
+
includeEdges: uniqueBy([
|
|
38815
39054
|
...current.canonical.includeEdges.filter((edge) => edgeTouchesSelected(edge.fromNodeId, edge.toNodeId)),
|
|
38816
39055
|
...previous.canonical.includeEdges.filter(previousIncludeEdge)
|
|
38817
|
-
],
|
|
38818
|
-
artifacts: [...selectedCurrentArtifacts
|
|
38819
|
-
|
|
39056
|
+
], graphIncludeEdgeIdentity),
|
|
39057
|
+
artifacts: uniqueBy([...selectedCurrentArtifacts.map((artifact) => {
|
|
39058
|
+
const old = previousArtifacts.find((candidate) => graphArtifactIdentity2(candidate) === graphArtifactIdentity2(artifact));
|
|
39059
|
+
return old ? { ...artifact, owners: sortedUniqueValues([...artifact.owners, ...old.owners]) } : artifact;
|
|
39060
|
+
}), ...previousArtifacts], graphArtifactIdentity2),
|
|
39061
|
+
namespacing: uniqueBy([
|
|
38820
39062
|
...current.canonical.namespacing.filter((entry) => currentRootOrNode(entry.graphNodeId)),
|
|
38821
|
-
...previous.canonical.namespacing.filter((entry) => !previousRootOrNode(entry.graphNodeId))
|
|
38822
|
-
],
|
|
38823
|
-
overrides: [
|
|
39063
|
+
...previous.canonical.namespacing.filter((entry) => !previousRootOrNode(entry.graphNodeId) || preservedNodeIds.has(entry.graphNodeId))
|
|
39064
|
+
], (entry) => `${entry.graphNodeId}\0${entry.type}\0${entry.name}`),
|
|
39065
|
+
overrides: uniqueBy([
|
|
38824
39066
|
...current.canonical.overrides.filter((entry) => currentRootOrNode(entry.graphNodeId) || currentRootOrNode(entry.overriddenGraphNodeId)),
|
|
38825
|
-
...previous.canonical.overrides.filter((entry) => !previousRootOrNode(entry.graphNodeId) && !previousRootOrNode(entry.overriddenGraphNodeId))
|
|
38826
|
-
],
|
|
38827
|
-
plainNameIncumbents: [
|
|
39067
|
+
...previous.canonical.overrides.filter((entry) => !selectedRootIds.has(entry.rootId) && (!previousRootOrNode(entry.graphNodeId) && !previousRootOrNode(entry.overriddenGraphNodeId) || preservedNodeIds.has(entry.graphNodeId)))
|
|
39068
|
+
], (entry) => `${entry.rootId}\0${entry.selector}`),
|
|
39069
|
+
plainNameIncumbents: uniqueBy([
|
|
38828
39070
|
...current.canonical.plainNameIncumbents.filter((entry) => currentRootOrNode(entry.graphNodeId)),
|
|
38829
|
-
...previous.canonical.plainNameIncumbents.filter((entry) => !previousRootOrNode(entry.graphNodeId))
|
|
38830
|
-
]
|
|
39071
|
+
...previous.canonical.plainNameIncumbents.filter((entry) => !previousRootOrNode(entry.graphNodeId) || preservedNodeIds.has(entry.graphNodeId))
|
|
39072
|
+
], (entry) => `${entry.adapter}\0${entry.targetFingerprint}\0${entry.type}\0${entry.name}`)
|
|
38831
39073
|
}
|
|
38832
39074
|
});
|
|
38833
39075
|
}
|
|
@@ -39157,16 +39399,31 @@ function uniqueBy(values, key) {
|
|
|
39157
39399
|
return true;
|
|
39158
39400
|
});
|
|
39159
39401
|
}
|
|
39160
|
-
function scopeInstallPlanToRoot(result, rootId, manifest) {
|
|
39402
|
+
function scopeInstallPlanToRoot(result, rootId, manifest, previousLock) {
|
|
39161
39403
|
const scopedOwners = scopedGraphOwnerKeys(result, rootId);
|
|
39404
|
+
const exclusiveOwners = new Set(scopedOwners);
|
|
39405
|
+
if (previousLock) {
|
|
39406
|
+
for (const id of graphRootClosure(previousLock, rootId)) exclusiveOwners.add(id);
|
|
39407
|
+
for (const root of previousLock.canonical.roots) {
|
|
39408
|
+
if (root.rootId === rootId) continue;
|
|
39409
|
+
for (const id of graphRootClosure(previousLock, root.rootId)) exclusiveOwners.delete(id);
|
|
39410
|
+
}
|
|
39411
|
+
}
|
|
39162
39412
|
const manifestByPath = new Map((manifest?.entries ?? []).map((entry) => [entry.path, entry]));
|
|
39163
39413
|
const preservedPaths = /* @__PURE__ */ new Set();
|
|
39164
39414
|
const plannedPaths = /* @__PURE__ */ new Set();
|
|
39165
39415
|
const operations = [];
|
|
39166
39416
|
for (const operation of result.plan.operations) {
|
|
39167
39417
|
plannedPaths.add(operation.relativeDestPath);
|
|
39168
|
-
|
|
39169
|
-
|
|
39418
|
+
const stale = operation.action === "remove" || operation.action === "drift" && !operation.desiredHash;
|
|
39419
|
+
const exclusivelyOwned = operation.owners?.length && operation.owners.every((owner) => exclusiveOwners.has(owner));
|
|
39420
|
+
if (stale ? exclusivelyOwned : operationBelongsToScopedRoot(operation, scopedOwners)) {
|
|
39421
|
+
const entry2 = manifestByPath.get(operation.relativeDestPath);
|
|
39422
|
+
const foreignOwners = entry2 && "owners" in entry2 && Array.isArray(entry2.owners) ? entry2.owners.filter((owner) => typeof owner === "string" && !exclusiveOwners.has(owner)) : [];
|
|
39423
|
+
operations.push(stale || !operation.owners ? operation : {
|
|
39424
|
+
...operation,
|
|
39425
|
+
owners: sortedUniqueValues([...operation.owners, ...foreignOwners])
|
|
39426
|
+
});
|
|
39170
39427
|
continue;
|
|
39171
39428
|
}
|
|
39172
39429
|
const entry = manifestByPath.get(operation.relativeDestPath);
|
|
@@ -39192,7 +39449,7 @@ function scopeInstallPlanToRoot(result, rootId, manifest) {
|
|
|
39192
39449
|
};
|
|
39193
39450
|
}
|
|
39194
39451
|
function scopeUpdatePlanToRoot(result, rootId, previousLock, manifest) {
|
|
39195
|
-
const scoped = scopeInstallPlanToRoot(result, rootId, manifest);
|
|
39452
|
+
const scoped = scopeInstallPlanToRoot(result, rootId, manifest, previousLock);
|
|
39196
39453
|
const selectedCurrentNodeIds = graphRootClosure(scoped.bundle.graphLock, rootId);
|
|
39197
39454
|
const selectedPreviousNodeIds = graphRootClosure(previousLock, rootId);
|
|
39198
39455
|
const graphLock = preserveUnrelatedGraphPackages(
|
|
@@ -40434,7 +40691,7 @@ async function initPackage(root) {
|
|
|
40434
40691
|
await writeFile24(instructionsPath, "# Agent Instructions\n", "utf8");
|
|
40435
40692
|
}
|
|
40436
40693
|
async function defaultBootstrapPackage(_root) {
|
|
40437
|
-
const packageRoot = await findAgentwheelPackageRoot(
|
|
40694
|
+
const packageRoot = await findAgentwheelPackageRoot(dirname42(fileURLToPath4(import.meta.url)));
|
|
40438
40695
|
if (!packageRoot) return void 0;
|
|
40439
40696
|
return {
|
|
40440
40697
|
name: "agentwheel",
|
|
@@ -40481,7 +40738,7 @@ async function findAgentwheelPackageRoot(start) {
|
|
|
40481
40738
|
let current = resolve48(start);
|
|
40482
40739
|
while (true) {
|
|
40483
40740
|
if (await findPackageManifestPath(current, { warnLegacy: false })) return current;
|
|
40484
|
-
const parent =
|
|
40741
|
+
const parent = dirname42(current);
|
|
40485
40742
|
if (parent === current) return void 0;
|
|
40486
40743
|
current = parent;
|
|
40487
40744
|
}
|