agentwheel 0.11.0 → 0.14.4

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
@@ -26,7 +26,7 @@ forward explicitly; installs make the current declaration true.
26
26
  ```bash
27
27
  npm i -g agentwheel
28
28
  agentwheel init
29
- agentwheel add github:your-org/agent-pack --adapter codex --mode tracking
29
+ agentwheel add github:your-org/agent-pack --adapter codex --installation-type local --mode tracking
30
30
  agentwheel plan
31
31
  agentwheel install
32
32
  ```
@@ -34,23 +34,35 @@ agentwheel install
34
34
  No lock-in. No central gatekeeper. Packages live in plain git repos or local folders, customizations
35
35
  live in your workspace, and runtimes stay generated output.
36
36
 
37
- > **Status: early (v0.11).** The public CLI vocabulary is package-manager style:
37
+ > **Status: early (v0.12).** The public CLI vocabulary is package-manager style:
38
38
  > `add`, `install`, `update`, and `uninstall`. A hidden `sync` shim remains for old bootstrapped
39
39
  > skills; use `install` in all new docs and scripts.
40
40
 
41
41
  ## Supported runtimes & resources
42
42
 
43
- agentwheel installs OpenPack resources into five built-in runtimes and into custom harnesses:
44
-
45
- - **OpenClaw** `.openclaw/`
46
- - **Claude Code** — `.claude/`
47
- - **Codex CLI** — `.codex/`
48
- - **GitHub Copilot** — `.github/`
49
- - **Hermes** — `.hermes/`
43
+ agentwheel installs OpenPack resources into five built-in runtimes and into custom harnesses.
44
+ Every built-in target is scoped by `--installation-type <type>`; built-ins currently use `local`
45
+ for project/workspace installs and `user` for documented user-level installs. If a package can be
46
+ installed in more than one type, agentwheel requires `--installation-type` instead of guessing.
47
+
48
+ - **OpenClaw** — workspace `skills/`, local plugin directories; user `~/.openclaw/skills`,
49
+ `~/.openclaw/workspace/AGENTS.md`, and `~/.openclaw/openclaw.json`
50
+ - **Claude Code** — `CLAUDE.md`, `.claude/`, `.mcp.json`, and user `~/.claude/`
51
+ - **Codex CLI** — `AGENTS.md`, `.agents/skills`, `plugins/`, `.codex/`, and user equivalents
52
+ - **GitHub Copilot CLI** — `.github/`, user `~/.copilot/`, and documented `.agents` skill alternatives
53
+ - **Hermes** — local `AGENTS.md`; user `~/.hermes/SOUL.md`, `~/.hermes/skills`,
54
+ `~/.hermes/plugins`, and `~/.hermes/config.yaml`
50
55
  - **Bring your own** — JSONC config adapters with `--adapter-config`, or programmatic adapters with `--adapter-module`
51
56
 
52
57
  Supported resource types include instructions, rules, skills, commands, subagents, MCP, hooks,
53
- settings, plugins, and fragments; see the full per-runtime target table below.
58
+ settings, plugins, and fragments. Runtime compatibility is per artifact and per installation type;
59
+ see [`docs/design/artifact-harness-compatibility.md`](docs/design/artifact-harness-compatibility.md).
60
+ Fragments are Agentwheel composition inputs, not runtime file-drop targets.
61
+
62
+ > `rules` is an OpenPack artifact kind, not a portable runtime concept. Claude rules are
63
+ > behavioral/path-scoped instructions, Copilot rule-like installs map to custom instructions, and
64
+ > Codex `.codex/rules` command policy is intentionally outside the built-in behavioral `rules`
65
+ > target. Unsupported rule targets require an explicit custom adapter instead of an inferred folder.
54
66
 
55
67
  ## Core Commands
56
68
 
@@ -60,10 +72,11 @@ settings, plugins, and fragments; see the full per-runtime target table below.
60
72
  | `agentwheel plan [name-or-source]` | Preview what `install` would reconcile without writing. |
61
73
  | `agentwheel install` | Reconcile configured packages into the current target or selected fleet. Uses the graph lock as input by default. |
62
74
  | `agentwheel install <name-or-source>` | Ensure semantics: configured name/source scopes the install; a new source is added and installed. |
63
- | `agentwheel update [name]` | Re-resolve tracking packages, then apply. Pinned packages stay locked. |
75
+ | `agentwheel update [name]` | Re-resolve tracking packages, then apply. Pinned packages stay locked. Use `--profile <name>` for profile-managed fleets. |
64
76
  | `agentwheel uninstall <name-or-source>` | Remove a configured package from runtimes and config. |
65
77
  | `agentwheel uninstall <name> --keep-files` | Remove from config/manifest while leaving runtime files unmanaged. |
