feat(init): --adopt flow detects + mirrors existing gates (closes #97)#101
Conversation
Implements #97. `klasp init --adopt --mode <mode>` detects existing quality gates (pre-commit framework, Husky, Lefthook, plain .git/hooks, lint-staged) and either prints a plan (inspect), writes a mirroring klasp.toml (mirror), or rejects with a clear "not yet supported" message (chain). - Adds non-destructive detectors for each supported gate. Hook configs are NEVER modified by mirror mode (per AC #3). - Generated klasp.toml is round-trip validated via ConfigV1::parse before write. - klasp doctor now flags `pre-commit` PATH gaps for adopted checks. - 10 integration tests + ~70 unit tests cover all 9 acceptance criteria. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fix duplicate `.pre-commit-config.yaml` filename in detector list (was listed twice instead of `.yaml`/`.yml`). Tighten generic "verify everything is healthy" → "verify each adopted binary is on PATH" so the final step's purpose is concrete. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- drop dead code (ChainSupport::AutoSafe, GateDetector trait, DetectedGate.confidence) - tighten types (TriggerKind, HookStage enums; timeout_secs becomes u64) - extract fs_util::atomic_write_text shared between init + writer - dedup detector helpers (first_existing_file, hook_to_trigger, package_json_has_lint_staged) - replace TOCTOU is_file()-then-read with NotFound-matched read - drop narrating comment + hardcoded --mode mirror in writer header Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Code reviewSummaryPR #101 adds After the simplify pass ( Reviewed against Critical issues
Suggestions
What looks good
Verdict🟡 OK to merge with follow-ups filed. Both suggestions are correctness gaps in detector edge cases, not blockers — mirror mode runs ALONGSIDE the human gate, so silent under-mirroring degrades to "klasp covers a subset of human gate checks" rather than producing wrong output. File two follow-up issues for the husky multi-line and managed-marker tightening; merge this PR; address in a follow-up that can carry tests for the realistic-input cases neither detector currently exercises. |
- detect_husky: emit one ProposedCheck per substantive line; multi-line hook bodies no longer silently drop trailing commands. Add multi-command tests in unit + integration suites. - detect_plain_hooks: tighten MANAGED_MARKERS from bare "husky"/"lefthook" substrings to "husky.sh" and "lefthook run" (the actual generator-line patterns Husky/Lefthook write). Adds tests for user-comment false- positive + husky-named-tool false-attribution cases. Addresses code-review suggestions in PR #101 comment 4404947676. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI clippy + fmt failed on the prior fix commit. Apply `cargo fmt --all` across the adopt module + test fixtures, and tag the planned `GateType:: Tooling` variant with `#[allow(dead_code)]` (reserved for future stack- detection work; no detector emits it in v1). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review remediationBoth code-review suggestions addressed inline. No follow-up issues filed — fixed in this PR.
CI fmt + clippy enforcement that the local
|
- README.md: replace 3-command quickstart with `klasp setup`; add v0.4.0 callout near top; mark #97 + #103 as shipped in feature table; link docs/setup.md from quickstart and Documentation sections; keep 3-command flow as "scriptable / CI" sub-section. - docs/recipes.md: add `klasp setup` as canonical first-run section above per-tool recipes; reference docs/setup.md; update version header to include v0.4. - docs/roadmap.md: update status blurb to 2026-05-08; add v0.4.0 section with shipped deliverables for #97 (PR #101) and #103 (PR #104). - docs/adopt.md: add Agent narrowing section reflecting that [gate].agents now defaults to detected agents (not 3-agent default); update example session Next: block accordingly; link to docs/setup.md. - Cargo.toml + npm/pypi manifests: bump all versions to 0.4.0. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
klasp init --adopt --mode <inspect|mirror|chain>flow that detects existing quality gates (pre-commit framework, Husky, Lefthook, plain.git/hooks, lint-staged) and proposes aklasp.tomlmirroring theminspectprints the plan only;mirrorwrites a round-trip-validatedklasp.tomlwithout touching any hook config;chainis explicitly rejected in v1 with a follow-up message pointing at manual integration instructionsklasp doctornow surfaces missingpre-commiton PATH for adopted checks (issue First-run gate adoption: detect and mirror existing pre-commit/Husky/Lefthook setups #97 AC W5 release workflow: reintroduce x86_64-apple-darwin (macos-13) for tag-push artefact builds #9)Acceptance criteria coverage
All 9 AC items from #97 covered with integration tests in
klasp/tests/init_adopt.rs:--mode inspectprints plan, writes nothing--mode mirrorwrites klasp.toml without modifying user config.git/hooks,.husky/,lefthook.yml,.pre-commit-config.yaml--mode chainrejected with explanatory message (exit 2)type = "pre_commit"lint-stagedcommand via lockfile sniffrun:shell checks.git/hooksnever overwritten by defaultklasp doctorsurfaces missingpre-commiton PATHArchitecture
klasp/src/adopt/plan.rs— sharedAdoptionPlan/DetectedGateAPIklasp/src/adopt/detect_*.rs— one detector per gate type, all returningio::Result<Vec<DetectedGate>>klasp/src/adopt/render.rs— plan formatter (matches issue's example output)klasp/src/adopt/writer.rs— atomic klasp.toml generator with round-trip parse validationklasp/src/adopt/mode.rs— chain-mode rejection messagedocs/adopt.md— user-facing docTest plan
cargo build --workspaceclean (4 dead-code warnings only —ChainSupport::AutoSafeandGateDetectortrait reserved for chain-mode future work)cargo test --workspace: 647 passed, 6 ignored, 0 failedinit_adopt.rscover all ACs🤖 Generated with Claude Code