diff --git a/extensions/signal/src/setup-surface.test.ts b/extensions/signal/src/setup-surface.test.ts index 0b291f0b66c3..447e87abf1ad 100644 --- a/extensions/signal/src/setup-surface.test.ts +++ b/extensions/signal/src/setup-surface.test.ts @@ -329,39 +329,22 @@ describe("signalSetupWizard QR linking", () => { expect(linkSignalCliAccountMock).not.toHaveBeenCalled(); }); - it.each([ - { - name: "a failed link", - linkResult: { ok: false as const, error: "Link request timed out" }, - note: "Link request timed out", - showCompletionNote: true, - }, - { - name: "a linked account that signal-cli did not identify", - linkResult: { ok: true as const }, - note: "signal-cli linked successfully, but OpenClaw could not identify the linked account. Enter its Signal number to finish setup.", - showCompletionNote: false, - }, - ])( - "accepts a manual number after $name", - async ({ linkResult, note: expectedNote, showCompletionNote }) => { - linkSignalCliAccountMock.mockResolvedValueOnce(linkResult); - const note = vi.fn(async () => undefined); - const text = vi.fn(async () => "+15555550199"); + it("accepts a manual number after a failed link", async () => { + linkSignalCliAccountMock.mockResolvedValueOnce({ + ok: false, + error: "Link request timed out", + }); + const note = vi.fn(async () => undefined); + const text = vi.fn(async () => "+15555550199"); - const result = await configure({ prompter: { ...createQrPrompter(), note, text } }); + const result = await configure({ prompter: { ...createQrPrompter(), note, text } }); - expect(result.cfg.channels?.signal?.account).toBe("+15555550199"); - expect(text).toHaveBeenCalledOnce(); - expect(note).toHaveBeenCalledWith(expectedNote, "Signal account linking"); - const completionCall = note.mock.calls.find(([, title]) => title === "Signal next steps"); - if (showCompletionNote) { - expect(completionCall?.[0]).toContain('signal-cli link -n "OpenClaw"'); - } else { - expect(completionCall).toBeUndefined(); - } - }, - ); + expect(result.cfg.channels?.signal?.account).toBe("+15555550199"); + expect(text).toHaveBeenCalledOnce(); + expect(note).toHaveBeenCalledWith("Link request timed out", "Signal account linking"); + const completionCall = note.mock.calls.find(([, title]) => title === "Signal next steps"); + expect(completionCall?.[0]).toContain('signal-cli link -n "OpenClaw"'); + }); it("preserves a successful linked account when cancellation races completion", async () => { const abortController = new AbortController(); @@ -488,7 +471,7 @@ describe("signalSetupWizard QR linking", () => { it("does not assign a QR-linked identity already owned by a sibling account", async () => { linkSignalCliAccountMock.mockResolvedValueOnce({ ok: true, - associatedAccount: "signal:+1 (555) 555-0123", + associatedAccount: "+15555550123", }); const transport = { kind: "managed-native" as const, diff --git a/extensions/signal/src/setup-surface.ts b/extensions/signal/src/setup-surface.ts index 6528e99dcdcb..67f170004b93 100644 --- a/extensions/signal/src/setup-surface.ts +++ b/extensions/signal/src/setup-surface.ts @@ -213,36 +213,29 @@ export const signalSetupWizard: ChannelSetupWizard = { // A successful signal-cli result means the account is already linked on disk. // Preserve that authoritative result even if cancellation raced its final output. preparedCredentialValues[SIGNAL_LINK_COMPLETED_INPUT_KEY] = "true"; - const linkedAccount = normalizeSignalAccountInput(linkResult.associatedAccount); - if (linkedAccount) { - if (siblingAccounts.has(linkedAccount)) { - // The device link succeeded, but this setup target must not claim a sibling's identity. - // Abort before later setup inputs can create a transport-only target. - const error = new Error( - `${linkedAccount} is already assigned to another OpenClaw Signal account. Choose a different account or remove the existing assignment, then retry setup.`, - ); - await prompter.note(error.message, "Signal account linking"); - throw error; - } - if (configuredAccount && linkedAccount !== configuredAccount) { - const replaceConfiguredAccount = await prompter.confirm({ - message: `Use ${linkedAccount} instead of configured Signal account ${configuredAccount}?`, - initialValue: false, - }); - if (!replaceConfiguredAccount) { - throw new WizardCancelledError( - `Signal setup cancelled: ${linkedAccount} was linked in signal-cli, but replacing configured Signal account ${configuredAccount} was declined.`, - ); - } - } - preparedCredentialValues.signalNumber = linkedAccount; - preparedCredentialValues[SIGNAL_LINKED_ACCOUNT_INPUT_KEY] = "true"; - } else { - await prompter.note( - "signal-cli linked successfully, but OpenClaw could not identify the linked account. Enter its Signal number to finish setup.", - "Signal account linking", + const linkedAccount = linkResult.associatedAccount; + if (siblingAccounts.has(linkedAccount)) { + // The device link succeeded, but this setup target must not claim a sibling's identity. + // Abort before later setup inputs can create a transport-only target. + const error = new Error( + `${linkedAccount} is already assigned to another OpenClaw Signal account. Choose a different account or remove the existing assignment, then retry setup.`, ); + await prompter.note(error.message, "Signal account linking"); + throw error; } + if (configuredAccount && linkedAccount !== configuredAccount) { + const replaceConfiguredAccount = await prompter.confirm({ + message: `Use ${linkedAccount} instead of configured Signal account ${configuredAccount}?`, + initialValue: false, + }); + if (!replaceConfiguredAccount) { + throw new WizardCancelledError( + `Signal setup cancelled: ${linkedAccount} was linked in signal-cli, but replacing configured Signal account ${configuredAccount} was declined.`, + ); + } + } + preparedCredentialValues.signalNumber = linkedAccount; + preparedCredentialValues[SIGNAL_LINKED_ACCOUNT_INPUT_KEY] = "true"; return { credentialValues: preparedCredentialValues }; }, credentials: [],