chore: migrate to oxlint and oxfmt

Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
This commit is contained in:
Peter Steinberger
2026-01-14 14:31:43 +00:00
parent 912ebffc63
commit c379191f80
1480 changed files with 28608 additions and 43547 deletions

View File

@@ -36,9 +36,7 @@ function ensureAgentRunListener() {
const phase = evt.data?.phase;
if (phase === "start") {
const startedAt =
typeof evt.data?.startedAt === "number"
? (evt.data.startedAt as number)
: undefined;
typeof evt.data?.startedAt === "number" ? (evt.data.startedAt as number) : undefined;
agentRunStarts.set(evt.runId, startedAt ?? Date.now());
return;
}
@@ -48,13 +46,8 @@ function ensureAgentRunListener() {
? (evt.data.startedAt as number)
: agentRunStarts.get(evt.runId);
const endedAt =
typeof evt.data?.endedAt === "number"
? (evt.data.endedAt as number)
: undefined;
const error =
typeof evt.data?.error === "string"
? (evt.data.error as string)
: undefined;
typeof evt.data?.endedAt === "number" ? (evt.data.endedAt as number) : undefined;
const error = typeof evt.data?.error === "string" ? (evt.data.error as string) : undefined;
agentRunStarts.delete(evt.runId);
recordAgentRunSnapshot({
runId: evt.runId,
@@ -106,13 +99,8 @@ export async function waitForAgentJob(params: {
? (evt.data.startedAt as number)
: agentRunStarts.get(evt.runId);
const endedAt =
typeof evt.data?.endedAt === "number"
? (evt.data.endedAt as number)
: undefined;
const error =
typeof evt.data?.error === "string"
? (evt.data.error as string)
: undefined;
typeof evt.data?.endedAt === "number" ? (evt.data.endedAt as number) : undefined;
const error = typeof evt.data?.error === "string" ? (evt.data.error as string) : undefined;
const snapshot: AgentRunSnapshot = {
runId: evt.runId,
status: phase === "error" ? "error" : "ok",

View File

@@ -98,31 +98,21 @@ export const agentHandlers: GatewayRequestHandlers = {
let images: Array<{ type: "image"; data: string; mimeType: string }> = [];
if (normalizedAttachments.length > 0) {
try {
const parsed = await parseMessageWithAttachments(
message,
normalizedAttachments,
{ maxBytes: 5_000_000, log: context.logGateway },
);
const parsed = await parseMessageWithAttachments(message, normalizedAttachments, {
maxBytes: 5_000_000,
log: context.logGateway,
});
message = parsed.message.trim();
images = parsed.images;
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, String(err)),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, String(err)));
return;
}
}
const rawChannel =
typeof request.channel === "string" ? request.channel.trim() : "";
const rawChannel = typeof request.channel === "string" ? request.channel.trim() : "";
if (rawChannel) {
const normalized = normalizeMessageChannel(rawChannel);
if (
normalized &&
normalized !== "last" &&
!isGatewayMessageChannel(normalized)
) {
if (normalized && normalized !== "last" && !isGatewayMessageChannel(normalized)) {
respond(
false,
undefined,
@@ -145,8 +135,7 @@ export const agentHandlers: GatewayRequestHandlers = {
let cfgForAgent: ReturnType<typeof loadConfig> | undefined;
if (requestedSessionKey) {
const { cfg, storePath, store, entry, canonicalKey } =
loadSessionEntry(requestedSessionKey);
const { cfg, storePath, store, entry, canonicalKey } = loadSessionEntry(requestedSessionKey);
cfgForAgent = cfg;
const now = Date.now();
const sessionId = entry?.sessionId ?? randomUUID();
@@ -180,10 +169,7 @@ export const agentHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"send blocked by session policy",
),
errorShape(ErrorCodes.INVALID_REQUEST, "send blocked by session policy"),
);
return;
}
@@ -197,10 +183,7 @@ export const agentHandlers: GatewayRequestHandlers = {
await saveSessionStore(storePath, store);
}
}
if (
canonicalSessionKey === mainSessionKey ||
canonicalSessionKey === "global"
) {
if (canonicalSessionKey === mainSessionKey || canonicalSessionKey === "global") {
context.addChatRun(idem, {
sessionKey: requestedSessionKey,
clientRunId: idem,
@@ -215,10 +198,7 @@ export const agentHandlers: GatewayRequestHandlers = {
const requestedChannel = normalizeMessageChannel(request.channel) ?? "last";
const lastChannel = sessionEntry?.lastChannel;
const lastTo =
typeof sessionEntry?.lastTo === "string"
? sessionEntry.lastTo.trim()
: "";
const lastTo = typeof sessionEntry?.lastTo === "string" ? sessionEntry.lastTo.trim() : "";
const wantsDelivery = request.deliver === true;
@@ -241,9 +221,7 @@ export const agentHandlers: GatewayRequestHandlers = {
})();
const explicitTo =
typeof request.to === "string" && request.to.trim()
? request.to.trim()
: undefined;
typeof request.to === "string" && request.to.trim() ? request.to.trim() : undefined;
const deliveryTargetMode = explicitTo
? "explicit"
: isDeliverableMessageChannel(resolvedChannel)
@@ -251,9 +229,7 @@ export const agentHandlers: GatewayRequestHandlers = {
: undefined;
let resolvedTo =
explicitTo ||
(isDeliverableMessageChannel(resolvedChannel)
? lastTo || undefined
: undefined);
(isDeliverableMessageChannel(resolvedChannel) ? lastTo || undefined : undefined);
if (!resolvedTo && isDeliverableMessageChannel(resolvedChannel)) {
const cfg = cfgForAgent ?? loadConfig();
const fallback = resolveOutboundTarget({
@@ -267,8 +243,7 @@ export const agentHandlers: GatewayRequestHandlers = {
}
}
const deliver =
request.deliver === true && resolvedChannel !== INTERNAL_MESSAGE_CHANNEL;
const deliver = request.deliver === true && resolvedChannel !== INTERNAL_MESSAGE_CHANNEL;
const accepted = {
runId,

View File

@@ -6,10 +6,7 @@ import {
normalizeChannelId,
} from "../../channels/plugins/index.js";
import { buildChannelAccountSnapshot } from "../../channels/plugins/status.js";
import type {
ChannelAccountSnapshot,
ChannelPlugin,
} from "../../channels/plugins/types.js";
import type { ChannelAccountSnapshot, ChannelPlugin } from "../../channels/plugins/types.js";
import type { ClawdbotConfig } from "../../config/config.js";
import { loadConfig, readConfigFileSnapshot } from "../../config/config.js";
import { getChannelActivity } from "../../infra/channel-activity.js";
@@ -44,10 +41,7 @@ export async function logoutChannelAccount(params: {
params.plugin.config.defaultAccountId?.(params.cfg) ||
params.plugin.config.listAccountIds(params.cfg)[0] ||
DEFAULT_ACCOUNT_ID;
const account = params.plugin.config.resolveAccount(
params.cfg,
resolvedAccountId,
);
const account = params.plugin.config.resolveAccount(params.cfg, resolvedAccountId);
await params.context.stopChannel(params.channelId, resolvedAccountId);
const result = await params.plugin.gateway?.logoutAccount?.({
cfg: params.cfg,
@@ -59,14 +53,9 @@ export async function logoutChannelAccount(params: {
throw new Error(`Channel ${params.channelId} does not support logout`);
}
const cleared = Boolean(result.cleared);
const loggedOut =
typeof result.loggedOut === "boolean" ? result.loggedOut : cleared;
const loggedOut = typeof result.loggedOut === "boolean" ? result.loggedOut : cleared;
if (loggedOut) {
params.context.markChannelLoggedOut(
params.channelId,
true,
resolvedAccountId,
);
params.context.markChannelLoggedOut(params.channelId, true, resolvedAccountId);
}
return {
channel: params.channelId,
@@ -91,8 +80,7 @@ export const channelsHandlers: GatewayRequestHandlers = {
}
const probe = (params as { probe?: boolean }).probe === true;
const timeoutMsRaw = (params as { timeoutMs?: unknown }).timeoutMs;
const timeoutMs =
typeof timeoutMsRaw === "number" ? Math.max(1000, timeoutMsRaw) : 10_000;
const timeoutMs = typeof timeoutMsRaw === "number" ? Math.max(1000, timeoutMsRaw) : 10_000;
const cfg = loadConfig();
const runtime = context.getRuntimeSnapshot();
const plugins = listChannelPlugins();
@@ -108,8 +96,7 @@ export const channelsHandlers: GatewayRequestHandlers = {
const accounts = runtime.channelAccounts[channelId];
const defaultRuntime = runtime.channels[channelId];
const raw =
accounts?.[accountId] ??
(accountId === defaultAccountId ? defaultRuntime : undefined);
accounts?.[accountId] ?? (accountId === defaultAccountId ? defaultRuntime : undefined);
if (!raw) return undefined;
return raw;
};
@@ -174,11 +161,7 @@ export const channelsHandlers: GatewayRequestHandlers = {
});
}
}
const runtimeSnapshot = resolveRuntimeSnapshot(
channelId,
accountId,
defaultAccountId,
);
const runtimeSnapshot = resolveRuntimeSnapshot(channelId, accountId, defaultAccountId);
const snapshot = await buildChannelAccountSnapshot({
plugin,
cfg,
@@ -201,33 +184,26 @@ export const channelsHandlers: GatewayRequestHandlers = {
accounts.push(snapshot);
}
const defaultAccount =
accounts.find((entry) => entry.accountId === defaultAccountId) ??
accounts[0];
accounts.find((entry) => entry.accountId === defaultAccountId) ?? accounts[0];
return { accounts, defaultAccountId, defaultAccount, resolvedAccounts };
};
const payload: Record<string, unknown> = {
ts: Date.now(),
channelOrder: plugins.map((plugin) => plugin.id),
channelLabels: Object.fromEntries(
plugins.map((plugin) => [plugin.id, plugin.meta.label]),
),
channelLabels: Object.fromEntries(plugins.map((plugin) => [plugin.id, plugin.meta.label])),
channels: {} as Record<string, unknown>,
channelAccounts: {} as Record<string, unknown>,
channelDefaultAccountId: {} as Record<string, unknown>,
};
const channelsMap = payload.channels as Record<string, unknown>;
const accountsMap = payload.channelAccounts as Record<string, unknown>;
const defaultAccountIdMap = payload.channelDefaultAccountId as Record<
string,
unknown
>;
const defaultAccountIdMap = payload.channelDefaultAccountId as Record<string, unknown>;
for (const plugin of plugins) {
const { accounts, defaultAccountId, defaultAccount, resolvedAccounts } =
await buildChannelAccounts(plugin.id);
const fallbackAccount =
resolvedAccounts[defaultAccountId] ??
plugin.config.resolveAccount(cfg, defaultAccountId);
resolvedAccounts[defaultAccountId] ?? plugin.config.resolveAccount(cfg, defaultAccountId);
const summary = plugin.status?.buildChannelSummary
? await plugin.status.buildChannelSummary({
account: fallbackAccount,
@@ -262,16 +238,12 @@ export const channelsHandlers: GatewayRequestHandlers = {
return;
}
const rawChannel = (params as { channel?: unknown }).channel;
const channelId =
typeof rawChannel === "string" ? normalizeChannelId(rawChannel) : null;
const channelId = typeof rawChannel === "string" ? normalizeChannelId(rawChannel) : null;
if (!channelId) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid channels.logout channel",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid channels.logout channel"),
);
return;
}
@@ -280,25 +252,18 @@ export const channelsHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`channel ${channelId} does not support logout`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `channel ${channelId} does not support logout`),
);
return;
}
const accountIdRaw = (params as { accountId?: unknown }).accountId;
const accountId =
typeof accountIdRaw === "string" ? accountIdRaw.trim() : undefined;
const accountId = typeof accountIdRaw === "string" ? accountIdRaw.trim() : undefined;
const snapshot = await readConfigFileSnapshot();
if (!snapshot.valid) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"config invalid; fix it before logging out",
),
errorShape(ErrorCodes.INVALID_REQUEST, "config invalid; fix it before logging out"),
);
return;
}
@@ -312,11 +277,7 @@ export const channelsHandlers: GatewayRequestHandlers = {
});
respond(true, payload, undefined);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
};

View File

@@ -14,10 +14,7 @@ import {
isChatStopCommandText,
resolveChatRunExpiresAtMs,
} from "../chat-abort.js";
import {
type ChatImageContent,
parseMessageWithAttachments,
} from "../chat-attachments.js";
import { type ChatImageContent, parseMessageWithAttachments } from "../chat-attachments.js";
import {
ErrorCodes,
errorShape,
@@ -56,19 +53,13 @@ export const chatHandlers: GatewayRequestHandlers = {
const { cfg, storePath, entry } = loadSessionEntry(sessionKey);
const sessionId = entry?.sessionId;
const rawMessages =
sessionId && storePath
? readSessionMessages(sessionId, storePath, entry?.sessionFile)
: [];
sessionId && storePath ? readSessionMessages(sessionId, storePath, entry?.sessionFile) : [];
const hardMax = 1000;
const defaultLimit = 200;
const requested = typeof limit === "number" ? limit : defaultLimit;
const max = Math.min(hardMax, requested);
const sliced =
rawMessages.length > max ? rawMessages.slice(-max) : rawMessages;
const capped = capArrayByJsonBytes(
sliced,
MAX_CHAT_HISTORY_MESSAGES_BYTES,
).items;
const sliced = rawMessages.length > max ? rawMessages.slice(-max) : rawMessages;
const capped = capArrayByJsonBytes(sliced, MAX_CHAT_HISTORY_MESSAGES_BYTES).items;
let thinkingLevel = entry?.thinkingLevel;
if (!thinkingLevel) {
const configured = cfg.agents?.defaults?.thinkingDefault;
@@ -138,10 +129,7 @@ export const chatHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"runId does not match sessionKey",
),
errorShape(ErrorCodes.INVALID_REQUEST, "runId does not match sessionKey"),
);
return;
}
@@ -206,25 +194,18 @@ export const chatHandlers: GatewayRequestHandlers = {
let parsedImages: ChatImageContent[] = [];
if (normalizedAttachments.length > 0) {
try {
const parsed = await parseMessageWithAttachments(
p.message,
normalizedAttachments,
{ maxBytes: 5_000_000, log: context.logGateway },
);
const parsed = await parseMessageWithAttachments(p.message, normalizedAttachments, {
maxBytes: 5_000_000,
log: context.logGateway,
});
parsedMessage = parsed.message;
parsedImages = parsed.images;
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, String(err)),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, String(err)));
return;
}
}
const { cfg, storePath, store, entry, canonicalKey } = loadSessionEntry(
p.sessionKey,
);
const { cfg, storePath, store, entry, canonicalKey } = loadSessionEntry(p.sessionKey);
const timeoutMs = resolveAgentTimeoutMs({
cfg,
overrideMs: p.timeoutMs,
@@ -249,10 +230,7 @@ export const chatHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"send blocked by session policy",
),
errorShape(ErrorCodes.INVALID_REQUEST, "send blocked by session policy"),
);
return;
}
@@ -285,12 +263,10 @@ export const chatHandlers: GatewayRequestHandlers = {
const activeExisting = context.chatAbortControllers.get(clientRunId);
if (activeExisting) {
respond(
true,
{ runId: clientRunId, status: "in_flight" as const },
undefined,
{ cached: true, runId: clientRunId },
);
respond(true, { runId: clientRunId, status: "in_flight" as const }, undefined, {
cached: true,
runId: clientRunId,
});
return;
}

View File

@@ -1,7 +1,4 @@
import {
resolveAgentWorkspaceDir,
resolveDefaultAgentId,
} from "../../agents/agent-scope.js";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import {
CONFIG_PATH_CLAWDBOT,
loadConfig,
@@ -58,10 +55,7 @@ export const configHandlers: GatewayRequestHandlers = {
return;
}
const cfg = loadConfig();
const workspaceDir = resolveAgentWorkspaceDir(
cfg,
resolveDefaultAgentId(cfg),
);
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
const pluginRegistry = loadClawdbotPlugins({
config: cfg,
workspaceDir,
@@ -99,20 +93,13 @@ export const configHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid config.set params: raw (string) required",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid config.set params: raw (string) required"),
);
return;
}
const parsedRes = parseConfigJson5(rawValue);
if (!parsedRes.ok) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error));
return;
}
const validated = validateConfigObject(parsedRes.parsed);
@@ -163,11 +150,7 @@ export const configHandlers: GatewayRequestHandlers = {
}
const parsedRes = parseConfigJson5(rawValue);
if (!parsedRes.ok) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, parsedRes.error));
return;
}
const validated = validateConfigObject(parsedRes.parsed);
@@ -191,11 +174,9 @@ export const configHandlers: GatewayRequestHandlers = {
typeof (params as { note?: unknown }).note === "string"
? (params as { note?: string }).note?.trim() || undefined
: undefined;
const restartDelayMsRaw = (params as { restartDelayMs?: unknown })
.restartDelayMs;
const restartDelayMsRaw = (params as { restartDelayMs?: unknown }).restartDelayMs;
const restartDelayMs =
typeof restartDelayMsRaw === "number" &&
Number.isFinite(restartDelayMsRaw)
typeof restartDelayMsRaw === "number" && Number.isFinite(restartDelayMsRaw)
? Math.max(0, Math.floor(restartDelayMsRaw))
: undefined;

View File

@@ -6,10 +6,7 @@ export const connectHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"connect is only valid as the first request",
),
errorShape(ErrorCodes.INVALID_REQUEST, "connect is only valid as the first request"),
);
},
};

