summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/utils
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-12 15:15:27 -0600
committerAdam <[email protected]>2026-02-12 15:15:34 -0600
commit548608b7ad1252af3181201ef764b16c05d0b786 (patch)
treee33c2f8c5a7f30fbb2a7f068010ee98c13656491 /packages/app/src/utils
parent4e0f509e7b7d84395a541bdfa658f6c98f588221 (diff)
downloadopencode-548608b7ad1252af3181201ef764b16c05d0b786.tar.gz
opencode-548608b7ad1252af3181201ef764b16c05d0b786.zip
fix(app): terminal pty isolation
Diffstat (limited to 'packages/app/src/utils')
-rw-r--r--packages/app/src/utils/terminal-writer.test.ts33
-rw-r--r--packages/app/src/utils/terminal-writer.ts27
2 files changed, 60 insertions, 0 deletions
diff --git a/packages/app/src/utils/terminal-writer.test.ts b/packages/app/src/utils/terminal-writer.test.ts
new file mode 100644
index 000000000..d48dd4f4e
--- /dev/null
+++ b/packages/app/src/utils/terminal-writer.test.ts
@@ -0,0 +1,33 @@
+import { describe, expect, test } from "bun:test"
+import { terminalWriter } from "./terminal-writer"
+
+describe("terminalWriter", () => {
+ test("buffers and flushes once per schedule", () => {
+ const calls: string[] = []
+ const scheduled: VoidFunction[] = []
+ const writer = terminalWriter(
+ (data) => calls.push(data),
+ (flush) => scheduled.push(flush),
+ )
+
+ writer.push("a")
+ writer.push("b")
+ writer.push("c")
+
+ expect(calls).toEqual([])
+ expect(scheduled).toHaveLength(1)
+
+ scheduled[0]?.()
+ expect(calls).toEqual(["abc"])
+ })
+
+ test("flush is a no-op when empty", () => {
+ const calls: string[] = []
+ const writer = terminalWriter(
+ (data) => calls.push(data),
+ (flush) => flush(),
+ )
+ writer.flush()
+ expect(calls).toEqual([])
+ })
+})
diff --git a/packages/app/src/utils/terminal-writer.ts b/packages/app/src/utils/terminal-writer.ts
new file mode 100644
index 000000000..b6caff789
--- /dev/null
+++ b/packages/app/src/utils/terminal-writer.ts
@@ -0,0 +1,27 @@
+export function terminalWriter(
+ write: (data: string) => void,
+ schedule: (flush: VoidFunction) => void = queueMicrotask,
+) {
+ let chunks: string[] | undefined
+ let scheduled = false
+
+ const flush = () => {
+ scheduled = false
+ const items = chunks
+ if (!items?.length) return
+ chunks = undefined
+ write(items.join(""))
+ }
+
+ const push = (data: string) => {
+ if (!data) return
+ if (chunks) chunks.push(data)
+ else chunks = [data]
+
+ if (scheduled) return
+ scheduled = true
+ schedule(flush)
+ }
+
+ return { push, flush }
+}