From 91fa92ad06c214e226c10252a4620ebb6123d159 Mon Sep 17 00:00:00 2001 From: 4i3n6 <4i3n6@users.noreply.github.com> Date: Thu, 23 Jul 2026 12:36:12 -0300 Subject: [PATCH] fix(plugin): scope OpenCode marker commands to the plugin's directory 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 #3552. --- dev/opencode-plugin.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/dev/opencode-plugin.ts b/dev/opencode-plugin.ts index 77a8509b19..bc198c0085 100644 --- a/dev/opencode-plugin.ts +++ b/dev/opencode-plugin.ts @@ -9,18 +9,25 @@ import type { Plugin } from "@opencode-ai/plugin"; -export default (async ({ $ }) => { +export default (async ({ $, directory }) => { return { event: async ({ event }) => { + // `$` is the host's process-global Bun shell, shared by every plugin in + // the process. The promise-level `.cwd(directory)` on each command below + // is load-bearing: it pins the command to the directory this plugin + // instance was created for. Without it, the command runs in whatever the + // process-wide cwd happens to be at spawn time. Do not "simplify" to the + // instance-level `$.cwd(...)` — that mutates the shared default for every + // plugin in the host process. switch (event.type) { case "session.status": - await $`wt config state marker set ${'🤖'} || true`.quiet(); + await $`wt config state marker set ${'🤖'} || true`.cwd(directory).quiet(); break; case "session.idle": - await $`wt config state marker set ${'💬'} || true`.quiet(); + await $`wt config state marker set ${'💬'} || true`.cwd(directory).quiet(); break; case "session.deleted": - await $`wt config state marker clear || true`.quiet(); + await $`wt config state marker clear || true`.cwd(directory).quiet(); break; } },