@openchambery/web 1.17.1-beta.7 → 1.17.1-beta.8
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/README.md +3 -39
- package/bin/cli-output.js +0 -16
- package/bin/cli.js +3 -66
- package/bin/cli.test.js +4 -81
- package/bin/lib/DOCUMENTATION.md +5 -19
- package/bin/lib/cli-args.js +3 -327
- package/bin/lib/cli-http.js +0 -16
- package/bin/lib/cli-lifecycle.js +2 -111
- package/bin/lib/cli-paths.js +0 -57
- package/dist/assets/{AgentAvatar-htFrIvQx.js → AgentAvatar-C6Hxu5_o.js} +1 -1
- package/dist/assets/{AssistantView-BZiJsNuI.js → AssistantView-ZlXc0xFT.js} +1 -1
- package/dist/assets/{ChatContainer-CdmcMnL3.js → ChatContainer-BXFy3Uu2.js} +5 -5
- package/dist/assets/{DiagramView-B7sq74V-.js → DiagramView-CgotrQyK.js} +1 -1
- package/dist/assets/{FadeInOnReveal-8fY7XL23.js → FadeInOnReveal-CvNA_aGD.js} +1 -1
- package/dist/assets/{Icon-B7eLbnyj.js → Icon-BPJ_quEe.js} +1 -1
- package/dist/assets/{MarkdownRendererImpl-DICju9ve.js → MarkdownRendererImpl-Cj4y0P0S.js} +1 -1
- package/dist/assets/{MobileDetailNavigation-CuxWU1yf.js → MobileDetailNavigation-5tAL5d_M.js} +1 -1
- package/dist/assets/{MobileShareBridge-CPg9Eyro.js → MobileShareBridge-BL7Ehxhd.js} +1 -1
- package/dist/assets/{MobileSurface-D7sDH_tx.js → MobileSurface-ByMnQ5rD.js} +1 -1
- package/dist/assets/{MultiRunWindow-MSO0Equt.js → MultiRunWindow-Che7L3TX.js} +1 -1
- package/dist/assets/{OnboardingScreen-C87u_MLg.js → OnboardingScreen-CdvaEBtt.js} +1 -1
- package/dist/assets/{OverlayScrollbar-Kmmybw-z.js → OverlayScrollbar-C2pEDFq-.js} +1 -1
- package/dist/assets/SettingsView-D0p-e8Px.js +25 -0
- package/dist/assets/{SettingsWindow-Bl25cfXX.js → SettingsWindow-KYhsFUrb.js} +1 -1
- package/dist/assets/{TerminalView-jR5jP1b0.js → TerminalView-Da5aLqHR.js} +1 -1
- package/dist/assets/{ToolOutputDialog-DCEZb2DZ.js → ToolOutputDialog-DZI4uxx3.js} +1 -1
- package/dist/assets/{appThemeRegistry-aiRF-s3c.js → appThemeRegistry-DAgBeFsZ.js} +2 -2
- package/dist/assets/{button-bYWkDtDI.js → button-BmNJBT13.js} +1 -1
- package/dist/assets/{clipboard-CzpzN4Um.js → clipboard-CXWbHCAk.js} +1 -1
- package/dist/assets/{collapsible-A1PFvMRp.js → collapsible-68IqWBM1.js} +1 -1
- package/dist/assets/{context-menu-CkpHn-Bm.js → context-menu-BXH0AcOc.js} +1 -1
- package/dist/assets/desktopHosts-BpjUSDz4.js +1 -0
- package/dist/assets/{desktopRelayRestore-C5vYnSTd.js → desktopRelayRestore-BzUEk1i7.js} +1 -1
- package/dist/assets/{diagram-BkwKWaTO.js → diagram-YN0GZ1Q0.js} +1 -1
- package/dist/assets/{dialog-DW7-_iqo.js → dialog-BV1ENlLf.js} +1 -1
- package/dist/assets/es-EXZUX1sB.js +15 -0
- package/dist/assets/{fileQueries-P9SX4YwC.js → fileQueries-i4oziMnC.js} +1 -1
- package/dist/assets/fr-jWNPO91J.js +13 -0
- package/dist/assets/{gitApi-CMsZ2v08.js → gitApi-BW5AFgD1.js} +1 -1
- package/dist/assets/{gitApiHttp-DvIIcDAO.js → gitApiHttp-C1DaEMKR.js} +1 -1
- package/dist/assets/{input-B9aNttqV.js → input-BLVhPvhN.js} +1 -1
- package/dist/assets/{insertionBoundaries-Di3rCXgN.js → insertionBoundaries-D4KbXFFj.js} +1 -1
- package/dist/assets/ja-Dcb0VtDE.js +15 -0
- package/dist/assets/ko-CX71xNDX.js +15 -0
- package/dist/assets/{main-DY27kMV5.js → main-CcyyPAib.js} +2 -2
- package/dist/assets/{main-Chtf300b.js → main-DzxdsF_k.js} +5 -5
- package/dist/assets/{markdown-worker-BoB1_DPo.js → markdown-worker-Cq3Twp1A.js} +1 -1
- package/dist/assets/{markdownTheme-om5XcPqq.js → markdownTheme-CCnvI6L0.js} +1 -1
- package/dist/assets/{miniChat-BWbpl5SN.js → miniChat-BsNf9y48.js} +2 -2
- package/dist/assets/mobile-CsJg2IAq.js +2 -0
- package/dist/assets/{multirun-BfPcVktg.js → multirun-qs5hZkwM.js} +1 -1
- package/dist/assets/persistence-C_KCiMcY.js +3 -0
- package/dist/assets/{pl-BSjLn4dm.js → pl-mR_3Sqr8.js} +2 -2
- package/dist/assets/{projectMeta-CiAR7MRG.js → projectMeta-1SSTNg8w.js} +1 -1
- package/dist/assets/pt-BR-D1RpVOvC.js +15 -0
- package/dist/assets/radio-DBJG9Dd1.js +1 -0
- package/dist/assets/{renderElectronMiniChatApp-CiEXAVSt.js → renderElectronMiniChatApp-DOWE0jSA.js} +2 -2
- package/dist/assets/{renderMobileApp-BHvgSVPk.js → renderMobileApp-bklJJSZi.js} +3 -3
- package/dist/assets/{runtimeConfig-49YbZaqI.js → runtimeConfig-JSaYFA5x.js} +1 -1
- package/dist/assets/{runtimeEndpointReset-CdhtjuPe.js → runtimeEndpointReset-ix1NxqYw.js} +1 -1
- package/dist/assets/{sortable-tabs-strip-XeYica3j.js → sortable-tabs-strip-DncWjNx4.js} +1 -1
- package/dist/assets/src-B8mzksNL.css +2 -0
- package/dist/assets/store-oojlrF4d.js +15 -0
- package/dist/assets/{terminalApi-DAu7xKli.js → terminalApi-BYTA045F.js} +1 -1
- package/dist/assets/{tooltip-BSlxaNrR.js → tooltip-BYGBBTc2.js} +1 -1
- package/dist/assets/uk-UvnVqWv-.js +15 -0
- package/dist/assets/{url-DjkTDrad.js → url-CGHw6D-E.js} +1 -1
- package/dist/assets/useAppFontEffects-B1EhZNex.js +7 -0
- package/dist/assets/{useDesktopWindowControlsLayout-BwYnhrEy.js → useDesktopWindowControlsLayout-Dc69l-pm.js} +1 -1
- package/dist/assets/{useEffectiveDirectory-CEmsrrEs.js → useEffectiveDirectory-dCGvvYRh.js} +1 -1
- package/dist/assets/{useFontPreferences-BxMT_kty.js → useFontPreferences-Bu4ME5hk.js} +1 -1
- package/dist/assets/{useMobileNavigationStore-DryW-QdG.js → useMobileNavigationStore-DhkIZBJw.js} +4 -4
- package/dist/assets/useSessionAutoCleanup-D-r9oDye.js +1 -0
- package/dist/assets/{useWorkerHighlightedLines-CFW2AoPL.js → useWorkerHighlightedLines-05dLFgTI.js} +1 -1
- package/dist/assets/{utils-RUACCsOs.js → utils-DyUyiLje.js} +1 -1
- package/dist/assets/zh-CN-9v-RC966.js +15 -0
- package/dist/assets/zh-TW-BZ_wZdC-.js +15 -0
- package/dist/index.html +8 -8
- package/dist/mini-chat.html +8 -8
- package/dist/mobile.html +8 -8
- package/package.json +1 -1
- package/server/index.d.ts +0 -6
- package/server/index.js +5 -153
- package/server/lib/opencode/DOCUMENTATION.md +6 -10
- package/server/lib/opencode/cli-entry-runtime.js +0 -10
- package/server/lib/opencode/cli-options.js +0 -65
- package/server/lib/opencode/core-routes.js +2 -4
- package/server/lib/opencode/routes.test.js +0 -1
- package/server/lib/opencode/server-startup-runtime.js +0 -55
- package/server/lib/opencode/settings-helpers.js +0 -55
- package/server/lib/opencode/settings-helpers.test.js +0 -20
- package/server/lib/opencode/settings-normalization-runtime.js +0 -87
- package/server/lib/opencode/settings-normalization-runtime.test.js +0 -3
- package/server/lib/opencode/settings-runtime.js +9 -102
- package/server/lib/opencode/settings-runtime.test.js +0 -10
- package/server/lib/opencode/shutdown-runtime.js +1 -9
- package/server/lib/opencode/shutdown-runtime.test.js +0 -2
- package/server/lib/opencode/startup-pipeline-runtime.js +0 -20
- package/server/lib/opencode/startup-pipeline-runtime.test.js +2 -3
- package/server/lib/opencode/tunnel-wiring-runtime.js +2 -80
- package/server/lib/relay/DOCUMENTATION.md +1 -1
- package/bin/lib/cli-tunnel-capabilities.js +0 -9
- package/bin/lib/cli-tunnel-profiles.js +0 -366
- package/bin/lib/cli-tunnel-utils.js +0 -300
- package/bin/lib/commands-tunnel.js +0 -1761
- package/dist/assets/SettingsView-5YNu54KI.js +0 -25
- package/dist/assets/desktopHosts-D5m_ggY1.js +0 -1
- package/dist/assets/es-Cei_75Jt.js +0 -15
- package/dist/assets/fr-Dn7WSHh2.js +0 -13
- package/dist/assets/ja-DFARVqVj.js +0 -15
- package/dist/assets/ko-pyLnIyDY.js +0 -15
- package/dist/assets/mobile-DEQeGskq.js +0 -2
- package/dist/assets/persistence-CHA81Od7.js +0 -3
- package/dist/assets/pt-BR-DaWvr_0A.js +0 -15
- package/dist/assets/radio-BnF4XhCC.js +0 -1
- package/dist/assets/src-BtkWqMFu.css +0 -2
- package/dist/assets/store-DIpqFVjs.js +0 -15
- package/dist/assets/uk-CHCRqRKf.js +0 -15
- package/dist/assets/useAppFontEffects-BRNICZS2.js +0 -7
- package/dist/assets/useSessionAutoCleanup-DMJ1LiW_.js +0 -1
- package/dist/assets/zh-CN-BWEQZKXk.js +0 -15
- package/dist/assets/zh-TW-BbO-gJq3.js +0 -15
- package/server/lib/cloudflare-tunnel.js +0 -618
- package/server/lib/ngrok-tunnel.js +0 -343
- package/server/lib/ngrok-tunnel.test.js +0 -50
- package/server/lib/tunnels/DOCUMENTATION.md +0 -21
- package/server/lib/tunnels/executable-search.js +0 -140
- package/server/lib/tunnels/executable-search.test.js +0 -96
- package/server/lib/tunnels/index.js +0 -179
- package/server/lib/tunnels/index.test.js +0 -93
- package/server/lib/tunnels/install-help.js +0 -56
- package/server/lib/tunnels/install-help.test.js +0 -31
- package/server/lib/tunnels/managed-config.js +0 -201
- package/server/lib/tunnels/providers/cloudflare.js +0 -266
- package/server/lib/tunnels/providers/ngrok.js +0 -123
- package/server/lib/tunnels/registry.js +0 -51
- package/server/lib/tunnels/routes.js +0 -610
- package/server/lib/tunnels/types.js +0 -245
- package/server/lib/tunnels/types.test.js +0 -34
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
export const createServerStartupRuntime = (dependencies) => {
|
|
2
2
|
const {
|
|
3
3
|
process,
|
|
4
|
-
crypto,
|
|
5
4
|
server,
|
|
6
|
-
normalizeTunnelBootstrapTtlMs,
|
|
7
|
-
readSettingsFromDiskMigrated,
|
|
8
|
-
tunnelAuthController,
|
|
9
|
-
startTunnelWithNormalizedRequest,
|
|
10
5
|
gracefulShutdown,
|
|
11
6
|
getSignalsAttached,
|
|
12
7
|
setSignalsAttached,
|
|
13
8
|
syncToHmrState,
|
|
14
|
-
TUNNEL_MODE_QUICK,
|
|
15
|
-
TUNNEL_MODE_MANAGED_LOCAL,
|
|
16
|
-
TUNNEL_MODE_MANAGED_REMOTE,
|
|
17
9
|
} = dependencies;
|
|
18
10
|
|
|
19
11
|
const resolveBindHost = (host) =>
|
|
@@ -25,8 +17,6 @@ export const createServerStartupRuntime = (dependencies) => {
|
|
|
25
17
|
const startListeningAndMaybeTunnel = async ({
|
|
26
18
|
port,
|
|
27
19
|
bindHost,
|
|
28
|
-
startupTunnelRequest,
|
|
29
|
-
onTunnelReady,
|
|
30
20
|
}) => {
|
|
31
21
|
let activePort = port;
|
|
32
22
|
|
|
@@ -69,51 +59,6 @@ export const createServerStartupRuntime = (dependencies) => {
|
|
|
69
59
|
console.log(`Health check: http://${displayHost}:${activePort}/health`);
|
|
70
60
|
console.log(`Web interface: http://${displayHost}:${activePort}`);
|
|
71
61
|
|
|
72
|
-
if (startupTunnelRequest) {
|
|
73
|
-
const startupModeLabel = startupTunnelRequest.mode === TUNNEL_MODE_QUICK
|
|
74
|
-
? 'Quick Tunnel'
|
|
75
|
-
: (startupTunnelRequest.mode === TUNNEL_MODE_MANAGED_LOCAL
|
|
76
|
-
? 'Managed Local Tunnel'
|
|
77
|
-
: (startupTunnelRequest.mode === TUNNEL_MODE_MANAGED_REMOTE ? 'Managed Remote Tunnel' : 'Tunnel'));
|
|
78
|
-
console.log(`\nInitializing ${startupModeLabel} for provider '${startupTunnelRequest.provider}'...`);
|
|
79
|
-
try {
|
|
80
|
-
const { publicUrl, mode } = await startTunnelWithNormalizedRequest({
|
|
81
|
-
provider: startupTunnelRequest.provider,
|
|
82
|
-
mode: startupTunnelRequest.mode,
|
|
83
|
-
intent: startupTunnelRequest.intent,
|
|
84
|
-
hostname: startupTunnelRequest.hostname,
|
|
85
|
-
token: startupTunnelRequest.token,
|
|
86
|
-
configPath: startupTunnelRequest.configPath,
|
|
87
|
-
selectedPresetId: '',
|
|
88
|
-
selectedPresetName: '',
|
|
89
|
-
});
|
|
90
|
-
if (publicUrl) {
|
|
91
|
-
tunnelAuthController.setActiveTunnel({
|
|
92
|
-
tunnelId: crypto.randomUUID(),
|
|
93
|
-
publicUrl,
|
|
94
|
-
mode,
|
|
95
|
-
});
|
|
96
|
-
const settings = await readSettingsFromDiskMigrated();
|
|
97
|
-
const bootstrapTtlMs = settings?.tunnelBootstrapTtlMs === null
|
|
98
|
-
? null
|
|
99
|
-
: normalizeTunnelBootstrapTtlMs(settings?.tunnelBootstrapTtlMs);
|
|
100
|
-
const bootstrapToken = tunnelAuthController.issueBootstrapToken({ ttlMs: bootstrapTtlMs });
|
|
101
|
-
const connectUrl = `${publicUrl.replace(/\/$/, '')}/connect?t=${encodeURIComponent(bootstrapToken.token)}`;
|
|
102
|
-
if (onTunnelReady) {
|
|
103
|
-
onTunnelReady(publicUrl, connectUrl);
|
|
104
|
-
} else {
|
|
105
|
-
console.log(`\n🌐 Tunnel URL: ${connectUrl}`);
|
|
106
|
-
console.log('🔑 One-time connect link (expires after first use)\n');
|
|
107
|
-
}
|
|
108
|
-
} else if (onTunnelReady) {
|
|
109
|
-
onTunnelReady(publicUrl, null);
|
|
110
|
-
}
|
|
111
|
-
} catch (error) {
|
|
112
|
-
console.error(`Failed to start tunnel: ${error.message}`);
|
|
113
|
-
console.log('Continuing without tunnel...');
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
62
|
resolve();
|
|
118
63
|
} catch (error) {
|
|
119
64
|
reject(error);
|
|
@@ -57,14 +57,6 @@ export const createSettingsHelpers = (dependencies) => {
|
|
|
57
57
|
const {
|
|
58
58
|
normalizePathForPersistence,
|
|
59
59
|
normalizeDirectoryPath,
|
|
60
|
-
normalizeTunnelBootstrapTtlMs,
|
|
61
|
-
normalizeTunnelSessionTtlMs,
|
|
62
|
-
normalizeTunnelProvider,
|
|
63
|
-
normalizeTunnelMode,
|
|
64
|
-
normalizeOptionalPath,
|
|
65
|
-
normalizeManagedRemoteTunnelHostname,
|
|
66
|
-
normalizeManagedRemoteTunnelPresets,
|
|
67
|
-
normalizeManagedRemoteTunnelPresetTokens,
|
|
68
60
|
sanitizeTypographySizesPartial,
|
|
69
61
|
normalizeStringArray,
|
|
70
62
|
sanitizeModelRefs,
|
|
@@ -408,50 +400,6 @@ export const createSettingsHelpers = (dependencies) => {
|
|
|
408
400
|
const normalizedDays = Math.max(1, Math.min(365, Math.round(candidate.autoDeleteAfterDays)));
|
|
409
401
|
result.autoDeleteAfterDays = normalizedDays;
|
|
410
402
|
}
|
|
411
|
-
if (candidate.tunnelBootstrapTtlMs === null) {
|
|
412
|
-
result.tunnelBootstrapTtlMs = null;
|
|
413
|
-
} else if (typeof candidate.tunnelBootstrapTtlMs === 'number' && Number.isFinite(candidate.tunnelBootstrapTtlMs)) {
|
|
414
|
-
result.tunnelBootstrapTtlMs = normalizeTunnelBootstrapTtlMs(candidate.tunnelBootstrapTtlMs);
|
|
415
|
-
}
|
|
416
|
-
if (typeof candidate.tunnelSessionTtlMs === 'number' && Number.isFinite(candidate.tunnelSessionTtlMs)) {
|
|
417
|
-
result.tunnelSessionTtlMs = normalizeTunnelSessionTtlMs(candidate.tunnelSessionTtlMs);
|
|
418
|
-
}
|
|
419
|
-
if (typeof candidate.tunnelProvider === 'string') {
|
|
420
|
-
const provider = normalizeTunnelProvider(candidate.tunnelProvider);
|
|
421
|
-
if (provider) {
|
|
422
|
-
result.tunnelProvider = provider;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
if (typeof candidate.tunnelMode === 'string') {
|
|
426
|
-
result.tunnelMode = normalizeTunnelMode(candidate.tunnelMode);
|
|
427
|
-
}
|
|
428
|
-
if (candidate.managedLocalTunnelConfigPath === null) {
|
|
429
|
-
result.managedLocalTunnelConfigPath = null;
|
|
430
|
-
} else if (typeof candidate.managedLocalTunnelConfigPath === 'string') {
|
|
431
|
-
const trimmed = candidate.managedLocalTunnelConfigPath.trim();
|
|
432
|
-
result.managedLocalTunnelConfigPath = trimmed.length > 0 ? normalizeOptionalPath(trimmed) : null;
|
|
433
|
-
}
|
|
434
|
-
if (typeof candidate.managedRemoteTunnelHostname === 'string') {
|
|
435
|
-
const hostname = normalizeManagedRemoteTunnelHostname(candidate.managedRemoteTunnelHostname);
|
|
436
|
-
result.managedRemoteTunnelHostname = hostname;
|
|
437
|
-
}
|
|
438
|
-
if (candidate.managedRemoteTunnelToken === null) {
|
|
439
|
-
result.managedRemoteTunnelToken = null;
|
|
440
|
-
} else if (typeof candidate.managedRemoteTunnelToken === 'string') {
|
|
441
|
-
result.managedRemoteTunnelToken = candidate.managedRemoteTunnelToken.trim();
|
|
442
|
-
}
|
|
443
|
-
const managedRemoteTunnelPresets = normalizeManagedRemoteTunnelPresets(candidate.managedRemoteTunnelPresets);
|
|
444
|
-
if (managedRemoteTunnelPresets) {
|
|
445
|
-
result.managedRemoteTunnelPresets = managedRemoteTunnelPresets;
|
|
446
|
-
}
|
|
447
|
-
const managedRemoteTunnelPresetTokens = normalizeManagedRemoteTunnelPresetTokens(candidate.managedRemoteTunnelPresetTokens);
|
|
448
|
-
if (managedRemoteTunnelPresetTokens) {
|
|
449
|
-
result.managedRemoteTunnelPresetTokens = managedRemoteTunnelPresetTokens;
|
|
450
|
-
}
|
|
451
|
-
if (typeof candidate.managedRemoteTunnelSelectedPresetId === 'string') {
|
|
452
|
-
const id = candidate.managedRemoteTunnelSelectedPresetId.trim();
|
|
453
|
-
result.managedRemoteTunnelSelectedPresetId = id || undefined;
|
|
454
|
-
}
|
|
455
403
|
|
|
456
404
|
const typography = sanitizeTypographySizesPartial(candidate.typographySizes);
|
|
457
405
|
if (typography) {
|
|
@@ -945,10 +893,8 @@ export const createSettingsHelpers = (dependencies) => {
|
|
|
945
893
|
|
|
946
894
|
const formatSettingsResponse = (settings) => {
|
|
947
895
|
const sanitized = sanitizeSettingsUpdate(settings);
|
|
948
|
-
delete sanitized.managedRemoteTunnelToken;
|
|
949
896
|
delete sanitized.summaryCustomAPIToken;
|
|
950
897
|
const bookmarks = normalizeStringArray(settings.securityScopedBookmarks);
|
|
951
|
-
const hasManagedRemoteTunnelToken = typeof settings?.managedRemoteTunnelToken === 'string' && settings.managedRemoteTunnelToken.trim().length > 0;
|
|
952
898
|
const hasSummaryCustomAPIToken = typeof settings?.summaryCustomAPIToken === 'string' && settings.summaryCustomAPIToken.trim().length > 0;
|
|
953
899
|
const pwaAppName = normalizePwaAppName(settings?.pwaAppName, '');
|
|
954
900
|
const pwaOrientation = normalizePwaOrientation(settings?.pwaOrientation, 'system');
|
|
@@ -956,7 +902,6 @@ export const createSettingsHelpers = (dependencies) => {
|
|
|
956
902
|
|
|
957
903
|
return {
|
|
958
904
|
...sanitized,
|
|
959
|
-
hasManagedRemoteTunnelToken,
|
|
960
905
|
hasSummaryCustomAPIToken,
|
|
961
906
|
...(pwaAppName ? { pwaAppName } : {}),
|
|
962
907
|
pwaOrientation,
|
|
@@ -6,14 +6,6 @@ import { createSettingsNormalizationRuntime } from './settings-normalization-run
|
|
|
6
6
|
const createTestHelpers = () => createSettingsHelpers({
|
|
7
7
|
normalizePathForPersistence: (value) => value,
|
|
8
8
|
normalizeDirectoryPath: (value) => value,
|
|
9
|
-
normalizeTunnelBootstrapTtlMs: (value) => value,
|
|
10
|
-
normalizeTunnelSessionTtlMs: (value) => value,
|
|
11
|
-
normalizeTunnelProvider: (value) => value,
|
|
12
|
-
normalizeTunnelMode: (value) => value,
|
|
13
|
-
normalizeOptionalPath: (value) => value,
|
|
14
|
-
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
15
|
-
normalizeManagedRemoteTunnelPresets: () => undefined,
|
|
16
|
-
normalizeManagedRemoteTunnelPresetTokens: () => undefined,
|
|
17
9
|
sanitizeTypographySizesPartial: () => undefined,
|
|
18
10
|
normalizeStringArray: (input) => input,
|
|
19
11
|
sanitizeModelRefs: () => undefined,
|
|
@@ -31,9 +23,6 @@ const createTestHelpersWithRealSanitizers = () => {
|
|
|
31
23
|
},
|
|
32
24
|
processLike: { platform: 'linux', env: {} },
|
|
33
25
|
realpathSync: (p) => p,
|
|
34
|
-
tunnelBootstrapTtlDefaultMs: 600000,
|
|
35
|
-
tunnelBootstrapTtlMinMs: 60000,
|
|
36
|
-
tunnelBootstrapTtlMaxMs: 3600000,
|
|
37
26
|
tunnelSessionTtlDefaultMs: 86400000,
|
|
38
27
|
tunnelSessionTtlMinMs: 3600000,
|
|
39
28
|
tunnelSessionTtlMaxMs: 604800000,
|
|
@@ -41,14 +30,6 @@ const createTestHelpersWithRealSanitizers = () => {
|
|
|
41
30
|
return createSettingsHelpers({
|
|
42
31
|
normalizePathForPersistence: (value) => value,
|
|
43
32
|
normalizeDirectoryPath: (value) => value,
|
|
44
|
-
normalizeTunnelBootstrapTtlMs: (value) => value,
|
|
45
|
-
normalizeTunnelSessionTtlMs: (value) => value,
|
|
46
|
-
normalizeTunnelProvider: (value) => value,
|
|
47
|
-
normalizeTunnelMode: (value) => value,
|
|
48
|
-
normalizeOptionalPath: (value) => value,
|
|
49
|
-
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
50
|
-
normalizeManagedRemoteTunnelPresets: () => undefined,
|
|
51
|
-
normalizeManagedRemoteTunnelPresetTokens: () => undefined,
|
|
52
33
|
sanitizeTypographySizesPartial: () => undefined,
|
|
53
34
|
normalizeStringArray: runtime.normalizeStringArray,
|
|
54
35
|
sanitizeModelRefs: runtime.sanitizeModelRefs,
|
|
@@ -305,7 +286,6 @@ describe('settings helpers', () => {
|
|
|
305
286
|
const secretSentinel = 'bootstrap-secret-sentinel';
|
|
306
287
|
const response = helpers.projectBootstrapSettingsResponse({
|
|
307
288
|
summaryCustomAPIToken: secretSentinel,
|
|
308
|
-
managedRemoteTunnelToken: secretSentinel,
|
|
309
289
|
defaultModel: 'm'.repeat(513),
|
|
310
290
|
messageStreamTransport: 'websocket',
|
|
311
291
|
sttProvider: 'server',
|
|
@@ -4,9 +4,6 @@ export const createSettingsNormalizationRuntime = (dependencies) => {
|
|
|
4
4
|
path,
|
|
5
5
|
processLike,
|
|
6
6
|
realpathSync,
|
|
7
|
-
tunnelBootstrapTtlDefaultMs,
|
|
8
|
-
tunnelBootstrapTtlMinMs,
|
|
9
|
-
tunnelBootstrapTtlMaxMs,
|
|
10
7
|
tunnelSessionTtlDefaultMs,
|
|
11
8
|
tunnelSessionTtlMinMs,
|
|
12
9
|
tunnelSessionTtlMaxMs,
|
|
@@ -267,16 +264,6 @@ export const createSettingsNormalizationRuntime = (dependencies) => {
|
|
|
267
264
|
|
|
268
265
|
const clampNumber = (value, min, max) => Math.max(min, Math.min(max, value));
|
|
269
266
|
|
|
270
|
-
const normalizeTunnelBootstrapTtlMs = (value) => {
|
|
271
|
-
if (value === null) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
if (!Number.isFinite(value)) {
|
|
275
|
-
return tunnelBootstrapTtlDefaultMs;
|
|
276
|
-
}
|
|
277
|
-
return clampNumber(Math.round(value), tunnelBootstrapTtlMinMs, tunnelBootstrapTtlMaxMs);
|
|
278
|
-
};
|
|
279
|
-
|
|
280
267
|
const normalizeTunnelSessionTtlMs = (value) => {
|
|
281
268
|
if (!Number.isFinite(value)) {
|
|
282
269
|
return tunnelSessionTtlDefaultMs;
|
|
@@ -284,76 +271,6 @@ export const createSettingsNormalizationRuntime = (dependencies) => {
|
|
|
284
271
|
return clampNumber(Math.round(value), tunnelSessionTtlMinMs, tunnelSessionTtlMaxMs);
|
|
285
272
|
};
|
|
286
273
|
|
|
287
|
-
const normalizeManagedRemoteTunnelHostname = (value) => {
|
|
288
|
-
if (typeof value !== 'string') {
|
|
289
|
-
return undefined;
|
|
290
|
-
}
|
|
291
|
-
const trimmed = value.trim();
|
|
292
|
-
if (!trimmed) {
|
|
293
|
-
return undefined;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
const parsed = (() => {
|
|
297
|
-
try {
|
|
298
|
-
if (trimmed.includes('://')) {
|
|
299
|
-
return new URL(trimmed);
|
|
300
|
-
}
|
|
301
|
-
return new URL(`https://${trimmed}`);
|
|
302
|
-
} catch {
|
|
303
|
-
return null;
|
|
304
|
-
}
|
|
305
|
-
})();
|
|
306
|
-
|
|
307
|
-
const hostname = parsed?.hostname?.trim().toLowerCase() || '';
|
|
308
|
-
if (!hostname) {
|
|
309
|
-
return undefined;
|
|
310
|
-
}
|
|
311
|
-
return hostname;
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
const normalizeManagedRemoteTunnelPresets = (value) => {
|
|
315
|
-
if (!Array.isArray(value)) {
|
|
316
|
-
return undefined;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const result = [];
|
|
320
|
-
const seenIds = new Set();
|
|
321
|
-
const seenHostnames = new Set();
|
|
322
|
-
|
|
323
|
-
for (const entry of value) {
|
|
324
|
-
if (!entry || typeof entry !== 'object') continue;
|
|
325
|
-
const candidate = entry;
|
|
326
|
-
const id = typeof candidate.id === 'string' ? candidate.id.trim() : '';
|
|
327
|
-
const name = typeof candidate.name === 'string' ? candidate.name.trim() : '';
|
|
328
|
-
const hostname = normalizeManagedRemoteTunnelHostname(candidate.hostname);
|
|
329
|
-
if (!id || !name || !hostname) continue;
|
|
330
|
-
if (seenIds.has(id) || seenHostnames.has(hostname)) continue;
|
|
331
|
-
seenIds.add(id);
|
|
332
|
-
seenHostnames.add(hostname);
|
|
333
|
-
result.push({ id, name, hostname });
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
return result;
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
const normalizeManagedRemoteTunnelPresetTokens = (value) => {
|
|
340
|
-
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
341
|
-
return undefined;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const result = {};
|
|
345
|
-
for (const [rawId, rawToken] of Object.entries(value)) {
|
|
346
|
-
const id = typeof rawId === 'string' ? rawId.trim() : '';
|
|
347
|
-
const token = typeof rawToken === 'string' ? rawToken.trim() : '';
|
|
348
|
-
if (!id || !token) {
|
|
349
|
-
continue;
|
|
350
|
-
}
|
|
351
|
-
result[id] = token;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
return Object.keys(result).length > 0 ? result : undefined;
|
|
355
|
-
};
|
|
356
|
-
|
|
357
274
|
const isUnsafeSkillRelativePath = (value) => {
|
|
358
275
|
if (typeof value !== 'string' || value.length === 0) {
|
|
359
276
|
return true;
|
|
@@ -452,11 +369,7 @@ export const createSettingsNormalizationRuntime = (dependencies) => {
|
|
|
452
369
|
normalizeDirectoryPath,
|
|
453
370
|
normalizePathForPersistence,
|
|
454
371
|
normalizeSettingsPaths,
|
|
455
|
-
normalizeTunnelBootstrapTtlMs,
|
|
456
372
|
normalizeTunnelSessionTtlMs,
|
|
457
|
-
normalizeManagedRemoteTunnelHostname,
|
|
458
|
-
normalizeManagedRemoteTunnelPresets,
|
|
459
|
-
normalizeManagedRemoteTunnelPresetTokens,
|
|
460
373
|
isUnsafeSkillRelativePath,
|
|
461
374
|
sanitizeTypographySizesPartial,
|
|
462
375
|
normalizeStringArray,
|
|
@@ -12,9 +12,6 @@ const createTestRuntime = (overrides = {}) => {
|
|
|
12
12
|
},
|
|
13
13
|
processLike: { platform: 'linux', env: {} },
|
|
14
14
|
realpathSync: (p) => p,
|
|
15
|
-
tunnelBootstrapTtlDefaultMs: 600000,
|
|
16
|
-
tunnelBootstrapTtlMinMs: 60000,
|
|
17
|
-
tunnelBootstrapTtlMaxMs: 3600000,
|
|
18
15
|
tunnelSessionTtlDefaultMs: 86400000,
|
|
19
16
|
tunnelSessionTtlMinMs: 3600000,
|
|
20
17
|
tunnelSessionTtlMaxMs: 604800000,
|
|
@@ -39,11 +39,6 @@ export const createSettingsRuntime = (deps) => {
|
|
|
39
39
|
normalizeStringArray,
|
|
40
40
|
formatSettingsResponse,
|
|
41
41
|
resolveDirectoryCandidate,
|
|
42
|
-
normalizeManagedRemoteTunnelHostname,
|
|
43
|
-
normalizeManagedRemoteTunnelPresets,
|
|
44
|
-
normalizeManagedRemoteTunnelPresetTokens,
|
|
45
|
-
syncManagedRemoteTunnelConfigWithPresets,
|
|
46
|
-
upsertManagedRemoteTunnelToken,
|
|
47
42
|
} = deps;
|
|
48
43
|
|
|
49
44
|
let persistSettingsLock = Promise.resolve();
|
|
@@ -725,67 +720,6 @@ export const createSettingsRuntime = (deps) => {
|
|
|
725
720
|
return { settings: changed ? next : settings, changed };
|
|
726
721
|
};
|
|
727
722
|
|
|
728
|
-
const migrateSettingsFromLegacyNamedTunnelKeys = async (current) => {
|
|
729
|
-
const settings = current && typeof current === 'object' ? current : {};
|
|
730
|
-
const next = { ...settings };
|
|
731
|
-
let changed = false;
|
|
732
|
-
|
|
733
|
-
if (!Object.prototype.hasOwnProperty.call(next, 'managedRemoteTunnelHostname')
|
|
734
|
-
&& Object.prototype.hasOwnProperty.call(next, 'namedTunnelHostname')) {
|
|
735
|
-
next.managedRemoteTunnelHostname = normalizeManagedRemoteTunnelHostname(next.namedTunnelHostname);
|
|
736
|
-
changed = true;
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
if (!Object.prototype.hasOwnProperty.call(next, 'managedRemoteTunnelToken')
|
|
740
|
-
&& Object.prototype.hasOwnProperty.call(next, 'namedTunnelToken')) {
|
|
741
|
-
if (next.namedTunnelToken === null) {
|
|
742
|
-
next.managedRemoteTunnelToken = null;
|
|
743
|
-
} else if (typeof next.namedTunnelToken === 'string') {
|
|
744
|
-
next.managedRemoteTunnelToken = next.namedTunnelToken.trim();
|
|
745
|
-
}
|
|
746
|
-
changed = true;
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
if (!Object.prototype.hasOwnProperty.call(next, 'managedRemoteTunnelPresets')
|
|
750
|
-
&& Object.prototype.hasOwnProperty.call(next, 'namedTunnelPresets')) {
|
|
751
|
-
next.managedRemoteTunnelPresets = normalizeManagedRemoteTunnelPresets(next.namedTunnelPresets);
|
|
752
|
-
changed = true;
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
if (!Object.prototype.hasOwnProperty.call(next, 'managedRemoteTunnelPresetTokens')
|
|
756
|
-
&& Object.prototype.hasOwnProperty.call(next, 'namedTunnelPresetTokens')) {
|
|
757
|
-
next.managedRemoteTunnelPresetTokens = normalizeManagedRemoteTunnelPresetTokens(next.namedTunnelPresetTokens);
|
|
758
|
-
changed = true;
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
if (!Object.prototype.hasOwnProperty.call(next, 'managedRemoteTunnelSelectedPresetId')
|
|
762
|
-
&& Object.prototype.hasOwnProperty.call(next, 'namedTunnelSelectedPresetId')) {
|
|
763
|
-
const selectedPresetId = typeof next.namedTunnelSelectedPresetId === 'string'
|
|
764
|
-
? next.namedTunnelSelectedPresetId.trim()
|
|
765
|
-
: '';
|
|
766
|
-
if (selectedPresetId) {
|
|
767
|
-
next.managedRemoteTunnelSelectedPresetId = selectedPresetId;
|
|
768
|
-
}
|
|
769
|
-
changed = true;
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const legacyKeys = [
|
|
773
|
-
'namedTunnelHostname',
|
|
774
|
-
'namedTunnelToken',
|
|
775
|
-
'namedTunnelPresets',
|
|
776
|
-
'namedTunnelPresetTokens',
|
|
777
|
-
'namedTunnelSelectedPresetId',
|
|
778
|
-
];
|
|
779
|
-
for (const key of legacyKeys) {
|
|
780
|
-
if (Object.prototype.hasOwnProperty.call(next, key)) {
|
|
781
|
-
delete next[key];
|
|
782
|
-
changed = true;
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
|
|
786
|
-
return { settings: changed ? next : settings, changed };
|
|
787
|
-
};
|
|
788
|
-
|
|
789
723
|
// `approvedDirectories` was a write-only registry: every project path and
|
|
790
724
|
// visited directory was appended forever, but nothing ever read it. Strip
|
|
791
725
|
// the stale key from persisted settings on upgrade.
|
|
@@ -839,21 +773,20 @@ export const createSettingsRuntime = (deps) => {
|
|
|
839
773
|
const migration2 = await migrateSettingsFromLegacyThemePreferences(migration1.settings);
|
|
840
774
|
const migration3 = await migrateSettingsFromLegacyCollapsedProjects(migration2.settings);
|
|
841
775
|
const migration4 = await migrateSettingsNotificationDefaults(migration3.settings);
|
|
842
|
-
const migration5 =
|
|
843
|
-
const migration6 =
|
|
844
|
-
const migration7 =
|
|
845
|
-
const migration8 =
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
return migration9.settings;
|
|
776
|
+
const migration5 = normalizeSettingsPaths(migration4.settings);
|
|
777
|
+
const migration6 = await migrateSettingsToDeterministicProjectIds(migration5.settings);
|
|
778
|
+
const migration7 = migrateSettingsRemoveApprovedDirectories(migration6.settings);
|
|
779
|
+
const migration8 = migrateSettingsCompactChatDefaults(migration7.settings);
|
|
780
|
+
if (migration1.changed || migration2.changed || migration3.changed || migration4.changed || migration5.changed || migration6.changed || migration7.changed || migration8.changed) {
|
|
781
|
+
await writeSettingsToDisk(migration8.settings);
|
|
782
|
+
}
|
|
783
|
+
return migration8.settings;
|
|
851
784
|
};
|
|
852
785
|
|
|
853
786
|
const persistSettings = async (changes) => {
|
|
854
787
|
persistSettingsLock = persistSettingsLock.then(async () => {
|
|
855
788
|
// Log field names only — changes can carry credentials (UI password,
|
|
856
|
-
// client tokens
|
|
789
|
+
// client tokens) that must never reach the log file.
|
|
857
790
|
console.log('[persistSettings] Updating fields:', Object.keys(changes || {}).join(', ') || '(none)');
|
|
858
791
|
const current = await readSettingsFromDisk();
|
|
859
792
|
const sanitized = sanitizeSettingsUpdate(changes);
|
|
@@ -900,32 +833,6 @@ export const createSettingsRuntime = (deps) => {
|
|
|
900
833
|
next = { ...next, activeProjectId: undefined };
|
|
901
834
|
}
|
|
902
835
|
|
|
903
|
-
if (Object.prototype.hasOwnProperty.call(sanitized, 'managedRemoteTunnelPresets')) {
|
|
904
|
-
await syncManagedRemoteTunnelConfigWithPresets(next.managedRemoteTunnelPresets);
|
|
905
|
-
}
|
|
906
|
-
|
|
907
|
-
if (Object.prototype.hasOwnProperty.call(sanitized, 'managedRemoteTunnelPresetTokens') && sanitized.managedRemoteTunnelPresetTokens) {
|
|
908
|
-
const presetsById = new Map((next.managedRemoteTunnelPresets || []).map((entry) => [entry.id, entry]));
|
|
909
|
-
const updates = Object.entries(sanitized.managedRemoteTunnelPresetTokens)
|
|
910
|
-
.map(([presetId, token]) => {
|
|
911
|
-
const preset = presetsById.get(presetId);
|
|
912
|
-
if (!preset || typeof token !== 'string' || token.trim().length === 0) {
|
|
913
|
-
return null;
|
|
914
|
-
}
|
|
915
|
-
return {
|
|
916
|
-
id: preset.id,
|
|
917
|
-
name: preset.name,
|
|
918
|
-
hostname: preset.hostname,
|
|
919
|
-
token: token.trim(),
|
|
920
|
-
};
|
|
921
|
-
})
|
|
922
|
-
.filter(Boolean);
|
|
923
|
-
|
|
924
|
-
for (const update of updates) {
|
|
925
|
-
await upsertManagedRemoteTunnelToken(update);
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
|
|
929
836
|
await writeSettingsToDisk(next);
|
|
930
837
|
return formatSettingsResponse(next);
|
|
931
838
|
});
|
|
@@ -21,11 +21,6 @@ const createRuntime = async () => {
|
|
|
21
21
|
normalizeStringArray: (values) => Array.isArray(values) ? values.filter((value) => typeof value === 'string') : [],
|
|
22
22
|
formatSettingsResponse: (settings) => settings,
|
|
23
23
|
resolveDirectoryCandidate: (value) => value,
|
|
24
|
-
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
25
|
-
normalizeManagedRemoteTunnelPresets: (value) => value,
|
|
26
|
-
normalizeManagedRemoteTunnelPresetTokens: (value) => value,
|
|
27
|
-
syncManagedRemoteTunnelConfigWithPresets: async () => {},
|
|
28
|
-
upsertManagedRemoteTunnelToken: async () => {},
|
|
29
24
|
});
|
|
30
25
|
|
|
31
26
|
return {
|
|
@@ -218,11 +213,6 @@ describe('settings runtime', () => {
|
|
|
218
213
|
normalizeStringArray: (values) => Array.isArray(values) ? values.filter((value) => typeof value === 'string') : [],
|
|
219
214
|
formatSettingsResponse: (settings) => settings,
|
|
220
215
|
resolveDirectoryCandidate: (value) => value,
|
|
221
|
-
normalizeManagedRemoteTunnelHostname: (value) => value,
|
|
222
|
-
normalizeManagedRemoteTunnelPresets: (value) => value,
|
|
223
|
-
normalizeManagedRemoteTunnelPresetTokens: (value) => value,
|
|
224
|
-
syncManagedRemoteTunnelConfigWithPresets: async () => {},
|
|
225
|
-
upsertManagedRemoteTunnelToken: async () => {},
|
|
226
216
|
});
|
|
227
217
|
|
|
228
218
|
try {
|
|
@@ -27,8 +27,6 @@ export const createGracefulShutdownRuntime = (dependencies) => {
|
|
|
27
27
|
getServer,
|
|
28
28
|
getUiAuthController,
|
|
29
29
|
setUiAuthController,
|
|
30
|
-
getActiveTunnelController,
|
|
31
|
-
setActiveTunnelController,
|
|
32
30
|
tunnelAuthController,
|
|
33
31
|
closeFeatureRoutes,
|
|
34
32
|
} = dependencies;
|
|
@@ -135,13 +133,7 @@ export const createGracefulShutdownRuntime = (dependencies) => {
|
|
|
135
133
|
setUiAuthController(null);
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
if (activeTunnelController) {
|
|
140
|
-
console.log('Stopping active tunnel...');
|
|
141
|
-
activeTunnelController.stop();
|
|
142
|
-
setActiveTunnelController(null);
|
|
143
|
-
tunnelAuthController.clearActiveTunnel();
|
|
144
|
-
}
|
|
136
|
+
tunnelAuthController?.clearActiveTunnel?.();
|
|
145
137
|
|
|
146
138
|
console.log('Graceful shutdown complete');
|
|
147
139
|
if (exitProcess) {
|
|
@@ -27,8 +27,6 @@ const createRuntime = (server, shutdownTimeoutMs = 1000, overrides = {}) => crea
|
|
|
27
27
|
getServer: () => server,
|
|
28
28
|
getUiAuthController: () => null,
|
|
29
29
|
setUiAuthController: vi.fn(),
|
|
30
|
-
getActiveTunnelController: () => null,
|
|
31
|
-
setActiveTunnelController: vi.fn(),
|
|
32
30
|
tunnelAuthController: { clearActiveTunnel: vi.fn() },
|
|
33
31
|
...overrides,
|
|
34
32
|
});
|
|
@@ -35,22 +35,12 @@ export const createStartupPipelineRuntime = (dependencies) => {
|
|
|
35
35
|
setManagedOpenCodeBridgeOrigin,
|
|
36
36
|
staticRoutesRuntime,
|
|
37
37
|
process,
|
|
38
|
-
crypto,
|
|
39
|
-
normalizeTunnelBootstrapTtlMs,
|
|
40
|
-
readSettingsFromDiskMigrated,
|
|
41
|
-
tunnelAuthController,
|
|
42
|
-
startTunnelWithNormalizedRequest,
|
|
43
38
|
gracefulShutdown,
|
|
44
39
|
getSignalsAttached,
|
|
45
40
|
setSignalsAttached,
|
|
46
41
|
syncToHmrState,
|
|
47
|
-
TUNNEL_MODE_QUICK,
|
|
48
|
-
TUNNEL_MODE_MANAGED_LOCAL,
|
|
49
|
-
TUNNEL_MODE_MANAGED_REMOTE,
|
|
50
42
|
host,
|
|
51
43
|
port,
|
|
52
|
-
startupTunnelRequest,
|
|
53
|
-
onTunnelReady,
|
|
54
44
|
tunnelRuntimeContext,
|
|
55
45
|
attachSignals,
|
|
56
46
|
apiOnly,
|
|
@@ -109,27 +99,17 @@ export const createStartupPipelineRuntime = (dependencies) => {
|
|
|
109
99
|
|
|
110
100
|
const serverStartupRuntime = createServerStartupRuntime({
|
|
111
101
|
process,
|
|
112
|
-
crypto,
|
|
113
102
|
server,
|
|
114
|
-
normalizeTunnelBootstrapTtlMs,
|
|
115
|
-
readSettingsFromDiskMigrated,
|
|
116
|
-
tunnelAuthController,
|
|
117
|
-
startTunnelWithNormalizedRequest,
|
|
118
103
|
gracefulShutdown,
|
|
119
104
|
getSignalsAttached,
|
|
120
105
|
setSignalsAttached,
|
|
121
106
|
syncToHmrState,
|
|
122
|
-
TUNNEL_MODE_QUICK,
|
|
123
|
-
TUNNEL_MODE_MANAGED_LOCAL,
|
|
124
|
-
TUNNEL_MODE_MANAGED_REMOTE,
|
|
125
107
|
});
|
|
126
108
|
|
|
127
109
|
const bindHost = serverStartupRuntime.resolveBindHost(host);
|
|
128
110
|
const startupResult = await serverStartupRuntime.startListeningAndMaybeTunnel({
|
|
129
111
|
port,
|
|
130
112
|
bindHost,
|
|
131
|
-
startupTunnelRequest,
|
|
132
|
-
onTunnelReady,
|
|
133
113
|
});
|
|
134
114
|
tunnelRuntimeContext.setActivePort(startupResult.activePort);
|
|
135
115
|
if (typeof setManagedOpenCodeBridgeOrigin === 'function') {
|
|
@@ -13,9 +13,8 @@ describe('startup pipeline runtime', () => {
|
|
|
13
13
|
isRequestOriginAllowed: () => true, rejectWebSocketUpgrade: () => {}, buildOpenCodeUrl: () => '', getOpenCodeAuthHeaders: () => ({}), globalEventHub: {}, processForwardedEventPayload: () => {}, messageStreamWsClients: new Set(), triggerHealthCheck: () => {}, upstreamStallTimeoutMs: 1,
|
|
14
14
|
terminalHeartbeatIntervalMs: 1, terminalRebindWindowMs: 1, terminalMaxRebindsPerWindow: 1, setupProxy: () => {}, scheduleOpenCodeApiDetection: () => {},
|
|
15
15
|
bootstrapOpenCodeAtStartup: () => { order.push('bootstrap'); }, setManagedOpenCodeBridgeOrigin: (origin) => { order.push(origin); },
|
|
16
|
-
staticRoutesRuntime: { registerStaticRoutes: () => {}, registerApiOnlyFallbackRoutes: () => {} }, process: {},
|
|
17
|
-
|
|
18
|
-
TUNNEL_MODE_QUICK: 'quick', TUNNEL_MODE_MANAGED_LOCAL: 'local', TUNNEL_MODE_MANAGED_REMOTE: 'remote', host: '127.0.0.1', port: 0, startupTunnelRequest: null, onTunnelReady: () => {}, tunnelRuntimeContext: { setActivePort: () => {} }, attachSignals: false, apiOnly: false, dictationModelsDir: '',
|
|
16
|
+
staticRoutesRuntime: { registerStaticRoutes: () => {}, registerApiOnlyFallbackRoutes: () => {} }, process: {}, gracefulShutdown: () => {}, getSignalsAttached: () => false, setSignalsAttached: () => {}, syncToHmrState: () => {},
|
|
17
|
+
host: '127.0.0.1', port: 0, tunnelRuntimeContext: { setActivePort: () => {} }, attachSignals: false, apiOnly: false, dictationModelsDir: '',
|
|
19
18
|
});
|
|
20
19
|
expect(order).toEqual(['http://127.0.0.1:41234', 'bootstrap']);
|
|
21
20
|
});
|