feat!: tbd v0.2.2 + agent-skill onboarding (dual-scope install, @latest runner, supply-chain docs)#52
Conversation
Run `tbd setup --auto` with get-tbd@0.2.2 to refresh the project's tbd integration: - Migrate .tbd/config.yml format f03 -> f04 (adds sync.storage: git-common-dir-v1, refreshes docs_cache entries) - Add .tbd/.gitattributes to protect ID mappings from merge deletion - Refresh portable Agent Skill (.agents/skills/tbd/SKILL.md) - Refresh AGENTS.md tbd integration block (format=f04) - Install Codex surface hooks (.codex/) https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Align repren's agent-skill installation with the cli-agent-skill-patterns
guideline. repren is a general-purpose utility with no per-project config,
so it stays a dual-scope (project or global) skill invoked via a pinned
zero-install uvx runner — no need to add it as a project dependency.
Changes:
- install_skill now writes both the portable cross-agent surface
(.agents/skills/repren/) and the Claude Code mirror (.claude/skills/repren/),
under $HOME (global) or a project root (--agent-base). --agent-base still
accepts a legacy .claude/.agents path (its parent is used as the root).
- SKILL.md is now a template: {{REPREN_VERSION}} is rendered to the installed
public version at install time, replacing the unpinned `uvx repren@latest`
with a pinned `uvx repren@<version>` fallback (supply-chain hygiene). Examples
are local-first (`repren ...`) with the pinned uvx runner documented as the
no-install fallback. Local PEP 440 "+..." segments are dropped from the pin.
- Updated docstring, README, CLI help, and fallback messages accordingly.
- Tests: cover both surfaces, version pinning, and absence of @latest; golden
A6 made version-independent.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
…g-style) BREAKING CHANGE: replace `--install-skill --agent-base DIR` with explicit `--project` / `--global` scope flags, following the cli-agent-skill-patterns §6.6.2 model for dual-scope tools. repren carries no per-project config, so it is a dual-scope skill (project or global), and scope is now resolved like `git config`: implicit when unambiguous, a hard error when not. - New flags on --install-skill: --project, --global, --dir DIR, --no-repo-check. - Inside a git repo, scope is implicitly --project. In an ambiguous location (home dir, filesystem root, or outside any repo) repren refuses before writing and names the flag to pass, instead of silently writing global agent surfaces. - --project always refuses $HOME (that is what --global is for); the resolved target is printed before writing so a wrong scope can be cancelled. - Both surfaces (.agents/skills/repren/ and .claude/skills/repren/) are still written under the resolved root. - claude_skill exposes resolve_install_target() + SkillScopeError for testing; install_skill() now takes project/global_install/dir/no_repo_check. Migration: `--install-skill` (old global default) -> `--install-skill --global`; `--install-skill --agent-base=./.claude` -> `--install-skill --project` (run from the repo) or `--install-skill --project --dir PATH`. To be noted in release notes. Updated docstring, README, CLI help, tests (scope-resolution unit tests + golden A6/A7), and the golden coverage gate. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Make skill installation instantly discoverable, so an agent pointed at
`uvx repren@<version> --help` can install repren as a skill with no other docs.
- Add an IMPORTANT skill-install callout to `repren --help` and `--docs`
(the §6.5 "discoverable help" practice): names the exact `--install-skill`
commands for project and global scope.
- README now leads with a one-line instruction anyone can hand to their agent
("Run `uvx repren@2.1.0 --help` and follow the instructions to install repren
as a skill"), and the Agent Use section is reorganized to lead with that
one-liner, then explain how it works.
- Drop the last unpinned `@latest` from the docs in favor of a pinned
`uvx repren@<version>`.
- Golden test H5 locks in that `--help` shows the install instructions.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Make the pinned repren version in the docs maintainable, and prominently note
repren's zero runtime dependencies as a security/simplicity advantage.
Version generation (so version strings are never hand-edited):
- gendocs.py now substitutes a {{REPREN_VERSION}} placeholder in the manual and
normalizes the hand-written README header, pinning docs to a single resolved
version: REPREN_DOCS_VERSION env override -> installed clean-release version ->
DEFAULT_DOC_VERSION fallback. Idempotent across runs.
Content (docs/repren-docs.md is the source of truth, synced into the docstring
and README by gendocs):
- Lead the intro and Agent Use with the agent one-liner
("Run `uvx repren@<version> --help` and follow the instructions to install ...").
- Prominently document ZERO runtime dependencies (vs dev-only tooling), adapting
the supply-chain notes from jlevy/strif: no transitive tree to audit/compromise,
single file you can review.
- Add a pinning/supply-chain note: examples pin an explicit version rather than
@latest (uv applies no cool-off by default); document UV_EXCLUDE_NEWER as the
opt-in "always-latest but cooled" alternative.
- Refresh install commands to the --project/--global scope flags.
Tests: cover get_doc_version (env override, dev fallback), _is_clean_release,
render_version, header-pin idempotency, and that generated docs contain no raw
placeholder.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Per project decision: the README/manual install instructions use the simpler `uvx repren@latest`, leaning on repren's zero runtime dependencies (no transitive attack surface) plus a documented cool-off option for safety. This aligns with the guidelines, which pin the *skill's* runner but allow human prose to use @latest. - Human-facing docs (README header, intro, Installation, Agent Use) now use `uvx repren@latest`. - Reframe the supply-chain note around @latest: zero deps keep the risk small; document `UV_EXCLUDE_NEWER` cool-off and an explicit pin as opt-in hardening. - Clarify that the installed SKILL.md still pins the exact version it was generated from (reproducible agent invocations) even though the human quick-start uses @latest — this pinning is handled at install time in claude_skill.py. - Revert the now-unneeded version-injection in gendocs.py (no placeholder in human docs) and its tests. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Strengthen SKILL.md so agents understand repren's benefits and reach for it on large-scale renames instead of hand-editing file by file or scripting sed/perl loops. - Rewrite the `description` frontmatter (the agent's trigger) to position repren as the preferred tool for multi-file renames/search-replace, naming the differentiating features: combined content+filename changes, simultaneous/swap replacements, case-variant awareness, and dry-run/backups/undo. - Add a "Prefer Repren for Bulk Renames" section spelling out each benefit and when it wins over manual edits or sed/perl/awk. - Frame "When to Use Repren" as the default choice. - Update the two tryscript goldens that snapshot the description line. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Switch the skill runner to @latest and remove the version-injection machinery, relying on uv's release cool-off for protection — repren has zero runtime dependencies, so the only code a runner fetches is repren itself, which makes @latest a documented exception to the "pin zero-install runners" rule. - SKILL.md / claude_skill.py: invoke `uvx repren@latest`; drop the {{REPREN_VERSION}} placeholder, _pinned_version(), and _render_skill(). get_skill_content() now just reads the file. Update the matching unit test and tryscript golden (which now assert @latest is used and the placeholder never leaks). - docs: reframe the manual's "how it works" around @latest + UV_EXCLUDE_NEWER cool-off. - Add SUPPLY-CHAIN-SECURITY.md (the portable hardening flag file) per the supply-chain hardening guideline: runtime risk is minimal here (zero deps), but the 14-day cool-off, lockfile discipline, and audit rules still apply to the dev dependency toolchain. Reference it from AGENTS.md (CLAUDE.md symlinks to it) so agents see it before adding deps. - Clarify in SKILL.md and the manual that repren does not read .gitignore: dotfiles (incl. .git/) are excluded by default; richer scoping needs explicit --include/--exclude. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
An agent that discovers repren via `uvx repren@latest --help` has no `repren` on PATH, so the install hint now shows the zero-install form alongside the on-PATH one. This closes the discoverability loop: point an agent at the repo, it runs the suggested uvx call, and the help epilog hands it the exact command to install repren as a skill. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
PR #52 Review NotesReview target: #52 SummaryThis is a strong direction overall: the dual-surface skill install and Issues
Documentation / Spec Sync
Existing CommentsNo existing PR comments or unresolved review threads were present when I checked. CI / Verification
|
…chain doc Address PR review findings: - [P1] resolve_install_target now installs at the git repository root for implicit and bare --project scope, instead of whatever subdirectory the command ran from. An explicit --dir still wins as given. Add a _git_root() helper (matches .git as dir or file, so worktrees/submodules work) and a nested-dir CLI + unit regression test. - [P2] Make the scope-resolution unit tests portable: compare against resolved paths (home.resolve(), tmp_path.resolve()) so they pass on macOS, where /home and /tmp canonicalize. docs/development.md tells contributors to run `uv run pytest`. - [P2] SUPPLY-CHAIN-SECURITY.md no longer over-claims full compliance: it now "adopts" the policy and records the unpinned zero-install dev/CI runners (uvx flowmark@latest, npx tryscript@latest) as tracked exceptions to pin in a follow-up. The skill's `uvx repren@latest` runner is intentionally unpinned (zero runtime deps + documented UV_EXCLUDE_NEWER cool-off) and is recorded as a deliberate exception. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Expand the "Comparison to Alternatives" table with two researched, sourced rows: - Atomic file operations: repren and sd write content via temp-file + atomic rename; rnr only renames (atomic); sed/awk/perl varies (GNU sed and gawk inplace are atomic, perl -i only on >=5.28, a plain redirect never); fastmod/ast-grep/comby overwrite in place. - Agent skill support: repren ships a skill via --install-skill; ast-grep ships an official agent skill + MCP server; the others have no first-party agent integration. Add explanatory notes under the table and mention ast-grep's agent skill/MCP in its "when to use" bullet, so the comparison stays accurate (repren is not the only tool with agent integration). Regenerated README + docstring from the manual. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
…doc guidelines The skill module is generic across coding agents (Claude Code, Codex, Gemini, and others), so the Claude-specific name no longer fits. - Rename repren/claude_skill.py to repren/agent_skill.py (git rename) and update its imports, the internal --install-skill dest (install_claude_skill -> install_skill), and the module's own self-references. The CLI surface (--install-skill) is unchanged, and the module is internal, so no compatibility shim is needed. - Rewrite the test imports using repren itself. Apply common-doc-guidelines across the docs we own: minimize em dashes (prefer full stops, commas, colons, semicolons), and write "and" rather than "+" in prose. Covers the manual (docs/repren-docs.md), README header, SKILL.md, SUPPLY-CHAIN-SECURITY.md, the agent_skill.py docstring, and the --help SKILL_HINT. Regenerated README and the docstring from the manual; updated the matching help golden. The one remaining em dash is in the tbd-managed AGENTS.md block, which tbd regenerates. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
`repren --skill | head -3` made head close the pipe early; with the longer skill description, repren was still writing and Python surfaced a BrokenPipeError traceback, failing the H4 golden on CI. Behave like a standard Unix filter instead: reset SIGPIPE to its default disposition (POSIX), with a BrokenPipeError fallback for platforms without SIGPIPE. This also covers `repren --docs | head`, `repren --help | head`, etc. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Per the project Python rules, standard-library imports belong at module top, not inlined inside functions. Move `import signal` (repren.py) and `import argparse` (agent_skill.py) to the top-level import blocks. Also harden the SIGPIPE setup: guard `signal.signal()` with both `hasattr(signal, "SIGPIPE")` (Windows has no SIGPIPE) and a `ValueError` catch (signal.signal only works on the main thread, so embedding/off-thread callers degrade gracefully). The remaining inline imports are intentional and stay: the `override` backport behind a sys.version_info guard, the importlib.resources/pkg_resources version fallback, and the markdown_renderer/agent_skill imports wrapped in try/except ImportError so repren still runs when copied as a standalone single-file script. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Tags are unprefixed (2.0.0, 1.0.2, ...), so this release ships as 3.1.0. Point the "pin an exact version" example at it instead of the stale 2.0.0. Regenerated README and the docstring from the manual. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Per cli-agent-skill-patterns §6.4 ("route, don't restate") and §3.1 (progressive
disclosure), the skill body should name each use case and the one command that reaches
it, then point at the tool's own docs for the mechanics. The body had grown into a
near-copy of `repren --docs`: flag tables, pattern-file format, per-feature recipes, a
Notes section.
Cut it from ~260 to ~45 lines: keep the frontmatter description (the discovery/"when"
layer, unchanged), a tight when-to-use list with one command per intent, when-not-to-use,
and two safety/scoping reminders. Everything else routes to `repren --docs`, which the
agent reads when it actually uses the tool. This saves context on every activation and
removes drift between the skill and the CLI's own help.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Apply common-doc-guidelines (cut pompousness and meta-commentary; eliminate words that
add no information):
- Replace the "Using a coding agent?" / "The one thing to know" hooks with plain
factual leads ("Coding agents:", and a direct sentence in Agent Use).
- Tighten the intro zero-deps paragraph; drop "by design" and the "Amid the rise of
supply-chain attacks" framing.
- Condense the comparison-table footnote to a single line and drop the redundant
agent-skill gloss (the table and Agent Use section already make it clear).
- README header: drop the decorative emojis and marketing phrasing; state the two
callouts factually.
Regenerated README and the docstring from the manual.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Make the primary call to action stand out: bold the "Run uvx repren@latest --help ..." line in the block-quote callout (intro and Agent Use). Regenerated README and the docstring. https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz
Summary
This branch turns repren into a tool a coding agent can discover and adopt on its own,
and hardens how it's installed and documented. Point any agent at this repo (or paste the
suggested
uvxcall), and it learns — from repren's own--help— how to install reprenas a skill and then reaches for it automatically on bulk refactors. Along the way it
upgrades the tbd integration, reworks skill install to
git config-style scopes, settlesthe runner on
uvx repren@latest(leaning on repren's zero runtime dependencies plusuv's release cool-off), and documents the supply-chain stance.
The agent-onboarding loop (the headline)
uvx repren@latest --helpand follow the instructions to install repren as a skill." This is the first thing in
the README.
uvx repren@latest --helpruns repren with no prior install and ends with aninstall hint that shows the exact
uvx repren@latest --install-skillcommand (boththe on-PATH and zero-install forms), so the loop is self-consistent.
repren automatically for renames/refactors.
Changes
tbd integration
f03 → f04,.tbd/.gitattributes,refreshed portable Agent Skill + AGENTS.md block, Codex surface hooks).
tbd doctorhealthy.Skill install: reach + scope
install_skillwrites both surfaces: portable.agents/skills/repren/(Codex,Gemini, others) and the
.claude/skills/repren/mirror.git config— implicit when unambiguous, a hard error when not.New flags
--project/--global/--dir DIR/--no-repo-check; ambiguous targets(home, fs root, outside a repo) are refused before writing.
Runner:
uvx repren@latest+ cool-off (supply-chain)uvx repren@latest. Removed the{{REPREN_VERSION}}injection machinery (_pinned_version/_render_skill) — simpler.@latestfetchesonly repren itself; for extra margin, opt into uv's cool-off (
UV_EXCLUDE_NEWER).SUPPLY-CHAIN-SECURITY.md(the portable hardening flag file, pertbd guidelines supply-chain-hardening), referenced from AGENTS.md/CLAUDE.md: runtimerisk is minimal here, but the 14-day cool-off, lockfile discipline, and audit rules
still apply to the dev dependency toolchain.
Discoverability & docs
--helpsurfaces the skill install prominently.
renames, spelling out the wins: combined content+filename edits, simultaneous/swap
replacements, case-variant awareness, dry-run/backups/undo.
.gitignore; dotfiles (incl..git/) are excluded by default, and richer scoping needs explicit--include/--exclude.repren --install-skillscope handling changed. The--agent-base DIRflag is removed.uvx repren --install-skill(defaulted to global~/.claude)uvx repren@latest --install-skill --global(global must now be explicit)uvx repren --install-skill --agent-base=./.claudeuvx repren@latest --install-skill --project(run from the repo), or--project --dir PATHInside a git repo, scope is implicitly
--project; ambiguous locations are refusedbefore writing, so
cd ~ && repren --install-skillcan no longer silently rewrite yourglobal agent surfaces.
Test Plan
Automated (CI: Ubuntu × Python 3.10/3.11/3.12/3.13/3.14)
uv run python devtools/lint.py) ✅uv run pytest), incl. skill-content, scope-resolution,and CLI install tests ✅
--help/--docs/--skill, both install surfaces,--global, ambiguous-scoperefusal, replacements/renames/case/json) ✅
scripts/check-golden-coverage.sh) ✅gendocsidempotent —repren.pydocstring + README regenerate with no diff ✅Manual scenarios verified locally
uvx repren@latest --helpepilog shows bothrepren --install-skillanduvx repren@latest --install-skillforms (closes the onboarding loop)SKILL.mdcontainsuvx repren@latestand no{{REPREN_VERSION}}placeholder--install-skill --project --dirwrites both surfaces;--globalwrites under$HOME; outside-repo / home-dir targets are refused with an actionable message.git/);node_modules/is not auto-excluded(requires explicit
--exclude) — matches the new docsSuggested additional testing (not blocking)
and confirm it installs the skill and invokes repren unprompted on a rename task
UV_EXCLUDE_NEWERin the environment propagates to the skill'suvxcallsuv tool install repren(PATH install) so the non-uvxpath is coveredRelated Beads
None — tracked directly on this branch.
https://claude.ai/code/session_01RbwU9HuU5Ys84HVm94UdUz