feat: Agent CLI 与终端审计回放全面优化

- Agent CLI: 多轮对话、SSH 长连接、流式推理、Evolver 按用户隔离、历史侧栏
- 终端审计: 回放播放器、命令书签、筛选分页导出、命令输出统计、录制落盘修复
- 修复 session_commands 表迁移、Kill 竞态导致录制丢失、无录制会话回放提示
- 审计历史页只读(移除删除),移除回放弹框录制搜索
This commit is contained in:
Logan committed 2026-07-01 12:13:53 +08:00
1 parent 9a3dd304f7
commit 1acb0c49af
81 files changed
+3916 -1655

No files matched your search

+2 -69
View File
@@ -5,7 +5,6 @@ package remoteexec
import (
"bytes"
"context"
"fmt"
"log"
"net"
@@ -70,10 +69,7 @@ type UploadResult struct {
// 返回合并的 stdout+stderr 输出、退出码和错误。
func Exec(cfg SSHConfig, command string, timeout time.Duration) (*ExecResult, error) {
start := time.Now()
result := &ExecResult{
Host: cfg.Host,
Port: cfg.Port,
}
result := &ExecResult{Host: cfg.Host, Port: cfg.Port}
client, err := connect(cfg)
if err != nil {
@@ -83,70 +79,7 @@ func Exec(cfg SSHConfig, command string, timeout time.Duration) (*ExecResult, er
}
defer client.Close()
// 创建 session
session, err := client.NewSession()
if err != nil {
result.Duration = time.Since(start).Milliseconds()
result.Error = fmt.Sprintf("创建SSH会话失败: %v", err)
return result, err
}
defer session.Close()
// 设置超时
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// 在 goroutine 中执行,支持超时
type execOut struct {
output []byte
err error
}
ch := make(chan execOut, 1)
go func() {
var stdout, stderr bytes.Buffer
session.Stdout = &stdout
session.Stderr = &stderr
err := session.Run(command)
// 合并输出
output := stdout.Bytes()
if stderr.Len() > 0 {
if len(output) > 0 {
output = append(output, '\n')
}
output = append(output, stderr.Bytes()...)
}
ch <- execOut{output: output, err: err}
}()
select {
case <-ctx.Done():
result.Duration = time.Since(start).Milliseconds()
result.Error = fmt.Sprintf("执行超时(%v)", timeout)
result.ExitCode = -1
return result, fmt.Errorf("exec timeout after %v", timeout)
case out := <-ch:
result.Duration = time.Since(start).Milliseconds()
result.Output = string(out.output)
if out.err != nil {
if exitErr, ok := out.err.(*ssh.ExitError); ok {
result.ExitCode = exitErr.ExitStatus()
result.Success = false
} else {
result.ExitCode = -1
result.Error = out.err.Error()
result.Success = false
return result, out.err
}
} else {
result.ExitCode = 0
result.Success = true
}
}
return result, nil
return execWithClient(client, cfg, command, timeout)
}
// BatchExec 在多台远程主机上并发执行相同命令。