feat(context): add tmux-context plugin injecting the agent's tmux location

Add @deepseek-ai/dsh-tmux-context: an opt-in per-turn context plugin that
reads which tmux session/window/pane this agent process runs in (plus the
window layout tree) via the ctx.bash seam, and injects it as one durable,
source-attributed user/message when the location changes.

- Pull on the first step of each turn; no tmux hook or background process.
- Detect a real pane by tty, not $TMUX_PANE alone: a terminal launched from
  a tmux shell inherits $TMUX/$TMUX_PANE from that ancestor, so the command
  also matches the pane's #{pane_tty} against this process's controlling
  terminal and emits fields only on a match.
- No-op outside a real pane, without a bash executor, or on a malformed
  reading.
- Own location and layout only: no pane sizes, no sibling-pane scraping.
- Unit tests at 100% per-file coverage, plus a keyless Loader e2e with a
  mock bash provider so it replays without tmux.
- Agent Note: 2026-07-27-tmux-location-context.
This commit is contained in:
Turtle
2026-07-28 21:29:24 +08:00
parent cad0615261
commit 1ac946f747
26 changed files with 1244 additions and 6 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| `agent/session-start` | `emit` | [`packages/core/agent/src/types.ts:299`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | [`goal`](../packages/goal/goal), [`goal-session`](../packages/goal/goal-session), [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex), [`workspace-context`](../packages/context/workspace-context) |
| `agent/settled` | `emit` | [`packages/core/agent/src/types.ts:387`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | [`compact-basic`](../packages/compact/compact-basic) |
| `agent/status` | `emit` | [`packages/core/agent/src/types.ts:236`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emitAgentEvent`) | [`agent`](../packages/core/agent), `apiproxy`, [`goal-session`](../packages/goal/goal-session), [`tui`](../packages/ui/tui) |
| `agent/step` | `serial` | [`packages/core/agent/src/types.ts:326`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`compact-basic`](../packages/compact/compact-basic), [`plan-mode`](../packages/plan/plan-mode), [`session-checkpoint-policy`](../packages/session-persistence/session-checkpoint-policy), [`time-context`](../packages/context/time-context), [`tool-skill`](../packages/skill/tool-skill), [`user-approval`](../packages/ui/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `agent/step` | `serial` | [`packages/core/agent/src/types.ts:326`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`compact-basic`](../packages/compact/compact-basic), [`plan-mode`](../packages/plan/plan-mode), [`session-checkpoint-policy`](../packages/session-persistence/session-checkpoint-policy), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-skill`](../packages/skill/tool-skill), [`user-approval`](../packages/ui/user-approval), [`workspace-context`](../packages/context/workspace-context) |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/types.ts:373`](../packages/core/agent/src/types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`hooks-codex`](../packages/hooks/hooks-codex) |
| `approval/request` | `waterfall` | [`packages/ui/user-approval/src/index.ts:30`](../packages/ui/user-approval/src/index.ts) | [`user-approval`](../packages/ui/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp) |
| `commands/change` | `emit` | [`packages/ui/commands/src/index.ts:154`](../packages/ui/commands/src/index.ts) | [`commands`](../packages/ui/commands) (`events.dispatch`) | `apiproxy`, [`tui`](../packages/ui/tui) |