All notable changes to @dotbabel/dotbabel land here. Format follows
Keep a Changelog, versioning follows
SemVer.
Historical entries below v2.0.0 reference the legacy package name
@dotclaude/dotclaude and the legacy plugins/dotclaude/ path — these are
preserved verbatim because they describe state at the time of release.
dotclaude to dotbabel to position the
toolkit as model-agnostic governance for any agentic CLI (Claude Code,
Codex, Gemini, Copilot).
@dotclaude/dotclaude → @dotbabel/dotbabeldotclaude-* → dotbabel-*$id host: dotclaude.dev → dotbabel.devplugins/dotclaude/ → plugins/dotbabel/dotclaude-core → dotbabel-core, dotclaude-agents → dotbabel-agents~/.config/dotbabel/~/.cache/dotbabel/DOTBABEL_* (12 vars; see Migration below)A read-fallback compatibility layer keeps v1.x setups working through the 2.x release window. All compat shims are removed in 3.0.0.
~/.config/dotclaude/ and ~/.cache/dotclaude/ are still honored when
the canonical paths are absent. A one-time process.emitWarning with code
DOTBABEL_LEGACY_CONFIG (or _CACHE) fires per process on fallback.DOTCLAUDE_* env vars fall back when the corresponding DOTBABEL_*
is unset. A one-time warning with code DOTBABEL_LEGACY_ENV fires per
process per variable.<configDir>/handoff.env) is now written
with export DOTBABEL_HANDOFF_REPO=....To migrate cleanly:
npm install -g @dotbabel/dotbabel (uninstall @dotclaude/dotclaude if needed).dotbabel bootstrap to update ~/.claude/ symlinks.DOTCLAUDE_* env vars in your shell rc files to DOTBABEL_*.mv ~/.config/dotclaude ~/.config/dotbabel to silence the
DOTBABEL_LEGACY_CONFIG warning.See docs/upgrade-guide.md for the full migration walkthrough.
--from value (#147) (#154) (c02c13e)pull -o <path> stdout contract per §5.5.1 OPS-2 (#148) (#154) (c02c13e)pull requires explicit <query> per spec §5.2.1. Previous versions silently defaulted to latest when the positional was omitted, which contradicted the spec. The fix removes the implicit default; users who relied on bare dotclaude handoff pull as shorthand must now type dotclaude handoff pull latest. Narrowing behavior of pull latest (host detection via env vars + --from) is unchanged. (#152) (#154) (c02c13e)The v1.0 stable cut of @dotclaude/dotclaude. Locks the handoff v2
surface, fixes the busybox/Alpine substrate crash, formalizes spec
templates that the v0.11.0 binary already implemented, and adds a CI
gate that prevents the release-pipeline drift behind #133/#134.
See docs/migrations/v1.0.md for the full verb-rename mapping and migration examples.
handoff: verb-rename surface redesign (#87, lands in this release). The pre-v1 pull verb (which fetched from the remote) and --to <cli> flag are gone. --from <cli> is now mandatory whenever the verb cannot infer the producing CLI from the input. Per spec §6.5 migration table:
| Before (≤0.10.x) | After (v1.0) |
|---|---|
dotclaude handoff pull <id> |
dotclaude handoff fetch <id> |
dotclaude handoff pull <id> --to claude |
dotclaude handoff fetch <id> (consumer CLI is implicit) |
dotclaude handoff push <id> |
dotclaude handoff push <id> (unchanged when <id> given) |
dotclaude handoff push --from <cli> |
unchanged; --from required when <id> is omitted |
| (no equivalent) | dotclaude handoff pull <id> — render a local session |
pull is now strictly local — it renders a local session as a
<handoff> block, summary markdown (--summary), or a file
(-o <path>). fetch is the remote-transport verb. --to is
removed; the consumer CLI is always implicit (it’s the one running
the binary).
pull <id> local rendering with --summary and -o <path|auto|-> modes (#87). Stream isolation per spec §5.5.1 OPS-2: <handoff>/summary/path on stdout, progress on stderr.prune --older-than <30d|6m|1y|YYYY-MM-DD> for transport cleanup, with --dry-run and --yes.--tag <label> (multi-valued on push, single-value filter on list --remote --tag) and list --remote --tags histogram.--verify forces re-run. doctor verb unchanged.<handoff> block surfaces source CLI’s customTitle / thread_name when present; resolver accepts named aliases on codex..github/workflows/release-gate.yml enforces version-tag alignment on every PR to main and runs the published-tarball-vs-source diff on release PRs (#134).docs/migrations/v1.0.md migration guide; spec §5.3.2 amended to formalize the narrowed no <cli> session matches form when --from is set.pick_newest() no longer crashes on busybox/Alpine. The runtime || fallback chain (find -printf → stat -f → stat -c) is replaced by a single probe at script init that detects GNU/BSD/posix substrates and selects one deterministic path. Fixed in #139.dotclaude-handoff: handoff-resolve: .... Fixed in #140 — the resolver script’s prefix is stripped before the binary’s own prefix is added.js-yaml is now lazy-loaded inside build-index.mjs. dotclaude handoff --help and other handoff commands no longer require js-yaml to be installed. Fixed in #140.handoff #131 — system requirements (out of scope: sh-only environments). The handoff toolchain requires bash 4+, jq 1.6+, perl 5.x, git 2.x, and GNU coreutils on the path. POSIX sh-only environments (e.g. minimal Alpine without bash installed) are unsupported. Substrate detection at script init handles GNU vs BSD vs busybox coreutils transparently as long as bash is present. See docs/handoff-guide.md.
handoff #132 — known property: branch namespace is host-agnostic. Handoff branches are named handoff/<project>/<cli>/<YYYY-MM>/<short-uuid> (no hostname segment). If you fetch a session on machine A, edit it locally, then push from machine B against the same short-uuid, the second push overwrites the first. The short-uuid collision check (metadata.json:hostname) detects cross-host overwrites and exits 2 unless --force-collision is set, but the branch namespace itself is host-agnostic by design. See docs/handoff-guide.md.
handoff CP-1 — Copilot slash-handler does not pass --summary / -o flags through. /handoff pull latest --summary and /handoff pull latest -o <path> exit 64 inside the Copilot CLI before the binary is invoked (the Copilot slash parser strips flag-prefixed arguments). Mitigation: invoke the bare binary, e.g. !dotclaude handoff pull latest --summary. The Claude Code and Codex slash paths are unaffected.
handoff CX-1 — progress messages go to stderr per spec §5.5.1 OPS-2. When capturing the first line of pull <id> output (e.g. inside the Codex !-shell which displays the interleaved combined stream), redirect stderr explicitly: dotclaude handoff pull <id> 2>/dev/null | head -1. The <handoff> block, summary markdown, and -o-target path are stdout; the latest <cli> session: <id> and using --from <cli> override lines are stderr.
dotclaude handoff push now requires a one-time dotclaude handoff init against $DOTCLAUDE_HANDOFF_REPO. Existing v1 branches remain readable; writes always emit the new v2 shape. Migrate script lands as a follow-up (plan PR C). Migration is one command: dotclaude handoff init.--via github, --via gist-token, --via git-fallback, DOTCLAUDE_GH_TOKEN, and the references/transport-github.md file are removed. Migration is s/ --via git-fallback//g across any script that called dotclaude handoff push|pull --via git-fallback; gist users move to a private git repo (gh repo create handoff-store --private + export DOTCLAUDE_HANDOFF_REPO=git@github.com:<user>/handoff-store.git) and delete leftover gists with gh gist list + gh gist delete <id>.push <cli> <query> and pull <cli> <handle> now exit 64 with a migration message pointing at --from. Power-user subs (resolve/describe/digest/file) keep their explicit <cli> <id>.handoff push/pull: the <cli> positional is removed. The
resolver already auto-detects across all three roots (claude,
copilot, codex); forcing the user to state the source CLI was
busywork. Migration:
dotclaude-handoff push claude <q> → dotclaude-handoff push <q>
(or ... push <q> --from claude to force a root).dotclaude-handoff pull claude <h> → dotclaude-handoff pull <h>
(or ... pull <h> --from claude).resolve, describe, digest, file) keep
their explicit <cli> <id> — scripting entry points unchanged.The binary now exits 64 on the removed form with an actionable
message pointing at --from and this CHANGELOG. Bare
dotclaude-handoff (no positionals) now executes push (host’s
latest session), aligning the binary with SKILL.md’s five-form
surface. Help still lives behind --help.
--from <cli> flag on push / pull / bare <query>.
Narrows auto-detection to a single root. Useful for scripting and
for resolving short-UUID collisions across roots.detectHost() env-probe routing. The binary best-effort
identifies the agentic CLI it is running inside via CLAUDECODE,
CLAUDE_CODE_SSE_PORT, and CODEX_* / COPILOT_* / GITHUB_COPILOT_*
prefix scans. All signals are labelled UNCONFIRMED in the source —
false positives are cheap (a narrower resolve) and false negatives
fall back to the union resolver.push (no query) now prints
one stderr line naming which fallback fired:
no current-session signal in <cli>, using latest <cli> session: <short>
— host was detected, narrowed to its root.using --from <cli> override, latest session: <short> — --from
was explicit, host was not detected or differed.host not detected, using latest across all clis: <short> —
union-resolver fallback.--to default is the detected host. Previously hardcoded to
claude; now matches whichever CLI the binary is running inside
(falling back to claude when undetected).No breaking changes. This release adds cross-machine session handoff via GitHub
Gists, a docker-engineer agent, a curl-pipe-bash installer, and a refactored
agent build pipeline.
/handoff push, pull, remote-list,
and doctor sub-commands let a session started on one machine (Windows/WSL)
be resumed on another (PopOS / macOS / CI). Default transport uses
gh gist; --via gist-token (curl + PAT) and --via git-fallback (raw
git) are documented workarounds for hosts where gh is unavailable or
blocked. Includes a push-side secret-scrubbing pass covering eight token
patterns, a handoff-doctor.sh preflight with per-transport remediation
blocks, and 80 bats unit tests plus an e2e gist round-trip harness (#46,
#49).docker-engineer agent — Compose orchestration and runtime ops; covers
multi-service health, volume binding, network bridge configuration, and
registry operations (#47).curl -sSL .../install.sh | bash path for
users who prefer not to use npm. Idempotent; respects NO_COLOR (#44).No breaking changes. This release adds the global-lifecycle CLI
(dotclaude bootstrap, dotclaude sync), first-class agents, the
taxonomy pipeline (schemas → backfill → search/list/show → build-plugin),
and a broad set of provider and IaC agents.
dotclaude bootstrap (set up or refresh
~/.claude/) and dotclaude sync <pull|status|push> (update an
installation). Both are idempotent, support --json / --quiet
/ --no-color, and are registered as subcommands of the umbrella
dotclaude dispatcher alongside the taxonomy commands (#29).kubernetes-specialist skill (#31).*-specialist skills (#32).*-specialist skills (#33).data-scientist, compliance-auditor,
and the veracity-audit skill (#41).dotclaude search, dotclaude list, dotclaude show
build-plugin script + generated plugin templates (#38)./review-pr (#22) and /create-inspection
(#23), plus strengthened branch-health gates and mandatory test plans
in /review-pr (#25).npm run lint now wires prettier and
markdownlint-cli2 (#18).bootstrap / sync
subcommands (#30).dotclaude-agents spec registered; .gitignore cleaned up (#39).actions/upload-artifact 4.6.2 → 7.0.1 (#13).bootstrap now links hooks/ into ~/.claude/hooks/ so
guard-destructive-git and friends apply globally (#35).js-yaml prototype pollution (GHSA-mh29-5h37-fv8m) (#27).PR_ACTOR (derived from PR author)
instead of the GITHUB_ACTOR builtin, restoring correct bot
detection (#20, #21).@kaiohenricunha/harness → @dotclaude/dotclaude.
Update your package.json dependency and all imports.harness-* → dotclaude-* (e.g. harness-doctor
→ dotclaude-doctor). Update CI workflows, pre-commit hooks, and any scripts
that invoke them directly.HARNESS_DEBUG → DOTCLAUDE_DEBUG,
HARNESS_JSON → DOTCLAUDE_JSON, HARNESS_REPO_ROOT → DOTCLAUDE_REPO_ROOT.
Note: HARNESS_CHANGED_FILES (CI diff input) and HARNESS_SYNC_SKIP_SECRET_SCAN
(sync.sh bypass) are not renamed — they remain HARNESS_*.plugins/harness/ → plugins/dotclaude/
(affects deep imports — use the public barrel @dotclaude/dotclaude instead).harness-core → dotclaude-core (update Spec ID: lines in PR
bodies and any depends_on_specs references).@kaiohenricunha to @dotclaude — published under
the public dotclaude npm org.First public release targeting npm publish --provenance --access public.
Productizes the plugin: public Node API barrel, structured-error contract,
umbrella CLI, shell hardening, full bats + vitest coverage, dogfood wiring,
and the docs set consumers need to adopt.
plugins/dotclaude/src/index.mjs — 24+ named exports
covering every validator + ValidationError + EXIT_CODES + version.plugins/dotclaude/src/lib/errors.mjs): every
validator emits ValidationError instances with stable .code, .file,
.pointer, .expected, .got, .hint, .category. Enumerated codes
(SPEC_STATUS_INVALID, MANIFEST_CHECKSUM_MISMATCH,
COVERAGE_UNCOVERED, DRIFT_TEAM_COUNT, …) are a stable contract —
renames are breaking.EXIT_CODES ({OK:0, VALIDATION:1, ENV:2, USAGE:64}) consumed
by every bin. 64 mirrors BSD sysexits.h EX_USAGE.dotclaude CLI that dispatches to subcommands:
harness validate-specs|validate-skills|check-spec-coverage|check-instruction-drift|detect-drift|doctor|init.
Every bin also exists as a standalone — dotclaude-doctor, dotclaude-init,
etc.dotclaude-doctor — runs through env, repo, facts, manifest, specs,
drift, and hook checks and reports ✓/✗/⚠ with exit 0/1/2.dotclaude-detect-drift — wraps plugins/dotclaude/scripts/detect-branch-drift.mjs
so npx dotclaude-detect-drift resolves. Fixes the broken
plugins/dotclaude/templates/workflows/detect-drift.yml:15 invocation.--help, --version, --json,
--verbose, --no-color, plus bin-specific flags (--update,
--project-name, --force, --target-dir, …).--json output on every bin and on validate-settings.sh, suitable
for jq -r '.events[] | …' CI pipelines.set -euo pipefail across every shipped shell script; ✓/✗/⚠ helpers
factored into plugins/dotclaude/scripts/lib/output.sh and mirrored in
src/lib/output.mjs.guard-destructive-git.sh — normalizes tab whitespace,
boundary-anchors git tokens, adds blocks for git branch -D and
git worktree remove --force, and exposes BYPASS_DESTRUCTIVE_GIT=1
bypass. Exit 2 preserved per Claude Code PreToolUse protocol.bootstrap.sh --quiet + --help plus a trailing
run 'dotclaude-doctor' to verify install hint when the bin is on PATH.sync.sh secret scan — literal _KEY / _TOKEN / _SECRET + AWS
keys + bearer tokens are refused at push time.
HARNESS_SYNC_SKIP_SECRET_SCAN=1 is the documented escape hatch.plugins/dotclaude/tests/bats/ (34 tests) covering every
hardened shell surface.vitest run --coverage enforces lines 85 /
functions 85 / branches 80 / statements 85 via vitest.config.mjs.examples/minimal-consumer/ — committed post-dotclaude-init scaffold..claude/{settings,skills-manifest}.json,
docs/repo-facts.json, docs/specs/dotclaude-core/{spec.json,spec.md}.
Every validator exits 0 against the root (see npm run dogfood).LICENSE, CHANGELOG.md (this file), CONTRIBUTING.md,
CODE_OF_CONDUCT.md, docs/{index,quickstart,cli-reference,api-reference,architecture,personas,troubleshooting,upgrade-guide}.md,
docs/adr/, plugins/dotclaude/templates/README.md. README.md and
plugins/dotclaude/README.md rewritten for consumer clarity..claude/commands/*.md) get YAML frontmatter matching the
skills/*/SKILL.md schema.plugins/dotclaude/src/*.mjs are no
longer a supported contract. Use the barrel import.package.json — "main" now points at the real barrel; "exports"
field added; three new "bin" entries; "files" covers
plugins/dotclaude/scripts/ so refresh-worktrees.sh,
detect-branch-drift.mjs, and auto-update-manifest.mjs ship in the
tarball; version bumped to 0.2.0.ValidationError instances, not strings. Existing
CI pipelines that grep stderr continue to work because
ValidationError.prototype.toString() preserves the
"<file>: <message>" format; pipelines that consume --json get the
structured payload.import { … } from "@dotclaude/dotclaude/src/validate-specs.mjs")
are no longer a supported contract — use the barrel.Retroactive entry. Initial plugin skeleton: spec-harness library, five
validators, template tree, hook, and test_validate_settings.sh. Never
published to npm — the first published version is 0.2.0.
dotclaude upgrade subcommand to migrate consumer repos across versions..d.ts shipping for stronger type inference (via hand-authored declarations
— TypeScript migration is out of scope per ADR-0002).