66
- | `agentwheel status` | Show configured packages, manifest/lock presence, and install state. |
78
+ | `agentwheel status` | Show configured packages, manifest/lock presence, and install state. Use `--profile <name>` for profile-managed fleets; `status --all` uses profile `all` when present. |
79
+ | `agentwheel doctor` | Check runtime setup and suggest the explicit companion skill install command when it is missing. |
67
80
 
68
81
  Mental model: **`install` = make what is declared true. `update` = move tracking declarations forward,
69
82
  then make them true.**
@@ -76,7 +89,7 @@ to reconcile those removals.
76
89
  npm i -g agentwheel
77
90
 
78
91
  agentwheel init
79
- agentwheel add github:your-org/agent-pack --adapter openclaw --mode tracking
92
+ agentwheel add github:your-org/agent-pack --adapter openclaw --installation-type local --mode tracking
80
93
  agentwheel plan
81
94
  agentwheel install
82
95
  ```
@@ -101,6 +114,18 @@ agentwheel checks npm for newer versions at most once every 24 hours and prints
101
114
  stderr warning when an update is available. Disable it with `--no-update-check` or
102
115
  `AGENTWHEEL_NO_UPDATE_CHECK=1`.
103
116
 
117
+ ## Companion Skill Doctor
118
+
119
+ Agentwheel ships its own companion skill in `github:NestDevLab/agentwheel` as `skills/agentwheel`.
120
+ The CLI never installs it silently into runtime folders. Use `doctor` to check the selected runtime
121
+ and print the exact preview and install commands when the skill is missing:
122
+
123
+ ```bash
124
+ agentwheel doctor --adapter copilot --user
125
+ agentwheel install github:NestDevLab/agentwheel --adapter copilot --user --skill agentwheel --dry-run
126
+ agentwheel install github:NestDevLab/agentwheel --adapter copilot --user --skill agentwheel
127
+ ```
128
+
104
129
  ## Runtime Targeting
105
130
 
106
131
  Normal use does not need `--target-root`. Run agentwheel inside a runtime folder and it detects the
@@ -111,10 +136,20 @@ cd ~/.openclaw
111
136
  agentwheel install
112
137
  ```
113
138
 
114
- If the current directory is already the runtime directory (`~/.openclaw`), agentwheel uses its
115
- parent as the root so output lands in `~/.openclaw/skills`, not `~/.openclaw/.openclaw/skills`.
116
- If the current directory contains a runtime directory (`./.openclaw`), that directory is used as
117
- the target under the current project.
139
+ Explicit source installs with an explicit adapter default to user-level artifacts, so this works as
140
+ a global install:
141
+
142
+ ```bash
143
+ agentwheel install github:your-org/agent-pack --adapter codex,claude
144
+ ```
145
+
146
+ Use `--local` for the current directory or `-t/--target-root <project>` for another
147
+ project/workspace. Use `--user`, `--local`, or `-i/--installation-type <type>` when you want the
148
+ scope to be explicit. For example, Codex local skills install into `.agents/skills`, while Codex user
149
+ skills install into `~/.agents/skills`.
150
+
151
+ When adding a new source this way, Agentwheel saves one package entry per adapter so later installs
152
+ do not collapse Codex and Claude state into the same config entry.
118
153
 
119
154
  For a control-plane setup, define named agents in config. Global config lives at
120
155
  `~/.agentwheel/config.json`; project config lives at `.agentwheel/config.json`; project values win.
@@ -122,10 +157,11 @@ For a control-plane setup, define named agents in config. Global config lives at
122
157
  ```jsonc
123
158
  {
124
159
  "agents": {
125
- "lab-openclaw": { "adapter": "openclaw", "root": "/Users/me/.openclaw-home", "transport": "local" },
160
+ "lab-openclaw": { "adapter": "openclaw", "installationType": "local", "root": "$HOME/.openclaw-home", "transport": "local" },
126
161
  "remote-codex": {
127
162
  "adapter": "codex",
128
- "root": "/home/agent/project",
163
+ "installationType": "local",
164
+ "root": "/workspace/project",
129
165
  "transport": "ssh",
130
166
  "host": "agent-host.example",
131
167
  "user": "agent",
@@ -147,7 +183,9 @@ For a control-plane setup, define named agents in config. Global config lives at
147
183
  ```bash
148
184
  agentwheel install --agent lab-openclaw
149
185
  agentwheel install --all
186
+ agentwheel update --profile daily --dry-run
150
187
  agentwheel install --profile daily
188
+ agentwheel status --profile daily
151
189
  agentwheel install --all-detected
152
190
  ```
153
191
 
@@ -201,7 +239,7 @@ Install only part of a package with `--select <type>/<name>`. `--skill <name>` i
201
239
  `update` runs.
202
240
 
203
241
  ```bash
