AIWG 2026.6.4 — "Project-local deploy parity + safer `aiwg remove`"
AIWG 2026.6.4 — "Project-local deploy parity + safer `aiwg remove`"
Released: 2026-06-21 Channel: stable (`npm install -g aiwg`)
A correctness cut. Project-local extension/addon bundles now deploy to every provider the same way they always did for Claude; `aiwg remove` fails cleanly instead of crashing; and the kernel-skill prune can no longer wipe your skills directory when it can't locate the AIWG root. The npm-publish pipeline is also hardened so a single failing step no longer strands the `@next` channel.
No change to the base footprint — `npm i -g aiwg` installs the same surface.
Highlights
| What changed | Why you care |
|---|---|
| Project-local bundles deploy to Factory & Codex | A `.aiwg/extensions/<id>/` bundle with `agents/` or `rules/` now lands in `.factory/droids` + `.factory/rules` and `.codex/agents` + `.codex/rules` — not just `.claude/`. |
| `AIWG_ROOT` no longer required for project-local agent bundles | Deploying an agent-shadowing bundle without `AIWG_ROOT` no longer empties your provider's kernel skill directory. |
| `aiwg remove` fails cleanly | No more `path argument must be of type string` TypeError. Clear errors and exit codes instead. |
| `@next` channel can't be stranded | A partial publish failure no longer leaves the prerelease channel behind. |
Fixes
Project-local bundles deploy on Factory and Codex (#124)
`tools/agents/providers/claude.mjs` has long detected when `--source` points at a project-local bundle (`agents/`, `commands/`, `skills/`, or `rules/` directly under the source root) and deployed those artifacts. `factory.mjs` and `codex.mjs` lacked that `isAddonSource` short-circuit, so project-local extension/addon bundles silently deployed 0 agents and 0 rules to Factory and Codex — they only scanned the `agentic/code/{frameworks,addons}` tree, which doesn't exist inside a project-local bundle.
Both providers now carry the same check:
mkdir -p .aiwg/extensions/my-bundle/agents .aiwg/extensions/my-bundle/rules
# … add an agent + a rule + a manifest …
aiwg use my-bundle
# Before: Factory/Codex → "Deploying 0 agents…", "Deploying 0 rules…"
# After: agent → .factory/droids/, .codex/agents/
# rule → .factory/rules/, .codex/rules/
(Codex resolves commands and skills from `srcRoot` inside their own deploy steps, so only agents and rules needed the explicit handling there.)
Kernel-skill prune is null-safe (#123)
Deploying a project-local agent-shadowing bundle without `AIWG_ROOT` set could empty the provider's kernel skill directory (e.g. `.claude/skills/`). `computeAllKernelNames` walked up from the bundle path, found no `agentic/code/{frameworks,addons}` tree, returned an empty desired set, and `pruneStaleAiwgSkills` deleted every AIWG-managed kernel skill.
Two-part fix:
1. The `use` CLI now injects `AIWG_ROOT` (the resolved install root) into the project-local deploy subprocess, so the desired-kernel set resolves correctly even though `--source` is the bundle path. 2. `computeAllKernelNames` now validates `AIWG_ROOT` and returns `null` when no AIWG tree is locatable; `pruneStaleAiwgSkills` skips on `null` — mirroring the `computeAllArtifactBasenames` contract (#1627). `hermes.mjs` guards the null before spreading.
Setting `AIWG_ROOT` is still honored, but is no longer required for project-local agent bundles.
`aiwg remove` no longer crashes (#118)
`aiwg remove all --provider factory` (and `aiwg remove <unknown-id>`) crashed with `Error: The "path" argument must be of type string. Received an instance of Object` before doing any work. The plugin-uninstaller CLI was calling `new PluginUninstaller({ dryRun, force, keepData })`, but the constructor takes `(aiwgRoot: string)` — so `path.join(<options-object>, 'registry.json')` threw immediately. The collected options were also never forwarded to `uninstall()`, and the result handler read fields that don't exist.
The CLI now:
- constructs via `createUninstaller()` (resolves the AIWG root correctly);
- forwards `{ force, dryRun, keepProjects }` to `uninstall()`;
- reports from `result.errors` / `result.stats`;
- rejects unknown flags (including `--provider`) with a clear message + exit 2.
Behavior now:
aiwg remove all --provider factory # → clear "--provider only for project-local/user-scope" error (handled at the TS layer, #1610)
aiwg uninstall-plugin all --provider # → "Error: unknown flag --provider" (exit 2)
aiwg remove all # → "Plugin 'all' is not installed" (exit 1) — no TypeError
CI / release pipeline
- `@next` advances even when an earlier publish step fails, so a partial
failure no longer strands the prerelease channel.
- `@aiwg/cockpit` publishes from `./apps/cockpit` rather than via
`npm --prefix`.
- The Gitea publish workflow is scoped to the Gitea npm registry only.
Upgrade
npm install -g aiwg # 2026.6.4
aiwg version # → 2026.6.4 [stable]
No action required. If you previously set `AIWG_ROOT` solely to protect your kernel skills directory when deploying project-local agent bundles, that workaround is no longer necessary.
Links
- Changelog: `CHANGELOG.md`
- Project-local bundles: `docs/customization/project-local-quickstart.md`
- CLI reference (`aiwg remove`): `docs/cli-reference.md`