From f45a8cb7a122db73109cb57a0bd1b3efabb59050 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Mon, 3 Aug 2026 20:20:23 -0700 Subject: [PATCH] fix(mobile): detect files directly under path roots --- .../markdown-file-path-detection.test.ts | 15 +++++++++++++++ .../components/markdown-file-path-detection.ts | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/mobile/src/components/markdown-file-path-detection.test.ts b/mobile/src/components/markdown-file-path-detection.test.ts index 1b78c102692..7e029e45d33 100644 --- a/mobile/src/components/markdown-file-path-detection.test.ts +++ b/mobile/src/components/markdown-file-path-detection.test.ts @@ -74,6 +74,21 @@ describe('detectFilePathSegments', () => { expect(detectFilePathSegments('/repo/src/index.ts')).toEqual([ { type: 'file', value: '/repo/src/index.ts', path: '/repo/src/index.ts' } ]) + expect(detectFilePathSegments('/root.ts')).toEqual([ + { type: 'file', value: '/root.ts', path: '/root.ts' } + ]) + }) + + it('detects files directly under explicit Windows and relative roots', () => { + expect(detectFilePathSegments(String.raw`C:\root.ts`)).toEqual([ + { type: 'file', value: String.raw`C:\root.ts`, path: String.raw`C:\root.ts` } + ]) + expect(detectFilePathSegments('./root.ts')).toEqual([ + { type: 'file', value: './root.ts', path: 'root.ts' } + ]) + expect(detectFilePathSegments('../root.ts')).toEqual([ + { type: 'file', value: '../root.ts', path: '../root.ts' } + ]) }) it('detects paths with :line and :line:col suffixes', () => { diff --git a/mobile/src/components/markdown-file-path-detection.ts b/mobile/src/components/markdown-file-path-detection.ts index cf24b2c4b51..744727869a4 100644 --- a/mobile/src/components/markdown-file-path-detection.ts +++ b/mobile/src/components/markdown-file-path-detection.ts @@ -87,7 +87,7 @@ const EXTENSION_SET = new Set(FILE_EXTENSIONS) // alternatives cover Windows drives, UNC, and POSIX absolute roots; the optional // tail captures agent-style :line(:col) citations. const CANDIDATE_PATTERN = - /(?:[A-Za-z]:[\\/]|\\\\|[\\/])?(?:\.{1,2}[\\/])?(?:[\w.@~+-]+[\\/])+[\w.@+-]+\.[A-Za-z0-9]+(?::[1-9]\d*(?::[1-9]\d*)?)?/g + /(?:(?:[A-Za-z]:[\\/]|\\\\|[\\/]|\.{1,2}[\\/])(?:[\w.@~+-]+[\\/])*|(?:[\w.@~+-]+[\\/])+)[\w.@+-]+\.[A-Za-z0-9]+(?::[1-9]\d*(?::[1-9]\d*)?)?/g // A path candidate in chat prose is short; a much longer run can't hold one worth // linkifying but can push CANDIDATE_PATTERN into super-linear backtracking, so we