Skip to content

fix: opencode 2.0.19+ support (team_spawn, worktrees, teammate edits, read-only agents) - #46

Merged
hueyexe merged 2 commits into
hueyexe:mainfrom
zudsniper:fix/opencode-2.0.24
Oct 19, 2026
Merged

hueyexe merged 2 commits into
hueyexe:mainfrom
zudsniper:fix/opencode-2.0.24

Conversation

@zudsniper

@zudsniper zudsniper commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

fixes the team_spawn crash + silent worktree failure from #40 on opencode 2.0.19+, plus the stuff that still stops teammates from working after that.

vs #41 / #43

both guard ctx.permission.rules, #41 also validates depends_on. this does both, plus:

▸ worktree root cause: #41 adds a warning but couldn't find why worktree.create made nothing. 2.0.19+ worktree endpoints need a projectID. ensemble never sent one → creation failed → everyone shared the base tree. now passes ctx.location.project.id to create/list/remove/refresh

▸ detached worktrees (2.0.32+): opencode now does git worktree add --detach (packages/core/src/git.ts). teammate commits land on a detached HEAD → team_merge: "not something we can merge". if the new worktree has no branch, ensemble creates it

▸ edits stuck on approval: v2 checks in-location files as relative paths, so edit <worktree>/** allow never matched → ask nobody answers. worktree teammates also get edit * allow. outside-the-worktree stays behind external_directory

▸ read-only detection: was name-only (plan, explore). custom reviewers got a worktree + shell * allow. now reads the agent's own rules via agent.get, names as fallback

not touched: the 4th #40 thing (notifications redelivered after purge).

on permission.rules: since 2.0.19 core merges session rules after agent rules (merge(agent, session), last match wins), so the session.create permissions already win. skipping rules() when it's gone loses nothing.

verification

✓ bun run typecheck clean
✓ bun test 857 pass / 0 fail (new: projectID pass-through, detached naming, read-only from rules, edit *, unknown depends_on)
✓ bun run lint only pre-existing warnings
✓ live on 2.0.24 + 2.0.32:

team_create → team_spawn(build, worktree) → own worktree + branch → commit
           → team_shutdown → team_merge ✓ → team_cleanup

✗ not verified: subagent-mode teammates (explore etc.) on opencode's free big-pickle. they get "free tier can only be used from within OpenCode", built-ins too, so it looks like a host/provider thing, not ensemble.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GUtz6gBn7rhXaufK97d8cm

zudsniper and others added 2 commits October 12, 2026 00:04
Fixes hueyexe#40 against OpenCode 2.0.24:

- session.create: only call permission.rules() when the host still has it
  (2.0.3-2.0.18). Since 2.0.19 the session ruleset merges after the agent's
  (core permission.ts merge(agent, session) with last-match evaluation), so
  create() permissions are enough and rules() no longer exists.
- worktree create/list/remove/refresh: pass the location's projectID, which
  the 2.0.19+ worktree API requires; worktree creation silently failed
  without it and every teammate shared the base tree.
- team_spawn: also allow `edit *` for worktree teammates. V2 checks files
  inside the session location as relative paths, so the absolute
  `<worktree>/**` rule never matched and edits fell back to an ask nobody
  could answer. Files outside the worktree stay behind external_directory.
- team_spawn: detect read-only agents from the agent's own permission rules
  (agent.get) instead of only the names plan/explore, so custom reviewer
  agents are not given a worktree and `shell * allow`.
- team_tasks_add: reject unknown depends_on IDs up front instead of creating
  a task that can never unblock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GUtz6gBn7rhXaufK97d8cm
OpenCode 2.0.32 creates worktrees with `git worktree add --detach`, so a
teammate's commits landed on a detached HEAD and team_merge failed with
"not something we can merge". When the new worktree has no branch, create
the requested branch in it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GUtz6gBn7rhXaufK97d8cm
@zudsniper
zudsniper requested a review from hueyexe as a code owner October 17, 2026 09:34
@zudsniper zudsniper changed the title fix: support OpenCode 2.0.19+ (team_spawn, worktrees, teammate edits, read-only agents) fix: opencode 2.0.19+ support (team_spawn, worktrees, teammate edits, read-only agents) Oct 17, 2026
@hueyexe
hueyexe merged commit 0d64ef3 into hueyexe:main Oct 19, 2026
2 checks passed
hueyexe added a commit that referenced this pull request Oct 19, 2026
…ty, isolation warning

- team_spawn: bind session to the worktree directory when workspace binding
  is unavailable, so the 'edit * allow' rule scopes to the worktree instead
  of the whole shared tree
- v2-client: gitCreateBranch now returns the effective branch (or null);
  logs failures and falls back to 'git switch' for the existing-branch
  re-spawn race. worktree.create records the effective branch only — a
  failed create can no longer point team_merge at a stale same-named branch
  whose commits would silently shadow new work
- v2-client: guard ctx.permission?.rules against a missing permission domain
- team_spawn: spawn result now warns plainly when worktree isolation did
  not complete (cherry-picked from PR #41, issue #40 bug 2)
- tests: branch-failure error path, cross-team depends_on rejection (from
  PR #41)
@hueyexe

hueyexe commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Merged — thank you for the comprehensive 2.x compat work. Post-merge review applied four follow-up fixes on top (commit 024967a): (1) team_spawn now binds the session to the worktree directory when workspace binding is unavailable, so the edit * allow rule is genuinely scoped to the worktree instead of the whole shared tree — the premise your comment relied on wasn't established without it; (2) gitCreateBranch failures are now logged and fall back to git switch for the existing-branch re-spawn race, and worktree.create records only the effective branch — recording the requested name unconditionally could point team_merge at a stale same-named branch and silently lose the teammate's new work; (3) the guard now uses ctx.permission?.rules to survive a missing permission domain entirely; (4) PR #41's isolationInfo spawn-result warning was cherry-picked so the lead is told plainly when isolation did not complete (issue #40 bug 2's reporting ask). One minor behavior to note: with agent.readOnly returning false, the ?? only falls through on undefined, so a host that reports its plan agent as writable gets plan teammates with worktrees and bash * allow — called out in the release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants