From d6026ff1faaa61dda4d8115ae2876d3ec9404f6f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 16 Jul 2026 16:23:24 -0700 Subject: [PATCH] fix(clickclack): clear deadcode and lint breaks in setup flow Recent setup commits left the hard-zero gates red on every PR: parseClickClackSetupCodeInput was exported but only used internally, ClickClackSetupCodeClaimError was exported yet consumed only by its test (production catches it structurally through a status field), a string spread tripped no-misused-spread, and a computed "token" key tripped no-useless-computed-key. Un-export both symbols, switch the test to a structural claim-error stand-in matching what the formatter reads, and apply the two mechanical lint fixes. --- extensions/clickclack/src/setup-claim.ts | 2 +- extensions/clickclack/src/setup-core.test.ts | 15 ++++++++------- extensions/clickclack/src/setup-core.ts | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/extensions/clickclack/src/setup-claim.ts b/extensions/clickclack/src/setup-claim.ts index 9bc4ff3de031..148fd891a3ce 100644 --- a/extensions/clickclack/src/setup-claim.ts +++ b/extensions/clickclack/src/setup-claim.ts @@ -13,7 +13,7 @@ const CLICKCLACK_ERROR_BODY_LIMIT_BYTES = 8 * 1024; const CLICKCLACK_SETUP_CODE_CLAIM_JSON_LIMIT_BYTES = 64 * 1024; const CLICKCLACK_SETUP_CODE_CLAIM_TIMEOUT_MS = 30_000; -export class ClickClackSetupCodeClaimError extends Error { +class ClickClackSetupCodeClaimError extends Error { constructor( readonly status: number, detail: string, diff --git a/extensions/clickclack/src/setup-core.test.ts b/extensions/clickclack/src/setup-core.test.ts index 4daee6ab28c6..d714d5b4e902 100644 --- a/extensions/clickclack/src/setup-core.test.ts +++ b/extensions/clickclack/src/setup-core.test.ts @@ -14,13 +14,18 @@ vi.mock("./setup-claim.js", async (importOriginal) => ({ vi.mock("./setup-verify.js", () => ({ verifyClickClackAccountAfterSetup, })); -import { ClickClackSetupCodeClaimError } from "./setup-claim.js"; import { applyClickClackCredentialConfig, clickClackSetupAdapter, normalizeClickClackBaseUrl, } from "./setup-core.js"; +// Structural stand-in for the internal claim error: the setup formatter +// duck-types on a numeric `status`, so tests need only that shape. +function makeClaimError(status: number, detail: string): Error { + return Object.assign(new Error(`claim failed (${status}): ${detail}`), { status }); +} + function validate(params: { cfg?: OpenClawConfig; accountId?: string; @@ -163,16 +168,12 @@ describe("ClickClack setup adapter", () => { }); it("maps invalid and rate-limited claims to actionable errors", async () => { - claimClickClackSetupCode.mockRejectedValueOnce( - new ClickClackSetupCodeClaimError(404, "not found"), - ); + claimClickClackSetupCode.mockRejectedValueOnce(makeClaimError(404, "not found")); await expect( prepare({ code: "ABCD-EFGH-JKMN", baseUrl: "https://clickclack.example" }), ).rejects.toThrow("invalid, expired, or already used"); - claimClickClackSetupCode.mockRejectedValueOnce( - new ClickClackSetupCodeClaimError(429, "retry later"), - ); + claimClickClackSetupCode.mockRejectedValueOnce(makeClaimError(429, "retry later")); await expect( prepare({ code: "ABCD-EFGH-JKMN", baseUrl: "https://clickclack.example" }), ).rejects.toThrow("Too many ClickClack setup code attempts"); diff --git a/extensions/clickclack/src/setup-core.ts b/extensions/clickclack/src/setup-core.ts index 089581bd6f7a..09db51db7733 100644 --- a/extensions/clickclack/src/setup-core.ts +++ b/extensions/clickclack/src/setup-core.ts @@ -42,7 +42,7 @@ function normalizeClickClackSetupCode(value: string): string | undefined { const normalized = value.trim().toUpperCase().replaceAll("-", "").replaceAll(" ", ""); if ( normalized.length !== SETUP_CODE_LENGTH || - [...normalized].some((character) => !SETUP_CODE_ALPHABET.includes(character)) + Array.from(normalized).some((character) => !SETUP_CODE_ALPHABET.includes(character)) ) { return undefined; } @@ -57,7 +57,7 @@ function requireHttpsClickClackBaseUrl(value: string | undefined): string { return baseUrl; } -export function parseClickClackSetupCodeInput(params: { code: string; baseUrl?: string }): { +function parseClickClackSetupCodeInput(params: { code: string; baseUrl?: string }): { code: string; baseUrl: string; } { @@ -263,7 +263,7 @@ export const clickClackSetupAdapter: ChannelSetupAdapter = { return { ...remainingInput, baseUrl: setup.baseUrl, - ["token"]: claim.token, + token: claim.token, workspace: claim.workspace.id, ...(claim.defaults.defaultTo !== undefined ? { defaultTo: claim.defaults.defaultTo } : {}), ...(claim.defaults.allowFrom !== undefined