snow-flow 10.0.13 → 10.0.15
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
|
@@ -938,10 +938,11 @@ function DialogAuthEnterprise() {
|
|
|
938
938
|
const toast = useToast()
|
|
939
939
|
const { theme } = useTheme()
|
|
940
940
|
|
|
941
|
-
const [step, setStep] = createSignal<"subdomain" | "
|
|
941
|
+
const [step, setStep] = createSignal<"subdomain" | "code" | "verifying">("subdomain")
|
|
942
942
|
const [subdomain, setSubdomain] = createSignal("")
|
|
943
943
|
const [sessionId, setSessionId] = createSignal("")
|
|
944
944
|
const [authCode, setAuthCode] = createSignal("")
|
|
945
|
+
const [verificationUrl, setVerificationUrl] = createSignal("")
|
|
945
946
|
|
|
946
947
|
let subdomainInput: TextareaRenderable
|
|
947
948
|
let codeInput: TextareaRenderable
|
|
@@ -969,7 +970,7 @@ function DialogAuthEnterprise() {
|
|
|
969
970
|
const currentStep = step()
|
|
970
971
|
if (currentStep === "subdomain") {
|
|
971
972
|
dialog.replace(() => <DialogAuth />)
|
|
972
|
-
} else if (currentStep === "
|
|
973
|
+
} else if (currentStep === "code") {
|
|
973
974
|
setStep("subdomain")
|
|
974
975
|
setSessionId("")
|
|
975
976
|
setAuthCode("")
|
|
@@ -1020,24 +1021,16 @@ function DialogAuthEnterprise() {
|
|
|
1020
1021
|
|
|
1021
1022
|
// Open browser with verification URL (works in Codespaces via xdg-open)
|
|
1022
1023
|
const url = data.verificationUrl
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
duration: 10000,
|
|
1031
|
-
})
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
|
-
setStep("browser")
|
|
1024
|
+
setVerificationUrl(url)
|
|
1025
|
+
tryOpenBrowser(url).then((opened) => {
|
|
1026
|
+
if (opened) {
|
|
1027
|
+
toast.show({ variant: "info", message: "Browser opened for verification", duration: 3000 })
|
|
1028
|
+
}
|
|
1029
|
+
})
|
|
1030
|
+
Clipboard.copy(url).catch(() => {})
|
|
1035
1031
|
|
|
1036
|
-
|
|
1037
|
-
setTimeout(() =>
|
|
1038
|
-
setStep("code")
|
|
1039
|
-
setTimeout(() => codeInput?.focus(), 10)
|
|
1040
|
-
}, 2000)
|
|
1032
|
+
setStep("code")
|
|
1033
|
+
setTimeout(() => codeInput?.focus(), 10)
|
|
1041
1034
|
} catch (e) {
|
|
1042
1035
|
toast.show({ variant: "error", message: e instanceof Error ? e.message : "Failed to start auth" })
|
|
1043
1036
|
}
|
|
@@ -1256,22 +1249,21 @@ function DialogAuthEnterprise() {
|
|
|
1256
1249
|
</box>
|
|
1257
1250
|
</Show>
|
|
1258
1251
|
|
|
1259
|
-
<Show when={step() === "browser"}>
|
|
1260
|
-
<box gap={1}>
|
|
1261
|
-
<text fg={theme.primary} attributes={TextAttributes.BOLD}>
|
|
1262
|
-
Opening browser for verification...
|
|
1263
|
-
</text>
|
|
1264
|
-
<text fg={theme.textMuted}>URL: https://{subdomain()}.snow-flow.dev/device/authorize</text>
|
|
1265
|
-
<box paddingTop={1}>
|
|
1266
|
-
<text fg={theme.text}>After logging in on the portal:</text>
|
|
1267
|
-
<text fg={theme.textMuted}> 1. Click "Approve" to authorize this device</text>
|
|
1268
|
-
<text fg={theme.textMuted}> 2. Copy the authorization code shown</text>
|
|
1269
|
-
</box>
|
|
1270
|
-
</box>
|
|
1271
|
-
</Show>
|
|
1272
|
-
|
|
1273
1252
|
<Show when={step() === "code"}>
|
|
1274
1253
|
<box gap={1}>
|
|
1254
|
+
<Show when={verificationUrl()}>
|
|
1255
|
+
<text fg={theme.primary} attributes={TextAttributes.BOLD}>
|
|
1256
|
+
Verify in your browser
|
|
1257
|
+
</text>
|
|
1258
|
+
<text fg={theme.text}>Open this URL to authorize this device:</text>
|
|
1259
|
+
<text fg={theme.primary}>{verificationUrl()}</text>
|
|
1260
|
+
<box paddingTop={1}>
|
|
1261
|
+
<text fg={theme.text}>After logging in on the portal:</text>
|
|
1262
|
+
<text fg={theme.textMuted}> 1. Click "Approve" to authorize this device</text>
|
|
1263
|
+
<text fg={theme.textMuted}> 2. Copy the authorization code shown</text>
|
|
1264
|
+
<text fg={theme.textMuted}> 3. Paste it below and press Enter</text>
|
|
1265
|
+
</box>
|
|
1266
|
+
</Show>
|
|
1275
1267
|
<text fg={theme.textMuted}>Enter the authorization code from the portal</text>
|
|
1276
1268
|
<textarea
|
|
1277
1269
|
ref={(val: TextareaRenderable) => (codeInput = val)}
|
|
@@ -1318,7 +1310,6 @@ function DialogAuthEnterpriseCombined() {
|
|
|
1318
1310
|
|
|
1319
1311
|
type CombinedStep =
|
|
1320
1312
|
| "subdomain"
|
|
1321
|
-
| "browser"
|
|
1322
1313
|
| "code"
|
|
1323
1314
|
| "verifying-enterprise"
|
|
1324
1315
|
| "checking-portal-sn"
|
|
@@ -1334,6 +1325,7 @@ function DialogAuthEnterpriseCombined() {
|
|
|
1334
1325
|
const [subdomain, setSubdomain] = createSignal("")
|
|
1335
1326
|
const [sessionId, setSessionId] = createSignal("")
|
|
1336
1327
|
const [authCode, setAuthCode] = createSignal("")
|
|
1328
|
+
const [verificationUrl, setVerificationUrl] = createSignal("")
|
|
1337
1329
|
const [enterpriseData, setEnterpriseData] = createSignal<{
|
|
1338
1330
|
token?: string
|
|
1339
1331
|
user?: { username?: string; email?: string; role?: string }
|
|
@@ -1401,7 +1393,7 @@ function DialogAuthEnterpriseCombined() {
|
|
|
1401
1393
|
if (evt.name === "escape") {
|
|
1402
1394
|
if (currentStep === "subdomain") {
|
|
1403
1395
|
dialog.replace(() => <DialogAuth />)
|
|
1404
|
-
} else if (currentStep === "
|
|
1396
|
+
} else if (currentStep === "code") {
|
|
1405
1397
|
setStep("subdomain")
|
|
1406
1398
|
setSessionId("")
|
|
1407
1399
|
setAuthCode("")
|
|
@@ -1476,23 +1468,16 @@ function DialogAuthEnterpriseCombined() {
|
|
|
1476
1468
|
|
|
1477
1469
|
// Open browser with verification URL (works in Codespaces via xdg-open)
|
|
1478
1470
|
const url = data.verificationUrl
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
duration: 10000,
|
|
1487
|
-
})
|
|
1488
|
-
}
|
|
1489
|
-
|
|
1490
|
-
setStep("browser")
|
|
1471
|
+
setVerificationUrl(url)
|
|
1472
|
+
tryOpenBrowser(url).then((opened) => {
|
|
1473
|
+
if (opened) {
|
|
1474
|
+
toast.show({ variant: "info", message: "Browser opened for verification", duration: 3000 })
|
|
1475
|
+
}
|
|
1476
|
+
})
|
|
1477
|
+
Clipboard.copy(url).catch(() => {})
|
|
1491
1478
|
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
setTimeout(() => codeInput?.focus(), 10)
|
|
1495
|
-
}, 2000)
|
|
1479
|
+
setStep("code")
|
|
1480
|
+
setTimeout(() => codeInput?.focus(), 10)
|
|
1496
1481
|
} catch (e) {
|
|
1497
1482
|
toast.show({ variant: "error", message: e instanceof Error ? e.message : "Failed to start auth" })
|
|
1498
1483
|
}
|
|
@@ -1915,28 +1900,22 @@ function DialogAuthEnterpriseCombined() {
|
|
|
1915
1900
|
</box>
|
|
1916
1901
|
</Show>
|
|
1917
1902
|
|
|
1918
|
-
{/* Step 2:
|
|
1919
|
-
<Show when={step() === "browser"}>
|
|
1920
|
-
<box gap={1}>
|
|
1921
|
-
<text fg={theme.primary} attributes={TextAttributes.BOLD}>
|
|
1922
|
-
Step 1 of 2: Enterprise Portal
|
|
1923
|
-
</text>
|
|
1924
|
-
<text fg={theme.text}>Opening browser for verification...</text>
|
|
1925
|
-
<text fg={theme.textMuted}>URL: https://{subdomain()}.snow-flow.dev/device/authorize</text>
|
|
1926
|
-
<box paddingTop={1}>
|
|
1927
|
-
<text fg={theme.text}>After logging in on the portal:</text>
|
|
1928
|
-
<text fg={theme.textMuted}> 1. Click "Approve" to authorize this device</text>
|
|
1929
|
-
<text fg={theme.textMuted}> 2. Copy the authorization code shown</text>
|
|
1930
|
-
</box>
|
|
1931
|
-
</box>
|
|
1932
|
-
</Show>
|
|
1933
|
-
|
|
1934
|
-
{/* Step 3: Enter auth code */}
|
|
1903
|
+
{/* Step 2: Verify in browser + enter auth code */}
|
|
1935
1904
|
<Show when={step() === "code"}>
|
|
1936
1905
|
<box gap={1}>
|
|
1937
1906
|
<text fg={theme.primary} attributes={TextAttributes.BOLD}>
|
|
1938
1907
|
Step 1 of 2: Enterprise Portal
|
|
1939
1908
|
</text>
|
|
1909
|
+
<Show when={verificationUrl()}>
|
|
1910
|
+
<text fg={theme.text}>Open this URL to authorize this device:</text>
|
|
1911
|
+
<text fg={theme.primary}>{verificationUrl()}</text>
|
|
1912
|
+
<box paddingTop={1}>
|
|
1913
|
+
<text fg={theme.text}>After logging in on the portal:</text>
|
|
1914
|
+
<text fg={theme.textMuted}> 1. Click "Approve" to authorize this device</text>
|
|
1915
|
+
<text fg={theme.textMuted}> 2. Copy the authorization code shown</text>
|
|
1916
|
+
<text fg={theme.textMuted}> 3. Paste it below and press Enter</text>
|
|
1917
|
+
</box>
|
|
1918
|
+
</Show>
|
|
1940
1919
|
<text fg={theme.textMuted}>Enter the authorization code from the portal</text>
|
|
1941
1920
|
<textarea
|
|
1942
1921
|
ref={(val: TextareaRenderable) => (codeInput = val)}
|
package/src/config/config.ts
CHANGED
|
@@ -26,6 +26,7 @@ import { BunProc } from "@/bun"
|
|
|
26
26
|
import { Installation } from "@/installation"
|
|
27
27
|
import { ConfigMarkdown } from "./markdown"
|
|
28
28
|
import { existsSync } from "fs"
|
|
29
|
+
import { execSync } from "child_process"
|
|
29
30
|
import { Bus } from "@/bus"
|
|
30
31
|
import { GlobalBus } from "@/bus/global"
|
|
31
32
|
import { Event } from "../server/event"
|
|
@@ -207,6 +208,26 @@ export namespace Config {
|
|
|
207
208
|
}
|
|
208
209
|
})
|
|
209
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Detect the best available JS runtime command.
|
|
213
|
+
* Prefers bun if available, falls back to node.
|
|
214
|
+
*/
|
|
215
|
+
function getRuntime(): string {
|
|
216
|
+
try {
|
|
217
|
+
execSync("bun --version", { stdio: "ignore" })
|
|
218
|
+
return "bun"
|
|
219
|
+
} catch {
|
|
220
|
+
return "node"
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
let _cachedRuntime: string | undefined
|
|
225
|
+
|
|
226
|
+
function runtime(): string {
|
|
227
|
+
if (_cachedRuntime === undefined) _cachedRuntime = getRuntime()
|
|
228
|
+
return _cachedRuntime
|
|
229
|
+
}
|
|
230
|
+
|
|
210
231
|
/**
|
|
211
232
|
* Get the MCP server command based on whether we're running bundled or in development
|
|
212
233
|
*/
|
|
@@ -269,9 +290,9 @@ export namespace Config {
|
|
|
269
290
|
log.info("checking bundled path", { bundledPath, exists })
|
|
270
291
|
if (exists) {
|
|
271
292
|
log.info("found bundled MCP server", { serverName, path: bundledPath })
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
return [
|
|
293
|
+
const rt = runtime()
|
|
294
|
+
log.info("using runtime for MCP server", { runtime: rt })
|
|
295
|
+
return [rt, "run", bundledPath]
|
|
275
296
|
}
|
|
276
297
|
}
|
|
277
298
|
|
|
@@ -295,7 +316,7 @@ export namespace Config {
|
|
|
295
316
|
})
|
|
296
317
|
}
|
|
297
318
|
|
|
298
|
-
return [
|
|
319
|
+
return [runtime(), "run", serverPath]
|
|
299
320
|
}
|
|
300
321
|
|
|
301
322
|
/**
|