Skip to content

Commit 4df615e

Browse files
Sync public snapshot from freebuff-private
Source: CodebuffAI/freebuff-private@165e8ac18ebed832547fcb6fdf324824a8061b85
1 parent 2fcd26f commit 4df615e

8 files changed

Lines changed: 1543 additions & 507 deletions

File tree

‎bun.lock‎

Lines changed: 47 additions & 57 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎cli/src/utils/__tests__/sponsored-clamps.test.ts‎

Lines changed: 51 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,10 @@ describe('the write guard', () => {
215215
})
216216

217217
describe('the real rooted filesystem passed to SDK tools', () => {
218-
test('reads inside the worktree only when OS containment is available', async () => {
218+
// Since COD-642 the file layer runs no shell and needs no broker, so these
219+
// work with or without an OS sandbox on the host. They used to answer
220+
// `[FILE_READ_ERROR]` wherever no sandbox could start.
221+
test('reads inside the worktree without a shell or OS containment', async () => {
219222
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-fs-'))
220223
const root = join(parent, 'worktree')
221224
mkdirSync(join(root, 'src'), { recursive: true })
@@ -224,71 +227,60 @@ describe('the real rooted filesystem passed to SDK tools', () => {
224227
const tools = sponsoredOverrideTools(isolatedContext(root, parent))
225228

226229
const read = await tools.read_files({ filePaths: ['src/inside.ts'] })
227-
if (containmentUsable()) {
228-
expect(read['src/inside.ts']).toContain('export const before = 1')
229-
} else {
230-
expect(read['src/inside.ts']).toBe('[FILE_READ_ERROR]')
231-
expect(read['src/inside.ts']).not.toContain('export const before = 1')
232-
}
230+
expect(read['src/inside.ts']).toContain('export const before = 1')
233231
} finally {
234232
rmSync(parent, { recursive: true, force: true })
235233
}
236234
})
237235

238-
test.skipIf(!containmentUsable())(
239-
'lists and globs inside the worktree through OS containment',
240-
async () => {
241-
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-list-'))
242-
const root = join(parent, 'worktree')
243-
mkdirSync(join(root, 'src'), { recursive: true })
244-
writeFileSync(join(root, 'src', 'inside.ts'), 'export const before = 1\n')
245-
try {
246-
const tools = sponsoredOverrideTools(isolatedContext(root, parent))
247-
const listed = await tools.list_directory({ path: 'src' })
248-
expect(JSON.stringify(listed)).toContain('inside.ts')
236+
test('lists and globs inside the worktree without a shell', async () => {
237+
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-list-'))
238+
const root = join(parent, 'worktree')
239+
mkdirSync(join(root, 'src'), { recursive: true })
240+
writeFileSync(join(root, 'src', 'inside.ts'), 'export const before = 1\n')
241+
try {
242+
const tools = sponsoredOverrideTools(isolatedContext(root, parent))
243+
const listed = await tools.list_directory({ path: 'src' })
244+
expect(JSON.stringify(listed)).toContain('inside.ts')
249245

250-
const globbed = await tools.glob({ pattern: '**/*.ts' })
251-
expect(JSON.stringify(globbed)).toContain('src/inside.ts')
252-
} finally {
253-
rmSync(parent, { recursive: true, force: true })
254-
}
255-
},
256-
)
246+
const globbed = await tools.glob({ pattern: '**/*.ts' })
247+
expect(JSON.stringify(globbed)).toContain('src/inside.ts')
248+
} finally {
249+
rmSync(parent, { recursive: true, force: true })
250+
}
251+
})
257252

258-
test.skipIf(!containmentUsable())(
259-
'writes and patches inside the worktree through OS containment',
260-
async () => {
261-
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-write-'))
262-
const root = join(parent, 'worktree')
263-
mkdirSync(join(root, 'src'), { recursive: true })
264-
try {
265-
const tools = sponsoredOverrideTools(isolatedContext(root, parent))
266-
const written = await tools.write_file({
267-
type: 'file',
268-
path: 'src/written.ts',
269-
content: 'export const written = true\n',
270-
})
271-
expect(JSON.stringify(written)).toContain('Created file successfully')
272-
273-
const patched = await tools.apply_patch({
274-
operation: {
275-
type: 'create_file',
276-
path: 'src/patched.ts',
277-
diff: '@@ -0,0 +1 @@\n+export const patched = true\n',
278-
},
279-
})
280-
expect(JSON.stringify(patched)).toContain('Applied 1 patch operation')
281-
expect(readFileSync(join(root, 'src', 'written.ts'), 'utf8')).toContain(
282-
'written = true',
283-
)
284-
expect(readFileSync(join(root, 'src', 'patched.ts'), 'utf8')).toContain(
285-
'patched = true',
286-
)
287-
} finally {
288-
rmSync(parent, { recursive: true, force: true })
289-
}
290-
},
291-
)
253+
test('writes and patches inside the worktree without a shell', async () => {
254+
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-write-'))
255+
const root = join(parent, 'worktree')
256+
mkdirSync(join(root, 'src'), { recursive: true })
257+
try {
258+
const tools = sponsoredOverrideTools(isolatedContext(root, parent))
259+
const written = await tools.write_file({
260+
type: 'file',
261+
path: 'src/written.ts',
262+
content: 'export const written = true\n',
263+
})
264+
expect(JSON.stringify(written)).toContain('Created file successfully')
265+
266+
const patched = await tools.apply_patch({
267+
operation: {
268+
type: 'create_file',
269+
path: 'src/patched.ts',
270+
diff: '@@ -0,0 +1 @@\n+export const patched = true\n',
271+
},
272+
})
273+
expect(JSON.stringify(patched)).toContain('Applied 1 patch operation')
274+
expect(readFileSync(join(root, 'src', 'written.ts'), 'utf8')).toContain(
275+
'written = true',
276+
)
277+
expect(readFileSync(join(root, 'src', 'patched.ts'), 'utf8')).toContain(
278+
'patched = true',
279+
)
280+
} finally {
281+
rmSync(parent, { recursive: true, force: true })
282+
}
283+
})
292284

293285
test('refuses dangling links and a link introduced after the surface guard', async () => {
294286
const parent = mkdtempSync(join(tmpdir(), 'sponsored-cli-links-'))

‎cli/src/utils/sponsored-run.ts‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,11 +1457,8 @@ export function sponsoredOverrideTools(
14571457
runtimeDir: context.runtimeDir,
14581458
linkedWorktree: context.worktree.linked,
14591459
})
1460-
const rootedFs = createSponsoredRootedFileSystem({
1461-
workspaceRoot,
1462-
runtimeDir: context.runtimeDir,
1463-
processBroker,
1464-
})
1460+
// No broker: the file layer pins directories itself (COD-642).
1461+
const rootedFs = createSponsoredRootedFileSystem({ workspaceRoot })
14651462
return {
14661463
read_files: async (input: {
14671464
filePaths: string[]
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { describe, expect, it } from 'bun:test'
2+
import fs from 'fs'
3+
import os from 'os'
4+
import path from 'path'
5+
6+
import {
7+
createSponsoredCodeSearchBroker,
8+
sponsoredRipgrepArgs,
9+
} from '../tools/sponsored-sandbox'
10+
import { codeSearch } from '../tools/code-search'
11+
12+
/**
13+
* Sponsored `code_search` with FIXED ripgrep arguments, spawned directly
14+
* (COD-642).
15+
*
16+
* Kept apart from `sponsored-sandbox.test.ts` so it can run on Windows CI
17+
* (`smoke-windows-bash`): nothing here needs a shell or an OS sandbox. The
18+
* sandboxed macOS/Linux search is exercised by the contained test in that
19+
* suite.
20+
*/
21+
22+
function workspace(): { root: string; runtime: string; parent: string } {
23+
const parent = fs.realpathSync(
24+
fs.mkdtempSync(path.join(os.tmpdir(), 'sponsored-search-')),
25+
)
26+
const root = path.join(parent, 'worktree')
27+
const runtime = path.join(parent, 'runtime')
28+
fs.mkdirSync(root, { recursive: true })
29+
fs.mkdirSync(runtime, { recursive: true })
30+
return { root, runtime, parent }
31+
}
32+
33+
describe('sponsored code search: fixed arguments, no shell', () => {
34+
it('runs ripgrep only with the argv it builds, and appends the fixed flags last', () => {
35+
const { root, parent } = workspace()
36+
fs.mkdirSync(path.join(root, '.github'))
37+
try {
38+
expect(
39+
sponsoredRipgrepArgs(
40+
[
41+
'--no-config',
42+
'-n',
43+
'--json',
44+
'-i',
45+
'-g',
46+
'*.ts',
47+
'--',
48+
'-x',
49+
'.',
50+
'.github',
51+
],
52+
root,
53+
),
54+
).toEqual([
55+
'--no-config',
56+
'-n',
57+
'--json',
58+
'-i',
59+
'-g',
60+
'*.ts',
61+
// After the caller's flags, so ripgrep's last-flag-wins makes them stick.
62+
'--no-follow',
63+
'--no-ignore-parent',
64+
'--no-ignore-global',
65+
'--',
66+
'-x',
67+
'.',
68+
'.github',
69+
])
70+
for (const args of [
71+
['-n', '--json', '--', 'x', '.'],
72+
['--no-config', '-n', '--json', '--pre', 'cat', '--', 'x', '.'],
73+
['--no-config', '-n', '--json', '--follow', '--', 'x', '.'],
74+
['--no-config', '-n', '--json', '--ignore-file', 'x', '--', 'x', '.'],
75+
['--no-config', '-n', '--json', '--', 'x', '/etc'],
76+
['--no-config', '-n', '--json', '--', 'x', '..'],
77+
['--no-config', '-n', '--json', 'x', '.'],
78+
['--no-config', '-n', '--json', '--'],
79+
]) {
80+
expect(() => sponsoredRipgrepArgs(args, root), args.join(' ')).toThrow()
81+
}
82+
} finally {
83+
fs.rmSync(parent, { recursive: true, force: true })
84+
}
85+
})
86+
87+
it('drops an included hidden directory that is a link, since ripgrep follows a named path', () => {
88+
const { root, parent } = workspace()
89+
const outside = path.join(parent, 'outside')
90+
fs.mkdirSync(outside)
91+
fs.symlinkSync(
92+
outside,
93+
path.join(root, '.github'),
94+
process.platform === 'win32' ? 'junction' : 'dir',
95+
)
96+
try {
97+
expect(
98+
sponsoredRipgrepArgs(
99+
['--no-config', '-n', '--json', '--', 'x', '.', '.github'],
100+
root,
101+
).slice(-2),
102+
).toEqual(['x', '.'])
103+
} finally {
104+
fs.rmSync(parent, { recursive: true, force: true })
105+
}
106+
})
107+
108+
it('runs ripgrep directly, with no shell and no sandbox, on Windows', async () => {
109+
// Windows has no OS sandbox and no `/bin/sh`, so a search there spawns the
110+
// bundled binary itself. Exercised on every OS by naming the platform,
111+
// since the direct spawn is the same code whatever binary it starts; on
112+
// Windows CI it starts the real `rg.exe`.
113+
const { root, runtime, parent } = workspace()
114+
const outside = path.join(parent, 'outside')
115+
fs.mkdirSync(outside)
116+
fs.writeFileSync(path.join(outside, 'secret.ts'), 'NEEDLE_OUTSIDE\n')
117+
fs.writeFileSync(
118+
path.join(root, 'inside.ts'),
119+
'export const NEEDLE = true\n',
120+
)
121+
try {
122+
const processBroker = createSponsoredCodeSearchBroker({
123+
workspaceRoot: root,
124+
runtimeDir: runtime,
125+
platform: 'win32',
126+
})
127+
const found = await codeSearch({
128+
projectPath: root,
129+
pattern: 'NEEDLE',
130+
flags: '-g *.ts',
131+
processBroker,
132+
})
133+
expect(JSON.stringify(found)).toContain('export const NEEDLE = true')
134+
expect(JSON.stringify(found)).not.toContain('NEEDLE_OUTSIDE')
135+
136+
// The working directory is re-checked by the broker itself, not left to
137+
// the surface that called it.
138+
const refused = await codeSearch({
139+
projectPath: root,
140+
pattern: 'NEEDLE',
141+
cwd: outside,
142+
processBroker,
143+
})
144+
expect(JSON.stringify(refused)).toContain('inside its own worktree')
145+
expect(JSON.stringify(refused)).not.toContain('NEEDLE_OUTSIDE')
146+
147+
// Nothing to stage for: the binary runs where it is installed.
148+
expect(
149+
fs.readdirSync(runtime).filter((name) => name.startsWith('rg-')),
150+
).toEqual([])
151+
} finally {
152+
fs.rmSync(parent, { recursive: true, force: true })
153+
}
154+
})
155+
})

0 commit comments

Comments
 (0)