CLI: default pairing channel for pairing commands
This commit is contained in:
@@ -60,6 +60,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Discord: restore model picker back navigation when a provider is missing and document the Discord picker flow. (#21458) Thanks @pejmanjohn and @thewilloftheshadow.
|
||||
- Gateway/Pairing: tolerate legacy paired devices missing `roles`/`scopes` metadata in websocket upgrade checks and backfill metadata on reconnect. (#21447, fixes #21236) Thanks @joshavant.
|
||||
- Gateway/Pairing/CLI: align read-scope compatibility in pairing/device-token checks and add local `openclaw devices` fallback recovery for loopback `pairing required` deadlocks, with explicit fallback notice to unblock approval bootstrap flows. (#21616) Thanks @shakkernerd.
|
||||
- CLI/Pairing: default `pairing list` and `pairing approve` to the sole available pairing channel when omitted, so TUI-only setups can recover from `pairing required` without guessing channel arguments. (#21527) Thanks @losts1.
|
||||
- Auth/Onboarding: align OAuth profile-id config mapping with stored credential IDs for OpenAI Codex and Chutes flows, preventing `provider:default` mismatches when OAuth returns email-scoped credentials. (#12692) thanks @mudrii.
|
||||
- Docker: pin base images to SHA256 digests in Docker builds to prevent mutable tag drift. (#7734) Thanks @coygeek.
|
||||
- Docker/Security: run E2E and install-sh test images as non-root by adding appuser directives. Thanks @thewilloftheshadow.
|
||||
|
||||
@@ -163,6 +163,15 @@ describe("pairing cli", () => {
|
||||
expect(listChannelPairingRequests).toHaveBeenCalledWith("zalo");
|
||||
});
|
||||
|
||||
it("defaults list to the sole available channel", async () => {
|
||||
listPairingChannels.mockReturnValueOnce(["slack"]);
|
||||
listChannelPairingRequests.mockResolvedValueOnce([]);
|
||||
|
||||
await runPairing(["pairing", "list"]);
|
||||
|
||||
expect(listChannelPairingRequests).toHaveBeenCalledWith("slack");
|
||||
});
|
||||
|
||||
it("accepts channel as positional for approve (npm-run compatible)", async () => {
|
||||
mockApprovedPairing();
|
||||
|
||||
@@ -199,4 +208,20 @@ describe("pairing cli", () => {
|
||||
accountId: "yy",
|
||||
});
|
||||
});
|
||||
|
||||
it("defaults approve to the sole available channel when only code is provided", async () => {
|
||||
listPairingChannels.mockReturnValueOnce(["slack"]);
|
||||
mockApprovedPairing();
|
||||
|
||||
await runPairing(["pairing", "approve", "ABCDEFGH"]);
|
||||
|
||||
expect(approveChannelPairingCode).toHaveBeenCalledWith({
|
||||
channel: "slack",
|
||||
code: "ABCDEFGH",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps approve usage error when multiple channels exist and channel is omitted", async () => {
|
||||
await expect(runPairing(["pairing", "approve", "ABCDEFGH"])).rejects.toThrow("Usage:");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ export function registerPairingCli(program: Command) {
|
||||
.argument("[channel]", `Channel (${channels.join(", ")})`)
|
||||
.option("--json", "Print JSON", false)
|
||||
.action(async (channelArg, opts) => {
|
||||
const channelRaw = opts.channel ?? channelArg;
|
||||
const channelRaw = opts.channel ?? channelArg ?? (channels.length === 1 ? channels[0] : "");
|
||||
if (!channelRaw) {
|
||||
throw new Error(
|
||||
`Channel required. Use --channel <channel> or pass it as the first argument (expected one of: ${channels.join(", ")})`,
|
||||
@@ -120,9 +120,20 @@ export function registerPairingCli(program: Command) {
|
||||
.argument("[code]", "Pairing code (when channel is passed as the 1st arg)")
|
||||
.option("--notify", "Notify the requester on the same channel", false)
|
||||
.action(async (codeOrChannel, code, opts) => {
|
||||
const channelRaw = opts.channel ?? codeOrChannel;
|
||||
const resolvedCode = opts.channel ? codeOrChannel : code;
|
||||
if (!opts.channel && !code) {
|
||||
const defaultChannel = channels.length === 1 ? channels[0] : "";
|
||||
const usingExplicitChannel = Boolean(opts.channel);
|
||||
const hasPositionalCode = code != null;
|
||||
const channelRaw = usingExplicitChannel
|
||||
? opts.channel
|
||||
: hasPositionalCode
|
||||
? codeOrChannel
|
||||
: defaultChannel;
|
||||
const resolvedCode = usingExplicitChannel
|
||||
? codeOrChannel
|
||||
: hasPositionalCode
|
||||
? code
|
||||
: codeOrChannel;
|
||||
if (!channelRaw || !resolvedCode) {
|
||||
throw new Error(
|
||||
`Usage: ${formatCliCommand("openclaw pairing approve <channel> <code>")} (or: ${formatCliCommand("openclaw pairing approve --channel <channel> <code>")})`,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user