View File

@@ -1,11 +1,5 @@
import {
normalizeCronJobCreate,
normalizeCronJobPatch,
} from "../../cron/normalize.js";
import {
readCronRunLogEntries,
resolveCronRunLogPath,
} from "../../cron/run-log.js";
import { normalizeCronJobCreate, normalizeCronJobPatch } from "../../cron/normalize.js";
import { readCronRunLogEntries, resolveCronRunLogPath } from "../../cron/run-log.js";
import type { CronJobCreate, CronJobPatch } from "../../cron/types.js";
import {
ErrorCodes,
@@ -92,9 +86,7 @@ export const cronHandlers: GatewayRequestHandlers = {
respond(true, job, undefined);
},
"cron.update": async ({ params, respond, context }) => {
const normalizedPatch = normalizeCronJobPatch(
(params as { patch?: unknown } | null)?.patch,
);
const normalizedPatch = normalizeCronJobPatch((params as { patch?: unknown } | null)?.patch);
const candidate =
normalizedPatch && typeof params === "object" && params !== null
? { ...(params as Record<string, unknown>), patch: normalizedPatch }
@@ -120,17 +112,11 @@ export const cronHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid cron.update params: missing id",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.update params: missing id"),
);
return;
}
const job = await context.cron.update(
jobId,
p.patch as unknown as CronJobPatch,
);
const job = await context.cron.update(jobId, p.patch as unknown as CronJobPatch);
respond(true, job, undefined);
},
"cron.remove": async ({ params, respond, context }) => {
@@ -151,10 +137,7 @@ export const cronHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid cron.remove params: missing id",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.remove params: missing id"),
);
return;
}
@@ -179,10 +162,7 @@ export const cronHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid cron.run params: missing id",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.run params: missing id"),
);
return;
}
@@ -207,10 +187,7 @@ export const cronHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"invalid cron.runs params: missing id",
),
errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.runs params: missing id"),
);
return;
}

