feat: default to full-access mode with hook-based sensitive guards

This commit is contained in:
William Valentin
2026-02-18 11:14:35 -08:00
parent fc2090b599
commit a76c5ae346
9 changed files with 72 additions and 8 deletions
+5
View File
@@ -10,6 +10,11 @@ describe('ConfigBuilder', () => {
expect(obj.models.default.provider).toBe('anthropic');
expect(obj.models.default.api_key).toBe('sk-ant-test');
expect(obj.server.port).toBe(3777);
expect(obj.tools?.profile).toBe('full');
expect(obj.agents?.sensitive_mode).toBe('confirm_without_elevation');
expect((obj.hooks?.confirm as string[]) ?? []).toEqual(
expect.arrayContaining(['shell.*', 'browser.*', 'message.send']),
);
});
it('adds telegram channel', () => {
+22 -1
View File
@@ -33,6 +33,9 @@ export interface SetupConfig {
sandbox?: { enabled?: boolean };
pairing?: { enabled?: boolean };
tools?: { profile?: string };
agents?: {
sensitive_mode?: 'deny_without_elevation' | 'confirm_without_elevation';
};
agent_configs?: Record<string, {
model_tier?: 'fast' | 'default' | 'complex' | 'local';
tool_profile?: string;
@@ -85,10 +88,22 @@ export class ConfigBuilder {
models: {},
server: { port: 18800, localhost: true },
hooks: {
confirm: ['shell.*', 'file.write', 'file.patch'],
confirm: [
'shell.*',
'process.start',
'process.kill',
'browser.*',
'message.send',
'cron.create',
'cron.delete',
'file.write',
'file.patch',
],
log: ['web.*', 'file.read'],
silent: ['notify'],
},
tools: { profile: 'full' },
agents: { sensitive_mode: 'confirm_without_elevation' },
};
}
@@ -171,6 +186,12 @@ export class ConfigBuilder {
this.config.tools = { profile };
}
setSensitiveMode(mode: 'deny_without_elevation' | 'confirm_without_elevation'): void {
const agents = (this.config.agents ?? {}) as Record<string, unknown>;
agents.sensitive_mode = mode;
this.config.agents = agents as SetupConfig['agents'];
}
setResearchAgentEnabled(options: ResearchAgentOptions): void {
const agentConfigs = (this.config.agent_configs ?? {}) as Record<string, Record<string, unknown>>;
const existing = (agentConfigs.research ?? {}) as Record<string, unknown>;
+2
View File
@@ -60,6 +60,8 @@ describe('setupSecurity', () => {
const config = builder.build();
expect(config.sandbox!.enabled).toBe(true);
expect(config.pairing!.enabled).toBe(true);
expect(config.tools?.profile).toBe('full');
expect(config.agents?.sensitive_mode).toBe('confirm_without_elevation');
expect(config.agent_configs?.research?.model_tier).toBe('complex');
expect(config.agent_configs?.research?.tool_profile).toBe('messaging');
});
+5 -4
View File
@@ -2,10 +2,10 @@ import type { Prompter } from './prompts.js';
import type { ConfigBuilder } from './config.js';
const TOOL_PROFILES = [
{ label: 'messaging (recommended)', value: 'messaging' },
{ label: 'minimal (status only)', value: 'minimal' },
{ label: 'full (recommended)', value: 'full' },
{ label: 'coding (fs + runtime)', value: 'coding' },
{ label: 'full (unrestricted)', value: 'full' },
{ label: 'messaging (read + services, no shell/writes)', value: 'messaging' },
{ label: 'minimal (status only)', value: 'minimal' },
];
const RESEARCH_AGENT_TIERS = [
@@ -35,12 +35,13 @@ export async function setupSecurity(p: Prompter, builder: ConfigBuilder): Promis
p.println();
p.println(' Tool profiles control which tools the agent can use:');
p.println(' full — all tools available (file, shell, web, memory, messaging)');
p.println(' full — all tools available (file, shell, web, memory, messaging) (default)');
p.println(' coding — file system + shell + sessions + memory');
p.println(' messaging — read-only + web/memory + connected services (no file writes/shell)');
p.println(' minimal — status checks only (read-only, safest)');
const profile = await p.choose('Tool policy profile:', TOOL_PROFILES);
builder.setToolProfile(profile);
builder.setSensitiveMode('confirm_without_elevation');
p.println();
p.println(' Research agent adds a dedicated specialist for deep web research.');