204
- agentwheel add github:NestDevLab/agent-mesh --skill codex-tmux --adapter codex
242
+ agentwheel add github:NestDevLab/agent-mesh --skill codex-tmux --adapter codex --installation-type local
205
243
  agentwheel plan
206
244
  agentwheel install
207
245
  ```
@@ -287,21 +325,23 @@ pulled in by a meta-package. Overrides are explicit; package array order never d
287
325
  "source": "github:NestDevLab/agent-must-have#core",
288
326
  "driver": "git",
289
327
  "adapter": "codex",
328
+ "installationType": "local",
290
329
  "mode": "tracking"
291
330
  },
292
331
  {
293
332
  "name": "agent-toolkit-nestdev",
294
- "source": "github:Yehonal/agent-toolkit#main",
333
+ "source": "github:example-org/agent-toolkit#main",
295
334
  "driver": "git",
296
335
  "adapter": "codex",
336
+ "installationType": "local",
297
337
  "mode": "tracking",
298
338
  "select": [
299
339
  "rules/self-improve-on-correction.md",
300
340
  "skills/self-improve"
301
341
  ],
302
342
  "overrides": [
303
- "github:FrancescoBorzi/agent-toolkit::rules/self-improve-on-correction.md",
304
- "github:FrancescoBorzi/agent-toolkit::skills/self-improve"
343
+ "github:example-upstream/agent-toolkit::rules/self-improve-on-correction.md",
344
+ "github:example-upstream/agent-toolkit::skills/self-improve"
305
345
  ]
306
346
  }
307
347
  ]
@@ -316,9 +356,9 @@ losing artifact. Otherwise planning fails instead of hiding a collision.
316
356
  The same declaration can be created from the CLI:
317
357
 
318
358
  ```bash
319
- agentwheel add github:Yehonal/agent-toolkit#main \
359
+ agentwheel add github:example-org/agent-toolkit#main \
320
360
  --skill self-improve \
321
- --override 'github:FrancescoBorzi/agent-toolkit::skills/self-improve'
361
+ --override 'github:example-upstream/agent-toolkit::skills/self-improve'
322
362
  ```
323
363
 
324
364
  `agentwheel plan`, `agentwheel deps tree`, and `agentwheel deps why` print `OVERRIDE` lines for
@@ -351,9 +391,16 @@ published:
351
391
  {
352
392
  "name": "myco-internal",
353
393
  "targets": {
354
- "instructions": { "dest": ".myco/context/AGENTS.md" },
355
- "rules": { "dest": ".myco/policy/rules" },
356
- "skills": { "dest": ".myco/lib/skills" }
394
+ "instructions": {
395
+ "local": { "dest": ".myco/context/AGENTS.md" }
396
+ },
397
+ "rules": {
398
+ "local": { "dest": ".myco/policy/rules" }
399
+ },
400
+ "skills": {
401
+ "local": { "dest": ".myco/lib/skills" },
402
+ "user": { "root": "home", "dest": ".myco/skills" }
403
+ }
357
404
  }
358
405
  }
359
406
  ```
@@ -370,18 +417,19 @@ agentwheel install ./my-pack --adapter-module ./myco-adapter.js
370
417
 
371
418
  Built-in runtime targets:
372
419
 
373
- | Runtime | Main targets |
420
+ | Runtime | Native supported targets |
374
421
  |---|---|
375
- | **OpenClaw** | `.openclaw/AGENTS.md`, `.openclaw/skills`, `.openclaw/rules`, `.openclaw/commands`, `.openclaw/agents`, MCP/hooks/settings, semantic plugin planning |
376
- | **Claude Code** | `.claude/CLAUDE.md`, `.claude/skills`, `.claude/commands`, `.claude/agents`, `.claude/rules`, `.claude/.mcp.json`, `.claude/settings.json` |
377
- | **Codex CLI** | `.codex/AGENTS.md`, `.codex/skills`, `.codex/commands`, `.codex/agents`, `.codex/rules`, `.codex/config.toml`, `.codex/hooks.json` |
378
- | **Hermes** | `.hermes/AGENTS.md`, `.hermes/skills`, `.hermes/rules`, `.hermes/commands`, `.hermes/agents`, MCP/hooks/settings |
379
- | **GitHub Copilot** | `.github/copilot-instructions.md`, `.github/instructions`, `.github/prompts`, `.github/skills`, `.github/agents`, `.vscode/mcp.json` |
422
+ | **OpenClaw** | `local: skills/, .openclaw/plugins/`; `user: ~/.openclaw/workspace/AGENTS.md, ~/.openclaw/skills, ~/.openclaw/openclaw.json`; no built-in `rules` target |
423
+ | **Claude Code** | `local: CLAUDE.md, .claude/skills, .claude/rules, .claude/commands, .claude/agents, .claude/plugins, .mcp.json, .claude/settings.json`; `user: ~/.claude/...` except project MCP; rules are behavioral/path-scoped |
424
+ | **Codex CLI** | `local: AGENTS.md, .agents/skills, plugins/, .codex/agents, .codex/config.toml, .codex/hooks.json`; `user: ~/.codex/AGENTS.md, ~/.agents/skills, ~/.codex/plugins, ~/.codex/agents, ~/.codex/config.toml, ~/.codex/hooks.json`; no built-in `rules` target; generic settings are planned, not implemented |
425
+ | **Hermes** | `local: AGENTS.md`; `user: ~/.hermes/SOUL.md, ~/.hermes/skills, ~/.hermes/plugins, ~/.hermes/config.yaml`; rules require explicit adapter config |
426
+ | **GitHub Copilot CLI** | `local: .github/copilot-instructions.md, .github/instructions, .github/prompts, .github/skills, .github/plugins, .github/agents, .github/mcp.json, .github/hooks, .github/settings.json`; `user: ~/.copilot/copilot-instructions.md, ~/.copilot/instructions, ~/.copilot/skills, ~/.copilot/plugins, ~/.copilot/agents, ~/.copilot/mcp-config.json, ~/.copilot/hooks, ~/.copilot/settings.json`; rule-like artifacts map to instructions |
380
427
 
