snow-flow 10.0.125 → 10.0.127

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "10.0.125",
3
+ "version": "10.0.127",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -116,21 +116,22 @@ 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
- const log = (msg: string) => process.stderr.write("[sf] " + msg + "\n")
120
119
  // promise to prevent immediate exit
121
120
  return new Promise<void>(async (resolve) => {
122
121
  let mode: "dark" | "light" = "dark"
123
- if (!skipThemeDetection) {
122
+ if (skipThemeDetection) {
123
+ console.log("[snow-flow] skipping theme detection")
124
+ } else {
125
+ console.log("[snow-flow] detecting theme...")
124
126
  mode = await getTerminalBackgroundColor()
127
+ console.log(`[snow-flow] theme: ${mode}`)
125
128
  }
126
129
  const onExit = async () => {
127
130
  await input.onExit?.()
128
131
  resolve()
129
132
  }
130
133
 
131
- const { createCliRenderer } = await import("@opentui/core")
132
-
133
- const renderer = await createCliRenderer({
134
+ const renderConfig = {
134
135
  targetFps: 60,
135
136
  gatherStats: false,
136
137
  exitOnCtrlC: false,
@@ -138,99 +139,79 @@ export function tui(input: {
138
139
  consoleOptions: {
139
140
  keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }],
140
141
  onCopySelection: (text: string) => {
141
- Clipboard.copy(text).catch(() => {})
142
+ Clipboard.copy(text).catch((error: Error) => {
143
+ console.error(`Failed to copy console selection to clipboard: ${error}`)
144
+ })
142
145
  },
143
146
  },
144
- })
147
+ } as Parameters<typeof render>[1]
145
148
 
146
- // All diagnostics via writeOut so they appear in the terminal
147
- const r = renderer as any
148
- const diag = (msg: string) => r.writeOut(msg + "\r\n")
149
- diag("lib=" + !!r.lib + " ptr=" + !!r.rendererPtr + " thread=" + r._useThread)
150
- diag("altScreen=" + r._useAlternateScreen + " dims=" + r.width + "x" + r.height)
151
- diag("root=" + !!r.root + " rootChildren=" + r.root?.getChildren?.()?.length)
152
-
153
- // After 3s, check render loop state and try to kick it
154
- setTimeout(async () => {
155
- diag("--- 3s check ---")
156
- diag("rootChildren=" + r.root?.getChildren?.()?.length)
157
- diag("_isRunning=" + r._isRunning)
158
- diag("_controlState=" + r._controlState)
159
- diag("liveReqs=" + r.liveRequestCounter)
160
- diag("rendering=" + r.rendering + " updateScheduled=" + r.updateScheduled)
161
- diag("nextRenderBuffer=" + !!r.nextRenderBuffer)
162
-
163
- // Try full render pipeline: root.render → renderNative
164
- try {
165
- diag("calling root.render(nextRenderBuffer)...")
166
- r.root.render(r.nextRenderBuffer, 16)
167
- diag("root.render done, calling renderNative()...")
168
- r.renderNative()
169
- diag("renderNative done!")
170
- } catch (e: any) {
171
- diag("manual render pipeline FAILED: " + e.message)
172
- if (e.stack) diag(e.stack.split("\n").slice(0, 3).join(" | "))
173
- }
149
+ // On Linux, @opentui disables Zig renderer threading which prevents output.
150
+ // OTUI_FORCE_THREAD=1 overrides this for hosted PTY environments (Docker/Cloud Run).
151
+ let rendererOrConfig: any = renderConfig
152
+ if (process.env.OTUI_FORCE_THREAD) {
153
+ const { createCliRenderer } = await import("@opentui/core")
154
+ const cliRenderer = await createCliRenderer(renderConfig as any)
155
+ ;(cliRenderer as any).useThread = true
156
+ rendererOrConfig = cliRenderer
157
+ }
174
158
 
175
- // Also try kicking the loop directly
176
- setTimeout(async () => {
177
- diag("--- 5s: calling loop() ---")
178
- try {
179
- await r.loop()
180
- diag("loop() completed")
181
- } catch (e: any) {
182
- diag("loop() FAILED: " + e.message)
183
- }
184
- }, 2000)
185
- }, 3000)
186
-
187
- await render(
188
- () => (
189
- <ErrorBoundary
190
- fallback={(error, reset) => <ErrorComponent error={error} reset={reset} onExit={onExit} mode={mode} />}
191
- >
192
- <ArgsProvider {...input.args}>
193
- <ExitProvider onExit={onExit}>
194
- <KVProvider>
195
- <ToastProvider>
196
- <RouteProvider>
197
- <SDKProvider
198
- url={input.url}
199
- directory={input.directory}
200
- fetch={input.fetch}
201
- events={input.events}
202
- >
203
- <SyncProvider>
204
- <ThemeProvider mode={mode}>
205
- <LocalProvider>
206
- <KeybindProvider>
207
- <PromptStashProvider>
208
- <DialogProvider>
209
- <CommandProvider>
210
- <FrecencyProvider>
211
- <PromptHistoryProvider>
212
- <PromptRefProvider>
213
- <App />
214
- </PromptRefProvider>
215
- </PromptHistoryProvider>
216
- </FrecencyProvider>
217
- </CommandProvider>
218
- </DialogProvider>
219
- </PromptStashProvider>
220
- </KeybindProvider>
221
- </LocalProvider>
222
- </ThemeProvider>
223
- </SyncProvider>
224
- </SDKProvider>
225
- </RouteProvider>
226
- </ToastProvider>
227
- </KVProvider>
228
- </ExitProvider>
229
- </ArgsProvider>
230
- </ErrorBoundary>
231
- ),
232
- renderer,
233
- )
159
+ try {
160
+ console.log("[snow-flow] starting tui...")
161
+ await render(
162
+ () => {
163
+ return (
164
+ <ErrorBoundary
165
+ fallback={(error, reset) => <ErrorComponent error={error} reset={reset} onExit={onExit} mode={mode} />}
166
+ >
167
+ <ArgsProvider {...input.args}>
168
+ <ExitProvider onExit={onExit}>
169
+ <KVProvider>
170
+ <ToastProvider>
171
+ <RouteProvider>
172
+ <SDKProvider
173
+ url={input.url}
174
+ directory={input.directory}
175
+ fetch={input.fetch}
176
+ events={input.events}
177
+ >
178
+ <SyncProvider>
179
+ <ThemeProvider mode={mode}>
180
+ <LocalProvider>
181
+ <KeybindProvider>
182
+ <PromptStashProvider>
183
+ <DialogProvider>
184
+ <CommandProvider>
185
+ <FrecencyProvider>
186
+ <PromptHistoryProvider>
187
+ <PromptRefProvider>
188
+ <App />
189
+ </PromptRefProvider>
190
+ </PromptHistoryProvider>
191
+ </FrecencyProvider>
192
+ </CommandProvider>
193
+ </DialogProvider>
194
+ </PromptStashProvider>
195
+ </KeybindProvider>
196
+ </LocalProvider>
197
+ </ThemeProvider>
198
+ </SyncProvider>
199
+ </SDKProvider>
200
+ </RouteProvider>
201
+ </ToastProvider>
202
+ </KVProvider>
203
+ </ExitProvider>
204
+ </ArgsProvider>
205
+ </ErrorBoundary>
206
+ )
207
+ },
208
+ rendererOrConfig,
209
+ )
210
+ } catch (e) {
211
+ console.error("[snow-flow] render failed:", e instanceof Error ? e.message : e)
212
+ if (e instanceof Error && e.stack) console.error(e.stack)
213
+ resolve()
214
+ }
234
215
  })
235
216
  }
