From 6f8bab7cd5155e7685d6dff8c445d1100328af7b Mon Sep 17 00:00:00 2001 From: Marius Wichtner Date: Wed, 8 Jul 2026 20:41:59 +0200 Subject: [PATCH] feat(config): expose stable sandbox schema --- apps/web/src/app/config.json/extras.ts | 21 ++++++++++++++++++++ apps/web/src/tests/cli-config-schema.test.ts | 17 ++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/apps/web/src/app/config.json/extras.ts b/apps/web/src/app/config.json/extras.ts index 8130a11ce5..41b2f80a51 100644 --- a/apps/web/src/app/config.json/extras.ts +++ b/apps/web/src/app/config.json/extras.ts @@ -75,6 +75,27 @@ export const kiloExtras = { description: 'Hide Kilo Gateway models that may train on your prompts from model listings', type: 'boolean', }, + sandbox: { + type: 'object', + properties: { + enabled: { + type: 'boolean', + description: 'Enable sandbox confinement for new sessions (default: false)', + }, + network: { + type: 'string', + enum: ['allow', 'deny'], + description: 'Control outbound network access from sandboxed tools (default: deny)', + }, + writable_paths: { + type: 'array', + items: { type: 'string' }, + description: 'Additional filesystem paths that sandboxed tools may write to', + }, + }, + additionalProperties: false, + description: 'Sandbox configuration for agent tools', + }, commit_message: { description: 'Configuration for AI-generated commit messages', type: 'object', diff --git a/apps/web/src/tests/cli-config-schema.test.ts b/apps/web/src/tests/cli-config-schema.test.ts index 8d4c371ea8..4a91edc7c7 100644 --- a/apps/web/src/tests/cli-config-schema.test.ts +++ b/apps/web/src/tests/cli-config-schema.test.ts @@ -51,6 +51,7 @@ describe('kilo config.json schema merge', () => { expect(props.terminal_command_display).toBeDefined(); expect(props.code_edit_display).toBeDefined(); expect(props.hide_prompt_training_models).toBeDefined(); + expect(props.sandbox).toBeDefined(); }); test('auto_collapse_reasoning is a boolean', () => { @@ -77,6 +78,22 @@ describe('kilo config.json schema merge', () => { expect(cm.properties.prompt).toEqual(expect.objectContaining({ type: 'string' })); }); + test('sandbox is a first-class config object', () => { + const sandbox = props.sandbox as { + properties: Record; + additionalProperties: boolean; + }; + expect(sandbox.properties.enabled.type).toBe('boolean'); + expect(sandbox.properties.network.enum).toEqual(['allow', 'deny']); + expect(sandbox.properties.writable_paths.type).toBe('array'); + expect(sandbox.additionalProperties).toBe(false); + + const experimental = props.experimental as { properties: Record }; + expect(experimental.properties.sandbox).toBeUndefined(); + expect(experimental.properties.sandbox_restrict_network).toBeUndefined(); + expect(experimental.properties.sandbox_writable_paths).toBeUndefined(); + }); + test('allows null on model and small_model', () => { const model = props.model as { anyOf: Array<{ type?: string }> }; expect(model.anyOf.some(m => m.type === 'null')).toBe(true);