Skip to content

[FEATURE]: add directory parameter to task tool for monorepo subagent dispatch #29271

@trin4ik

Description

@trin4ik

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.tsInstanceStore.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:

  1. Add directory?: string to Parameters and BaseParameters schemas.
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions