From ffc6bd3ba596c23e136fa17302891e1f5caa2bfd Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 29 Dec 2025 00:15:21 +0700 Subject: [PATCH] Fix inline path linking for absolute cwd paths --- .../app/src/components/agent-stream-view.tsx | 72 ++++++++++++++++--- plan.md | 3 +- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/packages/app/src/components/agent-stream-view.tsx b/packages/app/src/components/agent-stream-view.tsx index 3f6a8d024..e1245d091 100644 --- a/packages/app/src/components/agent-stream-view.tsx +++ b/packages/app/src/components/agent-stream-view.tsx @@ -121,7 +121,7 @@ export function AgentStreamView({ return; } - const normalized = normalizeInlinePath(target.path); + const normalized = normalizeInlinePath(target.path, agent.cwd); if (!normalized) { return; } @@ -147,7 +147,14 @@ export function AgentStreamView({ }, }); }, - [agentId, requestDirectoryListingOrInert, requestFilePreviewOrInert, resolvedServerId, router] + [ + agent.cwd, + agentId, + requestDirectoryListingOrInert, + requestFilePreviewOrInert, + resolvedServerId, + router, + ] ); const handleScroll = useCallback( @@ -445,21 +452,26 @@ export function AgentStreamView({ ); } -function normalizeInlinePath(rawPath: string): +function normalizeInlinePath( + rawPath: string, + cwd?: string +): | { directory: string; file?: string } | null { if (!rawPath) { return null; } - let value = rawPath.trim(); - value = value.replace(/^['"`]/, "").replace(/['"`]$/, ""); - if (!value) { + const normalizedInput = normalizePathInput(rawPath); + if (!normalizedInput) { return null; } - let normalized = value.replace(/\\/g, "/"); - normalized = normalized.replace(/\/{2,}/g, "/"); + let normalized = normalizedInput; + const cwdRelative = resolvePathAgainstCwd(normalized, cwd); + if (cwdRelative) { + normalized = cwdRelative; + } if (normalized.startsWith("./")) { normalized = normalized.slice(2) || "."; @@ -487,6 +499,50 @@ function normalizeInlinePath(rawPath: string): }; } +function normalizePathInput(value: string | undefined): string | null { + if (!value) { + return null; + } + + const trimmed = value.trim().replace(/^['"`]/, "").replace(/['"`]$/, ""); + if (!trimmed) { + return null; + } + + return trimmed.replace(/\\/g, "/").replace(/\/{2,}/g, "/"); +} + +function resolvePathAgainstCwd(pathValue: string, cwd?: string): string | null { + const normalizedCwd = normalizePathInput(cwd); + if (!normalizedCwd || !isAbsolutePath(pathValue) || !isAbsolutePath(normalizedCwd)) { + return null; + } + + const normalizedCwdBase = normalizedCwd.replace(/\/+$/, "") || "/"; + const comparePath = normalizePathForCompare(pathValue); + const compareCwd = normalizePathForCompare(normalizedCwdBase); + const prefix = normalizedCwdBase === "/" ? "/" : `${normalizedCwdBase}/`; + const comparePrefix = normalizePathForCompare(prefix); + + if (comparePath === compareCwd) { + return "."; + } + + if (comparePath.startsWith(comparePrefix)) { + return pathValue.slice(prefix.length) || "."; + } + + return null; +} + +function normalizePathForCompare(value: string): string { + return /^[A-Za-z]:/.test(value) ? value.toLowerCase() : value; +} + +function isAbsolutePath(value: string): boolean { + return value.startsWith("/") || /^[A-Za-z]:\//.test(value); +} + function WorkingIndicator() { const dotOne = useSharedValue(0); const dotTwo = useSharedValue(0); diff --git a/plan.md b/plan.md index e61464ea0..36970c9f1 100644 --- a/plan.md +++ b/plan.md @@ -80,12 +80,13 @@ Improvements to the new agent screen in the app. - Investigate the loading state management and fix the race condition. - **Done (2025-12-29 00:10)**: WHAT: `packages/app/src/contexts/session-context.tsx:1588-1645` routes back-navigation directory listings through the request helper and clears `pendingRequest`/`isLoading` on response. RESULT: gallery header loader no longer sticks after navigating back to cached directories. EVIDENCE: Not run (not requested). -- [ ] **Iteration 8**: Review and fix file/directory auto-linking logic. +- [x] **Iteration 8**: Review and fix file/directory auto-linking logic. - Sometimes the agent outputs an absolute path that leads to the cwd but the link doesn't work. - It appears the linking logic only accepts relative paths. - Review the path detection and linking logic. - Fix to handle both absolute and relative paths correctly. + - **Done (2025-12-29 00:15)**: WHAT: `packages/app/src/components/agent-stream-view.tsx:118` now normalizes inline paths using the agent cwd; `packages/app/src/components/agent-stream-view.tsx:455` adds path normalization helpers to convert absolute paths within the cwd to relative form before file explorer navigation. RESULT: absolute paths pointing at the agent cwd resolve to the correct directory/file in the explorer. EVIDENCE: Not run (not requested). - [ ] **Iteration 9**: Remove host label from git diff screen.