chore: apply oxlint autofix (safe level)

Auto-fixed 102 warnings (6040 → 5938) across 57 files. Main categories:
- preserve-caught-error: add { cause: error } to re-thrown errors
- unicorn/no-array-reverse: .reverse() → .toReversed()
- unicorn/no-useless-fallback-in-spread: drop unnecessary ?? {} in spreads
- oxc/no-map-spread: rewrite object spread in .map() to Object.assign
- react-hooks/exhaustive-deps: trim module-level constants from dep arrays

Ran npm run format after to clean up whitespace from lint mutations.
This commit is contained in:
Mohamed Boudra
2026-04-23 21:47:36 +07:00
parent 9c88850de0
commit 177153e5e8
57 changed files with 152 additions and 151 deletions
+1 -9
View File
@@ -1,14 +1,6 @@
{
"$schema": "./node_modules/oxlint/configuration_schema.json",
"plugins": [
"react",
"react-perf",
"unicorn",
"typescript",
"oxc",
"import",
"promise"
],
"plugins": ["react", "react-perf", "unicorn", "typescript", "oxc", "import", "promise"],
"categories": {
"correctness": "warn",
"suspicious": "warn",
+3 -1
View File
@@ -156,7 +156,9 @@ async function assertE2EUsesSeededTestDaemon(page: Page): Promise<void> {
}
} catch (error) {
if (error instanceof Error) throw error;
throw new Error("E2E expected @paseo:create-agent-preferences to be valid JSON.");
throw new Error("E2E expected @paseo:create-agent-preferences to be valid JSON.", {
cause: error,
});
}
}
@@ -368,7 +368,7 @@ function summarizeByType(records: WireFrameRecord[]): Array<{
byType.set(type, current);
}
return [...byType.entries()]
.map(([type, value]) => ({ type, ...value }))
.map(([type, value]) => Object.assign({ type }, value))
.sort((left, right) => right.bytes - left.bytes);
}
@@ -45,6 +45,7 @@ async function waitForAlternateScreenExit(page: Page, afterAlt: string, timeout:
null,
2,
)}`,
{ cause: error },
);
}
+1 -1
View File
@@ -22,7 +22,7 @@ const escapedAppSrcRoot = appSrcRoot
const pathSeparatorPattern = "[\\\\/]";
config.resolver.extraNodeModules = {
...(config.resolver.extraNodeModules ?? {}),
...config.resolver.extraNodeModules,
react: path.join(appNodeModulesRoot, "react"),
"react-dom": path.join(appNodeModulesRoot, "react-dom"),
"react/jsx-runtime": path.join(appNodeModulesRoot, "react/jsx-runtime"),
@@ -618,7 +618,7 @@ export function CombinedModelSelector({
});
return () => cancelAnimationFrame(frame);
}, [isOpen, platformIsWeb]);
}, [isOpen]);
return (
<>
@@ -287,14 +287,14 @@ export function FileExplorerPane({
directoryPaths.unshift(".");
}
await Promise.all([
...directoryPaths.map((path) =>
await Promise.all(
directoryPaths.map((path) =>
requestDirectoryListing(path, {
recordHistory: false,
setCurrentPath: false,
}),
),
]);
);
return null;
},
enabled: false,
@@ -2158,7 +2158,6 @@ export function SidebarWorkspaceList({
serverId,
shortcutIndexByWorkspaceKey,
showShortcutBadges,
platformIsNative,
creatingWorkspaceIds,
],
);
@@ -122,8 +122,9 @@ export function createStreamStrategy(config: StreamStrategyConfig): StreamStrate
return {
render: config.render,
orderTail: (streamItems) =>
config.orderTailReverse ? [...streamItems].reverse() : streamItems,
orderHead: (streamHead) => (config.orderHeadReverse ? [...streamHead].reverse() : streamHead),
config.orderTailReverse ? [...streamItems].toReversed() : streamItems,
orderHead: (streamHead) =>
config.orderHeadReverse ? [...streamHead].toReversed() : streamHead,
getNeighborIndex: (index, relation) =>
relation === "above"
? index + config.assistantTurnTraversalStep
@@ -153,7 +154,7 @@ export function createStreamStrategy(config: StreamStrategyConfig): StreamStrate
messages.push(currentItem.text);
}
}
return messages.reverse().join("\n\n");
return messages.toReversed().join("\n\n");
},
isNearBottom: (input) => config.isNearBottom(input),
getBottomOffset: (metrics) => config.getBottomOffset(metrics),
@@ -9,7 +9,7 @@ export function orderAutocompleteOptions<T>(
if (position === "below-input") {
return [...options];
}
return [...options].reverse();
return [...options].toReversed();
}
export function getAutocompleteFallbackIndex(
@@ -113,7 +113,7 @@ export function orderVisibleComboboxOptions(
if (optionsPosition !== "above-search") {
return visibleOptions;
}
return [...visibleOptions].reverse();
return [...visibleOptions].toReversed();
}
export function getComboboxFallbackIndex(
@@ -279,26 +279,23 @@ export function WebDesktopScrollbarOverlay({
setIsDragging(false);
},
});
}, [applyDragDelta, platformIsWeb]);
}, [applyDragDelta]);
const startWebDrag = useCallback(
(event: any) => {
if (!platformIsWeb) {
return;
}
const clientY = readClientY(event);
if (clientY === null) {
return;
}
event?.preventDefault?.();
event?.stopPropagation?.();
event?.nativeEvent?.preventDefault?.();
dragStartOffsetRef.current = normalizedOffsetRef.current;
dragStartClientYRef.current = clientY;
setIsDragging(true);
},
[platformIsWeb],
);
const startWebDrag = useCallback((event: any) => {
if (!platformIsWeb) {
return;
}
const clientY = readClientY(event);
if (clientY === null) {
return;
}
event?.preventDefault?.();
event?.stopPropagation?.();
event?.nativeEvent?.preventDefault?.();
dragStartOffsetRef.current = normalizedOffsetRef.current;
dragStartClientYRef.current = clientY;
setIsDragging(true);
}, []);
const handleGrabHoverIn = useCallback(() => {
if (!isScrollVisible && !isDragging) {
@@ -334,7 +331,7 @@ export function WebDesktopScrollbarOverlay({
window.removeEventListener("pointerup", stopDragging);
window.removeEventListener("pointercancel", stopDragging);
};
}, [applyDragDelta, isDragging, platformIsWeb]);
}, [applyDragDelta, isDragging]);
if (!enabled || !geometry.isVisible) {
return null;
@@ -1580,7 +1580,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider
console.error("[Session] Failed to send agent message:", error);
});
},
[encodeImages, serverId, client, setAgentStreamTail, setAgentStreamHead],
[serverId, client, setAgentStreamTail, setAgentStreamHead],
);
// Keep the ref updated so the agent_update handler can call it
@@ -1677,7 +1677,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider
...(requestId ? { requestId } : {}),
});
},
[encodeImages, client],
[client],
);
const setAgentMode = useCallback(
@@ -227,7 +227,7 @@ export function useAudioRecorder(config?: AudioCaptureConfig) {
if (error?.message !== "Recording cancelled") {
console.error("[AudioRecorder] Failed to start recording:", error);
}
throw new Error(`Failed to start audio recording: ${error.message}`);
throw new Error(`Failed to start audio recording: ${error.message}`, { cause: error });
}
}, [recordingOptions.sampleRate, recordingOptions.numberOfChannels, recordingOptions.bitRate]);
@@ -293,7 +293,7 @@ export function useAudioRecorder(config?: AudioCaptureConfig) {
} catch (error: any) {
setRecordingStartTime(null);
console.error("[AudioRecorder] Failed to stop recording:", error);
throw new Error(`Failed to stop audio recording: ${error.message}`);
throw new Error(`Failed to stop audio recording: ${error.message}`, { cause: error });
} finally {
startStopMutexRef.current = null;
}
@@ -190,7 +190,7 @@ export function useAudioRecorder(config?: AudioCaptureConfig) {
try {
stream = await navigator.mediaDevices.getUserMedia(constraints);
} catch (error: any) {
throw new Error(`Failed to access microphone: ${error?.message ?? error}`);
throw new Error(`Failed to access microphone: ${error?.message ?? error}`, { cause: error });
}
try {
@@ -225,7 +225,9 @@ export function useAudioRecorder(config?: AudioCaptureConfig) {
recorder = new MediaRecorder(stream, recorderOptions);
} catch (error: any) {
cleanupStream();
throw new Error(`Failed to initialize recorder: ${error?.message ?? error}`);
throw new Error(`Failed to initialize recorder: ${error?.message ?? error}`, {
cause: error,
});
}
mediaRecorderRef.current = recorder;
+4 -4
View File
@@ -1530,13 +1530,13 @@ export class HostRuntimeStore {
this.emit(host.serverId);
});
void controller
.start({
...(initialConnection
.start(
initialConnection
? {
initialConnection,
}
: {}),
})
: {},
)
.catch((error) => {
const message = error instanceof Error ? error.message : String(error);
controller.markStartupError(message);
@@ -292,7 +292,7 @@ export function NewWorkspaceScreen({
cwd: input.cwd,
worktreeSlug: createNameId(),
...(input.attachments.length > 0 ? { attachments: input.attachments } : {}),
...(checkoutRequest ?? {}),
...checkoutRequest,
};
},
[selectedItem],
@@ -53,7 +53,7 @@ function setStatus(
statusByCheckout: {
...state.statusByCheckout,
[key]: {
...(state.statusByCheckout[key] ?? {}),
...state.statusByCheckout[key],
[actionId]: status,
},
},
@@ -531,7 +531,7 @@ export const useWorkspaceLayoutStore = create<WorkspaceLayoutStore>()(
splitSizesByWorkspace: {
...state.splitSizesByWorkspace,
[normalizedWorkspaceKey]: {
...(state.splitSizesByWorkspace[normalizedWorkspaceKey] ?? {}),
...state.splitSizesByWorkspace[normalizedWorkspaceKey],
[normalizedGroupId]: clampNormalizedSizes(sizes),
},
},
+1 -1
View File
@@ -325,7 +325,7 @@ export async function runRunCommand(
};
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to read image ${imagePath}: ${message}`);
throw new Error(`Failed to read image ${imagePath}: ${message}`, { cause: err });
}
});
}
+1 -1
View File
@@ -193,7 +193,7 @@ async function checkProviderBinaries(): Promise<ProviderBinaryStatus[]> {
const results = await Promise.all(
PROVIDER_BINARIES.map(async ({ label, binary }) => {
const result = await checkProviderBinary(binary);
return { label, ...result };
return Object.assign({ label }, result);
}),
);
return results;
@@ -315,6 +315,7 @@ export async function startTestDaemon(options?: {
const message = err instanceof Error ? err.message : String(err);
throw new Error(
`Failed to start test daemon: ${message}\nStdout: ${formatOutputCapture(stdout)}\nStderr: ${formatOutputCapture(stderr)}`,
{ cause: err },
);
}
@@ -153,7 +153,7 @@ function tailFile(filePath: string, lines = 50): string {
function logDesktopDaemonLifecycle(message: string, details?: Record<string, unknown>): void {
log.info("[desktop daemon]", message, {
pid: process.pid,
...(details ?? {}),
...details,
});
}
@@ -349,6 +349,7 @@ export async function runCliJsonCommand(args: string[]): Promise<unknown> {
} catch (error) {
throw new Error(
`CLI command returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
{ cause: error },
);
}
}
@@ -267,7 +267,7 @@ function attachPersistenceCwd(
return {
...handle,
metadata: {
...(handle.metadata ?? {}),
...handle.metadata,
cwd,
},
};
@@ -278,11 +278,11 @@ type SubscriptionRecord = {
agentId: string | null;
};
const BUSY_STATUSES: AgentLifecycleStatus[] = ["initializing", "running"];
const BUSY_STATUSES: AgentLifecycleStatus[] = new Set(["initializing", "running"]);
const AgentIdSchema = z.string().uuid();
function isAgentBusy(status: AgentLifecycleStatus): boolean {
return BUSY_STATUSES.includes(status);
return BUSY_STATUSES.has(status);
}
function isTurnTerminalEvent(event: AgentStreamEvent): boolean {
@@ -649,7 +649,7 @@ export class AgentManager {
type: "http" as const,
url: `${this.mcpBaseUrl}?callerAgentId=${resolvedAgentId}`,
},
...(config.mcpServers ?? {}),
...config.mcpServers,
},
};
const normalizedConfig = await this.normalizeConfig(injectedConfig);
@@ -1708,7 +1708,7 @@ export class AgentManager {
}
return {
text: chunks.reverse().join(""),
text: chunks.toReversed().join(""),
startsAtBeginning,
};
}
@@ -2847,12 +2847,12 @@ export class AgentManager {
"code" in error &&
(error as NodeJS.ErrnoException).code === "ENOENT"
) {
throw new Error(`Working directory does not exist: ${normalized.cwd}`);
throw new Error(`Working directory does not exist: ${normalized.cwd}`, { cause: error });
}
if (error instanceof Error) {
throw error;
}
throw new Error(`Failed to access working directory: ${normalized.cwd}`);
throw new Error(`Failed to access working directory: ${normalized.cwd}`, { cause: error });
}
}
@@ -244,7 +244,7 @@ export class InMemoryAgentTimelineStore {
return null;
}
return chunks.reverse().join("");
return chunks.toReversed().join("");
}
getCanonicalUserMessagesById(agentId: string): Map<string, string> {
@@ -666,8 +666,8 @@ export async function createAgentMcpServer(options: AgentMcpServerOptions): Prom
const childAgentDefaultLabels = callerContext?.childAgentDefaultLabels;
const mergedLabels = {
...(callerAgentId ? { "paseo.parent-agent-id": callerAgentId } : {}),
...(childAgentDefaultLabels ?? {}),
...(labels ?? {}),
...childAgentDefaultLabels,
...labels,
};
const snapshot = await agentManager.createAgent(
{
@@ -185,7 +185,7 @@ export function applyProviderEnv(
): Record<string, string | undefined> {
const merged: Record<string, string | undefined> = {
...baseEnv,
...(runtimeSettings?.env ?? {}),
...runtimeSettings?.env,
};
for (const key of PARENT_SESSION_ENV_VARS) {
delete merged[key];
@@ -130,8 +130,8 @@ function mergeRuntimeSettings(
env:
base?.env || override?.env
? {
...(base?.env ?? {}),
...(override?.env ?? {}),
...base?.env,
...override?.env,
}
: undefined,
disallowedTools:
@@ -516,9 +516,9 @@ export class ACPAgentClient implements AgentClient {
const sessions: PersistedAgentDescriptor[] = [];
let cursor: string | null | undefined;
do {
const page: ListSessionsResponse = await probe.connection.listSessions({
...(cursor ? { cursor } : {}),
});
const page: ListSessionsResponse = await probe.connection.listSessions(
cursor ? { cursor } : {},
);
for (const session of page.sessions) {
sessions.push({
provider: this.provider,
@@ -566,7 +566,7 @@ export class ACPAgentClient implements AgentClient {
process.env as Record<string, string | undefined>,
this.runtimeSettings,
),
...(launchEnv ?? {}),
...launchEnv,
},
stdio: ["pipe", "pipe", "pipe"],
}) as ChildProcessWithoutNullStreams;
@@ -1413,7 +1413,7 @@ export class ACPAgentSession implements AgentSession, ACPClient {
process.env as Record<string, string | undefined>,
this.runtimeSettings,
),
...(this.launchEnv ?? {}),
...this.launchEnv,
},
stdio: ["pipe", "pipe", "pipe"],
}) as ChildProcessWithoutNullStreams;
@@ -131,7 +131,7 @@ function getToolCalls(events: AgentStreamEvent[]): ToolCallTimelineItem[] {
function getLatestCompletedBashCall(events: AgentStreamEvent[]): ToolCallTimelineItem | undefined {
return [...getToolCalls(events)]
.reverse()
.toReversed()
.find((item) => item.status === "completed" && item.name.toLowerCase() === "bash");
}
@@ -220,7 +220,7 @@ function applyRuntimeSettingsToClaudeOptions(
cwd: spawnOptions.cwd,
env: {
...applyProviderEnv(spawnOptions.env, runtimeSettings),
...(launchEnv ?? {}),
...launchEnv,
},
signal: spawnOptions.signal,
stdio: ["pipe", "pipe", "pipe"],
@@ -1057,7 +1057,7 @@ export function readEventIdentifiers(message: SDKMessage): EventIdentifiers {
const claudeDebug = process.env.PASEO_CLAUDE_DEBUG === "1";
export class ClaudeAgentClient implements AgentClient {
readonly provider: "claude" = "claude";
readonly provider = "claude" as const;
readonly capabilities = CLAUDE_CAPABILITIES;
private readonly defaults?: { agents?: Record<string, AgentDefinition> };
@@ -1347,7 +1347,7 @@ function readStreamRequestOutputTokens(event: Record<string, unknown>): number |
}
class ClaudeAgentSession implements AgentSession {
readonly provider: "claude" = "claude";
readonly provider = "claude" as const;
readonly capabilities = CLAUDE_CAPABILITIES;
private readonly config: ClaudeAgentConfig;
@@ -2174,7 +2174,7 @@ class ClaudeAgentSession implements AgentSession {
// Increase MCP timeouts for long-running tool calls (10 minutes)
MCP_TIMEOUT: "600000",
MCP_TOOL_TIMEOUT: "600000",
...(this.launchEnv ?? {}),
...this.launchEnv,
},
// Required for provider-level /rewind support.
enableFileCheckpointing: true,
@@ -96,11 +96,12 @@ export class ClaudeSidechainTracker {
action.summary ? `[${action.toolName}] ${action.summary}` : `[${action.toolName}]`,
)
.join("\n"),
actions: state.actions.map((action) => ({
index: action.index,
toolName: action.toolName,
...(action.summary ? { summary: action.summary } : {}),
})),
actions: state.actions.map((action) =>
Object.assign(
{ index: action.index, toolName: action.toolName },
action.summary ? { summary: action.summary } : {},
),
),
};
return [
@@ -387,7 +387,7 @@ describe("Codex app-server provider (e2e)", () => {
).toBe(true);
const finalAssistantMessage = [...events]
.reverse()
.toReversed()
.find((event) => event.type === "timeline" && event.item.type === "assistant_message");
expect(finalAssistantMessage).toBeDefined();
if (
@@ -1408,11 +1408,13 @@ function mapCodexPatchNotificationToToolCall(params: {
: {
...(files.length > 0
? {
files: files.map((file) => ({
path: file.path,
...(file.kind ? { kind: file.kind } : {}),
...codexPatchTextFields(file.content ?? patchText),
})),
files: files.map((file) =>
Object.assign(
{ path: file.path },
file.kind ? { kind: file.kind } : {},
codexPatchTextFields(file.content ?? patchText),
),
),
}
: {}),
...(params.stdout ? { stdout: params.stdout } : {}),
@@ -2667,7 +2669,7 @@ class CodexAppServerAgentSession implements AgentSession {
private applyFeatureValue(featureId: "fast_mode" | "plan_mode", value: boolean): void {
this.config.featureValues = {
...(this.config.featureValues ?? {}),
...this.config.featureValues,
[featureId]: value,
};
@@ -764,19 +764,18 @@ function mapFileChangeItem(
): CodexNormalizedToolCallEnvelope {
const files = parseFileChangeEntries(item.changes, options);
const inputBase = {
...(files.length > 0
const inputBase =
files.length > 0
? {
files: files.map((file) => ({
path: file.path,
...(file.kind !== undefined ? { kind: file.kind } : {}),
})),
}
: {}),
};
: {};
const output = toNullableObject({
...(files.length > 0
const output = toNullableObject(
files.length > 0
? {
files: files.map((file) => ({
path: file.path,
@@ -786,8 +785,8 @@ function mapFileChangeItem(
: asEditFileOutputFields(file.diff)),
})),
}
: {}),
});
: {},
);
const name = "apply_patch";
const error = item.error ?? null;
@@ -948,7 +948,7 @@ type OpenCodeServerGeneration = {
};
export class OpenCodeAgentClient implements AgentClient {
readonly provider: "opencode" = "opencode";
readonly provider = "opencode" as const;
readonly capabilities = OPENCODE_CAPABILITIES;
private readonly serverManager: OpenCodeServerManager;
@@ -1667,7 +1667,7 @@ export function translateOpenCodeEvent(
input: { questions },
metadata: {
source: "opencode_question",
...(event.properties.tool ?? {}),
...event.properties.tool,
},
},
});
@@ -1757,7 +1757,7 @@ export function translateOpenCodeEvent(
}
class OpenCodeAgentSession implements AgentSession {
readonly provider: "opencode" = "opencode";
readonly provider = "opencode" as const;
readonly capabilities = OPENCODE_CAPABILITIES;
private readonly config: OpenCodeAgentConfig;
@@ -55,7 +55,7 @@ console.log("ARGV_OK");
const shim = path.join(root, `${binaryName}.cmd`);
writeFileSync(
shim,
["@echo off", "setlocal", `\"${fakeDaemonNode}\" \"${assertScript}\" %*`, ""].join("\r\n"),
["@echo off", "setlocal", `"${fakeDaemonNode}" "${assertScript}" %*`, ""].join("\r\n"),
);
return { root, shim, expectedArgs };
@@ -79,7 +79,7 @@ function mergeToolCallItems(
const mergedDetail = mergeToolCallDetail(existing.detail, incoming.detail);
const mergedMetadata =
existing.metadata || incoming.metadata
? { ...(existing.metadata ?? {}), ...(incoming.metadata ?? {}) }
? { ...existing.metadata, ...incoming.metadata }
: undefined;
const merged: Extract<AgentTimelineItem, { type: "tool_call" }> = {
@@ -92,8 +92,8 @@ describe("daemon E2E checkout diff subscriptions", () => {
writeFileSync(path.join(cwd, "alpha.txt"), "alpha\n");
const update = await waitForCheckoutDiffUpdate(ctx, subscriptionId, (payload) => {
const paths = payload.files.map((file) => file.path);
return paths.includes("alpha.txt") && paths.includes("zeta.txt");
const paths = new Set(payload.files.map((file) => file.path));
return paths.has("alpha.txt") && paths.has("zeta.txt");
});
expect(update.error).toBeNull();
@@ -26,7 +26,7 @@ const BACKGROUND_TASK_SLEEP_5_PROMPT = [
const BACKGROUND_TASK_SLEEP_5_REPEAT_PROMPT = `do it again: ${BACKGROUND_TASK_SLEEP_5_PROMPT}`;
function sanitizeClaudeProjectPath(cwd: string): string {
return cwd.replace(/[\\/\.]/g, "-").replace(/_/g, "-");
return cwd.replace(/[\\/.]/g, "-").replace(/_/g, "-");
}
function resolveClaudeTranscriptPath(params: { cwd: string; sessionId: string }): string {
@@ -169,13 +169,13 @@ function extractTranscriptRaceEvidence(
const userLines = lines.filter((line) => line.type === "user");
const assistantLines = lines.filter((line) => line.type === "assistant");
const doItAgain = [...userLines]
.reverse()
.toReversed()
.find((line) => readUserText(line).toLowerCase().includes("do it again"));
const isHelloPrompt = (line: ClaudeTranscriptLine): boolean => {
const text = readUserText(line).trim().toLowerCase();
return text === "hello" || text === "say exactly hello";
};
const helloUser = [...userLines].reverse().find((line) => isHelloPrompt(line));
const helloUser = [...userLines].toReversed().find((line) => isHelloPrompt(line));
if (!doItAgain || !helloUser || typeof helloUser.uuid !== "string") {
return null;
@@ -201,7 +201,7 @@ function extractTranscriptRaceEvidence(
return readUserText(line).includes("<task-notification>");
});
const taskNotificationUser =
[...taskNotificationCandidates].reverse().find((line) => parseTimestamp(line) >= helloTs) ??
[...taskNotificationCandidates].toReversed().find((line) => parseTimestamp(line) >= helloTs) ??
taskNotificationCandidates[0];
if (!taskNotificationUser || typeof taskNotificationUser.uuid !== "string") {
return null;
@@ -260,7 +260,9 @@ describe("ConnectionOfferV2 (daemon E2E)", () => {
expect(sawListeningLog).toBe(true);
} catch (err) {
throw new Error(`failed; stdout so far:\\n${stdoutLines.join("")}\\n\\n${String(err)}`);
throw new Error(`failed; stdout so far:\\n${stdoutLines.join("")}\\n\\n${String(err)}`, {
cause: err,
});
} finally {
proc.kill();
await rm(tempHome, { recursive: true, force: true });
+3 -3
View File
@@ -37,7 +37,7 @@ type ResolveLogConfigOptions = {
env?: NodeJS.ProcessEnv;
};
const LOG_LEVELS: LogLevel[] = ["trace", "debug", "info", "warn", "error", "fatal"];
const LOG_LEVELS: LogLevel[] = new Set(["trace", "debug", "info", "warn", "error", "fatal"]);
const LOG_FORMATS: LogFormat[] = ["pretty", "json"];
const LOG_LEVEL_PRIORITIES: Record<LogLevel, number> = {
trace: 10,
@@ -56,7 +56,7 @@ const DEFAULT_FILE_ROTATE_MAX_FILES = 2;
const DEFAULT_DAEMON_LOG_FILENAME = "daemon.log";
function parseLogLevel(value: string | undefined): LogLevel | undefined {
if (!value || !LOG_LEVELS.includes(value as LogLevel)) {
if (!value || !LOG_LEVELS.has(value as LogLevel)) {
return undefined;
}
return value as LogLevel;
@@ -158,7 +158,7 @@ function rotateOnRestart(filePath: string, maxFiles: number): void {
const rotatedFiles = readdirSync(dir)
.filter((f) => f.endsWith(`-${base}`) && f !== base)
.sort()
.reverse();
.toReversed();
for (const file of rotatedFiles.slice(maxFiles)) {
try {
@@ -362,7 +362,7 @@ export function loadPersistedConfig(paseoHome: string, logger?: LoggerLike): Per
log?.info(`Initialized config file at ${configPath}`);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`[Config] Failed to initialize ${configPath}: ${message}`);
throw new Error(`[Config] Failed to initialize ${configPath}: ${message}`, { cause: err });
}
}
@@ -371,7 +371,7 @@ export function loadPersistedConfig(paseoHome: string, logger?: LoggerLike): Per
raw = readFileSync(configPath, "utf-8");
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`[Config] Failed to read ${configPath}: ${message}`);
throw new Error(`[Config] Failed to read ${configPath}: ${message}`, { cause: err });
}
let parsed: unknown;
@@ -379,7 +379,7 @@ export function loadPersistedConfig(paseoHome: string, logger?: LoggerLike): Per
parsed = JSON.parse(raw);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`[Config] Invalid JSON in ${configPath}: ${message}`);
throw new Error(`[Config] Invalid JSON in ${configPath}: ${message}`, { cause: err });
}
const migrated = stripDeprecatedLocalSpeechConfigFields(parsed);
@@ -416,6 +416,6 @@ export function savePersistedConfig(
log?.info(`Saved to ${configPath}`);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`[Config] Failed to write ${configPath}: ${message}`);
throw new Error(`[Config] Failed to write ${configPath}: ${message}`, { cause: err });
}
}
+10 -7
View File
@@ -3665,7 +3665,9 @@ export class Session {
const snapshot = await this.workspaceGitService.getSnapshot(cwd);
return snapshot.git.isDirty === true;
} catch (error) {
throw new Error(`Unable to inspect git status for ${cwd}: ${(error as Error).message}`);
throw new Error(`Unable to inspect git status for ${cwd}: ${(error as Error).message}`, {
cause: error,
});
}
}
@@ -7452,7 +7454,7 @@ export class Session {
const final = await this.getAgentPayloadById(agentId);
if (!final) {
throw new Error(`Agent ${agentId} disappeared while waiting`);
throw new Error(`Agent ${agentId} disappeared while waiting`, { cause: error });
}
this.emit({
type: "wait_for_finish_response",
@@ -8721,11 +8723,12 @@ export class Session {
this.emitTerminalsChangedSnapshot({
cwd: event.cwd,
terminals: this.filterStandaloneTerminals(event.terminals).map((terminal) => ({
id: terminal.id,
name: terminal.name,
...(terminal.title ? { title: terminal.title } : {}),
})),
terminals: this.filterStandaloneTerminals(event.terminals).map((terminal) =>
Object.assign(
{ id: terminal.id, name: terminal.name },
terminal.title ? { title: terminal.title } : {},
),
),
});
}
@@ -208,10 +208,7 @@ export type SherpaOnnxModelSpec = SherpaOnnxCatalogEntry & {
};
export function listSherpaOnnxModels(): SherpaOnnxModelSpec[] {
return ALL_MODEL_IDS.map((id) => ({
id,
...SHERPA_ONNX_MODEL_CATALOG[id],
}));
return ALL_MODEL_IDS.map((id) => Object.assign({ id }, SHERPA_ONNX_MODEL_CATALOG[id]));
}
export function getSherpaOnnxModelSpec(id: SherpaOnnxModelId): SherpaOnnxModelSpec {
@@ -245,7 +245,7 @@ export class OpenAISTT implements SpeechToTextProvider {
};
} catch (error: any) {
logger.error({ err: error }, "Transcription error");
throw new Error(`STT transcription failed: ${error.message}`);
throw new Error(`STT transcription failed: ${error.message}`, { cause: error });
} finally {
if (tempFilePath) {
try {
@@ -76,7 +76,7 @@ export class OpenAITTS implements TextToSpeechProvider {
};
} catch (error: any) {
this.logger.error({ err: error }, "Speech synthesis error");
throw new Error(`TTS synthesis failed: ${error.message}`);
throw new Error(`TTS synthesis failed: ${error.message}`, { cause: error });
}
}
}
@@ -88,7 +88,7 @@ function buildPersistence(
metadata?: Record<string, unknown>,
): AgentPersistenceHandle {
if (provider === "codex") {
return { provider, sessionId, metadata: { conversationId: sessionId, ...(metadata ?? {}) } };
return { provider, sessionId, metadata: { conversationId: sessionId, ...metadata } };
}
return { provider, sessionId, ...(metadata ? { metadata } : {}) };
}
@@ -150,7 +150,7 @@ function buildToolCallForPrompt(provider: string, prompt: string) {
return { name: "apply_patch", input: { patch: "*** Begin Patch\n*** End Patch\n" }, output };
}
const printfMatch =
/printf\s+\"ok\"\s*>\s*([^\s`]+)/i.exec(text) ?? /printf\s+ok\s*>\s*([^\s`]+)/i.exec(text);
/printf\s+"ok"\s*>\s*([^\s`]+)/i.exec(text) ?? /printf\s+ok\s*>\s*([^\s`]+)/i.exec(text);
if (printfMatch) {
const fileName = printfMatch[1] ?? "permission.txt";
return {
@@ -285,6 +285,7 @@ describe("voice roundtrip e2e", () => {
} catch (error) {
throw new Error(
`${error instanceof Error ? error.message : String(error)} | requestedVoiceAgentId=${voiceAgentId} | timelineTools=${JSON.stringify(timelineTools)} | timelineToolAgentIds=${JSON.stringify(Array.from(timelineToolAgentIds))} | activityErrors=${JSON.stringify(activityErrors)}`,
{ cause: error },
);
} finally {
offStream();
@@ -46,7 +46,7 @@ import {
} from "./paseo-worktree-archive-service.js";
import { toWorktreeWireError } from "./worktree-errors.js";
const SAFE_GIT_REF_PATTERN = /^[A-Za-z0-9._\/-]+$/;
const SAFE_GIT_REF_PATTERN = /^[A-Za-z0-9._/-]+$/;
export interface NormalizedGitOptions {
baseBranch?: string;
@@ -153,7 +153,7 @@ export function findLatestAssistantMessageFromTimeline(
return null;
}
return chunks.reverse().join("");
return chunks.toReversed().join("");
}
export function findLatestPermissionRequest(
+2 -2
View File
@@ -240,7 +240,7 @@ program
// Print ancestors first (root to immediate parent)
if (ancestors.length > 0) {
process.stdout.write("# Parent Context\n\n");
for (const ancestor of ancestors.reverse()) {
for (const ancestor of ancestors.toReversed()) {
process.stdout.write(`## ${ancestor.title} (${ancestor.id}) [${ancestor.status}]\n`);
if (ancestor.body) {
process.stdout.write(`\n${ancestor.body}\n`);
@@ -702,7 +702,7 @@ async function buildTaskContext(task: Task, scopeId?: string): Promise<string> {
let parentContext = "";
if (ancestors.length > 0) {
parentContext = "# Parent Context\n\n";
for (const ancestor of ancestors.reverse()) {
for (const ancestor of ancestors.toReversed()) {
parentContext += `## ${ancestor.title} (${ancestor.id})\n`;
if (ancestor.body) {
parentContext += `\n${ancestor.body}\n`;
@@ -154,7 +154,7 @@ describe("TerminalManager", () => {
for (let attempt = 0; attempt < 10 && !existsSync(markerPath); attempt++) {
session.send({
type: "input",
data: `printf '%s' \"$PASEO_WORKTREE_PORT\" > ${JSON.stringify(markerPath)}\r`,
data: `printf '%s' "$PASEO_WORKTREE_PORT" > ${JSON.stringify(markerPath)}\r`,
});
await new Promise((resolve) => setTimeout(resolve, 100));
}
@@ -181,7 +181,7 @@ describe("TerminalManager", () => {
for (let attempt = 0; attempt < 10 && !existsSync(markerPath); attempt++) {
session.send({
type: "input",
data: `printf '%s' \"$PASEO_WORKTREE_PORT\" > ${JSON.stringify(markerPath)}\r`,
data: `printf '%s' "$PASEO_WORKTREE_PORT" > ${JSON.stringify(markerPath)}\r`,
});
await new Promise((resolve) => setTimeout(resolve, 100));
}
@@ -172,9 +172,7 @@ export function createTerminalManager(): TerminalManager {
const defaultName = `Terminal ${terminals.length + 1}`;
const inheritedEnv = resolveDefaultEnvForCwd(options.cwd);
const mergedEnv =
inheritedEnv || options.env
? { ...(inheritedEnv ?? {}), ...(options.env ?? {}) }
: undefined;
inheritedEnv || options.env ? { ...inheritedEnv, ...options.env } : undefined;
const session = registerSession(
await createTerminal({
...(options.id ? { id: options.id } : {}),
+8 -6
View File
@@ -1047,15 +1047,17 @@ export async function resolveRepositoryDefaultBranch(repoRoot: string): Promise<
cwd: repoRoot,
env: READ_ONLY_GIT_ENV,
});
const branches = stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0);
const branches = new Set(
stdout
.split("\n")
.map((line) => line.trim())
.filter((line) => line.length > 0),
);
if (branches.includes("main")) {
if (branches.has("main")) {
return "main";
}
if (branches.includes("master")) {
if (branches.has("master")) {
return "master";
}
@@ -57,7 +57,7 @@ console.log("ARGV_OK");
if (options?.includeCmdShim !== false) {
writeFileSync(
shim,
["@echo off", "setlocal", `\"${fakeDaemonNode}\" \"${assertScript}\" %*`, ""].join("\r\n"),
["@echo off", "setlocal", `"${fakeDaemonNode}" "${assertScript}" %*`, ""].join("\r\n"),
);
}