fix(plugin): scope OpenCode marker commands to the plugin's directory - #3554
Merged
Merged
Conversation
The OpenCode host injects the process-global Bun shell as `$`, shared by every plugin in the process. Unscoped commands run in whatever the process-wide cwd is at spawn time, so under concurrent sessions a marker write can land in a directory other than the one the event came from. Pin each command with the promise-level `.cwd(directory)` (directory is already provided by PluginInput). The instance-level `$.cwd(...)` must not be used: it mutates the shared default for every plugin in the host. Closes the wrong-directory execution mechanism discussed in max-sixty#3552.
worktrunk-bot
approved these changes
Jul 23, 2026
max-sixty
added a commit
that referenced
this pull request
Jul 25, 2026
Eleven commits landed on `main` while #3590 sat in CI, so they ship in v0.69.2 with no changelog entry. Most are user-facing, and three are data-loss fixes — exactly the drift the release skill's step-12 check exists to catch. The tag is held until this lands. Entries added, most-impactful first: - **#3589** — two ways shell integration deleted user data on a substring guess: an rc line that only *quotes* the init command, and a user's own `conf.d/wt.fish` deleted outright by `install`'s legacy cleanup. Plus forge detection moving from `host.contains("github")` to label-wise matching. - **#3585 + #3591** — truncate-in-place rc writes replaced by write-temp-then-rename, then generalized to every user-file write. - **#3578** — despite its `docs(step):` subject this carries three behavior fixes, including `wt step push` succeeding mid-rebase and moving the target branch onto a half-replayed history. - **#3588 + #3587** — conflict markers can no longer reach a commit via `wt step relocate --commit`, and `wt merge` refuses in its own name. - **#3554** — OpenCode marker writes could land in another session's worktree (thanks @4i3n6, who both reported and fixed it). Not documented, per convention: #3574 (doc comments only, no runtime or docs-site surface) and the three dependency bumps. Also corrects `.github/CLAUDE.md`, which lists three required status checks; there are four — `fast-checks` is required too, confirmed against the branch-protection API. Entries verified against the diffs by subagent. Two corrections came back and are folded in: the #3589 entry originally promised "two of them deleted" and described only one, and the #3578 entry mis-quoted the success line as `✓ Pushed to main` when it carries a commit count. > _This was written by Claude Code on behalf of max_
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #3552, as invited there.
The OpenCode host injects the process-global Bun shell as
$— a single instance shared by every plugin loaded in the process. The activity-marker plugin issued its commands unscoped, so each one ran in whatever the process-wide cwd was at spawn time; under concurrent parallel-agent sessions that means a marker write can land in a directory other than the one the event came from.This pins every command with the promise-level
.cwd(directory), per the review notes on the issue:directorypulled fromPluginInput(the factory now destructures{ $, directory }), andsession.deletedscopes the same way asset..cwd(directory)only — the instance-level$.cwd(...)would mutate the shared default for every plugin in the host process, so the call-site comment documents why the per-command form is load-bearing.Scope note, consistent with the issue discussion: this closes the "runs
wtin the wrong directory" mechanism on the plugin side; it does not claim to explain the parent-directoryrename(2)from the original report. The host-level question (injecting a scoped shell instead of the global one) belongs upstream with opencode — happy to raise it there as discussed.