Your AI agents are multiplying. OpenClaw, Claude Code, Codex CLI, Copilot, Hermes — and the next
harness your team adopts. Each one wants its own skills, rules, instructions, commands, subagents,
MCP servers, hooks, and settings, in its own layout.
agentwheel makes that one declared state. Add packages to .agentwheel/config.json, preview the
runtime changes, then install the declared state into each target. Updates move tracking sources
forward explicitly; installs make the current declaration true.
Weave skills, rules, and instructions across every AI agent.
2026-11-13
ดาว
—
เครื่องมือ
—
อัปไทม์
—
npm i -g agentwheel
agentwheel init
agentwheel add github:your-org/agent-pack --adapter codex --local --mode tracking
agentwheel plan
agentwheel install
No lock-in. No central gatekeeper. Packages live in plain git repos or local folders, customizations
live in your workspace, and runtimes stay generated output.
Install Methods
CLI install
npm i -g agentwheel
agentwheel init
Prefer pnpm? pnpm add -g agentwheel works too.
AI agent handoff
Give an agent install.md when you want it to install Agentwheel, verify the CLI,
install the companion skill, and show the right catalogue flow for your runtime.
The management skill keeps Agentwheel commands and safety rules inside the runtime you are using.
Install the discovery skill separately when you also want proactive, non-installing suggestions:
agentwheel installs OpenPack resources into five built-in runtimes and into custom harnesses.
Every built-in target is scoped by --installation-type <type>; built-ins currently use local
for project/workspace installs and user for documented user-level installs. If a package can be
installed in more than one type, agentwheel requires --installation-type instead of guessing.
OpenClaw — workspace skills/, local plugin directories; user ~/.openclaw/skills,
~/.openclaw/workspace/AGENTS.md, ~/.openclaw/workspace-subagents/<name>/AGENTS.md,
and ~/.openclaw/openclaw.json
Claude Code — CLAUDE.md, .claude/, .mcp.json, and user ~/.claude/
Codex CLI — AGENTS.md, .agents/skills, plugins/, .codex/, and user equivalents
GitHub Copilot CLI — .github/, user ~/.copilot/, and documented .agents skill alternatives
Hermes — local AGENTS.md; user ~/.hermes/SOUL.md, ~/.hermes/skills,
~/.hermes/plugins, and ~/.hermes/config.yaml
Bring your own — JSONC config adapters with --adapter-config, or programmatic adapters with --adapter-module
Supported resource types include instructions, rules, skills, commands, subagents, MCP, hooks,
settings, plugins, and fragments. Runtime compatibility is per artifact and per installation type;
see docs/design/artifact-harness-compatibility.md.
Fragments are Agentwheel composition inputs, not runtime file-drop targets.
rules is an OpenPack artifact kind, not a portable runtime concept. Claude rules are
behavioral/path-scoped instructions, Copilot rule-like installs map to custom instructions, and
Codex .codex/rules command policy is intentionally outside the built-in behavioral rules
target. Unsupported rule targets require an explicit custom adapter instead of an inferred folder.
Core Commands
Command
Meaning
agentwheel search <query>
Search configured registries and the public enriched/Vercel catalogue; supports stable JSON output for agent reranking.
agentwheel add <source>
Validate and save a package entry in .agentwheel/config.json; does not touch runtimes.
agentwheel pin <alias> <commit>
Change an existing pinned alias's exact commit, preserving its configuration; does not resolve sources or touch runtimes.
agentwheel plan [name-or-source]
Preview what install would reconcile without writing; supports --profile <name> and --json.
agentwheel install
Reconcile configured packages into the current target or selected fleet. Uses the graph lock as input by default.
agentwheel install <name-or-source>
Ensure semantics: configured name/source scopes the install; a new source is added and installed.
agentwheel update [name]
Re-resolve tracking packages, then apply. A configured name preserves artifacts owned by other roots; --dependency <name-or-source> moves one tracking dependency while unrelated graph nodes stay locked.
agentwheel skill update <name>
Resolve the owning configured package and reconcile only that skill plus genuine transitive composition inputs; sibling artifacts stay byte-identical and retain manifest/lock state.
agentwheel uninstall <name-or-source>
Remove a configured package from runtimes and config.
agentwheel uninstall <name> --keep-files
Remove from config/manifest while leaving runtime files unmanaged.
agentwheel status
Show configured packages, manifest/lock presence, and install state. For a named fleet, use --fleet <fleet-id> --profile <name>; --fleet <fleet-id> --all uses profile all when present.
agentwheel ownership handoff <type/name>
Transfer one manifest entry to a different workspace root after exact owner, hash, and revision checks; runtime content is not rewritten.
agentwheel mcp retire <package>
Preview removal of one exact legacy MCP contribution under an explicitly selected install-state key; add --apply only after review.
agentwheel doctor
Check runtime setup and suggest explicit companion/selected skill install commands when they are missing.
agentwheel cache prune
Preview old Git source snapshots; add --apply to remove them while retaining locked commits.
Mental model: install = make what is declared true. update = move tracking declarations forward,
then make them true.
Scoped installs do not remove files owned only by other configured packages; run a full agentwheel install
to reconcile those removals.
When a managed fleet profile moves between workspace roots, preview a single-artifact ownership
handoff first. The dry-run prints the current artifact hash and manifest revision:
Apply the same command with the reviewed values added as --expected-hash <sha256> and
--expected-revision <sha256>. Agentwheel takes the target apply lock, rejects a pending apply
journal, rechecks the old owner and the live artifact hash, then atomically updates only the install
manifest. Run one target at a time; named SSH agents use the same contract through --agent.
Use --from-unknown-owner instead of --from-workspace-root for an entry recorded as
workspace:unknown. A plain file or directory whose runtime no longer matches the recorded hash is
refused unless --carry-drift is passed: the dry-run prints the runtime hash, the apply also needs
--expected-runtime-hash <sha256>, and the manifest keeps the recorded hash so the next install
still reports the drift. Merge and managed-block entries never carry drift.
Qualify a Fleet-owned source with --from-fleet <id> together with its exact
--from-workspace-root; use --to-fleet <id> for a Fleet-owned destination. Both IDs must
be registered at the specified roots. These options qualify ownership, whereas --fleet
selects the governing workspace. --from-fleet cannot be combined with
--from-unknown-owner. For example, preview returning one entry to its original plain owner:
Reverse handoffs require a fresh reviewed plan against the post-handoff state; they do not
reuse old manifest revisions or erase audit history. For run-as targets, also pass the reviewed
--plan-digest and --expected-inventory-revision when applying. The qualified old/new owner
identities are included in the native plan, its digest and the audit. Each handoff changes the
inventory revision, so review subsequent operations against their exact intermediate states.
Use --source-state-key <exact-key> when an existing source manifest must be selected explicitly.
This is a command-local equivalent of a named agent's stateKey; it does not edit agent configuration,
move state files, or reconstruct graph locks. The key must be canonical and match the selected adapter
and installation type. The existing target identity, source owner, exact merge contribution, hash,
revision, pending-journal and migration guards still apply. For example:
Apply only the same reviewed selection with --expected-hash and --expected-revision. An explicit
key is never inferred from other claims and does not allow incomplete merge ownership or drift to
be carried for merge artifacts.
For a one-time MCP rename, keep the legacy artifact in a dedicated cutover workspace rather than
the canonical desired-state profile. Set the legacy manifest stateKey on its named agent, then
preview one runtime at a time:
The package must render exactly one MCP artifact. The command accepts only an exact JSON MCP server
object or exact Codex TOML MCP sections, rejects unexpected manifest entries or owners, and
revalidates the exact contribution under the apply lock. It removes only the selected legacy
server; sibling servers and user configuration remain. The command previews by default. A later
runtime approval must use the same command with --apply instead of --dry-run.
When stable and legacy manifests disagree, update --recover-legacy-state explicitly uses recovered stable state while preserving legacy evidence. Preview the same command with --dry-run first.
For a surgical dependency update, start with a dry-run:
The selector must uniquely match a locked tracking dependency by package name, dependency alias,
node id, or source. Agentwheel advances that node and its required tracking closure, writes the
complete graph lock, and applies atomically. Configured selections stay unchanged, so this mode
rejects package arguments, --select, --skill, --frozen-lock, and --offline. A later full
update can advance the remaining graph.
Quick Start
agentwheel init
agentwheel add github:your-org/agent-pack --adapter openclaw --installation-type local --mode tracking
agentwheel plan
agentwheel install
Artifact Discovery
Search configured registries and the complete public catalogue with one command:
Use --scope registry, --scope enriched, or --scope vercel to restrict a query. The default
--scope all combines every source, deduplicates equivalent artifacts, and reports every
provenance plus the safe installation route.
The optional agentwheel-discovery skill notices capability gaps during normal work, uses the
verified semantic catalogue index, reranks results against the original request, and suggests at
most three artifacts. It can read one instruction skill with agentwheel try before installation.
Search and trial never install or change configuration by themselves.
Registry maintenance remains available through agentwheel registry update and
agentwheel registry list. Registry short names continue to resolve during add/install.
Source Inputs
Agentwheel can install from explicit local paths, Git sources, catalogue short names, provider
indexes, and generated OpenPack wrappers:
OpenPack manifests stay portable and do not contain personal GitHub accounts or tokens. Configure
local gh accounts through a user-local auth profile; see Git Authentication
for the configuration format and runtime behavior.
mcp-registry:<server-name> reads the public MCP Registry and stages a generated OpenPack package
only when the server exposes a safe unauthenticated streamable-http remote. Entries that require
secret headers or only publish native package instructions remain discovery-only until they are
wrapped by an explicit OpenPack source.
clawhub:<package-name> reads ClawHub package metadata and stages a generated OpenPack plugin
wrapper for OpenClaw. The generated artifact plans openclaw plugins install --force clawhub:<name>;
plugin execution remains opt-in through Agentwheel's plugin execution controls.
Runtime reloads or service restarts remain a separate opt-in gate. Configure structured
reloadCommands on an agent or profile runtime, then pass --reload-runtimes (or the alias
--restart-runtimes) with an apply command that executes plugins:
Submit a public resource to the catalogue without editing index.json by hand:
npx agentwheel@latest registry publish https://github.com/owner/repo \
--description "Reusable skills and rules for coding agents." \
--tag skills,rules
The command normalizes the source, drafts the registry JSON, prints a verification command, and
prints a prefilled GitHub submission URL you can review before sending.
Contributor install from source:
git clone https://github.com/NestDevLab/agentwheel
cd agentwheel
pnpm install
pnpm build
pnpm link --global
plan, install --dry-run, and update --dry-run show what would change before runtime files are
written. uninstall removes clean managed files and keeps drifted files by default; use
agentwheel uninstall --force only when you also want to remove drifted managed files.
agentwheel checks npm for newer versions at most once every 24 hours and prints a non-blocking
stderr warning when an update is available. Disable it with --no-update-check or
AGENTWHEEL_NO_UPDATE_CHECK=1.
Companion Skill Doctor
Agentwheel ships two optional companion skills in github:NestDevLab/agentwheel:
skills/agentwheel-discovery proactively notices capability gaps, suggests up to three matches,
and offers a read-only skill trial before installation.
Install only the management skill when proactive recommendations are unwanted. Install both when
you want Agentwheel to surface reusable capabilities during normal work.
The CLI never installs the companion skill silently into runtime folders. Use doctor to check the
selected runtime and print the exact preview and install commands when a skill is missing:
doctor also accepts explicit skill checks and machine-readable output. In Syncwheel-managed
workspaces, it automatically includes the Syncwheel skill so Git/worktree maintenance guidance can
be installed into the active agent runtime when needed.
Use --local for the current directory or -t/--target-root <project> for another
project/workspace. Use exactly one of --user, --local, or --fleet <fleet-id> when desired
state scope matters. -i/--installation-type <type> selects the runtime's install layout inside
that scope. For example, Codex local skills install into .agents/skills, while Codex user skills
install into ~/.agents/skills. Named fleets are optional; ordinary user and local work does not
require a fleet registry.
When adding a new source this way, Agentwheel saves one package entry per adapter so later installs
do not collapse Codex and Claude state into the same config entry.
For a control-plane setup, register a named fleet and define its agents and profiles in that fleet's
config. A fleet is selected explicitly with --fleet <fleet-id>; no fleet has global priority and
Agentwheel never merges desired state from user, local, and fleet scopes.
If another scope already owns an intended runtime path, the plan fails closed even when the bytes
match. Use the separate normalization command to preview an explicit ownership transfer, review its
plan digest, and apply only that same plan. Fleet selection never implies takeover.
agentwheel fleet normalize example-fleet --from user --package core-agent-pack --json
agentwheel fleet normalize example-fleet --from user --package core-agent-pack \
--plan-digest <reviewed-sha256> --apply
agentwheel fleet normalize example-fleet --from user --recover
Recovery restores the source side from a pending normalization journal after verifying that the
recorded configs, manifests, and graph locks have not changed outside the transaction.
Named fleets use workspace schema v3 or newer and require a compatible Agentwheel CLI. Upgrade the CLI first,
verify agentwheel --version and agentwheel fleet --help, then create the fleet config and
register it. Do not edit the config to an older schema or run an older CLI against it.
SSH targets use the same manifest and drift model as local targets. Planning reads the remote
install manifest and hashes remote files before deciding whether a file is up to date, drifted, or
conflicting. SSH hosts need ssh, tar, and node available on PATH.
Target resolution order is exact: --target-root wins, then --agent, then auto-detect from the
current directory, then fallback to the current directory. --all-detected is an explicit escape hatch
for applying to every runtime marker found in the current directory or --target-root; --all remains
reserved for configured agents.
Linux service-user targets
A named local-run-as agent installs into another non-root account's passwd home.
Run Agentwheel from the caller's workspace: sources, graph locks and receipts stay
with the caller; confined reads, writes, manifests and rollback run as the service.
A non-login account works with an explicitly configured noninteractive sudo grant.
Add the agent/profile to a workspace that already declares its source packages:
agentwheel plan --local --profile service
agentwheel --reason "Install reviewed service profile" install --local --profile service
Require durable journaling in the workspace mutation policy while retaining its
revision policy. Linux 5.6+ openat2, Python 3 and immutable worker/interpreter
paths are required. OpenClaw validation additionally needs Linux POSIX ACLs and a
trusted immutable OpenClaw package; includes, programmatic adapters, arbitrary
commands and runtime reloads are rejected. See the transport requirements and
sudo example.
Changing transport creates a distinct state identity. Inspect legacy claims with
ownership recovery-plan, then review the exact JSON plan from adopt-legacy,
retire-stale, release-claim or handoff --dry-run --json. Apply only with its
matching digest and revisions. These commands preserve runtime bytes and modes;
a caller-home manifest is never reused as service-home ownership evidence.
Same-fleet normalization is limited to one service endpoint. Cross-account
migration and runtime restarts are separate operations.
Target state identity
Graph-backed installs keep two target fingerprints with different purposes:
The full target fingerprint records rendering inputs in the graph lock. Adapter code, adapter
configuration, and adapter module changes therefore remain visible and can produce a real update.
The stable state fingerprint selects the graph lock, install manifest, source lock, and apply
journal. It is derived from the contribution scope and effective destination, including the
normalized install root and a structured local or SSH endpoint. Adapter implementation evolution
that resolves to the same destination reuses the installed state instead of orphaning it.
Changing an artifact destination within the same effective install root is handled as a planned
transition from the old path to the new path. Changing the effective install root, local/SSH kind, or
SSH endpoint selects a different target state. SSH state identity requires an explicit host; a display
label is not endpoint identity.
State created by an older Agentwheel release may be named with the full target fingerprint. For a
local target, Agentwheel adopts that state only when one canonical graph lock, its v2 install
manifest, the contribution owner, and target details agree. When a tracked graph lock has advanced
past the installed manifest, Agentwheel uses the manifest only as prior runtime state and resolves
the graph fresh; it never treats that newer lock as the previously installed graph. Mixed digests
inside the owned contribution still fail closed. A supported install or uninstall carries an
explicit migration and revalidates the old and new state under the shared apply lock before replacing
the legacy paths. An explicit stateKey remains the manifest and source-lock key while its legacy
graph-lock path moves. Status, dependency inspection, uninstall, and journal commands use the same
discovery rules.
Agentwheel refuses ambiguous candidates, a graph lock without its correlated manifest, or
disagreeing stable and legacy state, and preserves those files for manual reconciliation. A pending
apply journal that embeds and exactly correlates the missing manifest and graph state remains
discoverable for recovery. Legacy SSH state is also preserved and refused because the old records do
not prove which endpoint owned it.
After reviewing agentwheel ownership recovery-plan, use --recover-legacy-state only for an
invalid local candidate whose historical files must remain preserved. The recovery plan ignores
that candidate when constructing the new stable state; it does not authorize runtime replacement.
Adopting matching unmanaged files still requires --force-conflict, while replacing differing files
still requires --replace-conflict. Review the resulting plan before applying the same flags:
Once the stable manifest exists, normal status and planning use it while retaining the invalid
historical candidate for explicit later cleanup.
When stale ownership must be retired before the target-state migration can run, bind the retirement
to the exact already-installed Fleet manifest instead of asking target-state discovery to choose it:
To use a target configured in a nested workspace while retiring ownership into its containing
registered Fleet, run from that workspace and select the destination owner separately:
--to-fleet qualifies the destination owner; --local, --user, or --fleet selects the target
workspace and its configured transport. The selected workspace must be within the registered
Fleet root, including after symlink resolution, and cannot identify a different Fleet.
The original --fleet <id> command remains supported for targets configured directly at that
Fleet root. Neither form changes agent configuration or relaxes contribution and revision guards.
The dry-run still proves exact destination coverage and runtime bytes. Apply only its emitted command,
which includes the plan, source, destination, and manifest-inventory revisions.
For duplicate state owned by the same registered Fleet, set both workspace roots to the Fleet root
and add --from-fleet-id <fleet-id>. The planner selects only legacy paths covered by the stable
Fleet manifest. For JSON deep merges it also accepts a source contribution that is an exact
recursive subset of the destination contribution. Across package revisions, merge entries must
identify the same package and artifact with equal source hashes; other merge contributions must
match exactly. A source-only path stays in the legacy manifest;
when every source entry is covered, apply removes the old manifest and source lock without changing
runtime files or the stable manifest. Preserve copies of those old state files before applying a
retirement when they are needed as historical evidence.
A nested, non-Fleet workspace (for example a profile checked out beneath a registered Fleet root)
can inherit paths that older installs claimed under a fingerprint-only state key. Those claims name
another plain workspace root, or this workspace's own root from before it was Fleet-qualified, so
install refuses them as foreign. Adopt them into this workspace's stable state without
--force-foreign-state, running from the workspace that owns the target:
The dry-run proves each moved entry: the previous owner root must hold a graph lock named by the
legacy fingerprint, and for another workspace root exactly one such lock must match the entry's
graph-lock digest, node, selector, and source hash. Only entries the current graph still installs at
the same path with the same artifact identity move; the rest stay in the source manifest and are
listed. The current graph groups packages as install does, by installation type and adapter
configuration, and the command refuses when they resolve to more than one install state or when
--installation-type, --adapter-config, or --adapter-module differs from what install resolves.
For plain entries, runtime bytes must match the recorded hash unless --carry-drift keeps that
hash, so the next install reports drift instead of overwriting local changes. A path another owner still claims blocks the
plan. A duplicate claim by the same previous owner is listed only when it sits under another legacy
key of that root with the same proof and the same recorded artifact and hashes; run the command
again with that key to retire it. Any other duplicate, including one in that root's current state,
blocks the plan. Apply only the emitted command. It writes the stable manifest first and the legacy
manifest second without rewriting runtime artifacts. A pending apply journal blocks the command:
recover the journal before planning again. Once the stable phase has completed, a new reviewed
dry-run retires the exact source copy left under the legacy key.
Coherent managed instruction blocks are also supported. There must be one complete selected
marker pair with matching selector, marker digest and recorded body hash; duplicate, overlapping,
missing or drifted markers are refused. --carry-drift is forbidden when a managed block is selected.
The reviewed plan records the original body hash separately from the whole-file runtime hash,
prefix/suffix/block digests and byte/mode snapshot. The native phase journals bind these values and
the whole install-manifest inventory. Initial apply and interrupted recovery require exact reviewed
before/after state, preserving concurrent edits rather than overwriting them. Additional overlapping
claims are refused; only an exact source/destination copy from the two-phase transition may remain.
The runtime file, its prefix, suffix, block and permissions stay unchanged. Adoption preserves the
recorded source metadata; it does not establish historical Git availability or evaluate a later source
update. Run ordinary install planning separately for that decision.
Core Ideas
Three places, one direction:
Where
What
Author
the package's git repo
upstream content, never edited in place
Workspace
your repo, under .agentwheel/
config, locks, trust decisions, and customizations
Runtime
.openclaw/, ~/.claude/, .codex/, ...
generated output
Flow: author + workspace → install → runtime.
Governed mutations
Workspace schema v4 can require a full mutation reason, durable receipts, and automatic
commit-after-verify revisioning for Agentwheel's mutating commands. Revision providers can use the
built-in exact-path Git implementation or a strict JSON command whose absolute entrypoint is
SHA-256 pinned. Runtime output remains generated state; only declared and verified repository paths
are eligible for a commit.
agentwheel install --reason "Install the reviewed artifact set"
agentwheel mutation list
agentwheel mutation show <operation-id>
agentwheel mutation finalize <operation-id>
agentwheel mutation recover-runtime <operation-id>
Provider-owned drafts are recorded as owned-but-unpublished, including their stack, branch,
projected draft tip, and integration control commit. Agentwheel never publishes them and does not
invent a publication command; inspect the durable record and follow the provider's separately
documented, authorized workflow. An active-active provider check may deliberately remain blocked
until then.
Packages
A package is a git repo or folder with an OpenPack manifest and a canonical layout:
Install only part of a package with --select <type>/<name>. --skill <name> is a shortcut for
--select skills/<name>, and selections saved during add are reused by later install and
update runs.
agentwheel add github:NestDevLab/agent-mesh --skill codex-tmux --adapter codex --installation-type local
agentwheel plan
agentwheel install
Use add --runtimes codex to restrict a saved package to matching runtime adapters. The option
accepts comma-separated names and can be repeated. When replacing an existing package alias,
pass its runtime restrictions and selection again; add replaces the saved entry.
To change only an existing pinned alias's revision, use its exact configured name and a full
40-hex commit SHA:
pin preserves the source URL, driver, adapter, runtime restrictions, installation type (including
its absence), package order and other fields. It accepts the normal workspace selectors
--fleet, --local, --user, or --target-root, and uses the same mutation policy, durable
receipts and revision provider as other source mutations. Missing or duplicate aliases, tracking
packages and abbreviated or symbolic revisions are refused. No sources are fetched or rendered;
use the normal plan/dry-run before installing the new revision.
Omitting --select preserves the complete existing selection. Supplying repeatable or
comma-separated --select type/name replaces the complete selection, including any legacy
skills or imported selection field. An explicit empty selection is refused.
For one source mutation with several aliases, use pin --pins-file reviewed-pins.json --fleet delivery --reason "Pin the reviewed source set". The JSON file is a nonempty array of objects
containing only alias, commit and optional select:
To replace the complete package declaration list without resolving sources, use
pin --packages-file reviewed-packages.json --fleet delivery --dry-run. The file must be a JSON
array of workspace package entries with unique names; an empty array explicitly removes all
package declarations. The preview prints the complete proposed config as JSON and writes nothing.
Review it, then run the same command without --dry-run and with --reason to apply through the
normal mutation policy, durable receipt and revision provider. This changes only desired source
config; it does not install or remove runtime artifacts. Run normal runtime plans before installing.
All non-package fields are preserved, as are the supplied package order, omitted defaults, metadata
and extension fields. Package entries must pass the workspace schema. --packages-file cannot be
combined with positional pins, --pins-file or --select. Existing pin forms also accept
--dry-run for a non-mutating config preview.
The batch cannot be combined with positional pins or --select. Every entry is validated before
the config write; duplicate aliases and extra fields are refused. An omitted select preserves
that package's selection; an explicit list replaces only that package's complete selection. The
batch shares one durable receipt and revision-provider transaction.
Package authors can mark artifacts as required. Required artifacts are always installed and cannot
be deselected:
mode: pinned never advances automatically. mode: tracking may advance to the newest release
allowed by an exact version, ~, ^, comparator range, or *. Status always reports installed,
locked, latest allowed, and latest overall versions, including newer releases outside the selected
policy. Version discovery uses a 24-hour cache by default; --refresh bypasses it and --offline
uses cached metadata marked stale when its TTL has expired. Git packages use semver tags as
enumerable releases. A branch without tags can report a changed HEAD but cannot select an older
compatible release; explicit refs and commits remain pins.
Project-owned selection exports
Workspace configuration schemaVersion: 2 can export named artifact selections. This is useful
when a project owns its content and portable local profiles, while a fleet only references the
project's curated selection for a remote runtime.
Configured packages can opt into adapter runtimes with "runtimes": ["claude"]. Profile and
named-agent plans match the declared target adapter; plain workspace commands match each package's
configured adapter. Agents sharing an adapter receive the same package roots. Upgrade every member
to a version supporting this field before using it in shared configuration.
The import is data-only: Agentwheel resolves the package first, then reads only
exports.selections from that resolved source's .agentwheel/config.json. It never imports the
source project's agents, profiles, SSH fields, adapter modules, trust policy, or other workspace
settings. Initial support is intentionally limited to local and git sources, so a Git import
uses the same immutable checkout as its artifacts.
A consuming fleet can reuse that selection without inheriting the project's runtime policy:
Resolution order is: exported base selection, each exported extends step, importer add, then
importer exclude; exclusion wins. Required artifacts remain selected. A package may use either
selection or select/legacy skills, never both, and CLI --select/--skill cannot override an
imported selection.
Plans print IMPORT and SELECT audit lines with the source, export catalog hash, requested
export, extension chain, additions, exclusions, and effective selectors. agentwheel plan --profile local-mac, agentwheel install --profile local-mac --dry-run, and --json expose the same audit
data. The export catalog and resolved selection are recorded in graph locks, so --frozen-lock
rejects config-only selection changes.
Package authors can also declare suggested companion packages. Suggestions are not installed by
default; users opt in with --with-suggestions for all suggestions relevant to selected artifacts,
or --suggestion <alias> for one named suggestion. The choice is saved when used with add or
install <source>.
Recursive resolution, locked.install reads the existing graph lock when present; newly
added packages resolve fresh and then write a deterministic lock.
Explicit updates.update re-resolves tracking sources and applies the new graph. Pinned
packages stay on the locked graph unless their declaration changes.
Fragment composition. Markdown files can transclude shared fragments with
`` or cross-package aliases such as
core:fragments/risk.md.
Trust. New transitive sources prompt before install. Pre-approve with --trust <glob> or
--yes, set a workspace trust policy, and manage persisted decisions with agentwheel trust.
Suggested companions.suggests uses the same source/selection shape as requires, but it
is opt-in. --with-suggestions pulls all relevant suggestions as non-blocking optional edges;
--suggestion <alias> pulls a specific suggestion and fails if that explicit suggestion cannot
resolve.
Offline & frozen installs.--offline guarantees zero network; --frozen-lock hard-fails if
resolution would differ from the lock.
Introspection.agentwheel deps tree prints the resolved graph (source resolution may refresh
incidental local caches but does not recover runtime journals or persist trust); agentwheel deps why <selector> explains why an artifact is installed.
Meta-packages (packs)
OpenPack v2 packages can omit provides when they declare at least one dependency. These
meta-packages install nothing of their own; they aggregate curated selections from other packages.
Uninstalling a meta-package removes the dependencies it pulled in unless those dependencies are
still owned by another configured package.
Use package-level overrides when a workspace intentionally wants one selected source to replace
an artifact that arrives from another package, such as a forked skill replacing the same skill
pulled in by a meta-package. Overrides are explicit; package array order never decides precedence.
The source::type/name selector identifies the artifact to replace. github:owner/repo matches
that repository at any ref; add #main or another ref to narrow it. The replacing package must
select exactly one artifact with the same type/name, and the override must match exactly one
losing artifact. Otherwise planning fails instead of hiding a collision.