feat: add setup-token + token auth
This commit is contained in:
@@ -177,7 +177,11 @@ Options:
|
|||||||
- `--workspace <dir>`
|
- `--workspace <dir>`
|
||||||
- `--non-interactive`
|
- `--non-interactive`
|
||||||
- `--mode <local|remote>`
|
- `--mode <local|remote>`
|
||||||
- `--auth-choice <oauth|claude-cli|token|openai-codex|openai-api-key|codex-cli|antigravity|gemini-api-key|apiKey|minimax-cloud|minimax|skip>`
|
- `--auth-choice <setup-token|claude-cli|token|openai-codex|openai-api-key|codex-cli|antigravity|gemini-api-key|apiKey|minimax-cloud|minimax|skip>`
|
||||||
|
- `--token-provider <id>` (non-interactive; used with `--auth-choice token`)
|
||||||
|
- `--token <token>` (non-interactive; used with `--auth-choice token`)
|
||||||
|
- `--token-profile-id <id>` (non-interactive; default: `<provider>:manual`)
|
||||||
|
- `--token-expires-in <duration>` (non-interactive; e.g. `365d`, `12h`)
|
||||||
- `--anthropic-api-key <key>`
|
- `--anthropic-api-key <key>`
|
||||||
- `--openai-api-key <key>`
|
- `--openai-api-key <key>`
|
||||||
- `--gemini-api-key <key>`
|
- `--gemini-api-key <key>`
|
||||||
|
|||||||
@@ -29,6 +29,19 @@ clawdbot models status
|
|||||||
clawdbot doctor
|
clawdbot doctor
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Alternative: run the wrapper (also updates Clawdbot config):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clawdbot models auth setup-token --provider anthropic
|
||||||
|
```
|
||||||
|
|
||||||
|
Manual token entry (any provider; writes `auth-profiles.json` + updates config):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
clawdbot models auth paste-token --provider anthropic
|
||||||
|
clawdbot models auth paste-token --provider openrouter
|
||||||
|
```
|
||||||
|
|
||||||
## Recommended: long‑lived Claude Code token
|
## Recommended: long‑lived Claude Code token
|
||||||
|
|
||||||
Run this on the **gateway host** (the machine running the Gateway):
|
Run this on the **gateway host** (the machine running the Gateway):
|
||||||
@@ -92,13 +105,15 @@ Use `--agent <id>` to target a specific agent; omit it to use the configured def
|
|||||||
2. **Clawdbot** syncs those into
|
2. **Clawdbot** syncs those into
|
||||||
`~/.clawdbot/agents/<agentId>/agent/auth-profiles.json` when the auth store is
|
`~/.clawdbot/agents/<agentId>/agent/auth-profiles.json` when the auth store is
|
||||||
loaded.
|
loaded.
|
||||||
3. OAuth refresh happens automatically on use if a token is expired.
|
3. Refreshable OAuth profiles can be refreshed automatically on use. Static
|
||||||
|
token profiles (including Claude CLI setup-token) are not refreshable by
|
||||||
|
Clawdbot.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### “No credentials found”
|
### “No credentials found”
|
||||||
|
|
||||||
If the Anthropic OAuth profile is missing, run `claude setup-token` on the
|
If the Anthropic token profile is missing, run `claude setup-token` on the
|
||||||
**gateway host**, then re-check:
|
**gateway host**, then re-check:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -240,7 +240,23 @@ export function buildProgram() {
|
|||||||
.option("--mode <mode>", "Wizard mode: local|remote")
|
.option("--mode <mode>", "Wizard mode: local|remote")
|
||||||
.option(
|
.option(
|
||||||
"--auth-choice <choice>",
|
"--auth-choice <choice>",
|
||||||
"Auth: oauth|claude-cli|token|openai-codex|openai-api-key|codex-cli|antigravity|gemini-api-key|apiKey|minimax-cloud|minimax|skip",
|
"Auth: setup-token|claude-cli|token|openai-codex|openai-api-key|codex-cli|antigravity|gemini-api-key|apiKey|minimax-cloud|minimax|skip",
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
"--token-provider <id>",
|
||||||
|
"Token provider id (non-interactive; used with --auth-choice token)",
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
"--token <token>",
|
||||||
|
"Token value (non-interactive; used with --auth-choice token)",
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
"--token-profile-id <id>",
|
||||||
|
"Auth profile id (non-interactive; default: <provider>:manual)",
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
"--token-expires-in <duration>",
|
||||||
|
"Optional token expiry duration (e.g. 365d, 12h)",
|
||||||
)
|
)
|
||||||
.option("--anthropic-api-key <key>", "Anthropic API key")
|
.option("--anthropic-api-key <key>", "Anthropic API key")
|
||||||
.option("--openai-api-key <key>", "OpenAI API key")
|
.option("--openai-api-key <key>", "OpenAI API key")
|
||||||
@@ -270,6 +286,7 @@ export function buildProgram() {
|
|||||||
mode: opts.mode as "local" | "remote" | undefined,
|
mode: opts.mode as "local" | "remote" | undefined,
|
||||||
authChoice: opts.authChoice as
|
authChoice: opts.authChoice as
|
||||||
| "oauth"
|
| "oauth"
|
||||||
|
| "setup-token"
|
||||||
| "claude-cli"
|
| "claude-cli"
|
||||||
| "token"
|
| "token"
|
||||||
| "openai-codex"
|
| "openai-codex"
|
||||||
@@ -282,6 +299,10 @@ export function buildProgram() {
|
|||||||
| "minimax"
|
| "minimax"
|
||||||
| "skip"
|
| "skip"
|
||||||
| undefined,
|
| undefined,
|
||||||
|
tokenProvider: opts.tokenProvider as string | undefined,
|
||||||
|
token: opts.token as string | undefined,
|
||||||
|
tokenProfileId: opts.tokenProfileId as string | undefined,
|
||||||
|
tokenExpiresIn: opts.tokenExpiresIn as string | undefined,
|
||||||
anthropicApiKey: opts.anthropicApiKey as string | undefined,
|
anthropicApiKey: opts.anthropicApiKey as string | undefined,
|
||||||
openaiApiKey: opts.openaiApiKey as string | undefined,
|
openaiApiKey: opts.openaiApiKey as string | undefined,
|
||||||
geminiApiKey: opts.geminiApiKey as string | undefined,
|
geminiApiKey: opts.geminiApiKey as string | undefined,
|
||||||
|
|||||||
@@ -64,17 +64,23 @@ export function buildAuthChoiceOptions(params: {
|
|||||||
if (claudeCli?.type === "oauth" || claudeCli?.type === "token") {
|
if (claudeCli?.type === "oauth" || claudeCli?.type === "token") {
|
||||||
options.push({
|
options.push({
|
||||||
value: "claude-cli",
|
value: "claude-cli",
|
||||||
label: "Anthropic OAuth (Claude CLI)",
|
label: "Anthropic token (Claude CLI)",
|
||||||
hint: formatOAuthHint(claudeCli.expires),
|
hint: formatOAuthHint(claudeCli.expires),
|
||||||
});
|
});
|
||||||
} else if (params.includeClaudeCliIfMissing && platform === "darwin") {
|
} else if (params.includeClaudeCliIfMissing && platform === "darwin") {
|
||||||
options.push({
|
options.push({
|
||||||
value: "claude-cli",
|
value: "claude-cli",
|
||||||
label: "Anthropic OAuth (Claude CLI)",
|
label: "Anthropic token (Claude CLI)",
|
||||||
hint: "requires Keychain access",
|
hint: "requires Keychain access",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.push({
|
||||||
|
value: "setup-token",
|
||||||
|
label: "Anthropic token (run setup-token)",
|
||||||
|
hint: "Runs `claude setup-token`",
|
||||||
|
});
|
||||||
|
|
||||||
options.push({
|
options.push({
|
||||||
value: "token",
|
value: "token",
|
||||||
label: "Anthropic token (paste setup-token)",
|
label: "Anthropic token (paste setup-token)",
|
||||||
|
|||||||
@@ -216,7 +216,68 @@ export async function applyAuthChoice(params: {
|
|||||||
provider: "anthropic",
|
provider: "anthropic",
|
||||||
mode: "token",
|
mode: "token",
|
||||||
});
|
});
|
||||||
} else if (params.authChoice === "token" || params.authChoice === "oauth") {
|
} else if (
|
||||||
|
params.authChoice === "setup-token" ||
|
||||||
|
params.authChoice === "oauth"
|
||||||
|
) {
|
||||||
|
await params.prompter.note(
|
||||||
|
[
|
||||||
|
"This will run `claude setup-token` to create a long-lived Anthropic token.",
|
||||||
|
"Requires an interactive TTY and a Claude Pro/Max subscription.",
|
||||||
|
].join("\n"),
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!process.stdin.isTTY) {
|
||||||
|
await params.prompter.note(
|
||||||
|
"`claude setup-token` requires an interactive TTY.",
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return { config: nextConfig, agentModelOverride };
|
||||||
|
}
|
||||||
|
|
||||||
|
const proceed = await params.prompter.confirm({
|
||||||
|
message: "Run `claude setup-token` now?",
|
||||||
|
initialValue: true,
|
||||||
|
});
|
||||||
|
if (!proceed) return { config: nextConfig, agentModelOverride };
|
||||||
|
|
||||||
|
const res = await (async () => {
|
||||||
|
const { spawnSync } = await import("node:child_process");
|
||||||
|
return spawnSync("claude", ["setup-token"], { stdio: "inherit" });
|
||||||
|
})();
|
||||||
|
if (res.error) {
|
||||||
|
await params.prompter.note(
|
||||||
|
`Failed to run claude: ${String(res.error)}`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return { config: nextConfig, agentModelOverride };
|
||||||
|
}
|
||||||
|
if (typeof res.status === "number" && res.status !== 0) {
|
||||||
|
await params.prompter.note(
|
||||||
|
`claude setup-token failed (exit ${res.status})`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return { config: nextConfig, agentModelOverride };
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = ensureAuthProfileStore(params.agentDir, {
|
||||||
|
allowKeychainPrompt: true,
|
||||||
|
});
|
||||||
|
if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) {
|
||||||
|
await params.prompter.note(
|
||||||
|
`No Claude CLI credentials found after setup-token. Expected ${CLAUDE_CLI_PROFILE_ID}.`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return { config: nextConfig, agentModelOverride };
|
||||||
|
}
|
||||||
|
|
||||||
|
nextConfig = applyAuthProfileConfig(nextConfig, {
|
||||||
|
profileId: CLAUDE_CLI_PROFILE_ID,
|
||||||
|
provider: "anthropic",
|
||||||
|
mode: "token",
|
||||||
|
});
|
||||||
|
} else if (params.authChoice === "token") {
|
||||||
const provider = (await params.prompter.select({
|
const provider = (await params.prompter.select({
|
||||||
message: "Token provider",
|
message: "Token provider",
|
||||||
options: [{ value: "anthropic", label: "Anthropic (only supported)" }],
|
options: [{ value: "anthropic", label: "Anthropic (only supported)" }],
|
||||||
|
|||||||
@@ -352,6 +352,7 @@ async function promptAuthConfig(
|
|||||||
runtime,
|
runtime,
|
||||||
) as
|
) as
|
||||||
| "oauth"
|
| "oauth"
|
||||||
|
| "setup-token"
|
||||||
| "claude-cli"
|
| "claude-cli"
|
||||||
| "token"
|
| "token"
|
||||||
| "openai-codex"
|
| "openai-codex"
|
||||||
@@ -403,7 +404,68 @@ async function promptAuthConfig(
|
|||||||
provider: "anthropic",
|
provider: "anthropic",
|
||||||
mode: "token",
|
mode: "token",
|
||||||
});
|
});
|
||||||
} else if (authChoice === "token" || authChoice === "oauth") {
|
} else if (authChoice === "setup-token" || authChoice === "oauth") {
|
||||||
|
note(
|
||||||
|
[
|
||||||
|
"This will run `claude setup-token` to create a long-lived Anthropic token.",
|
||||||
|
"Requires an interactive TTY and a Claude Pro/Max subscription.",
|
||||||
|
].join("\n"),
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!process.stdin.isTTY) {
|
||||||
|
note(
|
||||||
|
"`claude setup-token` requires an interactive TTY.",
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
const runNow = guardCancel(
|
||||||
|
await confirm({
|
||||||
|
message: "Run `claude setup-token` now?",
|
||||||
|
initialValue: true,
|
||||||
|
}),
|
||||||
|
runtime,
|
||||||
|
);
|
||||||
|
if (!runNow) return next;
|
||||||
|
|
||||||
|
const res = await (async () => {
|
||||||
|
const { spawnSync } = await import("node:child_process");
|
||||||
|
return spawnSync("claude", ["setup-token"], { stdio: "inherit" });
|
||||||
|
})();
|
||||||
|
if (res.error) {
|
||||||
|
note(
|
||||||
|
`Failed to run claude: ${String(res.error)}`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
if (typeof res.status === "number" && res.status !== 0) {
|
||||||
|
note(
|
||||||
|
`claude setup-token failed (exit ${res.status})`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = ensureAuthProfileStore(undefined, {
|
||||||
|
allowKeychainPrompt: true,
|
||||||
|
});
|
||||||
|
if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) {
|
||||||
|
note(
|
||||||
|
`No Claude CLI credentials found after setup-token. Expected ${CLAUDE_CLI_PROFILE_ID}.`,
|
||||||
|
"Anthropic setup-token",
|
||||||
|
);
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
next = applyAuthProfileConfig(next, {
|
||||||
|
profileId: CLAUDE_CLI_PROFILE_ID,
|
||||||
|
provider: "anthropic",
|
||||||
|
mode: "token",
|
||||||
|
});
|
||||||
|
} else if (authChoice === "token") {
|
||||||
const provider = guardCancel(
|
const provider = guardCancel(
|
||||||
await select({
|
await select({
|
||||||
message: "Token provider",
|
message: "Token provider",
|
||||||
@@ -726,6 +788,7 @@ async function promptAuthConfig(
|
|||||||
: (next.agents?.defaults?.model?.primary ?? "");
|
: (next.agents?.defaults?.model?.primary ?? "");
|
||||||
const preferAnthropic =
|
const preferAnthropic =
|
||||||
authChoice === "claude-cli" ||
|
authChoice === "claude-cli" ||
|
||||||
|
authChoice === "setup-token" ||
|
||||||
authChoice === "token" ||
|
authChoice === "token" ||
|
||||||
authChoice === "oauth" ||
|
authChoice === "oauth" ||
|
||||||
authChoice === "apiKey";
|
authChoice === "apiKey";
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import { spawnSync } from "node:child_process";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import {
|
import {
|
||||||
CLAUDE_CLI_PROFILE_ID,
|
CLAUDE_CLI_PROFILE_ID,
|
||||||
CODEX_CLI_PROFILE_ID,
|
CODEX_CLI_PROFILE_ID,
|
||||||
ensureAuthProfileStore,
|
ensureAuthProfileStore,
|
||||||
|
upsertAuthProfile,
|
||||||
} from "../agents/auth-profiles.js";
|
} from "../agents/auth-profiles.js";
|
||||||
import { resolveEnvApiKey } from "../agents/model-auth.js";
|
import { resolveEnvApiKey } from "../agents/model-auth.js";
|
||||||
|
import { normalizeProviderId } from "../agents/model-selection.js";
|
||||||
|
import { parseDurationMs } from "../cli/parse-duration.js";
|
||||||
import {
|
import {
|
||||||
type ClawdbotConfig,
|
type ClawdbotConfig,
|
||||||
CONFIG_PATH_CLAWDBOT,
|
CONFIG_PATH_CLAWDBOT,
|
||||||
@@ -206,18 +210,82 @@ export async function runNonInteractiveOnboarding(
|
|||||||
nextConfig = applyOpenAICodexModelDefault(nextConfig).next;
|
nextConfig = applyOpenAICodexModelDefault(nextConfig).next;
|
||||||
} else if (authChoice === "minimax") {
|
} else if (authChoice === "minimax") {
|
||||||
nextConfig = applyMinimaxConfig(nextConfig);
|
nextConfig = applyMinimaxConfig(nextConfig);
|
||||||
} else if (
|
} else if (authChoice === "setup-token" || authChoice === "oauth") {
|
||||||
authChoice === "token" ||
|
if (!process.stdin.isTTY) {
|
||||||
authChoice === "oauth" ||
|
runtime.error("`claude setup-token` requires an interactive TTY.");
|
||||||
authChoice === "openai-codex" ||
|
runtime.exit(1);
|
||||||
authChoice === "antigravity"
|
return;
|
||||||
) {
|
}
|
||||||
|
|
||||||
|
const res = spawnSync("claude", ["setup-token"], { stdio: "inherit" });
|
||||||
|
if (res.error) throw res.error;
|
||||||
|
if (typeof res.status === "number" && res.status !== 0) {
|
||||||
|
runtime.error(`claude setup-token failed (exit ${res.status})`);
|
||||||
|
runtime.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = ensureAuthProfileStore(undefined, {
|
||||||
|
allowKeychainPrompt: true,
|
||||||
|
});
|
||||||
|
if (!store.profiles[CLAUDE_CLI_PROFILE_ID]) {
|
||||||
|
runtime.error(
|
||||||
|
`No Claude CLI credentials found after setup-token. Expected auth profile ${CLAUDE_CLI_PROFILE_ID}.`,
|
||||||
|
);
|
||||||
|
runtime.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextConfig = applyAuthProfileConfig(nextConfig, {
|
||||||
|
profileId: CLAUDE_CLI_PROFILE_ID,
|
||||||
|
provider: "anthropic",
|
||||||
|
mode: "token",
|
||||||
|
});
|
||||||
|
} else if (authChoice === "token") {
|
||||||
|
const providerRaw = opts.tokenProvider?.trim();
|
||||||
|
const tokenRaw = opts.token?.trim();
|
||||||
|
if (!providerRaw) {
|
||||||
|
runtime.error(
|
||||||
|
"Missing --token-provider (required for --auth-choice token).",
|
||||||
|
);
|
||||||
|
runtime.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!tokenRaw) {
|
||||||
|
runtime.error("Missing --token (required for --auth-choice token).");
|
||||||
|
runtime.exit(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const provider = normalizeProviderId(providerRaw);
|
||||||
|
const profileId = (
|
||||||
|
opts.tokenProfileId?.trim() || `${provider}:manual`
|
||||||
|
).trim();
|
||||||
|
const expires =
|
||||||
|
opts.tokenExpiresIn?.trim() && opts.tokenExpiresIn.trim().length > 0
|
||||||
|
? Date.now() +
|
||||||
|
parseDurationMs(String(opts.tokenExpiresIn).trim(), {
|
||||||
|
defaultUnit: "d",
|
||||||
|
})
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
upsertAuthProfile({
|
||||||
|
profileId,
|
||||||
|
credential: {
|
||||||
|
type: "token",
|
||||||
|
provider,
|
||||||
|
token: tokenRaw,
|
||||||
|
...(expires ? { expires } : {}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
nextConfig = applyAuthProfileConfig(nextConfig, {
|
||||||
|
profileId,
|
||||||
|
provider,
|
||||||
|
mode: "token",
|
||||||
|
});
|
||||||
|
} else if (authChoice === "openai-codex" || authChoice === "antigravity") {
|
||||||
const label =
|
const label =
|
||||||
authChoice === "antigravity"
|
authChoice === "antigravity" ? "Antigravity" : "OpenAI Codex OAuth";
|
||||||
? "Antigravity"
|
|
||||||
: authChoice === "token"
|
|
||||||
? "Token"
|
|
||||||
: "OAuth";
|
|
||||||
runtime.error(`${label} requires interactive mode.`);
|
runtime.error(`${label} requires interactive mode.`);
|
||||||
runtime.exit(1);
|
runtime.exit(1);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ import type { GatewayDaemonRuntime } from "./daemon-runtime.js";
|
|||||||
|
|
||||||
export type OnboardMode = "local" | "remote";
|
export type OnboardMode = "local" | "remote";
|
||||||
export type AuthChoice =
|
export type AuthChoice =
|
||||||
|
// Legacy alias for `setup-token` (kept for backwards CLI compatibility).
|
||||||
| "oauth"
|
| "oauth"
|
||||||
|
| "setup-token"
|
||||||
| "claude-cli"
|
| "claude-cli"
|
||||||
| "token"
|
| "token"
|
||||||
| "openai-codex"
|
| "openai-codex"
|
||||||
@@ -27,6 +29,14 @@ export type OnboardOptions = {
|
|||||||
workspace?: string;
|
workspace?: string;
|
||||||
nonInteractive?: boolean;
|
nonInteractive?: boolean;
|
||||||
authChoice?: AuthChoice;
|
authChoice?: AuthChoice;
|
||||||
|
/** Used when `authChoice=token` in non-interactive mode. */
|
||||||
|
tokenProvider?: string;
|
||||||
|
/** Used when `authChoice=token` in non-interactive mode. */
|
||||||
|
token?: string;
|
||||||
|
/** Used when `authChoice=token` in non-interactive mode. */
|
||||||
|
tokenProfileId?: string;
|
||||||
|
/** Used when `authChoice=token` in non-interactive mode. */
|
||||||
|
tokenExpiresIn?: string;
|
||||||
anthropicApiKey?: string;
|
anthropicApiKey?: string;
|
||||||
openaiApiKey?: string;
|
openaiApiKey?: string;
|
||||||
geminiApiKey?: string;
|
geminiApiKey?: string;
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ export async function onboardCommand(
|
|||||||
runtime: RuntimeEnv = defaultRuntime,
|
runtime: RuntimeEnv = defaultRuntime,
|
||||||
) {
|
) {
|
||||||
assertSupportedRuntime(runtime);
|
assertSupportedRuntime(runtime);
|
||||||
|
const authChoice =
|
||||||
|
opts.authChoice === "oauth" ? ("setup-token" as const) : opts.authChoice;
|
||||||
|
const normalizedOpts =
|
||||||
|
authChoice === opts.authChoice ? opts : { ...opts, authChoice };
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
runtime.log(
|
runtime.log(
|
||||||
[
|
[
|
||||||
@@ -20,12 +25,12 @@ export async function onboardCommand(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.nonInteractive) {
|
if (normalizedOpts.nonInteractive) {
|
||||||
await runNonInteractiveOnboarding(opts, runtime);
|
await runNonInteractiveOnboarding(normalizedOpts, runtime);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await runInteractiveOnboarding(opts, runtime);
|
await runInteractiveOnboarding(normalizedOpts, runtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { OnboardOptions } from "./onboard-types.js";
|
export type { OnboardOptions } from "./onboard-types.js";
|
||||||
|
|||||||
Reference in New Issue
Block a user