@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,300 +0,0 @@
|
|
|
1
|
-
import { EXIT_CODE, TunnelCliError } from './cli-errors.js';
|
|
2
|
-
import { canPrompt, select as clackSelect, text as clackText, cancel as clackCancel, isCancel as clackIsCancel } from '../cli-output.js';
|
|
3
|
-
|
|
4
|
-
const TUNNEL_BOOTSTRAP_TTL_DEFAULT_MS = 30 * 60 * 1000;
|
|
5
|
-
const TUNNEL_BOOTSTRAP_TTL_MIN_MS = 60 * 1000;
|
|
6
|
-
const TUNNEL_BOOTSTRAP_TTL_MAX_MS = 24 * 60 * 60 * 1000;
|
|
7
|
-
const TUNNEL_SESSION_TTL_DEFAULT_MS = 8 * 60 * 60 * 1000;
|
|
8
|
-
const TUNNEL_SESSION_TTL_MIN_MS = 5 * 60 * 1000;
|
|
9
|
-
const TUNNEL_SESSION_TTL_MAX_MS = 30 * 24 * 60 * 60 * 1000;
|
|
10
|
-
const CONNECT_TTL_PICKER_OPTIONS = [
|
|
11
|
-
{ value: String(3 * 60 * 1000), label: '3m' },
|
|
12
|
-
{ value: String(TUNNEL_BOOTSTRAP_TTL_DEFAULT_MS), label: '30m' },
|
|
13
|
-
{ value: String(2 * 60 * 60 * 1000), label: '2h' },
|
|
14
|
-
{ value: String(8 * 60 * 60 * 1000), label: '8h' },
|
|
15
|
-
{ value: String(24 * 60 * 60 * 1000), label: '24h' },
|
|
16
|
-
{ value: '__custom__', label: 'Custom' },
|
|
17
|
-
];
|
|
18
|
-
const SESSION_TTL_PICKER_OPTIONS = [
|
|
19
|
-
{ value: String(60 * 60 * 1000), label: '1h' },
|
|
20
|
-
{ value: String(TUNNEL_SESSION_TTL_DEFAULT_MS), label: '8h' },
|
|
21
|
-
{ value: String(12 * 60 * 60 * 1000), label: '12h' },
|
|
22
|
-
{ value: String(24 * 60 * 60 * 1000), label: '24h' },
|
|
23
|
-
{ value: String(7 * 24 * 60 * 60 * 1000), label: '1w' },
|
|
24
|
-
{ value: String(30 * 24 * 60 * 60 * 1000), label: '30d' },
|
|
25
|
-
{ value: '__custom__', label: 'Custom' },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
function parseHumanDurationToMs(value) {
|
|
29
|
-
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
30
|
-
return Math.round(value);
|
|
31
|
-
}
|
|
32
|
-
if (typeof value !== 'string') {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const trimmed = value.trim().toLowerCase();
|
|
37
|
-
if (!trimmed) {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (/^\d+$/.test(trimmed)) {
|
|
42
|
-
return Number.parseInt(trimmed, 10);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const normalized = trimmed.replace(/\s+/g, '');
|
|
46
|
-
const pattern = /(\d+)(ms|s|m|h|d)/g;
|
|
47
|
-
let cursor = 0;
|
|
48
|
-
let total = 0;
|
|
49
|
-
let match;
|
|
50
|
-
while ((match = pattern.exec(normalized)) !== null) {
|
|
51
|
-
if (match.index !== cursor) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
cursor = pattern.lastIndex;
|
|
55
|
-
const amount = Number.parseInt(match[1], 10);
|
|
56
|
-
const unit = match[2];
|
|
57
|
-
const unitMs = unit === 'ms'
|
|
58
|
-
? 1
|
|
59
|
-
: unit === 's'
|
|
60
|
-
? 1000
|
|
61
|
-
: unit === 'm'
|
|
62
|
-
? 60 * 1000
|
|
63
|
-
: unit === 'h'
|
|
64
|
-
? 60 * 60 * 1000
|
|
65
|
-
: 24 * 60 * 60 * 1000;
|
|
66
|
-
total += amount * unitMs;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
if (cursor !== normalized.length) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return total;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function parseTtlMsOrThrow(rawValue, {
|
|
77
|
-
flagName,
|
|
78
|
-
minMs,
|
|
79
|
-
maxMs,
|
|
80
|
-
} = {}) {
|
|
81
|
-
const parsed = parseHumanDurationToMs(rawValue);
|
|
82
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
83
|
-
throw new TunnelCliError(
|
|
84
|
-
`Invalid value for ${flagName}. Use a positive duration like 30m, 24h, 1d, or milliseconds.`,
|
|
85
|
-
EXIT_CODE.USAGE_ERROR,
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
if (parsed < minMs || parsed > maxMs) {
|
|
89
|
-
throw new TunnelCliError(
|
|
90
|
-
`${flagName} must be between ${minMs}ms and ${maxMs}ms.`,
|
|
91
|
-
EXIT_CODE.USAGE_ERROR,
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
return parsed;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
function formatDurationForCli(ms) {
|
|
98
|
-
if (!Number.isFinite(ms) || ms <= 0) {
|
|
99
|
-
return null;
|
|
100
|
-
}
|
|
101
|
-
const value = Math.round(ms);
|
|
102
|
-
if (value % (24 * 60 * 60 * 1000) === 0) return `${value / (24 * 60 * 60 * 1000)}d`;
|
|
103
|
-
if (value % (60 * 60 * 1000) === 0) return `${value / (60 * 60 * 1000)}h`;
|
|
104
|
-
if (value % (60 * 1000) === 0) return `${value / (60 * 1000)}m`;
|
|
105
|
-
if (value % 1000 === 0) return `${value / 1000}s`;
|
|
106
|
-
return `${value}ms`;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function shellQuote(value) {
|
|
110
|
-
const text = String(value);
|
|
111
|
-
if (/^[A-Za-z0-9._\-/:=]+$/.test(text)) {
|
|
112
|
-
return text;
|
|
113
|
-
}
|
|
114
|
-
return `'${text.replace(/'/g, `'"'"'`)}'`;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function buildTunnelStartReplayCommand({
|
|
118
|
-
port,
|
|
119
|
-
provider,
|
|
120
|
-
mode,
|
|
121
|
-
profileName,
|
|
122
|
-
configPath,
|
|
123
|
-
hostname,
|
|
124
|
-
connectTtlMs,
|
|
125
|
-
sessionTtlMs,
|
|
126
|
-
qr,
|
|
127
|
-
noQr,
|
|
128
|
-
includeTokenPlaceholder,
|
|
129
|
-
tokenViaStdin,
|
|
130
|
-
tokenFileProvided,
|
|
131
|
-
}) {
|
|
132
|
-
const parts = ['openchamber', 'tunnel', 'start'];
|
|
133
|
-
if (Number.isFinite(port) && port > 0) {
|
|
134
|
-
parts.push('--port', String(port));
|
|
135
|
-
}
|
|
136
|
-
if (profileName) {
|
|
137
|
-
parts.push('--profile', shellQuote(profileName));
|
|
138
|
-
}
|
|
139
|
-
if (provider) {
|
|
140
|
-
parts.push('--provider', shellQuote(provider));
|
|
141
|
-
}
|
|
142
|
-
if (mode) {
|
|
143
|
-
parts.push('--mode', shellQuote(mode));
|
|
144
|
-
}
|
|
145
|
-
if (typeof configPath === 'string' && configPath.trim().length > 0) {
|
|
146
|
-
parts.push('--config', shellQuote(configPath));
|
|
147
|
-
}
|
|
148
|
-
if (typeof hostname === 'string' && hostname.trim().length > 0) {
|
|
149
|
-
parts.push('--hostname', shellQuote(hostname));
|
|
150
|
-
}
|
|
151
|
-
const connectTtl = formatDurationForCli(connectTtlMs);
|
|
152
|
-
if (connectTtl) {
|
|
153
|
-
parts.push('--connect-ttl', connectTtl);
|
|
154
|
-
}
|
|
155
|
-
const sessionTtl = formatDurationForCli(sessionTtlMs);
|
|
156
|
-
if (sessionTtl) {
|
|
157
|
-
parts.push('--session-ttl', sessionTtl);
|
|
158
|
-
}
|
|
159
|
-
if (qr) parts.push('--qr');
|
|
160
|
-
if (noQr) parts.push('--no-qr');
|
|
161
|
-
|
|
162
|
-
if (includeTokenPlaceholder) {
|
|
163
|
-
if (tokenViaStdin) {
|
|
164
|
-
parts.push('--token-stdin');
|
|
165
|
-
} else if (tokenFileProvided) {
|
|
166
|
-
parts.push('--token-file', '<redacted>');
|
|
167
|
-
} else {
|
|
168
|
-
parts.push('--token', '<redacted>');
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return parts.join(' ');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
function buildTunnelProfileAddCommand({ provider, hostname }) {
|
|
176
|
-
const parts = [
|
|
177
|
-
'openchamber',
|
|
178
|
-
'tunnel',
|
|
179
|
-
'profile',
|
|
180
|
-
'add',
|
|
181
|
-
'--provider',
|
|
182
|
-
shellQuote(provider || 'cloudflare'),
|
|
183
|
-
'--mode',
|
|
184
|
-
'managed-remote',
|
|
185
|
-
'--name',
|
|
186
|
-
'<name>',
|
|
187
|
-
'--hostname',
|
|
188
|
-
shellQuote(hostname || '<hostname>'),
|
|
189
|
-
'--token',
|
|
190
|
-
'<token>',
|
|
191
|
-
];
|
|
192
|
-
return parts.join(' ');
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
async function resolveTunnelTtlOverrides(options) {
|
|
196
|
-
let connectTtlRaw = typeof options.connectTtl === 'string' ? options.connectTtl : undefined;
|
|
197
|
-
let sessionTtlRaw = typeof options.sessionTtl === 'string' ? options.sessionTtl : undefined;
|
|
198
|
-
|
|
199
|
-
const shouldPrompt = !connectTtlRaw
|
|
200
|
-
&& !sessionTtlRaw
|
|
201
|
-
&& canPrompt(options);
|
|
202
|
-
|
|
203
|
-
if (shouldPrompt) {
|
|
204
|
-
const connectChoice = await clackSelect({
|
|
205
|
-
message: 'Select connect-link TTL',
|
|
206
|
-
options: CONNECT_TTL_PICKER_OPTIONS,
|
|
207
|
-
});
|
|
208
|
-
if (clackIsCancel(connectChoice)) {
|
|
209
|
-
clackCancel('Tunnel start cancelled.');
|
|
210
|
-
return null;
|
|
211
|
-
}
|
|
212
|
-
if (connectChoice === '__custom__') {
|
|
213
|
-
const enteredConnect = await clackText({
|
|
214
|
-
message: 'Enter connect-link TTL (e.g. 30m, 2h, 1d)',
|
|
215
|
-
placeholder: '30m',
|
|
216
|
-
validate(value) {
|
|
217
|
-
try {
|
|
218
|
-
parseTtlMsOrThrow(value, {
|
|
219
|
-
flagName: '--connect-ttl',
|
|
220
|
-
minMs: TUNNEL_BOOTSTRAP_TTL_MIN_MS,
|
|
221
|
-
maxMs: TUNNEL_BOOTSTRAP_TTL_MAX_MS,
|
|
222
|
-
});
|
|
223
|
-
return undefined;
|
|
224
|
-
} catch (error) {
|
|
225
|
-
return error instanceof Error ? error.message : 'Invalid TTL value';
|
|
226
|
-
}
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
if (clackIsCancel(enteredConnect)) {
|
|
230
|
-
clackCancel('Tunnel start cancelled.');
|
|
231
|
-
return null;
|
|
232
|
-
}
|
|
233
|
-
connectTtlRaw = enteredConnect.trim();
|
|
234
|
-
} else {
|
|
235
|
-
connectTtlRaw = connectChoice;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const sessionChoice = await clackSelect({
|
|
239
|
-
message: 'Select session TTL',
|
|
240
|
-
options: SESSION_TTL_PICKER_OPTIONS,
|
|
241
|
-
});
|
|
242
|
-
if (clackIsCancel(sessionChoice)) {
|
|
243
|
-
clackCancel('Tunnel start cancelled.');
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
if (sessionChoice === '__custom__') {
|
|
247
|
-
const enteredSession = await clackText({
|
|
248
|
-
message: 'Enter session TTL (e.g. 8h, 24h, 1d)',
|
|
249
|
-
placeholder: '8h',
|
|
250
|
-
validate(value) {
|
|
251
|
-
try {
|
|
252
|
-
parseTtlMsOrThrow(value, {
|
|
253
|
-
flagName: '--session-ttl',
|
|
254
|
-
minMs: TUNNEL_SESSION_TTL_MIN_MS,
|
|
255
|
-
maxMs: TUNNEL_SESSION_TTL_MAX_MS,
|
|
256
|
-
});
|
|
257
|
-
return undefined;
|
|
258
|
-
} catch (error) {
|
|
259
|
-
return error instanceof Error ? error.message : 'Invalid TTL value';
|
|
260
|
-
}
|
|
261
|
-
},
|
|
262
|
-
});
|
|
263
|
-
if (clackIsCancel(enteredSession)) {
|
|
264
|
-
clackCancel('Tunnel start cancelled.');
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
sessionTtlRaw = enteredSession.trim();
|
|
268
|
-
} else {
|
|
269
|
-
sessionTtlRaw = sessionChoice;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
const connectTtlMs = connectTtlRaw !== undefined
|
|
274
|
-
? parseTtlMsOrThrow(connectTtlRaw, {
|
|
275
|
-
flagName: '--connect-ttl',
|
|
276
|
-
minMs: TUNNEL_BOOTSTRAP_TTL_MIN_MS,
|
|
277
|
-
maxMs: TUNNEL_BOOTSTRAP_TTL_MAX_MS,
|
|
278
|
-
})
|
|
279
|
-
: undefined;
|
|
280
|
-
|
|
281
|
-
const sessionTtlMs = sessionTtlRaw !== undefined
|
|
282
|
-
? parseTtlMsOrThrow(sessionTtlRaw, {
|
|
283
|
-
flagName: '--session-ttl',
|
|
284
|
-
minMs: TUNNEL_SESSION_TTL_MIN_MS,
|
|
285
|
-
maxMs: TUNNEL_SESSION_TTL_MAX_MS,
|
|
286
|
-
})
|
|
287
|
-
: undefined;
|
|
288
|
-
|
|
289
|
-
return {
|
|
290
|
-
connectTtlMs,
|
|
291
|
-
sessionTtlMs,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
export {
|
|
297
|
-
buildTunnelStartReplayCommand,
|
|
298
|
-
buildTunnelProfileAddCommand,
|
|
299
|
-
resolveTunnelTtlOverrides,
|
|
300
|
-
};
|