Follow Discord
Sweep 22 Oct 2026 · 04:32Z Build v2.1.308 527 read Stable v2.1.308 Latest v2.1.308 Next v2.1.308 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

All settings changedsettings-reference

Nearest release: v2.1.305, published an hour after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 20 Oct 2026 18:25 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 20 Oct 2026 18:37 UTC.

Upstream edited
Recorded here
Lines+36added
Lines−659removed
From line 2 where the diff opens
First seen 21 Aug 2026 this site's first read of the page
Recorded edits143to this page, all time

The whole hunk

from line 2, old and new numbered
/
lines

This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.

The two sides of this change are more than 400 edits apart, too far apart to line up, so this is the differ's own diff of it and the words inside a line are not marked.

from line 2
22 
33> Complete reference for every Claude Code settings.json key: where each one goes, its type and default, and a paste-ready example, with an index of every key.
44 
5export const BackToIndex = ({href = '#all-settings', label = 'Back to index'}) => {
6 const [show, setShow] = useState(false);
7 useEffect(() => {
8 const onScroll = () => setShow(window.scrollY > window.innerHeight);
9 onScroll();
10 window.addEventListener('scroll', onScroll, {
11 passive: true
12 });
13 return () => window.removeEventListener('scroll', onScroll);
14 }, []);
15 return <div className="not-prose">
16 <style>{`
17 .bti-btn {
18 position: fixed; right: 20px; bottom: 20px; z-index: 40;
19 display: inline-flex; align-items: center; gap: 6px;
20 padding: 8px 12px; border-radius: 999px;
21 font-size: 13px; font-weight: 500; line-height: 1; text-decoration: none;
22 color: #1f1f1f; background: #ffffff; border: 1px solid #d9d9d9;
23 box-shadow: 0 2px 8px rgba(0,0,0,0.12);
24 opacity: 0; pointer-events: none; transform: translateY(6px);
25 transition: opacity 160ms ease, transform 160ms ease;
26 }
27 .bti-btn.bti-show { opacity: 1; pointer-events: auto; transform: translateY(0); }
28 .bti-btn:hover { border-color: #b3b3b3; }
29 .dark .bti-btn { color: #ececec; background: #1e1e1e; border-color: #3a3a3a; box-shadow: 0 2px 8px rgba(0,0,0,0.5); }
30 .dark .bti-btn:hover { border-color: #5a5a5a; }
31 @media (max-width: 1279px) { .bti-btn { bottom: 112px; } }
32 @media print { .bti-btn { display: none; } }
33 `}</style>
34 <a className={'bti-btn' + (show ? ' bti-show' : '')} href={href} aria-hidden={!show} tabIndex={show ? 0 : -1}>
35 <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M8 13V3M3.5 7.5 8 3l4.5 4.5" /></svg>
36 {label}
37 </a>
38 </div>;
39};
40 
41export const ReferenceFilter = ({placeholder, noun, facets, facetOrder, columnHelp, children}) => {
42 const useLive = init => {
43 const [v, setV] = useState(init);
44 const ref = useRef(init);
45 return [v, ref, x => {
46 ref.current = x;
47 setV(x);
48 }];
49 };
50 const cap = s => s.charAt(0).toUpperCase() + s.slice(1);
51 const plural = s => s.endsWith('y') ? s.slice(0, -1) + 'ies' : s + 's';
52 const facetNames = facets || ['category', 'topic', 'scope', 'where'];
53 const orderOf = {};
54 Object.keys(facetOrder || ({})).forEach(k => {
55 orderOf[k] = facetOrder[k].map(x => String(x).toLowerCase());
56 });
57 const rankIn = (col, v) => {
58 const list = orderOf[col];
59 if (!list) return -1;
60 const i = list.indexOf(String(v).toLowerCase());
61 return i < 0 ? list.length : i;
62 };
63 const cmpValues = col => (a, b) => {
64 const ra = rankIn(col, a);
65 const rb = rankIn(col, b);
66 if (ra !== rb) return ra - rb;
67 return a < b ? -1 : a > b ? 1 : 0;
68 };
69 const help = columnHelp || ({});
70 const FIRST_COL_HELP = 'Click an entry to open it.';
71 const optionLabel = (f, c) => c === 'All' ? 'All ' + plural(f.label.toLowerCase()) : c;
72 const nounText = noun || 'entries';
73 const placeholderText = placeholder || 'Filter this reference';
74 const rootRef = useRef(null);
75 const tablesRef = useRef(null);
76 const searchRef = useRef(null);
77 const menuRef = useRef({});
78 const [q, qRef, setQ] = useLive('');
79 const [sel, selRef, setSel] = useLive({});
80 const [sortBy, sortRef, setSortBy] = useLive(null);
81 const [menuOpen, menuOpenRef, setMenu] = useLive(null);
82 const [facetList, setFacetList] = useState([]);
83 const [firstHead, setFirstHead] = useState('');
84 const [counts, setCounts] = useState({
85 shown: 0,
86 total: 0
87 });
88 const [disabled, setDisabled] = useState(false);
89 const menuBtn = name => menuRef.current[name] ? menuRef.current[name].querySelector(':scope > button') : null;
90 const menuList = name => menuRef.current[name] ? menuRef.current[name].querySelector('[role="listbox"]') : null;
91 const closeMenu = name => {
92 setMenu(null);
93 const btn = menuBtn(name);
94 if (btn) btn.focus();
95 };
96 const focusSelected = name => {
97 const list = menuList(name);
98 if (!list) return;
99 const btn = list.querySelector('button[aria-selected="true"]') || list.querySelector('button');
100 if (btn) btn.focus();
101 };
102 const setFacet = (name, value) => {
103 setSel(Object.assign({}, selRef.current, {
104 [name]: value
105 }));
106 apply(qRef.current);
107 closeMenu(name);
108 };
109 const sortTables = by => {
110 (tablesRef.current || []).forEach(tab => {
111 const t = tab.el;
112 const idx = tab.heads.indexOf(by);
113 const body = t.querySelector('tbody');
114 if (idx < 0 || !body) return;
115 const rows = [...body.querySelectorAll('tr')];
116 const keyOf = r => r.children[idx] ? r.children[idx].textContent.trim().toLowerCase() : '';
117 const cmp = cmpValues(by);
118 rows.map((r, i) => ({
119 r,
120 i: Number(r.dataset.sfIndex !== undefined ? r.dataset.sfIndex : i),
121 k: keyOf(r)
122 })).sort((a, b) => cmp(a.k, b.k) || a.i - b.i).forEach(x => body.appendChild(x.r));
123 [...t.querySelectorAll('thead th')].forEach((h, i) => {
124 const sortable = tab.heads[i] === tab.heads[0] || facetNames.indexOf(tab.heads[i]) > -1;
125 if (sortable) h.setAttribute('aria-sort', i === idx ? 'ascending' : 'none'); else h.removeAttribute('aria-sort');
126 });
127 });
128 };
129 const scan = () => {
130 const tables = [];
131 let el = rootRef.current ? rootRef.current.nextElementSibling : null;
132 while (el) {
133 if (el.tagName === 'H2' || el.querySelector(':scope > h2')) break;
134 const found = el.tagName === 'TABLE' ? [el] : [...el.querySelectorAll('table')];
135 found.forEach(t => {
136 const headCells = [...t.querySelectorAll('thead th, thead td')];
137 const heads = headCells.map(h => h.textContent.trim().toLowerCase());
138 if (heads.length === 0) return;
139 const facetIdx = {};
140 heads.forEach((h, i) => {
141 if (facetNames.indexOf(h) > -1) facetIdx[h] = i;
142 });
143 if (!t.dataset.sfDecorated) {
144 t.dataset.sfDecorated = '1';
145 headCells.forEach((h, i) => {
146 const text = i === 0 ? help[heads[0]] || FIRST_COL_HELP : help[heads[i]];
147 if (text) h.title = text;
148 });
149 }
150 const rows = [...t.querySelectorAll('tbody tr')].map((r, i) => {
151 if (r.dataset.sfIndex === undefined) r.dataset.sfIndex = String(i);
152 const cells = r.querySelectorAll('td');
153 const fv = {};
154 Object.keys(facetIdx).forEach(h => {
155 fv[h] = cells[facetIdx[h]] ? cells[facetIdx[h]].textContent.trim() : '';
156 });
157 return {
158 el: r,
159 text: [...cells].map(c => c.textContent).join(' ').toLowerCase(),
160 facets: fv,
161 anchors: [...r.querySelectorAll('a[href^="#"]')].map(a => a.getAttribute('href').slice(1)),
162 ids: [...r.querySelectorAll('[id]')].map(n => n.id)
163 };
164 });
165 tables.push({
166 el: t,
167 box: t.closest('[data-table-wrapper]') || t,
168 rows,
169 heads
170 });
171 });
172 el = el.nextElementSibling;
173 }
174 tablesRef.current = tables;
175 if (sortRef.current) sortTables(sortRef.current);
176 return tables;
177 };
178 const apply = query => {
179 let tables = tablesRef.current || scan();
180 if (tables.some(t => !t.el.isConnected)) tables = scan();
181 const needle = query.trim().toLowerCase();
182 const sel = selRef.current;
183 const activeFacets = Object.keys(sel).filter(h => sel[h] && sel[h] !== 'All');
184 const show = (el, on) => {
185 const want = on ? '' : 'none';
186 if (el.style.display !== want) el.style.display = want;
187 };
188 let total = 0;
189 let shown = 0;
190 const visibleTargets = new Set();
191 tables.forEach(t => {
192 let tableVisible = 0;
193 t.rows.forEach(row => {
194 total += 1;
195 const catOk = activeFacets.every(h => {
196 const v = row.facets[h];
197 return v === sel[h] || v === '' || v === undefined;
198 });
199 const match = catOk && (needle === '' || row.text.includes(needle));
200 show(row.el, match);
201 if (match) {
202 tableVisible += 1;
203 row.anchors.forEach(a => visibleTargets.add(a));
204 }
205 });
206 show(t.box, !(t.rows.length > 0 && tableVisible === 0));
207 shown += tableVisible;
208 });
209 if (shown < total && visibleTargets.size > 0) {
210 tables.forEach(t => {
211 t.rows.forEach(row => {
212 if (row.el.style.display === 'none' && row.ids.some(id => visibleTargets.has(id))) {
213 show(row.el, true);
214 show(t.box, true);
215 shown += 1;
216 }
217 });
218 });
219 }
220 setCounts({
221 shown,
222 total
223 });
224 return total;
225 };
226 const deriveFacets = tables => {
227 const seen = {};
228 tables.forEach(t => t.rows.forEach(r => {
229 Object.keys(r.facets).forEach(h => {
230 if (!seen[h]) seen[h] = [];
231 if (r.facets[h] && seen[h].indexOf(r.facets[h]) === -1) seen[h].push(r.facets[h]);
232 });
233 }));
234 const list = facetNames.filter(h => seen[h] && seen[h].length > 0).map(h => ({
235 name: h,
236 label: cap(h),
237 values: seen[h].sort(cmpValues(h))
238 }));
239 setFacetList(list);
240 const first = tables[0] ? tables[0].heads[0] : '';
241 setFirstHead(first);
242 if (!sortRef.current && first) {
243 setSortBy(first);
244 sortTables(first);
245 }
246 const init = {};
247 list.forEach(f => {
248 init[f.name] = selRef.current[f.name] || 'All';
249 });
250 setSel(init);
251 };
252 const onChange = value => {
253 setQ(value);
254 apply(value);
255 };
256 const clearAll = () => {
257 const next = {};
258 Object.keys(selRef.current).forEach(k => {
259 next[k] = 'All';
260 });
261 setSel(next);
262 setQ('');
263 apply('');
264 if (searchRef.current) searchRef.current.focus();
265 };
266 useEffect(() => {
267 const tables = scan();
268 deriveFacets(tables);
269 const total = apply('');
270 let retryTimer;
271 if (total === 0) {
272 retryTimer = setTimeout(() => {
273 tablesRef.current = null;
274 if (apply(qRef.current) > 0) deriveFacets(tablesRef.current); else setDisabled(true);
275 }, 500);
276 }
277 const onKey = e => {
278 if (e.key === 'Escape' && menuOpenRef.current !== null) closeMenu(menuOpenRef.current);
279 if (!searchRef.current) return;
280 if (e.metaKey || e.ctrlKey || e.altKey) return;
281 const active = document.activeElement;
282 const tag = active && active.tagName;
283 const editable = active && active.isContentEditable;
284 const interactive = tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || tag === 'BUTTON' || tag === 'A' || editable || active && active.getAttribute && active.getAttribute('role');
285 if (e.key === '/' && !interactive) {
286 const r = rootRef.current ? rootRef.current.getBoundingClientRect() : null;
287 if (r && r.bottom > 0 && r.top < (window.innerHeight || 0)) {
288 e.preventDefault();
289 setMenu(null);
290 searchRef.current.focus();
291 }
292 }
293 if (e.key === 'Escape' && menuOpenRef.current === null && active === searchRef.current) {
294 onChange('');
295 searchRef.current.blur();
296 }
297 };
298 const onDocClick = e => {
299 const open = menuOpenRef.current;
300 if (open !== null && menuRef.current[open] && !menuRef.current[open].contains(e.target)) setMenu(null);
301 };
302 window.addEventListener('keydown', onKey);
303 document.addEventListener('mousedown', onDocClick);
304 return () => {
305 if (retryTimer) clearTimeout(retryTimer);
306 window.removeEventListener('keydown', onKey);
307 document.removeEventListener('mousedown', onDocClick);
308 (tablesRef.current || []).forEach(t => {
309 t.box.style.display = '';
310 t.rows.forEach(row => {
311 row.el.style.display = '';
312 });
313 });
314 };
315 }, []);
316 useEffect(() => {
317 if (menuOpen !== null) focusSelected(menuOpen);
318 }, [menuOpen]);
319 if (disabled) return null;
320 const facetActive = Object.keys(sel).some(h => sel[h] && sel[h] !== 'All');
321 const sortOptions = [firstHead].concat(facetList.map(f => f.name)).filter((h, i, a) => h && a.indexOf(h) === i);
322 return <>
323 <style>{`
324 .sf-root {
325 --sf-accent: #D97757;
326 --sf-bg: #fff;
327 --sf-border: #E8E6DC;
328 --sf-text: #141413;
329 --sf-text-3: #73726C;
330 --sf-text-4: #9C9A92;
331 }
332 .dark .sf-root {
333 --sf-bg: #1a1918;
334 --sf-border: #3a3936;
335 --sf-text: #e8e6dc;
336 --sf-text-3: #9c9a92;
337 --sf-text-4: #73726c;
338 }
339 .sf-root .sf-end {
340 position: absolute;
341 right: 10px;
342 top: 50%;
343 transform: translateY(-50%);
344 }
345 .sf-root .sf-x {
346 background: none;
347 border: none;
348 cursor: pointer;
349 color: var(--sf-text-3);
350 font-size: 14px;
351 padding: 2px 4px;
352 line-height: 1;
353 }
354 `}</style>
355 <div ref={rootRef} className="sf-root" style={{
356 margin: '16px 0 8px'
357 }}>
358 <div style={{
359 display: 'flex',
360 gap: '8px',
361 flexWrap: 'wrap',
362 alignItems: 'center'
363 }}>
364 <div style={{
365 position: 'relative',
366 flex: '1 1 260px',
367 maxWidth: '480px'
368 }}>
369 <input ref={searchRef} value={q} onChange={e => onChange(e.target.value)} placeholder={placeholderText} aria-label={placeholderText} style={{
370 width: '100%',
371 padding: '8px 56px 8px 12px',
372 borderRadius: '8px',
373 border: '1px solid var(--sf-border)',
374 background: 'var(--sf-bg)',
375 color: 'var(--sf-text)',
376 fontSize: '14px',
377 outline: 'none',
378 boxSizing: 'border-box'
379 }} />
380 {q ? <button type="button" onClick={() => {
381 onChange('');
382 if (searchRef.current) searchRef.current.focus();
383 }} aria-label="Clear text" className="sf-end sf-x">
384 ×
385 </button> : <span className="sf-end" style={{
386 fontFamily: 'var(--font-mono, ui-monospace, monospace)',
387 fontSize: '11px',
388 color: 'var(--sf-text-4)',
389 border: '1px solid var(--sf-border)',
390 borderRadius: '3px',
391 padding: '0 5px',
392 pointerEvents: 'none'
393 }}>
394 /
395 </span>}
396 </div>
397 {facetList.map(f => {
398 const cur = sel[f.name] || 'All';
399 const isOpen = menuOpen === f.name;
400 return <div key={f.name} ref={el => {
401 menuRef.current[f.name] = el;
402 }} style={{
403 position: 'relative'
404 }}>
405 <button type="button" onClick={() => setMenu(isOpen ? null : f.name)} onKeyDown={e => {
406 if (e.key === 'ArrowDown') {
407 e.preventDefault();
408 if (!isOpen) setMenu(f.name); else focusSelected(f.name);
409 }
410 }} aria-haspopup="listbox" aria-expanded={isOpen} style={{
411 display: 'flex',
412 alignItems: 'center',
413 gap: '8px',
414 padding: cur !== 'All' ? '8px 30px 8px 12px' : '8px 12px',
415 borderRadius: '8px',
416 border: '1px solid ' + (cur !== 'All' ? 'var(--sf-accent)' : 'var(--sf-border)'),
417 background: 'var(--sf-bg)',
418 color: cur === 'All' ? 'var(--sf-text-3)' : 'var(--sf-text)',
419 fontSize: '13.5px',
420 cursor: 'pointer',
421 whiteSpace: 'nowrap',
422 maxWidth: '260px'
423 }}>
424 <span style={{
425 overflow: 'hidden',
426 textOverflow: 'ellipsis'
427 }}>
428 {f.label + ': ' + optionLabel(f, cur)}
429 </span>
430 <span aria-hidden="true" style={{
431 fontSize: '9px',
432 color: 'var(--sf-text-4)',
433 transform: isOpen ? 'rotate(180deg)' : 'none',
434 transition: 'transform 120ms'
435 }}>
436 ▼
437 </span>
438 </button>
439 {cur !== 'All' && <button type="button" onClick={() => setFacet(f.name, 'All')} aria-label={'Clear ' + f.label + ' filter'} title={'Clear ' + f.label + ' filter'} className="sf-end sf-x">
440 ×
441 </button>}
442 {isOpen && <div role="listbox" aria-label={f.label} onKeyDown={e => {
443 const items = [...e.currentTarget.querySelectorAll('button')];
444 const idx = items.indexOf(document.activeElement);
445 if (e.key === 'ArrowDown') {
446 e.preventDefault();
447 (items[idx + 1] || items[0]).focus();
448 } else if (e.key === 'ArrowUp') {
449 e.preventDefault();
450 (items[idx - 1] || items[items.length - 1]).focus();
451 } else if (e.key === 'Home') {
452 e.preventDefault();
453 if (items[0]) items[0].focus();
454 } else if (e.key === 'End') {
455 e.preventDefault();
456 if (items[items.length - 1]) items[items.length - 1].focus();
457 } else if (e.key === 'Tab') {
458 closeMenu(f.name);
459 }
460 }} style={{
461 position: 'absolute',
462 top: 'calc(100% + 6px)',
463 left: 0,
464 zIndex: 1000,
465 minWidth: '260px',
466 maxHeight: '340px',
467 overflowY: 'auto',
468 background: 'var(--sf-bg)',
469 border: '1px solid var(--sf-border)',
470 borderRadius: '10px',
471 boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
472 padding: '5px'
473 }}>
474 {['All'].concat(f.values).map(c => {
475 const selected = cur === c;
476 return <button key={c} role="option" aria-selected={selected} tabIndex={-1} onClick={() => setFacet(f.name, c)} style={{
477 display: 'flex',
478 alignItems: 'center',
479 gap: '8px',
480 width: '100%',
481 textAlign: 'left',
482 padding: '7px 10px',
483 borderRadius: '6px',
484 border: 'none',
485 background: 'transparent',
486 color: selected ? 'var(--sf-accent)' : 'var(--sf-text)',
487 fontWeight: selected ? 600 : 400,
488 fontSize: '13.5px',
489 cursor: 'pointer'
490 }}>
491 <span aria-hidden="true" style={{
492 width: '14px',
493 color: 'var(--sf-accent)',
494 flexShrink: 0
495 }}>
496 {selected ? '✓' : ''}
497 </span>
498 {optionLabel(f, c)}
499 </button>;
500 })}
501 </div>}
502 </div>;
503 })}
504 {sortOptions.length > 1 && <div role="group" aria-label="Sort by" style={{
505 display: 'flex',
506 alignItems: 'center',
507 gap: '4px',
508 fontSize: '13px',
509 color: 'var(--sf-text-3)',
510 whiteSpace: 'nowrap'
511 }}>
512 <span style={{
513 marginRight: '4px'
514 }}>Sort by</span>
515 {sortOptions.map(o => {
516 const on = sortBy === o;
517 return <button key={o} type="button" aria-pressed={on} onClick={() => {
518 setSortBy(o);
519 sortTables(o);
520 }} style={{
521 padding: '6px 10px',
522 borderRadius: '8px',
523 border: '1px solid ' + (on ? 'var(--sf-accent)' : 'var(--sf-border)'),
524 background: 'var(--sf-bg)',
525 color: on ? 'var(--sf-text)' : 'var(--sf-text-3)',
526 fontSize: '13px',
527 cursor: 'pointer'
528 }}>
529 {o.charAt(0).toUpperCase() + o.slice(1)}
530 </button>;
531 })}
532 </div>}
533 </div>
534 <div aria-live="polite" style={{
535 margin: '8px 0 0',
536 fontSize: '13px',
537 color: 'var(--sf-text-3)',
538 minHeight: '1px'
539 }}>
540 {q.trim() === '' && !facetActive ? <>{counts.total} {nounText}</> : counts.shown === 0 ? <>
541 {q.trim() === '' ? 'No ' + nounText + ' match the selected filters.' : facetActive ? 'No ' + nounText + ' match \u201c' + q + '\u201d with the selected filters.' : 'No ' + nounText + ' match \u201c' + q + '\u201d.'}{' '}
542 <button type="button" onClick={clearAll} style={{
543 background: 'none',
544 border: 'none',
545 padding: 0,
546 color: 'var(--sf-accent)',
547 cursor: 'pointer',
548 font: 'inherit',
549 textDecoration: 'underline'
550 }}>
551 Clear filters
552 </button>
553 {children ? <> {children}</> : null}
554 </> : <>
555 Showing {counts.shown} of {counts.total} {nounText}
556 </>}
557 </div>
558 </div>
559 </>;
560};
561 
562<BackToIndex href="#all-settings" label="Back to index" />
5[Back to index](#all-settings)
5636 
5647This reference page lists each key Claude Code reads from a settings file, plus the [short group of keys](#global-config-settings) it keeps in `~/.claude.json` instead. To pick a file, or check precedence, start with [Settings files and precedence](/docs/en/settings).
5658 
566<span id="available-settings" />
567 
568<span id="scopes" />
569 
570<span id="all-settings" />
571 
5729## Settings index
57310 
57411Every key below links to its entry. Scope lists the [files](/docs/en/settings#settings-files-and-who-they-affect) it can go in: `User` is `~/.claude/settings.json`, `Project` is `.claude/settings.json`, `Local` is `.claude/settings.local.json`, and `Managed` is [what your organization deploys](/docs/en/managed-settings). `Any file` means all four, and `Global config` means [`~/.claude.json`](#global-config-settings).
575 
576<ReferenceFilter
577 noun="settings"
578 placeholder="Filter settings by key or purpose"
579 facetOrder={{ scope: ["Any file", "User, local, or managed", "User or managed", "User", "Managed", "Global config"] }}
580 columnHelp={{
581topic: "The section of this page that holds the entry. Use Sort by to group the table by topic.",
582scope: "Which settings files can set the key: user (~/.claude/settings.json), project (.claude/settings.json), local (.claude/settings.local.json), or managed (deployed by your organization). Global config keys are in ~/.claude.json instead.",
583}}
584/>
58512 
58613| Key | Description | Topic | Scope |
58714| :- | :- | :- | :- |
from line 574
1147574}
1148575```
1149576 
1150<span id="modelpicker-options" />
1151 
1152<span id="modelpicker-replacebuiltinoptions" />
1153 
1154577#### Fields for `modelPicker`
1155578 
1156579The key takes two fields, one for the rows themselves and one for whether they replace the built-in lineup or add to it.
from line 627
1204627 
1205628For the steps, including how to confirm the rates are in effect, see [Report spend at your contracted rates](/docs/en/costs#report-spend-at-your-contracted-rates).
1206629 
1207<span id="modelpricing-multiplier" />
1208 
1209<span id="modelpricing-overrides" />
1210 
1211630#### Fields for `modelPricing`
1212631 
1213632| Field | Type | What it does |
from line 976
1557976 }
1558977}
1559978```
1560 
1561<span id="exclude-sensitive-files" />
1562979 
1563980### `permissions.deny`
1564981 
from line 1703
22861703Paths use the same [prefixes](#sandbox-path-prefixes) as the `sandbox.filesystem.*` settings, and Claude Code merges the arrays from every settings scope the session loads. [Protect credentials](/docs/en/sandboxing#protect-credentials) covers what still applies from sources you exclude with `--setting-sources`. `mask` entries require Claude Code v2.1.221 or later.
22871704 
22881705`mask` substitution runs only through the sandbox proxy, so set [`sandbox.network.tlsTerminate`](#sandbox-network-tlsterminate), or [`allowPlaintextInject`](#sandbox-credentials-allowplaintextinject) for plain-HTTP test networks. `mask` applies to a single file, so list each credential file individually. Claude Code accepts but ignores the `mask` fields on a `deny` entry. [Mask credentials](/docs/en/sandboxing#mask-credentials) covers which settings sources are honored, and [Mask credential files](/docs/en/sandboxing#mask-credential-files) covers when an entry falls back to `deny`.
2289 
2290<span id="sandbox-credentials-files-extract" />
2291 
2292<span id="sandbox-credentials-files-onextractnomatch" />
2293 
2294<span id="sandbox-credentials-files-decode" />
2295 
2296<span id="sandbox-credentials-files-maskclaims" />
2297 
2298<span id="sandbox-credentials-files-maskduplicates" />
2299 
2300<span id="sandbox-credentials-files-injecthosts" />
23011706 
23021707#### Mask fields for files
23031708 
from line 1764
23591764The `name` must start with a letter or underscore and contain only letters, digits, and underscores. Claude Code merges the arrays from every settings scope the session loads, and applies `deny` when the same variable appears with both modes. [Protect credentials](/docs/en/sandboxing#protect-credentials) covers what still applies from sources you exclude with `--setting-sources`.
23601765 
23611766`mask` substitution runs only through the sandbox proxy, so set [`sandbox.network.tlsTerminate`](#sandbox-network-tlsterminate), or [`allowPlaintextInject`](#sandbox-credentials-allowplaintextinject) for plain-HTTP test networks; see [Mask credentials](/docs/en/sandboxing#mask-credentials). Claude Code accepts but ignores the `mask` fields on a `deny` entry.
2362 
2363<span id="sandbox-credentials-envvars-extract" />
2364 
2365<span id="sandbox-credentials-envvars-onextractnomatch" />
2366 
2367<span id="sandbox-credentials-envvars-decode" />
2368 
2369<span id="sandbox-credentials-envvars-maskclaims" />
2370 
2371<span id="sandbox-credentials-envvars-injecthosts" />
23721767 
23731768#### Mask fields for environment variables
23741769 
from line 2139
27442139 
27452140When more than one honored source sets it, Claude Code uses the value from the highest-precedence source: managed settings, then the `--settings` flag, then user settings.
27462141 
2747<span id="context-and-memory" />
2748 
27492142## Memory and context
27502143 
27512144Control what Claude Code loads into context, how it compacts, and where it keeps memory and plans. See [Manage context](/docs/en/context-window) and [Memory](/docs/en/memory).
from line 2261
28682261```
28692262 
28702263Exclusions apply only to user, project, and local memory files; managed policy CLAUDE.md files can't be excluded.
2871 
2872<span id="environment-variables" />
28732264 
28742265### `env`
28752266 
from line 2350
29592350 
29602351### `idleCompaction`
29612352 
2962Idle compaction [compacts](/docs/en/context-window#what-survives-compaction) a long conversation that you've stepped away from, shortly before its prompt cache expires. Your next message then sends a summary instead of the whole conversation. When you come back, the conversation shows `Compacted while idle, before the prompt cache expired`.
2353Idle compaction [compacts](/docs/en/context-window#what-survives-compaction) a long conversation that you've stepped away from, shortly before its prompt cache expires. Your next message then sends a summary instead of the whole conversation. When you come back, the conversation shows a line that starts with `Compacted while idle, before the prompt cache expired`.
29632354 
29642355Idle compaction is on by default for conversations that meet all of these conditions:
29652356 
from line 2375
29842375}
29852376```
29862377 
2378To turn idle compaction off or on from inside a session, run `/config` and change the **Idle compaction** row. Your choice is saved to your user settings and applies right away. The row requires Claude Code v2.1.302 or later. If you run one of those versions and `/config` doesn't show the row, check for these causes:
2379 
2380* **Another settings source sets the key**: a value in managed settings, the `--settings` flag, or a project or local settings file overrides your user settings. Change the key in that source instead
2381* **Feature flags are unavailable**: where Claude Code can't [fetch feature flags from Anthropic](/docs/en/env-vars#features-that-need-feature-flag-fetching), idle compaction doesn't run, so there is nothing to turn off
2382 
29872383The key requires Claude Code v2.1.290 or later. On an earlier version, which ignores this key, turn off [`autoCompactEnabled`](#autocompactenabled) to stop idle compaction.
29882384 
29892385#### Change the idle compaction threshold
from line 2449
30532449 
30542450### `taskOutputMaxChars`
30552451 
3056<Warning>
3057 Removed in v2.1.277, together with the `TaskOutput` tool it sized. Setting it has no effect on current versions. Claude reads a background task's [output file](/docs/en/tools-reference#background-commands) with `Read` instead.
3058</Warning>
2452> [!WARNING]
2453>
2454> Removed in v2.1.277, together with the `TaskOutput` tool it sized. Setting it has no effect on current versions. Claude reads a background task's [output file](/docs/en/tools-reference#background-commands) with `Read` instead.
30592455 
30602456Through v2.1.276, you set this key to the number of characters of a [background task's](/docs/en/tools-reference#background-commands) output that Claude received inline when it read the task with the `TaskOutput` tool.
30612457 
from line 2636
32402636```
32412637 
32422638See [Emoji shortcodes](/docs/en/interactive-mode#emoji-shortcodes). Requires Claude Code v2.1.217 or later.
3243 
3244<span id="file-suggestion-settings" />
32452639 
32462640### `fileSuggestion`
32472641 
from line 2680
32862680# Replace your-repo-file-index with your own file search command
32872681your-repo-file-index --query "$query" | head -20
32882682```
3289 
3290<span id="footer-link-badges" />
32912683 
32922684### `footerLinksRegexes`
32932685 
from line 2724
33322724 
33332725### `keybindingFlavor`
33342726 
3335<Warning>
3336 Deprecated since v2.1.261 and has no effect. The prompt's word-editing keys always [follow readline conventions](/docs/en/interactive-mode#make-ctrl-w-delete-back-to-whitespace), as in Bash. Claude Code still accepts `keybindingFlavor`, so a settings file that sets it stays valid.
3337</Warning>
2727> [!WARNING]
2728>
2729> Deprecated since v2.1.261 and has no effect. The prompt's word-editing keys always [follow readline conventions](/docs/en/interactive-mode#make-ctrl-w-delete-back-to-whitespace), as in Bash. Claude Code still accepts `keybindingFlavor`, so a settings file that sets it stays valid.
33382730 
33392731In v2.1.238 through v2.1.260, setting it to `"readline"` made `Ctrl+W` delete back to the previous whitespace instead of only the previous word.
33402732 
from line 3231
38393231 
38403232### `voiceEnabled`
38413233 
3842<Warning>
3843 Deprecated since v2.1.92, when the [`voice`](#voice) object replaced it. Claude Code still reads it so older settings files keep working, but new configurations should set `voice.enabled`.
3844</Warning>
3234> [!WARNING]
3235>
3236> Deprecated since v2.1.92, when the [`voice`](#voice) object replaced it. Claude Code still reads it so older settings files keep working, but new configurations should set `voice.enabled`.
38453237 
38463238Turn voice dictation on with the single Boolean form that predates the `voice` object. When both are set, `voice.enabled` applies.
38473239 
from line 3268
38763268## Git and attribution
38773269 
38783270Control the attribution Claude Code adds to commits and pull requests and how it works with git.
3879 
3880<span id="attribution-settings" />
38813271 
38823272### `attribution`
38833273 
from line 3297
39073297 
39083298### `includeCoAuthoredBy`
39093299 
3910<Warning>
3911 Deprecated since v2.0.62, when [`attribution`](#attribution) replaced it. Claude Code still reads it, but new configurations should set `attribution`.
3912</Warning>
3300> [!WARNING]
3301>
3302> Deprecated since v2.0.62, when [`attribution`](#attribution) replaced it. Claude Code still reads it, but new configurations should set `attribution`.
39133303 
39143304Use [`attribution`](#attribution) instead, which replaces this key and lets you change or hide the commit trailer, the pull request text, and the session link separately. Claude Code still honors `includeCoAuthoredBy: false` from settings files that predate `attribution`, but ignores it once you set `attribution.commit` or `attribution.pr`.
39153305 
from line 3410
40203410 }
40213411}
40223412```
4023 
4024<span id="hook-configuration" />
4025 
4026<span id="hook-and-skill-settings" />
40273413 
40283414## Hooks and automation
40293415 
from line 3621
42353621```
42363622 
42373623Requires Claude Code v2.1.219 or later; on v2.1.202 through v2.1.218, set the guideline in `/config` instead.
4238 
4239<span id="plugin-configuration" />
4240 
4241<span id="manage-plugins" />
4242 
4243<span id="plugin-settings" />
42443624 
42453625## Plugins and skills
42463626 
from line 4028
46484028 
46494029### `strictPluginOnlyCustomization.hooks`
46504030 
4651Lock the `hooks` surface. Claude Code stops running hooks from user, project, and local `settings.json`, and keeps running plugin hooks and hooks in managed settings.
4031Lock the `hooks` surface:
4032 
4033* **Stops running**:
4034 * Hooks from user, project, and local `settings.json`
4035 * Frontmatter hooks in skills, custom commands, and agents, from the sources that a [`skills`](#strictpluginonlycustomization-skills) or [`agents`](#strictpluginonlycustomization-agents) lock would block
4036* **Keeps running**: plugin hooks and hooks in managed settings
4037 
4038Skills, custom commands, and agents whose frontmatter hooks stop running still load while their own surface isn't locked.
46524039 
46534040* **Scope**: [`Managed`](#scopes)
46544041* **Type**: the string `"hooks"` in the [`strictPluginOnlyCustomization`](#strictpluginonlycustomization) array
from line 4572
51854572}
51864573```
51874574 
5188<span id="worktree-settings" />
5189 
51904575### `worktree`
51914576 
51924577Configure how Claude Code creates and manages [git worktrees](/docs/en/worktrees) for `--worktree`, the `EnterWorktree` tool, and isolated subagents and background sessions.
from line 4734
53494734 
53504735### `disableArtifact`
53514736 
5352<Warning>
5353 Deprecated, and replaced by [`enableArtifact`](#enableartifact). Claude Code still honors `disableArtifact: true` as equivalent to `enableArtifact: false`, and ignores `disableArtifact: false`.
5354</Warning>
4737> [!WARNING]
4738>
4739> Deprecated, and replaced by [`enableArtifact`](#enableartifact). Claude Code still honors `disableArtifact: true` as equivalent to `enableArtifact: false`, and ignores `disableArtifact: false`.
53554740 
53564741Use [`enableArtifact`](#enableartifact) instead to turn off the [Artifact](/docs/en/artifacts) tool, which publishes session output as a private web page on claude.ai. When you turn the **Artifacts** row off in `/config`, Claude Code writes `enableArtifact` to your user settings and clears this key.
53574742 
from line 4950
55654950A value that Desktop can't read as a list of hosts, such as `true` or an object, counts as an empty array until you correct it, except `null`, which counts as unset. Requires Claude Desktop v2.26454.0 or later.
55664951 
55674952If you set [`managedSourcesBehavior`](#managedsourcesbehavior) to `"merge"` in your highest-ranked source, Desktop combines the lists from every [admin source](/docs/en/managed-settings#how-claude-code-combines-managed-sources) and allows a host that matches any of them. If you set an empty array in one source, SSH sessions stay on for the hosts another source lists.
5568 
5569<span id="authentication-and-login" />
55704953 
55714954## Authentication and providers
55724955 
from line 5296
59135296 
59145297The desktop app ignores any other value, and a value that isn't a Boolean, such as the string `"true"` or `1`, also logs a warning.
59155298 
5916<span id="data-and-privacy" />
5917 
59185299## Privacy and telemetry
59195300 
59205301Control how long Claude Code keeps session data and what it sends. The switches that turn off usage metrics and error reports are environment variables, not settings keys: set `DISABLE_TELEMETRY`, `DISABLE_ERROR_REPORTING`, or `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` in the [`env`](#env) key or in the shell. [Telemetry services](/docs/en/data-usage#telemetry-services) says what each one stops. Two exceptions turn off from a settings file: [`feedbackDrafts`](#feedbackdrafts) below for Claude-drafted feedback, and [`feedbackSurveyRate`](#feedbacksurveyrate) below for the session survey.
from line 5384
60035384```
60045385 
60055386With the check skipped, WebFetch attempts any URL without consulting the blocklist, so pair it with [`WebFetch` permission rules](/docs/en/permissions#webfetch) if you need to restrict which domains Claude can reach.
6006 
6007<span id="managed-policy" />
60085387 
60095388## Enterprise and managed settings
60105389 
from line 5498
61195498 
61205499This key has no effect when no admin-deployed managed tier exists: the host's settings then apply as the only managed tier, still filtered to restrictive values. For the filter's limits and how the managed sources interact, see [Parent settings from embedding hosts](/docs/en/managed-settings#parent-settings-from-embedding-hosts) and [Restrict parent settings](/docs/en/claude-apps-gateway#restrict-parent-settings).
61215500 
6122<span id="compute-managed-settings-with-a-policy-helper" />
6123 
61245501### `policyHelper`
61255502 
61265503Run an executable you deploy that computes managed settings at startup, so you can derive policy from device posture, identity, or a remote service instead of a static file. Claude Code runs the helper before it accepts the first prompt and treats the settings it emits as the managed settings for the session.
from line 5821
64445821 
64455822### `permissionExplainerEnabled`
64465823 
6447<Warning>
6448 Removed in v2.1.257, together with the `Ctrl+E` command explanation on Bash and PowerShell permission prompts. Setting it has no effect on current versions.
6449</Warning>
5824> [!WARNING]
5825>
5826> Removed in v2.1.257, together with the `Ctrl+E` command explanation on Bash and PowerShell permission prompts. Setting it has no effect on current versions.
64505827 
64515828Through v2.1.256, you could press `Ctrl+E` on a Bash or PowerShell permission prompt to see a model-generated explanation of the command, and set this key to `false` to turn that shortcut off.
64525829 
from line 5851
64745851 
64755852### `teammateDefaultModel`
64765853 
6477<Warning>
6478 Removed in v2.1.234, together with its `/config` row **Default teammate model**. Setting it has no effect on current versions.
6479</Warning>
5854> [!WARNING]
5855>
5856> Removed in v2.1.234, together with its `/config` row **Default teammate model**. Setting it has no effect on current versions.
64805857 
64815858Through v2.1.233, you set this key to the model for [agent team](/docs/en/agent-teams#specify-teammates-and-models) teammates your prompt didn't name a model for: an alias such as `"sonnet"`, or `null` to follow the lead's model. For the model Claude Code picks for such teammates now, see [specify teammates and models](/docs/en/agent-teams#specify-teammates-and-models).
64825859 
64835860 
Feedback