snow-flow 10.0.129 → 10.0.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli/cmd/tui/app.tsx +44 -46
package/package.json
CHANGED
package/src/cli/cmd/tui/app.tsx
CHANGED
|
@@ -116,15 +116,20 @@ export function tui(input: {
|
|
|
116
116
|
}) {
|
|
117
117
|
_onUpgrade = input.onUpgrade
|
|
118
118
|
const skipThemeDetection = !!process.env.OPENCODE_SKIP_THEME_DETECTION || !!process.env.OPENCODE_REMOTE_TUI
|
|
119
|
+
// In hosted mode, use stderr for pre-render logs to keep terminal clean for the renderer
|
|
120
|
+
const forceThread = !!process.env.OTUI_FORCE_THREAD
|
|
121
|
+
const log = forceThread
|
|
122
|
+
? (msg: string) => process.stderr.write(`${msg}\n`)
|
|
123
|
+
: (msg: string) => console.log(msg)
|
|
119
124
|
// promise to prevent immediate exit
|
|
120
125
|
return new Promise<void>(async (resolve) => {
|
|
121
126
|
let mode: "dark" | "light" = "dark"
|
|
122
127
|
if (skipThemeDetection) {
|
|
123
|
-
|
|
128
|
+
log("[snow-flow] skipping theme detection")
|
|
124
129
|
} else {
|
|
125
|
-
|
|
130
|
+
log("[snow-flow] detecting theme...")
|
|
126
131
|
mode = await getTerminalBackgroundColor()
|
|
127
|
-
|
|
132
|
+
log(`[snow-flow] theme: ${mode}`)
|
|
128
133
|
}
|
|
129
134
|
const onExit = async () => {
|
|
130
135
|
await input.onExit?.()
|
|
@@ -146,16 +151,11 @@ export function tui(input: {
|
|
|
146
151
|
},
|
|
147
152
|
} as Parameters<typeof render>[1]
|
|
148
153
|
|
|
149
|
-
// On Linux, @opentui
|
|
150
|
-
//
|
|
151
|
-
const forceThread = !!process.env.OTUI_FORCE_THREAD
|
|
152
|
-
if (forceThread) {
|
|
153
|
-
console.log("[snow-flow] forcing renderer threading (OTUI_FORCE_THREAD)")
|
|
154
|
-
Object.defineProperty(process, "platform", { value: "darwin", configurable: true })
|
|
155
|
-
}
|
|
154
|
+
// On Linux, @opentui sets useThread=false which may prevent the Zig renderer
|
|
155
|
+
// from flushing output. HostedRendererDiag handles starting the loop and flushing.
|
|
156
156
|
|
|
157
157
|
try {
|
|
158
|
-
|
|
158
|
+
log("[snow-flow] starting tui...")
|
|
159
159
|
await render(
|
|
160
160
|
() => {
|
|
161
161
|
return (
|
|
@@ -220,49 +220,47 @@ function HostedRendererDiag() {
|
|
|
220
220
|
onMount(() => {
|
|
221
221
|
const r = renderer as any
|
|
222
222
|
const log = (msg: string) => process.stderr.write(`[sf-diag] ${msg}\n`)
|
|
223
|
-
log(`useThread=${r._useThread} isRunning=${r._isRunning} state=${r._controlState}
|
|
224
|
-
log(`platform=${process.platform} altScreen=${r._useAlternateScreen}`)
|
|
225
|
-
|
|
223
|
+
log(`useThread=${r._useThread} isRunning=${r._isRunning} state=${r._controlState}`)
|
|
224
|
+
log(`platform=${process.platform} altScreen=${r._useAlternateScreen} termSetup=${r._terminalIsSetup}`)
|
|
225
|
+
|
|
226
|
+
// On Linux, useThread=false means Zig render() buffers ANSI but doesn't write to fd 1.
|
|
227
|
+
// Patch renderNative to manually flush the Zig stdout buffer after each render frame.
|
|
228
|
+
const realWrite = r.realStdoutWrite
|
|
229
|
+
const stdout = r.stdout
|
|
230
|
+
if (realWrite && r.lib && r.rendererPtr) {
|
|
231
|
+
const origRenderNative = r.renderNative.bind(r)
|
|
232
|
+
r.renderNative = () => {
|
|
233
|
+
origRenderNative()
|
|
234
|
+
// Try to flush Zig's internal stdout buffer by calling writeOut with empty data
|
|
235
|
+
try {
|
|
236
|
+
r.lib.writeOut(r.rendererPtr, new Uint8Array(0).buffer, 0)
|
|
237
|
+
} catch {}
|
|
238
|
+
}
|
|
239
|
+
log("patched renderNative with flush")
|
|
240
|
+
}
|
|
226
241
|
|
|
227
|
-
//
|
|
242
|
+
// Clear screen and start the render loop
|
|
243
|
+
if (realWrite) {
|
|
244
|
+
realWrite.call(stdout, "\x1b[2J\x1b[H")
|
|
245
|
+
}
|
|
228
246
|
if (!r._isRunning) {
|
|
229
|
-
log("calling renderer.start()")
|
|
230
247
|
r.start()
|
|
231
|
-
log(`
|
|
248
|
+
log(`started: isRunning=${r._isRunning} state=${r._controlState}`)
|
|
232
249
|
}
|
|
233
250
|
|
|
234
|
-
//
|
|
251
|
+
// After 3s, log state and try direct fd write test
|
|
235
252
|
setTimeout(() => {
|
|
236
|
-
log(`
|
|
237
|
-
//
|
|
238
|
-
const realWrite = r.realStdoutWrite
|
|
239
|
-
if (realWrite) {
|
|
240
|
-
realWrite.call(r.stdout, "\x1b[2J\x1b[H\x1b[1;31m[sf-diag] REAL STDOUT WRITE OK\x1b[0m\r\n")
|
|
241
|
-
log("realStdoutWrite sent")
|
|
242
|
-
}
|
|
243
|
-
// Test lib.writeOut
|
|
253
|
+
log(`3s: isRunning=${r._isRunning} rendering=${r.rendering}`)
|
|
254
|
+
// Direct write to fd 1 to verify terminal connectivity
|
|
244
255
|
try {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
} catch
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
// Try 3: after 4s, try manual render cycle
|
|
253
|
-
setTimeout(() => {
|
|
254
|
-
log(`4s check: isRunning=${r._isRunning} rendering=${r.rendering}`)
|
|
255
|
-
try {
|
|
256
|
-
if (r.root && r.nextRenderBuffer) {
|
|
257
|
-
r.root.render(r.nextRenderBuffer, 0)
|
|
258
|
-
log("root.render done")
|
|
259
|
-
}
|
|
260
|
-
r.renderNative()
|
|
261
|
-
log("renderNative done")
|
|
262
|
-
} catch (e: any) {
|
|
263
|
-
log(`manual render error: ${e.message}`)
|
|
256
|
+
const fd1 = Bun.file("/dev/fd/1")
|
|
257
|
+
Bun.write(fd1, "\x1b[5;1H\x1b[1;31m[sf-diag] FD1 WRITE TEST\x1b[0m\r\n").catch(() => {})
|
|
258
|
+
} catch {}
|
|
259
|
+
// Also try realStdoutWrite
|
|
260
|
+
if (realWrite) {
|
|
261
|
+
realWrite.call(stdout, "\x1b[7;1H\x1b[1;32m[sf-diag] REAL WRITE TEST\x1b[0m\r\n")
|
|
264
262
|
}
|
|
265
|
-
},
|
|
263
|
+
}, 3000)
|
|
266
264
|
})
|
|
267
265
|
return null
|
|
268
266
|
}
|