agentwheel 0.20.17 → 0.20.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -132,6 +132,12 @@ Apply the same command with the reviewed values added as `--expected-hash <sha25
132
132
  journal, rechecks the old owner and the live artifact hash, then atomically updates only the install
133
133
  manifest. Run one target at a time; named SSH agents use the same contract through `--agent`.
134
134
 
135
+ Use `--from-unknown-owner` instead of `--from-workspace-root` for an entry recorded as
136
+ `workspace:unknown`. A plain file or directory whose runtime no longer matches the recorded hash is
137
+ refused unless `--carry-drift` is passed: the dry-run prints the runtime hash, the apply also needs
138
+ `--expected-runtime-hash <sha256>`, and the manifest keeps the recorded hash so the next install
139
+ still reports the drift. Merge and managed-block entries never carry drift.
140
+
135
141
  For a one-time MCP rename, keep the legacy artifact in a dedicated cutover workspace rather than
136
142
  the canonical desired-state profile. Set the legacy manifest `stateKey` on its named agent, then
137
143
  preview one runtime at a time:
@@ -471,6 +477,35 @@ when every source entry is covered, apply removes the old manifest and source lo
471
477
  runtime files or the stable manifest. Preserve copies of those old state files before applying a
472
478
  retirement when they are needed as historical evidence.
473
479
 
480
+ A nested, non-Fleet workspace (for example a profile checked out beneath a registered Fleet root)
481
+ can inherit paths that older installs claimed under a fingerprint-only state key. Those claims name
482
+ another plain workspace root, or this workspace's own root from before it was Fleet-qualified, so
483
+ install refuses them as foreign. Adopt them into this workspace's stable state without
484
+ `--force-foreign-state`, running from the workspace that owns the target:
485
+
486
+ ```bash
487
+ agentwheel ownership adopt-legacy --agent <agent> \
488
+ --source-state-key <adapter>.<installation-type>.<legacy-fingerprint> \
489
+ --from-workspace-root <previous-owner-root> --json
490
+ ```
491
+
492
+ The dry-run proves each moved entry: the previous owner root must hold a graph lock named by the
493
+ legacy fingerprint, and for another workspace root exactly one such lock must match the entry's
494
+ graph-lock digest, node, selector, and source hash. Only entries the current graph still installs at
495
+ the same path with the same artifact identity move; the rest stay in the source manifest and are
496
+ listed. The current graph groups packages as install does, by installation type and adapter
497
+ configuration, and the command refuses when they resolve to more than one install state or when
498
+ `--installation-type`, `--adapter-config`, or `--adapter-module` differs from what install resolves.
499
+ Runtime bytes must match the recorded hash unless `--carry-drift` keeps that hash, so the next
500
+ install reports drift instead of overwriting local changes. A path another owner still claims blocks the
501
+ plan. A duplicate claim by the same previous owner is listed only when it sits under another legacy
502
+ key of that root with the same proof and the same recorded artifact and hashes; run the command
503
+ again with that key to retire it. Any other duplicate, including one in that root's current state,
504
+ blocks the plan. Apply only the emitted command. It writes the stable manifest first and the legacy
505
+ manifest second, and changes nothing else. A pending apply journal blocks the command. If an apply
506
+ stops after the stable manifest was written, run the dry-run again: paths already in the stable
507
+ state are then retired from the legacy key.
508
+
474
509
  ## Core Ideas
475
510
 
476
511
  **Three places, one direction:**
@@ -5,9 +5,9 @@ import {
5
5
  commitManifestMetadataJournal,
6
6
  recoverPendingApply,
7
7
  uninstall
8
- } from "./chunk-A44XYLUT.js";
9
- import "./chunk-FP26KSBM.js";
10
- import "./chunk-GE7F76AC.js";
8
+ } from "./chunk-L37KQVRS.js";
9
+ import "./chunk-BHT57MK5.js";
10
+ import "./chunk-BNIF3FUR.js";
11
11
  export {
12
12
  applyCombinedInstallPlan,
13
13
  applyInstallPlan,
@@ -4,7 +4,7 @@ import {
4
4
  hashPath,
5
5
  pathExists,
6
6
  writeJsonAtomic
7
- } from "./chunk-GE7F76AC.js";
7
+ } from "./chunk-BNIF3FUR.js";
8
8
 
9
9
  // src/install/transaction.ts
10
10
  import { createHash as createHash6 } from "crypto";
@@ -2865,8 +2865,8 @@ async function recoverMutationRuntime(operationId, options = {}) {
2865
2865
  }
2866
2866
  mutation = GovernedMutation.activateExisting(receipt, baseline, lock);
2867
2867
  const [{ recoverPendingApply }, { readLinkedLocalApplyJournal: readLinkedLocalApplyJournal2, removeApplyJournal: removeApplyJournal2, localPathExists: localPathExists2 }] = await Promise.all([
2868
- import("./apply-ZGCJLZMZ.js"),
2869
- import("./transaction-4KBNHDQX.js")
2868
+ import("./apply-QJHTL7IK.js"),
2869
+ import("./transaction-JHZJWBII.js")
2870
2870
  ]);
2871
2871
  let missingReservation = false;
2872
2872
  for (const entry of pending) {
@@ -24,6 +24,14 @@ async function pathExists(path) {
24
24
  return false;
25
25
  }
26
26
  }
27
+ async function removeOnFailure(path, run) {
28
+ try {
29
+ return await run();
30
+ } catch (error) {
31
+ await rm(path, { recursive: true, force: true });
32
+ throw error;
33
+ }
34
+ }
27
35
  async function hashPath(path) {
28
36
  const stats = await stat(path);
29
37
  if (stats.isFile()) {
@@ -129,6 +137,7 @@ function isAlreadyExists(error) {
129
137
 
130
138
  export {
131
139
  pathExists,
140
+ removeOnFailure,
132
141
  hashPath,
133
142
  listFiles,
134
143
  isIgnoredGeneratedEntry,
@@ -24,11 +24,11 @@ import {
24
24
  rollbackCompletedOperations,
25
25
  sourceLockPath,
26
26
  writeApplyJournal
27
- } from "./chunk-FP26KSBM.js";
27
+ } from "./chunk-BHT57MK5.js";
28
28
  import {
29
29
  pathExists,
30
30
  writeJsonAtomic
31
- } from "./chunk-GE7F76AC.js";
31
+ } from "./chunk-BNIF3FUR.js";
32
32
 
33
33
  // src/install/apply.ts
34
34
  import { execFile } from "child_process";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  pathExists
4
- } from "./chunk-GE7F76AC.js";
4
+ } from "./chunk-BNIF3FUR.js";
5
5
 
6
6
  // src/source/identify.ts
7
7
  import { homedir } from "os";
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  inferSourceDriverName,
4
4
  isExplicitSource
5
- } from "./chunk-U2GRG4UI.js";
6
- import "./chunk-GE7F76AC.js";
5
+ } from "./chunk-QABA4WUP.js";
6
+ import "./chunk-BNIF3FUR.js";
7
7
  export {
8
8
  inferSourceDriverName,
9
9
  isExplicitSource