Files
ccg-workflow/codeagent-wrapper/filter.go
T
li 322a4d329e feat: Web UI 实时流式输出 + 自动打开浏览器 + 完成提示
- 新增 Web UI 实时输出(SSE)
  - 随机端口分配,避免端口冲突
  - 单面板显示,按后端类型分色(Codex 绿/Gemini 紫/Claude 橙)
  - 短生命周期,随任务结束而关闭
- 新增自动打开浏览器功能(跨平台:macOS/Linux/Windows)
- 新增完成提示(✓ 完成 + 浏览器通知)
- 新增内容类型显示
  - 💭 思考过程(reasoning - 灰色斜体)
  - 💻 命令执行(command - 黄色代码块)
  - 📝 最终回复(message - 白色)
- 修复 Codex turn.completed 事件捕获
- 扩展 stderr 噪音过滤到所有后端
- 新增 /ccg:enhance 命令(Prompt 增强)

修改文件:
- codeagent-wrapper/server.go: Web UI 核心实现
- codeagent-wrapper/executor.go: WebServer 集成
- codeagent-wrapper/parser.go: turn.completed 支持 + 内容类型
- codeagent-wrapper/filter.go: 全后端噪音过滤
- templates/commands/enhance.md: 新增 Prompt 增强命令
- README.md: 更新功能列表(15 个命令)
- package.json: v1.7.3

版本: v1.7.3
2026-01-09 04:27:10 +08:00

71 lines
1.4 KiB
Go

package main
import (
"bytes"
"io"
"strings"
)
// noisePatterns contains stderr patterns to filter for all backends
var noisePatterns = []string{
// Gemini specific
"[STARTUP]",
"Session cleanup disabled",
"Warning:",
"(node:",
"(Use `node --trace-warnings",
"Loaded cached credentials",
"Loading extension:",
"YOLO mode is enabled",
// Common noise
"[WARN] Skipping unreadable directory",
"supports tool updates. Listening for changes",
}
// filteringWriter wraps an io.Writer and filters out lines matching patterns
type filteringWriter struct {
w io.Writer
patterns []string
buf bytes.Buffer
}
func newFilteringWriter(w io.Writer, patterns []string) *filteringWriter {
return &filteringWriter{w: w, patterns: patterns}
}
func (f *filteringWriter) Write(p []byte) (n int, err error) {
f.buf.Write(p)
for {
line, err := f.buf.ReadString('\n')
if err != nil {
// incomplete line, put it back
f.buf.WriteString(line)
break
}
if !f.shouldFilter(line) {
f.w.Write([]byte(line))
}
}
return len(p), nil
}
func (f *filteringWriter) shouldFilter(line string) bool {
for _, pattern := range f.patterns {
if strings.Contains(line, pattern) {
return true
}
}
return false
}
// Flush writes any remaining buffered content
func (f *filteringWriter) Flush() {
if f.buf.Len() > 0 {
remaining := f.buf.String()
if !f.shouldFilter(remaining) {
f.w.Write([]byte(remaining))
}
f.buf.Reset()
}
}