Skip to content
BreachPilot

Settings (/system)

Route: webui/src/App.tsx:74webui/src/routes/SystemPage.tsx:6 (thin wrapper) → webui/src/features/settings/SettingsPage.tsx:20 (SettingsPage).

Wraps content with SettingsDraftProvider (features/settings/useSettingsDraft.tsx) — single shared draft for all categories; PATCH /config is atomic on save, deep-merge on server (docs/api.md: PATCH /config).

Layout (SettingsPage.tsx:28)

<StatusOverview>  // read-only summary (providers, models, secrets, plugins)
header: title "Settings" + savedAt (formatSavedAt) + Diagnostics button → category "advanced" + <SettingsSearch>
body: <SettingsNav> (sidebar 44 on desktop, segmented on mobile) + <ActiveCategory>
<UnsavedChangesBar>  // sticky footer when draft !== server
ComponentFileRole
SettingsNavfeatures/settings/SettingsNav.tsx4 categories `general
SettingsSearchfeatures/settings/SettingsSearch.tsxglobal search across all SECTIONS; onSearchSelect(cat,section,field) → setCategory(cat) + requestAnimationFrame scrollIntoView #setting-${section}-${field}
StatusOverviewfeatures/settings/StatusOverview.tsxcompact read-only chips from capabilities/config/secrets/models/providers
UnsavedChangesBarfeatures/settings/UnsavedChangesBar.tsxappears when draft dirty; Save → usePatchConfig (api/hooks.ts:142), Discard → revert
SettingRowfeatures/settings/SettingRow.tsxlabel+help+field+validation error wrapper
ConfigField / ConfigEditorfeatures/settings/ConfigField.tsx, ConfigEditor.tsxtyped inputs, redacted preview (sanitize() server-side)

Categories:

General (GeneralSettings.tsx)

SectionFields (config keys)Control
APIapi.enabled, api.host, api.port, api.event_buffer_size, api.shutdown_timeout_seconds, api.max_concurrent_runs, api.multi_operator, api.graph_routenumber/input/switch; allowed_origins validated loopback-only on PATCH
Reportsreports.dirpath
Assessmentassessment.max_commands, assessment.max_rounds, assessment.max_duration_secondsnumbers

Mirrors docs/api.md: Config Reference api block. Validation errors surface from 400 config_invalid details.errors via ConfigValidationErrorResponse (api/types.ts:783).

AI Provider (ProviderSettings.tsx)

Provider card as in docs/webui.md: System Page — segmented Ollama / ChatGPT bound to models.provider; switching PATCH /config deep-merge (→ chatgpt.enabled:true for ChatGPT) and invalidates models/modelsLive/providers via usePatchConfig.onSuccess (api/hooks.ts:152).

SubsectionHook / EndpointDetail
Provider pickeruseModels (hooks.ts:189), useProviders (hooks.ts:248), useSetModelProvider (hooks.ts:236POST /models/provider)registry vs chatgpt.configured_models
Live modelsuseLiveModels (hooks.ts:198GET /models/live)source badge `ollama
ChatGPT statusGET /providers (hooks.ts:248)host:port, default_model, badges signed-in/proxy-running/we_started
OAuthuseChatgptLogin (hooks.ts:294POST /providers/chatgpt/login)surfaces URL link, tokens never reach SPA
Proxy lifecycleuseChatgptProxyStart/Stop (hooks.ts:302POST /providers/chatgpt/proxy/{start,stop})Stop gated we_started
Ollama notestaticembeddings stay on Ollama under either provider
SecretsuseSecrets / usePutSecrets (hooks.ts:169GET/PUT /secrets)write-only inputs, configured/missing status

Features (FeatureSettings.tsx)

Feature-flag toggles surfaced from config + capabilities.features / run_options.flags:

FlagConfig sectionEffect
swarm / parallel_swarmswarmgated powerUps in RunWizard
critic / reflectionswarmonly when swarm on
adaptive_exploitsexploits
long_sessionsessionenables Campaign tab on RunPage
multi_model_consultmodels
ultrathinksession
recon_firstrun-leveltri-state in wizard
skillsskillsmaster + lookup/inject switches (see SkillsPage)
graph_routeapienables /graph + GET /graph/*
threat_intel / mitre / poc_verification / replay_simulator / peer_reviewfeaturesgate Advisory tools (RunPage AdvisoryPanel)

FeatureSettings.tsx renders switches via ConfigField bound to draft; settingMeta.ts defines labels/help/defaults per field.

Advanced (AdvancedSettings.tsx)

SectionComponent / HookDetail
Raw configConfigEditor (features/settings/ConfigEditor.tsx)read-only redacted GET /config (hooks.ts:124), editable JSON-ish form + PATCH /config
Secrets (expanded)useSecrets / usePutSecretsper-key configured/missing, write-only PUT /secrets {secrets:{...}}
PluginsusePlugins (hooks.ts:318GET /plugins)name/version/loaded/capabilities/enabled list
TelemetryuseTelemetry (hooks.ts:266GET /system/telemetry)summary + recent records
System infouseSystemInfo (hooks.ts:257GET /system/info)hostname/platform/os/python/local_ips/public_ip
Danger zoneDangerZone (features/settings/DangerZone.tsx) + useResetSystem (hooks.ts:409POST /system/reset)deletes runs + artifacts + workspaces
DiagnosticsuseDiagnostics (hooks.ts:401POST /diagnostics/{doctor,self-test})exit code + output <pre>

Search indexes AdvancedSettings fields under "advanced" so SettingsSearch can jump to e.g. api.graph_route.

Draft machinery (useSettingsDraft.tsx)

ExportRole
SettingsDraftProviderfetches GET /config + GET /config/schema (hooks.ts:124,133), seeds draft = config; exposes draft, patchDraft(path,value), reset, save, dirty, saving, error, savedAt
useSettingsDraft()consumer hook; patchDraft deep-merges a partial (e.g. {skills:{enabled:true}}), save() calls usePatchConfig mutation, on success writes data.config back and sets savedAt=Date.now() (SettingsPage.tsx:30 formatSavedAt)
formatSavedAtfeatures/settings/format.tsjust now / Ns ago

Dirty check is shallow diff of drafted keys vs server snapshot; UnsavedChangesBar enables Save/Discard accordingly.

settingMeta.ts

Declarative registry drives search + nav + field rendering. Each entry: category, section, field, label, help, type (switch/input/select/number), default, schemaRef. SettingsSearch flattens all entries, fuzzy-matches query across label/help/field; nav renders category counts from meta. Adding a config key = add an entry there first.

Validation

Server is author of truth. PATCH /config (api/hooks.ts:145) runs ConfigValidator; failure 400 config_invalid with details.errors[] rendered inline per field. allowed_origins validated loopback-only before write (docs/api.md: PATCH /config). Errors shown via useToast (hooks/use-toast.ts) + per-field messages.

source: repo docs (build sync)Edit this page on GitHub →