From 425a4ab2f2b8faec51152c000ca80d8d90f98b73 Mon Sep 17 00:00:00 2001 From: tanshanshan <22539261+tanshanshan@users.noreply.github.com> Date: Sun, 31 May 2026 17:46:10 +0800 Subject: [PATCH] chore(lint): enable object-shorthand (#81808) * fix: narrow current-main core type guards * fix: preserve query and test guard narrowing * fix(copilot): align client options with sdk rename * test(sms): type fetch mocks * fix(sms): preserve numeric allowlist entries * test(sms): preserve pairing send count assertion --------- Co-authored-by: Peter Steinberger --- extensions/copilot/src/attempt.ts | 1 - extensions/copilot/src/runtime.test.ts | 1 - extensions/copilot/src/runtime.ts | 6 ++---- extensions/sms/src/accounts.test.ts | 13 +++++++++++++ extensions/sms/src/accounts.ts | 11 +++++++---- extensions/sms/src/inbound.test.ts | 10 ++++++---- src/agents/model-provider-auth.worker.ts | 17 ++++++++--------- src/config/schema.hints.ts | 5 +++-- src/config/sessions.cache.test.ts | 2 +- 9 files changed, 40 insertions(+), 26 deletions(-) diff --git a/extensions/copilot/src/attempt.ts b/extensions/copilot/src/attempt.ts index d72b91f7676..d37dad63664 100644 --- a/extensions/copilot/src/attempt.ts +++ b/extensions/copilot/src/attempt.ts @@ -1097,7 +1097,6 @@ export function resolvePoolAcquire(params: AttemptParamsLike): { }, options: { copilotHome: resolved.copilotHome, - cwd: readString(params.cwd) ?? readString(params.workspaceDir), gitHubToken: resolved.authMode === "gitHubToken" ? resolved.gitHubToken : undefined, useLoggedInUser: resolved.authMode === "useLoggedInUser", }, diff --git a/extensions/copilot/src/runtime.test.ts b/extensions/copilot/src/runtime.test.ts index a7af3aa72cf..6378cd265eb 100644 --- a/extensions/copilot/src/runtime.test.ts +++ b/extensions/copilot/src/runtime.test.ts @@ -66,7 +66,6 @@ function makeOptions(overrides: Partial = {}): ClientCreate copilotHome: overrides.copilotHome ?? "copilot-home", useLoggedInUser: overrides.useLoggedInUser ?? true, gitHubToken: overrides.gitHubToken, - cwd: overrides.cwd, }; } diff --git a/extensions/copilot/src/runtime.ts b/extensions/copilot/src/runtime.ts index 196324b5c59..9b45bdbd2c0 100644 --- a/extensions/copilot/src/runtime.ts +++ b/extensions/copilot/src/runtime.ts @@ -20,10 +20,9 @@ export interface PoolKey { export interface ClientCreateOptions extends Omit< CopilotClientOptions, - "baseDirectory" | "gitHubToken" | "useLoggedInUser" | "workingDirectory" + "baseDirectory" | "workingDirectory" | "useLoggedInUser" | "gitHubToken" > { readonly copilotHome: string; - readonly cwd?: string; readonly useLoggedInUser?: boolean; readonly gitHubToken?: string; } @@ -362,11 +361,10 @@ function normalizeClientCreateOptions( options: ClientCreateOptions, normalizedCopilotHome: string, ): CopilotClientOptions { - const { copilotHome: _copilotHome, cwd, ...clientOptions } = options; + const { copilotHome: _copilotHome, ...clientOptions } = options; return { ...clientOptions, baseDirectory: normalizedCopilotHome, - workingDirectory: cwd, }; } diff --git a/extensions/sms/src/accounts.test.ts b/extensions/sms/src/accounts.test.ts index 38c2c539865..bdb8f3169b6 100644 --- a/extensions/sms/src/accounts.test.ts +++ b/extensions/sms/src/accounts.test.ts @@ -169,6 +169,19 @@ describe("SMS account config", () => { }); }); + it("coerces numeric allowFrom entries accepted by the config schema", () => { + const parsed = SmsConfigSchema.parse({ + accountSid: "AC123", + authToken: "token", + fromNumber: "+15550001111", + allowFrom: [15551234567], + }); + + expect(resolveSmsAccount({ channels: { sms: parsed } })).toMatchObject({ + allowFrom: ["+15551234567"], + }); + }); + it("discovers env-only SMS credentials as the implicit default account", () => { process.env.TWILIO_ACCOUNT_SID = "AC-env"; process.env.TWILIO_AUTH_TOKEN = "env-token"; diff --git a/extensions/sms/src/accounts.ts b/extensions/sms/src/accounts.ts index 8bd84a23ce3..245552457f4 100644 --- a/extensions/sms/src/accounts.ts +++ b/extensions/sms/src/accounts.ts @@ -24,13 +24,16 @@ function getChannelConfig(cfg: OpenClawConfig): SmsChannelConfig | undefined { return cfg?.channels?.[CHANNEL_ID] as SmsChannelConfig | undefined; } -function parseList(raw: string | string[] | undefined): string[] { +function parseList(raw: unknown): string[] { if (!raw) { return []; } - return (Array.isArray(raw) ? raw : normalizeStringEntries(raw.split(","))) - .map((entry) => normalizeSmsAllowFrom(entry)) - .filter(Boolean); + const entries = Array.isArray(raw) + ? raw + : typeof raw === "string" + ? normalizeStringEntries(raw.split(",")) + : [raw]; + return entries.map((entry) => normalizeSmsAllowFrom(String(entry))).filter(Boolean); } function parseTextChunkLimit(raw: unknown): number { diff --git a/extensions/sms/src/inbound.test.ts b/extensions/sms/src/inbound.test.ts index bfa2d4710af..207e0823a24 100644 --- a/extensions/sms/src/inbound.test.ts +++ b/extensions/sms/src/inbound.test.ts @@ -109,10 +109,12 @@ describe("dispatchSmsInboundEvent", () => { meta: undefined, }); expect(sendSmsViaTwilio).toHaveBeenCalledOnce(); - expect(sendSmsViaTwilio.mock.calls[0]?.[0]).toMatchObject({ - to: "+15551234567", - }); - expect(sendSmsViaTwilio.mock.calls[0]?.[0].text).toContain("PAIR123"); + expect(sendSmsViaTwilio).toHaveBeenCalledWith( + expect.objectContaining({ + to: "+15551234567", + text: expect.stringContaining("PAIR123"), + }), + ); }); it("uses the canonical routed session key for authorized SMS turns", async () => { diff --git a/src/agents/model-provider-auth.worker.ts b/src/agents/model-provider-auth.worker.ts index 6b4b5015b53..4a72d255057 100644 --- a/src/agents/model-provider-auth.worker.ts +++ b/src/agents/model-provider-auth.worker.ts @@ -30,16 +30,15 @@ type ProviderAuthWarmWorkerResult = }; function isWorkerInput(value: unknown): value is ProviderAuthWarmWorkerInput { + if (!value || typeof value !== "object") { + return false; + } + const record = value as Record; return ( - value !== null && - typeof value === "object" && - "cfg" in value && - (!("runtimeAuthStores" in value) || - Array.isArray((value as { runtimeAuthStores?: unknown }).runtimeAuthStores)) && - (!("runtimeAuthLookups" in value) || - Array.isArray((value as { runtimeAuthLookups?: unknown }).runtimeAuthLookups)) && - (!("omitFalseProviderAuth" in value) || - typeof (value as { omitFalseProviderAuth?: unknown }).omitFalseProviderAuth === "boolean") + "cfg" in record && + (!("runtimeAuthStores" in record) || Array.isArray(record.runtimeAuthStores)) && + (!("runtimeAuthLookups" in record) || Array.isArray(record.runtimeAuthLookups)) && + (!("omitFalseProviderAuth" in record) || typeof record.omitFalseProviderAuth === "boolean") ); } diff --git a/src/config/schema.hints.ts b/src/config/schema.hints.ts index ad0e0169a85..23ba0c24bf2 100644 --- a/src/config/schema.hints.ts +++ b/src/config/schema.hints.ts @@ -245,9 +245,10 @@ interface ZodDummy { unwrap: () => z.ZodType; } function isUnwrappable(object: unknown): object is ZodDummy { + if (!object || typeof object !== "object") { + return false; + } return ( - object !== null && - typeof object === "object" && "unwrap" in object && typeof (object as Record).unwrap === "function" && !(object instanceof z.ZodArray) diff --git a/src/config/sessions.cache.test.ts b/src/config/sessions.cache.test.ts index 7ad0f63c8cb..a9bb3756800 100644 --- a/src/config/sessions.cache.test.ts +++ b/src/config/sessions.cache.test.ts @@ -315,7 +315,7 @@ describe("Session Store Cache", () => { throw new Error("Expected cached entry"); } expect(entry?.polluted).toBeUndefined(); - expect(Object.hasOwn(entry as SessionEntry, "__proto__")).toBe(true); + expect(Object.hasOwn(entry as object, "__proto__")).toBe(true); expect(Object.prototype).not.toHaveProperty("polluted"); });