snow-flow 10.0.100 → 10.0.102

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.100",
3
+ "version": "10.0.102",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -117,18 +117,14 @@ export function tui(input: {
117
117
  _onUpgrade = input.onUpgrade
118
118
  // promise to prevent immediate exit
119
119
  return new Promise<void>(async (resolve) => {
120
- console.log("[snow-flow] detecting terminal background...")
121
120
  const mode = await getTerminalBackgroundColor()
122
- console.log("[snow-flow] background:", mode)
123
121
  const onExit = async () => {
124
122
  await input.onExit?.()
125
123
  resolve()
126
124
  }
127
125
 
128
- const isRemote = !!process.env.OPENCODE_REMOTE_TUI
129
- console.log("[snow-flow] starting render...", isRemote ? "(remote mode)" : "(local mode)")
130
126
  try {
131
- render(
127
+ await render(
132
128
  () => {
133
129
  return (
134
130
  <ErrorBoundary
@@ -179,7 +175,6 @@ export function tui(input: {
179
175
  targetFps: 60,
180
176
  gatherStats: false,
181
177
  exitOnCtrlC: false,
182
- ...(isRemote ? { remote: true } : {}),
183
178
  useKittyKeyboard: process.env.OPENCODE_DISABLE_KITTY_KEYBOARD ? undefined : {},
184
179
  consoleOptions: {
185
180
  keyBindings: [{ name: "y", ctrl: true, action: "copy-selection" }],
@@ -191,18 +186,15 @@ export function tui(input: {
191
186
  },
192
187
  },
193
188
  )
194
- console.log("[snow-flow] render() returned")
195
- } catch (e) {
196
- console.log(`[snow-flow] render() threw: ${e instanceof Error ? e.message : e}`)
189
+ } catch {
190
+ // render failure handled by ErrorBoundary
197
191
  }
198
192
  })
199
193
  }
200
194
 
201
195
  function App() {
202
- console.log("[snow-flow] App component mounting...")
203
196
  const route = useRoute()
204
197
  const dimensions = useTerminalDimensions()
205
- console.log("[snow-flow] dimensions:", dimensions().width, "x", dimensions().height)
206
198
  const renderer = useRenderer()
207
199
  renderer.disableStdoutInterception()
208
200
  const dialog = useDialog()
@@ -227,10 +219,6 @@ function App() {
227
219
  }
228
220
  const [terminalTitleEnabled, setTerminalTitleEnabled] = createSignal(kv.get("terminal_title_enabled", true))
229
221
 
230
- createEffect(() => {
231
- console.log(JSON.stringify(route.data))
232
- })
233
-
234
222
  // Update terminal window title based on current route and session
235
223
  createEffect(() => {
236
224
  if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return
@@ -1,138 +1,8 @@
1
1
  import { Hono } from "hono"
2
2
  import { lazy } from "../../util/lazy"
3
3
 
4
- const HTML = `<!doctype html>
5
- <html lang="en">
6
- <head>
7
- <meta charset="UTF-8">
8
- <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
9
- <meta name="apple-mobile-web-app-capable" content="yes">
10
- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
11
- <meta name="mobile-web-app-capable" content="yes">
12
- <meta name="theme-color" content="#0a0a1a">
13
- <title>Snow-Flow TUI</title>
14
- <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg viewBox='0 0 32 32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3ClinearGradient id='m' x1='16' y1='9' x2='16' y2='23' gradientUnits='userSpaceOnUse'%3E%3Cstop offset='0%25' stop-color='%23FFFFFF'/%3E%3Cstop offset='100%25' stop-color='%2300D9FF'/%3E%3C/linearGradient%3E%3C/defs%3E%3Cpath d='M4 23 L10 9 L16 15 L22 9 L28 23 Z' fill='url(%23m)' stroke='%2300D9FF' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E">
15
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.min.css">
16
- <style>
17
- * { margin: 0; padding: 0; box-sizing: border-box; }
18
- html, body { height: 100%; overflow: hidden; background: #0a0a1a; color: #e2e8f0; font-family: -apple-system, system-ui, sans-serif; }
19
- body { display: flex; flex-direction: column; padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
20
- #status { height: 32px; display: flex; align-items: center; justify-content: space-between; padding: 0 12px; background: #111127; border-bottom: 1px solid #1e1e3a; font-size: 12px; flex-shrink: 0; }
21
- #status .left { display: flex; align-items: center; gap: 8px; }
22
- #status .dot { width: 8px; height: 8px; border-radius: 50%; background: #444; }
23
- #status .dot.connected { background: #22c55e; }
24
- #status .dot.connecting { background: #eab308; animation: pulse 1s infinite; }
25
- #status .dot.error { background: #ef4444; }
26
- #status .label { color: #94a3b8; }
27
- #terminal-container { flex: 1; min-height: 0; }
28
- #terminal-container .xterm { height: 100%; padding: 4px; }
29
- @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
30
- @media (max-width: 600px) {
31
- #status { height: 28px; font-size: 11px; padding: 0 8px; }
32
- }
33
- </style>
34
- </head>
35
- <body>
36
- <div id="status">
37
- <div class="left">
38
- <div id="dot" class="dot connecting"></div>
39
- <span id="status-text" class="label">Connecting...</span>
40
- </div>
41
- <span class="label">Snow-Flow TUI</span>
42
- </div>
43
- <div id="terminal-container"></div>
44
- <script type="module">
45
- import { Terminal } from "https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/+esm"
46
- import { FitAddon } from "https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/+esm"
47
- import { WebLinksAddon } from "https://cdn.jsdelivr.net/npm/@xterm/addon-web-links@0.11.0/+esm"
48
-
49
- const dot = document.getElementById("dot")
50
- const statusText = document.getElementById("status-text")
51
-
52
- function setStatus(state, text) {
53
- dot.className = "dot " + state
54
- statusText.textContent = text
55
- }
56
-
57
- const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
58
-
59
- const term = new Terminal({
60
- fontSize: isMobile ? 13 : 15,
61
- fontFamily: "Menlo, 'Courier New', monospace",
62
- theme: {
63
- background: "#0a0a1a",
64
- foreground: "#e2e8f0",
65
- cursor: "#4f8ff7",
66
- cursorAccent: "#0a0a1a",
67
- selectionBackground: "rgba(79, 143, 247, 0.3)",
68
- black: "#1a1a2e",
69
- red: "#ef4444",
70
- green: "#22c55e",
71
- yellow: "#eab308",
72
- blue: "#3b82f6",
73
- magenta: "#a855f7",
74
- cyan: "#06b6d4",
75
- white: "#e2e8f0",
76
- },
77
- cursorBlink: true,
78
- convertEol: true,
79
- allowProposedApi: true,
80
- scrollback: 5000,
81
- })
82
-
83
- const fit = new FitAddon()
84
- term.loadAddon(fit)
85
- term.loadAddon(new WebLinksAddon())
86
- term.open(document.getElementById("terminal-container"))
87
- fit.fit()
88
-
89
- let ws
90
- let reconnectTimer
91
-
92
- function connect() {
93
- setStatus("connecting", "Connecting...")
94
- const proto = location.protocol === "https:" ? "wss:" : "ws:"
95
- ws = new WebSocket(proto + "//" + location.host + "/tui-ws/ws?cols=" + term.cols + "&rows=" + term.rows)
96
-
97
- ws.onopen = () => setStatus("connected", "Connected")
98
-
99
- ws.onmessage = (e) => term.write(typeof e.data === "string" ? e.data : new Uint8Array(e.data))
100
-
101
- ws.onclose = (e) => {
102
- setStatus("error", "Disconnected — reconnecting...")
103
- clearTimeout(reconnectTimer)
104
- reconnectTimer = setTimeout(connect, 2000)
105
- }
106
-
107
- ws.onerror = () => {
108
- setStatus("error", "Connection error")
109
- }
110
- }
111
-
112
- term.onData((data) => {
113
- if (ws && ws.readyState === WebSocket.OPEN) ws.send(data)
114
- })
115
-
116
- function doFit() {
117
- fit.fit()
118
- if (ws && ws.readyState === WebSocket.OPEN) {
119
- ws.send(JSON.stringify({ type: "resize", cols: term.cols, rows: term.rows }))
120
- }
121
- }
122
-
123
- window.addEventListener("resize", doFit)
124
- if (window.visualViewport) {
125
- window.visualViewport.addEventListener("resize", doFit)
126
- }
127
-
128
- connect()
129
- term.focus()
130
- </script>
131
- </body>
132
- </html>`
133
-
134
4
  export const TuiClientRoutes = lazy(() =>
135
5
  new Hono().get("/", (c) => {
136
- return c.html(HTML)
6
+ return c.redirect("/")
137
7
  }),
138
8
  )
@@ -5,7 +5,8 @@ import { describeRoute, generateSpecs, validator, resolver, openAPIRouteHandler
5
5
  import { Hono } from "hono"
6
6
  import { cors } from "hono/cors"
7
7
  import { streamSSE } from "hono/streaming"
8
- import { proxy } from "hono/proxy"
8
+ import { serveStatic } from "hono/bun"
9
+ import path from "path"
9
10
  import { basicAuth } from "hono/basic-auth"
10
11
  import z from "zod"
11
12
  import { Provider } from "../provider/provider"
@@ -531,21 +532,17 @@ export namespace Server {
531
532
  })
532
533
  },
533
534
  )
534
- .all("/*", async (c) => {
535
- const path = c.req.path
536
-
537
- const response = await proxy(`https://app.snow-flow.dev${path}`, {
538
- ...c.req,
539
- headers: {
540
- ...c.req.raw.headers,
541
- host: "app.snow-flow.dev",
542
- },
535
+ .use("/assets/*", serveStatic({ root: "./packages/app/dist" }))
536
+ .get("/*", async (c) => {
537
+ const filePath = path.join(process.cwd(), "packages/app/dist", c.req.path)
538
+ const file = Bun.file(filePath)
539
+ if (await file.exists()) {
540
+ return new Response(file)
541
+ }
542
+ // SPA fallback — serve index.html for all non-asset routes
543
+ return new Response(Bun.file(path.join(process.cwd(), "packages/app/dist/index.html")), {
544
+ headers: { "Content-Type": "text/html" },
543
545
  })
544
- response.headers.set(
545
- "Content-Security-Policy",
546
- "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self' data:",
547
- )
548
- return response
549
546
  }) as unknown as Hono,
550
547
  )
551
548