236
217
 
@@ -239,16 +220,6 @@ function App() {
239
220
  const dimensions = useTerminalDimensions()
240
221
  const renderer = useRenderer()
241
222
  renderer.disableStdoutInterception()
242
-
243
- // Diagnostic: check dimensions and renderer state from inside the component
244
- const r = renderer as any
245
- const diag = (msg: string) => r.writeOut?.("[App] " + msg + "\r\n") ?? process.stderr.write("[App] " + msg + "\n")
246
- diag("dims=" + dimensions().width + "x" + dimensions().height)
247
- diag("theme loading...")
248
- onMount(() => {
249
- diag("mounted! dims=" + dimensions().width + "x" + dimensions().height)
250
- diag("root children=" + r.root?.getChildren?.()?.length)
251
- })
252
223
  const dialog = useDialog()
253
224
  const local = useLocal()
254
225
  const kv = useKV()
package/src/pty/index.ts CHANGED
@@ -116,6 +116,7 @@ export namespace Pty {
116
116
  OPENCODE_SKIP_THEME_DETECTION: "1",
117
117
  OPENCODE_DISABLE_KITTY_KEYBOARD: "1",
118
118
  OTUI_USE_ALTERNATE_SCREEN: "0",
119
+ OTUI_FORCE_THREAD: "1",
119
120
  COLORTERM: "truecolor",
120
121
  FORCE_COLOR: "3",
121
122
  }
@@ -57,6 +57,7 @@ async function spawnTui(cols: number, rows: number, env?: Record<string, string>
57
57
  OPENCODE_SKIP_THEME_DETECTION: "1",
58
58
  OPENCODE_DISABLE_KITTY_KEYBOARD: "1",
59
59
  OTUI_USE_ALTERNATE_SCREEN: "0",
60
+ OTUI_FORCE_THREAD: "1",
60
61
  },
61
62
  },
62
63
  )