2026-03-31 18:47:00 +03:00
|
|
|
export const parseServeCliOptions = ({
|
|
|
|
|
argv = [],
|
|
|
|
|
env = {},
|
|
|
|
|
defaultPort,
|
|
|
|
|
cloudflareProvider,
|
|
|
|
|
managedLocalMode,
|
|
|
|
|
}) => {
|
|
|
|
|
const args = Array.isArray(argv) ? [...argv] : [];
|
|
|
|
|
const envPassword =
|
|
|
|
|
env.OPENCHAMBER_UI_PASSWORD ||
|
|
|
|
|
env.OPENCODE_UI_PASSWORD ||
|
|
|
|
|
null;
|
|
|
|
|
const envCfTunnel = env.OPENCHAMBER_TRY_CF_TUNNEL === 'true';
|
|
|
|
|
const envTunnelProvider = env.OPENCHAMBER_TUNNEL_PROVIDER || undefined;
|
|
|
|
|
const envTunnelMode = env.OPENCHAMBER_TUNNEL_MODE || undefined;
|
|
|
|
|
const envTunnelConfigRaw = env.OPENCHAMBER_TUNNEL_CONFIG;
|
|
|
|
|
const envTunnelConfig = typeof envTunnelConfigRaw === 'string'
|
|
|
|
|
? (envTunnelConfigRaw.trim().length > 0 ? envTunnelConfigRaw.trim() : null)
|
|
|
|
|
: undefined;
|
|
|
|
|
const envTunnelToken = env.OPENCHAMBER_TUNNEL_TOKEN || undefined;
|
|
|
|
|
const envTunnelHostname = env.OPENCHAMBER_TUNNEL_HOSTNAME || undefined;
|
2026-06-02 00:43:05 +03:00
|
|
|
const envApiOnly = env.OPENCHAMBER_API_ONLY === '1' || env.OPENCHAMBER_API_ONLY === 'true';
|
2026-03-31 18:47:00 +03:00
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
|
port: defaultPort,
|
|
|
|
|
host: undefined,
|
|
|
|
|
uiPassword: envPassword,
|
|
|
|
|
tryCfTunnel: envCfTunnel,
|
|
|
|
|
tunnelProvider: envTunnelProvider,
|
|
|
|
|
tunnelMode: envTunnelMode,
|
|
|
|
|
tunnelConfigPath: envTunnelConfig,
|
|
|
|
|
tunnelToken: envTunnelToken,
|
|
|
|
|
tunnelHostname: envTunnelHostname,
|
2026-06-02 00:43:05 +03:00
|
|
|
apiOnly: envApiOnly,
|
2026-03-31 18:47:00 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const consumeValue = (currentIndex, inlineValue) => {
|
|
|
|
|
if (typeof inlineValue === 'string') {
|
|
|
|
|
return { value: inlineValue, nextIndex: currentIndex };
|
|
|
|
|
}
|
|
|
|
|
const nextArg = args[currentIndex + 1];
|
|
|
|
|
if (typeof nextArg === 'string' && !nextArg.startsWith('--')) {
|
|
|
|
|
return { value: nextArg, nextIndex: currentIndex + 1 };
|
|
|
|
|
}
|
|
|
|
|
return { value: undefined, nextIndex: currentIndex };
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < args.length; i += 1) {
|
|
|
|
|
const arg = args[i];
|
|
|
|
|
if (!arg.startsWith('--')) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const eqIndex = arg.indexOf('=');
|
|
|
|
|
const optionName = eqIndex >= 0 ? arg.slice(2, eqIndex) : arg.slice(2);
|
|
|
|
|
const inlineValue = eqIndex >= 0 ? arg.slice(eqIndex + 1) : undefined;
|
|
|
|
|
|
|
|
|
|
if (optionName === 'port' || optionName === 'p') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
const parsedPort = parseInt(value ?? '', 10);
|
|
|
|
|
options.port = Number.isFinite(parsedPort) ? parsedPort : defaultPort;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'host') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.host = typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'ui-password') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.uiPassword = typeof value === 'string' ? value : '';
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-02 00:43:05 +03:00
|
|
|
if (optionName === 'api-only') {
|
|
|
|
|
options.apiOnly = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 18:47:00 +03:00
|
|
|
if (optionName === 'try-cf-tunnel') {
|
|
|
|
|
options.tryCfTunnel = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel-provider') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelProvider = typeof value === 'string' ? value : options.tunnelProvider;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel-mode') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelMode = typeof value === 'string' ? value : options.tunnelMode;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel-config') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelConfigPath = typeof value === 'string' ? value : null;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel-token') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelToken = typeof value === 'string' ? value : options.tunnelToken;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel-hostname') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelHostname = typeof value === 'string' ? value : options.tunnelHostname;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (optionName === 'tunnel') {
|
|
|
|
|
const { value, nextIndex } = consumeValue(i, inlineValue);
|
|
|
|
|
i = nextIndex;
|
|
|
|
|
options.tunnelProvider = cloudflareProvider;
|
|
|
|
|
options.tunnelMode = managedLocalMode;
|
|
|
|
|
options.tunnelConfigPath = typeof value === 'string' ? value : null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return options;
|
|
|
|
|
};
|