feat(cli): move provider login/logout
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
- Commands: gate all slash commands to authorized senders; add `/compact` to manually compact session context.
|
- Commands: gate all slash commands to authorized senders; add `/compact` to manually compact session context.
|
||||||
- Groups: `whatsapp.groups`, `telegram.groups`, and `imessage.groups` now act as allowlists when set. Add `"*"` to keep allow-all behavior.
|
- Groups: `whatsapp.groups`, `telegram.groups`, and `imessage.groups` now act as allowlists when set. Add `"*"` to keep allow-all behavior.
|
||||||
- Auto-reply: removed `autoReply` from Discord/Slack/Telegram channel configs; use `requireMention` instead (Telegram topics now support `requireMention` overrides).
|
- Auto-reply: removed `autoReply` from Discord/Slack/Telegram channel configs; use `requireMention` instead (Telegram topics now support `requireMention` overrides).
|
||||||
- CLI: remove `update`, `gateway-daemon`, `gateway {install|uninstall|start|stop|restart|daemon status|wake|send|agent}`, and `telegram` commands; use `daemon` for service control, `send`/`agent`/`wake` for RPC, and `nodes canvas` for canvas ops.
|
- CLI: remove `update`, `gateway-daemon`, `gateway {install|uninstall|start|stop|restart|daemon status|wake|send|agent}`, and `telegram` commands; move `login/logout` to `providers login/logout` (top-level aliases hidden); use `daemon` for service control, `send`/`agent`/`wake` for RPC, and `nodes canvas` for canvas ops.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Auto-reply: keep typing indicators alive during tool execution without changing typing-mode semantics. Thanks @thesash for PR #452.
|
- Auto-reply: keep typing indicators alive during tool execution without changing typing-mode semantics. Thanks @thesash for PR #452.
|
||||||
|
|||||||
@@ -44,13 +44,13 @@ clawdbot [--dev] [--profile <name>] <command>
|
|||||||
onboard
|
onboard
|
||||||
configure (alias: config)
|
configure (alias: config)
|
||||||
doctor
|
doctor
|
||||||
login
|
|
||||||
logout
|
|
||||||
providers
|
providers
|
||||||
list
|
list
|
||||||
status
|
status
|
||||||
add
|
add
|
||||||
remove
|
remove
|
||||||
|
login
|
||||||
|
logout
|
||||||
skills
|
skills
|
||||||
list
|
list
|
||||||
info
|
info
|
||||||
@@ -138,8 +138,6 @@ clawdbot [--dev] [--profile <name>] <command>
|
|||||||
pairing
|
pairing
|
||||||
list
|
list
|
||||||
approve
|
approve
|
||||||
telegram
|
|
||||||
pairing list|approve
|
|
||||||
docs
|
docs
|
||||||
dns
|
dns
|
||||||
setup
|
setup
|
||||||
@@ -198,22 +196,7 @@ Options:
|
|||||||
- `--non-interactive`: skip prompts; apply safe migrations only.
|
- `--non-interactive`: skip prompts; apply safe migrations only.
|
||||||
- `--deep`: scan system services for extra gateway installs.
|
- `--deep`: scan system services for extra gateway installs.
|
||||||
|
|
||||||
## Auth + provider helpers
|
## Provider helpers
|
||||||
|
|
||||||
### `login`
|
|
||||||
Link a WhatsApp Web account via QR.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
- `--verbose`
|
|
||||||
- `--provider <provider>` (default `whatsapp`)
|
|
||||||
- `--account <id>`
|
|
||||||
|
|
||||||
### `logout`
|
|
||||||
Clear cached WhatsApp Web credentials.
|
|
||||||
|
|
||||||
Options:
|
|
||||||
- `--provider <provider>`
|
|
||||||
- `--account <id>`
|
|
||||||
|
|
||||||
### `providers`
|
### `providers`
|
||||||
Manage chat provider accounts (WhatsApp/Telegram/Discord/Slack/Signal/iMessage).
|
Manage chat provider accounts (WhatsApp/Telegram/Discord/Slack/Signal/iMessage).
|
||||||
@@ -223,12 +206,23 @@ Subcommands:
|
|||||||
- `providers status`: check gateway reachability and provider health (`--probe` to verify credentials; use `status --deep` for local-only probes).
|
- `providers status`: check gateway reachability and provider health (`--probe` to verify credentials; use `status --deep` for local-only probes).
|
||||||
- `providers add`: wizard-style setup when no flags are passed; flags switch to non-interactive mode.
|
- `providers add`: wizard-style setup when no flags are passed; flags switch to non-interactive mode.
|
||||||
- `providers remove`: disable by default; pass `--delete` to remove config entries without prompts.
|
- `providers remove`: disable by default; pass `--delete` to remove config entries without prompts.
|
||||||
|
- `providers login`: interactive provider login (WhatsApp Web only).
|
||||||
|
- `providers logout`: log out of a provider session (WhatsApp Web only).
|
||||||
|
|
||||||
Common options:
|
Common options:
|
||||||
- `--provider <name>`: `whatsapp|telegram|discord|slack|signal|imessage`
|
- `--provider <name>`: `whatsapp|telegram|discord|slack|signal|imessage`
|
||||||
- `--account <id>`: provider account id (default `default`)
|
- `--account <id>`: provider account id (default `default`)
|
||||||
- `--name <label>`: display name for the account
|
- `--name <label>`: display name for the account
|
||||||
|
|
||||||
|
`providers login` options:
|
||||||
|
- `--provider <provider>` (default `whatsapp`; supports `whatsapp`/`web`)
|
||||||
|
- `--account <id>`
|
||||||
|
- `--verbose`
|
||||||
|
|
||||||
|
`providers logout` options:
|
||||||
|
- `--provider <provider>` (default `whatsapp`; supports `whatsapp`/`web`)
|
||||||
|
- `--account <id>`
|
||||||
|
|
||||||
`providers list` options:
|
`providers list` options:
|
||||||
- `--no-usage`: skip provider usage/quota snapshots (OAuth/API-backed only).
|
- `--no-usage`: skip provider usage/quota snapshots (OAuth/API-backed only).
|
||||||
- `--json`: output JSON (includes usage unless `--no-usage` is set).
|
- `--json`: output JSON (includes usage unless `--no-usage` is set).
|
||||||
|
|||||||
@@ -17,10 +17,10 @@ Short guide to verify the WhatsApp Web / Baileys stack without guessing.
|
|||||||
## Deep diagnostics
|
## Deep diagnostics
|
||||||
- Creds on disk: `ls -l ~/.clawdbot/credentials/whatsapp/<accountId>/creds.json` (mtime should be recent).
|
- Creds on disk: `ls -l ~/.clawdbot/credentials/whatsapp/<accountId>/creds.json` (mtime should be recent).
|
||||||
- Session store: `ls -l ~/.clawdbot/agents/<agentId>/sessions/sessions.json` (path can be overridden in config). Count and recent recipients are surfaced via `status`.
|
- Session store: `ls -l ~/.clawdbot/agents/<agentId>/sessions/sessions.json` (path can be overridden in config). Count and recent recipients are surfaced via `status`.
|
||||||
- Relink flow: `clawdbot logout && clawdbot login --verbose` when status codes 409–515 or `loggedOut` appear in logs. (Note: the QR login flow auto-restarts once for status 515 after pairing.)
|
- Relink flow: `clawdbot providers logout && clawdbot providers login --verbose` when status codes 409–515 or `loggedOut` appear in logs. (Note: the QR login flow auto-restarts once for status 515 after pairing.)
|
||||||
|
|
||||||
## When something fails
|
## When something fails
|
||||||
- `logged out` or status 409–515 → relink with `clawdbot logout` then `clawdbot login`.
|
- `logged out` or status 409–515 → relink with `clawdbot providers logout` then `clawdbot providers login`.
|
||||||
- Gateway unreachable → start it: `clawdbot gateway --port 18789` (use `--force` if the port is busy).
|
- Gateway unreachable → start it: `clawdbot gateway --port 18789` (use `--force` if the port is busy).
|
||||||
- No inbound messages → confirm linked phone is online and the sender is allowed (`whatsapp.allowFrom`); for group chats, ensure allowlist + mention rules match (`whatsapp.groups`, `routing.groupChat.mentionPatterns`).
|
- No inbound messages → confirm linked phone is online and the sender is allowed (`whatsapp.allowFrom`); for group chats, ensure allowlist + mention rules match (`whatsapp.groups`, `routing.groupChat.mentionPatterns`).
|
||||||
|
|
||||||
|
|||||||
@@ -138,9 +138,9 @@ clawdbot gateway --verbose
|
|||||||
If you’re logged out / unlinked:
|
If you’re logged out / unlinked:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clawdbot logout
|
clawdbot providers logout
|
||||||
trash ~/.clawdbot/credentials # if logout can't cleanly remove everything
|
trash ~/.clawdbot/credentials # if logout can't cleanly remove everything
|
||||||
clawdbot login --verbose # re-scan QR
|
clawdbot providers login --verbose # re-scan QR
|
||||||
```
|
```
|
||||||
|
|
||||||
### Media Send Failing
|
### Media Send Failing
|
||||||
@@ -219,7 +219,7 @@ Get verbose logging:
|
|||||||
#
|
#
|
||||||
# Then run verbose commands to mirror debug output to stdout:
|
# Then run verbose commands to mirror debug output to stdout:
|
||||||
clawdbot gateway --verbose
|
clawdbot gateway --verbose
|
||||||
clawdbot login --verbose
|
clawdbot providers login --verbose
|
||||||
```
|
```
|
||||||
|
|
||||||
## Log Locations
|
## Log Locations
|
||||||
@@ -250,7 +250,7 @@ Nuclear option:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
trash ~/.clawdbot
|
trash ~/.clawdbot
|
||||||
clawdbot login # re-pair WhatsApp
|
clawdbot providers login # re-pair WhatsApp
|
||||||
clawdbot gateway # start the Gateway again
|
clawdbot gateway # start the Gateway again
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ pnpm build
|
|||||||
pnpm link --global
|
pnpm link --global
|
||||||
|
|
||||||
# Pair WhatsApp Web (shows QR)
|
# Pair WhatsApp Web (shows QR)
|
||||||
clawdbot login
|
clawdbot providers login
|
||||||
|
|
||||||
# Run the Gateway (leave running)
|
# Run the Gateway (leave running)
|
||||||
clawdbot gateway --port 18789
|
clawdbot gateway --port 18789
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ This flow lets the macOS app act as a full remote control for a Clawdbot gateway
|
|||||||
- Nodes advertise their permission state via `node.list` / `node.describe` so agents know what’s available.
|
- Nodes advertise their permission state via `node.list` / `node.describe` so agents know what’s available.
|
||||||
|
|
||||||
## WhatsApp login flow (remote)
|
## WhatsApp login flow (remote)
|
||||||
- Run `clawdbot login --verbose` **on the remote host**. Scan the QR with WhatsApp on your phone.
|
- Run `clawdbot providers login --verbose` **on the remote host**. Scan the QR with WhatsApp on your phone.
|
||||||
- Re-run login on that host if auth expires. Health check will surface link problems.
|
- Re-run login on that host if auth expires. Health check will surface link problems.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|||||||
@@ -43,13 +43,13 @@ WhatsApp requires a real mobile number for verification. VoIP and virtual number
|
|||||||
- Result: unreliable delivery and frequent blocks, so support was removed.
|
- Result: unreliable delivery and frequent blocks, so support was removed.
|
||||||
|
|
||||||
## Login + credentials
|
## Login + credentials
|
||||||
- Login command: `clawdbot login` (QR via Linked Devices).
|
- Login command: `clawdbot providers login` (QR via Linked Devices).
|
||||||
- Multi-account login: `clawdbot login --account <id>` (`<id>` = `accountId`).
|
- Multi-account login: `clawdbot providers login --account <id>` (`<id>` = `accountId`).
|
||||||
- Default account (when `--account` is omitted): `default` if present, otherwise the first configured account id (sorted).
|
- Default account (when `--account` is omitted): `default` if present, otherwise the first configured account id (sorted).
|
||||||
- Credentials stored in `~/.clawdbot/credentials/whatsapp/<accountId>/creds.json`.
|
- Credentials stored in `~/.clawdbot/credentials/whatsapp/<accountId>/creds.json`.
|
||||||
- Backup copy at `creds.json.bak` (restored on corruption).
|
- Backup copy at `creds.json.bak` (restored on corruption).
|
||||||
- Legacy compatibility: older installs stored Baileys files directly in `~/.clawdbot/credentials/`.
|
- Legacy compatibility: older installs stored Baileys files directly in `~/.clawdbot/credentials/`.
|
||||||
- Logout: `clawdbot logout` (or `--account <id>`) deletes WhatsApp auth state (but keeps shared `oauth.json`).
|
- Logout: `clawdbot providers logout` (or `--account <id>`) deletes WhatsApp auth state (but keeps shared `oauth.json`).
|
||||||
- Logged-out socket => error instructs re-link.
|
- Logged-out socket => error instructs re-link.
|
||||||
|
|
||||||
## Inbound flow (DM + group)
|
## Inbound flow (DM + group)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ If you link your personal WhatsApp to CLAWDBOT, every message to you becomes “
|
|||||||
1) Pair WhatsApp Web (shows QR; scan with the assistant phone):
|
1) Pair WhatsApp Web (shows QR; scan with the assistant phone):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clawdbot login
|
clawdbot providers login
|
||||||
```
|
```
|
||||||
|
|
||||||
2) Start the Gateway (leave it running):
|
2) Start the Gateway (leave it running):
|
||||||
|
|||||||
@@ -430,7 +430,7 @@ You can add options like `debounce:2s cap:25 drop:summarize` for followup modes.
|
|||||||
Run the login command again and scan the QR code:
|
Run the login command again and scan the QR code:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clawdbot login
|
clawdbot providers login
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build errors on `main` — what’s the standard fix path?
|
### Build errors on `main` — what’s the standard fix path?
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ https://github.com/oven-sh/bun/issues/5951
|
|||||||
### WhatsApp (QR login)
|
### WhatsApp (QR login)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm clawdbot login
|
pnpm clawdbot providers login
|
||||||
```
|
```
|
||||||
|
|
||||||
Scan via WhatsApp → Settings → Linked Devices.
|
Scan via WhatsApp → Settings → Linked Devices.
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ pnpm clawdbot setup
|
|||||||
4) Link surfaces (example: WhatsApp):
|
4) Link surfaces (example: WhatsApp):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
clawdbot login
|
clawdbot providers login
|
||||||
```
|
```
|
||||||
|
|
||||||
5) Sanity check:
|
5) Sanity check:
|
||||||
@@ -56,7 +56,7 @@ clawdbot health
|
|||||||
```
|
```
|
||||||
|
|
||||||
If onboarding is still WIP/broken on your build:
|
If onboarding is still WIP/broken on your build:
|
||||||
- Run `clawdbot setup`, then `clawdbot login`, then start the Gateway manually (`clawdbot gateway`).
|
- Run `clawdbot setup`, then `clawdbot providers login`, then start the Gateway manually (`clawdbot gateway`).
|
||||||
|
|
||||||
## Bleeding edge workflow (Gateway in a terminal)
|
## Bleeding edge workflow (Gateway in a terminal)
|
||||||
|
|
||||||
|
|||||||
@@ -23,11 +23,10 @@ import {
|
|||||||
} from "../config/config.js";
|
} from "../config/config.js";
|
||||||
import { danger, setVerbose } from "../globals.js";
|
import { danger, setVerbose } from "../globals.js";
|
||||||
import { autoMigrateLegacyState } from "../infra/state-migrations.js";
|
import { autoMigrateLegacyState } from "../infra/state-migrations.js";
|
||||||
import { loginWeb, logoutWeb } from "../provider-web.js";
|
import { runProviderLogin, runProviderLogout } from "./provider-auth.js";
|
||||||
import { defaultRuntime } from "../runtime.js";
|
import { defaultRuntime } from "../runtime.js";
|
||||||
import { isRich, theme } from "../terminal/theme.js";
|
import { isRich, theme } from "../terminal/theme.js";
|
||||||
import { VERSION } from "../version.js";
|
import { VERSION } from "../version.js";
|
||||||
import { resolveWhatsAppAccount } from "../web/accounts.js";
|
|
||||||
import { emitCliBanner, formatCliBannerLine } from "./banner.js";
|
import { emitCliBanner, formatCliBannerLine } from "./banner.js";
|
||||||
import { registerBrowserCli } from "./browser-cli.js";
|
import { registerBrowserCli } from "./browser-cli.js";
|
||||||
import { hasExplicitOptions } from "./command-options.js";
|
import { hasExplicitOptions } from "./command-options.js";
|
||||||
@@ -138,7 +137,7 @@ export function buildProgram() {
|
|||||||
});
|
});
|
||||||
const examples = [
|
const examples = [
|
||||||
[
|
[
|
||||||
"clawdbot login --verbose",
|
"clawdbot providers login --verbose",
|
||||||
"Link personal WhatsApp Web and show QR + connection logs.",
|
"Link personal WhatsApp Web and show QR + connection logs.",
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
@@ -342,23 +341,22 @@ export function buildProgram() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Deprecated hidden aliases: use `clawdbot providers login/logout`. Remove in a future major.
|
||||||
program
|
program
|
||||||
program
|
.command("login", { hidden: true })
|
||||||
.command("login")
|
|
||||||
.description("Link your personal WhatsApp via QR (web provider)")
|
.description("Link your personal WhatsApp via QR (web provider)")
|
||||||
.option("--verbose", "Verbose connection logs", false)
|
.option("--verbose", "Verbose connection logs", false)
|
||||||
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
||||||
.option("--account <id>", "WhatsApp account id (accountId)")
|
.option("--account <id>", "WhatsApp account id (accountId)")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
setVerbose(Boolean(opts.verbose));
|
|
||||||
try {
|
try {
|
||||||
const provider = opts.provider ?? "whatsapp";
|
await runProviderLogin(
|
||||||
await loginWeb(
|
{
|
||||||
Boolean(opts.verbose),
|
provider: opts.provider as string | undefined,
|
||||||
provider,
|
account: opts.account as string | undefined,
|
||||||
undefined,
|
verbose: Boolean(opts.verbose),
|
||||||
|
},
|
||||||
defaultRuntime,
|
defaultRuntime,
|
||||||
opts.account as string | undefined,
|
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
defaultRuntime.error(danger(`Web login failed: ${String(err)}`));
|
defaultRuntime.error(danger(`Web login failed: ${String(err)}`));
|
||||||
@@ -367,23 +365,19 @@ export function buildProgram() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
program
|
program
|
||||||
.command("logout")
|
.command("logout", { hidden: true })
|
||||||
.description("Clear cached WhatsApp Web credentials")
|
.description("Log out of WhatsApp Web (keeps config)")
|
||||||
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
||||||
.option("--account <id>", "WhatsApp account id (accountId)")
|
.option("--account <id>", "WhatsApp account id (accountId)")
|
||||||
.action(async (opts) => {
|
.action(async (opts) => {
|
||||||
try {
|
try {
|
||||||
void opts.provider; // placeholder for future multi-provider; currently web only.
|
await runProviderLogout(
|
||||||
const cfg = loadConfig();
|
{
|
||||||
const account = resolveWhatsAppAccount({
|
provider: opts.provider as string | undefined,
|
||||||
cfg,
|
account: opts.account as string | undefined,
|
||||||
accountId: opts.account as string | undefined,
|
},
|
||||||
});
|
defaultRuntime,
|
||||||
await logoutWeb({
|
);
|
||||||
runtime: defaultRuntime,
|
|
||||||
authDir: account.authDir,
|
|
||||||
isLegacyAuthDir: account.isLegacyAuthDir,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
defaultRuntime.error(danger(`Logout failed: ${String(err)}`));
|
defaultRuntime.error(danger(`Logout failed: ${String(err)}`));
|
||||||
defaultRuntime.exit(1);
|
defaultRuntime.exit(1);
|
||||||
|
|||||||
51
src/cli/provider-auth.ts
Normal file
51
src/cli/provider-auth.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import { loadConfig } from "../config/config.js";
|
||||||
|
import { setVerbose } from "../globals.js";
|
||||||
|
import { defaultRuntime, type RuntimeEnv } from "../runtime.js";
|
||||||
|
import { loginWeb, logoutWeb } from "../provider-web.js";
|
||||||
|
import { resolveWhatsAppAccount } from "../web/accounts.js";
|
||||||
|
|
||||||
|
type ProviderAuthOptions = {
|
||||||
|
provider?: string;
|
||||||
|
account?: string;
|
||||||
|
verbose?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
function normalizeProvider(raw?: string): "whatsapp" | "web" {
|
||||||
|
const value = String(raw ?? "whatsapp").trim().toLowerCase();
|
||||||
|
if (value === "whatsapp" || value === "web") return value;
|
||||||
|
throw new Error(`Unsupported provider: ${value}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runProviderLogin(
|
||||||
|
opts: ProviderAuthOptions,
|
||||||
|
runtime: RuntimeEnv = defaultRuntime,
|
||||||
|
) {
|
||||||
|
const provider = normalizeProvider(opts.provider);
|
||||||
|
// Auth-only flow: do not mutate provider config here.
|
||||||
|
setVerbose(Boolean(opts.verbose));
|
||||||
|
await loginWeb(
|
||||||
|
Boolean(opts.verbose),
|
||||||
|
provider,
|
||||||
|
undefined,
|
||||||
|
runtime,
|
||||||
|
opts.account,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function runProviderLogout(
|
||||||
|
opts: ProviderAuthOptions,
|
||||||
|
runtime: RuntimeEnv = defaultRuntime,
|
||||||
|
) {
|
||||||
|
const provider = normalizeProvider(opts.provider);
|
||||||
|
// Auth-only flow: resolve account + clear session state only.
|
||||||
|
const cfg = loadConfig();
|
||||||
|
const account = resolveWhatsAppAccount({
|
||||||
|
cfg,
|
||||||
|
accountId: opts.account,
|
||||||
|
});
|
||||||
|
await logoutWeb({
|
||||||
|
runtime,
|
||||||
|
authDir: account.authDir,
|
||||||
|
isLegacyAuthDir: account.isLegacyAuthDir,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -7,7 +7,9 @@ import {
|
|||||||
providersStatusCommand,
|
providersStatusCommand,
|
||||||
} from "../commands/providers.js";
|
} from "../commands/providers.js";
|
||||||
import { listChatProviders } from "../providers/registry.js";
|
import { listChatProviders } from "../providers/registry.js";
|
||||||
|
import { danger } from "../globals.js";
|
||||||
import { defaultRuntime } from "../runtime.js";
|
import { defaultRuntime } from "../runtime.js";
|
||||||
|
import { runProviderLogin, runProviderLogout } from "./provider-auth.js";
|
||||||
import { hasExplicitOptions } from "./command-options.js";
|
import { hasExplicitOptions } from "./command-options.js";
|
||||||
|
|
||||||
const optionNamesAdd = [
|
const optionNamesAdd = [
|
||||||
@@ -116,4 +118,46 @@ export function registerProvidersCli(program: Command) {
|
|||||||
defaultRuntime.exit(1);
|
defaultRuntime.exit(1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
providers
|
||||||
|
.command("login")
|
||||||
|
.description("Link a provider account (WhatsApp Web only)")
|
||||||
|
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
||||||
|
.option("--account <id>", "WhatsApp account id (accountId)")
|
||||||
|
.option("--verbose", "Verbose connection logs", false)
|
||||||
|
.action(async (opts) => {
|
||||||
|
try {
|
||||||
|
await runProviderLogin(
|
||||||
|
{
|
||||||
|
provider: opts.provider as string | undefined,
|
||||||
|
account: opts.account as string | undefined,
|
||||||
|
verbose: Boolean(opts.verbose),
|
||||||
|
},
|
||||||
|
defaultRuntime,
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
defaultRuntime.error(danger(`Provider login failed: ${String(err)}`));
|
||||||
|
defaultRuntime.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
providers
|
||||||
|
.command("logout")
|
||||||
|
.description("Log out of a provider session (WhatsApp Web only)")
|
||||||
|
.option("--provider <provider>", "Provider alias (default: whatsapp)")
|
||||||
|
.option("--account <id>", "WhatsApp account id (accountId)")
|
||||||
|
.action(async (opts) => {
|
||||||
|
try {
|
||||||
|
await runProviderLogout(
|
||||||
|
{
|
||||||
|
provider: opts.provider as string | undefined,
|
||||||
|
account: opts.account as string | undefined,
|
||||||
|
},
|
||||||
|
defaultRuntime,
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
defaultRuntime.error(danger(`Provider logout failed: ${String(err)}`));
|
||||||
|
defaultRuntime.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ export async function healthCommand(
|
|||||||
runtime.log(
|
runtime.log(
|
||||||
summary.web.linked
|
summary.web.linked
|
||||||
? `Web: linked (auth age ${summary.web.authAgeMs ? `${Math.round(summary.web.authAgeMs / 60000)}m` : "unknown"})`
|
? `Web: linked (auth age ${summary.web.authAgeMs ? `${Math.round(summary.web.authAgeMs / 60000)}m` : "unknown"})`
|
||||||
: "Web: not linked (run clawdbot login)",
|
: "Web: not linked (run clawdbot providers login)",
|
||||||
);
|
);
|
||||||
if (summary.web.linked) {
|
if (summary.web.linked) {
|
||||||
const cfg = loadConfig();
|
const cfg = loadConfig();
|
||||||
|
|||||||
@@ -856,7 +856,7 @@ export async function setupProviders(
|
|||||||
}
|
}
|
||||||
} else if (!whatsappLinked) {
|
} else if (!whatsappLinked) {
|
||||||
await prompter.note(
|
await prompter.note(
|
||||||
"Run `clawdbot login` later to link WhatsApp.",
|
"Run `clawdbot providers login` later to link WhatsApp.",
|
||||||
"WhatsApp",
|
"WhatsApp",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1611,7 +1611,7 @@ export async function monitorWebProvider(
|
|||||||
|
|
||||||
if (loggedOut) {
|
if (loggedOut) {
|
||||||
runtime.error(
|
runtime.error(
|
||||||
"WhatsApp session logged out. Run `clawdbot login --provider web` to relink.",
|
"WhatsApp session logged out. Run `clawdbot providers login --provider web` to relink.",
|
||||||
);
|
);
|
||||||
await closeListener();
|
await closeListener();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export async function loginWeb(
|
|||||||
});
|
});
|
||||||
console.error(
|
console.error(
|
||||||
danger(
|
danger(
|
||||||
"WhatsApp reported the session is logged out. Cleared cached web session; please rerun clawdbot login and scan the QR again.",
|
"WhatsApp reported the session is logged out. Cleared cached web session; please rerun clawdbot providers login and scan the QR again.",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
throw new Error("Session logged out; cache cleared. Re-run login.");
|
throw new Error("Session logged out; cache cleared. Re-run login.");
|
||||||
|
|||||||
@@ -169,7 +169,9 @@ export async function createWaSocket(
|
|||||||
const status = getStatusCode(lastDisconnect?.error);
|
const status = getStatusCode(lastDisconnect?.error);
|
||||||
if (status === DisconnectReason.loggedOut) {
|
if (status === DisconnectReason.loggedOut) {
|
||||||
console.error(
|
console.error(
|
||||||
danger("WhatsApp session logged out. Run: clawdbot login"),
|
danger(
|
||||||
|
"WhatsApp session logged out. Run: clawdbot providers login",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -454,7 +456,7 @@ export async function pickProvider(
|
|||||||
const hasWeb = await webAuthExists(authDir);
|
const hasWeb = await webAuthExists(authDir);
|
||||||
if (!hasWeb) {
|
if (!hasWeb) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"No WhatsApp Web session found. Run `clawdbot login --verbose` to link.",
|
"No WhatsApp Web session found. Run `clawdbot providers login --verbose` to link.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return choice;
|
return choice;
|
||||||
|
|||||||
Reference in New Issue
Block a user