Repository navigation
[FEATURE]: add directory parameter to task tool for monorepo subagent dispatch #29271
Description
Feature hasn't been suggested before.
- I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Problem
In a monorepo each subproject can ship its own .opencode/, AGENTS.md and skills. Today there is no way to dispatch a subagent task into a subproject so that those project-local resources are picked up. The task tool always creates the child session inside the parent session's InstanceContext, so the subagent inherits the parent's working directory, agents, skills and AGENTS.md chain — even when the work clearly belongs to a different subproject.
Use case
Layout (simplified):
my-monorepo/
├─ AGENTS.md # monorepo-wide guidance
├─ .opencode/
│ └─ agent/
│ └─ orchestrator.md
├─ backend/
│ └─ api/
│ ├─ AGENTS.md # api-specific guidance
│ └─ .opencode/
│ └─ skill/
│ ├─ abstract-model/
│ ├─ events/
│ └─ metrics/
└─ frontend/
└─ web/
├─ AGENTS.md
└─ .opencode/skill/...
Parent session runs from my-monorepo/. The orchestrator needs to delegate a focused task to backend/api. With the current task tool the subagent sees only the monorepo-root AGENTS.md and root-level skills — none of the backend/api/.opencode/skill/* are available, even though they were authored exactly for that subagent's job.
Proposed solution
Add an optional directory: string parameter to the task tool. When set, the subagent runs inside the matching InstanceContext: cwd, agent registry, AGENTS.md walk-up and skills all resolve against that path. When omitted, behavior is identical to today (subagent inherits the parent session's directory) — fully backwards compatible.
This is essentially the same per-request directory routing that the HTTP middleware already applies (workspace-routing.ts + instance-context.ts → InstanceStore.load({ directory }) + Effect.provideService(InstanceRef, ctx)). The proposal is to make that capability reachable from the task tool's args so it can be driven by the LLM, not only by HTTP clients.
Before vs after
Before — subagent inherits parent's InstanceContext:
task({
subagent_type: "build",
description: "...",
prompt: "...",
})
// → subagent cwd = my-monorepo/
// → AGENTS.md: my-monorepo/AGENTS.md
// → skills: only monorepo-root skills
After — subagent gets backend/api's InstanceContext:
task({
subagent_type: "build",
description: "...",
prompt: "...",
directory: "/abs/path/my-monorepo/backend/api",
})
// → subagent cwd = my-monorepo/backend/api/
// → AGENTS.md: my-monorepo/AGENTS.md + my-monorepo/backend/api/AGENTS.md
// → skills: monorepo-root + backend/api/.opencode/skill/*
Implementation sketch
Single-file change in packages/opencode/src/tool/task.ts:
- Add
directory?: stringtoParametersandBaseParametersschemas. - Build a
scopedhelper. Whenparams.directoryis set, lazily resolveInstanceStore.ServiceviaEffect.serviceOptionand wrap the relevant Effects instore.provide({ directory }, ...). When omitted, pass the Effect through unchanged. - Wrap three calls in
scoped:agent.get(params.subagent_type)— resolve the subagent from the target project.sessions.create(...)— persist the new session withdirectoryset correctly.ops.prompt(...)— run the prompt loop inside the targetInstanceContext.
Using serviceOption keeps TaskTool's declared dependency surface unchanged when directory is omitted, so existing test layers and the ToolRegistry.layer requirement set do not need to change.
Related context
- feat(session): add support for per-session working directories #9365 (
feat(session): add support for per-session working directories) — partially overlapping: it makes per-sessionSession.directorywork, but explicitly does not coverSession.create/Session.forkused by thetasktool (see comments on that PR about monorepo subagents inheriting the wrong directory). The proposal here addresses that specific gap from the task-tool side. - Create session with a different root/working directory #1143, [FEATURE]: Allow sessions to have custom working directories #9366 (both closed) — broader "per-session working directory" tracking, related but coarser.
OPENCODE_EXPERIMENTAL_WORKSPACES— early/buggy alternative, scoped to whole workspaces, does not solve subdirectory dispatch from within a single workspace.
Backwards compatibility
directory is optional. When omitted, the tool behaves exactly as today: the child session inherits the parent session's InstanceContext. No public API or schema changes for existing callers.
Verification plan
Spin up bun dev serve, create a parent session in a monorepo root, drive the subagent with task({ ..., directory: "<repo>/backend/api" }), then ask it to print pwd, the names of skills it can see, and the AGENTS.md paths it has loaded. Expected: cwd matches the target subproject, project-local skills appear, both root and subproject AGENTS.md are loaded. Compare with a no-directory call to confirm default behavior is unchanged.
I have a working patch and a green local run against this exact scenario. Happy to open the PR if the approach sounds right.
Activity
github-actions commentedon May 25, 2026
This issue might be a duplicate of existing issues. Please check:
If your proposal is meaningfully different (e.g., specifically targeting the
tasktool'sdirectoryparameter rather than a broader orchestration system), it may help to add a brief note clarifying the distinction from #17994.trin4ik commentedon May 25, 2026
Thanks for pointing this out. I agree this overlaps with #17994 in motivation, but I don't think it is a duplicate.
#17994 is a broader request for native multi-agent orchestration / isolated workspaces / worktree lifecycle management. This issue is intentionally much narrower: expose an optional
directoryargument on the existingtasktool so a child session can run inside the matchingInstanceContext.That means no workspace lifecycle, no worktree creation, no merge strategy, and no new orchestration system. The goal is only to let an existing parent agent dispatch an existing subagent into a specific project directory and have cwd, local
.opencode,AGENTS.mdwalk-up, agents and skills resolve from that directory.Related PRs I found:
InstanceContextfor HTTP session routes once a session already has the right directory. It does not lettaskcreate a child session in a different directory or resolve the subagent/skills from that target directory.taskstill creates/forks under the parentInstanceContextand resolves the subagent from the parent project.So this proposal can be a small standalone addition:
task({ ..., directory })wrapsagent.get,sessions.create, andops.promptinInstanceStore.load/provide({ directory }). Whendirectoryis omitted, behavior stays exactly as today.Happy to open a focused PR for just this if the approach sounds acceptable.
trin4ik commentedon May 26, 2026
Quick follow-up while we've been using a local plugin that backports this exact
directoryparam totask(shadow registration via opencode plugin API, stop-gap until this lands upstream): we hit a related Web UI gotcha that's worth documenting alongside this feature, since it surfaces precisely when the per-project subagent dispatch starts working as intended.Setup
After dispatching a subagent with
task({ directory: "<repo>/backend/api/v3", ... }), the child session is correctly created withdirectory=<repo>/backend/api/v3. TUI side everything works as expected —session_child_firstkeybind navigates into the running child live, regardless of where TUI is anchored.Web UI behaviour
opencode Web UI renders a per-project session list view by filtering through
GET /session?directory=<X>. Result:directory=<repo_root>)directory=<repo_root>/backend/api/v3) live<repo_root><repo_root>/backend/api/v3After the child finishes the subtask-card click in the parent session opens it normally (different render path — direct ID lookup, not listing).
Probe data confirming
directoryfilter on/sessionlistingWhile a child session was live (parent's
directory=<repo_root>, child'sdirectory=<repo_root>/backend/api/v3):So the route-level layer is fine — direct GET and parent→children traversal don't filter by directory. The
/sessionlisting endpoint that Web UI consumes for its session list does.Why this matters here specifically
Once this feature ships, monorepo orchestrator workflows will routinely produce child sessions in subdirectories of the parent. Without a complementary tweak on the Web UI side, the live monitoring experience splits:
The workaround (open both projects in Web UI in parallel) is acceptable but worth being aware of when announcing this feature.
Diff in child session metadata that drives the filter
The
/sessionlisting-side filter keys off two fields that differ between a parent-instance child and a target-instance child:Everything else (
projectID,parentID,agent,model,permission, ...) is byte-for-byte identical between the two metadata shapes. So the routing is purely offdirectory.Suggestion (separate from the core feature, listing-side)
When the parent session has the listing open, surface its
childrenregardless of their owndirectory— either by:/session?directory=<parent_dir>, also call/session/<parent_id>/children(cross-instance, already works on the API) and merge.?include_children=trueflag on/session?directory=<X>that pulls in children of in-scope sessions regardless of their own directory.github-actions commentedon Jul 26, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.