View File

@@ -13,9 +13,7 @@ export const healthHandlers: GatewayRequestHandlers = {
if (cached && now - cached.ts < HEALTH_REFRESH_INTERVAL_MS) {
respond(true, cached, undefined, { cached: true });
void refreshHealthSnapshot({ probe: false }).catch((err) =>
logHealth.error(
`background health refresh failed: ${formatError(err)}`,
),
logHealth.error(`background health refresh failed: ${formatError(err)}`),
);
return;
}
@@ -23,11 +21,7 @@ export const healthHandlers: GatewayRequestHandlers = {
const snap = await refreshHealthSnapshot({ probe: false });
respond(true, snap, undefined);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
status: async ({ respond }) => {

View File

@@ -23,11 +23,7 @@ export const modelsHandlers: GatewayRequestHandlers = {
const models = await context.loadGatewayModelCatalog();
respond(true, { models }, undefined);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, String(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, String(err)));
}
},
};

View File

@@ -1,9 +1,5 @@
import type { ErrorObject } from "ajv";
import {
ErrorCodes,
errorShape,
formatValidationErrors,
} from "../protocol/index.js";
import { ErrorCodes, errorShape, formatValidationErrors } from "../protocol/index.js";
import { formatForLog } from "../ws-log.js";
import type { RespondFn } from "./types.js";
@@ -26,18 +22,11 @@ export function respondInvalidParams(params: {
);
}
export async function respondUnavailableOnThrow(
respond: RespondFn,
fn: () => Promise<void>,
) {
export async function respondUnavailableOnThrow(respond: RespondFn, fn: () => Promise<void>) {
try {
await fn();
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
}

View File

@@ -97,11 +97,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
await respondUnavailableOnThrow(respond, async () => {
const approved = await approveNodePairing(requestId);
if (!approved) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "unknown requestId"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "unknown requestId"));
return;
}
context.broadcast(
@@ -130,11 +126,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
await respondUnavailableOnThrow(respond, async () => {
const rejected = await rejectNodePairing(requestId);
if (!rejected) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "unknown requestId"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "unknown requestId"));
return;
}
context.broadcast(
@@ -184,27 +176,15 @@ export const nodeHandlers: GatewayRequestHandlers = {
await respondUnavailableOnThrow(respond, async () => {
const trimmed = displayName.trim();
if (!trimmed) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "displayName required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "displayName required"));
return;
}
const updated = await renamePairedNode(nodeId, trimmed);
if (!updated) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "unknown nodeId"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "unknown nodeId"));
return;
}
respond(
true,
{ nodeId: updated.nodeId, displayName: updated.displayName },
undefined,
);
respond(true, { nodeId: updated.nodeId, displayName: updated.displayName }, undefined);
});
},
"node.list": async ({ params, respond, context }) => {
@@ -221,21 +201,14 @@ export const nodeHandlers: GatewayRequestHandlers = {
const pairedById = new Map(list.paired.map((n) => [n.nodeId, n]));
const connected = context.bridge?.listConnected?.() ?? [];
const connectedById = new Map(connected.map((n) => [n.nodeId, n]));
const nodeIds = new Set<string>([
...pairedById.keys(),
...connectedById.keys(),
]);
const nodeIds = new Set<string>([...pairedById.keys(), ...connectedById.keys()]);
const nodes = [...nodeIds].map((nodeId) => {
const paired = pairedById.get(nodeId);
const live = connectedById.get(nodeId);
const caps = uniqueSortedStrings([
...(live?.caps ?? paired?.caps ?? []),
]);
const commands = uniqueSortedStrings([
...(live?.commands ?? paired?.commands ?? []),
]);
const caps = uniqueSortedStrings([...(live?.caps ?? paired?.caps ?? [])]);
const commands = uniqueSortedStrings([...(live?.commands ?? paired?.commands ?? [])]);
return {
nodeId,
@@ -277,11 +250,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
const { nodeId } = params as { nodeId: string };
const id = String(nodeId ?? "").trim();
if (!id) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "nodeId required"));
return;
}
await respondUnavailableOnThrow(respond, async () => {
@@ -291,18 +260,12 @@ export const nodeHandlers: GatewayRequestHandlers = {
const live = connected.find((n) => n.nodeId === id);
if (!paired && !live) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "unknown nodeId"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "unknown nodeId"));
return;
}
const caps = uniqueSortedStrings([...(live?.caps ?? paired?.caps ?? [])]);
const commands = uniqueSortedStrings([
...(live?.commands ?? paired?.commands ?? []),
]);
const commands = uniqueSortedStrings([...(live?.commands ?? paired?.commands ?? [])]);
respond(
true,
@@ -336,11 +299,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
}
const bridge = context.bridge;
if (!bridge) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, "bridge not running"),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, "bridge not running"));
return;
}
const p = params as {
@@ -362,10 +321,7 @@ export const nodeHandlers: GatewayRequestHandlers = {
}
await respondUnavailableOnThrow(respond, async () => {
const paramsJSON =
"params" in p && p.params !== undefined
? JSON.stringify(p.params)
: null;
const paramsJSON = "params" in p && p.params !== undefined ? JSON.stringify(p.params) : null;
const res = await bridge.invoke({
nodeId,
command,
@@ -376,11 +332,9 @@ export const nodeHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.UNAVAILABLE,
res.error?.message ?? "node invoke failed",
{ details: { nodeError: res.error ?? null } },
),
errorShape(ErrorCodes.UNAVAILABLE, res.error?.message ?? "node invoke failed", {
details: { nodeError: res.error ?? null },
}),
);
return;
}

View File

@@ -1,7 +1,4 @@
import {
getChannelPlugin,
normalizeChannelId,
} from "../../channels/plugins/index.js";
import { getChannelPlugin, normalizeChannelId } from "../../channels/plugins/index.js";
import type { ChannelId } from "../../channels/plugins/types.js";
import { DEFAULT_CHAT_CHANNEL } from "../../channels/registry.js";
import { loadConfig } from "../../config/config.js";
@@ -52,19 +49,13 @@ export const sendHandlers: GatewayRequestHandlers = {
}
const to = request.to.trim();
const message = request.message.trim();
const channelInput =
typeof request.channel === "string" ? request.channel : undefined;
const normalizedChannel = channelInput
? normalizeChannelId(channelInput)
: null;
const channelInput = typeof request.channel === "string" ? request.channel : undefined;
const normalizedChannel = channelInput ? normalizeChannelId(channelInput) : null;
if (channelInput && !normalizedChannel) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`unsupported channel: ${channelInput}`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `unsupported channel: ${channelInput}`),
);
return;
}
@@ -80,10 +71,7 @@ export const sendHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`unsupported channel: ${channel}`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `unsupported channel: ${channel}`),
);
return;
}
@@ -96,11 +84,7 @@ export const sendHandlers: GatewayRequestHandlers = {
mode: "explicit",
});
if (!resolved.ok) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, String(resolved.error)),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, String(resolved.error)));
return;
}
const results = await deliverOutboundPayloads({
@@ -174,19 +158,13 @@ export const sendHandlers: GatewayRequestHandlers = {
return;
}
const to = request.to.trim();
const channelInput =
typeof request.channel === "string" ? request.channel : undefined;
const normalizedChannel = channelInput
? normalizeChannelId(channelInput)
: null;
const channelInput = typeof request.channel === "string" ? request.channel : undefined;
const normalizedChannel = channelInput ? normalizeChannelId(channelInput) : null;
if (channelInput && !normalizedChannel) {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`unsupported poll channel: ${channelInput}`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `unsupported poll channel: ${channelInput}`),
);
return;
}
@@ -208,10 +186,7 @@ export const sendHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`unsupported poll channel: ${channel}`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `unsupported poll channel: ${channel}`),
);
return;
}
@@ -224,11 +199,7 @@ export const sendHandlers: GatewayRequestHandlers = {
mode: "explicit",
});
if (!resolved.ok) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, String(resolved.error)),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, String(resolved.error)));
return;
}
const normalized = outbound.pollMaxOptions

