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