{"_id":"@buckeyestudio/toh-terminal-bash","name":"@buckeyestudio/toh-terminal-bash","dist-tags":{"next":"0.1.1-rc.2","latest":"0.1.1-rc.2"},"versions":{"0.1.1-rc.2":{"name":"@buckeyestudio/toh-terminal-bash","description":"Persistent shell PTY backend over the TheOpen Harness subprocess terminal primitive","version":"0.1.1-rc.2","publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/terminal/terminal-bash"},"type":"module","main":"lib/index.js","types":"lib/types/index.d.ts","exports":{".":{"types":"./lib/types/index.d.ts","default":"./lib/index.js"},"./invariant":{"types":"./lib/types/invariant.d.ts","default":"./lib/invariant.js"},"./src/*":"./src/*","./package.json":"./package.json"},"license":"MIT","author":{"name":"buckeyestudio"},"peerDependencies":{"@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-terminal":"^0.1.1-rc.2","@buckeyestudio/toh-sandbox":"^0.1.1-rc.2","@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2","@buckeyestudio/toh-sandbox-policy":"^0.1.1-rc.2","@buckeyestudio/toh-subprocess":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"dependencies":{"@buckeyestudio/toh-pwsh-local":"^0.1.1-rc.2","@buckeyestudio/schemastery":"^3.18.1"},"devDependencies":{"@buckeyestudio/toh-agent":"^0.1.1-rc.2","@buckeyestudio/toh-invariants":"^0.1.1-rc.2","@buckeyestudio/toh-terminal":"^0.1.1-rc.2","@buckeyestudio/toh-sandbox":"^0.1.1-rc.2","@buckeyestudio/toh-sandbox-policy":"^0.1.1-rc.2","@buckeyestudio/toh-session":"^0.1.1-rc.2","@buckeyestudio/toh-subprocess":"^0.1.1-rc.2","@buckeyestudio/toh-subprocess-local":"^0.1.1-rc.2","@buckeyestudio/cordis":"^4.0.1"},"_id":"@buckeyestudio/toh-terminal-bash@0.1.1-rc.2","bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","_integrity":"sha512-awEQxnELslLMENjlh5t4KE+hn6XiQnbq7QrhtCMSr6dozYPmJ/pM6TWrFAkK70i+xJjImoAJqb1+ntgKgdqfcw==","_resolved":"/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-terminal-bash-0.1.1-rc.2.tgz","_from":"file:/home/runner/work/theopen-harness/theopen-harness/dist/npm/buckeyestudio-toh-terminal-bash-0.1.1-rc.2.tgz","_nodeVersion":"24.19.0","_npmVersion":"11.17.0","dist":{"integrity":"sha512-awEQxnELslLMENjlh5t4KE+hn6XiQnbq7QrhtCMSr6dozYPmJ/pM6TWrFAkK70i+xJjImoAJqb1+ntgKgdqfcw==","shasum":"60b4ae88f0d8cf649f7c6eab8aefef32de7a7f33","tarball":"https://registry.npmjs.org/@buckeyestudio/toh-terminal-bash/-/toh-terminal-bash-0.1.1-rc.2.tgz","fileCount":12,"unpackedSize":58329,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDeWn8/gOmI8YHRXSWJOkq8NYO5ypWcCRuUzy6QYPMHZAiEApmWaf+R5m0BtJqAjL+XJjk77XhaMgX/r8AMz6N07wgY="}]},"_npmUser":{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"},"directories":{},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/toh-terminal-bash_0.1.1-rc.2_1787489548575_0.6258762110844525"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-23T12:52:28.384Z","0.1.1-rc.2":"2026-08-23T12:52:28.717Z","modified":"2026-08-23T12:52:28.951Z"},"maintainers":[{"name":"buckeyestudio","email":"dustinwloring1988@gmail.com"}],"description":"Persistent shell PTY backend over the TheOpen Harness subprocess terminal primitive","homepage":"https://github.com/dustinwloring1988/theopen-harness#readme","repository":{"type":"git","url":"git+https://github.com/dustinwloring1988/theopen-harness.git","directory":"packages/terminal/terminal-bash"},"author":{"name":"buckeyestudio"},"bugs":{"url":"https://github.com/dustinwloring1988/theopen-harness/issues"},"license":"MIT","readme":"# @buckeyestudio/toh-terminal-bash\n\n[English](README.md) | 中文\n\n这是一个基于 `ctx.subprocess.spawnTerminal`、为 `ctx.terminals` 提供的持久 shell 后端。它在共享 `ctx.sandboxPolicy` 下启动交互式 shell，保留有界的逐行输出并检测就绪状态；进程管理提供方则负责 PTY 分配、环境清理、前台进程组、信号发送和完整终端会话清理。因此，同一个 PTY 后端可以与本地或远程执行世界提供方组合。\n\n## 插件（`terminal-bash`）\n\n该插件注入 `pty`、`sandboxPolicy` 和 `subprocess`，然后注册所配置的后端类型（`shell`）。`danger-full-access` 无需沙箱提供方即可直接启动 shell；受限模式要求同一执行世界中存在 `ctx.sandbox`，并通过它包装确切的 shell argv，未挂载时会在 spawn 前失败。spawn 时，一次 `ctx.sandboxPolicy.resolve({ session })` 调用会同时给出实际模式与会话工作区根目录；调用方省略 cwd 时，同一根目录也是 shell 的默认 cwd。当某个所有者存在开放的 PTY 或正在进行 spawn 时，如果配置变更会得到不同的实际模式，系统会在对应 `sandbox/mode` 事件提交前拒绝该变更。该限制绑定到确切所有者，因此即使提供方重新加载并保留现有会话，它仍然有效。更改模式前，请等待创建完成并关闭会话，避免以更宽权限打开的终端在权限降级后继续存在。\n\n`shellDialect` 选择 shell 栈（默认 `bash`，或 `pwsh`）：它决定默认的 `shellPath`／`shellArgs`（bash 为 `--noprofile --norc -i`；pwsh 经共享的 `toh-pwsh-local` 解析器得到 `-NoLogo -NoProfile`）与启动契约。bash 方言通过环境安装提示符（`PS1` 加 OSC `133;D;` 终结的 `PROMPT_COMMAND`）。pwsh 无法从环境安装提示符，因此后端通过会话写入 `prompt` 函数，并等待受控提示符真正可见——因为 pwsh 从横幅到提示符的间隙可能超过静默上限，所以会在后续 send 上循环等待；同时其环境去掉 bash 专属标记并加 `NO_COLOR`。同一条首发送还会带上共享的 `toh-pwsh-local` 编码前缀，在一切运行之前把 `[Console]::OutputEncoding` 与 `$OutputEncoding` 钉为 UTF-8：会话解码路径按 UTF-8 读取 PTY 字节，未钉住编码的控制台会以宿主代码页输出非 ASCII 内容。两种方言发出相同的 BEL 终结 OSC 标记，因此就绪机制与消费方与方言无关。\n\n就绪检测结合以下机制：由前台状态验证的私有 bash 提示符标记、提供方报告的前台 stdin 等待事实、静默回退和绝对超时。只有最新自有标记之后的可打印尾部与受控 `PS1` 完全相等，标记才算就绪；即使 OSC 标记和提示符被拆到多个数据回调中也一样。因此，较早提示符之后的回显输入或输出无法使当前 send 完成。受控 `PROMPT_COMMAND` 会在每次输出提示符前重新设定该 `PS1`，因此在 shell 内覆盖提示符不会使后续 send 退化到静默就绪。提供方写入前收集的提示符与静默证据，包括写入前前台检查仍在等待时收集的证据，都会在写入边界丢弃。如果 bash 在终端提供方发布其重新取得前台进程组的状态前打印标记，轮询会在普通静默上限之后再保留该候选状态 `handoffGraceMs`，使恰好同时发生的前台交接有机会胜出。因此，继承 `PROMPT_COMMAND` 的交互式子进程无法一直抑制推断空闲就绪直至绝对超时。未知的前台状态绝不会作为精确空闲的正向信号。同样，一次 send 之前就已存在的前台进程组 stdin 等待并不代表写入后就绪：必须先观察到同一进程组脱离该等待，之后再次进入等待才能使该次 send 完成；前台进程组发生变化则构成新的证据。尚未发布的启动过程中，回退路径要求已经观察到输出；零输出静默不能发布空会话，超时则拒绝 spawn。取消操作会关闭尚未发布的 shell，并以调用方提供的确切中止原因拒绝；`TerminalBackendCleanupError` 会单独保留清理失败。调用方的 signal 会转发给终端分配与就绪初始化；发布后，句柄负责其生命周期。未完成的终端控制序列受 `maxReadBytes` 限制；超过上限后，系统会丢弃内容直到其终止符。格式错误的 UTF-8 终端输出使用替换字符；末尾的回车会跨回调保留，使拆分的 CRLF 合并为一个换行。\n\n取消发送时，系统会先把排队输入标记为已取消，再要求终端句柄向当前前台进程组发送真正的 `SIGINT`；异步写入前检查即使随后结算，也无法执行该输入。如果提供方写入已在途，信号发送会等待其结算；写入被拒绝时不会发送信号。已取消的 send 会保留其位置，直到写入与前台信号发送都结算，因此后继 send 不会收到延迟字节或该信号。因此，永不结算的提供方写入或信号会无限期保留该位置；恢复手段是关闭会话（`terminal_close`）。取消等待期间，绝对 deadline 仍保持启用。信号发送失败是终端传输失败，会拒绝活跃 send。取消绝不会通过写入 `\\x03` 模拟中断，因此，即使程序运行在 raw 模式下，也仍可取消。关闭操作会拒绝新的公开信号、停止就绪轮询，并等待由句柄提供方负责的完整会话终止，然后才把活跃 send 结算为 `session_exit`。\n\n## 模型体验\n\n### 当前文件策略与间接消费方\n\n#### 模型看到的内容\n\n策略归属方会贡献与具体能力无关的 `sandbox:policy` 上下文。模型通过 `@buckeyestudio/toh-tool-terminal` 或其他 PTY 消费方还可能收到有界的 MOTD、发送增量、scrollback 页、就绪原因和清理错误。\n\n#### Token 影响\n\n装载该后端期间，当前策略子句会一直存在。消费方返回有界输出前，保留的 PTY scrollback 不会进入模型历史。\n\n#### KV Cache 影响\n\n常驻策略发生变化时，会在保留的历史之后追加一份由归属方渲染、取代先前状态的运行时上下文快照；消费方结果保持仅追加。\n\n## 已知限制与暂缓事项\n\n- 输出按行规范化；不支持全屏备用缓冲区交互。\n- 精确 stdin 等待检测取决于已挂载的进程管理提供方；无法证明该状态的提供方使用提示符标记和静默／超时就绪机制。Windows 正是这样的提供方：shell pid 是伪前台进程组，没有精确的 stdin-wait 档，因此无标记的子进程按静默上限结算。\n- pwsh 引导（UTF-8 编码钉与 `prompt` 函数）通过 `[Console]::` 写入，Windows ACL 沙箱的只读模式（ConstrainedLanguage）可能拒绝它。shell 仍可通过受控可打印提示符和静默档结算，但无法使用 marker 就绪，非 ASCII 输出也可能沿用宿主代码页。\n- 清理保证以 `SubprocessTerminalHandle` 的保证为准；提供方特定的缺口属于该实现的约定，而非这个 PTY 消费方。\n- harness 进程退出后，会话无法继续存在。\n","readmeFilename":"README.zh.md","_rev":"1-6083060c452cde895f826b9c68a1ea35"}