diff --git a/.oxlintrc.json b/.oxlintrc.json index c0d6cc8eaa3..4754b9ff177 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -20,7 +20,6 @@ "typescript/consistent-return": "off", "typescript/no-explicit-any": "error", "typescript/no-extraneous-class": "off", - "typescript/no-unnecessary-type-arguments": "off", "typescript/no-unnecessary-type-conversion": "off", "typescript/no-unsafe-type-assertion": "off", "unicorn/consistent-function-scoping": "off", diff --git a/extensions/browser/src/browser-tool.ts b/extensions/browser/src/browser-tool.ts index 0768763ea34..0cc9ba04f02 100644 --- a/extensions/browser/src/browser-tool.ts +++ b/extensions/browser/src/browser-tool.ts @@ -286,7 +286,7 @@ async function callBrowserProxy(params: { ? Math.max(1, Math.floor(params.timeoutMs)) : DEFAULT_BROWSER_PROXY_TIMEOUT_MS; const gatewayTimeoutMs = proxyTimeoutMs + BROWSER_PROXY_GATEWAY_TIMEOUT_SLACK_MS; - const payload = await browserToolDeps.callGatewayTool<{ payloadJSON?: string; payload?: string }>( + const payload = await browserToolDeps.callGatewayTool( "node.invoke", { timeoutMs: gatewayTimeoutMs }, { diff --git a/extensions/irc/src/channel.ts b/extensions/irc/src/channel.ts index ede728ab31e..eef0cca8df1 100644 --- a/extensions/irc/src/channel.ts +++ b/extensions/irc/src/channel.ts @@ -101,11 +101,7 @@ const listIrcDirectoryGroupsFromConfig = createResolvedDirectoryEntriesLister({ +const ircConfigAdapter = createScopedChannelConfigAdapter({ sectionKey: "irc", listAccountIds: listIrcAccountIds, resolveAccount: adaptScopedAccountAccessor(resolveIrcAccount), diff --git a/extensions/matrix/src/config-adapter.ts b/extensions/matrix/src/config-adapter.ts index 3d28e77fabc..6d2433682cb 100644 --- a/extensions/matrix/src/config-adapter.ts +++ b/extensions/matrix/src/config-adapter.ts @@ -11,14 +11,12 @@ import { type ResolvedMatrixAccount, } from "./matrix/accounts.js"; import { normalizeMatrixAllowList } from "./matrix/monitor/allowlist.js"; -import type { CoreConfig } from "./types.js"; export { DEFAULT_ACCOUNT_ID }; export const matrixConfigAdapter = createScopedChannelConfigAdapter< ResolvedMatrixAccount, - ReturnType, - CoreConfig + ReturnType >({ sectionKey: "matrix", listAccountIds: listMatrixAccountIds, diff --git a/scripts/anthropic-prompt-probe.ts b/scripts/anthropic-prompt-probe.ts index 3e943bc5d0f..4e3f383caec 100644 --- a/scripts/anthropic-prompt-probe.ts +++ b/scripts/anthropic-prompt-probe.ts @@ -580,7 +580,7 @@ async function runGatewayPrompt(prompt: string): Promise { try { const url = `ws://127.0.0.1:${port}`; await waitForGatewayReady(url, gatewayToken); - const agentRes = await callGateway<{ runId?: string }>({ + const agentRes = await callGateway({ url, token: gatewayToken, method: "agent", @@ -607,7 +607,7 @@ async function runGatewayPrompt(prompt: string): Promise { tmpDir, }; } - const waitRes = await callGateway<{ status?: string; error?: string; payloads?: unknown[] }>({ + const waitRes = await callGateway({ url, token: gatewayToken, method: "agent.wait", diff --git a/scripts/lib/plugin-clawhub-release.ts b/scripts/lib/plugin-clawhub-release.ts index 7a6a62109ba..e9a122a25f7 100644 --- a/scripts/lib/plugin-clawhub-release.ts +++ b/scripts/lib/plugin-clawhub-release.ts @@ -105,7 +105,7 @@ export function collectClawHubPublishablePluginPackages( const publishable: PublishablePluginPackage[] = []; const validationErrors: string[] = []; - for (const candidate of collectExtensionPackageJsonCandidates(rootDir)) { + for (const candidate of collectExtensionPackageJsonCandidates(rootDir)) { const { extensionId, packageDir, packageJson } = candidate; if (packageJson.openclaw?.release?.publishToClawHub !== true) { continue; diff --git a/src/acp/translator.ts b/src/acp/translator.ts index cc7762ff3b1..146c00798ec 100644 --- a/src/acp/translator.ts +++ b/src/acp/translator.ts @@ -1144,7 +1144,7 @@ export class AcpGatewayAgent implements Agent { } let result: AgentWaitResult | undefined; try { - result = await this.gateway.request( + result = await this.gateway.request( "agent.wait", { runId: pending.idempotencyKey, @@ -1308,7 +1308,7 @@ export class AcpGatewayAgent implements Agent { } private async getSessionTranscript(sessionKey: string): Promise { - const result = await this.gateway.request<{ messages?: unknown[] }>("sessions.get", { + const result = await this.gateway.request("sessions.get", { key: sessionKey, limit: ACP_LOAD_SESSION_REPLAY_LIMIT, }); diff --git a/src/agents/acp-spawn.ts b/src/agents/acp-spawn.ts index aa6256cfa76..a4c411755bd 100644 --- a/src/agents/acp-spawn.ts +++ b/src/agents/acp-spawn.ts @@ -1181,7 +1181,7 @@ export async function spawnAcpDirect( }); } try { - const response = await callGateway<{ runId?: string }>({ + const response = await callGateway({ method: "agent", params: { message: params.task, diff --git a/src/agents/bash-tools.exec-approval-request.ts b/src/agents/bash-tools.exec-approval-request.ts index 0e70e5a80b2..751dbd5425b 100644 --- a/src/agents/bash-tools.exec-approval-request.ts +++ b/src/agents/bash-tools.exec-approval-request.ts @@ -91,11 +91,7 @@ export async function registerExecApprovalRequest( ): Promise { // Two-phase registration is critical: the ID must be registered server-side // before exec returns `approval-pending`, otherwise `/approve` can race and orphan. - const registrationResult = await callGatewayTool<{ - id?: string; - expiresAtMs?: number; - decision?: string; - }>( + const registrationResult = await callGatewayTool( "exec.approval.request", { timeoutMs: DEFAULT_APPROVAL_REQUEST_TIMEOUT_MS }, buildExecApprovalRequestToolParams(params), diff --git a/src/agents/bash-tools.exec-host-node.ts b/src/agents/bash-tools.exec-host-node.ts index c2ba0399bf2..73e8922a8aa 100644 --- a/src/agents/bash-tools.exec-host-node.ts +++ b/src/agents/bash-tools.exec-host-node.ts @@ -97,7 +97,7 @@ export async function executeNodeHostCommand( ); } const argv = buildNodeShellCommand(params.command, nodeInfo?.platform); - const prepareRaw = await callGatewayTool<{ payload?: unknown }>( + const prepareRaw = await callGatewayTool( "node.invoke", { timeoutMs: 15_000 }, { @@ -370,15 +370,7 @@ export async function executeNodeHostCommand( } try { - const raw = await callGatewayTool<{ - payload?: { - stdout?: string; - stderr?: string; - error?: string | null; - exitCode?: number | null; - timedOut?: boolean; - }; - }>( + const raw = await callGatewayTool( "node.invoke", { timeoutMs: invokeTimeoutMs }, buildInvokeParams(approvedByAsk, approvalDecision, approvalId, true), diff --git a/src/agents/pi-tools.before-tool-call.ts b/src/agents/pi-tools.before-tool-call.ts index 641fca01709..6f27346c460 100644 --- a/src/agents/pi-tools.before-tool-call.ts +++ b/src/agents/pi-tools.before-tool-call.ts @@ -233,11 +233,11 @@ export async function runBeforeToolCallHook(args: { } }; try { - const requestResult = await callGatewayTool<{ + const requestResult: { id?: string; status?: string; decision?: string | null; - }>( + } = await callGatewayTool( "plugin.approval.request", // Buffer beyond the approval timeout so the gateway can clean up // and respond before the client-side RPC timeout fires. @@ -281,10 +281,10 @@ export async function runBeforeToolCallHook(args: { } else { // Wait for the decision, but abort early if the agent run is cancelled // so the user isn't blocked for the full approval timeout. - const waitPromise = callGatewayTool<{ + const waitPromise: Promise<{ id?: string; decision?: string | null; - }>( + }> = callGatewayTool( "plugin.approval.waitDecision", // Buffer beyond the approval timeout so the gateway can clean up // and respond before the client-side RPC timeout fires. diff --git a/src/agents/run-wait.ts b/src/agents/run-wait.ts index 72b6e8d05bc..b7f49b75eac 100644 --- a/src/agents/run-wait.ts +++ b/src/agents/run-wait.ts @@ -122,7 +122,7 @@ export async function waitForAgentRun(params: { }): Promise { const timeoutMs = Math.max(1, Math.floor(params.timeoutMs)); try { - const wait = await (params.callGateway ?? runWaitDeps.callGateway)({ + const wait = await (params.callGateway ?? runWaitDeps.callGateway)({ method: "agent.wait", params: { runId: params.runId, diff --git a/src/agents/subagent-announce-output.ts b/src/agents/subagent-announce-output.ts index e9f5a38ea08..b40b105cfb2 100644 --- a/src/agents/subagent-announce-output.ts +++ b/src/agents/subagent-announce-output.ts @@ -241,7 +241,7 @@ export async function readSubagentOutput( sessionKey: string, outcome?: SubagentRunOutcome, ): Promise { - const history = await subagentAnnounceOutputDeps.callGateway<{ messages?: Array }>({ + const history = await subagentAnnounceOutputDeps.callGateway({ method: "chat.history", params: { sessionKey, limit: 100 }, }); @@ -276,7 +276,7 @@ export async function waitForSubagentRunOutcome( timeoutMs: number, ): Promise { const waitMs = Math.max(0, Math.floor(timeoutMs)); - return await subagentAnnounceOutputDeps.callGateway({ + return await subagentAnnounceOutputDeps.callGateway({ method: "agent.wait", params: { runId, diff --git a/src/agents/tools/agent-step.ts b/src/agents/tools/agent-step.ts index c570d2a4d78..fcd20a3ca96 100644 --- a/src/agents/tools/agent-step.ts +++ b/src/agents/tools/agent-step.ts @@ -28,7 +28,7 @@ export async function runAgentStep(params: { sourceTool?: string; }): Promise { const stepIdem = crypto.randomUUID(); - const response = await agentStepDeps.callGateway<{ runId?: string }>({ + const response = await agentStepDeps.callGateway({ method: "agent", params: { message: params.message, diff --git a/src/agents/tools/nodes-tool.ts b/src/agents/tools/nodes-tool.ts index ea3331de55e..d9fdf856180 100644 --- a/src/agents/tools/nodes-tool.ts +++ b/src/agents/tools/nodes-tool.ts @@ -53,13 +53,13 @@ async function resolveNodePairApproveScopes( gatewayOpts: GatewayCallOptions, requestId: string, ): Promise { - const pairing = await callGatewayTool<{ + const pairing: { pending?: Array<{ requestId?: string; commands?: unknown; requiredApproveScopes?: unknown; }>; - }>("node.pair.list", gatewayOpts, {}, { scopes: ["operator.pairing"] }); + } = await callGatewayTool("node.pair.list", gatewayOpts, {}, { scopes: ["operator.pairing"] }); const pending = Array.isArray(pairing?.pending) ? pairing.pending : []; const match = pending.find((entry) => entry?.requestId === requestId); if (Array.isArray(match?.requiredApproveScopes)) { diff --git a/src/agents/tools/sessions-resolution.ts b/src/agents/tools/sessions-resolution.ts index dd6b26f10d3..8a8f19cd3cf 100644 --- a/src/agents/tools/sessions-resolution.ts +++ b/src/agents/tools/sessions-resolution.ts @@ -82,7 +82,7 @@ export async function isRequesterSpawnedSessionVisible(params: { return true; } try { - const resolved = await sessionsResolutionDeps.callGateway<{ key?: string }>({ + const resolved = await sessionsResolutionDeps.callGateway({ method: "sessions.resolve", params: { key: params.targetSessionKey, @@ -231,7 +231,7 @@ async function callGatewayResolveSessionId(params: { requesterInternalKey?: string; restrictToSpawned: boolean; }): Promise { - const result = await sessionsResolutionDeps.callGateway<{ key?: string }>({ + const result = await sessionsResolutionDeps.callGateway({ method: "sessions.resolve", params: buildSessionIdResolveParams(params), }); @@ -288,7 +288,7 @@ async function resolveSessionKeyFromKey(params: { }): Promise { try { // Try key-based resolution first so non-standard keys keep working. - const result = await sessionsResolutionDeps.callGateway<{ key?: string }>({ + const result = await sessionsResolutionDeps.callGateway({ method: "sessions.resolve", params: { key: params.key, diff --git a/src/auto-reply/reply/commands-acp/targets.ts b/src/auto-reply/reply/commands-acp/targets.ts index 1b85d493b78..310dd6704fb 100644 --- a/src/auto-reply/reply/commands-acp/targets.ts +++ b/src/auto-reply/reply/commands-acp/targets.ts @@ -19,7 +19,7 @@ async function resolveSessionKeyByToken(token: string): Promise { for (const params of attempts) { try { - const resolved = await callGateway<{ key?: string }>({ + const resolved = await callGateway({ method: "sessions.resolve", params, timeoutMs: 8_000, diff --git a/src/auto-reply/reply/commands-subagents/shared.ts b/src/auto-reply/reply/commands-subagents/shared.ts index 68f63c8f996..0fc0c0ced5f 100644 --- a/src/auto-reply/reply/commands-subagents/shared.ts +++ b/src/auto-reply/reply/commands-subagents/shared.ts @@ -334,7 +334,7 @@ export async function resolveFocusTargetSession(params: { for (const attempt of attempts) { try { - const resolved = await callGateway<{ key?: string }>({ + const resolved = await callGateway({ method: "sessions.resolve", params: attempt, }); diff --git a/src/channels/plugins/config-writes.ts b/src/channels/plugins/config-writes.ts index 286e94c5324..43e0fa9e0b0 100644 --- a/src/channels/plugins/config-writes.ts +++ b/src/channels/plugins/config-writes.ts @@ -12,9 +12,9 @@ import { type ConfigWriteTargetLike, } from "./config-write-policy-shared.js"; import type { ChannelId } from "./types.core.js"; -export type ConfigWriteScope = ConfigWriteScopeLike; -export type ConfigWriteTarget = ConfigWriteTargetLike; -export type ConfigWriteAuthorizationResult = ConfigWriteAuthorizationResultLike; +export type ConfigWriteScope = ConfigWriteScopeLike; +export type ConfigWriteTarget = ConfigWriteTargetLike; +export type ConfigWriteAuthorizationResult = ConfigWriteAuthorizationResultLike; function isInternalConfigWriteMessageChannel(channel?: string | null): boolean { return normalizeLowercaseStringOrEmpty(channel) === "webchat"; diff --git a/src/cli/capability-cli.ts b/src/cli/capability-cli.ts index b8fe6a062ed..872500e34a9 100644 --- a/src/cli/capability-cli.ts +++ b/src/cli/capability-cli.ts @@ -549,12 +549,12 @@ async function runModelRun(params: { } const { provider, model } = resolveModelRefOverride(params.model); - const response = await callGateway<{ + const response: { result?: { payloads?: Array<{ text?: string; mediaUrl?: string | null; mediaUrls?: string[] }>; meta?: { agentMeta?: { provider?: string; model?: string } }; }; - }>({ + } = await callGateway({ method: "agent", params: { agentId, @@ -871,12 +871,12 @@ async function runTtsConvert(params: { }) { if (params.transport === "gateway") { const gatewayConnection = buildGatewayConnectionDetailsWithResolvers({ config: loadConfig() }); - const result = await callGateway<{ + const result: { audioPath?: string; provider?: string; outputFormat?: string; voiceCompatible?: boolean; - }>({ + } = await callGateway({ method: "tts.convert", params: { text: params.text, @@ -964,10 +964,10 @@ async function runTtsConvert(params: { async function runTtsProviders(transport: CapabilityTransport) { const cfg = loadConfig(); if (transport === "gateway") { - const payload = await callGateway<{ + const payload: { providers?: Array>; active?: string; - }>({ + } = await callGateway({ method: "tts.providers", timeoutMs: 30_000, }); diff --git a/src/cli/command-secret-gateway.ts b/src/cli/command-secret-gateway.ts index 5228ce0baec..3be730f690c 100644 --- a/src/cli/command-secret-gateway.ts +++ b/src/cli/command-secret-gateway.ts @@ -687,7 +687,7 @@ export async function resolveCommandSecretRefsViaGateway(params: { let payload: GatewaySecretsResolveResult; try { - payload = await callGateway({ + payload = await callGateway({ config: params.config, method: "secrets.resolve", requiredMethods: ["secrets.resolve"], diff --git a/src/commands/agent-via-gateway.ts b/src/commands/agent-via-gateway.ts index c61c3b20439..759d7f702e6 100644 --- a/src/commands/agent-via-gateway.ts +++ b/src/commands/agent-via-gateway.ts @@ -122,14 +122,14 @@ export async function agentViaGatewayCommand(opts: AgentCliOpts, runtime: Runtim const channel = normalizeMessageChannel(opts.channel); const idempotencyKey = normalizeOptionalString(opts.runId) || randomIdempotencyKey(); - const response = await withProgress( + const response: GatewayAgentResponse = await withProgress( { label: "Waiting for agent reply…", indeterminate: true, enabled: opts.json !== true, }, async () => - await callGateway({ + await callGateway({ method: "agent", params: { message: body, diff --git a/src/commands/onboard-non-interactive.gateway.test.ts b/src/commands/onboard-non-interactive.gateway.test.ts index a2abd6ab258..29364439f3d 100644 --- a/src/commands/onboard-non-interactive.gateway.test.ts +++ b/src/commands/onboard-non-interactive.gateway.test.ts @@ -453,7 +453,7 @@ describe("onboard (non-interactive): gateway and remote auth", () => { expect(cfg.gateway?.remote?.token).toBe(token); gatewayClientCalls.length = 0; - const health = await callGateway<{ ok?: boolean }>({ method: "health" }); + const health = await callGateway({ method: "health" }); expect(health?.ok).toBe(true); const lastCall = gatewayClientCalls[gatewayClientCalls.length - 1]; expect(lastCall?.url).toBe(`ws://127.0.0.1:${port}`); diff --git a/src/flows/channel-setup.status.ts b/src/flows/channel-setup.status.ts index 0ee5abc5630..ddaa8b94f2c 100644 --- a/src/flows/channel-setup.status.ts +++ b/src/flows/channel-setup.status.ts @@ -31,7 +31,7 @@ export type ChannelStatusSummary = { statusLines: string[]; }; -export type ChannelSetupSelectionContribution = FlowContribution & { +export type ChannelSetupSelectionContribution = FlowContribution & { kind: "channel"; surface: "setup"; channel: ChannelChoice; diff --git a/src/gateway/gateway-acp-bind.live.test.ts b/src/gateway/gateway-acp-bind.live.test.ts index 4fb818ec809..b3ae7bef082 100644 --- a/src/gateway/gateway-acp-bind.live.test.ts +++ b/src/gateway/gateway-acp-bind.live.test.ts @@ -287,7 +287,7 @@ async function bindConversationAndWait(params: { originatingAccountId: params.originatingAccountId, }); - const mainHistory = await params.client.request<{ messages?: unknown[] }>("chat.history", { + const mainHistory: { messages?: unknown[] } = await params.client.request("chat.history", { sessionKey: params.sessionKey, limit: 16, }); @@ -316,7 +316,7 @@ async function waitForAgentRunOk( runId: string, timeoutMs = LIVE_TIMEOUT_MS, ) { - const result = await client.request<{ status?: string }>( + const result: { status?: string } = await client.request( "agent.wait", { runId, @@ -345,7 +345,7 @@ async function sendChatAndWait(params: { content: string; }>; }) { - const started = await params.client.request<{ runId?: string; status?: string }>("chat.send", { + const started: { runId?: string; status?: string } = await params.client.request("chat.send", { sessionKey: params.sessionKey, message: params.message, idempotencyKey: params.idempotencyKey, @@ -371,7 +371,7 @@ async function waitForAssistantText(params: { const startedAt = Date.now(); while (Date.now() - startedAt < timeoutMs) { - const history = await params.client.request<{ messages?: unknown[] }>("chat.history", { + const history: { messages?: unknown[] } = await params.client.request("chat.history", { sessionKey: params.sessionKey, limit: 16, }); @@ -387,7 +387,7 @@ async function waitForAssistantText(params: { await sleep(500); } - const finalHistory = await params.client.request<{ messages?: unknown[] }>("chat.history", { + const finalHistory: { messages?: unknown[] } = await params.client.request("chat.history", { sessionKey: params.sessionKey, limit: 16, }); @@ -408,7 +408,7 @@ async function waitForAssistantTurn(params: { const startedAt = Date.now(); while (Date.now() - startedAt < timeoutMs) { - const history = await params.client.request<{ messages?: unknown[] }>("chat.history", { + const history: { messages?: unknown[] } = await params.client.request("chat.history", { sessionKey: params.sessionKey, limit: 16, }); @@ -421,7 +421,7 @@ async function waitForAssistantTurn(params: { await sleep(500); } - const finalHistory = await params.client.request<{ messages?: unknown[] }>("chat.history", { + const finalHistory: { messages?: unknown[] } = await params.client.request("chat.history", { sessionKey: params.sessionKey, limit: 16, }); diff --git a/src/gateway/gateway-cli-backend.connect.test.ts b/src/gateway/gateway-cli-backend.connect.test.ts index 2e3b49a4d8d..01b7a9858eb 100644 --- a/src/gateway/gateway-cli-backend.connect.test.ts +++ b/src/gateway/gateway-cli-backend.connect.test.ts @@ -80,7 +80,7 @@ describe("gateway cli backend connect", () => { token, deviceIdentity, }); - const health = await client.request<{ ok?: boolean }>("health", undefined, { + const health = await client.request("health", undefined, { timeoutMs: 5_000, }); expect(health).toMatchObject({ diff --git a/src/gateway/gateway-models.profiles.live.test.ts b/src/gateway/gateway-models.profiles.live.test.ts index dd7bee0d2f8..aa8bd5dcdfd 100644 --- a/src/gateway/gateway-models.profiles.live.test.ts +++ b/src/gateway/gateway-models.profiles.live.test.ts @@ -1153,7 +1153,7 @@ async function requestGatewayAgentText(params: { params.modelKey, ).length; const accepted = await withGatewayLiveProbeTimeout( - params.client.request<{ runId?: unknown; status?: unknown }>("agent", { + params.client.request("agent", { sessionKey: params.sessionKey, idempotencyKey: params.idempotencyKey, message: params.message, diff --git a/src/gateway/gateway.test.ts b/src/gateway/gateway.test.ts index c0d2e6b1d9f..3c61689c2d6 100644 --- a/src/gateway/gateway.test.ts +++ b/src/gateway/gateway.test.ts @@ -175,10 +175,7 @@ describe("gateway e2e", () => { const sessionKey = "agent:dev:mock-openai"; const runId = nextGatewayId("run"); - const payload = await client.request<{ - status?: unknown; - runId?: unknown; - }>( + const payload = await client.request( "agent", { sessionKey, diff --git a/src/gateway/server.auth.control-ui.suite.ts b/src/gateway/server.auth.control-ui.suite.ts index 07e2619cc47..9cd242fd2a2 100644 --- a/src/gateway/server.auth.control-ui.suite.ts +++ b/src/gateway/server.auth.control-ui.suite.ts @@ -346,11 +346,10 @@ export function registerControlUiAndPairingSuite(): void { "x-forwarded-for": "203.0.113.10", }, }); - const challengePromise = onceMessage<{ - type?: string; - event?: string; - payload?: Record | null; - }>(ws, (o) => o.type === "event" && o.event === "connect.challenge"); + const challengePromise = onceMessage( + ws, + (o) => o.type === "event" && o.event === "connect.challenge", + ); await new Promise((resolve) => ws.once("open", resolve)); const challenge = await challengePromise; const nonce = (challenge.payload as { nonce?: unknown } | undefined)?.nonce; @@ -1074,11 +1073,10 @@ export function registerControlUiAndPairingSuite(): void { const socket = new WebSocket(`ws://127.0.0.1:${port}`, { headers: { host: "gateway.example" }, }); - const challengePromise = onceMessage<{ - type?: string; - event?: string; - payload?: Record | null; - }>(socket, (o) => o.type === "event" && o.event === "connect.challenge"); + const challengePromise = onceMessage( + socket, + (o) => o.type === "event" && o.event === "connect.challenge", + ); await new Promise((resolve) => socket.once("open", resolve)); const challenge = await challengePromise; const nonce = (challenge.payload as { nonce?: unknown } | undefined)?.nonce; diff --git a/src/gateway/server.auth.default-token.suite.ts b/src/gateway/server.auth.default-token.suite.ts index 34337a70111..b856c0f2a67 100644 --- a/src/gateway/server.auth.default-token.suite.ts +++ b/src/gateway/server.auth.default-token.suite.ts @@ -321,11 +321,11 @@ export function registerDefaultAuthTokenSuite(): void { test("sends connect challenge on open", async () => { const ws = new WebSocket(`ws://127.0.0.1:${port}`); - const evtPromise = onceMessage<{ + const evtPromise: Promise<{ type?: string; event?: string; payload?: Record | null; - }>(ws, (o) => o.type === "event" && o.event === "connect.challenge"); + }> = onceMessage(ws, (o) => o.type === "event" && o.event === "connect.challenge"); await new Promise((resolve) => ws.once("open", resolve)); const evt = await evtPromise; const nonce = (evt.payload as { nonce?: unknown } | undefined)?.nonce; @@ -350,7 +350,7 @@ export function registerDefaultAuthTokenSuite(): void { test("rejects non-connect first request", async () => { const ws = await openWs(port); ws.send(JSON.stringify({ type: "req", id: "h1", method: "health" })); - const res = await onceMessage<{ type?: string; id?: string; ok?: boolean; error?: unknown }>( + const res: { type?: string; id?: string; ok?: boolean; error?: unknown } = await onceMessage( ws, (o) => o.type === "res" && o.id === "h1", ); diff --git a/src/gateway/server.auth.shared.ts b/src/gateway/server.auth.shared.ts index 0184a90cfd6..08425f8ef49 100644 --- a/src/gateway/server.auth.shared.ts +++ b/src/gateway/server.auth.shared.ts @@ -63,11 +63,11 @@ const readConnectChallengeNonce = async (ws: WebSocket) => { if (cached) { return cached; } - const challenge = await onceMessage<{ + const challenge: { type?: string; event?: string; payload?: Record | null; - }>(ws, (o) => o.type === "event" && o.event === "connect.challenge"); + } = await onceMessage(ws, (o) => o.type === "event" && o.event === "connect.challenge"); const nonce = (challenge.payload as { nonce?: unknown } | undefined)?.nonce; expect(typeof nonce).toBe("string"); return String(nonce); @@ -290,7 +290,7 @@ async function sendRawConnectReq( }, }), ); - return onceMessage<{ + const response: { type?: string; id?: string; ok?: boolean; @@ -302,7 +302,8 @@ async function sendRawConnectReq( reason?: string; }; }; - }>(ws, isConnectResMessage(params.id)); + } = await onceMessage(ws, isConnectResMessage(params.id)); + return response; } async function resolvePairedTokenForDeviceIdentityPath(deviceIdentityPath: string): Promise<{ diff --git a/src/gateway/server.health.test.ts b/src/gateway/server.health.test.ts index 883694b6a88..9e133b34e9b 100644 --- a/src/gateway/server.health.test.ts +++ b/src/gateway/server.health.test.ts @@ -15,16 +15,6 @@ const CLI_PRESENCE_TIMEOUT_MS = 3_000; let harness: GatewayServerHarness; -type GatewayFrame = { - type?: string; - id?: string; - ok?: boolean; - event?: string; - payload?: Record | null; - seq?: number; - stateVersion?: { presence?: number; [key: string]: unknown }; -}; - beforeAll(async () => { harness = await startGatewayServerHarness(); }); @@ -40,12 +30,9 @@ describe("gateway server health/presence", () => { async () => { const { ws } = await harness.openClient(); - const healthP = onceMessage(ws, (o) => o.type === "res" && o.id === "health1"); - const statusP = onceMessage(ws, (o) => o.type === "res" && o.id === "status1"); - const presenceP = onceMessage( - ws, - (o) => o.type === "res" && o.id === "presence1", - ); + const healthP = onceMessage(ws, (o) => o.type === "res" && o.id === "health1"); + const statusP = onceMessage(ws, (o) => o.type === "res" && o.id === "status1"); + const presenceP = onceMessage(ws, (o) => o.type === "res" && o.id === "presence1"); const sendReq = (id: string, method: string) => ws.send(JSON.stringify({ type: "req", id, method })); @@ -99,7 +86,7 @@ describe("gateway server health/presence", () => { method: "last-heartbeat", }), ); - const last = await onceMessage(ws, (o) => o.type === "res" && o.id === "hb-last"); + const last = await onceMessage(ws, (o) => o.type === "res" && o.id === "hb-last"); expect(last.ok).toBe(true); const lastPayload = last.payload as HeartbeatPayload | null | undefined; expect(lastPayload?.status).toBe("sent"); @@ -113,10 +100,7 @@ describe("gateway server health/presence", () => { params: { enabled: false }, }), ); - const toggle = await onceMessage( - ws, - (o) => o.type === "res" && o.id === "hb-toggle-off", - ); + const toggle = await onceMessage(ws, (o) => o.type === "res" && o.id === "hb-toggle-off"); expect(toggle.ok).toBe(true); expect((toggle.payload as { enabled?: boolean } | undefined)?.enabled).toBe(false); @@ -129,10 +113,7 @@ describe("gateway server health/presence", () => { async () => { const { ws } = await harness.openClient(); - const presenceEventP = onceMessage( - ws, - (o) => o.type === "event" && o.event === "presence", - ); + const presenceEventP = onceMessage(ws, (o) => o.type === "event" && o.event === "presence"); ws.send( JSON.stringify({ type: "req", @@ -156,7 +137,7 @@ describe("gateway server health/presence", () => { const { ws } = await harness.openClient(); const runId = randomUUID(); - const evtPromise = onceMessage( + const evtPromise = onceMessage( ws, (o) => o.type === "event" && @@ -178,7 +159,7 @@ describe("gateway server health/presence", () => { test("shutdown event is broadcast on close", { timeout: PRESENCE_EVENT_TIMEOUT_MS }, async () => { const localHarness = await startGatewayServerHarness(); const { ws } = await localHarness.openClient(); - const shutdownP = onceMessage( + const shutdownP = onceMessage( ws, (o) => o.type === "event" && o.event === "shutdown", SHUTDOWN_EVENT_TIMEOUT_MS, @@ -199,7 +180,7 @@ describe("gateway server health/presence", () => { harness.openClient(), ]); const waits = clients.map(({ ws }) => - onceMessage(ws, (o) => o.type === "event" && o.event === "presence"), + onceMessage(ws, (o) => o.type === "event" && o.event === "presence"), ); clients[0].ws.send( JSON.stringify({ @@ -238,7 +219,7 @@ describe("gateway server health/presence", () => { }, }); - const presenceP = onceMessage( + const presenceP = onceMessage( ws, (o) => o.type === "res" && o.id === "fingerprint", FINGERPRINT_TIMEOUT_MS, @@ -283,7 +264,7 @@ describe("gateway server health/presence", () => { }, }); - const presenceP = onceMessage( + const presenceP = onceMessage( ws, (o) => o.type === "res" && o.id === "cli-presence", CLI_PRESENCE_TIMEOUT_MS, diff --git a/src/gateway/server.node-invoke-approval-bypass.test.ts b/src/gateway/server.node-invoke-approval-bypass.test.ts index 444349b3786..556e6634be4 100644 --- a/src/gateway/server.node-invoke-approval-bypass.test.ts +++ b/src/gateway/server.node-invoke-approval-bypass.test.ts @@ -131,11 +131,7 @@ describe("node.invoke approval bypass", () => { const ws = new WebSocket(`ws://127.0.0.1:${port}`); trackConnectChallengeNonce(ws); const challengePromise = resolveDevice - ? onceMessage<{ - type?: string; - event?: string; - payload?: Record | null; - }>(ws, (o) => o.type === "event" && o.event === "connect.challenge") + ? onceMessage(ws, (o) => o.type === "event" && o.event === "connect.challenge") : null; await new Promise((resolve) => ws.once("open", resolve)); const nonce = (() => { diff --git a/src/gateway/server.roles-allowlist-update.test.ts b/src/gateway/server.roles-allowlist-update.test.ts index f0046985740..5a8e200d7e2 100644 --- a/src/gateway/server.roles-allowlist-update.test.ts +++ b/src/gateway/server.roles-allowlist-update.test.ts @@ -158,7 +158,7 @@ describe("gateway role enforcement", () => { displayName: "node-role-enforcement", }); - const binsPayload = await nodeClient.request<{ bins?: unknown[] }>("skills.bins", {}); + const binsPayload = await nodeClient.request("skills.bins", {}); expect(Array.isArray(binsPayload?.bins)).toBe(true); await expect(nodeClient.request("status", {})).rejects.toThrow("unauthorized role"); diff --git a/src/gateway/test-helpers.server.ts b/src/gateway/test-helpers.server.ts index b188306838b..65a776489c0 100644 --- a/src/gateway/test-helpers.server.ts +++ b/src/gateway/test-helpers.server.ts @@ -794,11 +794,11 @@ export async function readConnectChallengeNonce( } trackConnectChallengeNonce(ws); try { - const evt = await onceMessage<{ - type?: string; - event?: string; - payload?: Record | null; - }>(ws, (o) => o.type === "event" && o.event === "connect.challenge", timeoutMs); + const evt = await onceMessage( + ws, + (o) => o.type === "event" && o.event === "connect.challenge", + timeoutMs, + ); const nonce = (evt.payload as { nonce?: unknown } | undefined)?.nonce; if (typeof nonce === "string" && nonce.trim().length > 0) { (ws as TrackedWs)[CONNECT_CHALLENGE_NONCE_KEY] = nonce.trim(); diff --git a/src/mcp/channel-bridge.ts b/src/mcp/channel-bridge.ts index 621f151a029..ec6d573c93b 100644 --- a/src/mcp/channel-bridge.ts +++ b/src/mcp/channel-bridge.ts @@ -159,7 +159,7 @@ export class OpenClawChannelBridge { includeLastMessage?: boolean; }): Promise { await this.waitUntilReady(); - const response = await this.requestGateway("sessions.list", { + const response: SessionListResult = await this.requestGateway("sessions.list", { limit: params?.limit ?? 50, search: params?.search, includeDerivedTitles: params?.includeDerivedTitles ?? true, @@ -192,7 +192,7 @@ export class OpenClawChannelBridge { limit = 20, ): Promise> { await this.waitUntilReady(); - const response = await this.requestGateway("chat.history", { + const response: ChatHistoryResult = await this.requestGateway("chat.history", { sessionKey, limit, }); diff --git a/src/tui/gateway-chat.ts b/src/tui/gateway-chat.ts index 934cd2edd4a..32bb804ec5d 100644 --- a/src/tui/gateway-chat.ts +++ b/src/tui/gateway-chat.ts @@ -257,7 +257,7 @@ export class GatewayChatClient { } async listModels(): Promise { - const res = await this.client.request<{ models?: GatewayModelChoice[] }>("models.list"); + const res = await this.client.request("models.list"); return Array.isArray(res?.models) ? res.models : []; } } diff --git a/test/gateway.multi.e2e.test.ts b/test/gateway.multi.e2e.test.ts index 9d020f754d0..043d49e2040 100644 --- a/test/gateway.multi.e2e.test.ts +++ b/test/gateway.multi.e2e.test.ts @@ -103,7 +103,7 @@ describe("gateway multi-instance e2e", () => { const sessionKey = "agent:main:telegram:direct:123456"; const idempotencyKey = `idem-${randomUUID()}`; - const sendRes = await chatClient.request<{ runId?: string; status?: string }>("chat.send", { + const sendRes = await chatClient.request("chat.send", { sessionKey, message: "/context list", idempotencyKey, diff --git a/test/helpers/gateway-e2e-harness.ts b/test/helpers/gateway-e2e-harness.ts index e4b05c10102..4c3da079bfb 100644 --- a/test/helpers/gateway-e2e-harness.ts +++ b/test/helpers/gateway-e2e-harness.ts @@ -14,10 +14,6 @@ import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../src/utils/mess export { extractFirstTextBlock }; -type NodeListPayload = { - nodes?: Array<{ nodeId?: string; connected?: boolean; paired?: boolean }>; -}; - export type ChatEventPayload = { runId?: string; sessionKey?: string; @@ -348,7 +344,7 @@ export async function waitForNodeStatus( ); try { while (Date.now() < deadline) { - const list = await client.request("node.list", {}); + const list = await client.request("node.list", {}); const match = list.nodes?.find((n) => n.nodeId === nodeId); if (match?.connected && match?.paired) { return;