View File

@@ -99,11 +99,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const p = params as import("../protocol/index.js").SessionsPatchParams;
const key = String(p.key ?? "").trim();
if (!key) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "key required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "key required"));
return;
}
@@ -153,11 +149,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const p = params as import("../protocol/index.js").SessionsResetParams;
const key = String(p.key ?? "").trim();
if (!key) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "key required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "key required"));
return;
}
@@ -192,11 +184,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
};
store[primaryKey] = next;
await saveSessionStore(storePath, store);
respond(
true,
{ ok: true, key: target.canonicalKey, entry: next },
undefined,
);
respond(true, { ok: true, key: target.canonicalKey, entry: next }, undefined);
},
"sessions.delete": async ({ params, respond }) => {
if (!validateSessionsDeleteParams(params)) {
@@ -213,11 +201,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const p = params as import("../protocol/index.js").SessionsDeleteParams;
const key = String(p.key ?? "").trim();
if (!key) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "key required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "key required"));
return;
}
@@ -228,16 +212,12 @@ export const sessionsHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
`Cannot delete the main session (${mainKey}).`,
),
errorShape(ErrorCodes.INVALID_REQUEST, `Cannot delete the main session (${mainKey}).`),
);
return;
}
const deleteTranscript =
typeof p.deleteTranscript === "boolean" ? p.deleteTranscript : true;
const deleteTranscript = typeof p.deleteTranscript === "boolean" ? p.deleteTranscript : true;
const storePath = target.storePath;
const store = loadSessionStore(storePath);
@@ -286,11 +266,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
}
}
respond(
true,
{ ok: true, key: target.canonicalKey, deleted: existed, archived },
undefined,
);
respond(true, { ok: true, key: target.canonicalKey, deleted: existed, archived }, undefined);
},
"sessions.compact": async ({ params, respond }) => {
if (!validateSessionsCompactParams(params)) {
@@ -307,11 +283,7 @@ export const sessionsHandlers: GatewayRequestHandlers = {
const p = params as import("../protocol/index.js").SessionsCompactParams;
const key = String(p.key ?? "").trim();
if (!key) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "key required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "key required"));
return;
}

View File

@@ -1,7 +1,4 @@
import {
resolveAgentWorkspaceDir,
resolveDefaultAgentId,
} from "../../agents/agent-scope.js";
import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
import { installSkill } from "../../agents/skills-install.js";
import { buildWorkspaceSkillStatus } from "../../agents/skills-status.js";
import type { ClawdbotConfig } from "../../config/config.js";
@@ -30,10 +27,7 @@ export const skillsHandlers: GatewayRequestHandlers = {
return;
}
const cfg = loadConfig();
const workspaceDir = resolveAgentWorkspaceDir(
cfg,
resolveDefaultAgentId(cfg),
);
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
const report = buildWorkspaceSkillStatus(workspaceDir, {
config: cfg,
});
@@ -57,10 +51,7 @@ export const skillsHandlers: GatewayRequestHandlers = {
timeoutMs?: number;
};
const cfg = loadConfig();
const workspaceDirRaw = resolveAgentWorkspaceDir(
cfg,
resolveDefaultAgentId(cfg),
);
const workspaceDirRaw = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
const result = await installSkill({
workspaceDir: workspaceDirRaw,
skillName: p.name,
@@ -71,9 +62,7 @@ export const skillsHandlers: GatewayRequestHandlers = {
respond(
result.ok,
result,
result.ok
? undefined
: errorShape(ErrorCodes.UNAVAILABLE, result.message),
result.ok ? undefined : errorShape(ErrorCodes.UNAVAILABLE, result.message),
);
},
"skills.update": async ({ params, respond }) => {
@@ -124,10 +113,6 @@ export const skillsHandlers: GatewayRequestHandlers = {
skills,
};
await writeConfigFile(nextConfig);
respond(
true,
{ ok: true, skillKey: p.skillKey, config: current },
undefined,
);
respond(true, { ok: true, skillKey: p.skillKey, config: current }, undefined);
},
};

View File

@@ -1,14 +1,8 @@
import { resolveMainSessionKeyFromConfig } from "../../config/sessions.js";
import { getLastHeartbeatEvent } from "../../infra/heartbeat-events.js";
import { setHeartbeatsEnabled } from "../../infra/heartbeat-runner.js";
import {
enqueueSystemEvent,
isSystemEventContextChanged,
} from "../../infra/system-events.js";
import {
listSystemPresence,
updateSystemPresence,
} from "../../infra/system-presence.js";
import { enqueueSystemEvent, isSystemEventContextChanged } from "../../infra/system-events.js";
import { listSystemPresence, updateSystemPresence } from "../../infra/system-presence.js";
import { ErrorCodes, errorShape } from "../protocol/index.js";
import type { GatewayRequestHandlers } from "./types.js";
@@ -39,39 +33,26 @@ export const systemHandlers: GatewayRequestHandlers = {
"system-event": ({ params, respond, context }) => {
const text = typeof params.text === "string" ? params.text.trim() : "";
if (!text) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "text required"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "text required"));
return;
}
const sessionKey = resolveMainSessionKeyFromConfig();
const instanceId =
typeof params.instanceId === "string" ? params.instanceId : undefined;
const instanceId = typeof params.instanceId === "string" ? params.instanceId : undefined;
const host = typeof params.host === "string" ? params.host : undefined;
const ip = typeof params.ip === "string" ? params.ip : undefined;
const mode = typeof params.mode === "string" ? params.mode : undefined;
const version =
typeof params.version === "string" ? params.version : undefined;
const platform =
typeof params.platform === "string" ? params.platform : undefined;
const deviceFamily =
typeof params.deviceFamily === "string" ? params.deviceFamily : undefined;
const version = typeof params.version === "string" ? params.version : undefined;
const platform = typeof params.platform === "string" ? params.platform : undefined;
const deviceFamily = typeof params.deviceFamily === "string" ? params.deviceFamily : undefined;
const modelIdentifier =
typeof params.modelIdentifier === "string"
? params.modelIdentifier
: undefined;
typeof params.modelIdentifier === "string" ? params.modelIdentifier : undefined;
const lastInputSeconds =
typeof params.lastInputSeconds === "number" &&
Number.isFinite(params.lastInputSeconds)
typeof params.lastInputSeconds === "number" && Number.isFinite(params.lastInputSeconds)
? params.lastInputSeconds
: undefined;
const reason =
typeof params.reason === "string" ? params.reason : undefined;
const reason = typeof params.reason === "string" ? params.reason : undefined;
const tags =
Array.isArray(params.tags) &&
params.tags.every((t) => typeof t === "string")
Array.isArray(params.tags) && params.tags.every((t) => typeof t === "string")
? (params.tags as string[])
: undefined;
const presenceUpdate = updateSystemPresence({
@@ -95,24 +76,15 @@ export const systemHandlers: GatewayRequestHandlers = {
const reasonValue = next.reason ?? reason;
const normalizedReason = (reasonValue ?? "").toLowerCase();
const ignoreReason =
normalizedReason.startsWith("periodic") ||
normalizedReason === "heartbeat";
normalizedReason.startsWith("periodic") || normalizedReason === "heartbeat";
const hostChanged = changed.has("host");
const ipChanged = changed.has("ip");
const versionChanged = changed.has("version");
const modeChanged = changed.has("mode");
const reasonChanged = changed.has("reason") && !ignoreReason;
const hasChanges =
hostChanged ||
ipChanged ||
versionChanged ||
modeChanged ||
reasonChanged;
const hasChanges = hostChanged || ipChanged || versionChanged || modeChanged || reasonChanged;
if (hasChanges) {
const contextChanged = isSystemEventContextChanged(
sessionKey,
presenceUpdate.key,
);
const contextChanged = isSystemEventContextChanged(sessionKey, presenceUpdate.key);
const parts: string[] = [];
if (contextChanged || hostChanged || ipChanged) {
const hostLabel = next.host?.trim() || "Unknown";

View File

@@ -8,18 +8,11 @@ import type { GatewayRequestHandlers } from "./types.js";
export const talkHandlers: GatewayRequestHandlers = {
"talk.mode": ({ params, respond, context, client, isWebchatConnect }) => {
if (
client &&
isWebchatConnect(client.connect) &&
!context.hasConnectedMobileNode()
) {
if (client && isWebchatConnect(client.connect) && !context.hasConnectedMobileNode()) {
respond(
false,
undefined,
errorShape(
ErrorCodes.UNAVAILABLE,
"talk disabled: no connected iOS/Android nodes",
),
errorShape(ErrorCodes.UNAVAILABLE, "talk disabled: no connected iOS/Android nodes"),
);
return;
}

View File

@@ -5,11 +5,7 @@ import type { CronService } from "../../cron/service.js";
import type { startNodeBridgeServer } from "../../infra/bridge/server.js";
import type { WizardSession } from "../../wizard/session.js";
import type { ChatAbortControllerEntry } from "../chat-abort.js";
import type {
ConnectParams,
ErrorShape,
RequestFrame,
} from "../protocol/index.js";
import type { ConnectParams, ErrorShape, RequestFrame } from "../protocol/index.js";
import type { ChannelRuntimeSnapshot } from "../server-channels.js";
import type { DedupeEntry } from "../server-shared.js";
@@ -44,21 +40,14 @@ export type GatewayRequestContext = {
},
) => void;
bridge: Awaited<ReturnType<typeof startNodeBridgeServer>> | null;
bridgeSendToSession: (
sessionKey: string,
event: string,
payload: unknown,
) => void;
bridgeSendToSession: (sessionKey: string, event: string, payload: unknown) => void;
hasConnectedMobileNode: () => boolean;
agentRunSeq: Map<string, number>;
chatAbortControllers: Map<string, ChatAbortControllerEntry>;
chatAbortedRuns: Map<string, number>;
chatRunBuffers: Map<string, string>;
chatDeltaSentAt: Map<string, number>;
addChatRun: (
sessionId: string,
entry: { sessionKey: string; clientRunId: string },
) => void;
addChatRun: (sessionId: string, entry: { sessionKey: string; clientRunId: string }) => void;
removeChatRun: (
sessionId: string,
clientRunId: string,
@@ -107,8 +96,6 @@ export type GatewayRequestHandlerOptions = {
context: GatewayRequestContext;
};
export type GatewayRequestHandler = (
opts: GatewayRequestHandlerOptions,
) => Promise<void> | void;
export type GatewayRequestHandler = (opts: GatewayRequestHandlerOptions) => Promise<void> | void;
export type GatewayRequestHandlers = Record<string, GatewayRequestHandler>;

View File

@@ -35,11 +35,9 @@ export const updateHandlers: GatewayRequestHandlers = {
typeof (params as { note?: unknown }).note === "string"
? (params as { note?: string }).note?.trim() || undefined
: undefined;
const restartDelayMsRaw = (params as { restartDelayMs?: unknown })
.restartDelayMs;
const restartDelayMsRaw = (params as { restartDelayMs?: unknown }).restartDelayMs;
const restartDelayMs =
typeof restartDelayMsRaw === "number" &&
Number.isFinite(restartDelayMsRaw)
typeof restartDelayMsRaw === "number" && Number.isFinite(restartDelayMsRaw)
? Math.max(0, Math.floor(restartDelayMsRaw))
: undefined;
const timeoutMsRaw = (params as { timeoutMs?: unknown }).timeoutMs;

View File

@@ -1,7 +1,4 @@
import {
loadVoiceWakeConfig,
setVoiceWakeTriggers,
} from "../../infra/voicewake.js";
import { loadVoiceWakeConfig, setVoiceWakeTriggers } from "../../infra/voicewake.js";
import { ErrorCodes, errorShape } from "../protocol/index.js";
import { normalizeVoiceWakeTriggers } from "../server-utils.js";
import { formatForLog } from "../ws-log.js";
@@ -13,11 +10,7 @@ export const voicewakeHandlers: GatewayRequestHandlers = {
const cfg = await loadVoiceWakeConfig();
respond(true, { triggers: cfg.triggers });
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
"voicewake.set": async ({ params, respond, context }) => {
@@ -25,10 +18,7 @@ export const voicewakeHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"voicewake.set requires triggers: string[]",
),
errorShape(ErrorCodes.INVALID_REQUEST, "voicewake.set requires triggers: string[]"),
);
return;
}
@@ -38,11 +28,7 @@ export const voicewakeHandlers: GatewayRequestHandlers = {
context.broadcastVoiceWakeChanged(cfg.triggers);
respond(true, { triggers: cfg.triggers });
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
};

View File

@@ -13,9 +13,7 @@ const WEB_LOGIN_METHODS = new Set(["web.login.start", "web.login.wait"]);
const resolveWebLoginProvider = () =>
listChannelPlugins().find((plugin) =>
(plugin.gatewayMethods ?? []).some((method) =>
WEB_LOGIN_METHODS.has(method),
),
(plugin.gatewayMethods ?? []).some((method) => WEB_LOGIN_METHODS.has(method)),
) ?? null;
export const webHandlers: GatewayRequestHandlers = {
@@ -41,10 +39,7 @@ export const webHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"web login provider is not available",
),
errorShape(ErrorCodes.INVALID_REQUEST, "web login provider is not available"),
);
return;
}
@@ -71,11 +66,7 @@ export const webHandlers: GatewayRequestHandlers = {
});
respond(true, result, undefined);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
"web.login.wait": async ({ params, respond, context }) => {
@@ -100,10 +91,7 @@ export const webHandlers: GatewayRequestHandlers = {
respond(
false,
undefined,
errorShape(
ErrorCodes.INVALID_REQUEST,
"web login provider is not available",
),
errorShape(ErrorCodes.INVALID_REQUEST, "web login provider is not available"),
);
return;
}
@@ -130,11 +118,7 @@ export const webHandlers: GatewayRequestHandlers = {
}
respond(true, result, undefined);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, formatForLog(err)));
}
},
};

View File

@@ -28,18 +28,13 @@ export const wizardHandlers: GatewayRequestHandlers = {
}
const running = context.findRunningWizard();
if (running) {
respond(
false,
undefined,
errorShape(ErrorCodes.UNAVAILABLE, "wizard already running"),
);
respond(false, undefined, errorShape(ErrorCodes.UNAVAILABLE, "wizard already running"));
return;
}
const sessionId = randomUUID();
const opts = {
mode: params.mode as "local" | "remote" | undefined,
workspace:
typeof params.workspace === "string" ? params.workspace : undefined,
workspace: typeof params.workspace === "string" ? params.workspace : undefined,
};
const session = new WizardSession((prompter) =>
context.wizardRunner(opts, defaultRuntime, prompter),
@@ -66,33 +61,19 @@ export const wizardHandlers: GatewayRequestHandlers = {
const sessionId = params.sessionId as string;
const session = context.wizardSessions.get(sessionId);
if (!session) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"));
return;
}
const answer = params.answer as
| { stepId?: string; value?: unknown }
| undefined;
const answer = params.answer as { stepId?: string; value?: unknown } | undefined;
if (answer) {
if (session.getStatus() !== "running") {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "wizard not running"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "wizard not running"));
return;
}
try {
await session.answer(String(answer.stepId ?? ""), answer.value);
} catch (err) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, formatForLog(err)),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, formatForLog(err)));
return;
}
}
@@ -117,11 +98,7 @@ export const wizardHandlers: GatewayRequestHandlers = {
const sessionId = params.sessionId as string;
const session = context.wizardSessions.get(sessionId);
if (!session) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"));
return;
}
session.cancel();
@@ -147,11 +124,7 @@ export const wizardHandlers: GatewayRequestHandlers = {
const sessionId = params.sessionId as string;
const session = context.wizardSessions.get(sessionId);
if (!session) {
respond(
false,
undefined,
errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"),
);
respond(false, undefined, errorShape(ErrorCodes.INVALID_REQUEST, "wizard not found"));
return;
}
const status = {