mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
chore(lint): enable no-useless-assignment
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
"eslint/no-useless-constructor": "error",
|
||||
"eslint/no-useless-rename": "error",
|
||||
"eslint/no-useless-return": "error",
|
||||
"eslint/no-useless-assignment": "error",
|
||||
"eslint/no-unused-vars": "error",
|
||||
"eslint/no-warning-comments": "error",
|
||||
"eslint/no-unmodified-loop-condition": "error",
|
||||
|
||||
@@ -302,7 +302,7 @@ export async function cleanupOpenClawOwnedAcpxProcessTree(params: {
|
||||
return { inspectedPids: [], terminatedPids: [], skippedReason: "missing-root" };
|
||||
}
|
||||
|
||||
let processes: AcpxProcessInfo[] = [];
|
||||
let processes: AcpxProcessInfo[];
|
||||
try {
|
||||
processes = await (params.deps?.listProcesses ?? listPlatformProcesses)();
|
||||
} catch {
|
||||
|
||||
@@ -1196,7 +1196,7 @@ export class AcpxRuntime implements AcpRuntime {
|
||||
const record = await this.sessionStore.load(
|
||||
input.handle.acpxRecordId ?? input.handle.sessionKey,
|
||||
);
|
||||
let closeSucceeded = false;
|
||||
let closeSucceeded;
|
||||
try {
|
||||
await this.resolveDelegateForLoadedRecord(input.handle, record).close({
|
||||
handle: input.handle,
|
||||
|
||||
@@ -137,7 +137,7 @@ async function diagnoseCdpHealthCommand(
|
||||
if (settled) {
|
||||
return;
|
||||
}
|
||||
let parsed: { id?: unknown; result?: unknown } | null = null;
|
||||
let parsed: { id?: unknown; result?: unknown } | null;
|
||||
try {
|
||||
parsed = JSON.parse(rawDataToString(raw)) as { id?: unknown; result?: unknown };
|
||||
} catch {
|
||||
|
||||
@@ -559,7 +559,7 @@ describe("browser chrome helpers", () => {
|
||||
onConnection: (wss) => {
|
||||
wss.on("connection", (ws) => {
|
||||
ws.on("message", (raw) => {
|
||||
let message: { id?: unknown; method?: unknown } | null = null;
|
||||
let message: { id?: unknown; method?: unknown } | null;
|
||||
try {
|
||||
const text =
|
||||
typeof raw === "string"
|
||||
|
||||
@@ -469,7 +469,7 @@ export function resolveProfile(
|
||||
const rawProfileUrl = profile.cdpUrl?.trim() ?? "";
|
||||
let cdpHost = resolved.cdpHost;
|
||||
let cdpPort = profile.cdpPort ?? 0;
|
||||
let cdpUrl = "";
|
||||
let cdpUrl;
|
||||
const driver = profile.driver === "existing-session" ? "existing-session" : "openclaw";
|
||||
const headless = profile.headless ?? resolved.headless;
|
||||
const headlessSource =
|
||||
|
||||
@@ -1066,7 +1066,7 @@ async function findPageByTargetId(
|
||||
const pages = await getAllPages(browser);
|
||||
let resolvedViaCdp = false;
|
||||
for (const page of pages) {
|
||||
let tid: string | null = null;
|
||||
let tid: string | null;
|
||||
try {
|
||||
tid = await pageTargetId(page);
|
||||
resolvedViaCdp = true;
|
||||
@@ -1170,7 +1170,7 @@ export async function getPageForTargetId(opts: {
|
||||
}
|
||||
|
||||
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
let sameMainFrame = false;
|
||||
let sameMainFrame;
|
||||
try {
|
||||
sameMainFrame = request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
@@ -1197,7 +1197,7 @@ function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
}
|
||||
|
||||
function isSubframeDocumentNavigationRequest(page: Page, request: Request): boolean {
|
||||
let sameMainFrame = false;
|
||||
let sameMainFrame;
|
||||
try {
|
||||
sameMainFrame = request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
|
||||
@@ -150,7 +150,7 @@ function formatDoctorLine(check: BrowserDoctorCheck): string {
|
||||
|
||||
async function runBrowserDoctor(parent: BrowserParentOpts, profile?: string, deep?: boolean) {
|
||||
const checks: BrowserDoctorCheck[] = [];
|
||||
let status: BrowserStatus | null = null;
|
||||
let status: BrowserStatus | null;
|
||||
|
||||
try {
|
||||
status = await fetchBrowserStatus(parent, profile);
|
||||
|
||||
@@ -171,7 +171,7 @@ export async function handleBrowserGatewayRequest({
|
||||
}
|
||||
|
||||
const cfg = getRuntimeConfig();
|
||||
let nodeTarget: NodeSession | null = null;
|
||||
let nodeTarget: NodeSession | null;
|
||||
try {
|
||||
nodeTarget = resolveBrowserNodeTarget({
|
||||
cfg,
|
||||
|
||||
@@ -388,7 +388,6 @@ describe("canvas host", () => {
|
||||
const linkName = `test-link-${Date.now()}-${Math.random().toString(16).slice(2)}.txt`;
|
||||
const linkPath = path.join(a2uiRoot, linkName);
|
||||
let createdBundle = false;
|
||||
let createdLink = false;
|
||||
|
||||
try {
|
||||
await fs.stat(bundlePath);
|
||||
@@ -398,7 +397,6 @@ describe("canvas host", () => {
|
||||
}
|
||||
|
||||
await fs.symlink(path.join(process.cwd(), "package.json"), linkPath);
|
||||
createdLink = true;
|
||||
|
||||
try {
|
||||
const res = await captureA2uiResponse(`${A2UI_PATH}/`);
|
||||
@@ -421,9 +419,7 @@ describe("canvas host", () => {
|
||||
expect(symlinkRes.status).toBe(404);
|
||||
expect(symlinkRes.body).toBe("not found");
|
||||
} finally {
|
||||
if (createdLink) {
|
||||
await fs.rm(linkPath, { force: true });
|
||||
}
|
||||
await fs.rm(linkPath, { force: true });
|
||||
if (createdBundle) {
|
||||
await fs.rm(bundlePath, { force: true });
|
||||
}
|
||||
|
||||
@@ -337,7 +337,6 @@ export async function startCodexAttemptThread(params: {
|
||||
if (startupClientForAbandonedRequestCleanup === failedClient) {
|
||||
startupClientForAbandonedRequestCleanup = undefined;
|
||||
}
|
||||
attemptedClient = undefined;
|
||||
if (attempt >= CODEX_APP_SERVER_STARTUP_CONNECTION_CLOSE_MAX_ATTEMPTS) {
|
||||
embeddedAgentLog.warn(
|
||||
"codex app-server connection closed during startup; retries exhausted",
|
||||
|
||||
@@ -965,8 +965,19 @@ export async function runCodexAppServerAttempt(
|
||||
let client: CodexAppServerClient;
|
||||
let thread: CodexAppServerThreadLifecycleBinding;
|
||||
let trajectoryEndRecorded = false;
|
||||
const markTrajectoryEndRecorded = () => {
|
||||
trajectoryEndRecorded = true;
|
||||
};
|
||||
let nativeHookRelay: NativeHookRelayRegistrationHandle | undefined;
|
||||
let releaseSharedClientLease: (() => void) | undefined;
|
||||
const releaseSharedClientLeaseOnce = () => {
|
||||
const release = releaseSharedClientLease;
|
||||
if (!release) {
|
||||
return;
|
||||
}
|
||||
releaseSharedClientLease = undefined;
|
||||
release();
|
||||
};
|
||||
let sandboxExecEnvironmentAcquired = false;
|
||||
const releaseSandboxExecEnvironment = async () => {
|
||||
if (sandboxExecEnvironmentAcquired) {
|
||||
@@ -1914,7 +1925,7 @@ export async function runCodexAppServerAttempt(
|
||||
aborted: runAbortController.signal.aborted,
|
||||
promptError: turnStartErrorMessage,
|
||||
});
|
||||
trajectoryEndRecorded = true;
|
||||
markTrajectoryEndRecorded();
|
||||
runAgentHarnessLlmOutputHook({
|
||||
event: {
|
||||
runId: params.runId,
|
||||
@@ -1979,8 +1990,7 @@ export async function runCodexAppServerAttempt(
|
||||
},
|
||||
});
|
||||
params.abortSignal?.removeEventListener("abort", abortFromUpstream);
|
||||
releaseSharedClientLease?.();
|
||||
releaseSharedClientLease = undefined;
|
||||
releaseSharedClientLeaseOnce();
|
||||
if (usageLimitError) {
|
||||
await markCodexAuthProfileBlockedFromRateLimits({
|
||||
params,
|
||||
@@ -2000,8 +2010,7 @@ export async function runCodexAppServerAttempt(
|
||||
}
|
||||
}
|
||||
if (!turn) {
|
||||
releaseSharedClientLease?.();
|
||||
releaseSharedClientLease = undefined;
|
||||
releaseSharedClientLeaseOnce();
|
||||
throw new Error("codex app-server turn/start failed without an error");
|
||||
}
|
||||
turnIdRef.current = turn.turn.id;
|
||||
@@ -2250,7 +2259,7 @@ export async function runCodexAppServerAttempt(
|
||||
yieldDetected,
|
||||
promptError: normalizeCodexTrajectoryError(finalPromptError),
|
||||
});
|
||||
trajectoryEndRecorded = true;
|
||||
markTrajectoryEndRecorded();
|
||||
await mirrorTranscriptBestEffort({
|
||||
params,
|
||||
agentId: sessionAgentId,
|
||||
@@ -2427,7 +2436,7 @@ export async function runCodexAppServerAttempt(
|
||||
notificationCleanup();
|
||||
requestCleanup();
|
||||
closeCleanup?.();
|
||||
releaseSharedClientLease?.();
|
||||
releaseSharedClientLeaseOnce();
|
||||
if (nativeHookRelay) {
|
||||
if (shouldDelayNativeHookRelayUnregister) {
|
||||
// Codex hook subprocesses can outlive a completed app-server turn by a
|
||||
|
||||
@@ -420,7 +420,7 @@ export function convertOpenClawToolToSdkTool(
|
||||
);
|
||||
}
|
||||
|
||||
let preparedArgs = args;
|
||||
let preparedArgs;
|
||||
try {
|
||||
preparedArgs = sourceTool.prepareArguments ? sourceTool.prepareArguments(args) : args;
|
||||
} catch (error: unknown) {
|
||||
|
||||
@@ -478,8 +478,8 @@ export function normalizeCompatibilityConfig({
|
||||
}
|
||||
|
||||
const changes: string[] = [];
|
||||
let updated = rawEntry;
|
||||
let changed = false;
|
||||
let updated;
|
||||
let changed;
|
||||
const bindingsToAdd: AgentBindingConfig[] = [];
|
||||
|
||||
const aliases = normalizeLegacyChannelAliases({
|
||||
|
||||
@@ -298,7 +298,7 @@ export function createDiscordAutoPresenceController(params: {
|
||||
let lastAppliedAt = 0;
|
||||
|
||||
const runEvaluation = (options?: { force?: boolean }) => {
|
||||
let decision: DiscordAutoPresenceDecision | null = null;
|
||||
let decision: DiscordAutoPresenceDecision | null;
|
||||
try {
|
||||
decision = resolveDiscordAutoPresenceDecision({
|
||||
discordConfig: params.discordConfig,
|
||||
|
||||
@@ -256,7 +256,7 @@ export function createDiscordDraftPreviewController(params: {
|
||||
);
|
||||
}
|
||||
const alreadyStarted = progressDraftGate.hasStarted;
|
||||
let progressActive = false;
|
||||
let progressActive;
|
||||
if (shouldStartDiscordProgressDraftNow(line)) {
|
||||
await progressDraftGate.startNow();
|
||||
progressActive = progressDraftGate.hasStarted;
|
||||
|
||||
@@ -146,7 +146,7 @@ function copyRuntimeMessageFields(source: Message, target: Message): void {
|
||||
}
|
||||
|
||||
function shouldHydrateDiscordMessage(params: { message: Message }) {
|
||||
let currentText = "";
|
||||
let currentText;
|
||||
try {
|
||||
currentText = resolveDiscordMessageText(params.message, {
|
||||
includeForwarded: true,
|
||||
|
||||
@@ -336,7 +336,7 @@ export function formatDiscordDeployErrorDetails(err: unknown): string {
|
||||
details.push(`code=${discordCode}`);
|
||||
}
|
||||
if (rawBody !== undefined) {
|
||||
let bodyText = "";
|
||||
let bodyText;
|
||||
try {
|
||||
bodyText = JSON.stringify(rawBody);
|
||||
} catch {
|
||||
|
||||
@@ -92,7 +92,7 @@ export function resolveFeishuGroupSession(params: {
|
||||
(replyInThread ? messageId : null))
|
||||
: null;
|
||||
|
||||
let peerId = chatId;
|
||||
let peerId;
|
||||
switch (groupSessionScope) {
|
||||
case "group_sender":
|
||||
peerId = buildFeishuConversationId({ chatId, scope: "group_sender", senderOpenId });
|
||||
|
||||
@@ -64,7 +64,7 @@ export const detectFeishuLegacyStateMigrations: BundledChannelLegacyStateMigrati
|
||||
stateDir,
|
||||
}) => {
|
||||
const dedupDir = path.join(stateDir, "feishu", "dedup");
|
||||
let entries: fs.Dirent[] = [];
|
||||
let entries: fs.Dirent[];
|
||||
try {
|
||||
entries = fs.readdirSync(dedupDir, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -400,7 +400,7 @@ function inspectSessionTranscript(params: {
|
||||
return null;
|
||||
}
|
||||
|
||||
let raw = "";
|
||||
let raw;
|
||||
try {
|
||||
raw = fs.readFileSync(params.transcriptPath, "utf-8");
|
||||
} catch {
|
||||
|
||||
@@ -474,7 +474,7 @@ export async function monitorSingleAccount(params: MonitorSingleAccountParams):
|
||||
log(`feishu[${accountId}]: dedup warmup loaded ${warmupCount} entries from disk`);
|
||||
}
|
||||
|
||||
let threadBindingManager: ReturnType<typeof createFeishuThreadBindingManager> | null = null;
|
||||
let threadBindingManager: ReturnType<typeof createFeishuThreadBindingManager> | null | undefined;
|
||||
try {
|
||||
const eventDispatcher = createEventDispatcher(account);
|
||||
const chatHistories = new Map<string, HistoryEntry[]>();
|
||||
|
||||
@@ -347,7 +347,7 @@ async function runNewAppFlow(params: {
|
||||
const targetAccountId = resolveDefaultFeishuAccountId(next);
|
||||
|
||||
// ----- QR scan flow -----
|
||||
let appId: string | null = null;
|
||||
let appId: string | null;
|
||||
let appSecret: SecretInput | null = null;
|
||||
let appSecretProbeValue: string | null = null;
|
||||
let scanDomain: FeishuDomain | undefined;
|
||||
@@ -366,7 +366,6 @@ async function runNewAppFlow(params: {
|
||||
if (scanResult) {
|
||||
appId = scanResult.appId;
|
||||
appSecret = scanResult.appSecret;
|
||||
appSecretProbeValue = scanResult.appSecret;
|
||||
scanDomain = scanResult.domain;
|
||||
scanOpenId = scanResult.openId;
|
||||
} else {
|
||||
|
||||
@@ -588,7 +588,7 @@ export function createDirFetchTool(): AnyAgentTool {
|
||||
throw new Error(`dir.fetch UNCOMPRESSED_TOO_LARGE: ${reason}`);
|
||||
};
|
||||
for (const { relPath, absPath } of walked) {
|
||||
let size = 0;
|
||||
let size;
|
||||
try {
|
||||
const st = await fs.stat(absPath);
|
||||
size = st.size;
|
||||
|
||||
@@ -531,7 +531,6 @@ export function buildGoogleVideoGenerationProvider(): VideoGenerationProvider {
|
||||
}
|
||||
let generatedVideos = extractGeneratedVideos(operation);
|
||||
if (generatedVideos.length === 0 && !hasReferenceInputs && !usedRestFallback) {
|
||||
usedRestFallback = true;
|
||||
operation = await generateGoogleVideoViaRest({
|
||||
baseUrl: restBaseUrl,
|
||||
headers: authHeaders,
|
||||
|
||||
@@ -128,7 +128,7 @@ export function normalizeCompatibilityConfig({
|
||||
|
||||
const changes: string[] = [];
|
||||
let updated = rawEntry;
|
||||
let changed = false;
|
||||
let changed;
|
||||
|
||||
const root = normalizeGoogleChatEntry({
|
||||
entry: updated,
|
||||
|
||||
@@ -313,7 +313,7 @@ async function readCredentialsFile(filePath: string): Promise<Record<string, unk
|
||||
throw new Error("Google Chat service account file path is empty");
|
||||
}
|
||||
|
||||
let handle: Awaited<ReturnType<typeof fs.open>> | null = null;
|
||||
let handle: Awaited<ReturnType<typeof fs.open>> | null;
|
||||
try {
|
||||
handle = await fs.open(resolvedPath, "r");
|
||||
} catch {
|
||||
|
||||
@@ -214,8 +214,8 @@ export function createGoogleChatWebhookRequestHandler(params: {
|
||||
inFlightLimiter: params.webhookInFlightLimiter,
|
||||
handle: async ({ targets }) => {
|
||||
const headerBearer = extractBearerToken(req.headers.authorization);
|
||||
let selectedTarget: WebhookTarget | null = null;
|
||||
let parsedEvent: GoogleChatEvent | null = null;
|
||||
let selectedTarget: WebhookTarget | null;
|
||||
let parsedEvent: GoogleChatEvent | null;
|
||||
const readAndParseEvent = async (
|
||||
profile: "pre-auth" | "post-auth",
|
||||
): Promise<ParsedGoogleChatInboundSuccess | null> => {
|
||||
|
||||
@@ -86,7 +86,7 @@ function readPersistedEntries(): {
|
||||
if (!line) {
|
||||
continue;
|
||||
}
|
||||
let parsed: Partial<IMessageReplyCacheEntry> | null = null;
|
||||
let parsed: Partial<IMessageReplyCacheEntry> | null;
|
||||
try {
|
||||
parsed = JSON.parse(line) as Partial<IMessageReplyCacheEntry>;
|
||||
} catch {
|
||||
|
||||
@@ -127,7 +127,7 @@ function isSshIMessageCliWrapper(cliPath: string): boolean {
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
let detected = false;
|
||||
let detected;
|
||||
try {
|
||||
const content = readFileSync(expandCliPathForInspection(cliPath), "utf8");
|
||||
detected = /\bssh\b[\s\S]*\bimsg\b/u.test(content);
|
||||
@@ -732,7 +732,7 @@ async function trySendAttachmentForTarget(params: {
|
||||
runCliJson: (args: readonly string[]) => Promise<Record<string, unknown>>;
|
||||
resolveMessageGuidImpl?: IMessageSendOpts["resolveMessageGuidImpl"];
|
||||
}): Promise<IMessageSendResult | null> {
|
||||
let attachmentChatTarget: string | null = null;
|
||||
let attachmentChatTarget: string | null;
|
||||
try {
|
||||
attachmentChatTarget = await resolveAttachmentChatTarget({
|
||||
target: params.target,
|
||||
|
||||
@@ -399,10 +399,7 @@ async function addMatrixAccount(params: {
|
||||
}
|
||||
}
|
||||
|
||||
let deviceHealth: MatrixCliAccountAddResult["deviceHealth"] = {
|
||||
currentDeviceId: null,
|
||||
staleOpenClawDeviceIds: [],
|
||||
};
|
||||
let deviceHealth: MatrixCliAccountAddResult["deviceHealth"];
|
||||
try {
|
||||
const addedDevices = await listMatrixOwnDevices({ accountId, cfg: updated });
|
||||
deviceHealth = {
|
||||
|
||||
@@ -215,7 +215,7 @@ function resolvePreferredMatrixStorageRoot(params: {
|
||||
};
|
||||
}
|
||||
|
||||
let siblingEntries: fs.Dirent[] = [];
|
||||
let siblingEntries: fs.Dirent[];
|
||||
try {
|
||||
siblingEntries = fs.readdirSync(parentDir, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -41,7 +41,7 @@ import {
|
||||
} from "../sync-state.js";
|
||||
import { createMatrixThreadBindingManager } from "../thread-bindings.js";
|
||||
import { registerMatrixAutoJoin } from "./auto-join.js";
|
||||
import { resolveMatrixMonitorConfig, type MatrixResolvedAllowlistEntry } from "./config.js";
|
||||
import { resolveMatrixMonitorConfig } from "./config.js";
|
||||
import { createDirectRoomTracker } from "./direct.js";
|
||||
import { registerMatrixMonitorEvents } from "./events.js";
|
||||
import { createMatrixRoomMessageHandler } from "./handler.js";
|
||||
@@ -168,31 +168,30 @@ export async function monitorMatrixProvider(opts: MonitorMatrixOpts = {}): Promi
|
||||
|
||||
const allowlistOnly = accountConfig.allowlistOnly === true;
|
||||
const accountAllowBots = accountConfig.allowBots;
|
||||
let allowFrom: string[] = (accountConfig.dm?.allowFrom ?? []).map(String);
|
||||
let groupAllowFrom: string[] = (accountConfig.groupAllowFrom ?? []).map(String);
|
||||
let allowFromResolvedEntries: MatrixResolvedAllowlistEntry[] = [];
|
||||
let groupAllowFromResolvedEntries: MatrixResolvedAllowlistEntry[] = [];
|
||||
let roomsConfig = accountConfig.groups ?? accountConfig.rooms;
|
||||
let needsRoomAliasesForConfig = false;
|
||||
const initialAllowFrom = (accountConfig.dm?.allowFrom ?? []).map(String);
|
||||
const initialGroupAllowFrom = (accountConfig.groupAllowFrom ?? []).map(String);
|
||||
const configuredBotUserIds = resolveConfiguredMatrixBotUserIds({
|
||||
cfg,
|
||||
accountId: effectiveAccountId,
|
||||
});
|
||||
|
||||
({
|
||||
const {
|
||||
allowFrom,
|
||||
allowFromResolvedEntries,
|
||||
groupAllowFrom,
|
||||
groupAllowFromResolvedEntries,
|
||||
roomsConfig,
|
||||
roomsConfig: resolvedRoomsConfig,
|
||||
} = await resolveMatrixMonitorConfig({
|
||||
cfg,
|
||||
accountId: effectiveAccountId,
|
||||
allowFrom,
|
||||
groupAllowFrom,
|
||||
allowFrom: initialAllowFrom,
|
||||
groupAllowFrom: initialGroupAllowFrom,
|
||||
roomsConfig,
|
||||
runtime,
|
||||
}));
|
||||
});
|
||||
roomsConfig = resolvedRoomsConfig;
|
||||
needsRoomAliasesForConfig = Boolean(
|
||||
roomsConfig && Object.keys(roomsConfig).some((key) => key.trim().startsWith("#")),
|
||||
);
|
||||
|
||||
@@ -64,7 +64,7 @@ async function resolvePendingMigrationStatePath(params: {
|
||||
}
|
||||
|
||||
const accountStorageDir = path.dirname(rootDir);
|
||||
let siblingEntries: string[] = [];
|
||||
let siblingEntries: string[];
|
||||
try {
|
||||
siblingEntries = (await fs.readdir(accountStorageDir, { withFileTypes: true }))
|
||||
.filter((entry) => entry.isDirectory())
|
||||
|
||||
@@ -1357,7 +1357,7 @@ export class MatrixClient {
|
||||
return await fail("Matrix recovery key is required");
|
||||
}
|
||||
|
||||
let stagedKeyId: string | null = null;
|
||||
let stagedKeyId: string | null;
|
||||
try {
|
||||
stagedKeyId = (await this.resolveDefaultSecretStorageKeyId(crypto)) ?? null;
|
||||
this.recoveryKeyStore.stageEncodedRecoveryKey({
|
||||
|
||||
@@ -655,7 +655,7 @@ export class MatrixVerificationManager {
|
||||
if (!crypto) {
|
||||
throw new Error("Matrix crypto is not available");
|
||||
}
|
||||
let request: MatrixVerificationRequestLike | null = null;
|
||||
let request: MatrixVerificationRequestLike | null;
|
||||
if (params.ownUser) {
|
||||
request = await crypto.requestOwnUserVerification();
|
||||
} else if (params.userId && params.deviceId && crypto.requestDeviceVerification) {
|
||||
|
||||
@@ -503,8 +503,8 @@ export function createMattermostInteractionHandler(params: {
|
||||
}
|
||||
|
||||
const userName = payload.user_name ?? payload.user_id;
|
||||
let originalMessage = "";
|
||||
let originalPost: MattermostPost | null = null;
|
||||
let originalMessage;
|
||||
let originalPost: MattermostPost | null;
|
||||
let clickedButtonName: string | null = null;
|
||||
try {
|
||||
originalPost = await client.request<MattermostPost>(`/posts/${payload.post_id}`);
|
||||
|
||||
@@ -33,16 +33,15 @@ export async function runWithReconnect(
|
||||
const { initialDelayMs = 2000, maxDelayMs = 60_000 } = opts;
|
||||
const jitterRatio = Math.max(0, opts.jitterRatio ?? 0);
|
||||
const random = opts.random ?? Math.random;
|
||||
let retryDelay = initialDelayMs;
|
||||
const backoff = createReconnectBackoff(initialDelayMs, maxDelayMs);
|
||||
let attempt = 0;
|
||||
|
||||
while (!opts.abortSignal?.aborted) {
|
||||
let shouldIncreaseDelay = false;
|
||||
let outcome: ReconnectOutcome = "resolved";
|
||||
let error: unknown;
|
||||
try {
|
||||
await connectFn();
|
||||
retryDelay = initialDelayMs;
|
||||
backoff.reset();
|
||||
} catch (err) {
|
||||
if (opts.abortSignal?.aborted) {
|
||||
return;
|
||||
@@ -50,12 +49,11 @@ export async function runWithReconnect(
|
||||
outcome = "rejected";
|
||||
error = err;
|
||||
opts.onError?.(err);
|
||||
shouldIncreaseDelay = true;
|
||||
}
|
||||
if (opts.abortSignal?.aborted) {
|
||||
return;
|
||||
}
|
||||
const delayMs = withJitter(retryDelay, jitterRatio, random);
|
||||
const delayMs = withJitter(backoff.current(), jitterRatio, random);
|
||||
const shouldReconnect =
|
||||
opts.shouldReconnect?.({
|
||||
attempt,
|
||||
@@ -68,13 +66,26 @@ export async function runWithReconnect(
|
||||
}
|
||||
opts.onReconnect?.(delayMs);
|
||||
await sleepAbortable(delayMs, opts.abortSignal);
|
||||
if (shouldIncreaseDelay) {
|
||||
retryDelay = Math.min(retryDelay * 2, maxDelayMs);
|
||||
if (outcome === "rejected") {
|
||||
backoff.increase();
|
||||
}
|
||||
attempt++;
|
||||
}
|
||||
}
|
||||
|
||||
function createReconnectBackoff(initialDelayMs: number, maxDelayMs: number) {
|
||||
let retryDelay = initialDelayMs;
|
||||
return {
|
||||
current: () => retryDelay,
|
||||
reset: () => {
|
||||
retryDelay = initialDelayMs;
|
||||
},
|
||||
increase: () => {
|
||||
retryDelay = Math.min(retryDelay * 2, maxDelayMs);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function withJitter(baseMs: number, jitterRatio: number, random: () => number): number {
|
||||
if (jitterRatio <= 0) {
|
||||
return baseMs;
|
||||
|
||||
@@ -261,7 +261,7 @@ export async function registerSlashCommands(params: {
|
||||
}
|
||||
|
||||
// Fetch existing commands to avoid duplicates
|
||||
let existing: MattermostCommandResponse[] = [];
|
||||
let existing: MattermostCommandResponse[];
|
||||
try {
|
||||
existing = await listMattermostCommands(client, teamId);
|
||||
} catch (err) {
|
||||
|
||||
@@ -555,7 +555,7 @@ async function scanMemoryFiles(
|
||||
}
|
||||
}
|
||||
|
||||
let dirReadable: boolean | null = null;
|
||||
let dirReadable: boolean | null;
|
||||
try {
|
||||
await fs.access(memoryDir, fsSync.constants.R_OK);
|
||||
dirReadable = true;
|
||||
@@ -587,7 +587,7 @@ async function scanMemoryFiles(
|
||||
}
|
||||
}
|
||||
|
||||
let totalFiles: number | null = 0;
|
||||
let totalFiles: number | null;
|
||||
if (dirReadable === null) {
|
||||
totalFiles = null;
|
||||
} else {
|
||||
|
||||
@@ -819,7 +819,7 @@ async function normalizeSessionEntryPathForComparison(params: {
|
||||
async function scrubDreamingNarrativeArtifacts(logger: Logger): Promise<void> {
|
||||
const cfg = getRuntimeConfig();
|
||||
const agentsDir = path.join(resolveStateDir(), "agents");
|
||||
let agentEntries: Dirent[] = [];
|
||||
let agentEntries: Dirent[];
|
||||
try {
|
||||
agentEntries = await fs.readdir(agentsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
@@ -894,7 +894,7 @@ async function scrubDreamingNarrativeArtifacts(logger: Logger): Promise<void> {
|
||||
});
|
||||
}
|
||||
|
||||
let sessionFiles: Dirent[] = [];
|
||||
let sessionFiles: Dirent[];
|
||||
try {
|
||||
sessionFiles = await fs.readdir(sessionsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
@@ -923,7 +923,7 @@ async function scrubDreamingNarrativeArtifacts(logger: Logger): Promise<void> {
|
||||
if (Date.now() - stat.mtimeMs < DREAMING_ORPHAN_MIN_AGE_MS) {
|
||||
continue;
|
||||
}
|
||||
let content = "";
|
||||
let content;
|
||||
try {
|
||||
content = await fs.readFile(transcriptPath, "utf-8");
|
||||
} catch {
|
||||
|
||||
@@ -884,7 +884,7 @@ describe("memory-core dreaming phases", () => {
|
||||
);
|
||||
|
||||
const readSpy = vi.spyOn(fs, "readFile");
|
||||
let transcriptReadCount = 0;
|
||||
let transcriptReadCount;
|
||||
try {
|
||||
await withDreamingTestClock(async () => {
|
||||
await triggerLightDreaming(beforeAgentReply, workspaceDir, 5);
|
||||
|
||||
@@ -504,7 +504,7 @@ describe("memory index", () => {
|
||||
managersForCleanup.add(first);
|
||||
await first.probeEmbeddingAvailability();
|
||||
const closePromise = closeMemoryIndexManagersForAgent({ cfg, agentId: "main" });
|
||||
let second: MemoryIndexManager | null = null;
|
||||
let second: MemoryIndexManager | null;
|
||||
try {
|
||||
await vi.waitFor(() => {
|
||||
expect(providerCloseCalls).toBe(1);
|
||||
|
||||
@@ -125,9 +125,9 @@ export async function runMemoryEmbeddingRetryLoop<T>(params: {
|
||||
maxAttempts: number;
|
||||
baseDelayMs: number;
|
||||
}): Promise<T> {
|
||||
let attempt = 1;
|
||||
let delayMs = params.baseDelayMs;
|
||||
while (true) {
|
||||
const attempts = Math.max(1, params.maxAttempts);
|
||||
for (const attempt of Array.from({ length: attempts }, (_, index) => index + 1)) {
|
||||
const delayMs = params.baseDelayMs * 2 ** (attempt - 1);
|
||||
try {
|
||||
return await params.run();
|
||||
} catch (err) {
|
||||
@@ -136,10 +136,9 @@ export async function runMemoryEmbeddingRetryLoop<T>(params: {
|
||||
throw err;
|
||||
}
|
||||
await params.waitForRetry(delayMs);
|
||||
delayMs *= 2;
|
||||
attempt += 1;
|
||||
}
|
||||
}
|
||||
throw new Error("retry loop exhausted");
|
||||
}
|
||||
|
||||
export async function runMemoryEmbeddingBatchRetryWithSplit<TInput, TOutput>(params: {
|
||||
|
||||
@@ -282,7 +282,7 @@ export abstract class MemoryManagerSyncOps {
|
||||
`sqlite-vec load timed out after ${Math.round(VECTOR_LOAD_TIMEOUT_MS / 1000)}s`,
|
||||
);
|
||||
}
|
||||
let ready = false;
|
||||
let ready;
|
||||
try {
|
||||
ready = (await this.vectorReady) || false;
|
||||
} catch (err) {
|
||||
@@ -1667,7 +1667,7 @@ export abstract class MemoryManagerSyncOps {
|
||||
this.fts.loadError = undefined;
|
||||
this.ensureSchema();
|
||||
|
||||
let nextMeta: MemoryIndexMeta | null = null;
|
||||
let nextMeta: MemoryIndexMeta | null;
|
||||
|
||||
try {
|
||||
nextMeta = await runMemoryAtomicReindex({
|
||||
|
||||
@@ -2444,7 +2444,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
return cached;
|
||||
}
|
||||
const db = this.ensureDb();
|
||||
let rows: Array<{ collection: string; path: string }> = [];
|
||||
let rows: Array<{ collection: string; path: string }>;
|
||||
try {
|
||||
rows = db
|
||||
.prepare("SELECT collection, path FROM documents WHERE hash = ? AND active = 1")
|
||||
@@ -2506,7 +2506,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
return null;
|
||||
}
|
||||
const exactPath = path.normalize(trimmedFile).replace(/\\/g, "/");
|
||||
let rows: Array<{ path: string }> = [];
|
||||
let rows: Array<{ path: string }>;
|
||||
try {
|
||||
const db = this.ensureDb();
|
||||
const exactRows = db
|
||||
|
||||
@@ -82,7 +82,7 @@ function createSkippedRemPreview(): RemDreamingPreview {
|
||||
|
||||
async function listWorkspaceDailyFiles(workspaceDir: string, limit?: number): Promise<string[]> {
|
||||
const memoryDir = path.join(workspaceDir, "memory");
|
||||
let entries: string[] = [];
|
||||
let entries: string[];
|
||||
try {
|
||||
const dirEntries = await fs.readdir(memoryDir, { withFileTypes: true });
|
||||
entries = dirEntries
|
||||
|
||||
@@ -587,7 +587,7 @@ describe("short-term promotion", () => {
|
||||
it("lets repeated dreaming-only daily signals clear the default promotion gates", async () => {
|
||||
await withTempWorkspace(async (workspaceDir) => {
|
||||
const queryDays = ["2026-04-01", "2026-04-02", "2026-04-03"];
|
||||
let candidateKey = "";
|
||||
let candidateKey;
|
||||
|
||||
for (const [index, day] of queryDays.entries()) {
|
||||
const nowMs = Date.parse(`${day}T10:00:00.000Z`);
|
||||
|
||||
@@ -225,14 +225,13 @@ export async function syncMemoryWikiBridgeSources(params: {
|
||||
const publicArtifacts = await listActiveMemoryPublicArtifacts({ cfg: params.appConfig });
|
||||
const state = await readMemoryWikiSourceSyncState(params.config.vault.path);
|
||||
const results: Array<{ pagePath: string; changed: boolean; created: boolean }> = [];
|
||||
let artifactCount = 0;
|
||||
const activeKeys = new Set<string>();
|
||||
const artifacts = await collectBridgeArtifacts(params.config.bridge, publicArtifacts);
|
||||
const agentIdsByWorkspace = new Map<string, string[]>();
|
||||
for (const artifact of publicArtifacts) {
|
||||
agentIdsByWorkspace.set(artifact.workspaceDir, artifact.agentIds);
|
||||
}
|
||||
artifactCount = artifacts.length;
|
||||
const artifactCount = artifacts.length;
|
||||
for (const artifact of artifacts) {
|
||||
const stats = await fs.stat(artifact.absolutePath);
|
||||
activeKeys.add(artifact.syncKey);
|
||||
|
||||
@@ -52,7 +52,7 @@ export const entraIdAuthMethod: ProviderAuthMethod = {
|
||||
);
|
||||
}
|
||||
|
||||
let account = getLoggedInAccount();
|
||||
const account = getLoggedInAccount();
|
||||
let tenantId = account?.tenantId;
|
||||
if (account) {
|
||||
const useExisting = await ctx.prompter.confirm({
|
||||
@@ -61,7 +61,6 @@ export const entraIdAuthMethod: ProviderAuthMethod = {
|
||||
});
|
||||
if (!useExisting) {
|
||||
const loginResult = await loginWithTenantFallback(ctx);
|
||||
account = loginResult.account;
|
||||
tenantId = loginResult.tenantId ?? loginResult.account?.tenantId;
|
||||
}
|
||||
} else {
|
||||
@@ -70,7 +69,6 @@ export const entraIdAuthMethod: ProviderAuthMethod = {
|
||||
"Azure Login",
|
||||
);
|
||||
const loginResult = await loginWithTenantFallback(ctx);
|
||||
account = loginResult.account;
|
||||
tenantId = loginResult.tenantId ?? loginResult.account?.tenantId;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ async function listLegacyLearningFiles(
|
||||
): Promise<
|
||||
Array<{ storePath: string; sessionKey: string | null; filePath: string; learnings: string[] }>
|
||||
> {
|
||||
let entries: Dirent[] = [];
|
||||
let entries: Dirent[];
|
||||
try {
|
||||
entries = await fs.readdir(storePath, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -442,8 +442,10 @@ export async function sendMSTeamsMessages(params: {
|
||||
return await sendOnce();
|
||||
}
|
||||
|
||||
let attempt = 1;
|
||||
while (true) {
|
||||
for (const attempt of Array.from(
|
||||
{ length: retryOptions.maxAttempts },
|
||||
(_, index) => index + 1,
|
||||
)) {
|
||||
try {
|
||||
return await sendOnce();
|
||||
} catch (err) {
|
||||
@@ -465,9 +467,9 @@ export async function sendMSTeamsMessages(params: {
|
||||
});
|
||||
|
||||
await sleep(delayMs);
|
||||
attempt = nextAttempt;
|
||||
}
|
||||
}
|
||||
throw new Error("unreachable Teams send retry loop exit");
|
||||
};
|
||||
|
||||
const sendMessageInContext = async (
|
||||
|
||||
@@ -195,7 +195,7 @@ describeLive("music generation provider live", () => {
|
||||
requireProfileKeys: REQUIRE_PROFILE_KEYS,
|
||||
hasLiveKeys,
|
||||
});
|
||||
let authLabel = "unresolved";
|
||||
let authLabel;
|
||||
try {
|
||||
const auth = await resolveApiKeyForProvider({
|
||||
provider: testCase.providerId,
|
||||
|
||||
@@ -100,7 +100,7 @@ async function listLegacyFiles(params: {
|
||||
parse: (value: unknown) => unknown;
|
||||
}): Promise<Array<{ accountId: string; filePath: string; value: unknown }>> {
|
||||
const dir = path.join(params.stateDir, "nostr");
|
||||
let entries: Dirent[] = [];
|
||||
let entries: Dirent[];
|
||||
try {
|
||||
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -188,7 +188,6 @@ async function readOpenRouterAudioStream(
|
||||
buffer = lines.pop() ?? "";
|
||||
for (const line of lines) {
|
||||
if (processOpenRouterSseLine(line.trim(), result)) {
|
||||
doneSeen = true;
|
||||
await reader.cancel();
|
||||
return {
|
||||
audioBuffer: Buffer.concat(result.audioBuffers),
|
||||
|
||||
@@ -322,7 +322,7 @@ async function runBackendExec(params: {
|
||||
env: {},
|
||||
usePty: false,
|
||||
});
|
||||
let result: ExecResult | null = null;
|
||||
let result: ExecResult | null | undefined;
|
||||
try {
|
||||
result = await runCommand({
|
||||
command: execSpec.argv[0] ?? "ssh",
|
||||
@@ -372,7 +372,7 @@ describe("openshell sandbox backend e2e", () => {
|
||||
const scopeKey = `session:openshell-e2e-deny:${scopeSuffix}`;
|
||||
const allowSandboxName = `openclaw-policy-allow-${scopeSuffix}`;
|
||||
const gatewayPort = await allocatePort();
|
||||
let hostPolicyServer: HostPolicyServer | null = null;
|
||||
let hostPolicyServer: HostPolicyServer | null | undefined;
|
||||
const sandboxCfg = {
|
||||
mode: "all" as const,
|
||||
backend: "openshell" as const,
|
||||
|
||||
@@ -623,8 +623,10 @@ async function restartWhatsAppQaDriverSession(params: {
|
||||
}
|
||||
|
||||
async function startWhatsAppQaDriverSessionWithRetry(params: { authDir: string }) {
|
||||
let attempt = 1;
|
||||
while (true) {
|
||||
for (const attempt of Array.from(
|
||||
{ length: WHATSAPP_QA_TRANSIENT_DRIVER_ATTEMPTS },
|
||||
(_, index) => index + 1,
|
||||
)) {
|
||||
try {
|
||||
return await startWhatsAppQaDriverSession({ authDir: params.authDir });
|
||||
} catch (error) {
|
||||
@@ -634,10 +636,10 @@ async function startWhatsAppQaDriverSessionWithRetry(params: { authDir: string }
|
||||
) {
|
||||
throw error;
|
||||
}
|
||||
attempt += 1;
|
||||
await new Promise((resolve) => setTimeout(resolve, WHATSAPP_QA_DRIVER_RECONNECT_DELAY_MS));
|
||||
}
|
||||
}
|
||||
throw new Error("unreachable WhatsApp QA driver retry loop exit");
|
||||
}
|
||||
|
||||
function formatApprovalResultValue(value: unknown) {
|
||||
|
||||
@@ -40,7 +40,7 @@ export async function resolveQaNodeExecPath(params?: {
|
||||
|
||||
const locator = platform === "win32" ? "where" : "which";
|
||||
const execFileImpl = params?.execFileImpl ?? execFileAsync;
|
||||
let stdout = "";
|
||||
let stdout;
|
||||
try {
|
||||
({ stdout } = await execFileImpl(locator, ["node"], {
|
||||
encoding: "utf8",
|
||||
|
||||
@@ -3187,7 +3187,7 @@ export async function startQaMockOpenAiServer(params?: { host?: string; port?: n
|
||||
}
|
||||
if (req.method === "POST" && url.pathname === "/v1/messages") {
|
||||
const raw = await readBody(req);
|
||||
let body: AnthropicMessagesRequest = {};
|
||||
let body: AnthropicMessagesRequest;
|
||||
try {
|
||||
body = raw ? (JSON.parse(raw) as AnthropicMessagesRequest) : {};
|
||||
} catch {
|
||||
|
||||
@@ -704,7 +704,7 @@ export async function runMatrixQaLive(params: {
|
||||
const syncState: { driver?: string; observer?: string } = {};
|
||||
const syncStreams: MatrixQaSyncStreams = {};
|
||||
let canaryMs: number | undefined;
|
||||
let initialGatewayBootMs = 0;
|
||||
let initialGatewayBootMs;
|
||||
let scenarioGatewayBootMs = 0;
|
||||
let scenarioRestartGatewayMs = 0;
|
||||
let scenarioTransportInterruptMs = 0;
|
||||
|
||||
@@ -1239,7 +1239,7 @@ async function withMatrixQaIsolatedE2eeDriverRoom<T>(
|
||||
);
|
||||
};
|
||||
|
||||
let patchedGateway = false;
|
||||
let patchedGateway;
|
||||
let client: MatrixQaE2eeScenarioClient | undefined;
|
||||
try {
|
||||
await applyPatch({
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function requestMatrixJson<T>(params: {
|
||||
...(params.body !== undefined ? { body: JSON.stringify(params.body) } : {}),
|
||||
signal: AbortSignal.timeout(resolveTimerTimeoutMs(params.timeoutMs, 20_000)),
|
||||
});
|
||||
let body: unknown = {};
|
||||
let body: unknown;
|
||||
try {
|
||||
body = (await response.json()) as unknown;
|
||||
} catch {
|
||||
|
||||
@@ -142,8 +142,8 @@ export function resolveAccountBase(
|
||||
const resolvedAccountId = accountId ?? resolveDefaultAccountId(cfg);
|
||||
const qqbot = readQQBotSection(cfg);
|
||||
|
||||
let accountConfig: Record<string, unknown> = {};
|
||||
let appId = "";
|
||||
let accountConfig: Record<string, unknown>;
|
||||
let appId;
|
||||
|
||||
if (resolvedAccountId === DEFAULT_ACCOUNT_ID) {
|
||||
accountConfig = normalizeAccountConfig(asRecord(qqbot));
|
||||
|
||||
@@ -554,7 +554,7 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
|
||||
return;
|
||||
}
|
||||
|
||||
let payload: SignalReceivePayload | null = null;
|
||||
let payload: SignalReceivePayload | null;
|
||||
try {
|
||||
payload = JSON.parse(event.data) as SignalReceivePayload;
|
||||
} catch (err) {
|
||||
|
||||
@@ -99,8 +99,8 @@ export function normalizeCompatibilityConfig({
|
||||
}
|
||||
|
||||
const changes: string[] = [];
|
||||
let updated = rawEntry;
|
||||
let changed = false;
|
||||
let updated;
|
||||
let changed;
|
||||
|
||||
const aliases = normalizeLegacyChannelAliases({
|
||||
entry: rawEntry,
|
||||
|
||||
@@ -187,7 +187,7 @@ export async function resolveSlackEffectiveAllowFrom(
|
||||
if (options?.includePairingStore !== true) {
|
||||
return base;
|
||||
}
|
||||
let storeAllowFrom: string[] = [];
|
||||
let storeAllowFrom: string[];
|
||||
try {
|
||||
const resolved = await readChannelIngressStoreAllowFromForDmPolicy({
|
||||
provider: "slack",
|
||||
|
||||
@@ -39,7 +39,7 @@ function pruneSlackExternalArgMenuStore(
|
||||
}
|
||||
|
||||
function createSlackExternalArgMenuToken(store: Map<string, SlackExternalArgMenuEntry>): string {
|
||||
let token = "";
|
||||
let token;
|
||||
do {
|
||||
token = generateSecureToken(SLACK_EXTERNAL_ARG_MENU_TOKEN_BYTES);
|
||||
} while (store.has(token));
|
||||
|
||||
@@ -1405,7 +1405,7 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
||||
return session;
|
||||
})();
|
||||
nativeProgressStreamStartPromise = startPromise;
|
||||
let startedSession: SlackStreamSession | null = null;
|
||||
let startedSession: SlackStreamSession | null;
|
||||
try {
|
||||
startedSession = await startPromise;
|
||||
} finally {
|
||||
|
||||
@@ -276,7 +276,7 @@ function delaySlackDnsRetry(attempt: number): Promise<void> {
|
||||
}
|
||||
|
||||
async function withSlackDnsRequestRetry<T>(operation: string, fn: () => Promise<T>): Promise<T> {
|
||||
for (let attempt = 0; ; attempt += 1) {
|
||||
for (const attempt of Array.from({ length: SLACK_DNS_RETRY_ATTEMPTS + 1 }, (_, index) => index)) {
|
||||
try {
|
||||
return await fn();
|
||||
} catch (err) {
|
||||
@@ -289,6 +289,7 @@ async function withSlackDnsRequestRetry<T>(operation: string, fn: () => Promise<
|
||||
await delaySlackDnsRetry(attempt + 1);
|
||||
}
|
||||
}
|
||||
throw new Error("unreachable Slack DNS retry loop exit");
|
||||
}
|
||||
|
||||
function isSlackCustomizeScopeError(err: unknown): boolean {
|
||||
|
||||
@@ -100,7 +100,7 @@ type ProbeOptions = {
|
||||
};
|
||||
|
||||
function addTailscaleHint(account: ResolvedSmsAccount, hints: string[]): void {
|
||||
let host = "";
|
||||
let host;
|
||||
try {
|
||||
host = new URL(account.publicWebhookUrl).hostname;
|
||||
} catch {
|
||||
|
||||
@@ -276,7 +276,7 @@ function extractTokenFromHeaders(req: IncomingMessage): string | undefined {
|
||||
function parsePayload(req: IncomingMessage, body: string): SynologyWebhookPayload | null {
|
||||
const contentType = normalizeLowercaseStringOrEmpty(req.headers["content-type"]);
|
||||
|
||||
let bodyFields: Record<string, unknown> = {};
|
||||
let bodyFields: Record<string, unknown>;
|
||||
if (contentType.includes("application/json")) {
|
||||
bodyFields = parseJsonBody(body);
|
||||
} else if (contentType.includes("application/x-www-form-urlencoded")) {
|
||||
@@ -390,7 +390,7 @@ async function parseWebhookPayloadRequest(params: {
|
||||
return { ok: false };
|
||||
}
|
||||
|
||||
let payload: SynologyWebhookPayload | null = null;
|
||||
let payload: SynologyWebhookPayload | null;
|
||||
try {
|
||||
payload = parsePayload(params.req, bodyResult.body);
|
||||
} catch (err) {
|
||||
|
||||
@@ -210,12 +210,12 @@ export function createTelegramBotCore(
|
||||
if (!begin.accepted) {
|
||||
return;
|
||||
}
|
||||
let completed = false;
|
||||
try {
|
||||
await next();
|
||||
completed = true;
|
||||
} finally {
|
||||
updateTracker.finishUpdate(begin.update, { completed });
|
||||
updateTracker.finishUpdate(begin.update, { completed: true });
|
||||
} catch (error) {
|
||||
updateTracker.finishUpdate(begin.update, { completed: false });
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1850,7 +1850,7 @@ export const registerTelegramHandlers = ({
|
||||
return;
|
||||
}
|
||||
|
||||
let media: Awaited<ReturnType<typeof resolveMedia>> = null;
|
||||
let media: Awaited<ReturnType<typeof resolveMedia>>;
|
||||
try {
|
||||
media = await resolveMedia({
|
||||
ctx,
|
||||
|
||||
@@ -782,7 +782,7 @@ export const dispatchTelegramMessage = async ({
|
||||
let replyFenceGeneration: number | undefined;
|
||||
const replyAbortController = new AbortController();
|
||||
let replyAbortControllerQueued = false;
|
||||
let dispatchWasSuperseded = false;
|
||||
let dispatchWasSuperseded;
|
||||
const isDispatchSuperseded = () =>
|
||||
replyFenceGeneration !== undefined &&
|
||||
isTelegramReplyFenceSuperseded({
|
||||
|
||||
@@ -602,7 +602,7 @@ export function describeReplyTarget(msg: Message): TelegramReplyTarget | null {
|
||||
msg.quote ?? (externalReply as (Message & { quote?: Message["quote"] }) | undefined)?.quote;
|
||||
const rawQuoteText = quote?.text;
|
||||
const quoteText = resolveTelegramTextContent(rawQuoteText);
|
||||
let body = "";
|
||||
let body;
|
||||
let kind: TelegramReplyTarget["kind"] = "reply";
|
||||
const filteredQuoteText = hadUnsafeTelegramText(rawQuoteText, quoteText);
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ function listTelegramLegacySidecarAccountIds(params: {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
}): string[] {
|
||||
let persistedAccountIds: string[] = [];
|
||||
let persistedAccountIds: string[];
|
||||
try {
|
||||
persistedAccountIds = fs
|
||||
.readdirSync(path.join(params.stateDir, "telegram"), { withFileTypes: true })
|
||||
|
||||
@@ -92,7 +92,10 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
|
||||
|
||||
// Helper to authenticate with retry logic
|
||||
async function authenticateWithRetry(maxAttempts = 10): Promise<string> {
|
||||
for (let attempt = 1; ; attempt++) {
|
||||
for (const attempt of Array.from(
|
||||
{ length: Math.max(1, maxAttempts) },
|
||||
(_, index) => index + 1,
|
||||
)) {
|
||||
if (opts.abortSignal?.aborted) {
|
||||
throw new Error("Aborted while waiting to authenticate");
|
||||
}
|
||||
@@ -120,6 +123,7 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
|
||||
});
|
||||
}
|
||||
}
|
||||
throw new Error("unreachable Tlon authentication retry loop exit");
|
||||
}
|
||||
|
||||
let api: UrbitSSEClient | null = null;
|
||||
|
||||
@@ -401,7 +401,7 @@ async function runLiveVideoProviderCase(testCase: LiveProviderCase): Promise<voi
|
||||
requireProfileKeys: REQUIRE_PROFILE_KEYS,
|
||||
hasLiveKeys,
|
||||
});
|
||||
let authLabel = "unresolved";
|
||||
let authLabel;
|
||||
try {
|
||||
const auth = await resolveApiKeyForProvider({
|
||||
provider: testCase.providerId,
|
||||
@@ -436,7 +436,6 @@ async function runLiveVideoProviderCase(testCase: LiveProviderCase): Promise<voi
|
||||
});
|
||||
const liveSize = testCase.providerId === "openai" ? "1280x720" : undefined;
|
||||
const logPrefix = `[live:video-generation] provider=${testCase.providerId} model=${providerModel}`;
|
||||
let generatedVideo: LiveGeneratedVideo | null = null;
|
||||
|
||||
const generateAttempt = await runLiveVideoAttempt({
|
||||
authLabel,
|
||||
@@ -464,7 +463,7 @@ async function runLiveVideoProviderCase(testCase: LiveProviderCase): Promise<voi
|
||||
expectLiveVideoCasePassed(summaryParams);
|
||||
return;
|
||||
}
|
||||
generatedVideo = generateAttempt.video;
|
||||
const generatedVideo = generateAttempt.video;
|
||||
|
||||
if (!RUN_FULL_VIDEO_MODES) {
|
||||
expectLiveVideoCasePassed(summaryParams);
|
||||
|
||||
@@ -129,7 +129,7 @@ async function readLegacyCallRecords(filePath: string): Promise<{
|
||||
entries: PreparedLegacyCallRecord[];
|
||||
warnings: string[];
|
||||
}> {
|
||||
let content = "";
|
||||
let content;
|
||||
try {
|
||||
content = await fs.readFile(filePath, "utf8");
|
||||
} catch {
|
||||
|
||||
@@ -237,23 +237,21 @@ export class TwilioProvider implements VoiceCallProvider {
|
||||
twiml: string,
|
||||
operation: string,
|
||||
): Promise<void> {
|
||||
let retryIndex = 0;
|
||||
while (true) {
|
||||
for (const retryDelayMs of TWILIO_CALL_UPDATE_RETRY_DELAYS_MS) {
|
||||
try {
|
||||
await this.apiRequest(`/Calls/${providerCallId}.json`, { Twiml: twiml });
|
||||
return;
|
||||
} catch (err) {
|
||||
const retryDelayMs = TWILIO_CALL_UPDATE_RETRY_DELAYS_MS[retryIndex];
|
||||
if (retryDelayMs === undefined || !isTwilioCallNotInProgressError(err)) {
|
||||
if (!isTwilioCallNotInProgressError(err)) {
|
||||
throw err;
|
||||
}
|
||||
retryIndex += 1;
|
||||
console.warn(
|
||||
`[voice-call] Twilio ${operation} update hit call state race (21220); retrying in ${retryDelayMs}ms`,
|
||||
);
|
||||
await sleep(retryDelayMs);
|
||||
}
|
||||
}
|
||||
await this.apiRequest(`/Calls/${providerCallId}.json`, { Twiml: twiml });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -124,7 +124,7 @@ export class RealtimeAudioPacer {
|
||||
}
|
||||
|
||||
let delayMs = 0;
|
||||
let sent = true;
|
||||
let sent;
|
||||
if (item.type === "audio") {
|
||||
this.queuedAudioBytes = Math.max(0, this.queuedAudioBytes - item.chunk.length);
|
||||
sent = this.params.send(this.params.serializer.media(item.chunk.toString("base64")));
|
||||
|
||||
@@ -245,7 +245,6 @@ async function runLoop(
|
||||
currentContext.messages.push(message);
|
||||
newMessages.push(message);
|
||||
}
|
||||
pendingMessages = [];
|
||||
}
|
||||
|
||||
// Stream assistant response
|
||||
|
||||
@@ -725,7 +725,7 @@ export const listCredentialSets = internalQuery({
|
||||
);
|
||||
}
|
||||
|
||||
let rows: CredentialSetRecord[] = [];
|
||||
let rows: CredentialSetRecord[];
|
||||
const kind = args.kind?.trim();
|
||||
if (kind) {
|
||||
if (normalizedStatus === "all") {
|
||||
|
||||
@@ -265,7 +265,7 @@ function extractProxyCapture(rawBody: string, req: http.IncomingMessage): ProxyC
|
||||
let parsed: {
|
||||
system?: Array<{ text?: string }>;
|
||||
messages?: Array<{ role?: string; content?: unknown }>;
|
||||
} | null = null;
|
||||
} | null;
|
||||
try {
|
||||
parsed = JSON.parse(rawBody) as typeof parsed;
|
||||
} catch {
|
||||
|
||||
@@ -125,7 +125,7 @@ async function walkAllCodeFiles(rootDir, options = {}) {
|
||||
const includeTests = options.includeTests === true;
|
||||
|
||||
async function walk(dir) {
|
||||
let entries = [];
|
||||
let entries;
|
||||
try {
|
||||
entries = await fs.readdir(dir, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -26,7 +26,7 @@ export function collectFilesSync(
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
let entries: fs.Dirent[] = [];
|
||||
let entries: fs.Dirent[];
|
||||
try {
|
||||
entries = fs.readdirSync(current, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -53,7 +53,7 @@ function collectSharedExtensionSourceFiles(): string[] {
|
||||
|
||||
function collectBundledExtensionSourceFiles(): string[] {
|
||||
const extensionsDir = path.join(process.cwd(), "extensions");
|
||||
let entries: fs.Dirent[] = [];
|
||||
let entries: fs.Dirent[];
|
||||
try {
|
||||
entries = fs.readdirSync(extensionsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
@@ -93,7 +93,7 @@ function main() {
|
||||
const legacyCompatOffenders: string[] = [];
|
||||
const legacyBroadSubpathOffenders = new Map<string, string[]>();
|
||||
for (const entryFile of filesToCheck) {
|
||||
let content = "";
|
||||
let content;
|
||||
try {
|
||||
content = fs.readFileSync(entryFile, "utf8");
|
||||
} catch {
|
||||
|
||||
@@ -20,7 +20,7 @@ function collectFilesSync(rootDir, options) {
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
let entries = [];
|
||||
let entries;
|
||||
try {
|
||||
entries = fs.readdirSync(current, { withFileTypes: true });
|
||||
} catch {
|
||||
|
||||
@@ -877,7 +877,7 @@ async function syncControlUiRawCopyBaseline(options: { checkOnly: boolean; write
|
||||
await writeFile(RAW_COPY_BASELINE_PATH, expected, "utf8");
|
||||
}
|
||||
if (options.checkOnly && current !== expected) {
|
||||
let currentEntries: RawCopyBaselineEntry[] = [];
|
||||
let currentEntries: RawCopyBaselineEntry[];
|
||||
try {
|
||||
const parsed = JSON.parse(current) as Partial<RawCopyBaseline>;
|
||||
currentEntries = Array.isArray(parsed.entries) ? parsed.entries : [];
|
||||
|
||||
@@ -2025,10 +2025,9 @@ let childCwd = repoRoot;
|
||||
let cleanupChildCwd = () => {};
|
||||
let cleanupDone = false;
|
||||
let remoteChangedGateBase = "";
|
||||
let scriptStdinPrepared = false;
|
||||
const scriptBootstrap = prepareAwsMacosScriptStdinBootstrap(normalizedArgs, provider);
|
||||
normalizedArgs = scriptBootstrap.args;
|
||||
scriptStdinPrepared = scriptBootstrap.prepared;
|
||||
const scriptStdinPrepared = scriptBootstrap.prepared;
|
||||
try {
|
||||
if (shouldUseFullCheckoutForCleanSparseRemoteSync(normalizedArgs, provider)) {
|
||||
const runWords = runCommandArgs(normalizedArgs);
|
||||
|
||||
@@ -761,10 +761,10 @@ async function run(): Promise<SuccessResult | FailureResult> {
|
||||
});
|
||||
|
||||
let readAuthHeader = "";
|
||||
let sentMessageId = "";
|
||||
let sentMessageId;
|
||||
let setupStage: "discord-api" | "send-message" = "discord-api";
|
||||
let senderAuthorId: string | undefined;
|
||||
let minBindingBoundAt = startedAt - 3_000;
|
||||
let minBindingBoundAt;
|
||||
let webhookForCleanup: WebhookForCleanup | undefined;
|
||||
|
||||
try {
|
||||
|
||||
@@ -124,7 +124,7 @@ export function createGatewayWsClient(params: {
|
||||
|
||||
ws.on("message", (data) => {
|
||||
const text = toText(data);
|
||||
let frame: GatewayFrame | null = null;
|
||||
let frame: GatewayFrame | null;
|
||||
try {
|
||||
frame = JSON.parse(text) as GatewayFrame;
|
||||
} catch {
|
||||
|
||||
@@ -542,7 +542,7 @@ function rewriteClawHubMarkdownLinkTarget(rawTarget, relativeSourceDir, source)
|
||||
return rawTarget;
|
||||
}
|
||||
|
||||
let normalizedRelative = "";
|
||||
let normalizedRelative;
|
||||
if (pathPart.startsWith("docs/")) {
|
||||
normalizedRelative = normalizeSlashes(pathPart.slice("docs/".length));
|
||||
} else if (
|
||||
|
||||
@@ -123,7 +123,7 @@ if (toolCall?.type !== "function" || toolCall?.function?.name !== "get_weather")
|
||||
throw new Error(`unexpected tool call: ${JSON.stringify(toolCall)}`);
|
||||
}
|
||||
|
||||
let args = {};
|
||||
let args;
|
||||
try {
|
||||
args = JSON.parse(toolCall.function.arguments || "{}");
|
||||
} catch {
|
||||
|
||||
@@ -97,7 +97,7 @@ const server = http.createServer((req, res) => {
|
||||
}
|
||||
|
||||
const bodyText = await readBody(req);
|
||||
let body = {};
|
||||
let body;
|
||||
try {
|
||||
body = bodyText ? JSON.parse(bodyText) : {};
|
||||
} catch {
|
||||
|
||||
@@ -305,7 +305,7 @@ const server = http.createServer((req, res) => {
|
||||
`${JSON.stringify({ method: req.method, path: url.pathname, body: bodyText })}\n`,
|
||||
);
|
||||
}
|
||||
let body = {};
|
||||
let body;
|
||||
try {
|
||||
body = bodyText ? JSON.parse(bodyText) : {};
|
||||
} catch {
|
||||
|
||||
@@ -198,7 +198,8 @@ async function acquirePackageLock(lockDir: string, ownerToken: string): Promise<
|
||||
const timeoutMs = readPositiveIntEnv("OPENCLAW_PARALLELS_PACKAGE_LOCK_TIMEOUT_MS", 30 * 60_000);
|
||||
const staleMs = readPositiveIntEnv("OPENCLAW_PARALLELS_PACKAGE_LOCK_STALE_MS", 2 * 60 * 60_000);
|
||||
const startedAt = Date.now();
|
||||
let announcedWait = false;
|
||||
let waitAnnouncementBudget = 1;
|
||||
const consumeWaitAnnouncement = () => waitAnnouncementBudget-- > 0;
|
||||
while (Date.now() - startedAt < timeoutMs) {
|
||||
try {
|
||||
await mkdir(lockDir);
|
||||
@@ -210,9 +211,8 @@ async function acquirePackageLock(lockDir: string, ownerToken: string): Promise<
|
||||
}
|
||||
}
|
||||
await removeStalePackageLock(lockDir, staleMs);
|
||||
if (!announcedWait) {
|
||||
if (consumeWaitAnnouncement()) {
|
||||
say(`Wait for Parallels package lock: ${lockDir}`);
|
||||
announcedWait = true;
|
||||
}
|
||||
await delay(1_000);
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ export function readLogTail(logPath: string, maxBytes = LOG_READY_TAIL_BYTES): s
|
||||
const bytesToRead = Math.min(Math.max(1, maxBytes), stat.size);
|
||||
const buffer = Buffer.alloc(bytesToRead);
|
||||
const fd = fs.openSync(logPath, "r");
|
||||
let bytesRead = 0;
|
||||
let bytesRead;
|
||||
try {
|
||||
bytesRead = fs.readSync(fd, buffer, 0, bytesToRead, stat.size - bytesToRead);
|
||||
} finally {
|
||||
|
||||
@@ -91,7 +91,7 @@ async function run() {
|
||||
|
||||
for (const url of targets) {
|
||||
console.log(`\n=== ${url}`);
|
||||
let localStatus = "skipped";
|
||||
let localStatus;
|
||||
let localTitle = "";
|
||||
let localText = "";
|
||||
let localError: string | undefined;
|
||||
|
||||
@@ -202,7 +202,7 @@ function main() {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
let parentRunId = "";
|
||||
let parentRunId;
|
||||
try {
|
||||
const dispatchArgs = ["workflow", "run", WORKFLOW, "--ref", branch];
|
||||
for (const [key, value] of Object.entries(dispatchInputs)) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user