Skip to content

Commit 470de91

Browse files
authored
Windows: Update context directory regex to match Windows-style file patterns (#1014)
I have added tests, but here also a screenshot from Windows machine correctly matching current directory from the caller: <img width="1097" height="501" alt="Screenshot 2025-11-07 at 19 37 41" src="https://github.com/user-attachments/assets/95e3f7e2-efd2-44f9-867e-6de54400c07a" /> <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Enhances `matchFileDir` to parse Windows and file:// stack trace paths and adds tests; include changeset for patch release. > > - **packages/js-sdk**: > - **Template utils (`src/template/utils.ts`)**: > - Update `matchFileDir` regex and normalization to support Windows drive letters, backslashes, and `file:///` URIs; strip `:line:column` and trailing `)`. > - **Tests (`tests/template/utils/matchFileDir.test.ts`)**: > - Add cases for Windows paths (with/without anonymous), `file:///` URIs, and paths containing parentheses. > - **Release**: > - Add changeset (`.changeset/every-wolves-brake.md`) marking a patch for `e2b`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit eb53033. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 56d16a8 commit 470de91

File tree

3 files changed

+90
-3
lines changed

3 files changed

+90
-3
lines changed

.changeset/every-wolves-brake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'e2b': patch
3+
---
4+
5+
fixes default context directory for windows paths

packages/js-sdk/src/template/utils.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,28 @@ export function getCallerFrame(depth: number): string | undefined {
182182
* Matches patterns like:
183183
* - "at <anonymous> (/path/to/file.js:1:1)"
184184
* - "at /path/to/file.js:1:1"
185-
*
185+
* - "at <anonymous> (file:///C:/path/to/file.js:1:1)"
186+
* - "at (file:///C:/path/to/file.js:1:1)"
186187
* @param line A line from a stack trace
187188
* @returns The directory of the file, or undefined if not found
188189
*/
189190
export function matchFileDir(line: string): string | undefined {
190-
const match = line.match(/\/[^:]+/)
191+
const match = line.match(
192+
/(?:file:\/\/\/)?([A-Za-z]:)?([/\\][^:]+)(?::\d+:\d+)?\)?/
193+
)
191194
if (match) {
192-
const filePath = match[0]
195+
// Extract the full matched path
196+
let filePath = match[0]
197+
198+
// Remove file:/// protocol prefix if present
199+
filePath = filePath.replace(/^file:\/\/\//, '')
200+
201+
// Remove trailing closing parenthesis if present
202+
filePath = filePath.replace(/\)$/, '')
203+
204+
// Remove :line:column suffix if present
205+
filePath = filePath.replace(/:\d+:\d+$/, '')
206+
193207
return path.dirname(filePath)
194208
}
195209
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,78 @@
11
import { expect, test } from 'vitest'
22
import { matchFileDir } from '../../../src/template/utils'
33

4+
// Basic Unix/Linux paths
45
test('matchFileDir', () => {
56
expect(matchFileDir('at /path/to/file.js:1:1')).toBe('/path/to')
67
})
78

89
test('matchFileDir (anonymous)', () => {
910
expect(matchFileDir('at <anonymous> (/path/to/file.js:1:1)')).toBe('/path/to')
1011
})
12+
13+
test('matchFileDir Unix path with spaces', () => {
14+
expect(matchFileDir('at /home/user/my project/file.js:1:1')).toBe(
15+
'/home/user/my project'
16+
)
17+
})
18+
19+
test('matchFileDir Unix path with special characters', () => {
20+
expect(matchFileDir('at /path/to-my_dir.test/file.js:1:1')).toBe(
21+
'/path/to-my_dir.test'
22+
)
23+
})
24+
25+
test('matchFileDir Unix root directory', () => {
26+
expect(matchFileDir('at /file.js:1:1')).toBe('/')
27+
})
28+
29+
test('matchFileDir Unix path with @symbol (scoped packages)', () => {
30+
expect(matchFileDir('at /node_modules/@scope/package/index.js:1:1')).toBe(
31+
'/node_modules/@scope/package'
32+
)
33+
})
34+
35+
test('matchFileDir Unix path with brackets (Next.js dynamic routes)', () => {
36+
expect(matchFileDir('at /app/routes/[id]/page.js:1:1')).toBe(
37+
'/app/routes/[id]'
38+
)
39+
})
40+
41+
// Basic Windows paths (forward slash)
42+
test('matchFileDir Windows path', () => {
43+
expect(matchFileDir('at C:/path/to/file.js:1:1')).toBe('C:/path/to')
44+
})
45+
46+
test('matchFileDir Windows path (anonymous)', () => {
47+
expect(matchFileDir('at <anonymous> (C:/path/to/file.js:1:1)')).toBe(
48+
'C:/path/to'
49+
)
50+
})
51+
52+
test('matchFileDir Windows path with spaces', () => {
53+
expect(matchFileDir('at C:/Program Files/App/index.js:1:1')).toBe(
54+
'C:/Program Files/App'
55+
)
56+
})
57+
58+
// File protocol paths
59+
test('matchFileDir file:// protocol Windows', () => {
60+
expect(matchFileDir('at <anonymous> (file:///C:/path/to/file.js:1:1)')).toBe(
61+
'C:/path/to'
62+
)
63+
})
64+
65+
test('matchFileDir file:// protocol Windows (no anonymous)', () => {
66+
expect(matchFileDir('at (file:///C:/path/to/file.js:1:1)')).toBe('C:/path/to')
67+
})
68+
69+
// Paths with parentheses
70+
test('matchFileDir with parentheses in path', () => {
71+
expect(matchFileDir('at /path/to(1)/file.js:1:1')).toBe('/path/to(1)')
72+
})
73+
74+
test('matchFileDir with parentheses in path (anonymous)', () => {
75+
expect(matchFileDir('at <anonymous> (/path/to(1)/file.js:1:1)')).toBe(
76+
'/path/to(1)'
77+
)
78+
})

0 commit comments

Comments
 (0)