agentwheel 0.21.6 → 0.21.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -583,7 +583,7 @@ async function withFilesystemLock(lockPath, timeoutMs, fn, description = "cache"
583
583
  if (Date.now() - started > timeoutMs) {
584
584
  throw new Error(`Timed out waiting for ${description} lock at ${lockPath}`);
585
585
  }
586
- await new Promise((resolve45) => setTimeout(resolve45, 50));
586
+ await new Promise((resolve46) => setTimeout(resolve46, 50));
587
587
  }
588
588
  }
589
589
  try {
@@ -853,7 +853,7 @@ var init_protocol = __esm({
853
853
  // src/mutation/process.ts
854
854
  import { spawn } from "child_process";
855
855
  async function runProcess(command, args, options = {}) {
856
- return new Promise((resolve45, reject) => {
856
+ return new Promise((resolve46, reject) => {
857
857
  const useProcessGroup = options.killProcessGroup === true && process.platform !== "win32";
858
858
  const child = spawn(command, args, {
859
859
  cwd: options.cwd,
@@ -913,7 +913,7 @@ async function runProcess(command, args, options = {}) {
913
913
  reject(new Error(`${command} exited ${exitCode}${detail ? `: ${detail}` : ""}`));
914
914
  return;
915
915
  }
916
- resolve45(result);
916
+ resolve46(result);
917
917
  });
918
918
  if (options.input !== void 0) child.stdin.end(options.input);
919
919
  else child.stdin.end();
@@ -1961,13 +1961,13 @@ async function spawnWithInput(command, args, input) {
1961
1961
  if (result.stderr) throw new Error(result.stderr);
1962
1962
  }
1963
1963
  function waitForProcess(child, label) {
1964
- return new Promise((resolve45, reject) => {
1964
+ return new Promise((resolve46, reject) => {
1965
1965
  const stderr = [];
1966
1966
  child.stderr?.on("data", (chunk) => stderr.push(chunk));
1967
1967
  child.on("error", reject);
1968
1968
  child.on("close", (code) => {
1969
1969
  const message = Buffer.concat(stderr).toString("utf8");
1970
- if (code === 0) resolve45({ stderr: "" });
1970
+ if (code === 0) resolve46({ stderr: "" });
1971
1971
  else reject(new Error(`${label} exited ${code}${message ? `: ${message}` : ""}`));
1972
1972
  });
1973
1973
  });
@@ -3267,10 +3267,197 @@ var init_workspace = __esm({
3267
3267
  }
3268
3268
  });
3269
3269
 
3270
+ // src/model/fleet.ts
3271
+ import { lstat, readFile as readFile11, realpath } from "fs/promises";
3272
+ import { homedir as homedir5 } from "os";
3273
+ import { isAbsolute as isAbsolute7, relative as relative5, resolve as resolve12 } from "path";
3274
+ async function resolveWorkspaceScope(request = {}) {
3275
+ const selected = [request.user === true, request.local === true, request.fleet !== void 0].filter(Boolean).length;
3276
+ if (selected > 1) {
3277
+ throw new Error("Choose exactly one workspace selector: --user, --local, or --fleet <id>.");
3278
+ }
3279
+ const globalRoot = resolve12(request.globalRoot ?? homedir5());
3280
+ if (request.user) {
3281
+ const config2 = await readWorkspaceConfig(globalRoot);
3282
+ assertNonFleetScope("user", config2);
3283
+ return { kind: "user", root: globalRoot, config: config2 };
3284
+ }
3285
+ if (request.fleet !== void 0) {
3286
+ const id = fleetIdSchema.parse(request.fleet);
3287
+ const registration = await showRegisteredFleet(id, { globalRoot });
3288
+ const root = await assertCanonicalDirectory(registration.root, `Registered fleet '${id}' root`);
3289
+ const config2 = await readRequiredConfig(root, `fleet '${id}'`);
3290
+ assertFleetContract(id, registration, config2);
3291
+ return { kind: "fleet", root, fleetId: id, config: config2 };
3292
+ }
3293
+ const cwd = resolve12(request.cwd ?? process.cwd());
3294
+ const discoveredRoot = await findExistingWorkspaceRoot(cwd);
3295
+ if (!discoveredRoot || discoveredRoot === globalRoot) {
3296
+ if (request.local === true && cwd !== globalRoot) {
3297
+ return { kind: "local", root: cwd, config: await readWorkspaceConfig(cwd) };
3298
+ }
3299
+ throw missingScopeError(request.local === true ? "local" : "implicit local");
3300
+ }
3301
+ const config = await readRequiredConfig(discoveredRoot, "local");
3302
+ assertNonFleetScope("local", config);
3303
+ return { kind: "local", root: discoveredRoot, config };
3304
+ }
3305
+ async function registerFleet(request) {
3306
+ const id = fleetIdSchema.parse(request.id);
3307
+ const requiredPackages = sortedUnique3(request.requiredPackages);
3308
+ if (requiredPackages.length === 0) throw new Error("Fleet registration requires at least one --required-package <name>.");
3309
+ const globalRoot = resolve12(request.globalRoot ?? homedir5());
3310
+ const home = await readWorkspaceConfig(globalRoot);
3311
+ if (supportsFleetConfig(home) && home.fleetId) {
3312
+ throw new Error(`The home config is fleet '${home.fleetId}', so it cannot own the global fleet registry.`);
3313
+ }
3314
+ const existing = supportsFleetConfig(home) ? await canonicalizeExistingFleetRoots(home.fleets, globalRoot) : {};
3315
+ if (existing[id]) throw new Error(`Fleet '${id}' is already registered.`);
3316
+ const root = await assertCanonicalDirectory(request.root, `Fleet '${id}' root`);
3317
+ const duplicateRoot = Object.entries(existing).find(([, value]) => value.root === root);
3318
+ if (duplicateRoot) throw new Error(`Fleet root ${root} is already registered as '${duplicateRoot[0]}'.`);
3319
+ if (root === globalRoot) throw new Error("A fleet root must be outside the user config root contract.");
3320
+ const target = await readRequiredConfig(root, `fleet '${id}'`);
3321
+ const registration = registeredFleetSchema.parse({ root, requiredPackages });
3322
+ assertFleetContract(id, registration, target);
3323
+ const upgraded = workspaceConfigSchema.parse({
3324
+ ...home,
3325
+ schemaVersion: CURRENT_WORKSPACE_SCHEMA_VERSION,
3326
+ exports: home.schemaVersion >= 2 ? home.exports : { selections: {} },
3327
+ fleets: { ...existing, [id]: registration }
3328
+ });
3329
+ const configPath = globalWorkspaceConfigPath(globalRoot);
3330
+ declareMutationPath(configPath);
3331
+ await writeJsonAtomic(configPath, upgraded);
3332
+ return { id, ...registration };
3333
+ }
3334
+ async function canonicalizeExistingFleetRoots(fleets, globalRoot) {
3335
+ const canonical = /* @__PURE__ */ new Map();
3336
+ const normalized = {};
3337
+ for (const [id, registration] of Object.entries(fleets).sort(([a], [b]) => a.localeCompare(b))) {
3338
+ const root = await canonicalizeDirectory(registration.root, `Registered fleet '${id}' root`);
3339
+ if (root === globalRoot) throw new Error(`Registered fleet '${id}' root must be outside the user config root contract.`);
3340
+ const incumbent = canonical.get(root);
3341
+ if (incumbent) {
3342
+ throw new Error(`Fleet root ${root} is registered more than once as '${incumbent}' and '${id}'.`);
3343
+ }
3344
+ canonical.set(root, id);
3345
+ normalized[id] = registeredFleetSchema.parse({ ...registration, root });
3346
+ }
3347
+ return normalized;
3348
+ }
3349
+ async function listRegisteredFleets(options = {}) {
3350
+ const globalRoot = resolve12(options.globalRoot ?? homedir5());
3351
+ const home = await readWorkspaceConfig(globalRoot);
3352
+ if (!supportsFleetConfig(home)) return [];
3353
+ return Object.entries(home.fleets).sort(([a], [b]) => a.localeCompare(b)).map(([id, registration]) => ({ id, ...registration }));
3354
+ }
3355
+ async function showRegisteredFleet(idInput, options = {}) {
3356
+ const id = fleetIdSchema.parse(idInput);
3357
+ const fleets = await listRegisteredFleets(options);
3358
+ const registration = fleets.find((candidate) => candidate.id === id);
3359
+ if (!registration) {
3360
+ throw new Error(`Unknown fleet '${id}'. Use 'agentwheel fleet list' or register it with 'agentwheel fleet register'.`);
3361
+ }
3362
+ return registration;
3363
+ }
3364
+ async function resolveWorkspaceOwnershipScope(workspaceRootInput, options = {}) {
3365
+ const workspaceRoot = await canonicalizeDirectory(resolve12(workspaceRootInput), "Workspace ownership root");
3366
+ if (options.fleetId) {
3367
+ return { root: workspaceRoot, fleetId: fleetIdSchema.parse(options.fleetId) };
3368
+ }
3369
+ const syntacticallyContaining = (await listRegisteredFleets({ globalRoot: options.globalRoot })).filter((fleet2) => containsPath(resolve12(fleet2.root), workspaceRoot));
3370
+ const registered = await Promise.all(syntacticallyContaining.map(async (fleet2) => ({
3371
+ ...fleet2,
3372
+ root: await canonicalizeDirectory(fleet2.root, `Registered fleet '${fleet2.id}' root`)
3373
+ })));
3374
+ const containing = registered.filter((fleet2) => containsPath(fleet2.root, workspaceRoot));
3375
+ if (containing.length > 1) {
3376
+ throw new Error(
3377
+ `Workspace ${workspaceRoot} is contained by multiple registered fleets: ` + containing.map((fleet2) => `'${fleet2.id}' at ${fleet2.root}`).join(", ") + ". Resolve the overlapping registrations before planning ownership."
3378
+ );
3379
+ }
3380
+ const fleet = containing[0];
3381
+ if (fleet) assertFleetContract(fleet.id, fleet, await readRequiredConfig(fleet.root, `fleet '${fleet.id}'`));
3382
+ return fleet ? { root: fleet.root, fleetId: fleet.id } : { root: workspaceRoot };
3383
+ }
3384
+ async function readRequiredConfig(root, label) {
3385
+ const path = workspaceConfigPath(root);
3386
+ if (!await pathExists(path)) throw missingScopeError(label);
3387
+ try {
3388
+ return workspaceConfigSchema.parse(JSON.parse(await readFile11(path, "utf8")));
3389
+ } catch (error) {
3390
+ throw new Error(`Invalid ${label} Agentwheel config at ${path}: ${error instanceof Error ? error.message : String(error)}`);
3391
+ }
3392
+ }
3393
+ function assertFleetContract(id, registration, config) {
3394
+ if (!supportsFleetConfig(config)) {
3395
+ throw new Error(`Fleet '${id}' config must use schemaVersion 3 or newer before registration or selection.`);
3396
+ }
3397
+ if (config.fleetId !== id) {
3398
+ throw new Error(`Fleet fleetId mismatch: expected '${id}', found '${config.fleetId ?? "missing"}'.`);
3399
+ }
3400
+ if (Object.keys(config.fleets).length > 0) {
3401
+ throw new Error(`Fleet '${id}' config may not contain the home fleets registry.`);
3402
+ }
3403
+ const names = new Set(config.packages.map((pkg) => pkg.name));
3404
+ for (const packageName of registration.requiredPackages) {
3405
+ if (!names.has(packageName)) throw new Error(`Fleet '${id}' is missing required package '${packageName}'.`);
3406
+ }
3407
+ }
3408
+ async function assertCanonicalDirectory(input, label) {
3409
+ const canonical = await canonicalizeDirectory(input, label);
3410
+ const normalized = resolve12(input);
3411
+ const stats = await lstat(input);
3412
+ if (stats.isSymbolicLink() || canonical !== normalized || input !== normalized) {
3413
+ throw new Error(`${label} must be canonical and symlink-unambiguous: ${input} resolves to ${canonical}.`);
3414
+ }
3415
+ return canonical;
3416
+ }
3417
+ async function canonicalizeDirectory(input, label) {
3418
+ if (!isAbsolute7(input)) throw new Error(`${label} must be an absolute canonical path.`);
3419
+ let canonical;
3420
+ try {
3421
+ canonical = await realpath(input);
3422
+ } catch {
3423
+ throw new Error(`${label} does not exist: ${input}`);
3424
+ }
3425
+ const stats = await lstat(canonical);
3426
+ if (!stats.isDirectory()) throw new Error(`${label} is not a directory: ${input}`);
3427
+ return canonical;
3428
+ }
3429
+ function missingScopeError(label) {
3430
+ return new Error(
3431
+ `Missing ${label} Agentwheel workspace config. Select --user, --local, or --fleet <id>, or run 'agentwheel init workspace' in the intended local root. Agentwheel never falls back to home desired state.`
3432
+ );
3433
+ }
3434
+ function assertNonFleetScope(kind, config) {
3435
+ if (supportsFleetConfig(config) && config.fleetId) {
3436
+ throw new Error(
3437
+ `The ${kind} config declares fleetId '${config.fleetId}'. Select it through the registered --fleet <id> scope.`
3438
+ );
3439
+ }
3440
+ }
3441
+ function sortedUnique3(values) {
3442
+ return [...new Set(values.map((value) => value.trim()).filter(Boolean))].sort((a, b) => a.localeCompare(b));
3443
+ }
3444
+ function containsPath(parent, candidate) {
3445
+ const path = relative5(parent, candidate);
3446
+ return path === "" || !path.startsWith("..") && !isAbsolute7(path);
3447
+ }
3448
+ var init_fleet = __esm({
3449
+ "src/model/fleet.ts"() {
3450
+ "use strict";
3451
+ init_fs();
3452
+ init_declarations();
3453
+ init_workspace();
3454
+ }
3455
+ });
3456
+
3270
3457
  // src/mutation/repository.ts
3271
3458
  import { createHash as createHash7 } from "crypto";
3272
- import { lstat, readFile as readFile11, readlink, readdir as readdir4 } from "fs/promises";
3273
- import { posix as posix3, relative as relative5, resolve as resolve12, sep as sep3 } from "path";
3459
+ import { lstat as lstat2, readFile as readFile12, readlink, readdir as readdir4 } from "fs/promises";
3460
+ import { posix as posix3, relative as relative6, resolve as resolve13, sep as sep3 } from "path";
3274
3461
  async function discoverGitRepository(start) {
3275
3462
  const probe = await runProcess("git", ["-C", start, "rev-parse", "--show-toplevel"], { allowExitCodes: [0, 128] });
3276
3463
  if (probe.exitCode !== 0) return void 0;
@@ -3293,7 +3480,7 @@ async function assertGitPreflight(repository) {
3293
3480
  if (result.exitCode === 0) throw new Error(`Revisioning refuses an in-progress Git operation (${marker}) in ${gitDir}.`);
3294
3481
  }
3295
3482
  for (const marker of ["rebase-merge", "rebase-apply"]) {
3296
- if (await exists(resolve12(gitDir, marker))) throw new Error(`Revisioning refuses an in-progress Git operation (${marker}) in ${gitDir}.`);
3483
+ if (await exists(resolve13(gitDir, marker))) throw new Error(`Revisioning refuses an in-progress Git operation (${marker}) in ${gitDir}.`);
3297
3484
  }
3298
3485
  }
3299
3486
  async function assertHeadLease(repositoryRoot, expectedHead, head, paths, provider) {
@@ -3409,16 +3596,16 @@ async function hashHeadPath(repositoryRoot, head, path) {
3409
3596
  return sha256(result.stdout);
3410
3597
  }
3411
3598
  async function hashWorkingPath(repositoryRoot, path) {
3412
- const absolute = resolve12(repositoryRoot, ...path.split("/"));
3599
+ const absolute = resolve13(repositoryRoot, ...path.split("/"));
3413
3600
  let stats;
3414
3601
  try {
3415
- stats = await lstat(absolute);
3602
+ stats = await lstat2(absolute);
3416
3603
  } catch (error) {
3417
3604
  if (isMissing3(error)) return null;
3418
3605
  throw error;
3419
3606
  }
3420
3607
  if (stats.isSymbolicLink()) return sha256(Buffer.from(await readlink(absolute), "utf8"));
3421
- if (stats.isFile()) return sha256(await readFile11(absolute));
3608
+ if (stats.isFile()) return sha256(await readFile12(absolute));
3422
3609
  if (stats.isDirectory()) return hashDirectory(absolute);
3423
3610
  throw new Error(`Unsupported repository path kind: ${path}`);
3424
3611
  }
@@ -3427,11 +3614,11 @@ async function hashDirectory(root) {
3427
3614
  async function walk2(dir) {
3428
3615
  for (const entry of (await readdir4(dir, { withFileTypes: true })).sort((a, b) => a.name.localeCompare(b.name))) {
3429
3616
  if (entry.name === ".git" || entry.name === "node_modules") continue;
3430
- const absolute = resolve12(dir, entry.name);
3431
- const relativePath = normalizeRepoPath(relative5(root, absolute));
3617
+ const absolute = resolve13(dir, entry.name);
3618
+ const relativePath = normalizeRepoPath(relative6(root, absolute));
3432
3619
  if (entry.isDirectory()) await walk2(absolute);
3433
3620
  else if (entry.isSymbolicLink()) hash2.update(relativePath).update("\0").update(await readlink(absolute)).update("\0");
3434
- else if (entry.isFile()) hash2.update(relativePath).update("\0").update(await readFile11(absolute)).update("\0");
3621
+ else if (entry.isFile()) hash2.update(relativePath).update("\0").update(await readFile12(absolute)).update("\0");
3435
3622
  }
3436
3623
  }
3437
3624
  await walk2(root);
@@ -3451,7 +3638,7 @@ function isMissing3(error) {
3451
3638
  }
3452
3639
  async function exists(path) {
3453
3640
  try {
3454
- await lstat(path);
3641
+ await lstat2(path);
3455
3642
  return true;
3456
3643
  } catch (error) {
3457
3644
  if (isMissing3(error)) return false;
@@ -3467,9 +3654,9 @@ var init_repository = __esm({
3467
3654
 
3468
3655
  // src/mutation/providers.ts
3469
3656
  import { createHash as createHash8 } from "crypto";
3470
- import { chmod as chmod2, mkdtemp, open as open2, readFile as readFile12, rename as rename5, rm as rm4, rmdir, stat as stat3, writeFile as writeFile7 } from "fs/promises";
3657
+ import { chmod as chmod2, mkdtemp, open as open2, readFile as readFile13, rename as rename5, rm as rm4, rmdir, stat as stat3, writeFile as writeFile7 } from "fs/promises";
3471
3658
  import { tmpdir as tmpdir2 } from "os";
3472
- import { isAbsolute as isAbsolute7, join as join10, resolve as resolve13 } from "path";
3659
+ import { isAbsolute as isAbsolute8, join as join10, resolve as resolve14 } from "path";
3473
3660
  function revisionProviderRejection(error) {
3474
3661
  return error instanceof RevisionProviderRejectedError ? error.response : void 0;
3475
3662
  }
@@ -3675,7 +3862,7 @@ async function assertProviderSemantics(request, response, config) {
3675
3862
  }
3676
3863
  async function invokeGitProvider(providerId, request, config) {
3677
3864
  const repository = await discoverGitRepository(request.repositoryRoot);
3678
- if (!repository || repository.root !== resolve13(request.repositoryRoot)) {
3865
+ if (!repository || repository.root !== resolve14(request.repositoryRoot)) {
3679
3866
  throw new Error(`Git revision provider requires the repository root itself: ${request.repositoryRoot}.`);
3680
3867
  }
3681
3868
  if (request.action === "check" || request.action === "preflight") {
@@ -3752,7 +3939,7 @@ async function finalizeGit(providerId, request, config) {
3752
3939
  const stagedAfterHooks = splitNull2((await runProcess("git", ["-C", request.repositoryRoot, "diff", "--cached", "--name-only", "-z"], { env: env2 })).stdout);
3753
3940
  assertExactSet(stagedAfterHooks, request.paths.map((entry) => entry.path), "temporary Git index after hooks");
3754
3941
  await verifyTemporaryIndexPaths(request, env2);
3755
- const message = await readFile12(messagePath, "utf8");
3942
+ const message = await readFile13(messagePath, "utf8");
3756
3943
  assertCommitMessageContract(message, request, planDigest);
3757
3944
  commitSha = (await runProcess("git", ["-C", request.repositoryRoot, "commit-tree", tree, "-p", repository.head], {
3758
3945
  env: env2,
@@ -3783,7 +3970,7 @@ async function runCommitHooks(request, env2, messagePath) {
3783
3970
  ["commit-msg", [messagePath]]
3784
3971
  ]) {
3785
3972
  const rawPath = (await runProcess("git", ["-C", request.repositoryRoot, "rev-parse", "--git-path", `hooks/${name}`])).stdout.toString("utf8").trim();
3786
- const hookPath = isAbsolute7(rawPath) ? rawPath : resolve13(request.repositoryRoot, rawPath);
3973
+ const hookPath = isAbsolute8(rawPath) ? rawPath : resolve14(request.repositoryRoot, rawPath);
3787
3974
  let executable = false;
3788
3975
  try {
3789
3976
  executable = ((await stat3(hookPath)).mode & 73) !== 0;
@@ -3869,9 +4056,9 @@ async function realignIndexAfterRecoveredCommit(repositoryRoot, expectedHead, co
3869
4056
  }
3870
4057
  async function captureIndexLease(repositoryRoot) {
3871
4058
  const rawPath = (await runProcess("git", ["-C", repositoryRoot, "rev-parse", "--git-path", "index"])).stdout.toString("utf8").trim();
3872
- const path = isAbsolute7(rawPath) ? rawPath : resolve13(repositoryRoot, rawPath);
4059
+ const path = isAbsolute8(rawPath) ? rawPath : resolve14(repositoryRoot, rawPath);
3873
4060
  try {
3874
- const [content, info] = await Promise.all([readFile12(path), stat3(path)]);
4061
+ const [content, info] = await Promise.all([readFile13(path), stat3(path)]);
3875
4062
  return { path, sha256: sha2562(content), mode: info.mode & 511 };
3876
4063
  } catch (error) {
3877
4064
  if (isMissing4(error)) return { path, sha256: null, mode: 384 };
@@ -3887,7 +4074,7 @@ async function replaceIndexCas(repositoryRoot, lease, commitSha) {
3887
4074
  await runProcess("git", ["-C", repositoryRoot, "read-tree", commitSha], {
3888
4075
  env: { ...process.env, GIT_INDEX_FILE: replacementPath }
3889
4076
  });
3890
- const replacement = await readFile12(replacementPath);
4077
+ const replacement = await readFile13(replacementPath);
3891
4078
  handle = await open2(lockPath, "wx", lease.mode);
3892
4079
  const current = await readOptionalFile(lease.path);
3893
4080
  const currentSha256 = current ? sha2562(current) : null;
@@ -3929,7 +4116,7 @@ async function hashGitObject(repositoryRoot, spec) {
3929
4116
  }
3930
4117
  async function readOptionalFile(path) {
3931
4118
  try {
3932
- return await readFile12(path);
4119
+ return await readFile13(path);
3933
4120
  } catch (error) {
3934
4121
  if (isMissing4(error)) return null;
3935
4122
  throw error;
@@ -4035,14 +4222,14 @@ var init_providers = __esm({
4035
4222
 
4036
4223
  // src/mutation/coordinator.ts
4037
4224
  import { randomUUID as randomUUID2 } from "crypto";
4038
- import { homedir as homedir5 } from "os";
4039
- import { isAbsolute as isAbsolute8, relative as relative6, resolve as resolve14, sep as sep4 } from "path";
4225
+ import { homedir as homedir6 } from "os";
4226
+ import { dirname as dirname9, isAbsolute as isAbsolute9, relative as relative7, resolve as resolve15, sep as sep4 } from "path";
4040
4227
  function dirtyRepositoryPaths(repositoryRoot, baseline, paths) {
4041
4228
  const conflicts = /* @__PURE__ */ new Set();
4042
4229
  for (const path of paths) {
4043
- const absolute = isAbsolute8(path) ? resolve14(path) : resolve14(process.cwd(), path);
4044
- const relativePath = relative6(repositoryRoot, absolute);
4045
- if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${sep4}`) || isAbsolute8(relativePath)) continue;
4230
+ const absolute = isAbsolute9(path) ? resolve15(path) : resolve15(process.cwd(), path);
4231
+ const relativePath = relative7(repositoryRoot, absolute);
4232
+ if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${sep4}`) || isAbsolute9(relativePath)) continue;
4046
4233
  const normalized = relativePath.split(sep4).join("/");
4047
4234
  if (baseline.changed.has(normalized)) conflicts.add(normalized);
4048
4235
  }
@@ -4259,13 +4446,18 @@ async function checkMutationProvider(workspaceRoot, globalRoot) {
4259
4446
  });
4260
4447
  return invokeRevisionProvider(policy.revisioning.provider, request, { workspaceRoot });
4261
4448
  }
4262
- async function mutationPolicyForWorkspace(workspaceRoot, globalRoot = homedir5()) {
4449
+ async function mutationPolicyForWorkspace(workspaceRoot, globalRoot = homedir6()) {
4263
4450
  const scopedConfig = await readWorkspaceConfig(workspaceRoot);
4264
4451
  const scoped = scopedConfig.schemaVersion === 4 ? scopedConfig.mutationPolicy : void 0;
4265
- if (resolve14(workspaceRoot) === resolve14(globalRoot)) return scoped;
4452
+ if (resolve15(workspaceRoot) === resolve15(globalRoot)) return scoped;
4266
4453
  const globalConfig = await readWorkspaceConfig(globalRoot);
4267
4454
  const global = globalConfig.schemaVersion === 4 ? globalConfig.mutationPolicy : void 0;
4268
- return mergeMutationPolicies(global, scoped);
4455
+ let existingRoot = resolve15(workspaceRoot);
4456
+ while (!await pathExists(existingRoot) && dirname9(existingRoot) !== existingRoot) existingRoot = dirname9(existingRoot);
4457
+ const owner = await resolveWorkspaceOwnershipScope(existingRoot, { globalRoot });
4458
+ const fleetConfig = owner.fleetId ? await readWorkspaceConfig(owner.root) : void 0;
4459
+ const fleet = fleetConfig?.schemaVersion === 4 ? fleetConfig.mutationPolicy : void 0;
4460
+ return mergeMutationPolicies(mergeMutationPolicies(global, fleet), scoped);
4269
4461
  }
4270
4462
  function mergeMutationPolicies(global, scoped) {
4271
4463
  if (!global) return scoped;
@@ -4337,6 +4529,8 @@ var init_coordinator = __esm({
4337
4529
  "use strict";
4338
4530
  init_mutation();
4339
4531
  init_workspace();
4532
+ init_fleet();
4533
+ init_fs();
4340
4534
  init_declarations();
4341
4535
  init_providers();
4342
4536
  init_protocol();
@@ -4619,18 +4813,18 @@ __export(transaction_exports, {
4619
4813
  writeApplyJournal: () => writeApplyJournal
4620
4814
  });
4621
4815
  import { createHash as createHash9 } from "crypto";
4622
- import { cp as cp2, lstat as lstat2, mkdir as mkdir7, open as open3, readFile as readFile13, readdir as readdir5, rm as rm5, stat as stat4 } from "fs/promises";
4623
- import { dirname as dirname9, join as join11, relative as relative7, resolve as resolve15, sep as sep5 } from "path";
4816
+ import { cp as cp2, lstat as lstat3, mkdir as mkdir7, open as open3, readFile as readFile14, readdir as readdir5, rm as rm5, stat as stat4 } from "fs/promises";
4817
+ import { dirname as dirname10, join as join11, relative as relative8, resolve as resolve16, sep as sep5 } from "path";
4624
4818
  async function assertNoSymlinkPath(path) {
4625
- const absolute = resolve15(path);
4819
+ const absolute = resolve16(path);
4626
4820
  let current = absolute;
4627
4821
  while (true) {
4628
4822
  try {
4629
- if ((await lstat2(current)).isSymbolicLink()) throw new Error(`Symlink path is unsupported: ${current}`);
4823
+ if ((await lstat3(current)).isSymbolicLink()) throw new Error(`Symlink path is unsupported: ${current}`);
4630
4824
  } catch (error) {
4631
4825
  if (error.code !== "ENOENT") throw error;
4632
4826
  }
4633
- const parent = dirname9(current);
4827
+ const parent = dirname10(current);
4634
4828
  if (parent === current) break;
4635
4829
  current = parent;
4636
4830
  }
@@ -4639,15 +4833,15 @@ async function ownershipRuntimeSnapshot(path) {
4639
4833
  await assertNoSymlinkPath(path);
4640
4834
  const hash2 = createHash9("sha256");
4641
4835
  async function visit(candidate) {
4642
- const info = await lstat2(candidate);
4836
+ const info = await lstat3(candidate);
4643
4837
  if (info.isSymbolicLink() || !info.isDirectory() && !info.isFile()) {
4644
4838
  throw new Error(`Unsupported ownership runtime path: ${candidate}`);
4645
4839
  }
4646
- hash2.update(JSON.stringify([relative7(path, candidate), info.isDirectory() ? "dir" : "file", info.mode & 4095]));
4840
+ hash2.update(JSON.stringify([relative8(path, candidate), info.isDirectory() ? "dir" : "file", info.mode & 4095]));
4647
4841
  if (info.isDirectory()) {
4648
4842
  for (const name of (await readdir5(candidate)).sort()) await visit(join11(candidate, name));
4649
4843
  } else {
4650
- const content = await readFile13(candidate);
4844
+ const content = await readFile14(candidate);
4651
4845
  hash2.update(String(content.length)).update("\0").update(content);
4652
4846
  }
4653
4847
  }
@@ -4656,14 +4850,14 @@ async function ownershipRuntimeSnapshot(path) {
4656
4850
  }
4657
4851
  function metadataAuditPath(audit, path) {
4658
4852
  mutationOperationIdSchema.parse(audit.operationId);
4659
- if (resolve15(audit.workspaceRoot) !== audit.workspaceRoot || path !== `.agentwheel/ownership-releases/${audit.operationId}.json`) {
4853
+ if (resolve16(audit.workspaceRoot) !== audit.workspaceRoot || path !== `.agentwheel/${audit.kind === "ownership-handoff" ? "ownership-handoffs" : "ownership-releases"}/${audit.operationId}.json`) {
4660
4854
  throw new Error("Invalid ownership release audit path.");
4661
4855
  }
4662
4856
  return join11(audit.workspaceRoot, ...path.split("/"));
4663
4857
  }
4664
4858
  function metadataRuntimePath(root, path) {
4665
- const result = resolve15(root, path);
4666
- if (!path || relative7(resolve15(root), result).split(sep5).join("/") !== path || path === ".agentwheel" || path.startsWith(".agentwheel/") || result === resolve15(root) || !result.startsWith(`${resolve15(root)}${sep5}`)) {
4859
+ const result = resolve16(root, path);
4860
+ if (!path || relative8(resolve16(root), result).split(sep5).join("/") !== path || path === ".agentwheel" || path.startsWith(".agentwheel/") || result === resolve16(root) || !result.startsWith(`${resolve16(root)}${sep5}`)) {
4667
4861
  throw new Error(`Unsafe ownership release path: ${path}`);
4668
4862
  }
4669
4863
  return result;
@@ -4677,7 +4871,7 @@ async function syncMetadataPath(path, directoryOnly = false) {
4677
4871
  await file.close();
4678
4872
  }
4679
4873
  }
4680
- const directory = await open3(directoryOnly ? path : dirname9(path), "r");
4874
+ const directory = await open3(directoryOnly ? path : dirname10(path), "r");
4681
4875
  try {
4682
4876
  await directory.sync();
4683
4877
  } finally {
@@ -4781,8 +4975,8 @@ async function listAllApplyJournals(targetRoot, adapter, transport = localTransp
4781
4975
  return found.sort((a, b) => a.path.localeCompare(b.path));
4782
4976
  }
4783
4977
  async function readLinkedLocalApplyJournal(path, operationId, expectedDigest, expectedTransportDescription) {
4784
- const absolutePath = resolve15(path);
4785
- const journal = parseApplyJournal(JSON.parse(await readFile13(absolutePath, "utf8")));
4978
+ const absolutePath = resolve16(path);
4979
+ const journal = parseApplyJournal(JSON.parse(await readFile14(absolutePath, "utf8")));
4786
4980
  if (journal.version !== 2 || !journal.mutation) {
4787
4981
  throw new Error(`Runtime apply journal ${absolutePath} is not linked to a governed mutation.`);
4788
4982
  }
@@ -4800,7 +4994,7 @@ async function readLinkedLocalApplyJournal(path, operationId, expectedDigest, ex
4800
4994
  }) !== expectedDigest) {
4801
4995
  throw new Error(`Runtime apply journal ${absolutePath} digest does not match its durable receipt.`);
4802
4996
  }
4803
- const expectedPath = resolve15(applyJournalPath(journal.targetRoot, journal.adapter, {
4997
+ const expectedPath = resolve16(applyJournalPath(journal.targetRoot, journal.adapter, {
4804
4998
  installationType: journal.installationType,
4805
4999
  stateKey: journal.stateKey
4806
5000
  }));
@@ -4815,7 +5009,7 @@ async function removeApplyJournal(targetRoot, adapter, transport = localTranspor
4815
5009
  if (existing?.mutation) await beginResolveMutationRuntimeJournal(existing.mutation.operationId, path);
4816
5010
  await transport.rm(applyJournalPath(targetRoot, adapter, scope));
4817
5011
  await transport.rm(applyBackupDir(targetRoot, adapter, scope));
4818
- if ((existing?.metadataAudit || existing?.metadataGuards) && transport.kind === "local") await syncMetadataPath(dirname9(path), true);
5012
+ if ((existing?.metadataAudit || existing?.metadataGuards) && transport.kind === "local") await syncMetadataPath(dirname10(path), true);
4819
5013
  if (existing?.mutation) await resolveMutationRuntimeJournal(existing.mutation.operationId, path);
4820
5014
  }
4821
5015
  async function abortApplyJournal(targetRoot, adapter, transport = localTransport, scope = {}) {
@@ -4875,7 +5069,7 @@ function applyJournalLinkDigest(journal, transport) {
4875
5069
  adapter: journal.adapter,
4876
5070
  installationType: journal.installationType ?? null,
4877
5071
  stateKey: journal.stateKey ?? null,
4878
- targetRoot: resolve15(journal.targetRoot),
5072
+ targetRoot: resolve16(journal.targetRoot),
4879
5073
  baseRevision: journal.baseRevision,
4880
5074
  graphLockDigest: journal.graphLockDigest ?? null,
4881
5075
  graphLockPath: journal.graphLockPath ?? null,
@@ -4951,7 +5145,7 @@ async function recordBackup(operation, index, targetRoot, adapter, transport = l
4951
5145
  }
4952
5146
  const backupPath = join11(applyBackupDir(targetRoot, adapter, scope), String(index));
4953
5147
  await rm5(backupPath, { recursive: true, force: true });
4954
- await mkdir7(dirname9(backupPath), { recursive: true });
5148
+ await mkdir7(dirname10(backupPath), { recursive: true });
4955
5149
  await cp2(operation.destPath, backupPath, { recursive: operation.kind === "dir", dereference: true });
4956
5150
  return {
4957
5151
  index,
@@ -5017,15 +5211,15 @@ var init_transaction = __esm({
5017
5211
  });
5018
5212
 
5019
5213
  // src/install/toml-merge.ts
5020
- import { mkdir as mkdir8, readFile as readFile14, writeFile as writeFile8 } from "fs/promises";
5021
- import { dirname as dirname10 } from "path";
5214
+ import { mkdir as mkdir8, readFile as readFile15, writeFile as writeFile8 } from "fs/promises";
5215
+ import { dirname as dirname11 } from "path";
5022
5216
  async function mergeCodexTomlMcp(sourcePath, destPath) {
5023
- const source = JSON.parse(await readFile14(sourcePath, "utf8"));
5217
+ const source = JSON.parse(await readFile15(sourcePath, "utf8"));
5024
5218
  const servers = extractMcpServers(source);
5025
- const current = await pathExists(destPath) ? await readFile14(destPath, "utf8") : "";
5219
+ const current = await pathExists(destPath) ? await readFile15(destPath, "utf8") : "";
5026
5220
  const withoutManaged = removeManagedMcpSections(current, Object.keys(servers));
5027
5221
  const merged = appendMcpServers(withoutManaged, servers);
5028
- await mkdir8(dirname10(destPath), { recursive: true });
5222
+ await mkdir8(dirname11(destPath), { recursive: true });
5029
5223
  await writeFile8(destPath, merged, "utf8");
5030
5224
  }
5031
5225
  function mismatchedCodexTomlMcpServers(source, currentContent) {
@@ -5141,14 +5335,14 @@ var init_toml_merge = __esm({
5141
5335
  });
5142
5336
 
5143
5337
  // src/install/yaml-merge.ts
5144
- import { mkdir as mkdir9, readFile as readFile15, writeFile as writeFile9 } from "fs/promises";
5145
- import { dirname as dirname11 } from "path";
5338
+ import { mkdir as mkdir9, readFile as readFile16, writeFile as writeFile9 } from "fs/promises";
5339
+ import { dirname as dirname12 } from "path";
5146
5340
  import { parse as parse2, stringify } from "yaml";
5147
5341
  async function mergeYamlFile(sourcePath, destPath) {
5148
- const source = parseYamlValue(await readFile15(sourcePath, "utf8"));
5149
- const current = await pathExists(destPath) ? parseYamlValue(await readFile15(destPath, "utf8")) : {};
5342
+ const source = parseYamlValue(await readFile16(sourcePath, "utf8"));
5343
+ const current = await pathExists(destPath) ? parseYamlValue(await readFile16(destPath, "utf8")) : {};
5150
5344
  const merged = deepMerge2(current, source);
5151
- await mkdir9(dirname11(destPath), { recursive: true });
5345
+ await mkdir9(dirname12(destPath), { recursive: true });
5152
5346
  await writeFile9(destPath, stringify(merged), "utf8");
5153
5347
  }
5154
5348
  function parseYamlValue(content) {
@@ -5206,8 +5400,8 @@ var init_yaml_merge = __esm({
5206
5400
  });
5207
5401
 
5208
5402
  // src/install/merge-removal.ts
5209
- import { mkdir as mkdir10, readFile as readFile16, writeFile as writeFile10 } from "fs/promises";
5210
- import { dirname as dirname12 } from "path";
5403
+ import { mkdir as mkdir10, readFile as readFile17, writeFile as writeFile10 } from "fs/promises";
5404
+ import { dirname as dirname13 } from "path";
5211
5405
  import { parse as parse3, stringify as stringify2 } from "yaml";
5212
5406
  function assertExactMergeContribution(contribution, strategy, currentContent) {
5213
5407
  if (strategy === "codex-toml-mcp") {
@@ -5274,7 +5468,7 @@ async function mergeRemovalForInstall(sourcePath, strategy, currentContent, opti
5274
5468
  return introducedMergeContent(parseMergeDestination(currentContent, strategy), source);
5275
5469
  }
5276
5470
  async function removeMergeContribution(destPath, strategy, removal) {
5277
- const content = await readFile16(destPath, "utf8");
5471
+ const content = await readFile17(destPath, "utf8");
5278
5472
  if (strategy === "codex-toml-mcp") {
5279
5473
  const servers = isRecord4(removal.mcpServers) ? removal.mcpServers : removal;
5280
5474
  await writeFile10(destPath, removeCodexTomlMcpSections(content, Object.keys(servers)), "utf8");
@@ -5282,7 +5476,7 @@ async function removeMergeContribution(destPath, strategy, removal) {
5282
5476
  }
5283
5477
  const current = parseMergeDestination(content, strategy);
5284
5478
  removeIntroducedContent(current, removal);
5285
- await mkdir10(dirname12(destPath), { recursive: true });
5479
+ await mkdir10(dirname13(destPath), { recursive: true });
5286
5480
  await writeFile10(destPath, strategy === "yaml-deep" ? stringify2(current) : `${JSON.stringify(current, null, 2)}
5287
5481
  `, "utf8");
5288
5482
  }
@@ -5298,7 +5492,7 @@ async function readMergeSource(sourcePath, strategy) {
5298
5492
  if (strategy === "openclaw-json-deep") {
5299
5493
  return requireRecord(await renderOpenClawJsonMergeSource(sourcePath), "OpenClaw JSON merge source");
5300
5494
  }
5301
- const content = await readFile16(sourcePath, "utf8");
5495
+ const content = await readFile17(sourcePath, "utf8");
5302
5496
  if (strategy === "yaml-deep") return requireRecord(normalizeYamlValue2(parse3(content)), "YAML merge source");
5303
5497
  return requireRecord(JSON.parse(content), "JSON merge source");
5304
5498
  }
@@ -5550,9 +5744,9 @@ var init_desired = __esm({
5550
5744
 
5551
5745
  // src/install/instructions-block.ts
5552
5746
  import { createHash as createHash10 } from "crypto";
5553
- import { mkdtemp as mkdtemp2, readFile as readFile17, realpath, rm as rm6, writeFile as writeFile11 } from "fs/promises";
5747
+ import { mkdtemp as mkdtemp2, readFile as readFile18, realpath as realpath2, rm as rm6, writeFile as writeFile11 } from "fs/promises";
5554
5748
  import { tmpdir as tmpdir3 } from "os";
5555
- import { basename as basename2, dirname as dirname13, join as join12, relative as relative8 } from "path";
5749
+ import { basename as basename2, dirname as dirname14, join as join12, relative as relative9 } from "path";
5556
5750
  function exactManagedInstructionBlockSnapshot(content, selector) {
5557
5751
  const beginCount = [...content.matchAll(new RegExp(`<!-- BEGIN openpack:include ${escapeRegex(selector)}(?=\\s|-->)`, "gu"))].length;
5558
5752
  const endCount = [...content.matchAll(new RegExp(`<!-- END openpack:include ${escapeRegex(selector)}(?=\\s|-->)`, "gu"))].length;
@@ -5603,7 +5797,7 @@ function exactManagedInstructionBlockSnapshot(content, selector) {
5603
5797
  };
5604
5798
  }
5605
5799
  async function desiredManagedInstructionBlockHash(sourcePath) {
5606
- const source = await readFile17(sourcePath, "utf8");
5800
+ const source = await readFile18(sourcePath, "utf8");
5607
5801
  return hashText(managedBlockBody(source));
5608
5802
  }
5609
5803
  async function readManagedInstructionBlockState(destPath, selector, transport) {
@@ -5623,7 +5817,7 @@ async function readManagedInstructionBlockState(destPath, selector, transport) {
5623
5817
  };
5624
5818
  }
5625
5819
  async function writeManagedInstructionBlock(sourcePath, destPath, selector, transport, options = {}) {
5626
- const source = await readFile17(sourcePath, "utf8");
5820
+ const source = await readFile18(sourcePath, "utf8");
5627
5821
  const desired = renderManagedInstructionBlock(selector, source);
5628
5822
  const existing = await readOptionalText(destPath, transport);
5629
5823
  const merged = upsertManagedInstructionBlock(existing ?? "", selector, desired.block, options);
@@ -5643,7 +5837,7 @@ async function managedInstructionBlockLanded(destPath, selector, expectedHash, t
5643
5837
  }
5644
5838
  async function managedInstructionPhysicalKey(destPath, transport) {
5645
5839
  if (transport.kind !== "local" || !await transport.pathExists(destPath)) return destPath;
5646
- return realpath(destPath);
5840
+ return realpath2(destPath);
5647
5841
  }
5648
5842
  async function claudeInstructionBridgesAgents(claudePath, agentsPath, transport) {
5649
5843
  if (!await transport.pathExists(claudePath)) return false;
@@ -5735,7 +5929,7 @@ function assertCleanBlock(block, selector) {
5735
5929
  }
5736
5930
  }
5737
5931
  function referencesAgentsMd(content, claudePath, agentsPath) {
5738
- const claudeDir = dirname13(claudePath);
5932
+ const claudeDir = dirname14(claudePath);
5739
5933
  for (const rawLine of content.split(/\r?\n/)) {
5740
5934
  const line = rawLine.trim();
5741
5935
  const atImport = /^@import\s+(.+)$/i.exec(line);
@@ -5745,7 +5939,7 @@ function referencesAgentsMd(content, claudePath, agentsPath) {
5745
5939
  const cleaned = referenced.trim().replace(/^["']|["']$/g, "");
5746
5940
  if (!/AGENTS\.md$/i.test(cleaned)) continue;
5747
5941
  const candidate = cleaned.startsWith("/") ? cleaned : join12(claudeDir, cleaned);
5748
- if (relative8(dirname13(agentsPath), candidate).replaceAll("\\", "/") === "AGENTS.md") return true;
5942
+ if (relative9(dirname14(agentsPath), candidate).replaceAll("\\", "/") === "AGENTS.md") return true;
5749
5943
  if (candidate === agentsPath) return true;
5750
5944
  }
5751
5945
  return false;
@@ -5753,7 +5947,7 @@ function referencesAgentsMd(content, claudePath, agentsPath) {
5753
5947
  async function samePhysicalPath(left, right, transport) {
5754
5948
  if (transport.kind !== "local") return false;
5755
5949
  if (!await transport.pathExists(left) || !await transport.pathExists(right)) return false;
5756
- return await realpath(left) === await realpath(right);
5950
+ return await realpath2(left) === await realpath2(right);
5757
5951
  }
5758
5952
  async function readOptionalText(path, transport) {
5759
5953
  if (!await transport.pathExists(path)) return void 0;
@@ -5803,9 +5997,9 @@ __export(apply_exports, {
5803
5997
  });
5804
5998
  import { execFile as execFile4 } from "child_process";
5805
5999
  import { createHash as createHash11, randomUUID as randomUUID3 } from "crypto";
5806
- import { link as link2, mkdir as mkdir11, mkdtemp as mkdtemp3, open as open4, readFile as readFile18, rm as rm7, writeFile as writeFile12 } from "fs/promises";
6000
+ import { link as link2, mkdir as mkdir11, mkdtemp as mkdtemp3, open as open4, readFile as readFile19, rm as rm7, writeFile as writeFile12 } from "fs/promises";
5807
6001
  import { tmpdir as tmpdir4 } from "os";
5808
- import { basename as basename3, dirname as dirname14, join as join13, resolve as resolve16 } from "path";
6002
+ import { basename as basename3, dirname as dirname15, join as join13, resolve as resolve17 } from "path";
5809
6003
  import { promisify as promisify4 } from "util";
5810
6004
  async function applyInstallPlan(plan, sourceLock, options = {}) {
5811
6005
  return applyPlanTransactionally(plan, { ...options, sourceLock });
@@ -6172,7 +6366,7 @@ async function assertCommittedJournalState(journal, expectedManifest, transport)
6172
6366
  }
6173
6367
  }
6174
6368
  if (journal.workspaceConfigPath && journal.workspaceConfig) {
6175
- const actual = JSON.parse(await readFile18(journal.workspaceConfigPath, "utf8"));
6369
+ const actual = JSON.parse(await readFile19(journal.workspaceConfigPath, "utf8"));
6176
6370
  if (canonicalJson5(actual) !== canonicalJson5(journal.workspaceConfig)) {
6177
6371
  throw new Error(`Workspace config postcheck failed for ${journal.workspaceConfigPath}.`);
6178
6372
  }
@@ -6182,7 +6376,7 @@ async function assertCommittedJournalState(journal, expectedManifest, transport)
6182
6376
  async function assertMetadataAuditGuards(journal, after, transport, requireAfter = false) {
6183
6377
  const audit = journal.metadataAudit;
6184
6378
  const sha = /^[a-f0-9]{64}$/;
6185
- if (transport.kind !== "local" || audit.kind !== "ownership-release" || after.adapter !== journal.adapter || after.targetRoot !== journal.targetRoot || after.installationType !== journal.installationType || after.stateKey !== journal.stateKey || journal.mode !== "uninstall" || journal.operations.length || journal.completed.length || journal.sourceLock || journal.graphLock || journal.graphLockPath || journal.graphLockRemovePath || journal.stateRemoveKey || journal.workspaceConfigPath || journal.workspaceConfig || !sha.test(audit.planDigest) || !sha.test(journal.baseRevision ?? "") || audit.auditFiles.length !== 1 || audit.runtime.length !== 1 || !audit.inventory.length) {
6379
+ if (transport.kind !== "local" || audit.kind !== "ownership-release" && audit.kind !== "ownership-handoff" || after.adapter !== journal.adapter || after.targetRoot !== journal.targetRoot || after.installationType !== journal.installationType || after.stateKey !== journal.stateKey || journal.mode !== "uninstall" || journal.operations.length || journal.completed.length || journal.sourceLock || journal.graphLock || journal.graphLockPath || journal.graphLockRemovePath || journal.stateRemoveKey || journal.workspaceConfigPath || journal.workspaceConfig || !sha.test(audit.planDigest) || !sha.test(journal.baseRevision ?? "") || audit.auditFiles.length !== 1 || audit.runtime.length !== 1 || !audit.inventory.length) {
6186
6380
  throw new Error("Invalid metadata-audit transaction; no state was committed.");
6187
6381
  }
6188
6382
  await assertMetadataStateGuards(journal, after, audit, transport, requireAfter);
@@ -6193,7 +6387,7 @@ async function assertMetadataAuditGuards(journal, after, transport, requireAfter
6193
6387
  throw new Error("Metadata-audit content digest is invalid.");
6194
6388
  }
6195
6389
  try {
6196
- if (await readFile18(path, "utf8") !== file.content) throw new Error(`Metadata-audit file changed: ${path}`);
6390
+ if (await readFile19(path, "utf8") !== file.content) throw new Error(`Metadata-audit file changed: ${path}`);
6197
6391
  } catch (error) {
6198
6392
  if (error.code !== "ENOENT" || requireAfter) throw error;
6199
6393
  }
@@ -6235,8 +6429,8 @@ async function assertMetadataStateGuards(journal, after, guards, transport, requ
6235
6429
  }
6236
6430
  async function writeAuditFileExclusive(path, content) {
6237
6431
  await assertNoSymlinkPath(path);
6238
- await mkdir11(dirname14(path), { recursive: true });
6239
- await syncMetadataPath(dirname14(dirname14(path)), true);
6432
+ await mkdir11(dirname15(path), { recursive: true });
6433
+ await syncMetadataPath(dirname15(dirname15(path)), true);
6240
6434
  const temporary = `${path}.pending-${randomUUID3()}`;
6241
6435
  try {
6242
6436
  const handle = await open4(temporary, "wx", 384);
@@ -6249,9 +6443,9 @@ async function writeAuditFileExclusive(path, content) {
6249
6443
  try {
6250
6444
  await link2(temporary, path);
6251
6445
  } catch (error) {
6252
- if (error.code !== "EEXIST" || await readFile18(path, "utf8") !== content) throw error;
6446
+ if (error.code !== "EEXIST" || await readFile19(path, "utf8") !== content) throw error;
6253
6447
  }
6254
- const directory = await open4(dirname14(path), "r");
6448
+ const directory = await open4(dirname15(path), "r");
6255
6449
  try {
6256
6450
  await directory.sync();
6257
6451
  } finally {
@@ -6710,7 +6904,7 @@ async function assertBaseRevision(plan, transport) {
6710
6904
  async function assertTargetStateFilePreconditions(plan, transport, graphLockWritePath) {
6711
6905
  const expected = plan.targetStateFilePreconditions;
6712
6906
  if (!expected) return;
6713
- if (graphLockWritePath && resolve16(graphLockWritePath) !== resolve16(expected.graphLockPath)) {
6907
+ if (graphLockWritePath && resolve17(graphLockWritePath) !== resolve17(expected.graphLockPath)) {
6714
6908
  throw new Error(
6715
6909
  `Graph-lock destination changed after planning: expected ${expected.graphLockPath}, found ${graphLockWritePath}; replan needed.`
6716
6910
  );
@@ -6903,7 +7097,7 @@ async function validateOpenClawConfig(configPath, destPath, transport) {
6903
7097
  if (!transport.execFile) {
6904
7098
  throw new Error(`Cannot validate OpenClaw config over ${transport.description}: transport does not support command execution.`);
6905
7099
  }
6906
- const openClawHome = dirname14(destPath);
7100
+ const openClawHome = dirname15(destPath);
6907
7101
  const bundledBin = join13(openClawHome, "npm", "node_modules", ".bin", "openclaw");
6908
7102
  const script = String.raw`
6909
7103
  set -euo pipefail
@@ -6954,8 +7148,8 @@ __export(identify_exports, {
6954
7148
  inferSourceDriverName: () => inferSourceDriverName,
6955
7149
  isExplicitSource: () => isExplicitSource
6956
7150
  });
6957
- import { homedir as homedir9 } from "os";
6958
- import { resolve as resolve23 } from "path";
7151
+ import { homedir as homedir10 } from "os";
7152
+ import { resolve as resolve24 } from "path";
6959
7153
  function inferSourceDriverName(source) {
6960
7154
  if (source.startsWith("clawhub:")) return "clawhub";
6961
7155
  if (source.startsWith("mcp-registry:")) return "mcp-registry";
@@ -6973,9 +7167,9 @@ async function isExplicitSource(source) {
6973
7167
  return pathExists(resolveLocalPath(source));
6974
7168
  }
6975
7169
  function resolveLocalPath(source) {
6976
- if (source === "~") return homedir9();
6977
- if (source.startsWith("~/")) return resolve23(homedir9(), source.slice(2));
6978
- return resolve23(source);
7170
+ if (source === "~") return homedir10();
7171
+ if (source.startsWith("~/")) return resolve24(homedir10(), source.slice(2));
7172
+ return resolve24(source);
6979
7173
  }
6980
7174
  var init_identify = __esm({
6981
7175
  "src/source/identify.ts"() {
@@ -6985,11 +7179,11 @@ var init_identify = __esm({
6985
7179
  });
6986
7180
 
6987
7181
  // src/cli/index.ts
6988
- import { createHash as createHash28 } from "crypto";
7182
+ import { createHash as createHash29 } from "crypto";
6989
7183
  import { existsSync } from "fs";
6990
7184
  import { mkdir as mkdir27, mkdtemp as mkdtemp6, readFile as readFile45, realpath as realpath4, rm as rm17, writeFile as writeFile24 } from "fs/promises";
6991
7185
  import { homedir as homedir18, tmpdir as tmpdir7 } from "os";
6992
- import { basename as basename24, dirname as dirname37, isAbsolute as isAbsolute14, join as join61, relative as relative19, resolve as resolve44 } from "path";
7186
+ import { basename as basename24, dirname as dirname38, isAbsolute as isAbsolute14, join as join62, relative as relative19, resolve as resolve45 } from "path";
6993
7187
  import { fileURLToPath as fileURLToPath4 } from "url";
6994
7188
  import { Command } from "commander";
6995
7189
 
@@ -7077,12 +7271,12 @@ init_manifest2();
7077
7271
  // src/install/plan.ts
7078
7272
  init_adapter();
7079
7273
  init_manifest();
7080
- import { basename as basename8, join as join24, relative as relative9 } from "path";
7274
+ import { basename as basename8, join as join24, relative as relative10 } from "path";
7081
7275
 
7082
7276
  // src/staging/codex-subagents.ts
7083
7277
  init_fs();
7084
- import { mkdir as mkdir12, readFile as readFile19, writeFile as writeFile13 } from "fs/promises";
7085
- import { basename as basename4, dirname as dirname15, join as join14 } from "path";
7278
+ import { mkdir as mkdir12, readFile as readFile20, writeFile as writeFile13 } from "fs/promises";
7279
+ import { basename as basename4, dirname as dirname16, join as join14 } from "path";
7086
7280
  import { parse as parseYaml } from "yaml";
7087
7281
  var requiredCodexAgentFields = ["name", "description", "developer_instructions"];
7088
7282
  async function renderCodexSubagents(artifacts, stageRoot, adapter) {
@@ -7109,7 +7303,7 @@ async function renderCodexSubagent(artifact, stageRoot) {
7109
7303
  const renderedPath = join14(stageRoot, ".agentwheel-rendered", "codex-subagents", `${agentName}.toml`);
7110
7304
  const lowerSourcePath = sourcePath.toLowerCase();
7111
7305
  if (artifact.kind === "file" && (artifact.name.toLowerCase().endsWith(".toml") || lowerSourcePath.endsWith(".toml"))) {
7112
- const content = await readFile19(sourcePath, "utf8");
7306
+ const content = await readFile20(sourcePath, "utf8");
7113
7307
  validateCodexAgentToml(content, sourcePath);
7114
7308
  return {
7115
7309
  ...artifact,
@@ -7126,9 +7320,9 @@ async function renderCodexSubagent(artifact, stageRoot) {
7126
7320
  if (artifact.kind === "file" && !artifact.name.toLowerCase().endsWith(".md") && !lowerSourcePath.endsWith(".md")) {
7127
7321
  throw new Error(`Codex subagent ${artifact.relativePath} must be a .toml file, .md file, or directory containing AGENTS.md.`);
7128
7322
  }
7129
- const markdown = await readFile19(markdownPath, "utf8");
7323
+ const markdown = await readFile20(markdownPath, "utf8");
7130
7324
  const toml = markdownToCodexAgentToml(agentName, markdown);
7131
- await mkdir12(dirname15(renderedPath), { recursive: true });
7325
+ await mkdir12(dirname16(renderedPath), { recursive: true });
7132
7326
  await writeFile13(renderedPath, toml, "utf8");
7133
7327
  return {
7134
7328
  ...artifact,
@@ -7210,8 +7404,8 @@ function escapeRegExp2(value) {
7210
7404
 
7211
7405
  // src/staging/copilot-artifacts.ts
7212
7406
  init_fs();
7213
- import { mkdir as mkdir13, readFile as readFile20, writeFile as writeFile14 } from "fs/promises";
7214
- import { basename as basename5, dirname as dirname16, join as join15 } from "path";
7407
+ import { mkdir as mkdir13, readFile as readFile21, writeFile as writeFile14 } from "fs/promises";
7408
+ import { basename as basename5, dirname as dirname17, join as join15 } from "path";
7215
7409
  async function renderCopilotArtifacts(artifacts, stageRoot, adapter) {
7216
7410
  if (adapter?.name !== "copilot") return artifacts;
7217
7411
  const names = /* @__PURE__ */ new Set();
@@ -7241,8 +7435,8 @@ async function renderCopilotSubagent(artifact, stageRoot) {
7241
7435
  if (artifact.kind === "file" && !artifact.name.toLowerCase().endsWith(".md")) {
7242
7436
  throw new Error(`Copilot subagent ${artifact.relativePath} must be a .md file or directory containing AGENTS.md.`);
7243
7437
  }
7244
- const markdown = await readFile20(markdownPath, "utf8");
7245
- await mkdir13(dirname16(renderedPath), { recursive: true });
7438
+ const markdown = await readFile21(markdownPath, "utf8");
7439
+ await mkdir13(dirname17(renderedPath), { recursive: true });
7246
7440
  await writeFile14(renderedPath, ensureCopilotAgentDescription(agentName, markdown), "utf8");
7247
7441
  return {
7248
7442
  ...artifact,
@@ -7297,8 +7491,8 @@ function yamlString(value) {
7297
7491
 
7298
7492
  // src/staging/openclaw-subagents.ts
7299
7493
  init_fs();
7300
- import { mkdir as mkdir14, readFile as readFile21, writeFile as writeFile15 } from "fs/promises";
7301
- import { basename as basename6, dirname as dirname17, join as join16 } from "path";
7494
+ import { mkdir as mkdir14, readFile as readFile22, writeFile as writeFile15 } from "fs/promises";
7495
+ import { basename as basename6, dirname as dirname18, join as join16 } from "path";
7302
7496
  async function renderOpenClawSubagents(artifacts, stageRoot, adapter) {
7303
7497
  if (adapter?.name !== "openclaw") return artifacts;
7304
7498
  const names = /* @__PURE__ */ new Set();
@@ -7327,15 +7521,15 @@ async function renderOpenClawSubagent(artifact, stageRoot) {
7327
7521
  if (artifact.kind === "file" && !artifact.name.toLowerCase().endsWith(".md") && !sourcePath.toLowerCase().endsWith(".md")) {
7328
7522
  throw new Error(`OpenClaw subagent ${artifact.relativePath} must be a .md file or directory containing AGENTS.md.`);
7329
7523
  }
7330
- const parsed = splitFrontmatter3(await readFile21(markdownPath, "utf8"));
7524
+ const parsed = splitFrontmatter3(await readFile22(markdownPath, "utf8"));
7331
7525
  const body = parsed.body.trim().length > 0 ? parsed.body.trim() : `# ${titleFromAgentId(agentId)}
7332
7526
 
7333
7527
  ${parsed.description ?? `OpenClaw subagent ${agentId}.`}`;
7334
7528
  const renderedPath = join16(stageRoot, ".agentwheel-rendered", "openclaw-subagents", agentId, "AGENTS.md");
7335
- await mkdir14(dirname17(renderedPath), { recursive: true });
7529
+ await mkdir14(dirname18(renderedPath), { recursive: true });
7336
7530
  await writeFile15(renderedPath, `${body}
7337
7531
  `, "utf8");
7338
- const renderedDir = dirname17(renderedPath);
7532
+ const renderedDir = dirname18(renderedPath);
7339
7533
  return {
7340
7534
  ...artifact,
7341
7535
  name: agentId,
@@ -7370,7 +7564,7 @@ import { join as join18 } from "path";
7370
7564
 
7371
7565
  // src/targets/plugins/common.ts
7372
7566
  init_fs();
7373
- import { readFile as readFile22 } from "fs/promises";
7567
+ import { readFile as readFile23 } from "fs/promises";
7374
7568
  import { join as join17 } from "path";
7375
7569
  import { parseDocument } from "yaml";
7376
7570
  function pluginStateRoot(request) {
@@ -7394,14 +7588,14 @@ function safeNameSegment(value) {
7394
7588
  async function jsonPluginName(root, relativeManifestPath, fallback) {
7395
7589
  const manifestPath = join17(root, relativeManifestPath);
7396
7590
  if (!await pathExists(manifestPath)) return fallback;
7397
- const parsed = JSON.parse(await readFile22(manifestPath, "utf8"));
7591
+ const parsed = JSON.parse(await readFile23(manifestPath, "utf8"));
7398
7592
  return typeof parsed.name === "string" && parsed.name.trim().length > 0 ? parsed.name.trim() : fallback;
7399
7593
  }
7400
7594
  async function yamlPluginName(root, relativeManifestPaths, fallback) {
7401
7595
  for (const relativeManifestPath of relativeManifestPaths) {
7402
7596
  const manifestPath = join17(root, relativeManifestPath);
7403
7597
  if (!await pathExists(manifestPath)) continue;
7404
- const document = parseDocument(await readFile22(manifestPath, "utf8"));
7598
+ const document = parseDocument(await readFile23(manifestPath, "utf8"));
7405
7599
  const parsed = document.toJSON();
7406
7600
  if (!isRecord5(parsed)) continue;
7407
7601
  for (const key of ["name", "module", "package"]) {
@@ -7534,7 +7728,7 @@ async function hermesPluginSpec(request) {
7534
7728
 
7535
7729
  // src/targets/plugins/openclaw.ts
7536
7730
  init_fs();
7537
- import { readFile as readFile23 } from "fs/promises";
7731
+ import { readFile as readFile24 } from "fs/promises";
7538
7732
  import { join as join22 } from "path";
7539
7733
  function openClawPluginInstallCommand(request) {
7540
7734
  return ["openclaw", "plugins", "install", "--force", request.path];
@@ -7564,7 +7758,7 @@ async function openClawPluginName(root, fallback) {
7564
7758
  for (const manifestName of ["plugin.json", "openclaw.plugin.json"]) {
7565
7759
  const manifestPath = join22(root, manifestName);
7566
7760
  if (!await pathExists(manifestPath)) continue;
7567
- const parsed = JSON.parse(await readFile23(manifestPath, "utf8"));
7761
+ const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
7568
7762
  if (typeof parsed.name === "string" && parsed.name.trim().length > 0) return parsed.name.trim();
7569
7763
  }
7570
7764
  return fallback;
@@ -7574,7 +7768,7 @@ async function openClawClawHubPluginMetadata(root, fallback) {
7574
7768
  if (!await pathExists(metadataPath)) {
7575
7769
  throw new Error("OpenClaw ClawHub plugins must contain clawhub.json");
7576
7770
  }
7577
- const parsed = JSON.parse(await readFile23(metadataPath, "utf8"));
7771
+ const parsed = JSON.parse(await readFile24(metadataPath, "utf8"));
7578
7772
  const installSpec = stringField(parsed.installSpec);
7579
7773
  if (!installSpec?.startsWith("clawhub:")) {
7580
7774
  throw new Error("OpenClaw ClawHub plugin metadata must declare installSpec starting with clawhub:");
@@ -7663,7 +7857,7 @@ function skipWarning(selector, adapter, installationType, artifactType, support)
7663
7857
  init_adapter();
7664
7858
  init_selection();
7665
7859
  init_fs();
7666
- import { readFile as readFile24 } from "fs/promises";
7860
+ import { readFile as readFile25 } from "fs/promises";
7667
7861
  import { basename as basename7, join as join23 } from "path";
7668
7862
  import { parseDocument as parseDocument2 } from "yaml";
7669
7863
  var behavioralRuleFormats = ["markdown-rule", "claude-markdown-rule", "copilot-instruction-rule"];
@@ -7868,7 +8062,7 @@ async function validateGenericStructure(artifact, target) {
7868
8062
  async function validateSkillFrontmatter(artifact, skillMdPath) {
7869
8063
  let content;
7870
8064
  try {
7871
- content = await readFile24(skillMdPath, "utf8");
8065
+ content = await readFile25(skillMdPath, "utf8");
7872
8066
  } catch (error) {
7873
8067
  return [{ artifact, message: `could not read SKILL.md: ${errorMessage(error)}` }];
7874
8068
  }
@@ -7938,7 +8132,7 @@ async function validateHermesPlugin(artifact) {
7938
8132
  return [{ artifact, message: "Hermes plugins must contain plugin.yaml or plugin.yml" }];
7939
8133
  }
7940
8134
  try {
7941
- const document = parseDocument2(await readFile24(manifestPath, "utf8"));
8135
+ const document = parseDocument2(await readFile25(manifestPath, "utf8"));
7942
8136
  if (document.errors.length > 0) {
7943
8137
  return [{ artifact, message: `Hermes ${basename7(manifestPath)} must be valid YAML: ${document.errors[0]?.message ?? "parse error"}` }];
7944
8138
  }
@@ -7962,7 +8156,7 @@ async function firstExistingPath(paths) {
7962
8156
  }
7963
8157
  async function parseJsonPluginManifest(manifestPath, label) {
7964
8158
  try {
7965
- const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
8159
+ const parsed = JSON.parse(await readFile25(manifestPath, "utf8"));
7966
8160
  if (!isRecord6(parsed)) {
7967
8161
  return { ok: false, message: `${label} ${basename7(manifestPath)} must be a JSON object` };
7968
8162
  }
@@ -8009,7 +8203,7 @@ async function validateOpenClawClawHubPlugin(artifact) {
8009
8203
  return [{ artifact, message: "OpenClaw ClawHub plugins must contain clawhub.json" }];
8010
8204
  }
8011
8205
  try {
8012
- const parsed = JSON.parse(await readFile24(metadataPath, "utf8"));
8206
+ const parsed = JSON.parse(await readFile25(metadataPath, "utf8"));
8013
8207
  if (!isRecord6(parsed)) {
8014
8208
  return [{ artifact, message: "OpenClaw ClawHub clawhub.json must be a JSON object" }];
8015
8209
  }
@@ -8033,7 +8227,7 @@ async function openClawPluginManifestPaths(artifact) {
8033
8227
  async function parseOpenClawPluginManifest(manifestPath) {
8034
8228
  const manifestName = basename7(manifestPath);
8035
8229
  try {
8036
- const parsed = JSON.parse(await readFile24(manifestPath, "utf8"));
8230
+ const parsed = JSON.parse(await readFile25(manifestPath, "utf8"));
8037
8231
  if (!isRecord6(parsed)) {
8038
8232
  return { ok: false, path: manifestPath, message: `OpenClaw ${manifestName} must be a JSON object` };
8039
8233
  }
@@ -8050,7 +8244,7 @@ async function parseJsonObjectArtifact(artifact) {
8050
8244
  return { ok: false, message: "merge artifacts must be JSON files" };
8051
8245
  }
8052
8246
  try {
8053
- const parsed = JSON.parse(await readFile24(artifactPath(artifact), "utf8"));
8247
+ const parsed = JSON.parse(await readFile25(artifactPath(artifact), "utf8"));
8054
8248
  if (!isRecord6(parsed)) return { ok: false, message: "merge artifacts must contain a JSON object" };
8055
8249
  return { ok: true, value: parsed };
8056
8250
  } catch (error) {
@@ -8062,7 +8256,7 @@ async function parseYamlObjectArtifact(artifact) {
8062
8256
  return { ok: false, message: "merge artifacts must be YAML files" };
8063
8257
  }
8064
8258
  try {
8065
- const document = parseDocument2(await readFile24(artifactPath(artifact), "utf8"));
8259
+ const document = parseDocument2(await readFile25(artifactPath(artifact), "utf8"));
8066
8260
  if (document.errors.length > 0) {
8067
8261
  return { ok: false, message: `merge artifact must be valid YAML: ${document.errors[0]?.message ?? "parse error"}` };
8068
8262
  }
@@ -8784,7 +8978,7 @@ async function operationForArtifact(artifact, adapter, targetRoot, installationT
8784
8978
  kind: "file",
8785
8979
  sourcePath: artifact.stagedPath ?? artifact.sourcePath,
8786
8980
  destPath: destPath2,
8787
- relativeDestPath: relative9(targetRoot, destPath2).replaceAll("\\", "/"),
8981
+ relativeDestPath: relative10(targetRoot, destPath2).replaceAll("\\", "/"),
8788
8982
  desiredHash: artifact.hash,
8789
8983
  reason: "destination missing",
8790
8984
  channel: artifact.channel ?? "managed",
@@ -8802,7 +8996,7 @@ async function operationForArtifact(artifact, adapter, targetRoot, installationT
8802
8996
  kind: artifact.kind,
8803
8997
  sourcePath: artifact.stagedPath ?? artifact.sourcePath,
8804
8998
  destPath,
8805
- relativeDestPath: relative9(targetRoot, destPath).replaceAll("\\", "/"),
8999
+ relativeDestPath: relative10(targetRoot, destPath).replaceAll("\\", "/"),
8806
9000
  desiredHash: artifact.hash,
8807
9001
  reason: "destination missing",
8808
9002
  channel: artifact.channel ?? "managed",
@@ -9799,14 +9993,14 @@ async function writeMermaidAsset(response) {
9799
9993
  "content-type": "application/javascript; charset=utf-8",
9800
9994
  "cache-control": "public, max-age=3600"
9801
9995
  });
9802
- await new Promise((resolve45) => {
9996
+ await new Promise((resolve46) => {
9803
9997
  const stream = createReadStream(assetPath);
9804
9998
  stream.on("error", () => {
9805
9999
  if (!response.headersSent) writeText(response, 404, "Mermaid asset unavailable.\n");
9806
10000
  else response.destroy();
9807
- resolve45();
10001
+ resolve46();
9808
10002
  });
9809
- stream.on("end", resolve45);
10003
+ stream.on("end", resolve46);
9810
10004
  stream.pipe(response);
9811
10005
  });
9812
10006
  }
@@ -9833,14 +10027,14 @@ function escapeHtml2(value) {
9833
10027
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
9834
10028
  }
9835
10029
  function listen(server, port, bind) {
9836
- return new Promise((resolve45, reject) => {
10030
+ return new Promise((resolve46, reject) => {
9837
10031
  const onError = (error) => {
9838
10032
  server.off("listening", onListening);
9839
10033
  reject(error);
9840
10034
  };
9841
10035
  const onListening = () => {
9842
10036
  server.off("error", onError);
9843
- resolve45();
10037
+ resolve46();
9844
10038
  };
9845
10039
  server.once("error", onError);
9846
10040
  server.once("listening", onListening);
@@ -9848,7 +10042,7 @@ function listen(server, port, bind) {
9848
10042
  });
9849
10043
  }
9850
10044
  function waitForShutdown(server, beforeClose) {
9851
- return new Promise((resolve45) => {
10045
+ return new Promise((resolve46) => {
9852
10046
  let closing = false;
9853
10047
  const shutdown = () => {
9854
10048
  if (closing) return;
@@ -9856,7 +10050,7 @@ function waitForShutdown(server, beforeClose) {
9856
10050
  process.off("SIGINT", shutdown);
9857
10051
  process.off("SIGTERM", shutdown);
9858
10052
  beforeClose();
9859
- server.close(() => resolve45());
10053
+ server.close(() => resolve46());
9860
10054
  };
9861
10055
  process.once("SIGINT", shutdown);
9862
10056
  process.once("SIGTERM", shutdown);
@@ -9866,7 +10060,7 @@ function waitForShutdown(server, beforeClose) {
9866
10060
  process.off("SIGINT", shutdown);
9867
10061
  process.off("SIGTERM", shutdown);
9868
10062
  beforeClose();
9869
- resolve45();
10063
+ resolve46();
9870
10064
  });
9871
10065
  });
9872
10066
  }
@@ -9885,13 +10079,13 @@ function errorMessage2(error) {
9885
10079
 
9886
10080
  // src/source/clawhub.ts
9887
10081
  import { mkdir as mkdir15, rm as rm8, writeFile as writeFile16 } from "fs/promises";
9888
- import { basename as basename10, dirname as dirname18, join as join28, resolve as resolve18 } from "path";
10082
+ import { basename as basename10, dirname as dirname19, join as join28, resolve as resolve19 } from "path";
9889
10083
 
9890
10084
  // src/model/package.ts
9891
10085
  init_artifact();
9892
10086
  init_fs();
9893
10087
  init_artifact();
9894
- import { readFile as readFile25 } from "fs/promises";
10088
+ import { readFile as readFile26 } from "fs/promises";
9895
10089
  import { join as join26 } from "path";
9896
10090
  import { parse as parse4, printParseErrorCode as printParseErrorCode2 } from "jsonc-parser";
9897
10091
  import { z as z11 } from "zod";
@@ -9999,7 +10193,7 @@ async function findPackageManifestPath(root, options = {}) {
9999
10193
  async function readPackageManifest(root) {
10000
10194
  const path = await findPackageManifestPath(root);
10001
10195
  if (!path) return void 0;
10002
- const content = await readFile25(path, "utf8");
10196
+ const content = await readFile26(path, "utf8");
10003
10197
  const errors = [];
10004
10198
  const parsed = parse4(content, errors, { allowTrailingComma: true, disallowComments: false });
10005
10199
  if (errors.length > 0) {
@@ -10079,12 +10273,12 @@ init_fs();
10079
10273
  // src/source/local.ts
10080
10274
  import { createHash as createHash13 } from "crypto";
10081
10275
  import { readdir as readdir6, stat as stat5 } from "fs/promises";
10082
- import { basename as basename9, join as join27, relative as relative10, resolve as resolve17 } from "path";
10276
+ import { basename as basename9, join as join27, relative as relative11, resolve as resolve18 } from "path";
10083
10277
  init_fs();
10084
10278
  var LocalSourceDriver = class {
10085
10279
  name = "local";
10086
10280
  async resolve(source) {
10087
- const resolvedPath = resolve17(source);
10281
+ const resolvedPath = resolve18(source);
10088
10282
  if (!await pathExists(resolvedPath)) {
10089
10283
  throw new Error(`Local source not found: ${resolvedPath}`);
10090
10284
  }
@@ -10224,7 +10418,7 @@ async function hashLocalSource(root, manifest) {
10224
10418
  const manifestPath = await findPackageManifestPath(root, { warnLegacy: false });
10225
10419
  if (manifestPath) {
10226
10420
  hash2.update("manifest\0");
10227
- hash2.update(relative10(root, manifestPath).replaceAll("\\", "/")).update("\0");
10421
+ hash2.update(relative11(root, manifestPath).replaceAll("\\", "/")).update("\0");
10228
10422
  hash2.update(await hashPath(manifestPath)).update("\0");
10229
10423
  }
10230
10424
  const provides = [...manifest.provides].sort((a, b) => `${a.type}\0${a.path}`.localeCompare(`${b.type}\0${b.path}`));
@@ -10426,7 +10620,7 @@ async function fetchClawHubPackage(fetchImpl, packageName) {
10426
10620
  throw new Error(`ClawHub lookup failed for ${packageName}`);
10427
10621
  }
10428
10622
  async function delay(ms) {
10429
- await new Promise((resolve45) => setTimeout(resolve45, ms));
10623
+ await new Promise((resolve46) => setTimeout(resolve46, ms));
10430
10624
  }
10431
10625
  function parseClawHubSource(source) {
10432
10626
  if (!source.startsWith(sourcePrefix)) {
@@ -10458,7 +10652,7 @@ async function writeGeneratedPackage(root, packageInfo) {
10458
10652
  };
10459
10653
  const pluginPath = join28(root, "plugins", pluginId, "clawhub.json");
10460
10654
  await rm8(root, { recursive: true, force: true });
10461
- await mkdir15(dirname18(pluginPath), { recursive: true });
10655
+ await mkdir15(dirname19(pluginPath), { recursive: true });
10462
10656
  await writeFile16(join28(root, "openpack.json"), `${JSON.stringify({
10463
10657
  schemaVersion: CURRENT_OPENPACK_SCHEMA_VERSION,
10464
10658
  name: `clawhub/${name}`,
@@ -10482,7 +10676,7 @@ function installNameFor2(value) {
10482
10676
  return basename10(value).replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "clawhub-plugin";
10483
10677
  }
10484
10678
  function cachePathFor(packageName, cacheRoot) {
10485
- const root = cacheRoot ? resolve18(cacheRoot) : join28(process.env.HOME ?? ".", ".agentwheel", "cache");
10679
+ const root = cacheRoot ? resolve19(cacheRoot) : join28(process.env.HOME ?? ".", ".agentwheel", "cache");
10486
10680
  const slug2 = `clawhub-${packageName}`.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "");
10487
10681
  return join28(root, slug2 || "clawhub-package");
10488
10682
  }
@@ -10490,14 +10684,14 @@ function cachePathFor(packageName, cacheRoot) {
10490
10684
  // src/source/git.ts
10491
10685
  import { execFile as execFile5 } from "child_process";
10492
10686
  import { mkdir as mkdir17, rename as rename6, rm as rm10, stat as stat7 } from "fs/promises";
10493
- import { homedir as homedir7 } from "os";
10494
- import { basename as basename11, dirname as dirname20, join as join31, resolve as resolve19, sep as sep6 } from "path";
10687
+ import { homedir as homedir8 } from "os";
10688
+ import { basename as basename11, dirname as dirname21, join as join31, resolve as resolve20, sep as sep6 } from "path";
10495
10689
  import { promisify as promisify5 } from "util";
10496
10690
  init_fs();
10497
10691
 
10498
10692
  // src/source/auth.ts
10499
- import { readFile as readFile26 } from "fs/promises";
10500
- import { homedir as homedir6 } from "os";
10693
+ import { readFile as readFile27 } from "fs/promises";
10694
+ import { homedir as homedir7 } from "os";
10501
10695
  import { join as join29 } from "path";
10502
10696
  var AUTH_CONFIG_ENV = "AGENTWHEEL_AUTH_CONFIG";
10503
10697
  async function gitAuthArguments(url) {
@@ -10520,9 +10714,9 @@ async function matchingGitAuthProfile(url) {
10520
10714
  );
10521
10715
  }
10522
10716
  async function readGitAuthConfig() {
10523
- const path = process.env[AUTH_CONFIG_ENV] ?? join29(homedir6(), ".agentwheel", "auth.json");
10717
+ const path = process.env[AUTH_CONFIG_ENV] ?? join29(homedir7(), ".agentwheel", "auth.json");
10524
10718
  try {
10525
- const parsed = JSON.parse(await readFile26(path, "utf8"));
10719
+ const parsed = JSON.parse(await readFile27(path, "utf8"));
10526
10720
  return parseGitAuthConfig(parsed, path);
10527
10721
  } catch (error) {
10528
10722
  if (isMissingFile(error)) return void 0;
@@ -10573,8 +10767,8 @@ function isMissingFile(error) {
10573
10767
  // src/source/cache.ts
10574
10768
  init_fs();
10575
10769
  import { randomUUID as randomUUID4 } from "crypto";
10576
- import { mkdir as mkdir16, readdir as readdir7, readFile as readFile27, rm as rm9, stat as stat6, writeFile as writeFile17 } from "fs/promises";
10577
- import { dirname as dirname19, join as join30 } from "path";
10770
+ import { mkdir as mkdir16, readdir as readdir7, readFile as readFile28, rm as rm9, stat as stat6, writeFile as writeFile17 } from "fs/promises";
10771
+ import { dirname as dirname20, join as join30 } from "path";
10578
10772
  var snapshotNamePattern = /^(.*)-([0-9a-f]{12})$/i;
10579
10773
  var leaseMarker = ".agentwheel-lease-";
10580
10774
  async function pruneGitCache(cacheRoot, options = {}) {
@@ -10605,7 +10799,7 @@ async function withGitCacheMaintenanceLock(cacheRoot, timeoutMs, fn) {
10605
10799
  if (Date.now() - started > timeoutMs) {
10606
10800
  throw new Error(`Timed out waiting for git cache maintenance lock at ${lockPath}`);
10607
10801
  }
10608
- await new Promise((resolve45) => setTimeout(resolve45, 50));
10802
+ await new Promise((resolve46) => setTimeout(resolve46, 50));
10609
10803
  }
10610
10804
  }
10611
10805
  try {
@@ -10642,7 +10836,7 @@ async function removeGeneratedEntries(root, preserveGit) {
10642
10836
  }
10643
10837
  }
10644
10838
  async function pruneGitCacheUnlocked(cacheRoot, options) {
10645
- const referencedCommits = await referencedGraphLockCommits(join30(dirname19(cacheRoot), "locks"));
10839
+ const referencedCommits = await referencedGraphLockCommits(join30(dirname20(cacheRoot), "locks"));
10646
10840
  const entries = await readdir7(cacheRoot, { withFileTypes: true });
10647
10841
  const groups = /* @__PURE__ */ new Map();
10648
10842
  for (const entry of entries) {
@@ -10701,7 +10895,7 @@ async function walkGraphLocks(root, visit) {
10701
10895
  await walkGraphLocks(path, visit);
10702
10896
  } else if (entry.isFile() && entry.name.endsWith(".graph-lock.json")) {
10703
10897
  try {
10704
- visit(JSON.parse(await readFile27(path, "utf8")));
10898
+ visit(JSON.parse(await readFile28(path, "utf8")));
10705
10899
  } catch (error) {
10706
10900
  throw new Error(`Cannot read graph lock ${path}; cache prune aborted: ${errorMessage3(error)}`);
10707
10901
  }
@@ -10709,7 +10903,7 @@ async function walkGraphLocks(root, visit) {
10709
10903
  }
10710
10904
  }
10711
10905
  async function hasLiveSnapshotLease(snapshotPath, dryRun) {
10712
- const directory = dirname19(snapshotPath);
10906
+ const directory = dirname20(snapshotPath);
10713
10907
  const prefix = `${snapshotPath.slice(directory.length + 1)}${leaseMarker}`;
10714
10908
  const entries = await readdir7(directory, { withFileTypes: true });
10715
10909
  let live = false;
@@ -10717,7 +10911,7 @@ async function hasLiveSnapshotLease(snapshotPath, dryRun) {
10717
10911
  if (!entry.isFile() || !entry.name.startsWith(prefix)) continue;
10718
10912
  const leasePath = join30(directory, entry.name);
10719
10913
  try {
10720
- const value = JSON.parse(await readFile27(leasePath, "utf8"));
10914
+ const value = JSON.parse(await readFile28(leasePath, "utf8"));
10721
10915
  if (typeof value.pid !== "number" || !Number.isSafeInteger(value.pid) || value.pid <= 0) {
10722
10916
  live = true;
10723
10917
  } else if (isProcessAlive2(value.pid)) {
@@ -10733,7 +10927,7 @@ async function hasLiveSnapshotLease(snapshotPath, dryRun) {
10733
10927
  }
10734
10928
  async function removeStaleMaintenanceLock(lockPath) {
10735
10929
  try {
10736
- const value = JSON.parse(await readFile27(join30(lockPath, "owner.json"), "utf8"));
10930
+ const value = JSON.parse(await readFile28(join30(lockPath, "owner.json"), "utf8"));
10737
10931
  if (typeof value.pid !== "number" || !Number.isSafeInteger(value.pid) || value.pid <= 0 || isProcessAlive2(value.pid)) {
10738
10932
  return false;
10739
10933
  }
@@ -10848,7 +11042,7 @@ var GitSourceDriver = class {
10848
11042
  async fetch(resolved) {
10849
11043
  return withFilesystemLock(`${resolved.resolvedPath}.lock`, resolved.cacheLockTimeoutMs ?? 3e4, async () => {
10850
11044
  const parsed = parseGitSource(resolved.source);
10851
- const cacheRoot = dirname20(resolved.resolvedPath);
11045
+ const cacheRoot = dirname21(resolved.resolvedPath);
10852
11046
  await mkdir17(cacheRoot, { recursive: true });
10853
11047
  await assertOwnedByCurrentUser(cacheRoot);
10854
11048
  if (await pathExists(resolved.resolvedPath)) await assertOwnedByCurrentUser(resolved.resolvedPath);
@@ -10922,7 +11116,7 @@ async function isDirectory(path) {
10922
11116
  }
10923
11117
  }
10924
11118
  function cachePathFor2(url, cacheRoot) {
10925
- const root = cacheRoot ? resolve19(cacheRoot) : join31(homedir7(), ".agentwheel", "cache");
11119
+ const root = cacheRoot ? resolve20(cacheRoot) : join31(homedir8(), ".agentwheel", "cache");
10926
11120
  const slug2 = url.replace(/^[a-z]+:\/\//i, "").replace(/\.git$/i, "").replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "");
10927
11121
  return join31(root, slug2 || basename11(url));
10928
11122
  }
@@ -10943,9 +11137,9 @@ async function resolveCommit(checkoutPath, ref) {
10943
11137
  throw lastError;
10944
11138
  }
10945
11139
  async function snapshotCommit(checkoutPath, commit) {
10946
- const snapshotPath = join31(dirname20(checkoutPath), `${basename11(checkoutPath)}-${commit.slice(0, 12)}`);
11140
+ const snapshotPath = join31(dirname21(checkoutPath), `${basename11(checkoutPath)}-${commit.slice(0, 12)}`);
10947
11141
  if (await pathExists(snapshotPath)) return snapshotPath;
10948
- const tempPath = join31(dirname20(checkoutPath), `${basename11(snapshotPath)}.tmp-${process.pid}-${Date.now()}`);
11142
+ const tempPath = join31(dirname21(checkoutPath), `${basename11(snapshotPath)}.tmp-${process.pid}-${Date.now()}`);
10949
11143
  const tempIndexPath = `${tempPath}.index`;
10950
11144
  await rm10(tempPath, { recursive: true, force: true });
10951
11145
  await rm10(tempIndexPath, { force: true });
@@ -10953,7 +11147,7 @@ async function snapshotCommit(checkoutPath, commit) {
10953
11147
  const env2 = { ...process.env, GIT_INDEX_FILE: tempIndexPath };
10954
11148
  try {
10955
11149
  await git(["-C", checkoutPath, "read-tree", commit], env2);
10956
- await git(["-C", checkoutPath, "checkout-index", "--all", `--prefix=${resolve19(tempPath)}${sep6}`], env2);
11150
+ await git(["-C", checkoutPath, "checkout-index", "--all", `--prefix=${resolve20(tempPath)}${sep6}`], env2);
10957
11151
  await removeGeneratedEntries(tempPath, false);
10958
11152
  } catch (error) {
10959
11153
  await rm10(tempPath, { recursive: true, force: true });
@@ -10983,7 +11177,7 @@ async function assertOwnedByCurrentUser(path) {
10983
11177
 
10984
11178
  // src/source/mcp-registry.ts
10985
11179
  import { mkdir as mkdir18, writeFile as writeFile18 } from "fs/promises";
10986
- import { basename as basename12, dirname as dirname21, join as join32, resolve as resolve20 } from "path";
11180
+ import { basename as basename12, dirname as dirname22, join as join32, resolve as resolve21 } from "path";
10987
11181
  init_fs();
10988
11182
  var registryBaseUrl = "https://registry.modelcontextprotocol.io/v0.1";
10989
11183
  var sourcePrefix2 = "mcp-registry:";
@@ -11091,7 +11285,7 @@ function isSafeHttpUrl(value) {
11091
11285
  async function writeGeneratedPackage2(root, server) {
11092
11286
  const serverId = installNameFor3(server.serverName);
11093
11287
  const mcpPath = join32(root, "mcp", `${serverId}.json`);
11094
- await mkdir18(dirname21(mcpPath), { recursive: true });
11288
+ await mkdir18(dirname22(mcpPath), { recursive: true });
11095
11289
  await writeFile18(join32(root, "openpack.json"), `${JSON.stringify({
11096
11290
  schemaVersion: CURRENT_OPENPACK_SCHEMA_VERSION,
11097
11291
  name: `mcp-registry/${server.serverName}`,
@@ -11113,7 +11307,7 @@ function installNameFor3(serverName) {
11113
11307
  return basename12(serverName).replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "mcp-server";
11114
11308
  }
11115
11309
  function cachePathFor3(serverName, cacheRoot) {
11116
- const root = cacheRoot ? resolve20(cacheRoot) : join32(process.env.HOME ?? ".", ".agentwheel", "cache");
11310
+ const root = cacheRoot ? resolve21(cacheRoot) : join32(process.env.HOME ?? ".", ".agentwheel", "cache");
11117
11311
  const slug2 = `mcp-registry-${serverName}`.replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "");
11118
11312
  return join32(root, slug2 || "mcp-registry-server");
11119
11313
  }
@@ -11123,16 +11317,16 @@ init_cache_identity();
11123
11317
  init_fs();
11124
11318
  import { createHash as createHash14, randomUUID as randomUUID5 } from "crypto";
11125
11319
  import { execFile as execFile6 } from "child_process";
11126
- import { cp as cp3, mkdir as mkdir19, readFile as readFile28, rename as rename7, rm as rm11 } from "fs/promises";
11127
- import { homedir as homedir8 } from "os";
11128
- import { basename as basename14, dirname as dirname23, join as join34, resolve as resolve21 } from "path";
11320
+ import { cp as cp3, mkdir as mkdir19, readFile as readFile29, rename as rename7, rm as rm11 } from "fs/promises";
11321
+ import { homedir as homedir9 } from "os";
11322
+ import { basename as basename14, dirname as dirname24, join as join34, resolve as resolve22 } from "path";
11129
11323
  import { promisify as promisify6 } from "util";
11130
11324
  import * as defaultSkillKit from "@skillkit/core";
11131
11325
 
11132
11326
  // src/source/skill-artifacts.ts
11133
11327
  init_fs();
11134
11328
  import { readdir as readdir8, stat as stat8 } from "fs/promises";
11135
- import { basename as basename13, dirname as dirname22, extname as extname2, join as join33 } from "path";
11329
+ import { basename as basename13, dirname as dirname23, extname as extname2, join as join33 } from "path";
11136
11330
  async function artifactsFromSkillPaths(paths, packageName) {
11137
11331
  const artifacts = [];
11138
11332
  const seen = /* @__PURE__ */ new Set();
@@ -11169,7 +11363,7 @@ async function artifactFromSkillPath(item, packageName) {
11169
11363
  };
11170
11364
  }
11171
11365
  if (stats.isFile() && basename13(item.path).toLowerCase() === "skill.md") {
11172
- const dir = dirname22(item.path);
11366
+ const dir = dirname23(item.path);
11173
11367
  const name = sanitizeSkillName(item.name ?? basename13(dir));
11174
11368
  return {
11175
11369
  type: "skills",
@@ -11225,7 +11419,7 @@ var SkillKitSourceDriver = class {
11225
11419
  async resolve(source, options = {}) {
11226
11420
  const spec = parseSkillKitSource(source);
11227
11421
  if (await pathExists(spec)) {
11228
- const resolvedPath = resolve21(spec);
11422
+ const resolvedPath = resolve22(spec);
11229
11423
  return {
11230
11424
  driver: this.name,
11231
11425
  source,
@@ -11277,7 +11471,7 @@ var SkillKitSourceDriver = class {
11277
11471
  sourceHash: await hashPath(resolved.resolvedPath)
11278
11472
  };
11279
11473
  }
11280
- const specCachePath = cachePathFor4(spec, dirname23(dirname23(resolved.resolvedPath)));
11474
+ const specCachePath = cachePathFor4(spec, dirname24(dirname24(resolved.resolvedPath)));
11281
11475
  const refIdentity = resolved.requestedRef ?? "default";
11282
11476
  const lockPath = `${specCachePath}.ref-${createHash14("sha256").update(refIdentity).digest("hex")}.lock`;
11283
11477
  const inflightKey = `${lockPath}\0${requestedCommit ?? "movable"}`;
@@ -11298,11 +11492,11 @@ var SkillKitSourceDriver = class {
11298
11492
  throw new Error("SkillKit provider API unavailable or cannot resolve source. Expected @skillkit/core detectProvider().clone().");
11299
11493
  }
11300
11494
  const materialized = await withFilesystemLock(lockPath, resolved.cacheLockTimeoutMs ?? 3e4, async () => {
11301
- const immutablePath = requestedCommit ? cachePathFor4(spec, dirname23(dirname23(specCachePath)), requestedCommit) : void 0;
11495
+ const immutablePath = requestedCommit ? cachePathFor4(spec, dirname24(dirname24(specCachePath)), requestedCommit) : void 0;
11302
11496
  if (immutablePath && await pathExists(immutablePath)) {
11303
11497
  return { path: immutablePath, commit: requestedCommit, cacheIdentity: requestedCommit };
11304
11498
  }
11305
- await mkdir19(dirname23(specCachePath), { recursive: true });
11499
+ await mkdir19(dirname24(specCachePath), { recursive: true });
11306
11500
  const candidatePath = `${specCachePath}.agentwheel-tmp-${process.pid}-${randomUUID5()}`;
11307
11501
  const publishPath = `${candidatePath}.publish`;
11308
11502
  let result;
@@ -11324,11 +11518,11 @@ var SkillKitSourceDriver = class {
11324
11518
  `SkillKit provider resolved ${resolvedIdentity.commit ?? "non-Git content"} instead of requested commit ${requestedCommit}`
11325
11519
  );
11326
11520
  }
11327
- const cachePath = cachePathFor4(spec, dirname23(dirname23(specCachePath)), resolvedIdentity.cacheKey);
11521
+ const cachePath = cachePathFor4(spec, dirname24(dirname24(specCachePath)), resolvedIdentity.cacheKey);
11328
11522
  if (await pathExists(cachePath)) {
11329
11523
  return { path: cachePath, commit: resolvedIdentity.commit, cacheIdentity: resolvedIdentity.cacheKey };
11330
11524
  }
11331
- const publishCandidate = resolve21(result.path) === resolve21(candidatePath) ? candidatePath : publishPath;
11525
+ const publishCandidate = resolve22(result.path) === resolve22(candidatePath) ? candidatePath : publishPath;
11332
11526
  if (publishCandidate === publishPath) await cp3(result.path, publishPath, { recursive: true, dereference: true });
11333
11527
  try {
11334
11528
  await rename7(publishCandidate, cachePath);
@@ -11382,7 +11576,7 @@ var SkillKitSourceDriver = class {
11382
11576
  for (const skill of this.discover(resolved.resolvedPath)) {
11383
11577
  const skillMd = join34(skill.path, "SKILL.md");
11384
11578
  if (await pathExists(skillMd)) {
11385
- this.core.translateSkill(await readFile28(skillMd, "utf8"), "openclaw", { sourceFilename: "SKILL.md" });
11579
+ this.core.translateSkill(await readFile29(skillMd, "utf8"), "openclaw", { sourceFilename: "SKILL.md" });
11386
11580
  }
11387
11581
  }
11388
11582
  return resolved;
@@ -11411,7 +11605,7 @@ function normalizeProviderSource(spec) {
11411
11605
  return spec;
11412
11606
  }
11413
11607
  function cachePathFor4(spec, cacheRoot, immutableIdentity) {
11414
- const root = cacheRoot ? resolve21(cacheRoot) : join34(homedir8(), ".agentwheel", "cache");
11608
+ const root = cacheRoot ? resolve22(cacheRoot) : join34(homedir9(), ".agentwheel", "cache");
11415
11609
  const sourceIdentity = createHash14("sha256").update(spec).digest("hex");
11416
11610
  const snapshotIdentity = immutableIdentity ? `-${immutableIdentity.toLowerCase()}` : "";
11417
11611
  return join34(root, "skillkit", `${packageSlug(spec)}-${sourceIdentity}${snapshotIdentity}`);
@@ -11458,14 +11652,14 @@ async function checkoutCommit(root, commit) {
11458
11652
  // src/source/vercel-skills.ts
11459
11653
  init_fs();
11460
11654
  import { stat as stat9 } from "fs/promises";
11461
- import { basename as basename15, join as join35, relative as relative11, resolve as resolve22 } from "path";
11655
+ import { basename as basename15, join as join35, relative as relative12, resolve as resolve23 } from "path";
11462
11656
  var VercelSkillsSourceDriver = class {
11463
11657
  name = "vercel-skills";
11464
11658
  git = new GitSourceDriver();
11465
11659
  async resolve(source, options = {}) {
11466
11660
  const parsed = parseVercelSource(source);
11467
11661
  if (parsed.kind === "local") {
11468
- const resolvedPath = resolve22(parsed.path);
11662
+ const resolvedPath = resolve23(parsed.path);
11469
11663
  if (!await pathExists(resolvedPath) || !(await stat9(resolvedPath)).isDirectory()) {
11470
11664
  throw new Error(`Vercel skills local source not found: ${resolvedPath}`);
11471
11665
  }
@@ -11525,7 +11719,7 @@ async function resolveVercelSkillSubpath(root, subpath) {
11525
11719
  for (const candidate of candidates) {
11526
11720
  if (await pathExists(candidate)) return candidate;
11527
11721
  }
11528
- const tried = candidates.map((candidate) => relative11(root, candidate)).join(", ");
11722
+ const tried = candidates.map((candidate) => relative12(root, candidate)).join(", ");
11529
11723
  throw new Error(`Vercel skills subpath not found: ${subpath} (tried ${tried})`);
11530
11724
  }
11531
11725
  function parseVercelSource(source) {
@@ -11595,7 +11789,7 @@ init_identify();
11595
11789
 
11596
11790
  // src/staging/staging.ts
11597
11791
  import { chmod as chmod3, cp as cp5, mkdir as mkdir22, mkdtemp as mkdtemp4, readdir as readdir11, stat as stat12 } from "fs/promises";
11598
- import { basename as basename19, dirname as dirname27, join as join39, relative as relative13, resolve as resolve25, sep as sep8 } from "path";
11792
+ import { basename as basename19, dirname as dirname28, join as join39, relative as relative14, resolve as resolve26, sep as sep8 } from "path";
11599
11793
  import { tmpdir as tmpdir5 } from "os";
11600
11794
  init_fs();
11601
11795
 
@@ -11603,8 +11797,8 @@ init_fs();
11603
11797
  init_artifact();
11604
11798
  init_fs();
11605
11799
  import { createHash as createHash15 } from "crypto";
11606
- import { readdir as readdir9, readFile as readFile29, stat as stat10, writeFile as writeFile19 } from "fs/promises";
11607
- import { basename as basename16, dirname as dirname24, extname as extname3, join as join36, relative as relative12, resolve as resolve24, sep as sep7 } from "path";
11800
+ import { readdir as readdir9, readFile as readFile30, stat as stat10, writeFile as writeFile19 } from "fs/promises";
11801
+ import { basename as basename16, dirname as dirname25, extname as extname3, join as join36, relative as relative13, resolve as resolve25, sep as sep7 } from "path";
11608
11802
  var includePattern = /<!--\s*openpack:include(\?)?\s+([^>]+?)\s*-->/g;
11609
11803
  var escapedIncludePattern = /<!--\s*openpack\\:include(\?)?\s+([^>]+?)\s*-->/g;
11610
11804
  var generatedPattern = /<!--\s*(?:BEGIN|END)\s+openpack:include\b/;
@@ -11650,7 +11844,7 @@ async function validateMarkdownIncludes(artifacts, packageRoot, options = {}) {
11650
11844
  }
11651
11845
  }
11652
11846
  async function expandFile(file, packageRoot, appendEntries, artifactPaths, options) {
11653
- const raw = await readFile29(file, "utf8");
11847
+ const raw = await readFile30(file, "utf8");
11654
11848
  const owner = ownerSelector(packageRoot, file, options.nodeId);
11655
11849
  const expanded = await expandContent(raw, packageRoot, [owner], artifactPaths, options);
11656
11850
  let content = expanded.content;
@@ -11752,14 +11946,14 @@ async function expandInclude(selector, packageRoot, artifactPaths, options) {
11752
11946
  if (!stats.isFile()) {
11753
11947
  throw new Error(`OpenPack include is not a file: ${displaySelector}`);
11754
11948
  }
11755
- const raw = sourceContent ?? await readFile29(sourcePath, "utf8");
11949
+ const raw = sourceContent ?? await readFile30(sourcePath, "utf8");
11756
11950
  const { optional: _optional, markers: _markers, chain: _chain, ...childOptions } = options;
11757
11951
  const expanded = await expandContent(raw, includePackageRoot, [...options.chain, displaySelector], includeArtifactPaths, {
11758
11952
  ...childOptions,
11759
11953
  nodeId: includeNodeId
11760
11954
  });
11761
11955
  const contentHash = sha2563(expanded.content);
11762
- const identity = `${includeNodeId ?? resolve24(includePackageRoot)}\0${parsed.selector}\0${contentHash}`;
11956
+ const identity = `${includeNodeId ?? resolve25(includePackageRoot)}\0${parsed.selector}\0${contentHash}`;
11763
11957
  const ownEntry = { selector: displaySelector, hash: contentHash };
11764
11958
  const composedFrom = uniqueComposedFrom([ownEntry, ...expanded.composedFrom]);
11765
11959
  if (!options.markers) return { rendered: expanded.content, composedFrom, identity };
@@ -11812,8 +12006,8 @@ function extractOpenPackIncludeSelectors(content) {
11812
12006
  return selectors;
11813
12007
  }
11814
12008
  function resolvePackageSelector(packageRoot, selector) {
11815
- const root = resolve24(packageRoot);
11816
- const resolved = resolve24(root, selector);
12009
+ const root = resolve25(packageRoot);
12010
+ const resolved = resolve25(root, selector);
11817
12011
  if (resolved !== root && !resolved.startsWith(`${root}${sep7}`)) {
11818
12012
  throw new Error(`OpenPack include escapes package root: ${selector}`);
11819
12013
  }
@@ -11843,12 +12037,12 @@ async function listMarkdownFiles(root) {
11843
12037
  }
11844
12038
  function composeEntriesForFile(artifact, file) {
11845
12039
  if (!artifact.compose?.length) return [];
11846
- if (artifact.kind === "file") return [resolve24(artifact.stagedPath ?? artifact.sourcePath), resolve24(file)].every(Boolean) && resolve24(artifact.stagedPath ?? artifact.sourcePath) === resolve24(file) ? artifact.compose : [];
11847
- return basename16(file) === "SKILL.md" && dirname24(file) === resolve24(artifact.stagedPath ?? artifact.sourcePath) ? artifact.compose : [];
12040
+ if (artifact.kind === "file") return [resolve25(artifact.stagedPath ?? artifact.sourcePath), resolve25(file)].every(Boolean) && resolve25(artifact.stagedPath ?? artifact.sourcePath) === resolve25(file) ? artifact.compose : [];
12041
+ return basename16(file) === "SKILL.md" && dirname25(file) === resolve25(artifact.stagedPath ?? artifact.sourcePath) ? artifact.compose : [];
11848
12042
  }
11849
12043
  function isPrimaryMarkdownFile(artifact, file) {
11850
- if (artifact.kind === "file") return resolve24(artifact.stagedPath ?? artifact.sourcePath) === resolve24(file);
11851
- return basename16(file) === "SKILL.md" && dirname24(file) === resolve24(artifact.stagedPath ?? artifact.sourcePath);
12044
+ if (artifact.kind === "file") return resolve25(artifact.stagedPath ?? artifact.sourcePath) === resolve25(file);
12045
+ return basename16(file) === "SKILL.md" && dirname25(file) === resolve25(artifact.stagedPath ?? artifact.sourcePath);
11852
12046
  }
11853
12047
  function orderedForExpansion(artifacts) {
11854
12048
  return [...artifacts].sort((a, b) => Number(a.type === "fragments") - Number(b.type === "fragments"));
@@ -11865,7 +12059,7 @@ function applyReplacements(content, replacements) {
11865
12059
  return out + content.slice(cursor);
11866
12060
  }
11867
12061
  function relativeSelector(root, file) {
11868
- return relative12(root, file).replaceAll("\\", "/");
12062
+ return relative13(root, file).replaceAll("\\", "/");
11869
12063
  }
11870
12064
  function ownerSelector(root, file, nodeId) {
11871
12065
  const selector = relativeSelector(root, file);
@@ -11895,8 +12089,8 @@ function artifactPathMap(artifacts) {
11895
12089
 
11896
12090
  // src/staging/customize.ts
11897
12091
  init_fs();
11898
- import { cp as cp4, mkdir as mkdir20, readdir as readdir10, readFile as readFile30, writeFile as writeFile20 } from "fs/promises";
11899
- import { dirname as dirname25, join as join37 } from "path";
12092
+ import { cp as cp4, mkdir as mkdir20, readdir as readdir10, readFile as readFile31, writeFile as writeFile20 } from "fs/promises";
12093
+ import { dirname as dirname26, join as join37 } from "path";
11900
12094
  async function applyCustomizations(artifacts, options) {
11901
12095
  let next = [...artifacts];
11902
12096
  next = await applyReplacements2(next, options, "override", installableArtifactTypes());
@@ -11917,10 +12111,10 @@ async function applyInstructionOverlay(artifacts, options) {
11917
12111
  const index = artifacts.findIndex((artifact2) => artifact2.type === "instructions");
11918
12112
  if (index < 0) return artifacts;
11919
12113
  const artifact = artifacts[index];
11920
- const managed = await readFile30(artifact.stagedPath ?? artifact.sourcePath, "utf8");
11921
- const local = await readFile30(overlayPath, "utf8");
12114
+ const managed = await readFile31(artifact.stagedPath ?? artifact.sourcePath, "utf8");
12115
+ const local = await readFile31(overlayPath, "utf8");
11922
12116
  const composedPath = join37(options.stageRoot, ".agentwheel-composed", "instructions", "AGENTS.md");
11923
- await mkdir20(dirname25(composedPath), { recursive: true });
12117
+ await mkdir20(dirname26(composedPath), { recursive: true });
11924
12118
  await writeFile20(
11925
12119
  composedPath,
11926
12120
  [
@@ -11993,7 +12187,7 @@ async function applyReplacements2(artifacts, options, channel, artifactTypes) {
11993
12187
  const artifactKind = entry.isDirectory() ? "dir" : "file";
11994
12188
  const existing = byKey.get(artifactMapKey);
11995
12189
  const stagedPath = join37(options.stageRoot, ".agentwheel-composed", channel, type, entry.name);
11996
- await mkdir20(dirname25(stagedPath), { recursive: true });
12190
+ await mkdir20(dirname26(stagedPath), { recursive: true });
11997
12191
  await cp4(full, stagedPath, { recursive: artifactKind === "dir", dereference: true });
11998
12192
  byKey.set(artifactMapKey, {
11999
12193
  ...existing,
@@ -12038,8 +12232,8 @@ async function sortedDirEntries2(path) {
12038
12232
 
12039
12233
  // src/staging/claude-subagents.ts
12040
12234
  init_fs();
12041
- import { mkdir as mkdir21, readFile as readFile31, writeFile as writeFile21 } from "fs/promises";
12042
- import { basename as basename18, dirname as dirname26, join as join38 } from "path";
12235
+ import { mkdir as mkdir21, readFile as readFile32, writeFile as writeFile21 } from "fs/promises";
12236
+ import { basename as basename18, dirname as dirname27, join as join38 } from "path";
12043
12237
  async function renderClaudeSubagents(artifacts, stageRoot, adapter) {
12044
12238
  if (adapter?.name !== "claude") return artifacts;
12045
12239
  const names = /* @__PURE__ */ new Set();
@@ -12068,9 +12262,9 @@ async function renderClaudeSubagent(artifact, stageRoot) {
12068
12262
  if (artifact.kind === "file" && !artifact.name.toLowerCase().endsWith(".md") && !sourcePath.toLowerCase().endsWith(".md")) {
12069
12263
  throw new Error(`Claude subagent ${artifact.relativePath} must be a .md file or directory containing AGENTS.md.`);
12070
12264
  }
12071
- const content = await readFile31(markdownPath, "utf8");
12265
+ const content = await readFile32(markdownPath, "utf8");
12072
12266
  const renderedPath = join38(stageRoot, ".agentwheel-rendered", "claude-subagents", `${agentName}.md`);
12073
- await mkdir21(dirname26(renderedPath), { recursive: true });
12267
+ await mkdir21(dirname27(renderedPath), { recursive: true });
12074
12268
  await writeFile21(renderedPath, content.endsWith("\n") ? content : `${content}
12075
12269
  `, "utf8");
12076
12270
  return {
@@ -12113,7 +12307,7 @@ async function stageResolvedArtifactsRaw(resolved, artifacts, parentDir = tmpdir
12113
12307
  await removeOnFailure(root, async () => {
12114
12308
  for (const artifact of artifacts) {
12115
12309
  const stagedPath = join39(root, artifact.relativePath);
12116
- await mkdir22(dirname27(stagedPath), { recursive: true });
12310
+ await mkdir22(dirname28(stagedPath), { recursive: true });
12117
12311
  await cp5(artifact.sourcePath, stagedPath, {
12118
12312
  recursive: artifact.kind === "dir",
12119
12313
  dereference: true,
@@ -12219,25 +12413,25 @@ async function copyAsset(asset, source, dest) {
12219
12413
  throw new Error(`Asset include source is not a file or directory: ${source}`);
12220
12414
  }
12221
12415
  if (!asset.include?.length) {
12222
- await mkdir22(dirname27(dest), { recursive: true });
12416
+ await mkdir22(dirname28(dest), { recursive: true });
12223
12417
  await cp5(source, dest, { recursive: true, dereference: true });
12224
12418
  if (asset.mode === "copy") await normalizeCopiedModes(dest);
12225
12419
  return;
12226
12420
  }
12227
12421
  for (const file of await listFiles2(source)) {
12228
- const rel = relative13(source, file).replaceAll("\\", "/");
12422
+ const rel = relative14(source, file).replaceAll("\\", "/");
12229
12423
  if (!matchesAny(rel, asset.include) && !matchesAny(basename19(file), asset.include)) continue;
12230
12424
  await copyAssetFile(file, join39(dest, rel), asset);
12231
12425
  }
12232
12426
  }
12233
12427
  async function copyAssetFile(source, dest, asset) {
12234
- await mkdir22(dirname27(dest), { recursive: true });
12428
+ await mkdir22(dirname28(dest), { recursive: true });
12235
12429
  await cp5(source, dest, { dereference: true });
12236
12430
  if (asset.mode === "copy") await chmod3(dest, 420);
12237
12431
  }
12238
12432
  function resolvePackagePath(packageRoot, path) {
12239
- const resolved = resolve25(packageRoot, path);
12240
- const root = resolve25(packageRoot);
12433
+ const resolved = resolve26(packageRoot, path);
12434
+ const root = resolve26(packageRoot);
12241
12435
  if (resolved !== root && !resolved.startsWith(`${root}${sep8}`)) {
12242
12436
  throw new Error(`Asset include escapes package root: ${path}`);
12243
12437
  }
@@ -12286,12 +12480,12 @@ init_adapters();
12286
12480
  init_adapter();
12287
12481
  init_artifact();
12288
12482
  init_workspace();
12289
- import { appendFile, cp as cp6, lstat as lstat3, mkdir as mkdir23, readdir as readdir13, rm as rm13 } from "fs/promises";
12290
- import { dirname as dirname29, join as join42, relative as relative14 } from "path";
12483
+ import { appendFile, cp as cp6, lstat as lstat4, mkdir as mkdir23, readdir as readdir13, rm as rm13 } from "fs/promises";
12484
+ import { dirname as dirname30, join as join42, relative as relative15 } from "path";
12291
12485
 
12292
12486
  // src/resolve/graph.ts
12293
12487
  import { createHash as createHash17 } from "crypto";
12294
- import { readdir as readdir12, readFile as readFile34, stat as stat14 } from "fs/promises";
12488
+ import { readdir as readdir12, readFile as readFile35, stat as stat14 } from "fs/promises";
12295
12489
  import { basename as basename20, extname as extname4, join as join41 } from "path";
12296
12490
  init_artifact();
12297
12491
  init_fs();
@@ -12302,7 +12496,7 @@ init_workspace();
12302
12496
  init_selection();
12303
12497
  init_fs();
12304
12498
  import { createHash as createHash16 } from "crypto";
12305
- import { readFile as readFile32 } from "fs/promises";
12499
+ import { readFile as readFile33 } from "fs/promises";
12306
12500
  import { z as z12 } from "zod";
12307
12501
  var selectionSourceConfigSchema = z12.object({
12308
12502
  schemaVersion: z12.literal(2),
@@ -12321,7 +12515,7 @@ async function resolveSelectionImport(sourceRoot, sourceDriver, selection) {
12321
12515
  }
12322
12516
  let raw;
12323
12517
  try {
12324
- raw = JSON.parse(await readFile32(path, "utf8"));
12518
+ raw = JSON.parse(await readFile33(path, "utf8"));
12325
12519
  } catch (error) {
12326
12520
  const message = error instanceof Error ? error.message : String(error);
12327
12521
  throw new Error(`Selection import '${parsedSelection.export}' cannot parse ${path}: ${message}`);
@@ -12385,17 +12579,17 @@ function resolveExport(name, selections, stack) {
12385
12579
  }
12386
12580
  function applySelection(inherited, additions, exclusions) {
12387
12581
  const excluded = new Set(exclusions);
12388
- return sortedUnique3([...inherited, ...additions]).filter((selector) => !excluded.has(selector));
12582
+ return sortedUnique4([...inherited, ...additions]).filter((selector) => !excluded.has(selector));
12389
12583
  }
12390
12584
  function normalizeSelectors(values, label) {
12391
12585
  try {
12392
- return sortedUnique3(normalizeArtifactSelectors(values) ?? []);
12586
+ return sortedUnique4(normalizeArtifactSelectors(values) ?? []);
12393
12587
  } catch (error) {
12394
12588
  const message = error instanceof Error ? error.message : String(error);
12395
12589
  throw new Error(`Invalid ${label}: ${message}`);
12396
12590
  }
12397
12591
  }
12398
- function sortedUnique3(values) {
12592
+ function sortedUnique4(values) {
12399
12593
  return [...new Set(values)].sort((a, b) => a.localeCompare(b));
12400
12594
  }
12401
12595
  function sha2564(value) {
@@ -12419,13 +12613,13 @@ function isRecord9(value) {
12419
12613
  }
12420
12614
 
12421
12615
  // src/resolve/identity.ts
12422
- import { homedir as homedir11 } from "os";
12423
- import { resolve as resolve27 } from "path";
12616
+ import { homedir as homedir12 } from "os";
12617
+ import { resolve as resolve28 } from "path";
12424
12618
 
12425
12619
  // src/registry/client.ts
12426
- import { readFile as readFile33, rm as rm12, stat as stat13 } from "fs/promises";
12427
- import { homedir as homedir10 } from "os";
12428
- import { dirname as dirname28, join as join40, resolve as resolve26 } from "path";
12620
+ import { readFile as readFile34, rm as rm12, stat as stat13 } from "fs/promises";
12621
+ import { homedir as homedir11 } from "os";
12622
+ import { dirname as dirname29, join as join40, resolve as resolve27 } from "path";
12429
12623
  import { fileURLToPath as fileURLToPath2 } from "url";
12430
12624
 
12431
12625
  // src/model/registry.ts
@@ -12525,7 +12719,7 @@ var RegistryClient = class {
12525
12719
  }
12526
12720
  async readCache() {
12527
12721
  if (!await pathExists(this.cachePath)) return void 0;
12528
- return registryCacheSchema.parse(JSON.parse(await readFile33(this.cachePath, "utf8")));
12722
+ return registryCacheSchema.parse(JSON.parse(await readFile34(this.cachePath, "utf8")));
12529
12723
  }
12530
12724
  isExpired(cache, ttlMs) {
12531
12725
  return this.now().getTime() - new Date(cache.fetchedAt).getTime() > ttlMs;
@@ -12542,12 +12736,12 @@ var RegistryClient = class {
12542
12736
  }
12543
12737
  const filePath = source.startsWith("file:") ? fileURLToPath2(source) : source;
12544
12738
  if (await pathExists(filePath)) {
12545
- const fullPath = resolve26(filePath);
12739
+ const fullPath = resolve27(filePath);
12546
12740
  const stats = await stat13(fullPath);
12547
- return readFile33(stats.isDirectory() ? join40(fullPath, "index.json") : fullPath, "utf8");
12741
+ return readFile34(stats.isDirectory() ? join40(fullPath, "index.json") : fullPath, "utf8");
12548
12742
  }
12549
- const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot: join40(dirname28(this.cachePath), "registry-repos") }));
12550
- return readFile33(join40(resolved.resolvedPath, "index.json"), "utf8");
12743
+ const resolved = await this.git.fetch(await this.git.resolve(source, { cacheRoot: join40(dirname29(this.cachePath), "registry-repos") }));
12744
+ return readFile34(join40(resolved.resolvedPath, "index.json"), "utf8");
12551
12745
  }
12552
12746
  warnCompatibility(entries) {
12553
12747
  for (const entry of entries) {
@@ -12585,7 +12779,7 @@ function mergeIndexes(indexes) {
12585
12779
  return [...merged.values()].sort((a, b) => a.name.localeCompare(b.name));
12586
12780
  }
12587
12781
  function defaultRegistryCachePath() {
12588
- return join40(homedir10(), ".agentwheel", "registry-cache.json");
12782
+ return join40(homedir11(), ".agentwheel", "registry-cache.json");
12589
12783
  }
12590
12784
  function sameSources(a, b) {
12591
12785
  return a.length === b.length && a.every((source, index) => source === b[index]);
@@ -12682,10 +12876,10 @@ function localSourcePath(source) {
12682
12876
  return source.startsWith("local:") ? source.slice("local:".length) : source;
12683
12877
  }
12684
12878
  function resolveLocalPath2(path, declaringPackageRoot) {
12685
- if (path === "~") return homedir11();
12686
- if (path.startsWith("~/")) return resolve27(homedir11(), path.slice(2));
12687
- if (path.startsWith("/")) return resolve27(path);
12688
- return resolve27(declaringPackageRoot, path);
12879
+ if (path === "~") return homedir12();
12880
+ if (path.startsWith("~/")) return resolve28(homedir12(), path.slice(2));
12881
+ if (path.startsWith("/")) return resolve28(path);
12882
+ return resolve28(declaringPackageRoot, path);
12689
12883
  }
12690
12884
  async function normalizeRegistrySource(name, options) {
12691
12885
  const client = options.registryClient ?? new RegistryClient({ workspaceRoot: options.workspaceRoot });
@@ -12784,7 +12978,7 @@ async function resolveDependencyGraph(roots, options) {
12784
12978
  optional: false,
12785
12979
  chain: [`workspace:${rootId}`],
12786
12980
  includeSuggestions: root.includeSuggestions ?? options.includeSuggestions,
12787
- suggestionAliases: sortedUnique4([...root.suggestionAliases ?? [], ...options.suggestionAliases ?? []])
12981
+ suggestionAliases: sortedUnique5([...root.suggestionAliases ?? [], ...options.suggestionAliases ?? []])
12788
12982
  };
12789
12983
  });
12790
12984
  const requiredQueue = rootRequirements();
@@ -13005,7 +13199,7 @@ Run without ${lockLabel === "Offline" ? "--offline" : "--frozen-lock"} first.`
13005
13199
  version: requirement.version,
13006
13200
  mode: requirement.mode,
13007
13201
  optional: requirement.optional,
13008
- selected: sortedUnique4([...previous?.selected ?? [], ...selected])
13202
+ selected: sortedUnique5([...previous?.selected ?? [], ...selected])
13009
13203
  });
13010
13204
  }
13011
13205
  return await collectDependencyNeeds(state, fetched, options, requirement.chain);
@@ -13075,7 +13269,7 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
13075
13269
  fetched,
13076
13270
  parsed.alias,
13077
13271
  dependency,
13078
- sortedUnique4([...dependency.select ?? [], parsed.selector]),
13272
+ sortedUnique5([...dependency.select ?? [], parsed.selector]),
13079
13273
  chain,
13080
13274
  options,
13081
13275
  parsed.optional || dependency.optional === true,
@@ -13127,7 +13321,7 @@ async function collectDependencyNeeds(state, fetched, options, chain) {
13127
13321
  fetched,
13128
13322
  include.alias,
13129
13323
  dependency,
13130
- sortedUnique4([...dependency.select ?? [], include.selector]),
13324
+ sortedUnique5([...dependency.select ?? [], include.selector]),
13131
13325
  chain,
13132
13326
  options,
13133
13327
  include.optional || dependency.optional === true
@@ -13160,7 +13354,7 @@ function dependencyRequirement(state, fetched, alias, dependency, select, chain,
13160
13354
  integrity: dependency.integrity,
13161
13355
  selectionReason,
13162
13356
  includeSuggestions: state.includeSuggestions,
13163
- suggestionAliases: sortedUnique4([...state.suggestionAliases])
13357
+ suggestionAliases: sortedUnique5([...state.suggestionAliases])
13164
13358
  };
13165
13359
  }
13166
13360
  function suggestionRequirement(state, fetched, alias, suggestion, select, chain, options, optional = shouldTreatSuggestionAsOptional(alias, suggestion, options), selectionReason) {
@@ -13177,7 +13371,7 @@ function suggestionRequirement(state, fetched, alias, suggestion, select, chain,
13177
13371
  );
13178
13372
  }
13179
13373
  function assertDependencyUpdateSelectors(lock, selectors) {
13180
- for (const selector of sortedUnique4(selectors ?? [])) {
13374
+ for (const selector of sortedUnique5(selectors ?? [])) {
13181
13375
  if (!lock) throw new Error(`Dependency update '${selector}' requires an existing graph lock.`);
13182
13376
  const nodeIds = matchingDependencyUpdateNodeIds(lock, selector);
13183
13377
  if (nodeIds.size === 0) throw new Error(`Tracking dependency not found in graph lock: ${selector}`);
@@ -13231,7 +13425,7 @@ function suggestionForAlias(suggestions, nodeId, alias) {
13231
13425
  return suggestion;
13232
13426
  }
13233
13427
  function warnNoDepsOnce(state, aliases, warn) {
13234
- const unique = sortedUnique4(aliases.filter(Boolean));
13428
+ const unique = sortedUnique5(aliases.filter(Boolean));
13235
13429
  if (unique.length === 0 || state.processedPackageAliases.has("__noDepsWarned")) return;
13236
13430
  state.processedPackageAliases.add("__noDepsWarned");
13237
13431
  warn?.(`--no-deps ignored dependencies for ${state.node.id}: ${unique.join(", ")}`);
@@ -13272,7 +13466,7 @@ function suggestionOptionsForState(state, options) {
13272
13466
  return {
13273
13467
  ...options,
13274
13468
  includeSuggestions: state.includeSuggestions || options.includeSuggestions === true,
13275
- suggestionAliases: sortedUnique4([...options.suggestionAliases ?? [], ...state.suggestionAliases])
13469
+ suggestionAliases: sortedUnique5([...options.suggestionAliases ?? [], ...state.suggestionAliases])
13276
13470
  };
13277
13471
  }
13278
13472
  function explicitSuggestionAlias(alias, options) {
@@ -13284,7 +13478,7 @@ function shouldTreatSuggestionAsOptional(alias, suggestion, options) {
13284
13478
  }
13285
13479
  function combinedSelectors(base, extra) {
13286
13480
  const values = [...base ?? [], ...extra ?? []];
13287
- return values.length > 0 ? sortedUnique4(values) : void 0;
13481
+ return values.length > 0 ? sortedUnique5(values) : void 0;
13288
13482
  }
13289
13483
  function parseDependencySelector(value) {
13290
13484
  const cleaned = value.trim();
@@ -13324,7 +13518,7 @@ async function collectIncludeNeeds(artifact, artifactsByRelativePath) {
13324
13518
  const file = stack.shift();
13325
13519
  if (scanned.has(file)) continue;
13326
13520
  scanned.add(file);
13327
- const content = await readFile34(file, "utf8");
13521
+ const content = await readFile35(file, "utf8");
13328
13522
  for (const include of extractOpenPackIncludeSelectors(content)) {
13329
13523
  await collectIncludeSelector(include.raw, include.optional, artifactsByRelativePath, scanned, stack, needs);
13330
13524
  }
@@ -13473,7 +13667,7 @@ function lockedNodeCoversRequirementSelection(node, requirement, options) {
13473
13667
  return false;
13474
13668
  }
13475
13669
  const requestedExclusionSet = new Set(requestedExclusions);
13476
- const requestedEffective = sortedUnique4([...lockedSelection2.inherited, ...requestedAdditions]).filter((selector) => !requestedExclusionSet.has(selector));
13670
+ const requestedEffective = sortedUnique5([...lockedSelection2.inherited, ...requestedAdditions]).filter((selector) => !requestedExclusionSet.has(selector));
13477
13671
  const lockedSelectors = new Set(node.selected);
13478
13672
  return requestedEffective.every((selector) => lockedSelectors.has(selector));
13479
13673
  }
@@ -13548,8 +13742,8 @@ function verifyIntegrity(integrity, sourceHash, label) {
13548
13742
  async function withCachePathLock(path, fn) {
13549
13743
  const previous = cacheLocks.get(path) ?? Promise.resolve();
13550
13744
  let release = () => void 0;
13551
- const current = previous.then(() => new Promise((resolve45) => {
13552
- release = resolve45;
13745
+ const current = previous.then(() => new Promise((resolve46) => {
13746
+ release = resolve46;
13553
13747
  }));
13554
13748
  cacheLocks.set(path, current);
13555
13749
  await previous;
@@ -13562,7 +13756,7 @@ async function withCachePathLock(path, fn) {
13562
13756
  }
13563
13757
  function computeSelectedSelectors(artifacts, select, isRoot, chain) {
13564
13758
  if (isRoot && select === void 0) {
13565
- return sortedUnique4(artifacts.map(artifactSelectorKey));
13759
+ return sortedUnique5(artifacts.map(artifactSelectorKey));
13566
13760
  }
13567
13761
  const explicit = normalizeArtifactSelectors(select) ?? [];
13568
13762
  const available = new Set(artifacts.map(artifactSelectorKey));
@@ -13571,7 +13765,7 @@ function computeSelectedSelectors(artifacts, select, isRoot, chain) {
13571
13765
  throw new Error(`Selected artifact not found in package: ${missing.join(", ")} (${chain.join(" -> ")})`);
13572
13766
  }
13573
13767
  const required = artifacts.filter((artifact) => artifact.required && artifact.type !== "fragments").map(artifactSelectorKey);
13574
- return sortedUnique4([...explicit, ...required]);
13768
+ return sortedUnique5([...explicit, ...required]);
13575
13769
  }
13576
13770
  function materializeRawNode(state) {
13577
13771
  refreshNode(state);
@@ -13584,11 +13778,11 @@ function materializeRawNode(state) {
13584
13778
  };
13585
13779
  }
13586
13780
  function refreshNode(state) {
13587
- state.node.requiredBy = sortedUnique4([...state.requiredBy]);
13588
- state.node.selected = sortedUnique4([...state.selected]);
13781
+ state.node.requiredBy = sortedUnique5([...state.requiredBy]);
13782
+ state.node.selected = sortedUnique5([...state.selected]);
13589
13783
  const selectionReasons = {};
13590
13784
  for (const [selector, reasons] of [...state.selectionReasons.entries()].sort(([a], [b]) => a.localeCompare(b))) {
13591
- selectionReasons[selector] = sortedUnique4([...reasons]);
13785
+ selectionReasons[selector] = sortedUnique5([...reasons]);
13592
13786
  }
13593
13787
  state.node.selectionReasons = Object.keys(selectionReasons).length > 0 ? selectionReasons : void 0;
13594
13788
  }
@@ -13633,7 +13827,7 @@ function graphNodeId(name, version, normalizedSource, resolvedCommit, sourceHash
13633
13827
  const digest3 = createHash17("sha256").update(normalizedSource).update("\0").update(resolvedCommit ?? sourceHash).digest("hex").slice(0, 12);
13634
13828
  return `${name}@${version}+${digest3}`;
13635
13829
  }
13636
- function sortedUnique4(values) {
13830
+ function sortedUnique5(values) {
13637
13831
  return [...new Set(values)].sort((a, b) => a.localeCompare(b));
13638
13832
  }
13639
13833
  function closureProcessingKey(value, updateClosure) {
@@ -13673,7 +13867,7 @@ init_declarations();
13673
13867
  async function remember(workspaceRoot, runtime, text) {
13674
13868
  const overlayPath = join42(workspaceRoot, ".agentwheel", "overlays", runtime, "instructions.local.md");
13675
13869
  declareMutationPath(overlayPath);
13676
- await mkdir23(dirname29(overlayPath), { recursive: true });
13870
+ await mkdir23(dirname30(overlayPath), { recursive: true });
13677
13871
  await appendFile(overlayPath, `${text.trim()}
13678
13872
  `, "utf8");
13679
13873
  return { overlayPath };
@@ -13701,12 +13895,12 @@ async function ejectArtifact(workspaceRoot, item) {
13701
13895
  for (const path of await listFilesIfPresent(ejectedPath)) declareMutationPath(path);
13702
13896
  if (artifact.kind === "dir") {
13703
13897
  for (const sourceFile of await listFiles3(sourcePath)) {
13704
- declareMutationPath(join42(ejectedPath, relative14(sourcePath, sourceFile)));
13898
+ declareMutationPath(join42(ejectedPath, relative15(sourcePath, sourceFile)));
13705
13899
  }
13706
13900
  } else {
13707
13901
  declareMutationPath(ejectedPath);
13708
13902
  }
13709
- await mkdir23(dirname29(ejectedPath), { recursive: true });
13903
+ await mkdir23(dirname30(ejectedPath), { recursive: true });
13710
13904
  await rm13(ejectedPath, { recursive: true, force: true });
13711
13905
  await cp6(sourcePath, ejectedPath, { recursive: artifact.kind === "dir", dereference: true });
13712
13906
  return {
@@ -13722,7 +13916,7 @@ async function ejectArtifact(workspaceRoot, item) {
13722
13916
  }
13723
13917
  }
13724
13918
  async function listFiles3(root) {
13725
- const stats = await lstat3(root);
13919
+ const stats = await lstat4(root);
13726
13920
  if (stats.isFile()) return [root];
13727
13921
  const files = [];
13728
13922
  async function walk2(dir) {
@@ -13825,7 +14019,7 @@ init_adapter();
13825
14019
  init_graph_lock();
13826
14020
  import { createHash as createHash19 } from "crypto";
13827
14021
  import { mkdir as mkdir25, readdir as readdir14 } from "fs/promises";
13828
- import { basename as basename21, dirname as dirname31, join as join45, posix as posix6, resolve as resolve31 } from "path";
14022
+ import { basename as basename21, dirname as dirname32, join as join45, posix as posix6, resolve as resolve31 } from "path";
13829
14023
  init_paths();
13830
14024
  init_merge_removal();
13831
14025
  init_transaction();
@@ -13992,7 +14186,7 @@ function formatSelectionImport(root) {
13992
14186
  // src/resolve/render.ts
13993
14187
  init_selection();
13994
14188
  import { createHash as createHash18 } from "crypto";
13995
- import { readFile as readFile35, mkdtemp as mkdtemp5 } from "fs/promises";
14189
+ import { readFile as readFile36, mkdtemp as mkdtemp5 } from "fs/promises";
13996
14190
  import { tmpdir as tmpdir6 } from "os";
13997
14191
  import { join as join43 } from "path";
13998
14192
  init_fs();
@@ -14185,7 +14379,7 @@ async function artifactContentMap(artifacts) {
14185
14379
  const out = /* @__PURE__ */ new Map();
14186
14380
  for (const artifact of artifacts) {
14187
14381
  if (artifact.kind !== "file") continue;
14188
- out.set(artifact.relativePath.replaceAll("\\", "/"), await readFile35(artifact.stagedPath ?? artifact.sourcePath, "utf8"));
14382
+ out.set(artifact.relativePath.replaceAll("\\", "/"), await readFile36(artifact.stagedPath ?? artifact.sourcePath, "utf8"));
14189
14383
  }
14190
14384
  return out;
14191
14385
  }
@@ -14507,9 +14701,9 @@ init_fs();
14507
14701
 
14508
14702
  // src/lifecycle/trust.ts
14509
14703
  init_fs();
14510
- import { mkdir as mkdir24, readFile as readFile36 } from "fs/promises";
14511
- import { homedir as homedir12 } from "os";
14512
- import { dirname as dirname30, join as join44 } from "path";
14704
+ import { mkdir as mkdir24, readFile as readFile37 } from "fs/promises";
14705
+ import { homedir as homedir13 } from "os";
14706
+ import { dirname as dirname31, join as join44 } from "path";
14513
14707
  import { z as z14 } from "zod";
14514
14708
  var trustStoreSchema = z14.object({
14515
14709
  version: z14.literal(1),
@@ -14517,9 +14711,9 @@ var trustStoreSchema = z14.object({
14517
14711
  });
14518
14712
  function normalizeTrustPolicy(policy) {
14519
14713
  return {
14520
- allow: sortedUnique5(policy?.allow ?? []),
14521
- acceptedSources: sortedUnique5(policy?.acceptedSources ?? []),
14522
- denyArtifactTypes: sortedUnique5(policy?.denyArtifactTypes ?? []),
14714
+ allow: sortedUnique6(policy?.allow ?? []),
14715
+ acceptedSources: sortedUnique6(policy?.acceptedSources ?? []),
14716
+ denyArtifactTypes: sortedUnique6(policy?.denyArtifactTypes ?? []),
14523
14717
  requireReviewForTransitive: policy?.requireReviewForTransitive ?? true
14524
14718
  };
14525
14719
  }
@@ -14556,10 +14750,10 @@ async function readTrustedSources(_workspaceRoot, storePath = defaultTrustStoreP
14556
14750
  return (await readTrustStore(storePath)).acceptedSources;
14557
14751
  }
14558
14752
  async function rememberTrustedSources(_workspaceRoot, sources, storePath = defaultTrustStorePath()) {
14559
- const unique = sortedUnique5(sources);
14753
+ const unique = sortedUnique6(sources);
14560
14754
  if (unique.length === 0) return [];
14561
14755
  const store = await readTrustStore(storePath);
14562
- const acceptedSources = sortedUnique5([...store.acceptedSources, ...unique]);
14756
+ const acceptedSources = sortedUnique6([...store.acceptedSources, ...unique]);
14563
14757
  await writeTrustStore(storePath, { version: 1, acceptedSources });
14564
14758
  return unique.filter((source) => !store.acceptedSources.includes(source));
14565
14759
  }
@@ -14578,19 +14772,19 @@ function matchesGlob2(value, pattern) {
14578
14772
  const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
14579
14773
  return new RegExp(`^${escaped}$`).test(value);
14580
14774
  }
14581
- function sortedUnique5(values) {
14775
+ function sortedUnique6(values) {
14582
14776
  return [...new Set(values)].sort((a, b) => a.localeCompare(b));
14583
14777
  }
14584
14778
  async function readTrustStore(path) {
14585
14779
  if (!await pathExists(path)) return { version: 1, acceptedSources: [] };
14586
- return trustStoreSchema.parse(JSON.parse(await readFile36(path, "utf8")));
14780
+ return trustStoreSchema.parse(JSON.parse(await readFile37(path, "utf8")));
14587
14781
  }
14588
14782
  async function writeTrustStore(path, store) {
14589
- await mkdir24(dirname30(path), { recursive: true });
14783
+ await mkdir24(dirname31(path), { recursive: true });
14590
14784
  await writeJsonAtomic(path, trustStoreSchema.parse(store));
14591
14785
  }
14592
14786
  function defaultTrustStorePath() {
14593
- return process.env.AGENTWHEEL_TRUST_STORE ?? join44(homedir12(), ".agentwheel", "trust.json");
14787
+ return process.env.AGENTWHEEL_TRUST_STORE ?? join44(homedir13(), ".agentwheel", "trust.json");
14594
14788
  }
14595
14789
 
14596
14790
  // src/lifecycle/source-plan.ts
@@ -14599,14 +14793,14 @@ init_selection();
14599
14793
 
14600
14794
  // src/model/workspace-owner.ts
14601
14795
  import { Buffer as Buffer2 } from "buffer";
14602
- import { isAbsolute as isAbsolute9, resolve as resolve28 } from "path";
14796
+ import { isAbsolute as isAbsolute10, resolve as resolve29 } from "path";
14603
14797
  var workspaceOwnerPrefix = "workspace-root:";
14604
14798
  var fleetOwnerSeparator = "|fleet-id:";
14605
14799
  var encodedRootPrefix = "v2:";
14606
14800
  var fleetIdPattern = /^[a-z0-9][a-z0-9._-]*$/i;
14607
14801
  var base64UrlPattern = /^[a-z0-9_-]+$/i;
14608
14802
  function workspaceOwnerForRoot(workspaceRoot, fleetId) {
14609
- const root = resolve28(workspaceRoot);
14803
+ const root = resolve29(workspaceRoot);
14610
14804
  const encodedRoot = root.includes(fleetOwnerSeparator) ? `${encodedRootPrefix}${Buffer2.from(root, "utf8").toString("base64url")}` : root;
14611
14805
  const legacy = `${workspaceOwnerPrefix}${encodedRoot}`;
14612
14806
  return fleetId ? `${legacy}${fleetOwnerSeparator}${fleetId}` : legacy;
@@ -14618,7 +14812,7 @@ function parseWorkspaceOwner(value) {
14618
14812
  const encodedRoot = separator === -1 ? encoded : encoded.slice(0, separator);
14619
14813
  const fleetId = separator === -1 ? void 0 : encoded.slice(separator + fleetOwnerSeparator.length);
14620
14814
  const rootValue = decodeRoot(encodedRoot);
14621
- if (!rootValue || !isAbsolute9(rootValue) || resolve28(rootValue) !== rootValue) return void 0;
14815
+ if (!rootValue || !isAbsolute10(rootValue) || resolve29(rootValue) !== rootValue) return void 0;
14622
14816
  if (fleetId !== void 0 && !fleetIdPattern.test(fleetId)) return void 0;
14623
14817
  return { root: rootValue, ...fleetId ? { fleetId } : {} };
14624
14818
  }
@@ -14711,187 +14905,8 @@ async function createExactMcpRetirementPlan(desiredArtifacts, adapter, targetRoo
14711
14905
  };
14712
14906
  }
14713
14907
 
14714
- // src/model/fleet.ts
14715
- init_fs();
14716
- init_declarations();
14717
- init_workspace();
14718
- import { lstat as lstat4, readFile as readFile37, realpath as realpath2 } from "fs/promises";
14719
- import { homedir as homedir13 } from "os";
14720
- import { isAbsolute as isAbsolute10, relative as relative15, resolve as resolve29 } from "path";
14721
- async function resolveWorkspaceScope(request = {}) {
14722
- const selected = [request.user === true, request.local === true, request.fleet !== void 0].filter(Boolean).length;
14723
- if (selected > 1) {
14724
- throw new Error("Choose exactly one workspace selector: --user, --local, or --fleet <id>.");
14725
- }
14726
- const globalRoot = resolve29(request.globalRoot ?? homedir13());
14727
- if (request.user) {
14728
- const config2 = await readWorkspaceConfig(globalRoot);
14729
- assertNonFleetScope("user", config2);
14730
- return { kind: "user", root: globalRoot, config: config2 };
14731
- }
14732
- if (request.fleet !== void 0) {
14733
- const id = fleetIdSchema.parse(request.fleet);
14734
- const registration = await showRegisteredFleet(id, { globalRoot });
14735
- const root = await assertCanonicalDirectory(registration.root, `Registered fleet '${id}' root`);
14736
- const config2 = await readRequiredConfig(root, `fleet '${id}'`);
14737
- assertFleetContract(id, registration, config2);
14738
- return { kind: "fleet", root, fleetId: id, config: config2 };
14739
- }
14740
- const cwd = resolve29(request.cwd ?? process.cwd());
14741
- const discoveredRoot = await findExistingWorkspaceRoot(cwd);
14742
- if (!discoveredRoot || discoveredRoot === globalRoot) {
14743
- if (request.local === true && cwd !== globalRoot) {
14744
- return { kind: "local", root: cwd, config: await readWorkspaceConfig(cwd) };
14745
- }
14746
- throw missingScopeError(request.local === true ? "local" : "implicit local");
14747
- }
14748
- const config = await readRequiredConfig(discoveredRoot, "local");
14749
- assertNonFleetScope("local", config);
14750
- return { kind: "local", root: discoveredRoot, config };
14751
- }
14752
- async function registerFleet(request) {
14753
- const id = fleetIdSchema.parse(request.id);
14754
- const requiredPackages = sortedUnique6(request.requiredPackages);
14755
- if (requiredPackages.length === 0) throw new Error("Fleet registration requires at least one --required-package <name>.");
14756
- const globalRoot = resolve29(request.globalRoot ?? homedir13());
14757
- const home = await readWorkspaceConfig(globalRoot);
14758
- if (supportsFleetConfig(home) && home.fleetId) {
14759
- throw new Error(`The home config is fleet '${home.fleetId}', so it cannot own the global fleet registry.`);
14760
- }
14761
- const existing = supportsFleetConfig(home) ? await canonicalizeExistingFleetRoots(home.fleets, globalRoot) : {};
14762
- if (existing[id]) throw new Error(`Fleet '${id}' is already registered.`);
14763
- const root = await assertCanonicalDirectory(request.root, `Fleet '${id}' root`);
14764
- const duplicateRoot = Object.entries(existing).find(([, value]) => value.root === root);
14765
- if (duplicateRoot) throw new Error(`Fleet root ${root} is already registered as '${duplicateRoot[0]}'.`);
14766
- if (root === globalRoot) throw new Error("A fleet root must be outside the user config root contract.");
14767
- const target = await readRequiredConfig(root, `fleet '${id}'`);
14768
- const registration = registeredFleetSchema.parse({ root, requiredPackages });
14769
- assertFleetContract(id, registration, target);
14770
- const upgraded = workspaceConfigSchema.parse({
14771
- ...home,
14772
- schemaVersion: CURRENT_WORKSPACE_SCHEMA_VERSION,
14773
- exports: home.schemaVersion >= 2 ? home.exports : { selections: {} },
14774
- fleets: { ...existing, [id]: registration }
14775
- });
14776
- const configPath = globalWorkspaceConfigPath(globalRoot);
14777
- declareMutationPath(configPath);
14778
- await writeJsonAtomic(configPath, upgraded);
14779
- return { id, ...registration };
14780
- }
14781
- async function canonicalizeExistingFleetRoots(fleets, globalRoot) {
14782
- const canonical = /* @__PURE__ */ new Map();
14783
- const normalized = {};
14784
- for (const [id, registration] of Object.entries(fleets).sort(([a], [b]) => a.localeCompare(b))) {
14785
- const root = await canonicalizeDirectory(registration.root, `Registered fleet '${id}' root`);
14786
- if (root === globalRoot) throw new Error(`Registered fleet '${id}' root must be outside the user config root contract.`);
14787
- const incumbent = canonical.get(root);
14788
- if (incumbent) {
14789
- throw new Error(`Fleet root ${root} is registered more than once as '${incumbent}' and '${id}'.`);
14790
- }
14791
- canonical.set(root, id);
14792
- normalized[id] = registeredFleetSchema.parse({ ...registration, root });
14793
- }
14794
- return normalized;
14795
- }
14796
- async function listRegisteredFleets(options = {}) {
14797
- const globalRoot = resolve29(options.globalRoot ?? homedir13());
14798
- const home = await readWorkspaceConfig(globalRoot);
14799
- if (!supportsFleetConfig(home)) return [];
14800
- return Object.entries(home.fleets).sort(([a], [b]) => a.localeCompare(b)).map(([id, registration]) => ({ id, ...registration }));
14801
- }
14802
- async function showRegisteredFleet(idInput, options = {}) {
14803
- const id = fleetIdSchema.parse(idInput);
14804
- const fleets = await listRegisteredFleets(options);
14805
- const registration = fleets.find((candidate) => candidate.id === id);
14806
- if (!registration) {
14807
- throw new Error(`Unknown fleet '${id}'. Use 'agentwheel fleet list' or register it with 'agentwheel fleet register'.`);
14808
- }
14809
- return registration;
14810
- }
14811
- async function resolveWorkspaceOwnershipScope(workspaceRootInput, options = {}) {
14812
- const workspaceRoot = await canonicalizeDirectory(resolve29(workspaceRootInput), "Workspace ownership root");
14813
- if (options.fleetId) {
14814
- return { root: workspaceRoot, fleetId: fleetIdSchema.parse(options.fleetId) };
14815
- }
14816
- const syntacticallyContaining = (await listRegisteredFleets({ globalRoot: options.globalRoot })).filter((fleet2) => containsPath(resolve29(fleet2.root), workspaceRoot));
14817
- const registered = await Promise.all(syntacticallyContaining.map(async (fleet2) => ({
14818
- ...fleet2,
14819
- root: await canonicalizeDirectory(fleet2.root, `Registered fleet '${fleet2.id}' root`)
14820
- })));
14821
- const containing = registered.filter((fleet2) => containsPath(fleet2.root, workspaceRoot));
14822
- if (containing.length > 1) {
14823
- throw new Error(
14824
- `Workspace ${workspaceRoot} is contained by multiple registered fleets: ` + containing.map((fleet2) => `'${fleet2.id}' at ${fleet2.root}`).join(", ") + ". Resolve the overlapping registrations before planning ownership."
14825
- );
14826
- }
14827
- const fleet = containing[0];
14828
- if (fleet) assertFleetContract(fleet.id, fleet, await readRequiredConfig(fleet.root, `fleet '${fleet.id}'`));
14829
- return fleet ? { root: fleet.root, fleetId: fleet.id } : { root: workspaceRoot };
14830
- }
14831
- async function readRequiredConfig(root, label) {
14832
- const path = workspaceConfigPath(root);
14833
- if (!await pathExists(path)) throw missingScopeError(label);
14834
- try {
14835
- return workspaceConfigSchema.parse(JSON.parse(await readFile37(path, "utf8")));
14836
- } catch (error) {
14837
- throw new Error(`Invalid ${label} Agentwheel config at ${path}: ${error instanceof Error ? error.message : String(error)}`);
14838
- }
14839
- }
14840
- function assertFleetContract(id, registration, config) {
14841
- if (!supportsFleetConfig(config)) {
14842
- throw new Error(`Fleet '${id}' config must use schemaVersion 3 or newer before registration or selection.`);
14843
- }
14844
- if (config.fleetId !== id) {
14845
- throw new Error(`Fleet fleetId mismatch: expected '${id}', found '${config.fleetId ?? "missing"}'.`);
14846
- }
14847
- if (Object.keys(config.fleets).length > 0) {
14848
- throw new Error(`Fleet '${id}' config may not contain the home fleets registry.`);
14849
- }
14850
- const names = new Set(config.packages.map((pkg) => pkg.name));
14851
- for (const packageName of registration.requiredPackages) {
14852
- if (!names.has(packageName)) throw new Error(`Fleet '${id}' is missing required package '${packageName}'.`);
14853
- }
14854
- }
14855
- async function assertCanonicalDirectory(input, label) {
14856
- const canonical = await canonicalizeDirectory(input, label);
14857
- const normalized = resolve29(input);
14858
- const stats = await lstat4(input);
14859
- if (stats.isSymbolicLink() || canonical !== normalized || input !== normalized) {
14860
- throw new Error(`${label} must be canonical and symlink-unambiguous: ${input} resolves to ${canonical}.`);
14861
- }
14862
- return canonical;
14863
- }
14864
- async function canonicalizeDirectory(input, label) {
14865
- if (!isAbsolute10(input)) throw new Error(`${label} must be an absolute canonical path.`);
14866
- let canonical;
14867
- try {
14868
- canonical = await realpath2(input);
14869
- } catch {
14870
- throw new Error(`${label} does not exist: ${input}`);
14871
- }
14872
- const stats = await lstat4(canonical);
14873
- if (!stats.isDirectory()) throw new Error(`${label} is not a directory: ${input}`);
14874
- return canonical;
14875
- }
14876
- function missingScopeError(label) {
14877
- return new Error(
14878
- `Missing ${label} Agentwheel workspace config. Select --user, --local, or --fleet <id>, or run 'agentwheel init workspace' in the intended local root. Agentwheel never falls back to home desired state.`
14879
- );
14880
- }
14881
- function assertNonFleetScope(kind, config) {
14882
- if (supportsFleetConfig(config) && config.fleetId) {
14883
- throw new Error(
14884
- `The ${kind} config declares fleetId '${config.fleetId}'. Select it through the registered --fleet <id> scope.`
14885
- );
14886
- }
14887
- }
14888
- function sortedUnique6(values) {
14889
- return [...new Set(values.map((value) => value.trim()).filter(Boolean))].sort((a, b) => a.localeCompare(b));
14890
- }
14891
- function containsPath(parent, candidate) {
14892
- const path = relative15(parent, candidate);
14893
- return path === "" || !path.startsWith("..") && !isAbsolute10(path);
14894
- }
14908
+ // src/lifecycle/source-plan.ts
14909
+ init_fleet();
14895
14910
 
14896
14911
  // src/model/target-state.ts
14897
14912
  init_graph_lock();
@@ -15265,7 +15280,7 @@ async function discoverTargetApplyJournal(options) {
15265
15280
  continue;
15266
15281
  }
15267
15282
  if (!journal.graphLockPath || !journal.graphLock || !journal.graphLockDigest) continue;
15268
- if (resolve31(dirname31(journal.graphLockPath)) !== resolve31(dirname31(options.graphLockPath))) continue;
15283
+ if (resolve31(dirname32(journal.graphLockPath)) !== resolve31(dirname32(options.graphLockPath))) continue;
15269
15284
  if (options.transport.kind === "ssh") {
15270
15285
  throw new Error(
15271
15286
  `Legacy SSH apply journal at ${item.path} does not record its original endpoint; Agentwheel cannot prove endpoint identity, so the journal was preserved.`
@@ -15407,7 +15422,7 @@ async function resolvePriorTargetState(options) {
15407
15422
  return {};
15408
15423
  }
15409
15424
  async function discoverLegacyStateCandidates(options) {
15410
- const directory = dirname31(options.graphLockPath);
15425
+ const directory = dirname32(options.graphLockPath);
15411
15426
  let names;
15412
15427
  try {
15413
15428
  names = await readdir14(directory);
@@ -15695,7 +15710,7 @@ function mcpServerNames(strategy, removal) {
15695
15710
  return new Set(Object.keys(servers));
15696
15711
  }
15697
15712
  function globalConfigRoot(globalRoot) {
15698
- return dirname31(dirname31(globalWorkspaceConfigPath(globalRoot)));
15713
+ return dirname32(dirname32(globalWorkspaceConfigPath(globalRoot)));
15699
15714
  }
15700
15715
  function ownedByWorkspace(owner, desiredOwner, workspaceRoot, ownsSubWorkspaces) {
15701
15716
  if (owner === desiredOwner) return true;
@@ -15841,7 +15856,7 @@ function targetLabel(target) {
15841
15856
 
15842
15857
  // src/runtime/target.ts
15843
15858
  init_workspace();
15844
- import { basename as basename22, dirname as dirname32, join as join47, resolve as resolve33 } from "path";
15859
+ import { basename as basename22, dirname as dirname33, join as join47, resolve as resolve33 } from "path";
15845
15860
 
15846
15861
  // src/transport/run-as-identity.ts
15847
15862
  import { execFileSync } from "child_process";
@@ -16013,7 +16028,7 @@ async function detectRuntimeTargets(cwd = process.cwd(), adapterFilter) {
16013
16028
  if (adapterFilter && marker.adapter !== adapterFilter) continue;
16014
16029
  for (const dir of marker.dirs) {
16015
16030
  if (basename22(root) === dir) {
16016
- matches.push({ adapter: marker.adapter, targetRoot: dirname32(root) });
16031
+ matches.push({ adapter: marker.adapter, targetRoot: dirname33(root) });
16017
16032
  } else if (await pathExists(join47(root, dir))) {
16018
16033
  matches.push({ adapter: marker.adapter, targetRoot: root });
16019
16034
  }
@@ -16060,7 +16075,7 @@ function dedupeTargets(matches) {
16060
16075
  function runtimeScanRoot(request) {
16061
16076
  const root = resolve33(request.targetRoot ?? request.cwd ?? process.cwd());
16062
16077
  if (request.targetRoot) return root;
16063
- return runtimeMarkers.some((marker) => marker.dirs.includes(basename22(root))) ? dirname32(root) : root;
16078
+ return runtimeMarkers.some((marker) => marker.dirs.includes(basename22(root))) ? dirname33(root) : root;
16064
16079
  }
16065
16080
 
16066
16081
  // src/lifecycle/profile.ts
@@ -16394,7 +16409,7 @@ init_selection();
16394
16409
  // src/cli/update-check.ts
16395
16410
  import { mkdir as mkdir26, readFile as readFile38, writeFile as writeFile22 } from "fs/promises";
16396
16411
  import { homedir as homedir14 } from "os";
16397
- import { dirname as dirname33, join as join48 } from "path";
16412
+ import { dirname as dirname34, join as join48 } from "path";
16398
16413
  var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
16399
16414
  var DEFAULT_TIMEOUT_MS = 300;
16400
16415
  var REGISTRY_URL = "https://registry.npmjs.org/agentwheel";
@@ -16447,7 +16462,7 @@ async function readCache(path) {
16447
16462
  }
16448
16463
  }
16449
16464
  async function writeCache(path, cache) {
16450
- await mkdir26(dirname33(path), { recursive: true });
16465
+ await mkdir26(dirname34(path), { recursive: true });
16451
16466
  await writeFile22(path, `${JSON.stringify(cache, null, 2)}
16452
16467
  `, "utf8");
16453
16468
  }
@@ -16683,11 +16698,11 @@ init_graph_lock();
16683
16698
 
16684
16699
  // src/cli/version.ts
16685
16700
  import { readFileSync as readFileSync2 } from "fs";
16686
- import { dirname as dirname34, join as join51 } from "path";
16701
+ import { dirname as dirname35, join as join51 } from "path";
16687
16702
  import { fileURLToPath as fileURLToPath3 } from "url";
16688
16703
  var FALLBACK_VERSION = "0.0.0";
16689
16704
  function resolveCliVersion() {
16690
- let dir = dirname34(fileURLToPath3(import.meta.url));
16705
+ let dir = dirname35(fileURLToPath3(import.meta.url));
16691
16706
  while (true) {
16692
16707
  try {
16693
16708
  const pkg = JSON.parse(readFileSync2(join51(dir, "package.json"), "utf8"));
@@ -16696,13 +16711,146 @@ function resolveCliVersion() {
16696
16711
  }
16697
16712
  } catch {
16698
16713
  }
16699
- const parent = dirname34(dir);
16714
+ const parent = dirname35(dir);
16700
16715
  if (parent === dir) return FALLBACK_VERSION;
16701
16716
  dir = parent;
16702
16717
  }
16703
16718
  }
16704
16719
 
16720
+ // src/lifecycle/ownership-handoff-audit.ts
16721
+ init_apply();
16722
+ init_manifest2();
16723
+ init_paths();
16724
+ init_transaction();
16725
+ init_coordinator();
16726
+ init_declarations();
16727
+ init_protocol();
16728
+ init_process();
16729
+ init_repository();
16730
+ init_transport();
16731
+ import { createHash as createHash20, randomUUID as randomUUID6 } from "crypto";
16732
+ import { join as join52, resolve as resolve36 } from "path";
16733
+ async function applyAuditedOwnershipHandoff(request, observe4) {
16734
+ const existing = activeMutationMetadata();
16735
+ const workspaceRoot = resolve36(request.workspaceRoot ?? existing.workspaceRoot);
16736
+ if (existing && (resolve36(existing.workspaceRoot) !== workspaceRoot || request.reason !== void 0 && existing.reason !== request.reason.replace(/\r\n?/gu, "\n").trim() || request.operationId && request.operationId !== existing.operationId)) {
16737
+ throw new Error("Ownership handoff does not match the active governed workspace, reason or operation.");
16738
+ }
16739
+ const operationId = mutationOperationIdSchema.parse(existing?.operationId ?? request.operationId ?? randomUUID6());
16740
+ const auditPath = join52(workspaceRoot, ".agentwheel", "ownership-handoffs", `${operationId}.json`);
16741
+ const mutation = existing ? void 0 : await GovernedMutation.begin({
16742
+ workspaceRoot,
16743
+ commandName: "agentwheel ownership handoff",
16744
+ reason: request.reason,
16745
+ operationId,
16746
+ noCommit: request.noCommit,
16747
+ globalRoot: request.globalRoot,
16748
+ anticipatedPaths: [auditPath]
16749
+ });
16750
+ try {
16751
+ const transport = request.transport ?? localTransport;
16752
+ assertGovernedRuntimeTransportSupported(transport);
16753
+ if (transport.kind !== "local") throw new Error("Audited ownership handoff supports local targets only.");
16754
+ await assertNoSymlinkPath(workspaceRoot);
16755
+ await assertNoSymlinkPath(auditPath);
16756
+ if ((existing ?? mutation?.metadata())?.revisionMode === "commit-after-verify") {
16757
+ const repository = await discoverGitRepository(workspaceRoot);
16758
+ if (!repository) throw new Error("Ownership handoff requires a declarative Git audit path.");
16759
+ const ignored = await runProcess("git", ["-C", repository.root, "check-ignore", "--no-index", "--", auditPath], { allowExitCodes: [0, 1] });
16760
+ if (ignored.exitCode === 0) throw new Error("Ownership handoff audit path is Git-ignored; declare it before handing off ownership.");
16761
+ }
16762
+ const scope = { installationType: request.installationType, stateKey: request.stateKey };
16763
+ await assertNoSymlinkPath(join52(request.targetRoot, ".agentwheel"));
16764
+ const lock = await acquireApplyLock(request.targetRoot, request.adapter, transport, {}, scope);
16765
+ try {
16766
+ if ((await listAllApplyJournals(request.targetRoot, void 0, transport)).length) {
16767
+ throw new Error("Cannot hand off ownership while an apply journal is pending. Recover the same operation first.");
16768
+ }
16769
+ if (await transport.pathExists(auditPath)) throw new Error("Ownership handoff intent already exists; recover the same operation instead of applying again.");
16770
+ const plan = await observe4(request, transport);
16771
+ if (plan.drifted && !request.expectedRuntimeHash) {
16772
+ throw new Error("Applying a drifted ownership handoff requires expectedRuntimeHash from a reviewed dry-run.");
16773
+ }
16774
+ const manifest = await readInstallManifest(request.targetRoot, request.adapter, transport, scope);
16775
+ if (!manifest || manifest.version !== 2 || manifest.revision !== plan.manifestRevision) {
16776
+ throw new Error("Ownership handoff manifest changed while locked; replan required.");
16777
+ }
16778
+ const inventory = await listInstallManifests(request.targetRoot, void 0, transport);
16779
+ for (const item of inventory) await assertNoSymlinkPath(item.path);
16780
+ const runtimePath = metadataRuntimePath(request.targetRoot, plan.path);
16781
+ const runtime = [{ path: plan.path, hash: await transport.hashPath(runtimePath), snapshotDigest: await ownershipRuntimeSnapshot(runtimePath) }];
16782
+ const reason = existing?.reason ?? mutation?.metadata().reason ?? request.reason ?? "Ownership handoff";
16783
+ const intent = {
16784
+ schemaVersion: 1,
16785
+ event: "ownership-handoff-intent",
16786
+ operationId,
16787
+ reason,
16788
+ // Explicit whitelist: never serialize manifest entries, mergeRemoval or runtime/config values.
16789
+ plan: {
16790
+ adapter: plan.adapter,
16791
+ installationType: manifest.installationType,
16792
+ stateKey: manifest.stateKey,
16793
+ targetRoot: plan.targetRoot,
16794
+ selector: plan.selector,
16795
+ path: plan.path,
16796
+ artifactHash: plan.artifactHash,
16797
+ runtimeHash: plan.runtimeHash,
16798
+ drifted: plan.drifted,
16799
+ manifestRevision: plan.manifestRevision,
16800
+ fromOwner: plan.fromOwner,
16801
+ toOwner: plan.toOwner
16802
+ },
16803
+ completion: "Verify the linked runtime journal and mutation receipt; intent alone is not completion."
16804
+ };
16805
+ const content = `${JSON.stringify(intent, null, 2)}
16806
+ `;
16807
+ const sha2568 = createHash20("sha256").update(content).digest("hex");
16808
+ declareMutationPath(auditPath);
16809
+ declareMutationPath(installManifestPath(request.targetRoot, request.adapter, scope));
16810
+ const metadata = mutationMetadataForApplyJournal();
16811
+ const now = (/* @__PURE__ */ new Date()).toISOString();
16812
+ const journal = {
16813
+ version: metadata ? 2 : 1,
16814
+ ...metadata ? { mutation: metadata } : {},
16815
+ mode: "uninstall",
16816
+ adapter: manifest.adapter,
16817
+ installationType: manifest.installationType,
16818
+ stateKey: manifest.stateKey,
16819
+ targetRoot: manifest.targetRoot,
16820
+ baseRevision: manifest.revision,
16821
+ createdAt: now,
16822
+ updatedAt: now,
16823
+ operations: [],
16824
+ completed: [],
16825
+ manifest: { ...manifest, entries: manifest.entries.map((entry) => entry.artifactType === request.artifactType && entry.artifactName === request.artifactName ? { ...entry, workspaceOwner: plan.toOwner } : entry) },
16826
+ metadataAudit: {
16827
+ kind: "ownership-handoff",
16828
+ workspaceRoot,
16829
+ operationId,
16830
+ planDigest: sha2568,
16831
+ inventory: inventory.map((item) => ({ stateKey: item.stateKey, revision: item.manifest.revision })),
16832
+ runtime,
16833
+ auditFiles: [{ path: `.agentwheel/ownership-handoffs/${operationId}.json`, content, sha256: sha2568 }]
16834
+ }
16835
+ };
16836
+ if (JSON.stringify(await observe4(request, transport)) !== JSON.stringify(plan)) {
16837
+ throw new Error("Ownership handoff preconditions changed before journaling; replan required.");
16838
+ }
16839
+ await writeApplyJournal(journal, transport);
16840
+ await commitManifestMetadataJournal(journal, transport);
16841
+ await mutation?.complete();
16842
+ return plan;
16843
+ } finally {
16844
+ await lock.release();
16845
+ }
16846
+ } catch (error) {
16847
+ await mutation?.fail(error);
16848
+ throw error;
16849
+ }
16850
+ }
16851
+
16705
16852
  // src/lifecycle/ownership.ts
16853
+ init_coordinator();
16706
16854
  init_manifest2();
16707
16855
  init_paths();
16708
16856
  init_merge_removal();
@@ -16710,7 +16858,7 @@ init_instructions_block();
16710
16858
  init_adapter();
16711
16859
  init_transaction();
16712
16860
  init_transport();
16713
- import { resolve as resolve36 } from "path";
16861
+ import { resolve as resolve37 } from "path";
16714
16862
  var unknownWorkspaceOwner = "workspace:unknown";
16715
16863
  async function planArtifactOwnershipHandoff(request) {
16716
16864
  return validateOwnershipHandoff(request, request.transport ?? localTransport);
@@ -16719,6 +16867,9 @@ async function applyArtifactOwnershipHandoff(request) {
16719
16867
  if (!request.expectedHash || !request.expectedRevision) {
16720
16868
  throw new Error("Applying an ownership handoff requires expectedHash and expectedRevision from a reviewed dry-run.");
16721
16869
  }
16870
+ if (request.workspaceRoot || activeMutationMetadata()) {
16871
+ return applyAuditedOwnershipHandoff(request, validateOwnershipHandoff);
16872
+ }
16722
16873
  const transport = request.transport ?? localTransport;
16723
16874
  assertGovernedRuntimeTransportSupported(transport);
16724
16875
  const scope = { installationType: request.installationType, stateKey: request.stateKey };
@@ -16854,8 +17005,8 @@ function containedArtifactPath(targetRoot, relativePath) {
16854
17005
  if (!relativePath || relativePath.startsWith("/") || relativePath.includes("\0")) {
16855
17006
  throw new Error(`Unsafe managed artifact path: ${relativePath}`);
16856
17007
  }
16857
- const root = resolve36(targetRoot);
16858
- const candidate = resolve36(root, relativePath);
17008
+ const root = resolve37(targetRoot);
17009
+ const candidate = resolve37(root, relativePath);
16859
17010
  if (candidate !== root && !candidate.startsWith(`${root}/`)) {
16860
17011
  throw new Error(`Managed artifact path escapes target root: ${relativePath}`);
16861
17012
  }
@@ -16892,8 +17043,8 @@ init_apply();
16892
17043
  init_paths();
16893
17044
  init_transaction();
16894
17045
  init_selection();
16895
- import { createHash as createHash20 } from "crypto";
16896
- import { resolve as resolve37 } from "path";
17046
+ import { createHash as createHash21 } from "crypto";
17047
+ import { resolve as resolve38 } from "path";
16897
17048
  init_declarations();
16898
17049
  init_transport();
16899
17050
  init_instructions_block();
@@ -17030,14 +17181,14 @@ async function observe(request, transport) {
17030
17181
  return { ...withoutDigest, planDigest: digest(withoutDigest) };
17031
17182
  }
17032
17183
  function normalizeRequest(request) {
17033
- const targetRoot = resolve37(request.targetRoot);
17184
+ const targetRoot = resolve38(request.targetRoot);
17034
17185
  const sourceStateKey = exactStateKey(request.adapter, request.sourceStateKey, request.installationType, "source");
17035
17186
  const destinationStateKey = exactStateKey(request.adapter, request.destinationStateKey, request.installationType, "destination");
17036
17187
  if (sourceStateKey === destinationStateKey) throw new Error("Source and destination state keys must differ.");
17037
17188
  if (!request.toFleetId.trim()) throw new Error("Destination Fleet id is required.");
17038
17189
  const fromFleetId = request.fromFleetId?.trim();
17039
17190
  if (request.fromFleetId !== void 0 && !fromFleetId) throw new Error("Source Fleet id cannot be empty.");
17040
- if (fromFleetId && (fromFleetId !== request.toFleetId.trim() || resolve37(request.fromWorkspaceRoot) !== resolve37(request.toWorkspaceRoot))) {
17191
+ if (fromFleetId && (fromFleetId !== request.toFleetId.trim() || resolve38(request.fromWorkspaceRoot) !== resolve38(request.toWorkspaceRoot))) {
17041
17192
  throw new Error("Fleet-qualified stale ownership retirement requires the same source and destination Fleet and workspace root.");
17042
17193
  }
17043
17194
  return {
@@ -17046,9 +17197,9 @@ function normalizeRequest(request) {
17046
17197
  installationType: request.installationType.trim(),
17047
17198
  sourceStateKey,
17048
17199
  destinationStateKey,
17049
- fromWorkspaceRoot: resolve37(request.fromWorkspaceRoot),
17200
+ fromWorkspaceRoot: resolve38(request.fromWorkspaceRoot),
17050
17201
  ...fromFleetId ? { fromFleetId } : {},
17051
- toWorkspaceRoot: resolve37(request.toWorkspaceRoot),
17202
+ toWorkspaceRoot: resolve38(request.toWorkspaceRoot),
17052
17203
  toFleetId: request.toFleetId.trim()
17053
17204
  };
17054
17205
  }
@@ -17069,7 +17220,7 @@ async function requireManifest(request, stateKey, transport, label) {
17069
17220
  installationType: manifest.installationType,
17070
17221
  stateKey: manifest.stateKey
17071
17222
  });
17072
- if (manifest.adapter !== request.adapter || manifest.installationType !== request.installationType || resolve37(manifest.targetRoot) !== request.targetRoot || actualStateKey !== stateKey) {
17223
+ if (manifest.adapter !== request.adapter || manifest.installationType !== request.installationType || resolve38(manifest.targetRoot) !== request.targetRoot || actualStateKey !== stateKey) {
17073
17224
  throw new Error(`${label} install manifest identity does not match the requested adapter, target, installation type, and state key.`);
17074
17225
  }
17075
17226
  return manifest;
@@ -17162,7 +17313,7 @@ function entryDigest(entry) {
17162
17313
  return digest(entry);
17163
17314
  }
17164
17315
  function digest(value) {
17165
- return createHash20("sha256").update(canonicalJson6(value)).digest("hex");
17316
+ return createHash21("sha256").update(canonicalJson6(value)).digest("hex");
17166
17317
  }
17167
17318
  function canonicalJson6(value) {
17168
17319
  if (Array.isArray(value)) return `[${value.map(canonicalJson6).join(",")}]`;
@@ -17176,9 +17327,9 @@ init_apply();
17176
17327
  init_manifest2();
17177
17328
  init_paths();
17178
17329
  init_transaction();
17179
- import { createHash as createHash21, randomUUID as randomUUID6 } from "crypto";
17330
+ import { createHash as createHash22, randomUUID as randomUUID7 } from "crypto";
17180
17331
  import { lstat as lstat5 } from "fs/promises";
17181
- import { join as join52, resolve as resolve38 } from "path";
17332
+ import { join as join53, resolve as resolve39 } from "path";
17182
17333
  init_coordinator();
17183
17334
  init_declarations();
17184
17335
  init_protocol();
@@ -17196,13 +17347,13 @@ async function applyReleaseOwnership(request) {
17196
17347
  })) {
17197
17348
  if (!value || !/^[a-f0-9]{64}$/.test(value)) throw new Error(`Reviewed SHA-256 ${name} is required to release a claim.`);
17198
17349
  }
17199
- const workspaceRoot = resolve38(request.workspaceRoot);
17350
+ const workspaceRoot = resolve39(request.workspaceRoot);
17200
17351
  const existing = activeMutationMetadata();
17201
- if (existing && (resolve38(existing.workspaceRoot) !== workspaceRoot || existing.reason !== request.reason.replace(/\r\n?/gu, "\n").trim() || request.operationId && request.operationId !== existing.operationId)) {
17352
+ if (existing && (resolve39(existing.workspaceRoot) !== workspaceRoot || existing.reason !== request.reason.replace(/\r\n?/gu, "\n").trim() || request.operationId && request.operationId !== existing.operationId)) {
17202
17353
  throw new Error("Ownership release does not match the active governed workspace, reason or operation.");
17203
17354
  }
17204
- const operationId = mutationOperationIdSchema.parse(existing?.operationId ?? request.operationId ?? randomUUID6());
17205
- const auditPath = join52(workspaceRoot, ".agentwheel", "ownership-releases", `${operationId}.json`);
17355
+ const operationId = mutationOperationIdSchema.parse(existing?.operationId ?? request.operationId ?? randomUUID7());
17356
+ const auditPath = join53(workspaceRoot, ".agentwheel", "ownership-releases", `${operationId}.json`);
17206
17357
  const mutation = existing ? void 0 : await GovernedMutation.begin({
17207
17358
  workspaceRoot,
17208
17359
  commandName: "agentwheel ownership release-claim",
@@ -17232,9 +17383,9 @@ async function applyReleaseOwnership(request) {
17232
17383
  async function applyLocked(request, operationId, auditPath) {
17233
17384
  const transport = request.transport ?? localTransport;
17234
17385
  if (transport.kind !== "local") throw new Error("Ownership release supports local targets only.");
17235
- await assertNoSymlinkPath(join52(resolve38(request.targetRoot), ".agentwheel"));
17386
+ await assertNoSymlinkPath(join53(resolve39(request.targetRoot), ".agentwheel"));
17236
17387
  await assertNoSymlinkPath(auditPath);
17237
- const lock = await acquireApplyLock(resolve38(request.targetRoot), request.adapter, transport, {}, {
17388
+ const lock = await acquireApplyLock(resolve39(request.targetRoot), request.adapter, transport, {}, {
17238
17389
  installationType: request.installationType,
17239
17390
  stateKey: request.stateKey
17240
17391
  });
@@ -17303,15 +17454,15 @@ async function applyLocked(request, operationId, auditPath) {
17303
17454
  async function observe2(request) {
17304
17455
  const transport = request.transport ?? localTransport;
17305
17456
  if (transport.kind !== "local") throw new Error("Ownership release supports local targets only.");
17306
- const targetRoot = resolve38(request.targetRoot);
17307
- const workspaceRoot = resolve38(request.workspaceRoot);
17457
+ const targetRoot = resolve39(request.targetRoot);
17458
+ const workspaceRoot = resolve39(request.workspaceRoot);
17308
17459
  const reason = mutationReasonSchema.parse(request.reason.trim());
17309
17460
  if (!request.stateKey || stateKeyFor(request.adapter, { stateKey: request.stateKey }) !== request.stateKey || !request.installationType.trim() || !request.selector.includes("/")) {
17310
17461
  throw new Error("Ownership release requires an exact state key, installation type and type/name selector.");
17311
17462
  }
17312
17463
  const runtimePath = metadataRuntimePath(targetRoot, request.path);
17313
17464
  await assertNoSymlinkPath(workspaceRoot);
17314
- await assertNoSymlinkPath(join52(targetRoot, ".agentwheel"));
17465
+ await assertNoSymlinkPath(join53(targetRoot, ".agentwheel"));
17315
17466
  const manifests = await listInstallManifests(targetRoot, void 0, transport);
17316
17467
  for (const item of manifests) await assertNoSymlinkPath(item.path);
17317
17468
  const source = manifests.find((item) => item.stateKey === request.stateKey);
@@ -17366,7 +17517,7 @@ async function observe2(request) {
17366
17517
  return { ...plan, planDigest: digest2(plan) };
17367
17518
  }
17368
17519
  function hash(content) {
17369
- return createHash21("sha256").update(content).digest("hex");
17520
+ return createHash22("sha256").update(content).digest("hex");
17370
17521
  }
17371
17522
  function digest2(value) {
17372
17523
  return hash(canonicalJson7(value));
@@ -17384,10 +17535,11 @@ init_manifest2();
17384
17535
  init_paths();
17385
17536
  init_transaction();
17386
17537
  init_instructions_block();
17387
- import { createHash as createHash23 } from "crypto";
17388
- import { realpath as realpath3 } from "fs/promises";
17389
- import { isAbsolute as isAbsolute12, join as join54, relative as relative17, resolve as resolve40 } from "path";
17538
+ init_fleet();
17390
17539
  init_manifest();
17540
+ import { createHash as createHash24 } from "crypto";
17541
+ import { realpath as realpath3 } from "fs/promises";
17542
+ import { isAbsolute as isAbsolute12, join as join55, relative as relative17, resolve as resolve41 } from "path";
17391
17543
  init_declarations();
17392
17544
  init_transport();
17393
17545
  init_fs();
@@ -17399,18 +17551,18 @@ init_instructions_block();
17399
17551
  init_merge_removal();
17400
17552
  init_graph_lock();
17401
17553
  init_manifest();
17402
- import { createHash as createHash22 } from "crypto";
17554
+ import { createHash as createHash23 } from "crypto";
17403
17555
  import { lstat as lstat6, readdir as readdir15 } from "fs/promises";
17404
- import { basename as basename23, dirname as dirname35, join as join53, posix as posix7, relative as relative16, resolve as resolve39 } from "path";
17556
+ import { basename as basename23, dirname as dirname36, join as join54, posix as posix7, relative as relative16, resolve as resolve40 } from "path";
17405
17557
  async function inventoryHistoricalLocks(fleetRoot) {
17406
- const root = join53(fleetRoot, ".agentwheel", "locks");
17558
+ const root = join54(fleetRoot, ".agentwheel", "locks");
17407
17559
  const found = [];
17408
17560
  async function visit(dir) {
17409
17561
  for (const entry of await readdir15(dir, { withFileTypes: true }).catch((error) => {
17410
17562
  if (error.code === "ENOENT") return [];
17411
17563
  throw error;
17412
17564
  })) {
17413
- const path = join53(dir, entry.name);
17565
+ const path = join54(dir, entry.name);
17414
17566
  if (entry.isDirectory()) await visit(path);
17415
17567
  else if (entry.isFile() && entry.name.endsWith(".graph-lock.json")) found.push(await historicalLock(path));
17416
17568
  }
@@ -17419,14 +17571,14 @@ async function inventoryHistoricalLocks(fleetRoot) {
17419
17571
  return found.sort((a, b) => a.path.localeCompare(b.path));
17420
17572
  }
17421
17573
  async function findLegacyNamedLocks(workspaceRoot, adapter, fingerprint) {
17422
- const root = join53(workspaceRoot, ".agentwheel", "locks");
17574
+ const root = join54(workspaceRoot, ".agentwheel", "locks");
17423
17575
  const found = [];
17424
17576
  for (const target of await readdir15(root, { withFileTypes: true }).catch((error) => {
17425
17577
  if (error.code === "ENOENT") return [];
17426
17578
  throw error;
17427
17579
  })) {
17428
17580
  if (!target.isDirectory()) continue;
17429
- const path = join53(root, target.name, adapter, `${fingerprint}.graph-lock.json`);
17581
+ const path = join54(root, target.name, adapter, `${fingerprint}.graph-lock.json`);
17430
17582
  const stats = await lstat6(path).catch((error) => {
17431
17583
  if (error.code === "ENOENT") return void 0;
17432
17584
  throw error;
@@ -17448,7 +17600,7 @@ async function planLegacyRecovery(input) {
17448
17600
  const { graphPlan, installRoot, targetKey: targetKey2, adapter, installationType, historicalLocks, transport } = input;
17449
17601
  assertCompleteGraphPlan(graphPlan);
17450
17602
  const binding = {
17451
- targetLockDir: dirname35(graphPlan.graphLockPath),
17603
+ targetLockDir: dirname36(graphPlan.graphLockPath),
17452
17604
  stableLockPath: graphPlan.graphLockPath,
17453
17605
  stableStateKey: graphPlan.plan.stateKey,
17454
17606
  currentFingerprint: graphPlan.targetFingerprint,
@@ -17487,7 +17639,7 @@ async function planLegacyRecovery(input) {
17487
17639
  const currentNodeIds = [...new Set(current.map((item) => item.graphNodeId).filter((value) => Boolean(value)))].sort();
17488
17640
  const currentSelectors = [...new Set(current.map((item) => item.logicalSelector).filter((value) => Boolean(value)))].sort();
17489
17641
  const currentOwners = [...new Set(current.flatMap((item) => item.owners ?? []))].sort();
17490
- const livePath = resolve39(installRoot, path);
17642
+ const livePath = resolve40(installRoot, path);
17491
17643
  if (relative16(installRoot, livePath).startsWith("..")) throw new Error(`Manifest path escapes target: ${path}`);
17492
17644
  const liveHash = await transport.pathExists(livePath) ? await transport.hashPath(livePath) : null;
17493
17645
  const reasons = [];
@@ -17559,8 +17711,8 @@ function claimFor(item, entry, locks, binding) {
17559
17711
  const matches = locks.filter((candidate) => candidate.digest === digest3);
17560
17712
  const evidence = [];
17561
17713
  const owner = "workspaceOwner" in entry ? entry.workspaceOwner : legacyUnownedWorkspaceOwner;
17562
- const sameRoot = binding.transportKind === "ssh" ? posix7.normalize(item.manifest.targetRoot) === posix7.normalize(binding.installRoot) : resolve39(item.manifest.targetRoot) === resolve39(binding.installRoot);
17563
- const inTargetDir = matches.filter((candidate) => resolve39(dirname35(candidate.path)) === resolve39(binding.targetLockDir));
17714
+ const sameRoot = binding.transportKind === "ssh" ? posix7.normalize(item.manifest.targetRoot) === posix7.normalize(binding.installRoot) : resolve40(item.manifest.targetRoot) === resolve40(binding.installRoot);
17715
+ const inTargetDir = matches.filter((candidate) => resolve40(dirname36(candidate.path)) === resolve40(binding.targetLockDir));
17564
17716
  const boundLocks = inTargetDir.filter((candidate) => lockBindsState(candidate, item, binding));
17565
17717
  if (owner !== binding.expectedOwner) evidence.push("workspace owner differs from selected Fleet target");
17566
17718
  if (item.manifest.version !== 2 || item.manifest.installationType !== binding.installationType) evidence.push("installation type differs or manifest is legacy v1");
@@ -17602,7 +17754,7 @@ function lockBindsState(candidate, manifest, binding) {
17602
17754
  if (!name.endsWith(".graph-lock.json")) return false;
17603
17755
  const fingerprint = name.slice(0, -".graph-lock.json".length);
17604
17756
  if (!/^[a-f0-9]{64}$/u.test(fingerprint)) return false;
17605
- const stable = resolve39(candidate.path) === resolve39(binding.stableLockPath);
17757
+ const stable = resolve40(candidate.path) === resolve40(binding.stableLockPath);
17606
17758
  if (stable) {
17607
17759
  return manifest.stateKey === binding.stableStateKey && candidate.lock.canonical.targetFingerprint === binding.currentFingerprint;
17608
17760
  }
@@ -17670,7 +17822,7 @@ function assertCompleteGraphPlan(plan) {
17670
17822
  }
17671
17823
  }
17672
17824
  function sha2566(value) {
17673
- return createHash22("sha256").update(value).digest("hex");
17825
+ return createHash23("sha256").update(value).digest("hex");
17674
17826
  }
17675
17827
 
17676
17828
  // src/lifecycle/ownership-adopt-legacy.ts
@@ -17692,12 +17844,12 @@ async function planAdoptLegacyOwnership(request) {
17692
17844
  async function applyAdoptLegacyOwnership(request) {
17693
17845
  assertApplyPreconditions2(request);
17694
17846
  const transport = request.transport ?? localTransport;
17695
- const targetRoot = resolve40(request.targetRoot);
17847
+ const targetRoot = resolve41(request.targetRoot);
17696
17848
  const installationType = request.installationType.trim();
17697
17849
  if (transport.kind !== "local") throw new Error("Legacy ownership adoption requires a local filesystem transport.");
17698
17850
  const beforeLock = await readInstallManifest(targetRoot, request.adapter, transport, { installationType, stateKey: request.sourceStateKey });
17699
17851
  if (beforeLock?.entries.some((entry) => entry.mode === "managed-block")) {
17700
- await assertNoSymlinkPath(join54(targetRoot, ".agentwheel"));
17852
+ await assertNoSymlinkPath(join55(targetRoot, ".agentwheel"));
17701
17853
  }
17702
17854
  const lock = await acquireApplyLock(targetRoot, request.adapter, transport, {}, {
17703
17855
  installationType,
@@ -17936,13 +18088,13 @@ async function observe3(request, transport) {
17936
18088
  }))
17937
18089
  } } : {}
17938
18090
  };
17939
- return { ...withoutDigest, planDigest: createHash23("sha256").update(canonicalJson6(withoutDigest)).digest("hex") };
18091
+ return { ...withoutDigest, planDigest: createHash24("sha256").update(canonicalJson6(withoutDigest)).digest("hex") };
17940
18092
  }
17941
18093
  async function normalizeRequest2(request) {
17942
18094
  if (request.destinationFleetId !== void 0) {
17943
18095
  throw new Error("Legacy ownership adoption targets a nested workspace; a Fleet target uses fleet normalize or ownership retire-stale.");
17944
18096
  }
17945
- const targetRoot = resolve40(request.targetRoot);
18097
+ const targetRoot = resolve41(request.targetRoot);
17946
18098
  const installationType = request.installationType.trim();
17947
18099
  const sourceStateKey = exactStateKey(request.adapter, request.sourceStateKey, installationType, "source");
17948
18100
  const destinationStateKey = exactStateKey(request.adapter, request.destinationStateKey, installationType, "destination");
@@ -17954,22 +18106,22 @@ async function normalizeRequest2(request) {
17954
18106
  const scope = await resolveWorkspaceOwnershipScope(request.workspaceRoot, { globalRoot: request.globalRoot });
17955
18107
  const destinationOwner = workspaceOwnerForRoot(scope.root, scope.fleetId);
17956
18108
  const workspaceRoot = await realpath3(request.workspaceRoot);
17957
- const sourceRoot = resolve40(request.fromWorkspaceRoot);
18109
+ const sourceRoot = resolve41(request.fromWorkspaceRoot);
17958
18110
  const sourceOwner = workspaceOwnerForRoot(sourceRoot);
17959
18111
  let sourceClass;
17960
- if (sourceRoot === workspaceRoot || sourceRoot === resolve40(request.workspaceRoot)) {
18112
+ if (sourceRoot === workspaceRoot || sourceRoot === resolve41(request.workspaceRoot)) {
17961
18113
  if (sourceOwner === destinationOwner) {
17962
18114
  throw new Error(`${sourceOwner} is already the destination owner; ordinary install migration handles its legacy state.`);
17963
18115
  }
17964
18116
  sourceClass = "own-legacy-owner";
17965
18117
  } else {
17966
18118
  const sourceForms = [sourceRoot, ...await realpath3(sourceRoot).then((path) => [path], () => [])];
17967
- const workspaceForms = [workspaceRoot, resolve40(request.workspaceRoot), scope.root];
18119
+ const workspaceForms = [workspaceRoot, resolve41(request.workspaceRoot), scope.root];
17968
18120
  if (sourceForms.some((source) => workspaceForms.some((workspace) => containsPath2(source, workspace) || containsPath2(workspace, source)))) {
17969
18121
  throw new Error(`Source root ${sourceRoot} contains or is contained by the destination workspace; it cannot be adopted as a foreign root.`);
17970
18122
  }
17971
18123
  for (const fleet of await listRegisteredFleets({ globalRoot: request.globalRoot })) {
17972
- const fleetForms = [resolve40(fleet.root), ...await realpath3(fleet.root).then((path) => [path], () => [])];
18124
+ const fleetForms = [resolve41(fleet.root), ...await realpath3(fleet.root).then((path) => [path], () => [])];
17973
18125
  if (sourceForms.some((source) => fleetForms.some((root) => containsPath2(root, source)))) {
17974
18126
  throw new Error(`Source root ${sourceRoot} is inside registered Fleet '${fleet.id}'; use fleet normalize or ownership retire-stale.`);
17975
18127
  }
@@ -18126,7 +18278,7 @@ function containsPath2(parent, candidate) {
18126
18278
  // src/version/policy.ts
18127
18279
  import { execFile as execFile7 } from "child_process";
18128
18280
  import { readFile as readFile40 } from "fs/promises";
18129
- import { join as join55, resolve as resolve41 } from "path";
18281
+ import { join as join56, resolve as resolve42 } from "path";
18130
18282
  import { promisify as promisify7 } from "util";
18131
18283
  import { parse as parseJsonc } from "jsonc-parser";
18132
18284
  import { z as z15 } from "zod";
@@ -18223,7 +18375,7 @@ async function discoverVersionsFromSource(pkg, workspaceRoot) {
18223
18375
  if (tagged.length > 0) return tagged;
18224
18376
  }
18225
18377
  if (driverName === "local") {
18226
- const root = resolve41(workspaceRoot, pkg.source);
18378
+ const root = resolve42(workspaceRoot, pkg.source);
18227
18379
  const manifest2 = await readPackageManifest(root);
18228
18380
  const current = manifest2 ? [{ version: manifest2.version, ref: pkg.requestedRef ?? root }] : [];
18229
18381
  try {
@@ -18238,7 +18390,7 @@ async function discoverVersionsFromSource(pkg, workspaceRoot) {
18238
18390
  }
18239
18391
  const driver = getSourceDriver(driverName);
18240
18392
  const resolved = await driver.resolve(pkg.source, {
18241
- cacheRoot: join55(workspaceRoot, ".agentwheel", "cache"),
18393
+ cacheRoot: join56(workspaceRoot, ".agentwheel", "cache"),
18242
18394
  mode: "tracking",
18243
18395
  ref: pkg.requestedRef
18244
18396
  });
@@ -18332,7 +18484,7 @@ function gitUrlFromSource(source) {
18332
18484
  throw new Error(`Version discovery does not support Git source: ${source}`);
18333
18485
  }
18334
18486
  function versionCachePath(workspaceRoot) {
18335
- return join55(workspaceRoot, ".agentwheel", "cache", "version-index.json");
18487
+ return join56(workspaceRoot, ".agentwheel", "cache", "version-index.json");
18336
18488
  }
18337
18489
  async function readVersionCache(path) {
18338
18490
  if (!await pathExists(path)) return { schemaVersion: 1, sources: {} };
@@ -18349,7 +18501,7 @@ init_semver();
18349
18501
  // src/profile/members.ts
18350
18502
  import { execFile as execFile8 } from "child_process";
18351
18503
  import { readFile as readFile41 } from "fs/promises";
18352
- import { join as join56, resolve as resolve42 } from "path";
18504
+ import { join as join57, resolve as resolve43 } from "path";
18353
18505
  import { promisify as promisify8 } from "util";
18354
18506
  import { z as z17 } from "zod";
18355
18507
 
@@ -18525,7 +18677,7 @@ async function invokeMemberStatus(member, parentWorkspace, chain, options, cliEn
18525
18677
  let stderr = "";
18526
18678
  try {
18527
18679
  if (member.transport === "local") {
18528
- const workspace = resolve42(parentWorkspace, member.workspace);
18680
+ const workspace = resolve43(parentWorkspace, member.workspace);
18529
18681
  const result = await execFileAsync8(process.execPath, [cliEntry, ...args], {
18530
18682
  cwd: workspace,
18531
18683
  env: env2,
@@ -18571,7 +18723,7 @@ async function runMemberAgentwheel(member, parentWorkspace, args, chain) {
18571
18723
  process.execPath,
18572
18724
  [process.argv[1], ...memberCommandArgs(member, args)],
18573
18725
  {
18574
- cwd: resolve42(parentWorkspace, member.workspace),
18726
+ cwd: resolve43(parentWorkspace, member.workspace),
18575
18727
  env: env2,
18576
18728
  maxBuffer: 20 * 1024 * 1024
18577
18729
  }
@@ -18651,7 +18803,7 @@ function memberFailure(member, health, error) {
18651
18803
  };
18652
18804
  }
18653
18805
  function memberCachePath(workspaceRoot, profileName, memberId) {
18654
- return join56(workspaceRoot, ".agentwheel", "cache", "member-status", profileName, `${memberId}.json`);
18806
+ return join57(workspaceRoot, ".agentwheel", "cache", "member-status", profileName, `${memberId}.json`);
18655
18807
  }
18656
18808
  async function readMemberCache(path) {
18657
18809
  if (!await pathExists(path)) return void 0;
@@ -18677,7 +18829,7 @@ function assertNoCompositeCycle(workspaceRoot, profileName, chain) {
18677
18829
  }
18678
18830
  }
18679
18831
  function compositeKey(workspaceRoot, profileName) {
18680
- return `${resolve42(workspaceRoot)}#${profileName}`;
18832
+ return `${resolve43(workspaceRoot)}#${profileName}`;
18681
18833
  }
18682
18834
 
18683
18835
  // src/status/repository.ts
@@ -18724,10 +18876,10 @@ function valueAfter(lines, prefix) {
18724
18876
  }
18725
18877
 
18726
18878
  // src/catalogue/client.ts
18727
- import { createHash as createHash24 } from "crypto";
18879
+ import { createHash as createHash25 } from "crypto";
18728
18880
  import { readFile as readFile42, rm as rm15 } from "fs/promises";
18729
18881
  import { homedir as homedir15 } from "os";
18730
- import { join as join57 } from "path";
18882
+ import { join as join58 } from "path";
18731
18883
 
18732
18884
  // src/model/catalogue.ts
18733
18885
  import { z as z18 } from "zod";
@@ -19000,18 +19152,18 @@ var CatalogueClient = class {
19000
19152
  }
19001
19153
  return {
19002
19154
  value: schema.parse(value),
19003
- digest: createHash24("sha256").update(bytes).digest("hex")
19155
+ digest: createHash25("sha256").update(bytes).digest("hex")
19004
19156
  };
19005
19157
  }
19006
19158
  };
19007
19159
  function defaultCatalogueCachePath() {
19008
- return join57(homedir15(), ".agentwheel", "catalogue-cache.json");
19160
+ return join58(homedir15(), ".agentwheel", "catalogue-cache.json");
19009
19161
  }
19010
19162
  function sameSources2(a, b) {
19011
19163
  return a.length === b.length && a.every((source, index) => source === b[index]);
19012
19164
  }
19013
19165
  function catalogueContentHash(enriched, vercel) {
19014
- return createHash24("sha256").update(JSON.stringify({ enriched, vercel })).digest("hex");
19166
+ return createHash25("sha256").update(JSON.stringify({ enriched, vercel })).digest("hex");
19015
19167
  }
19016
19168
 
19017
19169
  // src/search/index.ts
@@ -19373,9 +19525,9 @@ function includesToken(normalizedText, token) {
19373
19525
  }
19374
19526
 
19375
19527
  // src/semantic/index.ts
19376
- import { createHash as createHash25 } from "crypto";
19528
+ import { createHash as createHash26 } from "crypto";
19377
19529
  import { homedir as homedir16 } from "os";
19378
- import { join as join58 } from "path";
19530
+ import { join as join59 } from "path";
19379
19531
  import { env, pipeline } from "@huggingface/transformers";
19380
19532
  var DEFAULT_SEMANTIC_INDEX_URL = "https://raw.githubusercontent.com/NestDevLab/agentwheel-registry/main/catalogue-semantic-index/gte-v1/";
19381
19533
  var CONTRACT = {
@@ -19463,13 +19615,13 @@ var SemanticSearchClient = class {
19463
19615
  if (!response.ok) throw new Error(`Semantic index file failed (${response.status}): ${descriptor.path}`);
19464
19616
  const bytes = new Uint8Array(await response.arrayBuffer());
19465
19617
  if (bytes.byteLength !== descriptor.bytes) throw new Error(`Semantic index file size does not match: ${descriptor.path}`);
19466
- const digest3 = createHash25("sha256").update(bytes).digest("hex");
19618
+ const digest3 = createHash26("sha256").update(bytes).digest("hex");
19467
19619
  if (digest3 !== descriptor.sha256) throw new Error(`Semantic index checksum does not match: ${descriptor.path}`);
19468
19620
  return bytes;
19469
19621
  }
19470
19622
  };
19471
19623
  async function embedQuery(query) {
19472
- env.cacheDir = join58(homedir16(), ".agentwheel", "semantic-models");
19624
+ env.cacheDir = join59(homedir16(), ".agentwheel", "semantic-models");
19473
19625
  const extractor = await pipeline("feature-extraction", CONTRACT.model.id, {
19474
19626
  revision: CONTRACT.model.revision,
19475
19627
  dtype: CONTRACT.model.dtype,
@@ -19554,9 +19706,9 @@ function ensureTrailingSlash(value) {
19554
19706
 
19555
19707
  // src/trial/skill.ts
19556
19708
  init_selection();
19557
- import { createHash as createHash26 } from "crypto";
19709
+ import { createHash as createHash27 } from "crypto";
19558
19710
  import { readFile as readFile43, stat as stat16 } from "fs/promises";
19559
- import { join as join59 } from "path";
19711
+ import { join as join60 } from "path";
19560
19712
  import { parse as parseYaml2 } from "yaml";
19561
19713
  var MAX_TRIAL_SKILL_BYTES = 512 * 1024;
19562
19714
  async function createSkillTrial(driver, resolved, selectors) {
@@ -19568,7 +19720,7 @@ async function createSkillTrial(driver, resolved, selectors) {
19568
19720
  throw new Error("Skill trial requires exactly one selected skill. Use --skill <name> or --select skills/<name>.");
19569
19721
  }
19570
19722
  const artifact = skills[0];
19571
- const path = artifact.kind === "dir" ? join59(artifact.sourcePath, "SKILL.md") : artifact.sourcePath;
19723
+ const path = artifact.kind === "dir" ? join60(artifact.sourcePath, "SKILL.md") : artifact.sourcePath;
19572
19724
  const info = await stat16(path);
19573
19725
  if (info.size > MAX_TRIAL_SKILL_BYTES) {
19574
19726
  throw new Error(`Skill trial exceeds the ${MAX_TRIAL_SKILL_BYTES / 1024} KiB content limit.`);
@@ -19584,7 +19736,7 @@ async function createSkillTrial(driver, resolved, selectors) {
19584
19736
  skill: {
19585
19737
  name: artifact.name,
19586
19738
  relativePath: artifact.relativePath,
19587
- sha256: createHash26("sha256").update(content).digest("hex"),
19739
+ sha256: createHash27("sha256").update(content).digest("hex"),
19588
19740
  frontmatter,
19589
19741
  content
19590
19742
  }
@@ -19602,17 +19754,21 @@ function readSkillFrontmatter(content, artifact) {
19602
19754
  return { name: value.name, description: value.description };
19603
19755
  }
19604
19756
 
19757
+ // src/cli/index.ts
19758
+ init_fleet();
19759
+
19605
19760
  // src/lifecycle/fleet-normalize.ts
19606
- import { createHash as createHash27 } from "crypto";
19761
+ import { createHash as createHash28 } from "crypto";
19607
19762
  import { readFile as readFile44, readdir as readdir16, rm as rm16 } from "fs/promises";
19608
19763
  import { homedir as homedir17 } from "os";
19609
- import { dirname as dirname36, isAbsolute as isAbsolute13, join as join60, relative as relative18, resolve as resolve43 } from "path";
19764
+ import { dirname as dirname37, isAbsolute as isAbsolute13, join as join61, relative as relative18, resolve as resolve44 } from "path";
19610
19765
  init_manifest2();
19611
19766
  init_paths();
19612
19767
  init_merge_removal();
19613
19768
  init_instructions_block();
19614
19769
  init_transaction();
19615
19770
  init_adapter();
19771
+ init_fleet();
19616
19772
  init_graph_lock();
19617
19773
  init_manifest();
19618
19774
  init_workspace();
@@ -19896,17 +20052,17 @@ function normalizeRequest3(request) {
19896
20052
  ...profile ? { profile } : {},
19897
20053
  ...agent ? { agent } : {},
19898
20054
  ...orphanedOwnerRoots ? { orphanedOwnerRoots } : {},
19899
- ...request.globalRoot ? { globalRoot: resolve43(request.globalRoot) } : {}
20055
+ ...request.globalRoot ? { globalRoot: resolve44(request.globalRoot) } : {}
19900
20056
  };
19901
20057
  }
19902
20058
  function normalizeOrphanedOwnerRoot(value) {
19903
20059
  const root = value.trim();
19904
20060
  if (!root || !isAbsolute13(root)) throw new Error(`Invalid orphaned owner root '${value}'; expected an absolute workspace path.`);
19905
- return resolve43(root);
20061
+ return resolve44(root);
19906
20062
  }
19907
20063
  async function normalizationRoots(request) {
19908
20064
  const destination = await showRegisteredFleet(request.destinationFleet, { globalRoot: request.globalRoot });
19909
- const source = request.from === "user" ? resolve43(request.globalRoot ?? homedir17()) : (await showRegisteredFleet(request.from.slice("fleet:".length), { globalRoot: request.globalRoot })).root;
20065
+ const source = request.from === "user" ? resolve44(request.globalRoot ?? homedir17()) : (await showRegisteredFleet(request.from.slice("fleet:".length), { globalRoot: request.globalRoot })).root;
19910
20066
  return { source, destination: destination.root };
19911
20067
  }
19912
20068
  async function withOrderedLocks(roots, fn) {
@@ -19914,7 +20070,7 @@ async function withOrderedLocks(roots, fn) {
19914
20070
  if (index === roots.length) return fn();
19915
20071
  const root = roots[index];
19916
20072
  return withFilesystemLock(
19917
- join60(root, ".agentwheel", "fleet-normalize.lock"),
20073
+ join61(root, ".agentwheel", "fleet-normalize.lock"),
19918
20074
  5e3,
19919
20075
  () => run(index + 1),
19920
20076
  "fleet normalization"
@@ -20121,7 +20277,7 @@ async function inspectLegacySelfInstalledState(fleet, packageNames, profileName,
20121
20277
  let normalizedGraphCount = 0;
20122
20278
  for (const graph of graphCandidates) {
20123
20279
  const destinationState = await targetStateForGraph(fleet, graph, fleet.fleetId, allowOrphanedRetiredPackages);
20124
- if (resolve43(destinationState.graphLockPath) === resolve43(graph.path)) {
20280
+ if (resolve44(destinationState.graphLockPath) === resolve44(graph.path)) {
20125
20281
  const destinationManifest = (await collectManifestPaths([destinationState.manifestPath]))[0];
20126
20282
  if (destinationManifest?.manifest.entries.some((entry) => entry.workspaceOwner === fleetOwner && entryMatchesPackages(entry, selected))) {
20127
20283
  assertCorrelatedGraphManifest(
@@ -20136,7 +20292,7 @@ async function inspectLegacySelfInstalledState(fleet, packageNames, profileName,
20136
20292
  }
20137
20293
  }
20138
20294
  const legacyState = await legacyTargetStateForGraph(fleet, graph, allowOrphanedRetiredPackages);
20139
- if (resolve43(legacyState.graphLockPath) !== resolve43(graph.path)) {
20295
+ if (resolve44(legacyState.graphLockPath) !== resolve44(graph.path)) {
20140
20296
  throw new Error(`Legacy graph lock target identity is stale or noncanonical: ${graph.path}`);
20141
20297
  }
20142
20298
  const legacyManifest = (await collectManifestPaths([legacyState.manifestPath]))[0];
@@ -20311,7 +20467,7 @@ function targetKeysForAgent(scope, name) {
20311
20467
  async function runtimeRoots(scope) {
20312
20468
  const roots = /* @__PURE__ */ new Set([scope.root]);
20313
20469
  if (scope.config.packages.some((pkg) => pkg.installationType === "user") || Object.values(scope.config.agents).some((agent) => agent.installationType === "user")) {
20314
- roots.add(resolve43(process.env.AGENTWHEEL_TEST_HOME || process.env.HOME || homedir17()));
20470
+ roots.add(resolve44(process.env.AGENTWHEEL_TEST_HOME || process.env.HOME || homedir17()));
20315
20471
  }
20316
20472
  for (const [name, agent] of Object.entries(scope.config.agents)) {
20317
20473
  if (agent.transport === "ssh" || agent.transport === "local-run-as") throw new Error(`Installed-state normalization cannot inspect ${agent.transport} agent '${name}' locally.`);
@@ -20329,7 +20485,7 @@ async function runtimeRoots(scope) {
20329
20485
  async function collectManifests(roots) {
20330
20486
  const found = /* @__PURE__ */ new Map();
20331
20487
  for (const root of roots) {
20332
- const dir = join60(root, ".agentwheel");
20488
+ const dir = join61(root, ".agentwheel");
20333
20489
  let names;
20334
20490
  try {
20335
20491
  names = await readdir16(dir);
@@ -20339,7 +20495,7 @@ async function collectManifests(roots) {
20339
20495
  }
20340
20496
  for (const name of names.sort((a, b) => a.localeCompare(b))) {
20341
20497
  if (!name.endsWith(".install-manifest.json")) continue;
20342
- const path = join60(dir, name);
20498
+ const path = join61(dir, name);
20343
20499
  const raw = JSON.parse(await readFile44(path, "utf8"));
20344
20500
  const parsed = installManifestSchema.parse(raw);
20345
20501
  if (parsed.version !== 2) {
@@ -20348,14 +20504,14 @@ async function collectManifests(roots) {
20348
20504
  }
20349
20505
  continue;
20350
20506
  }
20351
- if (resolve43(parsed.targetRoot) !== resolve43(root)) {
20507
+ if (resolve44(parsed.targetRoot) !== resolve44(root)) {
20352
20508
  throw new Error(`Install manifest target root does not match its enumerated runtime root: ${path}`);
20353
20509
  }
20354
20510
  const expectedPath = installManifestPath(parsed.targetRoot, parsed.adapter, {
20355
20511
  installationType: parsed.installationType,
20356
20512
  stateKey: parsed.stateKey
20357
20513
  });
20358
- if (resolve43(expectedPath) !== resolve43(path)) {
20514
+ if (resolve44(expectedPath) !== resolve44(path)) {
20359
20515
  throw new Error(`Install manifest state identity does not match its canonical path: ${path}`);
20360
20516
  }
20361
20517
  found.set(path, { path, raw, manifest: { ...parsed, revision: computeManifestRevision(raw), legacy: false } });
@@ -20376,7 +20532,7 @@ async function collectManifestPaths(paths) {
20376
20532
  installationType: parsed.installationType,
20377
20533
  stateKey: parsed.stateKey
20378
20534
  });
20379
- if (resolve43(expectedPath) !== resolve43(path)) {
20535
+ if (resolve44(expectedPath) !== resolve44(path)) {
20380
20536
  throw new Error(`Install manifest state identity does not match its canonical path: ${path}`);
20381
20537
  }
20382
20538
  found.push({ path, raw, manifest: { ...parsed, revision: computeManifestRevision(raw), legacy: false } });
@@ -20395,7 +20551,7 @@ function assertNoForeignSamePathOwnership(manifests, renderedPaths, allowedOwner
20395
20551
  }
20396
20552
  }
20397
20553
  async function relevantGraphLocks(workspaceRoot, selected, targetKeys, include) {
20398
- const root = join60(workspaceRoot, ".agentwheel", "locks");
20554
+ const root = join61(workspaceRoot, ".agentwheel", "locks");
20399
20555
  if (!await pathExists(root)) return [];
20400
20556
  const results = [];
20401
20557
  for (const path of await listFiles(root)) {
@@ -20444,7 +20600,7 @@ async function hasRelevantLegacyManifestCandidate(scope, graph, selected) {
20444
20600
  const legacyManifest = (await collectManifestPaths([legacyState.manifestPath]))[0];
20445
20601
  if (legacyManifest?.manifest.entries.some((entry) => entryMatchesGraphPackages(entry, graph.lock, selected))) return true;
20446
20602
  const stableState = await targetStateForGraph(scope, graph, scope.fleetId ?? null);
20447
- if (resolve43(stableState.graphLockPath) !== resolve43(graph.path)) return false;
20603
+ if (resolve44(stableState.graphLockPath) !== resolve44(graph.path)) return false;
20448
20604
  const stableManifest = (await collectManifestPaths([stableState.manifestPath]))[0];
20449
20605
  return stableManifest?.manifest.entries.some((entry) => entryMatchesGraphPackages(entry, graph.lock, selected)) ?? false;
20450
20606
  }
@@ -20465,7 +20621,7 @@ async function legacyManifestPathForConfiguredTarget(scope, graph) {
20465
20621
  baseDir: scope.root
20466
20622
  });
20467
20623
  const targetRoot = resolveConfigPath(agent.root, scope.root);
20468
- const installRoot = resolve43(installRootForAdapterInstallationType(adapter, targetRoot, agent.installationType, { kind: "local" }));
20624
+ const installRoot = resolve44(installRootForAdapterInstallationType(adapter, targetRoot, agent.installationType, { kind: "local" }));
20469
20625
  const stateKey = stateKeyFor(adapter.name, {
20470
20626
  installationType: agent.installationType,
20471
20627
  stateKey: agent.stateKey,
@@ -20533,7 +20689,7 @@ async function targetStateForGraph(scope, graph, identityFleetId = scope.fleetId
20533
20689
  ssh: void 0,
20534
20690
  ...agent?.stateKey ? { stateKey: agent.stateKey } : {}
20535
20691
  };
20536
- const installRoot = resolve43(installRootForAdapterInstallationType(adapter, targetRoot, installationType, { kind: "local" }));
20692
+ const installRoot = resolve44(installRootForAdapterInstallationType(adapter, targetRoot, installationType, { kind: "local" }));
20537
20693
  const targetIdentity = resolveTargetStateIdentity({
20538
20694
  targetFingerprintParts: fingerprintParts,
20539
20695
  workspaceRoot: scope.root,
@@ -20565,16 +20721,16 @@ async function targetStateForGraph(scope, graph, identityFleetId = scope.fleetId
20565
20721
  async function installedTargetStateForGraph(scope, graph, manifests, owners, selected, identityFleetId = scope.fleetId ?? null) {
20566
20722
  const stable = await targetStateForGraph(scope, graph, identityFleetId);
20567
20723
  let state;
20568
- if (resolve43(graph.path) === resolve43(stable.graphLockPath)) {
20724
+ if (resolve44(graph.path) === resolve44(stable.graphLockPath)) {
20569
20725
  state = stable;
20570
20726
  } else {
20571
20727
  const released = await releasedTargetStateForGraph(scope, graph, identityFleetId);
20572
- if (resolve43(graph.path) !== resolve43(released.graphLockPath)) {
20728
+ if (resolve44(graph.path) !== resolve44(released.graphLockPath)) {
20573
20729
  throw new Error(`Graph lock target identity is stale or noncanonical: ${graph.path}`);
20574
20730
  }
20575
20731
  state = released;
20576
20732
  }
20577
- const manifest = manifests.find((candidate) => resolve43(candidate.path) === resolve43(state.manifestPath));
20733
+ const manifest = manifests.find((candidate) => resolve44(candidate.path) === resolve44(state.manifestPath));
20578
20734
  if (!manifest) {
20579
20735
  throw new Error(`Graph lock is not covered by its canonical install manifest: ${state.manifestPath}`);
20580
20736
  }
@@ -20598,7 +20754,7 @@ async function releasedTargetStateForGraph(scope, graph, identityFleetId = scope
20598
20754
  ...current,
20599
20755
  stateKey,
20600
20756
  targetFingerprint,
20601
- graphLockPath: join60(dirname36(graph.path), `${targetFingerprint}.graph-lock.json`),
20757
+ graphLockPath: join61(dirname37(graph.path), `${targetFingerprint}.graph-lock.json`),
20602
20758
  manifestPath: installManifestPath(current.installRoot, current.adapter, {
20603
20759
  installationType: current.installationType,
20604
20760
  stateKey
@@ -20606,7 +20762,7 @@ async function releasedTargetStateForGraph(scope, graph, identityFleetId = scope
20606
20762
  };
20607
20763
  }
20608
20764
  function assertCorrelatedGraphManifest(graph, state, manifest, owners, selected) {
20609
- if (manifest.manifest.adapter !== state.adapter || manifest.manifest.installationType !== state.installationType || manifest.manifest.stateKey !== state.stateKey || resolve43(manifest.manifest.targetRoot) !== resolve43(state.installRoot)) {
20765
+ if (manifest.manifest.adapter !== state.adapter || manifest.manifest.installationType !== state.installationType || manifest.manifest.stateKey !== state.stateKey || resolve44(manifest.manifest.targetRoot) !== resolve44(state.installRoot)) {
20610
20766
  throw new Error(`Install manifest identity does not match graph target state: ${manifest.path}`);
20611
20767
  }
20612
20768
  const entries = manifest.manifest.entries.filter((entry) => entryMatchesGraphPackages(entry, graph.lock, selected));
@@ -20663,7 +20819,7 @@ function destinationGraphFromSource(source, targetFingerprint) {
20663
20819
  function mergeDestinationManifest(existing, state, generatedAt, desiredEntries, replaceOwners = /* @__PURE__ */ new Set()) {
20664
20820
  if (existing) {
20665
20821
  const manifest2 = existing.manifest;
20666
- if (manifest2.adapter !== state.adapter || manifest2.installationType !== state.installationType || manifest2.stateKey !== state.stateKey || resolve43(manifest2.targetRoot) !== state.installRoot) {
20822
+ if (manifest2.adapter !== state.adapter || manifest2.installationType !== state.installationType || manifest2.stateKey !== state.stateKey || resolve44(manifest2.targetRoot) !== state.installRoot) {
20667
20823
  throw new Error(`Destination manifest identity diverges from the derived target: ${existing.path}`);
20668
20824
  }
20669
20825
  }
@@ -20723,7 +20879,7 @@ async function assertEquivalentRuntimeState(entry, sourcePath, destinationPath)
20723
20879
  const content = await readFile44(path, "utf8");
20724
20880
  if (hasMergeRemovalContent(entry.mergeRemoval)) {
20725
20881
  assertExactMergeContribution(entry.mergeRemoval, entry.mergeStrategy, content);
20726
- } else if (resolve43(sourcePath) === resolve43(destinationPath) && entry.mergeStrategy !== "codex-toml-mcp") {
20882
+ } else if (resolve44(sourcePath) === resolve44(destinationPath) && entry.mergeStrategy !== "codex-toml-mcp") {
20727
20883
  assertExactMergeContribution({}, entry.mergeStrategy, content);
20728
20884
  } else {
20729
20885
  throw new Error(`Installed-state normalization cannot prove incomplete merge ownership at ${path}.`);
@@ -20734,8 +20890,8 @@ async function assertEquivalentRuntimeState(entry, sourcePath, destinationPath)
20734
20890
  await assertEquivalentRuntimeBytes(sourcePath, destinationPath, entry.hash);
20735
20891
  }
20736
20892
  function renderedEntryPathForRoot(root, entryPath) {
20737
- const normalizedRoot = resolve43(root);
20738
- const candidate = resolve43(normalizedRoot, entryPath);
20893
+ const normalizedRoot = resolve44(root);
20894
+ const candidate = resolve44(normalizedRoot, entryPath);
20739
20895
  if (candidate !== normalizedRoot && !candidate.startsWith(`${normalizedRoot}/`)) {
20740
20896
  throw new Error(`Install manifest entry escapes its target root: ${entryPath}`);
20741
20897
  }
@@ -20826,8 +20982,8 @@ function ownerMatchesGraphPackage(lock, owner, selected) {
20826
20982
  return ownerMatchesPackage(owner, selected) || lock.canonical.roots.some((root) => selected.has(root.rootId) && root.graphNodeId === owner);
20827
20983
  }
20828
20984
  function renderedEntryPath(manifest, entry) {
20829
- const root = resolve43(manifest.targetRoot);
20830
- const candidate = resolve43(root, entry.path);
20985
+ const root = resolve44(manifest.targetRoot);
20986
+ const candidate = resolve44(root, entry.path);
20831
20987
  if (candidate !== root && !candidate.startsWith(`${root}/`)) {
20832
20988
  throw new Error(`Install manifest entry escapes its target root: ${entry.path}`);
20833
20989
  }
@@ -21168,7 +21324,7 @@ function configRevision(config) {
21168
21324
  return sha2567(canonicalJson8(config));
21169
21325
  }
21170
21326
  function normalizationJournalPath(sourceRoot, destinationFleet) {
21171
- return join60(sourceRoot, ".agentwheel", `fleet-normalize-${destinationFleet}.journal.json`);
21327
+ return join61(sourceRoot, ".agentwheel", `fleet-normalize-${destinationFleet}.journal.json`);
21172
21328
  }
21173
21329
  function canonicalJson8(value) {
21174
21330
  return JSON.stringify(sortValue(value));
@@ -21181,7 +21337,7 @@ function sortValue(value) {
21181
21337
  return value;
21182
21338
  }
21183
21339
  function sha2567(value) {
21184
- return createHash27("sha256").update(value).digest("hex");
21340
+ return createHash28("sha256").update(value).digest("hex");
21185
21341
  }
21186
21342
  function assertDigest(value) {
21187
21343
  if (!/^[a-f0-9]{64}$/.test(value)) throw new Error(`Invalid plan digest: ${value}`);
@@ -21335,7 +21491,7 @@ fleetCommand.command("normalize").description("plan or apply duplicate desired-s
21335
21491
  });
21336
21492
  cacheCommand.command("prune").description("remove old Git source snapshots while preserving locked commits").option("--user", "use the user workspace", false).option("--local", "use the nearest local workspace", false).option("--fleet <id>", "use one registered named fleet").option("-t, --target-root <path>", "explicit workspace root").option("--keep <count>", "newest snapshots to retain per source", parsePositiveInteger, 3).option("--apply", "delete the selected snapshots; without this flag only preview", false).action(async (options) => {
21337
21493
  const targetRoot = await workspaceContextRootFromOptions(normalizeRuntimeScopeOptions(options));
21338
- const cacheRoot = join61(targetRoot, ".agentwheel", "cache");
21494
+ const cacheRoot = join62(targetRoot, ".agentwheel", "cache");
21339
21495
  const result = await pruneGitCache(cacheRoot, { keepSnapshots: options.keep, dryRun: !options.apply });
21340
21496
  const verb = options.apply ? "Removed" : "Would remove";
21341
21497
  for (const path of result.removedPaths) console.log(`${verb} ${path}`);
@@ -21355,7 +21511,7 @@ program.command("pin").description("pin configured revisions or replace package
21355
21511
  throw new Error("Choose pin <alias> <commit> [--select ...], --pins-file <path>, or --packages-file <path>, exclusively.");
21356
21512
  }
21357
21513
  const inputFile = options.packagesFile ?? options.pinsFile;
21358
- const input = inputFile ? JSON.parse(await readFile45(resolve44(inputFile), "utf8")) : [{ alias, commit, ...options.select === void 0 ? {} : { select: options.select } }];
21514
+ const input = inputFile ? JSON.parse(await readFile45(resolve45(inputFile), "utf8")) : [{ alias, commit, ...options.select === void 0 ? {} : { select: options.select } }];
21359
21515
  const config = await pinConfiguredPackages(workspaceRoot, input, {
21360
21516
  dryRun: options.dryRun,
21361
21517
  replacePackages: options.packagesFile !== void 0
@@ -21368,7 +21524,7 @@ program.command("list").description("list artifacts exposed by a package source"
21368
21524
  const resolvedInput = await resolvePackageSource(source, targetRoot);
21369
21525
  const selectedArtifacts = selectedArtifactsFromOptionsOrRegistry(options, resolvedInput.registryEntry);
21370
21526
  const driver = getSourceDriver(options.driver ?? inferSourceDriverName(resolvedInput.source));
21371
- const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join61(targetRoot, ".agentwheel", "cache") }))));
21527
+ const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join62(targetRoot, ".agentwheel", "cache") }))));
21372
21528
  try {
21373
21529
  const artifacts = filterArtifactsBySelection(await driver.list(resolved), selectedArtifacts);
21374
21530
  for (const artifact of artifacts) {
@@ -21437,7 +21593,7 @@ program.command("try").description("read and validate one skill for the current
21437
21593
  const resolvedInput = await resolvePackageSource(source, targetRoot);
21438
21594
  const driver = getSourceDriver(options.driver ?? inferSourceDriverName(resolvedInput.source));
21439
21595
  const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, {
21440
- cacheRoot: join61(targetRoot, ".agentwheel", "cache")
21596
+ cacheRoot: join62(targetRoot, ".agentwheel", "cache")
21441
21597
  }))));
21442
21598
  try {
21443
21599
  const trial = await createSkillTrial(driver, resolved, selectedArtifactsFromOptionsOrRegistry(options, resolvedInput.registryEntry));
@@ -21459,7 +21615,7 @@ program.command("scan").description("scan a package source for validation findin
21459
21615
  const targetRoot = await workspaceContextRootFromOptions(normalizeRuntimeScopeOptions(options));
21460
21616
  const resolvedInput = await resolvePackageSource(source, targetRoot);
21461
21617
  const driver = getSourceDriver(options.driver ?? inferSourceDriverName(resolvedInput.source));
21462
- const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join61(targetRoot, ".agentwheel", "cache") }))));
21618
+ const resolved = await driver.export(await driver.translate(await driver.fetch(await driver.resolve(resolvedInput.source, { cacheRoot: join62(targetRoot, ".agentwheel", "cache") }))));
21463
21619
  try {
21464
21620
  const result = await driver.scan(resolved);
21465
21621
  if (result.findings.length === 0) {
@@ -21715,11 +21871,15 @@ ownershipCommand.command("handoff").description("transfer one managed artifact b
21715
21871
  const toWorkspaceRoot = normalizeCliPath(options.toWorkspaceRoot);
21716
21872
  if (options.toFleet) {
21717
21873
  const fleet = await showRegisteredFleet(options.toFleet);
21718
- if (resolve44(fleet.root) !== resolve44(toWorkspaceRoot)) {
21874
+ if (resolve45(fleet.root) !== resolve45(toWorkspaceRoot)) {
21719
21875
  throw new Error(`Destination fleet '${options.toFleet}' is registered at ${fleet.root}, not ${toWorkspaceRoot}.`);
21720
21876
  }
21721
21877
  }
21722
21878
  const request = {
21879
+ workspaceRoot: await workspaceRootFromOptions(normalizedOptions),
21880
+ reason: options.reason,
21881
+ operationId: options.operationId,
21882
+ noCommit: options.commit === false,
21723
21883
  installationType,
21724
21884
  stateKey: state.stableStateKey,
21725
21885
  targetRoot: state.installRoot,
@@ -21756,8 +21916,8 @@ ownershipCommand.command("recovery-plan").description("write a read-only per-pat
21756
21916
  const adapter = await resolveAdapterForTarget(target, {});
21757
21917
  const transport = transportForTarget(target);
21758
21918
  const requestedReport = normalizeCliPath(options.report);
21759
- const reportPath = join61(await realpath4(dirname37(requestedReport)), basename24(requestedReport));
21760
- const reportInsideTarget = relative19(resolve44(target.targetRoot), reportPath);
21919
+ const reportPath = join62(await realpath4(dirname38(requestedReport)), basename24(requestedReport));
21920
+ const reportInsideTarget = relative19(resolve45(target.targetRoot), reportPath);
21761
21921
  if (reportInsideTarget === "" || !reportInsideTarget.startsWith("..") && !isAbsolute14(reportInsideTarget)) {
21762
21922
  throw new Error("Recovery report must be outside the runtime target root.");
21763
21923
  }
@@ -21788,7 +21948,7 @@ ownershipCommand.command("retire-stale").description("retire stale source-manife
21788
21948
  const normalizedOptions = normalizeRuntimeScopeOptions(options);
21789
21949
  const fleet = await showRegisteredFleet(options.fleet);
21790
21950
  const toWorkspaceRoot = normalizeCliPath(options.toWorkspaceRoot);
21791
- if (resolve44(fleet.root) !== resolve44(toWorkspaceRoot)) {
21951
+ if (resolve45(fleet.root) !== resolve45(toWorkspaceRoot)) {
21792
21952
  throw new Error(`Destination Fleet '${options.fleet}' is registered at ${fleet.root}, not ${toWorkspaceRoot}.`);
21793
21953
  }
21794
21954
  const targets = await resolveCliTargets(normalizedOptions);
@@ -21796,7 +21956,7 @@ ownershipCommand.command("retire-stale").description("retire stale source-manife
21796
21956
  throw new Error(`Stale ownership retirement requires exactly one destination Fleet target, found ${targets.length}.`);
21797
21957
  }
21798
21958
  const target = targets[0];
21799
- if (target.fleetId !== options.fleet || resolve44(target.workspaceRoot) !== resolve44(fleet.root)) {
21959
+ if (target.fleetId !== options.fleet || resolve45(target.workspaceRoot) !== resolve45(fleet.root)) {
21800
21960
  throw new Error(`Resolved target does not belong to destination Fleet '${options.fleet}'.`);
21801
21961
  }
21802
21962
  const adapterOptions = adapterOptionsForTarget(target, normalizedOptions);
@@ -21918,7 +22078,7 @@ ownershipCommand.command("adopt-legacy").description("move proven legacy-keyed o
21918
22078
  ];
21919
22079
  for (const { flag, requested, resolved, none } of requestedAdapterSettings) {
21920
22080
  if (requested === void 0) continue;
21921
- if (resolved !== void 0 && resolve44(target.workspaceRoot, requested) === resolve44(target.workspaceRoot, resolved)) continue;
22081
+ if (resolved !== void 0 && resolve45(target.workspaceRoot, requested) === resolve45(target.workspaceRoot, resolved)) continue;
21922
22082
  throw new Error(`${flag} ${requested} does not match what install resolves for the configured packages: ${resolved ?? none}.`);
21923
22083
  }
21924
22084
  const adapter = await resolveAdapterForTarget(group.target, adapterOptions);
@@ -22088,7 +22248,7 @@ journalCommand.command("list").description("show pending apply journals for reso
22088
22248
  if (!journal) continue;
22089
22249
  pending += 1;
22090
22250
  console.log(`PENDING ${state.adapter.name}/${state.installationType} at ${state.installRoot}`);
22091
- console.log(` journal: ${join61(state.installRoot, ".agentwheel", `${state.state.stateKey}.apply-journal.json`)}`);
22251
+ console.log(` journal: ${join62(state.installRoot, ".agentwheel", `${state.state.stateKey}.apply-journal.json`)}`);
22092
22252
  console.log(` stateKey: ${state.state.stateKey}`);
22093
22253
  console.log(` createdAt: ${journal.createdAt}`);
22094
22254
  console.log(` updatedAt: ${journal.updatedAt}`);
@@ -22438,14 +22598,14 @@ async function packageEntryFromSource(source, targetRoot, options) {
22438
22598
  );
22439
22599
  }
22440
22600
  const bundle = options.deferGraphRendering ? await stageSourceRaw(driver, resolvedSource, {
22441
- cacheRoot: join61(targetRoot, ".agentwheel", "cache"),
22601
+ cacheRoot: join62(targetRoot, ".agentwheel", "cache"),
22442
22602
  mode: options.mode,
22443
22603
  ref: initialVersion?.ref,
22444
22604
  frozenLock: lockMode
22445
22605
  }) : await stageSource(driver, resolvedSource, {
22446
22606
  workspaceRoot: targetRoot,
22447
22607
  adapter,
22448
- cacheRoot: join61(targetRoot, ".agentwheel", "cache"),
22608
+ cacheRoot: join62(targetRoot, ".agentwheel", "cache"),
22449
22609
  mode: options.mode,
22450
22610
  ref: initialVersion?.ref,
22451
22611
  frozenLock: lockMode,
@@ -23054,7 +23214,7 @@ function scopeUpdatePlanToDependencies(result, selectors, previousLock, manifest
23054
23214
  selectedPreviousNodeIds,
23055
23215
  selectedRootIds
23056
23216
  );
23057
- const graphLockDigest = createHash28("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23217
+ const graphLockDigest = createHash29("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23058
23218
  return {
23059
23219
  ...result,
23060
23220
  bundle: { ...result.bundle, graphLock },
@@ -23180,7 +23340,7 @@ function operationBelongsToDependencyUpdate(operation, allowedNodeIds, allowedNa
23180
23340
  function scopeInstallPlanToArtifact(result, rootId, focused, manifest) {
23181
23341
  const scoped = scopePlanOperationsToArtifact(result, rootId, focused, manifest);
23182
23342
  const graphLock = focusedGraphLockForInstall(scoped.bundle.graphLock, rootId, focused);
23183
- const graphLockDigest = createHash28("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23343
+ const graphLockDigest = createHash29("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23184
23344
  return {
23185
23345
  ...scoped,
23186
23346
  bundle: { ...scoped.bundle, graphLock },
@@ -23191,7 +23351,7 @@ function scopeInstallPlanToArtifact(result, rootId, focused, manifest) {
23191
23351
  function scopeUpdatePlanToArtifact(result, rootId, focused, previousLock, manifest) {
23192
23352
  const scoped = scopePlanOperationsToArtifact(result, rootId, focused, manifest, previousLock);
23193
23353
  const graphLock = mergeFocusedArtifactGraphLock(scoped.bundle.graphLock, previousLock, rootId, focused);
23194
- const graphLockDigest = createHash28("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23354
+ const graphLockDigest = createHash29("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23195
23355
  return {
23196
23356
  ...scoped,
23197
23357
  bundle: { ...scoped.bundle, graphLock },
@@ -23486,7 +23646,7 @@ function scopeUpdatePlanToRoot(result, rootId, previousLock, manifest) {
23486
23646
  selectedPreviousNodeIds,
23487
23647
  /* @__PURE__ */ new Set([rootId])
23488
23648
  );
23489
- const graphLockDigest = createHash28("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23649
+ const graphLockDigest = createHash29("sha256").update(canonicalGraphLockJson(graphLock)).digest("hex");
23490
23650
  return {
23491
23651
  ...scoped,
23492
23652
  bundle: { ...scoped.bundle, graphLock },
@@ -23558,7 +23718,7 @@ function keepManifestEntryOperation(entry, targetRoot, scopeDescription, operati
23558
23718
  artifactType: entry.artifactType,
23559
23719
  artifactName: entry.artifactName,
23560
23720
  kind: entry.kind,
23561
- destPath: operation?.destPath ?? join61(targetRoot, entry.path),
23721
+ destPath: operation?.destPath ?? join62(targetRoot, entry.path),
23562
23722
  relativeDestPath: entry.path,
23563
23723
  desiredHash: entry.sourceHash,
23564
23724
  currentHash: operation?.currentHash ?? entry.hash,
@@ -23759,7 +23919,7 @@ function installRootContextForTarget(target) {
23759
23919
  return { kind: target.transport, homeRoot: target.runAs?.home };
23760
23920
  }
23761
23921
  async function withFreshReadOnlyGraphPlan(target, adapter, adapterOptions, installationType, packages, use) {
23762
- const stage = await mkdtemp6(join61(tmpdir7(), "agentwheel-recovery-"));
23922
+ const stage = await mkdtemp6(join62(tmpdir7(), "agentwheel-recovery-"));
23763
23923
  const priorTmpdir = process.env.TMPDIR;
23764
23924
  try {
23765
23925
  process.env.TMPDIR = stage;
@@ -23791,8 +23951,8 @@ async function withFreshReadOnlyGraphPlan(target, adapter, adapterOptions, insta
23791
23951
  yes: true,
23792
23952
  freshGraphOnly: true,
23793
23953
  deferForeignStateCheck: true,
23794
- cacheRoot: join61(stage, "source-cache"),
23795
- registryCachePath: join61(stage, "registry.json")
23954
+ cacheRoot: join62(stage, "source-cache"),
23955
+ registryCachePath: join62(stage, "registry.json")
23796
23956
  });
23797
23957
  return await use(graphPlan);
23798
23958
  } finally {
@@ -23879,7 +24039,7 @@ async function resolveCliTargetState(target, options) {
23879
24039
  migration: prior.migration,
23880
24040
  targetStateFilePreconditions: {
23881
24041
  graphLockPath: stableGraphLockPath,
23882
- graphLockRevision: stableLock ? createHash28("sha256").update(canonicalGraphLockJson(stableLock)).digest("hex") : null,
24042
+ graphLockRevision: stableLock ? createHash29("sha256").update(canonicalGraphLockJson(stableLock)).digest("hex") : null,
23883
24043
  sourceLockRevision: computeSourceLockRevision(stableSourceLock)
23884
24044
  }
23885
24045
  };
@@ -23902,7 +24062,7 @@ async function collectTargetStatus(target, options) {
23902
24062
  const pending = await collectPendingInstallWork(target, options);
23903
24063
  const foreignObservations = pending.foreignStateObservations;
23904
24064
  const effectiveGraphLock = graphLock ?? pending.observedGraphLock;
23905
- const observedManifestRevision = foreignObservations.length > 0 ? createHash28("sha256").update(JSON.stringify(foreignObservations.map((observation) => [
24065
+ const observedManifestRevision = foreignObservations.length > 0 ? createHash29("sha256").update(JSON.stringify(foreignObservations.map((observation) => [
23906
24066
  observation.fileName,
23907
24067
  observation.manifestRevision
23908
24068
  ]).sort())).digest("hex") : null;
@@ -24149,7 +24309,7 @@ async function assertCompositeMutationSupported(workspaceRoot, profile, readOnly
24149
24309
  `Composite-profile mutation is refused before member execution because ${member.id} uses ${member.transport}; durable remote policy and recovery preflight is not implemented.`
24150
24310
  );
24151
24311
  }
24152
- const memberRoot = resolve44(workspaceRoot, member.workspace);
24312
+ const memberRoot = resolve45(workspaceRoot, member.workspace);
24153
24313
  const memberPolicy = await mutationPolicyForWorkspace(memberRoot);
24154
24314
  if (memberPolicy?.revisioning.mode === "commit-after-verify") {
24155
24315
  throw new Error(
@@ -24386,12 +24546,12 @@ async function printDoctor(target, options) {
24386
24546
  const requestedSkills = doctorSkillRequests(target, options);
24387
24547
  const skills = [];
24388
24548
  for (const request of requestedSkills) {
24389
- const skillPath = join61(state.installRoot, targetMapping.dest, request.name);
24549
+ const skillPath = join62(state.installRoot, targetMapping.dest, request.name);
24390
24550
  const exists2 = await pathExists(skillPath);
24391
24551
  const manifestEntry = manifest?.entries.find((entry) => {
24392
24552
  if (entry.artifactType !== "skills") return false;
24393
24553
  const legacyInstallName = "installName" in entry && typeof entry.installName === "string" ? entry.installName : void 0;
24394
- return entry.artifactName === request.name || legacyInstallName === request.name || entry.path === join61(targetMapping.dest, request.name);
24554
+ return entry.artifactName === request.name || legacyInstallName === request.name || entry.path === join62(targetMapping.dest, request.name);
24395
24555
  });
24396
24556
  const status = manifestEntry ? "managed" : exists2 ? "present-unmanaged" : "missing";
24397
24557
  skills.push({
@@ -24471,7 +24631,7 @@ function doctorSkillLabel(name) {
24471
24631
  return `${name} skill`;
24472
24632
  }
24473
24633
  function isSyncwheelWorkspace(targetRoot) {
24474
- return existsSync(join61(targetRoot, ".syncwheel", "manifest.json"));
24634
+ return existsSync(join62(targetRoot, ".syncwheel", "manifest.json"));
24475
24635
  }
24476
24636
  function skillInstallCommand(adapter, installationType, options, skill, behavior = {}) {
24477
24637
  const args = [
@@ -24634,14 +24794,14 @@ function looksLikeSourceSpecifier(value) {
24634
24794
  }
24635
24795
  function normalizeCliPath(value) {
24636
24796
  if (value === "~") return homedir18();
24637
- if (value.startsWith("~/")) return resolve44(homedir18(), value.slice(2));
24638
- return resolve44(value);
24797
+ if (value.startsWith("~/")) return resolve45(homedir18(), value.slice(2));
24798
+ return resolve45(value);
24639
24799
  }
24640
24800
  function shellQuoteArgument(value) {
24641
24801
  return /^[a-z0-9_./:@%+=,-]+$/i.test(value) ? value : `'${value.replace(/'/g, `'"'"'`)}'`;
24642
24802
  }
24643
24803
  function isHomePath(path) {
24644
- return resolve44(path) === resolve44(homedir18());
24804
+ return resolve45(path) === resolve45(homedir18());
24645
24805
  }
24646
24806
  function adapterListFromOption(adapter) {
24647
24807
  if (!adapter) return [];
@@ -24696,11 +24856,11 @@ function filterUninstallPlanBySelection(plan, selected) {
24696
24856
  };
24697
24857
  }
24698
24858
  async function initPackage(root) {
24699
- await mkdir27(join61(root, "instructions"), { recursive: true });
24700
- await mkdir27(join61(root, "rules"), { recursive: true });
24701
- await mkdir27(join61(root, "skills"), { recursive: true });
24702
- const manifestPath = join61(root, "openpack.json");
24703
- const instructionsPath = join61(root, "instructions", "AGENTS.md");
24859
+ await mkdir27(join62(root, "instructions"), { recursive: true });
24860
+ await mkdir27(join62(root, "rules"), { recursive: true });
24861
+ await mkdir27(join62(root, "skills"), { recursive: true });
24862
+ const manifestPath = join62(root, "openpack.json");
24863
+ const instructionsPath = join62(root, "instructions", "AGENTS.md");
24704
24864
  const manifest = {
24705
24865
  schemaVersion: CURRENT_OPENPACK_SCHEMA_VERSION,
24706
24866
  name: "example/agentwheel-package",
@@ -24718,7 +24878,7 @@ async function initPackage(root) {
24718
24878
  await writeFile24(instructionsPath, "# Agent Instructions\n", "utf8");
24719
24879
  }
24720
24880
  async function defaultBootstrapPackage(_root) {
24721
- const packageRoot = await findAgentwheelPackageRoot(dirname37(fileURLToPath4(import.meta.url)));
24881
+ const packageRoot = await findAgentwheelPackageRoot(dirname38(fileURLToPath4(import.meta.url)));
24722
24882
  if (!packageRoot) return void 0;
24723
24883
  return {
24724
24884
  name: "agentwheel",
@@ -24762,10 +24922,10 @@ function withFleetExample(config) {
24762
24922
  };
24763
24923
  }
24764
24924
  async function findAgentwheelPackageRoot(start) {
24765
- let current = resolve44(start);
24925
+ let current = resolve45(start);
24766
24926
  while (true) {
24767
24927
  if (await findPackageManifestPath(current, { warnLegacy: false })) return current;
24768
- const parent = dirname37(current);
24928
+ const parent = dirname38(current);
24769
24929
  if (parent === current) return void 0;
24770
24930
  current = parent;
24771
24931
  }
@@ -24890,14 +25050,14 @@ async function governedCommandContext(command, options) {
24890
25050
  const kind = String(command.args[0] ?? "workspace");
24891
25051
  return {
24892
25052
  workspaceRoot: workspaceRoot2,
24893
- anticipatedPaths: kind === "package" ? [join61(targetRoot, "openpack.json"), join61(targetRoot, "instructions", "AGENTS.md")] : [workspaceConfigPath(targetRoot)]
25053
+ anticipatedPaths: kind === "package" ? [join62(targetRoot, "openpack.json"), join62(targetRoot, "instructions", "AGENTS.md")] : [workspaceConfigPath(targetRoot)]
24894
25054
  };
24895
25055
  }
24896
25056
  if (path === "package migrate") {
24897
25057
  const packageRoot = normalizeTargetRoot(String(command.args[0] ?? "."));
24898
25058
  return {
24899
25059
  workspaceRoot: await findExistingWorkspaceRoot(packageRoot) ?? packageRoot,
24900
- anticipatedPaths: ["agentwheel.json", "agentwheel.jsonc", "openpack.json", "openpack.jsonc"].map((name) => join61(packageRoot, name))
25060
+ anticipatedPaths: ["agentwheel.json", "agentwheel.jsonc", "openpack.json", "openpack.jsonc"].map((name) => join62(packageRoot, name))
24901
25061
  };
24902
25062
  }
24903
25063
  const source = typeof command.args[0] === "string" ? command.args[0] : void 0;
@@ -24909,14 +25069,13 @@ async function governedCommandContext(command, options) {
24909
25069
  const anticipatedPaths = [];
24910
25070
  if (path === "add" || path === "pin") anticipatedPaths.push(workspaceConfigPath(workspaceRoot));
24911
25071
  if (path === "remember" && options.runtime) {
24912
- anticipatedPaths.push(join61(workspaceRoot, ".agentwheel", "overlays", options.runtime, "instructions.local.md"));
25072
+ anticipatedPaths.push(join62(workspaceRoot, ".agentwheel", "overlays", options.runtime, "instructions.local.md"));
24913
25073
  }
24914
25074
  if (path === "uninstall" && source) anticipatedPaths.push(workspaceConfigPath(workspaceRoot));
24915
25075
  return {
24916
25076
  workspaceRoot,
24917
25077
  anticipatedPaths,
24918
- requireCleanWorkingTree: requiresCleanMutationPreflight(path),
24919
- requiresDeclarativeRepositoryDelta: path === "ownership handoff"
25078
+ requireCleanWorkingTree: requiresCleanMutationPreflight(path)
24920
25079
  };
24921
25080
  }
24922
25081
  function commandPath(command) {