381
428
  ## Docs
382
429
 
383
430
  - [`docs/spec/openpack.md`](docs/spec/openpack.md) — OpenPack package spec.
384
431
  - [`docs/fleet-config.md`](docs/fleet-config.md) — named agents, SSH targets, and profiles.
432
+ - [`docs/design/artifact-harness-compatibility.md`](docs/design/artifact-harness-compatibility.md) — artifact/harness compatibility matrix and rule semantics.
385
433
  - Resource catalogue: https://nestdevlab.github.io/agentwheel/catalogue.html.
386
434
  - [`DESIGN.md`](DESIGN.md) — architecture and module layout.
387
435
  - [`LIFECYCLE.md`](LIFECYCLE.md) — publish, install, update, and customization model.
@@ -18,6 +18,8 @@ import {
18
18
  writeFile
19
19
  } from "fs/promises";
20
20
  import { dirname, join, relative } from "path";
21
+ var IGNORED_ENTRY_NAMES = /* @__PURE__ */ new Set([".git", "node_modules", "__pycache__", ".DS_Store"]);
22
+ var IGNORED_SUFFIXES = [".pyc", ".pyo"];
21
23
  async function pathExists(path) {
22
24
  try {
23
25
  await stat(path);
@@ -48,7 +50,7 @@ async function listFiles(root) {
48
50
  async function walk(dir) {
49
51
  const entries = await readdir(dir, { withFileTypes: true });
50
52
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
51
- if (entry.name === ".git" || entry.name === "node_modules") continue;
53
+ if (isIgnoredGeneratedEntry(entry.name)) continue;
52
54
  const full = join(dir, entry.name);
53
55
  if (entry.isDirectory()) {
54
56
  await walk(full);
@@ -60,6 +62,9 @@ async function listFiles(root) {
60
62
  await walk(root);
61
63
  return out;
62
64
  }
65
+ function isIgnoredGeneratedEntry(name) {
66
+ return IGNORED_ENTRY_NAMES.has(name) || IGNORED_SUFFIXES.some((suffix) => name.endsWith(suffix));
67
+ }
63
68
  async function atomicCopy(source, dest, kind) {
64
69
  await mkdir(dirname(dest), { recursive: true });
65
70
  const temp = `${dest}.agentwheel-tmp-${process.pid}-${Date.now()}`;
@@ -67,7 +72,7 @@ async function atomicCopy(source, dest, kind) {
67
72
  if (kind === "file") {
68
73
  await copyFile(source, temp);
69
74
  } else {
70
- await cp(source, temp, { recursive: true, dereference: true });
75
+ await cp(source, temp, { recursive: true, dereference: true, filter: (path) => !isIgnoredGeneratedEntry(path.split(/[\\/]/).at(-1) ?? "") });
71
76
  }
72
77
  await rm(dest, { recursive: true, force: true });
73
78
  await rename(temp, dest);
@@ -104,6 +109,7 @@ function resolveLocalPath(source) {
104
109
  export {
105
110
  pathExists,
106
111
  hashPath,
112
+ isIgnoredGeneratedEntry,
107
113
  atomicCopy,
108
114
  writeJsonAtomic,
109
115
  inferSourceDriverName,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  inferSourceDriverName,
4
4
  isExplicitSource
5
- } from "./chunk-N2LZY7LO.js";
5
+ } from "./chunk-B3FMBTWC.js";
6
6
  export {
7
7
  inferSourceDriverName,
8
8
  isExplicitSource