# @deepseek-ai/dsh-terminal

[English](README.md) | 中文

限定所有者范围的持久 PTY seam。`TerminalSessionService` 注册为 `ctx.terminals`，生成不透明的会话 id，通过具名后端路由创建操作，将每个操作限制在完全相同的活跃 `Agent` 内，并在该 agent（智能体）或服务 dispose（资源释放）时等待后端完全停稳。

## 约定

- 后端注册一个稳定的 `type`，并返回尚未发布的 `TerminalBackendSession`；失败或取消的设置过程必须清理部分资源。若清理失败，则以 `TerminalBackendCleanupError` 拒绝，使注册表能在取消后继续保留该清理失败。
- spawn 取消会保留调用方提供的确切中止原因。后端设置完成后，服务 dispose 与所有者消失仍分别对应可供机器路由的不同失败。
- 所有者与服务的 dispose 会通过服务持有的信号中止尚未发布的设置，并等待后端结算和回滚后才返回。
- 如果回滚关闭失败，或后端报告启动清理失败，dispose 生命周期会以拒绝结束，不会声称已经完全停稳。调用方触发的取消仍收到其确切原因；生命周期触发的回滚失败也会拒绝待完成的 spawn。
- 调用方取消后发生的后端清理失败仍算作所有者活动，直到所有者或服务 dispose 并消费、报告该失败，避免生命周期策略把失败的清理误判为完全停稳。
- `hasOwnerActivity(owner)` 覆盖从尚未发布的设置到最终关闭的全过程，使生命周期策略能精确限制对应所有者，不受发布竞态影响。
- 成功的 spawn 会发布一个 `TerminalSessionId`。可选的 `name` 只是所有者本地的显示元数据，绝不代表权限。
- 一个会话最多接受一个活跃的发送操作。读取和信号操作可以观察该发送；在当前操作结算前，另一项发送会失败。
- `TerminalSendResult.waitReason` 与 `sessionStatus` 相互独立。`session_exit` 描述顶层 PTY 进程，而不是任意前台命令。
- `kill()` 与 dispose 只会在后端捕获的进程树完全停稳后完成。清理失败会以拒绝结束，而非声称成功；同时它会清除匹配的后端和注册表限制，使后续关闭能够重试，且不会干扰较新的尝试。

该 seam 不包含 `node-pty`、沙箱、工具 schema、提示词、任务或终端渲染策略。实现负责终端机制；消费方负责模型呈现和可选的后台任务注册。

## 模型体验

### 间接消费方

#### 模型看到的内容

没有直接可见内容。此包不注册提示词或工具；可见 schema 和结果文本由 `@deepseek-ai/dsh-tool-terminal` 负责。

#### Token 影响

没有直接影响。活跃会话状态会保留在进程本地，直到消费方返回有界结果。

#### KV Cache 影响

不会直接失效；请求前缀变更由上述消费方负责。

## 已知限制与暂缓事项

- 会话只存在于进程本地，harness 重启后不会恢复。
- 系统有意不支持跨 agent 共享；未来的共享会话设计需要独立的权限约定。
