Repository navigation
fix(init): fail closed on missing .claude dir and hoist OpenCode install (fixes #4046) - #4323
Conversation
- Add fs::create_dir_all for .claude dir in patch_settings_json_command and run_default_mode (fixes rtk-ai#2519, rtk-ai#4046 Windows regression) - Hoist OpenCode plugin installation before Unchanged early return in run_claude_md_mode_with - Fixes rtk-ai#4046 regressions.
📊 Automated PR Analysis
SummaryFixes three regressions around global Review Checklist
Analyzed automatically by wshm · This is an automated analysis, not a human review. |
The previous fix created the .claude directory unconditionally, but dry-run mode must not create directories. Only create the directory when not in dry-run mode. Fixes test: test_run_default_mode_dry_run_does_not_create_missing_claude_dir
- README.md: change --opencode description to 'Claude setup + OpenCode plugin' - supported-agents.md: clarify OpenCode installs Claude setup + plugin - troubleshooting.md: change --opencode label to 'Claude Code + OpenCode plugin' - main.rs: install Claude even when --opencode is passed (additive) - mod.rs: update help text to 'Claude setup + OpenCode plugin' Ports docs edits from rtk-ai#4052 to rtk-ai#4323.
…reation `rtk init -g --opencode` installs the Claude setup and the OpenCode plugin together. Cover a fresh home, --hook-only, a re-run with an unchanged CLAUDE.md block, and --dry-run. write_if_changed and the settings patch already create ~/.claude, so the extra create_dir_all calls only replaced the contextual error with a bare "File exists (os error 17)" and left an empty ~/.claude behind on --no-patch runs. An unchanged CLAUDE.md block stays silent after the plugin install, as on every other `rtk init` re-run. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
core::test_isolation fails the suite on a test file that names CARGO_BIN_EXE_rtk itself, since the child then writes to the contributor's real rtk data directory. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
KuSh
left a comment
There was a problem hiding this comment.
Round 2 of 3 — APPROVED (round 1 was posted on #4052, which this PR carries forward)
Claim: rtk init -g --opencode installs the Claude hook and the OpenCode plugin together (Fixes #4046).
Scope: accept (frozen at #4052 round 1). #4052 is closed in favour of this PR; no other open PR claims #4046.
Ran: 3 binaries (merge-base 7efbaef46, head 523b86e0, head merged onto current develop 083a9c5d), one CARGO_TARGET_DIR each, md5s distinct; 16-row rtk init matrix per binary under an isolated HOME, LC_ALL=C, stdin /dev/null, plus 8 probes (malformed CLAUDE.md block, read-only ~/.claude, --hook-only --no-patch, re-run output of every non-opencode mode, sibling agents, declined prompt); mutations: routing revert, hoist revert, redundant-line removal. Invariants: every decision branch of the new routing (default, --hook-only, --claude-md, --dry-run, local rejection, --agent cursor), idempotence, user settings.json/CLAUDE.md content preserved. Savings floor N/A (init change, no filtered output).
Matrix: executed this round on this head (never run on #4323 before; #4052's matrix ran on a different head).
CI @56a2c33da: 11/11 pass. Local gate on the fixup merged onto current develop: fmt, clippy, cargo test --all (4097) green.
Blocks merge (0)
The two #4052 mechanisms are fixed on this head: a fresh HOME with --opencode (default and --hook-only) exits 0 with hook + RTK.md + plugin, and re-running --claude-md --opencode restores a deleted plugin.
Fixed by my fixup (b95e5b755, 56a2c33da; low-hanging; threads closed by it)
- The two
create_dir_all(&claude_dir)?lines are redundant.write_if_changedand the settings patch already create~/.claude(#2521, merged 2026-09-26, after #4052's base — my "verified fix" part (a) in that review is superseded by it). With both lines removed, 14 of 16 matrix rows are byte-identical; the two that differ are~/.claudeas a file or dangling symlink, where the error now readsFailed to create directory: <path>: File existsinstead of a bareFile exists (os error 17). They also left an empty~/.claudebehind on--hook-only --no-patch(develop leaves nothing). - Every no-op
rtk initre-run printed an extraClaude Code will now use rtk…line (plain localrtk init,init -g --claude-md, and the--opencodevariants); develop is silent. TheUnchangedreturn keeps its silence now; the OpenCode install stays hoisted above it. - No test pinned the change. Reverting the
main.rsrouting or the hoist left 310 init unit tests and 5 init integration suites green.tests/init_opencode_test.rs(spawning rtk throughcommon::rtk_command(), ascore::test_isolationrequires) adds 5 tests (fresh home,--hook-only, unchanged-block re-run restores the plugin and stays silent,--hook-only --no-patchcreates no~/.claude,--dry-runwrites nothing); the routing revert fails 5/5, the hoist revert fails the re-run test, head as authored fails exactly the two tests that pin its defects. - Comment rewrite: no issue numbers or history, says why the install sits above the early return.
Filed as follow-ups
- NEW: a broken Claude side now aborts
--opencodebefore the plugin is installed.--claude-md --opencodewith a malformed<!-- rtk-instructionsblock, or--opencodewith an unwritable~/.claude, exits 1 with a clear message and no plugin (develop exits 0 and installs it). Loud rather than silent, and the class is the one named in #4052 round 1; filed as #4413, not blocking. Pre-existing: the same input already fails plainrtk init -gthat way.
Checked and correct — no need to re-verify
Local --opencode rejected (exit 1); --agent cursor --opencode installs OpenCode + Cursor and never creates ~/.claude; dry-run output lists all six actions and writes nothing; existing settings.json keys and CLAUDE.md content survive byte for byte; second --opencode --auto-patch leaves settings.json identical; CLAUDE_CONFIG_DIR pointing at a missing nested dir works; --uninstall --opencode after an install removes both; docs wording (README, supported-agents, troubleshooting, --show text) matches behaviour; clean merge with #4343 and #4269.
Your questions
None open. Note for the description: the "before" column in the PR body describes #4052's head, not develop (develop installs only the plugin), and test_global_opencode_installs_when_claude_dir_missing is #2521's test; it passes without this PR's create_dir_all lines.
Next
Nothing from you: the fixup (tests, two removed lines, restored re-run silence) is pushed on top of your head, code-reviewed twice, CI 11/11 on 56a2c33da. Approving.
Rounds: 2/3. Threads: 0 open, 0 resolved this round.
Summary
Fixes #4046 regressions where
--opencodewas riding the Claude install path, so every Claude-path failure or early-exit took the OpenCode plugin down with it.Changes
fs::create_dir_all(&claude_dir)inpatch_settings_json_commandandrun_default_modeto create the.claudedirectory if missing (fixes bug(init): global Claude init fails when ~/.claude is missing #2519,rtk init --opencodeappears to skip Claude hook installation #4046 Windows regression)Unchangedearly return inrun_claude_md_mode_withso OpenCode installs even when CLAUDE.md block is already up to dateFixes Three Regressions
init -g --opencode --auto-patchinit -g --opencode --hook-only --auto-patchinit -g --opencode --claude-md, re-runTest Coverage
Existing test
test_global_opencode_installs_when_claude_dir_missing(already#[cfg(unix)]) verifies the missing-dir fix. The hoisted OpenCode install ensures plugin installs even on re-run with unchanged CLAUDE.md block.