@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
package/bin/lib/cli-args.js
CHANGED
|
@@ -63,23 +63,11 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
63
63
|
all: false,
|
|
64
64
|
follow: true,
|
|
65
65
|
lines: DEFAULT_TAIL_LINES,
|
|
66
|
-
provider: undefined,
|
|
67
|
-
mode: undefined,
|
|
68
|
-
profile: undefined,
|
|
69
66
|
name: undefined,
|
|
70
|
-
configPath: undefined,
|
|
71
|
-
token: undefined,
|
|
72
|
-
tokenFile: undefined,
|
|
73
|
-
tokenStdin: false,
|
|
74
67
|
hostname: undefined,
|
|
75
68
|
server: undefined,
|
|
76
|
-
connectTtl: undefined,
|
|
77
|
-
sessionTtl: undefined,
|
|
78
69
|
qr: false,
|
|
79
70
|
explicitQr: false,
|
|
80
|
-
force: false,
|
|
81
|
-
showSecrets: false,
|
|
82
|
-
dryRun: false,
|
|
83
71
|
plain: false,
|
|
84
72
|
quiet: false,
|
|
85
73
|
explicitPort: false,
|
|
@@ -170,51 +158,12 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
170
158
|
options.explicitUiPassword = true;
|
|
171
159
|
break;
|
|
172
160
|
}
|
|
173
|
-
case 'provider': {
|
|
174
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
175
|
-
i = nextIndex;
|
|
176
|
-
options.provider = typeof value === 'string' ? value : options.provider;
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
case 'mode': {
|
|
180
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
181
|
-
i = nextIndex;
|
|
182
|
-
options.mode = typeof value === 'string' ? value : options.mode;
|
|
183
|
-
break;
|
|
184
|
-
}
|
|
185
|
-
case 'profile': {
|
|
186
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
187
|
-
i = nextIndex;
|
|
188
|
-
options.profile = typeof value === 'string' ? value : options.profile;
|
|
189
|
-
break;
|
|
190
|
-
}
|
|
191
161
|
case 'name': {
|
|
192
162
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
193
163
|
i = nextIndex;
|
|
194
164
|
options.name = typeof value === 'string' ? value : options.name;
|
|
195
165
|
break;
|
|
196
166
|
}
|
|
197
|
-
case 'config': {
|
|
198
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
199
|
-
i = nextIndex;
|
|
200
|
-
options.configPath = typeof value === 'string' ? value : null;
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
case 'token': {
|
|
204
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
205
|
-
i = nextIndex;
|
|
206
|
-
options.token = typeof value === 'string' ? value : options.token;
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
case 'token-file': {
|
|
210
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
211
|
-
i = nextIndex;
|
|
212
|
-
options.tokenFile = typeof value === 'string' ? value : options.tokenFile;
|
|
213
|
-
break;
|
|
214
|
-
}
|
|
215
|
-
case 'token-stdin':
|
|
216
|
-
options.tokenStdin = true;
|
|
217
|
-
break;
|
|
218
167
|
case 'hostname': {
|
|
219
168
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
220
169
|
i = nextIndex;
|
|
@@ -231,18 +180,6 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
231
180
|
options.server = value.trim();
|
|
232
181
|
break;
|
|
233
182
|
}
|
|
234
|
-
case 'connect-ttl': {
|
|
235
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
236
|
-
i = nextIndex;
|
|
237
|
-
options.connectTtl = typeof value === 'string' ? value : options.connectTtl;
|
|
238
|
-
break;
|
|
239
|
-
}
|
|
240
|
-
case 'session-ttl': {
|
|
241
|
-
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
242
|
-
i = nextIndex;
|
|
243
|
-
options.sessionTtl = typeof value === 'string' ? value : options.sessionTtl;
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
183
|
case 'json':
|
|
247
184
|
options.json = true;
|
|
248
185
|
break;
|
|
@@ -275,15 +212,6 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
275
212
|
options.qr = false;
|
|
276
213
|
options.explicitQr = true;
|
|
277
214
|
break;
|
|
278
|
-
case 'force':
|
|
279
|
-
options.force = true;
|
|
280
|
-
break;
|
|
281
|
-
case 'show-secrets':
|
|
282
|
-
options.showSecrets = true;
|
|
283
|
-
break;
|
|
284
|
-
case 'dry-run':
|
|
285
|
-
options.dryRun = true;
|
|
286
|
-
break;
|
|
287
215
|
case 'plain':
|
|
288
216
|
options.plain = true;
|
|
289
217
|
break;
|
|
@@ -312,21 +240,15 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
312
240
|
// may still pass this when starting a remote server.
|
|
313
241
|
break;
|
|
314
242
|
case 'try-cf-tunnel':
|
|
315
|
-
removedFlagErrors.push('`--try-cf-tunnel` was removed. Use: openchamber tunnel start --provider cloudflare --mode quick');
|
|
316
|
-
break;
|
|
317
243
|
case 'tunnel-qr':
|
|
318
|
-
removedFlagErrors.push('`--tunnel-qr` was removed. Use: openchamber tunnel start ... --qr');
|
|
319
|
-
break;
|
|
320
244
|
case 'tunnel-password-url':
|
|
321
|
-
removedFlagErrors.push('`--tunnel-password-url` was removed. Use UI password auth directly after tunnel start.');
|
|
322
|
-
break;
|
|
323
245
|
case 'tunnel-provider':
|
|
324
246
|
case 'tunnel-mode':
|
|
325
247
|
case 'tunnel-config':
|
|
326
248
|
case 'tunnel-token':
|
|
327
249
|
case 'tunnel-hostname':
|
|
328
250
|
case 'tunnel':
|
|
329
|
-
removedFlagErrors.push(`\`--${name}\` was removed
|
|
251
|
+
removedFlagErrors.push(`\`--${name}\` was removed. Use LAN pairing (\`openchamber connect-url\`) or private relay instead.`);
|
|
330
252
|
break;
|
|
331
253
|
default:
|
|
332
254
|
if (!long && name.length === 1) {
|
|
@@ -339,22 +261,18 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
339
261
|
}
|
|
340
262
|
|
|
341
263
|
const command = positional[0] || 'serve';
|
|
342
|
-
const subcommand = command === 'tunnel' ? (positional[1] || 'help') : null;
|
|
343
|
-
const tunnelAction = command === 'tunnel' ? (positional[2] || null) : null;
|
|
344
264
|
const startupAction = command === 'startup' ? (positional[1] || 'status') : null;
|
|
345
265
|
|
|
346
266
|
if (options.lan && typeof options.host !== 'string') {
|
|
347
267
|
options.host = '0.0.0.0';
|
|
348
268
|
}
|
|
349
269
|
|
|
350
|
-
if (
|
|
270
|
+
if (typeof options.hostname === 'string' && typeof options.host !== 'string') {
|
|
351
271
|
options.host = options.hostname;
|
|
352
272
|
}
|
|
353
273
|
|
|
354
274
|
return {
|
|
355
275
|
command,
|
|
356
|
-
subcommand,
|
|
357
|
-
tunnelAction,
|
|
358
276
|
startupAction,
|
|
359
277
|
options,
|
|
360
278
|
removedFlagErrors,
|
|
@@ -375,7 +293,6 @@ COMMANDS:
|
|
|
375
293
|
stop Stop running instance(s)
|
|
376
294
|
restart Stop and start the server
|
|
377
295
|
status Show server status
|
|
378
|
-
tunnel Tunnel lifecycle commands
|
|
379
296
|
startup Manage launch at system startup
|
|
380
297
|
logs Tail OpenChamber logs
|
|
381
298
|
connect-url Generate URL/QR for connecting another client
|
|
@@ -384,7 +301,7 @@ COMMANDS:
|
|
|
384
301
|
OPTIONS:
|
|
385
302
|
-p, --port Web server port (default: ${DEFAULT_PORT})
|
|
386
303
|
--host Bind address (default: 127.0.0.1)
|
|
387
|
-
--hostname Alias for --host
|
|
304
|
+
--hostname Alias for --host
|
|
388
305
|
--lan Bind to 0.0.0.0 for LAN access
|
|
389
306
|
--server <url> Public/server URL for connect-url links
|
|
390
307
|
--relay connect-url: also include the end-to-end-encrypted relay transport
|
|
@@ -413,7 +330,6 @@ EXAMPLES:
|
|
|
413
330
|
openchamber connect-url --port 3000 --qr
|
|
414
331
|
openchamber connect-url --server https://openchamber.example.com
|
|
415
332
|
openchamber startup enable # Start OpenChamber at user login
|
|
416
|
-
openchamber tunnel help # Show tunnel lifecycle help
|
|
417
333
|
openchamber logs # Follow logs for latest running instance
|
|
418
334
|
`);
|
|
419
335
|
}
|
|
@@ -486,251 +402,11 @@ EXAMPLES:
|
|
|
486
402
|
`);
|
|
487
403
|
}
|
|
488
404
|
|
|
489
|
-
function showTunnelHelp() {
|
|
490
|
-
console.log(`
|
|
491
|
-
Tunnel Lifecycle Commands
|
|
492
|
-
|
|
493
|
-
USAGE:
|
|
494
|
-
openchamber tunnel <SUBCOMMAND> [OPTIONS]
|
|
495
|
-
|
|
496
|
-
SUBCOMMANDS:
|
|
497
|
-
help Show this tunnel help
|
|
498
|
-
providers Show available tunnel providers and capabilities
|
|
499
|
-
ready Check tunnel readiness for a provider
|
|
500
|
-
doctor Run deep tunnel diagnostics
|
|
501
|
-
status Show tunnel status
|
|
502
|
-
start Start a tunnel
|
|
503
|
-
stop Stop active tunnel (keep server running)
|
|
504
|
-
profile Manage saved managed-remote profiles
|
|
505
|
-
|
|
506
|
-
COMMON OPTIONS:
|
|
507
|
-
-p, --port Target OpenChamber instance port
|
|
508
|
-
--host Bind address when auto-starting an instance
|
|
509
|
-
--lan Bind to 0.0.0.0 when auto-starting an instance
|
|
510
|
-
--ui-password Protect browser UI when auto-starting an instance
|
|
511
|
-
--api-only Start API routes only when auto-starting an instance
|
|
512
|
-
--json Output machine-readable JSON
|
|
513
|
-
--all Apply to all running instances (doctor default, stop)
|
|
514
|
-
|
|
515
|
-
START OPTIONS:
|
|
516
|
-
--provider <id> Tunnel provider id (default: cloudflare)
|
|
517
|
-
--mode <id> Tunnel mode (default: quick)
|
|
518
|
-
--profile <name> Start tunnel from saved profile name
|
|
519
|
-
--config [path] Managed-local config path (optional)
|
|
520
|
-
--token <token> Managed-remote token (visible in process list)
|
|
521
|
-
--token-file <path> Read token from file (recommended)
|
|
522
|
-
--token-stdin Read token from stdin
|
|
523
|
-
--hostname <hostname> Managed-remote hostname
|
|
524
|
-
--connect-ttl <value> Connect-link TTL (e.g. 30m, 24h, 1d)
|
|
525
|
-
--session-ttl <value> Session TTL (e.g. 8h, 24h, 1d)
|
|
526
|
-
--qr Print QR code for resulting tunnel URL
|
|
527
|
-
--no-qr Disable QR output
|
|
528
|
-
--dry-run Validate inputs without applying changes
|
|
529
|
-
|
|
530
|
-
OUTPUT OPTIONS:
|
|
531
|
-
--show-secrets Show full tokens in output (default: redacted)
|
|
532
|
-
--plain Disable colors and decorations
|
|
533
|
-
-q, --quiet Suppress non-essential output
|
|
534
|
-
--json Output machine-readable JSON
|
|
535
|
-
|
|
536
|
-
BEHAVIOR NOTES:
|
|
537
|
-
- One active tunnel per OpenChamber instance.
|
|
538
|
-
- Starting a different mode/provider replaces the current tunnel and revokes old connect links/sessions.
|
|
539
|
-
- Connect links are one-time; generating a new link revokes the previous unused link.
|
|
540
|
-
|
|
541
|
-
PROFILE USAGE:
|
|
542
|
-
openchamber tunnel profile list [--provider <id>] [--json]
|
|
543
|
-
openchamber tunnel profile show --name <name> [--provider <id>] [--json]
|
|
544
|
-
openchamber tunnel profile add --provider <id> --mode managed-remote --name <name> --hostname <host> --token <token> [--force] [--json]
|
|
545
|
-
openchamber tunnel profile add --provider <id> --mode managed-remote --name <name> --hostname <host> --token-file <path> [--force] [--json]
|
|
546
|
-
openchamber tunnel profile remove --name <name> [--provider <id>] [--json]
|
|
547
|
-
|
|
548
|
-
SHELL COMPLETION:
|
|
549
|
-
openchamber tunnel completion bash Generate Bash completion script
|
|
550
|
-
openchamber tunnel completion zsh Generate Zsh completion script
|
|
551
|
-
openchamber tunnel completion fish Generate Fish completion script
|
|
552
|
-
|
|
553
|
-
EXAMPLES:
|
|
554
|
-
openchamber tunnel providers
|
|
555
|
-
openchamber tunnel ready --provider cloudflare
|
|
556
|
-
openchamber tunnel doctor --provider cloudflare
|
|
557
|
-
openchamber tunnel status
|
|
558
|
-
openchamber tunnel start --qr
|
|
559
|
-
openchamber tunnel start --profile prod-main
|
|
560
|
-
openchamber tunnel start --provider cloudflare --mode managed-remote --token-file ~/.secrets/cf-token --hostname app.example.com
|
|
561
|
-
openchamber tunnel start --provider cloudflare --mode managed-local --config ~/.cloudflared/config.yml
|
|
562
|
-
openchamber tunnel start --dry-run --provider cloudflare --mode managed-remote --token-file ~/.secrets/cf-token --hostname app.example.com
|
|
563
|
-
echo "$TOKEN" | openchamber tunnel profile add --provider cloudflare --mode managed-remote --name prod-main --hostname app.example.com --token-stdin
|
|
564
|
-
openchamber tunnel profile list --provider cloudflare
|
|
565
|
-
openchamber tunnel profile list --json --show-secrets
|
|
566
|
-
openchamber tunnel stop --port 3000
|
|
567
|
-
`);
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
function generateCompletionScript(shell) {
|
|
571
|
-
const normalized = typeof shell === 'string' ? shell.trim().toLowerCase() : '';
|
|
572
|
-
|
|
573
|
-
if (normalized === 'bash') {
|
|
574
|
-
return `# Bash completion for openchamber tunnel
|
|
575
|
-
# Add to ~/.bashrc: eval "$(openchamber tunnel completion bash)"
|
|
576
|
-
_openchamber_tunnel() {
|
|
577
|
-
local cur prev commands tunnel_commands profile_commands common_flags start_flags
|
|
578
|
-
COMPREPLY=()
|
|
579
|
-
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
580
|
-
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
581
|
-
|
|
582
|
-
commands="serve stop restart status tunnel logs update"
|
|
583
|
-
tunnel_commands="help providers ready doctor status start stop profile completion"
|
|
584
|
-
profile_commands="list show add remove"
|
|
585
|
-
common_flags="--port --foreground --no-daemon --json --all --help --version --plain --quiet"
|
|
586
|
-
start_flags="--provider --mode --profile --config --token --token-file --token-stdin --hostname --connect-ttl --session-ttl --qr --no-qr --dry-run --show-secrets"
|
|
587
|
-
|
|
588
|
-
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
589
|
-
COMPREPLY=( $(compgen -W "\${commands}" -- "\${cur}") )
|
|
590
|
-
return 0
|
|
591
|
-
fi
|
|
592
|
-
|
|
593
|
-
if [[ "\${COMP_WORDS[1]}" == "tunnel" ]]; then
|
|
594
|
-
if [[ \${COMP_CWORD} -eq 2 ]]; then
|
|
595
|
-
COMPREPLY=( $(compgen -W "\${tunnel_commands}" -- "\${cur}") )
|
|
596
|
-
return 0
|
|
597
|
-
fi
|
|
598
|
-
if [[ "\${COMP_WORDS[2]}" == "profile" && \${COMP_CWORD} -eq 3 ]]; then
|
|
599
|
-
COMPREPLY=( $(compgen -W "\${profile_commands}" -- "\${cur}") )
|
|
600
|
-
return 0
|
|
601
|
-
fi
|
|
602
|
-
if [[ "\${COMP_WORDS[2]}" == "completion" && \${COMP_CWORD} -eq 3 ]]; then
|
|
603
|
-
COMPREPLY=( $(compgen -W "bash zsh fish" -- "\${cur}") )
|
|
604
|
-
return 0
|
|
605
|
-
fi
|
|
606
|
-
if [[ "\${COMP_WORDS[2]}" == "start" ]]; then
|
|
607
|
-
COMPREPLY=( $(compgen -W "\${start_flags} \${common_flags}" -- "\${cur}") )
|
|
608
|
-
return 0
|
|
609
|
-
fi
|
|
610
|
-
COMPREPLY=( $(compgen -W "\${common_flags}" -- "\${cur}") )
|
|
611
|
-
return 0
|
|
612
|
-
fi
|
|
613
|
-
|
|
614
|
-
COMPREPLY=( $(compgen -W "\${common_flags}" -- "\${cur}") )
|
|
615
|
-
return 0
|
|
616
|
-
}
|
|
617
|
-
complete -F _openchamber_tunnel openchamber
|
|
618
|
-
`;
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
if (normalized === 'zsh') {
|
|
622
|
-
return `#compdef openchamber
|
|
623
|
-
# Zsh completion for openchamber tunnel
|
|
624
|
-
# Add to ~/.zshrc: eval "$(openchamber tunnel completion zsh)"
|
|
625
|
-
|
|
626
|
-
_openchamber() {
|
|
627
|
-
local -a commands tunnel_commands profile_commands
|
|
628
|
-
|
|
629
|
-
commands=(
|
|
630
|
-
'serve:Start the web server'
|
|
631
|
-
'stop:Stop running instance(s)'
|
|
632
|
-
'restart:Stop and start the server'
|
|
633
|
-
'status:Show server status'
|
|
634
|
-
'tunnel:Tunnel lifecycle commands'
|
|
635
|
-
'logs:Tail OpenChamber logs'
|
|
636
|
-
'update:Check for and install updates'
|
|
637
|
-
)
|
|
638
|
-
|
|
639
|
-
tunnel_commands=(
|
|
640
|
-
'help:Show tunnel help'
|
|
641
|
-
'providers:Show available providers'
|
|
642
|
-
'ready:Check tunnel readiness'
|
|
643
|
-
'doctor:Run tunnel diagnostics'
|
|
644
|
-
'status:Show tunnel status'
|
|
645
|
-
'start:Start a tunnel'
|
|
646
|
-
'stop:Stop active tunnel'
|
|
647
|
-
'profile:Manage saved profiles'
|
|
648
|
-
'completion:Generate shell completion'
|
|
649
|
-
)
|
|
650
|
-
|
|
651
|
-
profile_commands=(
|
|
652
|
-
'list:List profiles'
|
|
653
|
-
'show:Show profile details'
|
|
654
|
-
'add:Add a profile'
|
|
655
|
-
'remove:Remove a profile'
|
|
656
|
-
)
|
|
657
|
-
|
|
658
|
-
_arguments -C \\
|
|
659
|
-
'1:command:->command' \\
|
|
660
|
-
'*::arg:->args'
|
|
661
|
-
|
|
662
|
-
case \$state in
|
|
663
|
-
command)
|
|
664
|
-
_describe 'command' commands
|
|
665
|
-
;;
|
|
666
|
-
args)
|
|
667
|
-
case \$words[1] in
|
|
668
|
-
tunnel)
|
|
669
|
-
if (( CURRENT == 2 )); then
|
|
670
|
-
_describe 'tunnel command' tunnel_commands
|
|
671
|
-
elif [[ \$words[2] == "profile" ]] && (( CURRENT == 3 )); then
|
|
672
|
-
_describe 'profile action' profile_commands
|
|
673
|
-
elif [[ \$words[2] == "completion" ]] && (( CURRENT == 3 )); then
|
|
674
|
-
_values 'shell' bash zsh fish
|
|
675
|
-
fi
|
|
676
|
-
;;
|
|
677
|
-
esac
|
|
678
|
-
;;
|
|
679
|
-
esac
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
compdef _openchamber openchamber
|
|
683
|
-
`;
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
if (normalized === 'fish') {
|
|
687
|
-
return `# Fish completion for openchamber tunnel
|
|
688
|
-
# Save to ~/.config/fish/completions/openchamber.fish
|
|
689
|
-
|
|
690
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'serve' -d 'Start the web server'
|
|
691
|
-
complete -c openchamber -n '__fish_seen_subcommand_from serve' -l foreground -d 'Run in foreground (for systemd/process managers)'
|
|
692
|
-
complete -c openchamber -n '__fish_seen_subcommand_from serve' -l no-daemon -d 'Run in foreground (alias for --foreground)'
|
|
693
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'stop' -d 'Stop running instance(s)'
|
|
694
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'restart' -d 'Stop and start the server'
|
|
695
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'status' -d 'Show server status'
|
|
696
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'tunnel' -d 'Tunnel lifecycle commands'
|
|
697
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'logs' -d 'Tail logs'
|
|
698
|
-
complete -c openchamber -n '__fish_use_subcommand' -a 'update' -d 'Check for updates'
|
|
699
|
-
|
|
700
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'help' -d 'Show tunnel help'
|
|
701
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'providers' -d 'Show providers'
|
|
702
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'ready' -d 'Check readiness'
|
|
703
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'doctor' -d 'Run diagnostics'
|
|
704
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'status' -d 'Show tunnel status'
|
|
705
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'start' -d 'Start a tunnel'
|
|
706
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'stop' -d 'Stop tunnel'
|
|
707
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'profile' -d 'Manage profiles'
|
|
708
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and not __fish_seen_subcommand_from help providers ready doctor status start stop profile completion' -a 'completion' -d 'Generate completions'
|
|
709
|
-
|
|
710
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l provider -d 'Provider id'
|
|
711
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l mode -d 'Tunnel mode'
|
|
712
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l profile -d 'Profile name'
|
|
713
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l config -d 'Config path'
|
|
714
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l token -d 'Token'
|
|
715
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l token-file -d 'Token file path'
|
|
716
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l token-stdin -d 'Read token from stdin'
|
|
717
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l hostname -d 'Hostname'
|
|
718
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l dry-run -d 'Validate without applying'
|
|
719
|
-
complete -c openchamber -n '__fish_seen_subcommand_from tunnel; and __fish_seen_subcommand_from start' -l qr -d 'Show QR code'
|
|
720
|
-
`;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
return null;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
|
|
727
405
|
export {
|
|
728
406
|
DEFAULT_PORT,
|
|
729
407
|
parseArgs,
|
|
730
408
|
showHelp,
|
|
731
409
|
showStartupHelp,
|
|
732
410
|
showConnectUrlHelp,
|
|
733
|
-
showTunnelHelp,
|
|
734
|
-
generateCompletionScript,
|
|
735
411
|
findClosestMatch,
|
|
736
412
|
};
|
package/bin/lib/cli-http.js
CHANGED
|
@@ -163,21 +163,6 @@ async function waitForServerHealth(port, {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
async function fetchTunnelProvidersFromPort(port, fetchImpl = globalThis.fetch) {
|
|
167
|
-
if (!Number.isFinite(port) || port <= 0 || typeof fetchImpl !== 'function') {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
const response = await fetchImpl(buildLocalUrl(port, '/api/openchamber/tunnel/providers'));
|
|
172
|
-
if (!response.ok) return null;
|
|
173
|
-
const body = await response.json().catch(() => null);
|
|
174
|
-
if (!body || !Array.isArray(body.providers)) return null;
|
|
175
|
-
return body.providers;
|
|
176
|
-
} catch {
|
|
177
|
-
return null;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
166
|
async function fetchSystemInfoFromPort(port, fetchImpl = globalThis.fetch, hostOverride) {
|
|
182
167
|
if (!Number.isFinite(port) || port <= 0 || typeof fetchImpl !== 'function') {
|
|
183
168
|
return null;
|
|
@@ -211,6 +196,5 @@ export {
|
|
|
211
196
|
requestJson,
|
|
212
197
|
isServerHealthReady,
|
|
213
198
|
waitForServerHealth,
|
|
214
|
-
fetchTunnelProvidersFromPort,
|
|
215
199
|
fetchSystemInfoFromPort,
|
|
216
200
|
};
|
package/bin/lib/cli-lifecycle.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import { DEFAULT_PORT } from './cli-args.js';
|
|
4
3
|
import { getRunDir, readDesktopLocalPortFromSettings } from './cli-paths.js';
|
|
5
|
-
import { resolveApiHost
|
|
6
|
-
import {
|
|
4
|
+
import { resolveApiHost } from './cli-network.js';
|
|
5
|
+
import { fetchSystemInfoFromPort, isServerHealthReady } from './cli-http.js';
|
|
7
6
|
import { isPortAvailable } from './cli-ports.js';
|
|
8
7
|
import {
|
|
9
8
|
getPidFilePath,
|
|
@@ -15,8 +14,6 @@ import {
|
|
|
15
14
|
getOpenchamberProcessState,
|
|
16
15
|
hasOpenchamberRuntimeInfo,
|
|
17
16
|
} from './cli-process.js';
|
|
18
|
-
import { DEFAULT_TUNNEL_PROVIDER_CAPABILITIES } from './cli-tunnel-capabilities.js';
|
|
19
|
-
|
|
20
17
|
function createLivePortInstance(port, info, host) {
|
|
21
18
|
if (!hasOpenchamberRuntimeInfo(info)) return null;
|
|
22
19
|
return {
|
|
@@ -87,79 +84,6 @@ async function fetchSystemInfoFromPortCandidates(port, fetchImpl, hosts, expecte
|
|
|
87
84
|
return { info: null, host: null };
|
|
88
85
|
}
|
|
89
86
|
|
|
90
|
-
async function resolveDoctorPortStatuses(options = {}) {
|
|
91
|
-
const runningEntries = await discoverRunningInstances();
|
|
92
|
-
const desktopEntry = await discoverDesktopInstance();
|
|
93
|
-
const statuses = [];
|
|
94
|
-
|
|
95
|
-
if (options.explicitPort) {
|
|
96
|
-
const requestedPort = options.port;
|
|
97
|
-
const runningMatch = runningEntries.find((entry) => entry.port === requestedPort);
|
|
98
|
-
if (runningMatch) {
|
|
99
|
-
statuses.push({
|
|
100
|
-
port: requestedPort,
|
|
101
|
-
available: true,
|
|
102
|
-
status: 'success',
|
|
103
|
-
line: `port ${requestedPort} available for tunneling`,
|
|
104
|
-
detail: 'Double-check this same port is configured in your provider dashboard/config.',
|
|
105
|
-
});
|
|
106
|
-
return { statuses, availableEntries: [runningMatch] };
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (desktopEntry && desktopEntry.port === requestedPort) {
|
|
110
|
-
statuses.push({
|
|
111
|
-
port: requestedPort,
|
|
112
|
-
available: false,
|
|
113
|
-
status: 'warning',
|
|
114
|
-
line: `port ${requestedPort} not available (desktop runtime)`,
|
|
115
|
-
detail: 'Use a CLI instance port from `openchamber serve` for tunneling.',
|
|
116
|
-
});
|
|
117
|
-
return { statuses, availableEntries: [] };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
statuses.push({
|
|
121
|
-
port: requestedPort,
|
|
122
|
-
available: false,
|
|
123
|
-
status: 'error',
|
|
124
|
-
line: `port ${requestedPort} not available (no running instance)`,
|
|
125
|
-
detail: `Start one with \`openchamber serve --port ${requestedPort}\`.`,
|
|
126
|
-
});
|
|
127
|
-
return { statuses, availableEntries: [] };
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
for (const entry of runningEntries) {
|
|
131
|
-
statuses.push({
|
|
132
|
-
port: entry.port,
|
|
133
|
-
available: true,
|
|
134
|
-
status: 'success',
|
|
135
|
-
line: `port ${entry.port} available for tunneling`,
|
|
136
|
-
detail: 'Double-check this same port is configured in your provider dashboard/config.',
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (desktopEntry && !runningEntries.some((entry) => entry.port === desktopEntry.port)) {
|
|
141
|
-
statuses.push({
|
|
142
|
-
port: desktopEntry.port,
|
|
143
|
-
available: false,
|
|
144
|
-
status: 'warning',
|
|
145
|
-
line: `port ${desktopEntry.port} not available (desktop runtime)`,
|
|
146
|
-
detail: 'Use a CLI instance port from `openchamber serve` for tunneling.',
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (runningEntries.length === 0) {
|
|
151
|
-
statuses.push({
|
|
152
|
-
port: null,
|
|
153
|
-
available: false,
|
|
154
|
-
status: 'warning',
|
|
155
|
-
line: 'no CLI ports available for tunneling',
|
|
156
|
-
detail: 'Start one with `openchamber serve`.',
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return { statuses, availableEntries: runningEntries };
|
|
161
|
-
}
|
|
162
|
-
|
|
163
87
|
async function discoverRunningInstances(options = {}) {
|
|
164
88
|
const instances = [];
|
|
165
89
|
const runDir = getRunDir();
|
|
@@ -376,39 +300,7 @@ async function discoverDesktopInstance(fetchImpl = globalThis.fetch) {
|
|
|
376
300
|
};
|
|
377
301
|
}
|
|
378
302
|
|
|
379
|
-
async function resolveTunnelProviders(options = {}, deps = {}) {
|
|
380
|
-
const readPorts = typeof deps.readPorts === 'function'
|
|
381
|
-
? deps.readPorts
|
|
382
|
-
: async () => (await discoverRunningInstances()).map((entry) => entry.port);
|
|
383
|
-
const fetchImpl = typeof deps.fetchImpl === 'function' ? deps.fetchImpl : globalThis.fetch;
|
|
384
|
-
|
|
385
|
-
const candidatePorts = [];
|
|
386
|
-
if (Number.isFinite(options.port) && options.port > 0) {
|
|
387
|
-
candidatePorts.push(options.port);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const discoveredPorts = await Promise.resolve(readPorts());
|
|
391
|
-
if (Array.isArray(discoveredPorts)) {
|
|
392
|
-
candidatePorts.push(...discoveredPorts);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
if (!candidatePorts.includes(DEFAULT_PORT)) {
|
|
396
|
-
candidatePorts.push(DEFAULT_PORT);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
for (const port of candidatePorts) {
|
|
400
|
-
const providers = await fetchTunnelProvidersFromPort(port, fetchImpl);
|
|
401
|
-
if (providers) {
|
|
402
|
-
return { providers, source: `api:${port}` };
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
return { providers: DEFAULT_TUNNEL_PROVIDER_CAPABILITIES, source: 'fallback' };
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
|
|
410
303
|
export {
|
|
411
|
-
resolveDoctorPortStatuses,
|
|
412
304
|
discoverRunningInstances,
|
|
413
305
|
discoverOpenChamberInstanceOnPort,
|
|
414
306
|
discoverLifecycleInstances,
|
|
@@ -417,5 +309,4 @@ export {
|
|
|
417
309
|
isDesktopRuntimeForPort,
|
|
418
310
|
inspectTunnelAttachability,
|
|
419
311
|
discoverDesktopInstance,
|
|
420
|
-
resolveTunnelProviders,
|
|
421
312
|
};
|
package/bin/lib/cli-paths.js
CHANGED
|
@@ -2,10 +2,6 @@ import fs from 'fs';
|
|
|
2
2
|
import os from 'os';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
|
|
5
|
-
const TUNNEL_PROFILES_FILE_NAME = 'tunnel-profiles.json';
|
|
6
|
-
const LEGACY_CLOUDFLARE_MANAGED_REMOTE_FILE_NAME = 'cloudflare-managed-remote-tunnels.json';
|
|
7
|
-
const TUNNEL_CLI_STATE_FILE_NAME = 'tunnel-cli-state.json';
|
|
8
|
-
|
|
9
5
|
function getDataDir() {
|
|
10
6
|
if (typeof process.env.OPENCHAMBER_DATA_DIR === 'string' && process.env.OPENCHAMBER_DATA_DIR.trim().length > 0) {
|
|
11
7
|
return path.resolve(process.env.OPENCHAMBER_DATA_DIR.trim());
|
|
@@ -43,55 +39,6 @@ function getLogFilePath(port) {
|
|
|
43
39
|
return path.join(getLogsDir(), `openchamber-${port}.log`);
|
|
44
40
|
}
|
|
45
41
|
|
|
46
|
-
function getTunnelProfilesFilePath() {
|
|
47
|
-
return path.join(getDataDir(), TUNNEL_PROFILES_FILE_NAME);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function getLegacyCloudflareManagedRemoteFilePath() {
|
|
51
|
-
return path.join(getDataDir(), LEGACY_CLOUDFLARE_MANAGED_REMOTE_FILE_NAME);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function getTunnelCliStateFilePath() {
|
|
55
|
-
return path.join(getDataDir(), TUNNEL_CLI_STATE_FILE_NAME);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function readTunnelCliState() {
|
|
59
|
-
const filePath = getTunnelCliStateFilePath();
|
|
60
|
-
try {
|
|
61
|
-
const raw = fs.readFileSync(filePath, 'utf8');
|
|
62
|
-
const parsed = JSON.parse(raw);
|
|
63
|
-
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
64
|
-
return {};
|
|
65
|
-
}
|
|
66
|
-
return parsed;
|
|
67
|
-
} catch {
|
|
68
|
-
return {};
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function readLastManagedLocalConfigPath() {
|
|
73
|
-
const state = readTunnelCliState();
|
|
74
|
-
if (typeof state.lastManagedLocalConfigPath !== 'string') {
|
|
75
|
-
return '';
|
|
76
|
-
}
|
|
77
|
-
return state.lastManagedLocalConfigPath.trim();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function writeLastManagedLocalConfigPath(configPath) {
|
|
81
|
-
if (typeof configPath !== 'string' || configPath.trim().length === 0) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
const filePath = getTunnelCliStateFilePath();
|
|
85
|
-
const current = readTunnelCliState();
|
|
86
|
-
const next = {
|
|
87
|
-
...current,
|
|
88
|
-
lastManagedLocalConfigPath: configPath.trim(),
|
|
89
|
-
updatedAt: Date.now(),
|
|
90
|
-
};
|
|
91
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
92
|
-
fs.writeFileSync(filePath, JSON.stringify(next, null, 2), 'utf8');
|
|
93
|
-
}
|
|
94
|
-
|
|
95
42
|
|
|
96
43
|
function getRunDir() {
|
|
97
44
|
const dir = path.join(getDataDir(), 'run');
|
|
@@ -105,9 +52,5 @@ export {
|
|
|
105
52
|
readDesktopLocalPortFromSettings,
|
|
106
53
|
ensureLogsDir,
|
|
107
54
|
getLogFilePath,
|
|
108
|
-
getTunnelProfilesFilePath,
|
|
109
|
-
getLegacyCloudflareManagedRemoteFilePath,
|
|
110
|
-
readLastManagedLocalConfigPath,
|
|
111
|
-
writeLastManagedLocalConfigPath,
|
|
112
55
|
getRunDir,
|
|
113
56
|
};
|