mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 13:22:37 +00:00
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:
+1
-9
@@ -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",
|
||||
|
||||
@@ -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 },
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 } : {}),
|
||||
|
||||
@@ -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"),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user