ScuttleBot

fix: disable PTY→IRC mirroring — session file is the clean path PTY output contains terminal UI artifacts (spinners, partial line renders, ANSI fragments, bracketed paste mode) that are too noisy for IRC. The session file mirror already handles all structured output cleanly. PTY mirror is kept for busy signal detection and dedup only — no IRC posting.

lmata 2026-04-05 23:21 trunk
Commit 4f3dcfeb8c16cf1edf949e22c514d9e423334006a1d9f8f9acd3889a81d82dc0
--- cmd/claude-relay/main.go
+++ cmd/claude-relay/main.go
@@ -212,15 +212,18 @@
212212
"SCUTTLEBOT_HOOKS_ENABLED="+boolString(cfg.HooksEnabled),
213213
"SCUTTLEBOT_SESSION_ID="+cfg.SessionID,
214214
"SCUTTLEBOT_NICK="+cfg.Nick,
215215
"SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
216216
)
217
- // Create PTY mirror early so session file loop can dedup against it.
217
+ // PTY mirror: only used for busy signal detection and dedup, NOT for
218
+ // posting to IRC. The session file mirror handles all IRC output with
219
+ // clean structured data. PTY output is too noisy (spinners, partial
220
+ // renders, ANSI fragments) for direct IRC posting.
218221
var ptyMirror *relaymirror.PTYMirror
219222
if relayActive {
220223
ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
221
- go func() { _ = relay.Post(ctx, line) }()
224
+ // no-op: session file mirror handles IRC output
222225
})
223226
go mirrorSessionLoop(ctx, relay, cfg, startedAt, ptyMirror)
224227
go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
225228
}
226229
227230
--- cmd/claude-relay/main.go
+++ cmd/claude-relay/main.go
@@ -212,15 +212,18 @@
212 "SCUTTLEBOT_HOOKS_ENABLED="+boolString(cfg.HooksEnabled),
213 "SCUTTLEBOT_SESSION_ID="+cfg.SessionID,
214 "SCUTTLEBOT_NICK="+cfg.Nick,
215 "SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
216 )
217 // Create PTY mirror early so session file loop can dedup against it.
 
 
 
218 var ptyMirror *relaymirror.PTYMirror
219 if relayActive {
220 ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
221 go func() { _ = relay.Post(ctx, line) }()
222 })
223 go mirrorSessionLoop(ctx, relay, cfg, startedAt, ptyMirror)
224 go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
225 }
226
227
--- cmd/claude-relay/main.go
+++ cmd/claude-relay/main.go
@@ -212,15 +212,18 @@
212 "SCUTTLEBOT_HOOKS_ENABLED="+boolString(cfg.HooksEnabled),
213 "SCUTTLEBOT_SESSION_ID="+cfg.SessionID,
214 "SCUTTLEBOT_NICK="+cfg.Nick,
215 "SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
216 )
217 // PTY mirror: only used for busy signal detection and dedup, NOT for
218 // posting to IRC. The session file mirror handles all IRC output with
219 // clean structured data. PTY output is too noisy (spinners, partial
220 // renders, ANSI fragments) for direct IRC posting.
221 var ptyMirror *relaymirror.PTYMirror
222 if relayActive {
223 ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
224 // no-op: session file mirror handles IRC output
225 })
226 go mirrorSessionLoop(ctx, relay, cfg, startedAt, ptyMirror)
227 go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
228 }
229
230
--- cmd/codex-relay/main.go
+++ cmd/codex-relay/main.go
@@ -231,11 +231,11 @@
231231
"SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
232232
)
233233
var ptyMirror *relaymirror.PTYMirror
234234
if relayActive {
235235
ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
236
- go func() { _ = relay.Post(ctx, line) }()
236
+ // no-op: session file mirror handles IRC output
237237
})
238238
go mirrorSessionLoop(ctx, relay, cfg, startedAt, preExisting, ptyMirror)
239239
go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
240240
}
241241
242242
--- cmd/codex-relay/main.go
+++ cmd/codex-relay/main.go
@@ -231,11 +231,11 @@
231 "SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
232 )
233 var ptyMirror *relaymirror.PTYMirror
234 if relayActive {
235 ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
236 go func() { _ = relay.Post(ctx, line) }()
237 })
238 go mirrorSessionLoop(ctx, relay, cfg, startedAt, preExisting, ptyMirror)
239 go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
240 }
241
242
--- cmd/codex-relay/main.go
+++ cmd/codex-relay/main.go
@@ -231,11 +231,11 @@
231 "SCUTTLEBOT_ACTIVITY_VIA_BROKER="+boolString(relayActive),
232 )
233 var ptyMirror *relaymirror.PTYMirror
234 if relayActive {
235 ptyMirror = relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
236 // no-op: session file mirror handles IRC output
237 })
238 go mirrorSessionLoop(ctx, relay, cfg, startedAt, preExisting, ptyMirror)
239 go presenceLoopPtr(ctx, &relay, cfg.HeartbeatInterval)
240 }
241
242
--- cmd/gemini-relay/main.go
+++ cmd/gemini-relay/main.go
@@ -222,11 +222,11 @@
222222
_, _ = io.Copy(ptmx, os.Stdin)
223223
}()
224224
// Dual-path mirroring: PTY for real-time text + session file for metadata.
225225
ptyMirror := relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
226226
if relayActive {
227
- go func() { _ = relay.Post(ctx, line) }()
227
+ // no-op: session file mirror handles IRC output
228228
}
229229
})
230230
ptyMirror.BusyCallback = func(now time.Time) {
231231
state.mu.Lock()
232232
state.lastBusy = now
233233
--- cmd/gemini-relay/main.go
+++ cmd/gemini-relay/main.go
@@ -222,11 +222,11 @@
222 _, _ = io.Copy(ptmx, os.Stdin)
223 }()
224 // Dual-path mirroring: PTY for real-time text + session file for metadata.
225 ptyMirror := relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
226 if relayActive {
227 go func() { _ = relay.Post(ctx, line) }()
228 }
229 })
230 ptyMirror.BusyCallback = func(now time.Time) {
231 state.mu.Lock()
232 state.lastBusy = now
233
--- cmd/gemini-relay/main.go
+++ cmd/gemini-relay/main.go
@@ -222,11 +222,11 @@
222 _, _ = io.Copy(ptmx, os.Stdin)
223 }()
224 // Dual-path mirroring: PTY for real-time text + session file for metadata.
225 ptyMirror := relaymirror.NewPTYMirror(defaultMirrorLineMax, 500*time.Millisecond, func(line string) {
226 if relayActive {
227 // no-op: session file mirror handles IRC output
228 }
229 })
230 ptyMirror.BusyCallback = func(now time.Time) {
231 state.mu.Lock()
232 state.lastBusy = now
233

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button