mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-04 07:20:23 +00:00
lint: enable small oxlint rules
This commit is contained in:
@@ -113,7 +113,7 @@ export async function serveAcpGateway(opts: AcpServerOptions = {}): Promise<void
|
||||
const output = Readable.toWeb(process.stdin) as unknown as ReadableStream<Uint8Array>;
|
||||
const stream = ndJsonStream(input, output);
|
||||
|
||||
new AgentSideConnection((conn: AgentSideConnection) => {
|
||||
const _connection = new AgentSideConnection((conn: AgentSideConnection) => {
|
||||
agent = new AcpGatewayAgent(conn, gateway, opts);
|
||||
agent.start();
|
||||
return agent;
|
||||
|
||||
@@ -330,7 +330,10 @@ describe("acp translator stop reason mapping", () => {
|
||||
await Promise.resolve();
|
||||
agent.handleGatewayDisconnect("1006: first disconnect");
|
||||
agent.handleGatewayReconnect();
|
||||
for (let attempt = 0; attempt < 5 && !resolveAgentWait; attempt += 1) {
|
||||
for (let attempt = 0; attempt < 5; attempt += 1) {
|
||||
if (resolveAgentWait) {
|
||||
break;
|
||||
}
|
||||
await Promise.resolve();
|
||||
}
|
||||
expect(resolveAgentWait).toBeDefined();
|
||||
|
||||
@@ -539,10 +539,10 @@ describe("spawnAcpDirect", () => {
|
||||
expect(accepted.childSessionKey).toMatch(/^agent:codex:acp:/);
|
||||
expect(accepted.runId).toBe("run-1");
|
||||
expect(accepted.mode).toBe("session");
|
||||
const patchCalls = hoisted.callGatewayMock.mock.calls
|
||||
const patchCall = hoisted.callGatewayMock.mock.calls
|
||||
.map((call: unknown[]) => call[0] as { method?: string; params?: Record<string, unknown> })
|
||||
.filter((request) => request.method === "sessions.patch");
|
||||
expect(patchCalls[0]?.params).toMatchObject({
|
||||
.find((request) => request.method === "sessions.patch");
|
||||
expect(patchCall?.params).toMatchObject({
|
||||
key: accepted.childSessionKey,
|
||||
spawnedBy: "agent:main:main",
|
||||
});
|
||||
|
||||
@@ -758,12 +758,13 @@ function shouldFailClosedInterpreterPreflight(command: string): {
|
||||
const rawArgv = splitShellArgs(raw);
|
||||
const argv = rawArgv ? stripPreflightEnvPrefix(rawArgv) : null;
|
||||
let commandIdx = 0;
|
||||
while (
|
||||
argv &&
|
||||
commandIdx < argv.length &&
|
||||
/^[A-Za-z_][A-Za-z0-9_]*=.*$/u.test(argv[commandIdx])
|
||||
) {
|
||||
commandIdx += 1;
|
||||
if (argv) {
|
||||
while (
|
||||
commandIdx < argv.length &&
|
||||
/^[A-Za-z_][A-Za-z0-9_]*=.*$/u.test(argv[commandIdx] ?? "")
|
||||
) {
|
||||
commandIdx += 1;
|
||||
}
|
||||
}
|
||||
const directExecutable = normalizeOptionalLowercaseString(argv?.[commandIdx]);
|
||||
const args = argv ? argv.slice(commandIdx + 1) : [];
|
||||
|
||||
@@ -25,8 +25,7 @@ function buildLiveAnthropicModel(): {
|
||||
const modelId =
|
||||
(process.env.OPENCLAW_LIVE_ANTHROPIC_CACHE_MODEL || "claude-sonnet-4-6")
|
||||
.split(/[/:]/)
|
||||
.filter(Boolean)
|
||||
.pop() || "claude-sonnet-4-6";
|
||||
.findLast(Boolean) || "claude-sonnet-4-6";
|
||||
return {
|
||||
apiKey,
|
||||
model: {
|
||||
|
||||
@@ -759,7 +759,7 @@ export async function runEmbeddedPiAgent(
|
||||
incompleteTurnText,
|
||||
});
|
||||
if (resolveReplayInvalidForAttempt(null)) {
|
||||
accumulatedReplayState = { ...accumulatedReplayState, replayInvalid: true };
|
||||
accumulatedReplayState.replayInvalid = true;
|
||||
}
|
||||
accumulatedReplayState = observeReplayMetadata(
|
||||
accumulatedReplayState,
|
||||
|
||||
@@ -323,27 +323,27 @@ export function sanitizeConfiguredModelProviderRequest(
|
||||
export function mergeProviderRequestOverrides(
|
||||
...overrides: Array<ProviderRequestTransportOverrides | undefined>
|
||||
): ProviderRequestTransportOverrides | undefined {
|
||||
let merged: ProviderRequestTransportOverrides | undefined;
|
||||
const merged: ProviderRequestTransportOverrides = {};
|
||||
let hasMerged = false;
|
||||
for (const current of overrides) {
|
||||
if (!current) {
|
||||
continue;
|
||||
}
|
||||
merged = {
|
||||
...merged,
|
||||
...(current.headers
|
||||
? {
|
||||
headers: {
|
||||
...merged?.headers,
|
||||
...current.headers,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(current.auth ? { auth: current.auth } : {}),
|
||||
...(current.proxy ? { proxy: current.proxy } : {}),
|
||||
...(current.tls ? { tls: current.tls } : {}),
|
||||
};
|
||||
hasMerged = true;
|
||||
if (current.headers) {
|
||||
merged.headers = Object.assign({}, merged.headers, current.headers);
|
||||
}
|
||||
if (current.auth) {
|
||||
merged.auth = current.auth;
|
||||
}
|
||||
if (current.proxy) {
|
||||
merged.proxy = current.proxy;
|
||||
}
|
||||
if (current.tls) {
|
||||
merged.tls = current.tls;
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
return hasMerged ? merged : undefined;
|
||||
}
|
||||
|
||||
export function mergeModelProviderRequestOverrides(
|
||||
@@ -354,10 +354,8 @@ export function mergeModelProviderRequestOverrides(
|
||||
);
|
||||
for (const current of overrides) {
|
||||
if (current?.allowPrivateNetwork !== undefined) {
|
||||
merged = {
|
||||
...merged,
|
||||
allowPrivateNetwork: current.allowPrivateNetwork,
|
||||
};
|
||||
merged ??= {};
|
||||
merged.allowPrivateNetwork = current.allowPrivateNetwork;
|
||||
}
|
||||
}
|
||||
return merged;
|
||||
|
||||
@@ -95,14 +95,14 @@ function fileNameFromPathLike(pathLike: string): string | undefined {
|
||||
|
||||
try {
|
||||
const url = new URL(value);
|
||||
const candidate = url.pathname.split("/").filter(Boolean).at(-1);
|
||||
const candidate = url.pathname.split("/").findLast(Boolean);
|
||||
return candidate && candidate.length > 0 ? candidate : undefined;
|
||||
} catch {
|
||||
// Not a URL; continue with path-like parsing.
|
||||
}
|
||||
|
||||
const normalized = value.replaceAll("\\", "/");
|
||||
const candidate = normalized.split("/").filter(Boolean).at(-1);
|
||||
const candidate = normalized.split("/").findLast(Boolean);
|
||||
return candidate && candidate.length > 0 ? candidate : undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ async function resolveContextReport(
|
||||
|
||||
export async function buildContextReply(params: HandleCommandsParams): Promise<ReplyPayload> {
|
||||
const args = parseContextArgs(params.command.commandBodyNormalized);
|
||||
const sub = normalizeLowercaseStringOrEmpty(args.split(/\s+/).filter(Boolean)[0]);
|
||||
const sub = normalizeLowercaseStringOrEmpty(args.split(/\s+/).find(Boolean));
|
||||
|
||||
if (!sub || sub === "help") {
|
||||
return {
|
||||
|
||||
@@ -85,7 +85,10 @@ function parseExecDirectiveArgs(raw: string): Omit<
|
||||
return { key, value };
|
||||
};
|
||||
|
||||
while (i < len) {
|
||||
for (;;) {
|
||||
if (i >= len) {
|
||||
break;
|
||||
}
|
||||
const token = takeToken();
|
||||
if (!token) {
|
||||
break;
|
||||
|
||||
@@ -65,7 +65,10 @@ function parseQueueDirectiveArgs(raw: string): {
|
||||
i = res.nextIndex;
|
||||
return res.token;
|
||||
};
|
||||
while (i < len) {
|
||||
for (;;) {
|
||||
if (i >= len) {
|
||||
break;
|
||||
}
|
||||
const token = takeToken();
|
||||
if (!token) {
|
||||
break;
|
||||
|
||||
@@ -291,9 +291,12 @@ describe("initSessionState thread forking", () => {
|
||||
if (!newSessionFile) {
|
||||
throw new Error("Missing session file for forked thread");
|
||||
}
|
||||
const [headerLine] = (await fs.readFile(newSessionFile, "utf-8"))
|
||||
const headerLine = (await fs.readFile(newSessionFile, "utf-8"))
|
||||
.split(/\r?\n/)
|
||||
.filter((line) => line.trim().length > 0);
|
||||
.find((line) => line.trim().length > 0);
|
||||
if (!headerLine) {
|
||||
throw new Error("Missing session header");
|
||||
}
|
||||
const parsedHeader = JSON.parse(headerLine) as {
|
||||
parentSession?: string;
|
||||
};
|
||||
@@ -522,7 +525,10 @@ describe("initSessionState thread forking", () => {
|
||||
expect(result.sessionEntry.forkedFromParent).toBe(true);
|
||||
expect(result.sessionEntry.sessionFile).toBeTruthy();
|
||||
const forkedContent = await fs.readFile(result.sessionEntry.sessionFile ?? "", "utf-8");
|
||||
const [headerLine] = forkedContent.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
||||
const headerLine = forkedContent.split(/\r?\n/).find((line) => line.trim().length > 0);
|
||||
if (!headerLine) {
|
||||
throw new Error("Missing session header");
|
||||
}
|
||||
const parsedHeader = JSON.parse(headerLine) as { parentSession?: string };
|
||||
const expectedParentSession = await fs.realpath(parentSessionFile);
|
||||
const actualParentSession = parsedHeader.parentSession
|
||||
|
||||
@@ -19,16 +19,10 @@ export function resolveCliCommandPathPolicy(commandPath: string[]): CliCommandPa
|
||||
if (!matchesCommandPath(commandPath, entry.commandPath, { exact: entry.exact })) {
|
||||
continue;
|
||||
}
|
||||
resolvedPolicy = {
|
||||
...resolvedPolicy,
|
||||
...entry.policy,
|
||||
};
|
||||
Object.assign(resolvedPolicy, entry.policy);
|
||||
}
|
||||
if (isGatewayConfigBypassCommandPath(commandPath)) {
|
||||
resolvedPolicy = {
|
||||
...resolvedPolicy,
|
||||
bypassConfigGuard: true,
|
||||
};
|
||||
resolvedPolicy.bypassConfigGuard = true;
|
||||
}
|
||||
return resolvedPolicy;
|
||||
}
|
||||
|
||||
@@ -67,12 +67,11 @@ export async function removeChannelConfigWizard(
|
||||
|
||||
const nextChannels: Record<string, unknown> = { ...next.channels };
|
||||
delete nextChannels[channel];
|
||||
next = {
|
||||
...next,
|
||||
channels: Object.keys(nextChannels).length
|
||||
? (nextChannels as OpenClawConfig["channels"])
|
||||
: undefined,
|
||||
};
|
||||
if (Object.keys(nextChannels).length) {
|
||||
next.channels = nextChannels as OpenClawConfig["channels"];
|
||||
} else {
|
||||
delete next.channels;
|
||||
}
|
||||
|
||||
note(
|
||||
[`${label} removed from config.`, "Note: credentials/sessions on disk are unchanged."].join(
|
||||
|
||||
@@ -75,11 +75,12 @@ function normalizeSnippet(raw: string | undefined, fallback: string): string {
|
||||
}
|
||||
|
||||
function firstParagraph(text: string): string {
|
||||
const parts = text
|
||||
.split(/\n\s*\n/)
|
||||
.map((chunk) => chunk.trim())
|
||||
.filter(Boolean);
|
||||
return parts[0] ?? "";
|
||||
return (
|
||||
text
|
||||
.split(/\n\s*\n/)
|
||||
.map((chunk) => chunk.trim())
|
||||
.find(Boolean) ?? ""
|
||||
);
|
||||
}
|
||||
|
||||
function parseSearchOutput(raw: string): DocResult[] {
|
||||
|
||||
@@ -446,12 +446,7 @@ async function promptBaseUrlAndKey(params: {
|
||||
initialValue: params.initialBaseUrl ?? OLLAMA_DEFAULT_BASE_URL,
|
||||
placeholder: "https://api.example.com/v1",
|
||||
validate: (val) => {
|
||||
try {
|
||||
new URL(val);
|
||||
return undefined;
|
||||
} catch {
|
||||
return "Please enter a valid URL (e.g. http://...)";
|
||||
}
|
||||
return URL.canParse(val) ? undefined : "Please enter a valid URL (e.g. http://...)";
|
||||
},
|
||||
});
|
||||
const baseUrl = baseUrlInput.trim();
|
||||
@@ -608,9 +603,7 @@ export function parseNonInteractiveCustomApiFlags(
|
||||
|
||||
export function applyCustomApiConfig(params: ApplyCustomApiConfigParams): CustomApiResult {
|
||||
const baseUrl = normalizeOptionalString(params.baseUrl) ?? "";
|
||||
try {
|
||||
new URL(baseUrl);
|
||||
} catch {
|
||||
if (!URL.canParse(baseUrl)) {
|
||||
throw new CustomApiError("invalid_base_url", "Custom provider base URL must be a valid URL.");
|
||||
}
|
||||
|
||||
|
||||
@@ -87,8 +87,7 @@ describe("config observe recovery", () => {
|
||||
const lines = (await fsp.readFile(auditPath, "utf-8")).trim().split("\n").filter(Boolean);
|
||||
const observe = lines
|
||||
.map((line) => JSON.parse(line) as Record<string, unknown>)
|
||||
.filter((line) => line.event === "config.observe")
|
||||
.at(-1);
|
||||
.findLast((line) => line.event === "config.observe");
|
||||
expect(observe?.restoredFromBackup).toBe(true);
|
||||
expect(observe?.suspicious).toEqual(
|
||||
expect.arrayContaining(["gateway-mode-missing-vs-last-good", "update-channel-only-root"]),
|
||||
@@ -154,8 +153,7 @@ describe("config observe recovery", () => {
|
||||
const lines = (await fsp.readFile(auditPath, "utf-8")).trim().split("\n").filter(Boolean);
|
||||
const observe = lines
|
||||
.map((line) => JSON.parse(line) as Record<string, unknown>)
|
||||
.filter((line) => line.event === "config.observe")
|
||||
.at(-1);
|
||||
.findLast((line) => line.event === "config.observe");
|
||||
expect(observe?.backupHash).toBeTypeOf("string");
|
||||
expect(observe?.lastKnownGoodIno ?? null).toBeNull();
|
||||
});
|
||||
|
||||
@@ -53,11 +53,7 @@ function flattenUnionSchema(raw: Record<string, unknown>): Record<string, unknow
|
||||
}
|
||||
const required =
|
||||
requiredSets.length > 0
|
||||
? [
|
||||
...requiredSets.reduce(
|
||||
(left, right) => new Set([...left].filter((key) => right.has(key))),
|
||||
),
|
||||
]
|
||||
? [...(requiredSets[0] ?? [])].filter((key) => requiredSets.every((set) => set.has(key)))
|
||||
: [];
|
||||
const { anyOf: _anyOf, oneOf: _oneOf, ...rest } = raw;
|
||||
return { ...rest, type: "object", properties: mergedProps, required };
|
||||
|
||||
@@ -389,7 +389,10 @@ describe("node.invoke approval bypass", () => {
|
||||
idempotencyKey: crypto.randomUUID(),
|
||||
});
|
||||
expect(invoke.ok).toBe(true);
|
||||
for (let i = 0; i < 100 && !lastInvokeParams; i += 1) {
|
||||
for (let i = 0; i < 100; i += 1) {
|
||||
if (lastInvokeParams) {
|
||||
break;
|
||||
}
|
||||
await sleep(50);
|
||||
}
|
||||
expect(lastInvokeParams).toBeTruthy();
|
||||
|
||||
@@ -306,6 +306,6 @@ describe("bonjour-discovery", () => {
|
||||
});
|
||||
|
||||
expect(calls.filter((c) => c[1] === "-B")).toHaveLength(1);
|
||||
expect(calls.filter((c) => c[1] === "-B")[0]?.[3]).toBe("local.");
|
||||
expect(calls.find((c) => c[1] === "-B")?.[3]).toBe("local.");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -138,8 +138,7 @@ function parsePinnedIdentity(stdout: string): FileIdentityStat {
|
||||
.trim()
|
||||
.split(/\r?\n/)
|
||||
.map((value) => value.trim())
|
||||
.filter(Boolean)
|
||||
.at(-1);
|
||||
.findLast(Boolean);
|
||||
if (!line) {
|
||||
throw new Error("Pinned write helper returned no identity");
|
||||
}
|
||||
|
||||
@@ -225,8 +225,11 @@ describe("drainPendingDeliveries for WhatsApp reconnect", () => {
|
||||
// Fail it so it matches the "no listener" filter
|
||||
const pending = fs
|
||||
.readdirSync(path.join(tmpDir, "delivery-queue"))
|
||||
.filter((f) => f.endsWith(".json"));
|
||||
const entryPath = path.join(tmpDir, "delivery-queue", pending[0]);
|
||||
.find((f) => f.endsWith(".json"));
|
||||
if (!pending) {
|
||||
throw new Error("Missing pending delivery entry");
|
||||
}
|
||||
const entryPath = path.join(tmpDir, "delivery-queue", pending);
|
||||
const entry = JSON.parse(fs.readFileSync(entryPath, "utf-8"));
|
||||
entry.lastError = "No active WhatsApp Web listener";
|
||||
entry.retryCount = 1;
|
||||
|
||||
@@ -98,8 +98,7 @@ function redactMatch(match: string, groups: string[]): string {
|
||||
if (match.includes("PRIVATE KEY-----")) {
|
||||
return redactPemBlock(match);
|
||||
}
|
||||
const token =
|
||||
groups.filter((value) => typeof value === "string" && value.length > 0).at(-1) ?? match;
|
||||
const token = groups.findLast((value) => typeof value === "string" && value.length > 0) ?? match;
|
||||
const masked = maskToken(token);
|
||||
if (token === match) {
|
||||
return masked;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export function isValidTimeZone(tz: string): boolean {
|
||||
try {
|
||||
new Intl.DateTimeFormat("en", { timeZone: tz });
|
||||
new Intl.DateTimeFormat("en", { timeZone: tz }).format();
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
|
||||
@@ -37,14 +37,9 @@ function getAjv(mode: "default" | "defaults"): AjvLike {
|
||||
instance.addFormat("uri", {
|
||||
type: "string",
|
||||
validate: (value: string) => {
|
||||
try {
|
||||
// Accept absolute URIs so generated config schemas can keep JSON Schema
|
||||
// `format: "uri"` without noisy AJV warnings during validation/build.
|
||||
new URL(value);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
// Accept absolute URIs so generated config schemas can keep JSON Schema
|
||||
// `format: "uri"` without noisy AJV warnings during validation/build.
|
||||
return URL.canParse(value);
|
||||
},
|
||||
});
|
||||
ajvSingletons.set(mode, instance);
|
||||
|
||||
@@ -85,14 +85,14 @@ export function applyExclusiveSlotSelection(params: {
|
||||
}
|
||||
|
||||
const warnings: string[] = [];
|
||||
let pluginsConfig = params.config.plugins ?? {};
|
||||
const pluginsConfig = params.config.plugins ?? {};
|
||||
let anyChanged = false;
|
||||
let entries = { ...pluginsConfig.entries };
|
||||
let slots = { ...pluginsConfig.slots };
|
||||
const entries = { ...pluginsConfig.entries };
|
||||
const slots = { ...pluginsConfig.slots };
|
||||
|
||||
for (const slotKey of slotKeys) {
|
||||
const prevSlot = slots[slotKey];
|
||||
slots = { ...slots, [slotKey]: params.selectedId };
|
||||
slots[slotKey] = params.selectedId;
|
||||
|
||||
const inferredPrevSlot = prevSlot ?? defaultSlotIdForKey(slotKey);
|
||||
if (inferredPrevSlot && inferredPrevSlot !== params.selectedId) {
|
||||
@@ -123,10 +123,7 @@ export function applyExclusiveSlotSelection(params: {
|
||||
}
|
||||
const entry = entries[plugin.id];
|
||||
if (!entry || entry.enabled !== false) {
|
||||
entries = {
|
||||
...entries,
|
||||
[plugin.id]: { ...entry, enabled: false },
|
||||
};
|
||||
entries[plugin.id] = { ...entry, enabled: false };
|
||||
disabledIds.push(plugin.id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user