mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
Merge pull request #12008 from Kilo-Org/feat/sandbox-writable-paths-ui-test
feat(sandbox): widen writable-paths settings input and add coverage
This commit is contained in:
@@ -242,6 +242,41 @@ describe("kilocode indexing config", () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe("kilocode sandbox writable paths config", () => {
|
||||
test("honors sandbox_writable_paths from global config only, ignoring project config", async () => {
|
||||
await using globalTmp = await tmpdir()
|
||||
await using tmp = await tmpdir({ git: true })
|
||||
|
||||
const prev = Global.Path.config
|
||||
;(Global.Path as { config: string }).config = globalTmp.path
|
||||
await clear()
|
||||
await disposeAllInstances()
|
||||
|
||||
try {
|
||||
await writeConfig(globalTmp.path, {
|
||||
$schema: "https://app.kilo.ai/config.json",
|
||||
experimental: { sandbox_writable_paths: ["/tmp/global"] },
|
||||
})
|
||||
// A project kilo.json must not widen the sandbox: its writable paths are dropped at merge time.
|
||||
await writeConfig(tmp.path, {
|
||||
experimental: { sandbox_writable_paths: ["/tmp/project"] },
|
||||
})
|
||||
|
||||
await provideTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async () => {
|
||||
const config = await load()
|
||||
expect(config.experimental?.sandbox_writable_paths).toEqual(["/tmp/global"])
|
||||
},
|
||||
})
|
||||
} finally {
|
||||
;(Global.Path as { config: string }).config = prev
|
||||
await clear()
|
||||
await disposeAllInstances()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("custom provider model config", () => {
|
||||
test("persists and removes reasoning across a global config reload", async () => {
|
||||
await using globalTmp = await tmpdir()
|
||||
|
||||
@@ -234,4 +234,34 @@ describe("sandbox policy", () => {
|
||||
expect(roots(ctx)).not.toContain(dirs.approved)
|
||||
expect(Exit.isFailure(result)).toBe(true)
|
||||
})
|
||||
|
||||
test("makes configured extra writable paths writable while unlisted paths stay denied", async () => {
|
||||
await using tmp = await fixture()
|
||||
const dirs = tmp.extra
|
||||
const ctx = context(dirs.a, dirs.a, dirs)
|
||||
const policy = profile(ctx, "deny", [dirs.approved])
|
||||
const result = await Effect.runPromise(
|
||||
Effect.all({
|
||||
extra: runSandbox(policy, assertWrite(path.join(dirs.approved, "allowed.txt")).pipe(Effect.exit)),
|
||||
other: runSandbox(policy, assertWrite(path.join(dirs.b, "denied.txt")).pipe(Effect.exit)),
|
||||
}),
|
||||
)
|
||||
|
||||
expect(policy.filesystem.allowWrite.map((rule) => rule.path)).toContain(dirs.approved)
|
||||
expect(roots(ctx)).not.toContain(dirs.approved)
|
||||
expect(Exit.isSuccess(result.extra)).toBe(true)
|
||||
expect(Exit.isFailure(result.other)).toBe(true)
|
||||
})
|
||||
|
||||
test("keeps .git denied inside a configured extra writable path", async () => {
|
||||
await using tmp = await fixture()
|
||||
const dirs = tmp.extra
|
||||
const ctx = context(dirs.a, dirs.a, dirs)
|
||||
const policy = profile(ctx, "deny", [dirs.approved])
|
||||
const result = await Effect.runPromise(
|
||||
runSandbox(policy, assertWrite(path.join(dirs.approved, ".git", "config")).pipe(Effect.exit)),
|
||||
)
|
||||
|
||||
expect(Exit.isFailure(result)).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user