Feature 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?: string to Parameters and BaseParameters schemas.
- Build a
scoped helper. When params.directory is set, lazily resolve InstanceStore.Service via Effect.serviceOption and wrap the relevant Effects in store.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 with directory set correctly.
ops.prompt(...) — run the prompt loop inside the target InstanceContext.
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
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.
Feature hasn't been suggested before.
Describe the enhancement you want to request
Problem
In a monorepo each subproject can ship its own
.opencode/,AGENTS.mdand skills. Today there is no way to dispatch a subagent task into a subproject so that those project-local resources are picked up. Thetasktool always creates the child session inside the parent session'sInstanceContext, 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):
Parent session runs from
my-monorepo/. The orchestrator needs to delegate a focused task tobackend/api. With the currenttasktool the subagent sees only the monorepo-rootAGENTS.mdand root-level skills — none of thebackend/api/.opencode/skill/*are available, even though they were authored exactly for that subagent's job.Proposed solution
Add an optional
directory: stringparameter to thetasktool. When set, the subagent runs inside the matchingInstanceContext: 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 thetasktool's args so it can be driven by the LLM, not only by HTTP clients.Before vs after
Before — subagent inherits parent's
InstanceContext:After — subagent gets
backend/api'sInstanceContext:Implementation sketch
Single-file change in
packages/opencode/src/tool/task.ts:directory?: stringtoParametersandBaseParametersschemas.scopedhelper. Whenparams.directoryis set, lazily resolveInstanceStore.ServiceviaEffect.serviceOptionand wrap the relevant Effects instore.provide({ directory }, ...). When omitted, pass the Effect through unchanged.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
serviceOptionkeepsTaskTool's declared dependency surface unchanged whendirectoryis omitted, so existing test layers and theToolRegistry.layerrequirement set do not need to change.Related context
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.OPENCODE_EXPERIMENTAL_WORKSPACES— early/buggy alternative, scoped to whole workspaces, does not solve subdirectory dispatch from within a single workspace.Backwards compatibility
directoryis optional. When omitted, the tool behaves exactly as today: the child session inherits the parent session'sInstanceContext. 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 withtask({ ..., directory: "<repo>/backend/api" }), then ask it to printpwd, 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-directorycall 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.