This commit is contained in:
2026-06-18 22:56:41 +08:00
parent 3d831650b7
commit db3d030169
15 changed files with 1123 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
package terminal
import (
"io"
"os"
"os/exec"
"strings"
procgrp "github.com/yan1h/agent-coding-workflow/internal/infra/proc"
)
// 终端窗口的兜底尺寸(前端尚未上报 resize 前使用)。
const (
defaultRows uint16 = 24
defaultCols uint16 = 80
)
// ptySession 持有平台相关的 shell 进程与 IO。resizeFn 由 startPTY 注入:
// Unix 调 pty.Setsize,Windows 为 nil(降级实现无 resize)。这样 ptySession
// 类型与生命周期方法可保持平台无关,仅 startPTY 按 build tag 特化。
type ptySession struct {
cmd *exec.Cmd
group procgrp.Group
rw io.ReadWriteCloser // PTY master(Unix)或 stdio 桥接(Windows)
resizeFn func(rows, cols uint16) error
}
func (p *ptySession) resize(rows, cols uint16) error {
if p.resizeFn == nil {
return nil
}
return p.resizeFn(rows, cols)
}
// terminate 是 Open 失败路径的尽力清理(kill 进程、释放句柄、关闭 IO)。
// 正常关闭走 Supervisor.Close → group.TerminateGroup 的整树终止。
func (p *ptySession) terminate() {
if p.cmd.Process != nil {
_ = p.cmd.Process.Kill()
}
p.group.Close()
_ = p.rw.Close()
}
// buildEnv 从宿主环境按白名单过滤出传给 shell 的环境变量,并补上 TERM 以便
// 终端程序正确渲染。白名单确保 APP_MASTER_KEY、DB DSN、git 凭据等敏感变量
// 不会透传给交互式 shell。
func buildEnv(whitelist []string) []string {
allow := make(map[string]bool, len(whitelist))
for _, k := range whitelist {
allow[k] = true
}
out := make([]string, 0, len(whitelist)+1)
hasTerm := false
for _, kv := range os.Environ() {
i := strings.IndexByte(kv, '=')
if i < 0 {
continue
}
name := kv[:i]
if !allow[name] {
continue
}
if name == "TERM" {
hasTerm = true
}
out = append(out, kv)
}
if !hasTerm {
out = append(out, "TERM=xterm-256color")
}
return out
}