anomalyco / anomalyco/opencode
[FEATURE]: Five session capabilities that exist in core but are unreachable from a plugin
@nexxeln is already working on this.
Since Sep 16, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Feature hasn't been suggested before.
- I searched existing issues. #43517 asks for read-only session enumeration and #40863 asks for hidden/ephemeral sessions; both are adjacent but neither covers the write-side gaps below. #34957 and #35364 track the tool-context gaps, which I have left out of this.
Describe the enhancement you want to request
Five capabilities exist and work in core, but are unreachable from a plugin because the value is either omitted from the plugin projection or not forwarded internally. Four are a forwarding change at a single call site; the fifth needs a design decision.
All references are upstream/v2 at 2cdd938152. We hit these porting three plugins to the v2 API.
1. session.compact is not projected. SessionDomain is a Pick of create | get | switchAgent | switchModel | prompt | generate | command | synthetic | interrupt | update | move | wait | context (packages/plugin/src/effect/session.ts:126). compact exists on the core interface (packages/core/src/session.ts:422) and is reachable over HTTP. A plugin that owns compaction via the compaction hook can respond to a fold the host starts, but cannot start one.
2. session.remove is not projected. Same Pick. Combined with (3), a plugin that creates sessions has no way to delete them.
3. parentID is not forwarded on session.create. Core accepts it — the input is { location } | { parentID } (packages/core/src/session.ts:91) — but the plugin projection enumerates fields and omits it (packages/core/src/plugin/host.ts:519). Since location is always supplied there, the parentID arm is unreachable, so every plugin-created session is a root. Removal cascades to children (packages/core/src/session.ts:356), so a parented child would be collected automatically; as it stands, plugin-created worker sessions accumulate with no host-side cleanup path. #40863 describes the create-child-then-delete pattern this prevents.
4. session.generate cannot use a different model. The input is { sessionID, prompt } (packages/core/src/session.ts:182) and the model is resolved from the session (packages/core/src/session/generate.ts:32). model is also readonly on the hook draft (packages/plugin/src/effect/session.ts:63), and prepare never reads it, so an override attempt fails silently rather than erroring. The use case is running a hidden, non-persisted completion — summarisation, classification — on a cheaper model than the session's. This one is a genuine new input rather than a forwarded field.
5. The subagent tool does not pass metadata to the child session. sessions.create is called with parentID, title, agent, model (packages/core/src/tool/plugin/subagent.ts:188). Session.create accepts metadata and the column exists, so the destination is already there — it is simply never populated. Forwarding an optional metadata argument would let a plugin read delegation context from the child's session row instead of parsing it back out of the prompt text. Today the only spawn-time channel is mutating the prompt string.
parentID itself is reliable for task-spawned children on both lines, and is the correct join key; the gap is that a plugin can neither set it nor remove what it creates.
Happy to open a PR for any subset of these if the shape is agreeable — 1, 2, 3 and 5 look like one-line changes each, and 4 would want a design opinion first.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.