Split out of #3757 from a CodeRabbit finding on src/integration/opencode_config.rs.
add_plugin/remove_plugin in src/integration/opencode_config.rs persist plugin registrations with fs::write, which truncates the target before writing. A failed or interrupted write (disk full, process kill, permission race) can leave tui.jsonc or cli.json empty or partially written and drop user plugin options and preferences. The same direct-write pattern is used elsewhere in the integration targets, so this should be fixed consistently rather than only for cli.json.
Scope
- Add a shared atomic-replace helper for integration-managed config files: write the full content to a temporary sibling file, then rename/replace the target.
- Use it in
add_plugin/remove_plugin and any other integration target that rewrites user-owned config in place.
- Preserve existing comments/formatting (the JSONC CST round-trip already handles that) and file permissions.
Sequencing
Do not start or merge this until #3757 is merged. It builds on the cli.json registration path added there, and changing it now would expand #3757 beyond its review scope.
Found while reviewing #3757; not introduced by that PR.
Split out of #3757 from a CodeRabbit finding on
src/integration/opencode_config.rs.add_plugin/remove_plugininsrc/integration/opencode_config.rspersist plugin registrations withfs::write, which truncates the target before writing. A failed or interrupted write (disk full, process kill, permission race) can leavetui.jsoncorcli.jsonempty or partially written and drop user plugin options and preferences. The same direct-write pattern is used elsewhere in the integration targets, so this should be fixed consistently rather than only forcli.json.Scope
add_plugin/remove_pluginand any other integration target that rewrites user-owned config in place.Sequencing
Do not start or merge this until #3757 is merged. It builds on the
cli.jsonregistration path added there, and changing it now would expand #3757 beyond its review scope.Found while reviewing #3757; not introduced by that PR.