6 6
7> Where Claude Code reads CLAUDE.md, settings.json, hooks, skills, commands, subagents, workflows, rules, and auto memory. Explore the .claude directory in your project and ~/.claude in your home directory.7> Where Claude Code reads CLAUDE.md, settings.json, hooks, skills, commands, subagents, workflows, rules, and auto memory. Explore the .claude directory in your project and ~/.claude in your home directory.
8 8
9export const ClaudeExplorer = () => {
10 const A = useMemo(() => ({href, children}) => <a href={href} style={{
11 color: 'var(--ce-accent)',
12 textDecoration: 'none',
13 borderBottom: '1px dotted var(--ce-accent)'
14 }}>{children}</a>, []);
15 const C = useMemo(() => ({children}) => <code style={{
16 fontFamily: 'var(--ce-mono)',
17 fontSize: '0.92em',
18 padding: '1px 4px',
19 borderRadius: '3px',
20 background: 'var(--ce-surface)',
21 border: '0.5px solid var(--ce-border-subtle)'
22 }}>{children}</code>, []);
23 const commandsNote = useMemo(() => <>Commands and skills are now the same mechanism. For new workflows, use <A href="/en/skills">skills/</A> instead: same <C>/name</C> invocation, plus you can bundle supporting files.</>, []);
24 const FILE_TREE = useMemo(() => ({
25 project: {
26 label: 'your-project/',
27 children: [{
28 id: 'claude-md',
29 label: 'CLAUDE.md',
30 type: 'file',
31 icon: 'md',
32 color: '#6A9BCC',
33 badge: 'committed',
34 oneLiner: 'Project instructions Claude reads every session',
35 when: 'Loaded into context at the start of every session',
36 description: 'Project-specific instructions that shape how Claude works in this repository. Put your conventions, common commands, and architectural context here so Claude operates with the same assumptions your team does.',
37 tips: ['Target under 200 lines. Longer files still load in full but may reduce adherence', <>CLAUDE.md loads into every session. If something only matters for specific tasks, move it to a <A href="/en/skills">skill</A> or a path-scoped <A href="/en/memory#organize-rules-with-claude/rules/">rule</A> so it loads only when needed</>, 'List the commands you run most, like build, test, and format, so Claude knows them without you spelling them out each time', <>Run <C>/memory</C> to open and edit CLAUDE.md from within a session</>, <>Also works at <C>.claude/CLAUDE.md</C> if you prefer to keep the project root clean</>],
38 exampleIntro: 'This example is for a TypeScript and React project. It lists the build and test commands, the framework conventions Claude should follow, and project-specific rules like export style and file layout.',
39 example: `# Project conventions
40
41## Commands
42- Build: \`npm run build\`
43- Test: \`npm test\`
44- Lint: \`npm run lint\`
45
46## Stack
47- TypeScript with strict mode
48- React 19, functional components only
49
50## Rules
51- Named exports, never default exports
52- Tests live next to source: \`foo.ts\` -> \`foo.test.ts\`
53- All API routes return \`{ data, error }\` shape`,
54 docsLink: '/en/memory'
55 }, {
56 id: 'mcp-json',
57 label: '.mcp.json',
58 type: 'file',
59 icon: 'json',
60 color: '#9B7BC4',
61 badge: 'committed',
62 oneLiner: 'Project-scoped MCP servers, shared with your team',
63 when: <>Servers connect when the session begins. Tool schemas are deferred by default and load on demand via <A href="/en/mcp#scale-with-mcp-tool-search">tool search</A></>,
64 description: <>Configures Model Context Protocol (MCP) servers that give Claude access to external tools: databases, APIs, browsers, and more. This file holds the project-scoped servers your whole team uses. Personal servers you want to keep to yourself go in <C>~/.claude.json</C> instead.</>,
65 tips: [<>Use environment variable references for secrets: <C>{'${GITHUB_TOKEN}'}</C></>, <>Lives at the project root, not inside <C>.claude/</C></>, <>For servers only you need, run <C>claude mcp add --scope user</C>. This writes to <C>~/.claude.json</C> instead of <C>.mcp.json</C></>],
66 exampleIntro: <>This example configures the GitHub MCP server so Claude can read issues and open pull requests. The <C>{'${GITHUB_TOKEN}'}</C> reference is read from your shell environment when Claude Code starts the server, so the token never lands in the file.</>,
67 example: `{
68 "mcpServers": {
69 "github": {
70 "command": "npx",
71 "args": ["-y", "@modelcontextprotocol/server-github"],
72 "env": {
73 "GITHUB_TOKEN": "\${GITHUB_TOKEN}"
74 }
75 }
76 }
77}`,
78 docsLink: '/en/mcp'
79 }, {
80 id: 'worktreeinclude',
81 label: '.worktreeinclude',
82 type: 'file',
83 icon: 'md',
84 color: '#8FA876',
85 badge: 'committed',
86 oneLiner: 'Gitignored files to copy into new worktrees',
87 when: <>Read when Claude creates a git worktree via <C>--worktree</C>, the <C>EnterWorktree</C> tool, or subagent <C>isolation: worktree</C></>,
88 description: <>Lists gitignored files to copy from your main repository into each new worktree. Worktrees are fresh checkouts, so untracked files like <C>.env</C> are missing by default. Patterns here use <C>.gitignore</C> syntax. Only files that match a pattern and are also gitignored get copied, so tracked files are never duplicated.</>,
89 tips: [<>Lives at the project root, not inside <C>.claude/</C></>, <>Git-only: if you configure a <A href="/en/hooks#worktreecreate">WorktreeCreate hook</A> for a different VCS, this file is not read. Copy files inside your hook script instead</>, <>Also applies to parallel sessions in the <A href="/en/desktop#work-in-parallel-with-sessions">desktop app</A></>],
90 exampleIntro: 'This example copies your local environment files and a secrets config into every worktree Claude creates. Comments start with # and blank lines are ignored, same as .gitignore.',
91 example: `# Local environment
92.env
93.env.local
94
95# API credentials
96config/secrets.json`,
97 docsLink: '/en/worktrees#copy-gitignored-files-into-worktrees'
98 }, {
99 id: 'dot-claude',
100 label: '.claude/',
101 type: 'folder',
102 icon: 'folder',
103 color: 'var(--ce-accent)',
104 oneLiner: 'Project-level configuration, rules, and extensions',
105 description: 'Everything Claude Code reads that is specific to this project. If you use git, commit most files here so your team shares them; a few, like settings.local.json, are automatically gitignored. Each file badge shows which.',
106 children: [{
107 id: 'settings-json',
108 label: 'settings.json',
109 type: 'file',
110 icon: 'json',
111 color: 'var(--ce-text-3)',
112 badge: 'committed',
113 oneLiner: 'Permissions, hooks, and configuration',
114 when: <>Overrides global <C>~/.claude/settings.json</C>. Local settings, CLI flags, and managed settings override this</>,
115 description: 'Settings that Claude Code applies directly. Permissions control which commands and tools Claude can use; hooks run your scripts at specific points in a session. Unlike CLAUDE.md, which Claude reads as guidance, these are enforced whether Claude follows them or not.',
116 contains: [<><A href="/en/permissions">permissions</A>: allow, deny, or prompt before Claude uses specific tools or commands</>, <><A href="/en/hooks">hooks</A>: run your own scripts on events like before a tool call or after a file edit</>, <><A href="/en/statusline">statusLine</A>: customize the line shown at the bottom while Claude works</>, <><A href="/en/settings#available-settings">model</A>: pick a default model for this project</>, <><A href="/en/settings#environment-variables">env</A>: environment variables set in every session</>, <><A href="/en/output-styles">outputStyle</A>: select a custom system-prompt style from output-styles/</>],
117 tips: [<>Bash permission patterns support wildcards: <C>Bash(npm test *)</C> matches any command starting with <C>npm test</C></>, <>Array settings like <C>permissions.allow</C> combine across all scopes; scalar settings like <C>model</C> use the most specific value</>],
118 exampleIntro: <>This example allows <C>npm test</C> and <C>npm run</C> commands without prompting, blocks <C>rm -rf</C>, and runs Prettier on files after Claude edits or writes them.</>,
119 example: `{
120 "permissions": {
121 "allow": [
122 "Bash(npm test *)",
123 "Bash(npm run *)"
124 ],
125 "deny": [
126 "Bash(rm -rf *)"
127 ]
128 },
129 "hooks": {
130 "PostToolUse": [{
131 "matcher": "Edit|Write",
132 "hooks": [{
133 "type": "command",
134 "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
135 }]
136 }]
137 }
138}`,
139 docsLink: '/en/settings'
140 }, {
141 id: 'settings-local-json',
142 label: 'settings.local.json',
143 type: 'file',
144 icon: 'json',
145 color: 'var(--ce-text-3)',
146 badge: 'gitignored',
147 oneLiner: 'Your personal settings overrides for this project',
148 when: 'Highest of the user-editable settings files; CLI flags and managed settings still take precedence',
149 description: 'Personal settings that take precedence over the project defaults. Same JSON format as settings.json, but not committed. Use this when you need different permissions or defaults than the team config.',
150 tips: [<>Same schema as settings.json. Array settings like <C>permissions.allow</C> combine across scopes; scalar settings like <C>model</C> use the local value</>, <>Claude Code adds this file to <C>~/.config/git/ignore</C> the first time it writes one. If you use a custom <C>core.excludesFile</C>, add the pattern there too. To share the ignore rule with your team, also add it to the project <C>.gitignore</C></>],
151 exampleIntro: 'This example adds Docker permissions on top of whatever the team settings.json allows.',
152 example: `{
153 "permissions": {
154 "allow": [
155 "Bash(docker *)"
156 ]
157 }
158}`,
159 docsLink: '/en/settings'
160 }, {
161 id: 'rules',
162 label: 'rules/',
163 type: 'folder',
164 icon: 'folder',
165 color: '#9B7BC4',
166 oneLiner: 'Topic-scoped instructions, optionally gated by file paths',
167 when: <>Rules without <C>paths:</C> load at session start. Rules with <C>paths:</C> load when a matching file enters context</>,
168 description: [<>Project instructions split into topic files that can load conditionally based on file paths. A rule without <C>paths:</C> frontmatter loads at session start like CLAUDE.md; a rule with <C>paths:</C> loads only when Claude reads a matching file.</>, <>Like CLAUDE.md, rules are guidance Claude reads, not configuration Claude Code enforces. For guaranteed behavior use <A href="/en/hooks">hooks</A> or <A href="/en/permissions">permissions</A>.</>],
169 tips: [<>Use <C>paths:</C> frontmatter with globs to scope rules to directories or file types</>, <>Subdirectories work: <C>.claude/rules/frontend/react.md</C> is discovered automatically</>, 'When CLAUDE.md approaches 200 lines, start splitting into rules'],
170 docsLink: '/en/memory#organize-rules-with-claude/rules/',
171 children: [{
172 id: 'rule-testing',
173 label: 'testing.md',
174 type: 'file',
175 icon: 'md',
176 color: '#9B7BC4',
177 badge: 'committed',
178 oneLiner: 'Test conventions scoped to test files',
179 when: <>Loaded when Claude reads a file matching the <C>paths:</C> globs below</>,
180 description: <>An example rule that only loads when Claude is working on test files. The <C>paths:</C> globs in the frontmatter define which files trigger it; here, anything ending in .test.ts or .test.tsx. For other files, this rule is not loaded into context.</>,
181 example: `---
182paths:
183 - "**/*.test.ts"
184 - "**/*.test.tsx"
185
186# Testing Rules
187
188- Use descriptive test names: "should [expected] when [condition]"
189- Mock external dependencies, not internal modules
190- Clean up side effects in afterEach`
191 }, {
192 id: 'rule-api',
193 label: 'api-design.md',
194 type: 'file',
195 icon: 'md',
196 color: '#9B7BC4',
197 badge: 'committed',
198 oneLiner: 'API conventions scoped to backend code',
199 when: <>Loaded when Claude reads a file matching the <C>paths:</C> glob below</>,
200 description: <>A second example showing a rule scoped to backend code. The <C>paths:</C> glob matches files under src/api/, so these conventions load only when Claude is editing API routes.</>,
201 example: `---
202paths:
203 - "src/api/**/*.ts"
204
205# API Design Rules
206
207- All endpoints must validate input with Zod schemas
208- Return shape: { data: T } | { error: string }
209- Rate limit all public endpoints`
210 }]
211 }, {
212 id: 'skills',
213 label: 'skills/',
214 type: 'folder',
215 icon: 'folder',
216 color: '#D4A843',
217 oneLiner: 'Reusable prompts you or Claude invoke by name',
218 when: <>Invoked with <C>/skill-name</C> or when Claude matches the task to a skill</>,
219 description: <>Each skill is a folder with a SKILL.md file plus any supporting files it needs. By default, both you and Claude can invoke a skill. Use frontmatter to control that: <C>disable-model-invocation: true</C> for user-only workflows like <C>/deploy</C>, or <C>user-invocable: false</C> to hide from the <C>/</C> menu while Claude can still invoke it.</>,
220 tips: [<>Skills accept arguments: <C>/deploy staging</C> passes "staging" as <C>$ARGUMENTS</C>. Use <C>$0</C>, <C>$1</C>, and so on for positional access</>, <>The <C>description</C> frontmatter determines when Claude auto-invokes the skill</>, 'Bundle reference docs alongside SKILL.md. Claude knows the skill directory path and can read supporting files when you mention them'],
221 docsLink: '/en/skills',
222 children: [{
223 id: 'skill-review',
224 label: 'security-review/',
225 type: 'folder',
226 icon: 'folder',
227 color: '#D4A843',
228 oneLiner: 'A skill bundling SKILL.md with supporting files',
229 children: [{
230 id: 'skill-review-md',
231 label: 'SKILL.md',
232 type: 'file',
233 icon: 'md',
234 color: '#D4A843',
235 badge: 'committed',
236 oneLiner: 'Entrypoint: trigger, invocability, instructions',
237 when: <>User types <C>/security-review <target></C>; Claude cannot auto-invoke this skill</>,
238 description: [<>This skill uses <C>disable-model-invocation: true</C> so only you can trigger it; Claude never invokes it on its own.</>, <>The <C>!`...`</C> line runs a shell command and injects its output into the prompt. <C>$ARGUMENTS</C> substitutes whatever you typed after the skill name. Claude sees the skill directory path, so mentioning a bundled file like checklist.md lets Claude read it.</>],
239 example: `---
240description: Reviews code changes for security vulnerabilities, authentication gaps, and injection risks
241disable-model-invocation: true
242argument-hint: <branch-or-path>
243
244## Diff to review
245
246!\`git diff $ARGUMENTS\`
247
248Audit the changes above for:
249
2501. Injection vulnerabilities (SQL, XSS, command)
2512. Authentication and authorization gaps
2523. Hardcoded secrets or credentials
253
254Use checklist.md in this skill directory for the full review checklist.
255
256Report findings with severity ratings and remediation steps.`
257 }, {
258 id: 'skill-checklist',
259 label: 'checklist.md',
260 type: 'file',
261 icon: 'md',
262 color: '#D4A843',
263 badge: 'committed',
264 oneLiner: 'Supporting file bundled with the skill',
265 when: 'Claude reads it on demand while running the skill',
266 description: <>Skills can bundle any supporting files: reference docs, templates, scripts. The skill directory path is prepended to SKILL.md, so Claude can read bundled files by name. For scripts in bash injection commands, use the <C>{'${CLAUDE_SKILL_DIR}'}</C> placeholder.</>,
267 example: `# Security Review Checklist
268
269## Input Validation
270- [ ] All user input sanitized before DB queries
271- [ ] File upload MIME types validated
272- [ ] Path traversal prevented on file operations
273
274## Authentication
275- [ ] JWT tokens expire after 24 hours
276- [ ] API keys stored in environment variables
277- [ ] Passwords hashed with bcrypt or argon2`
278 }]
279 }]
280 }, {
281 id: 'commands',
282 label: 'commands/',
283 type: 'folder',
284 icon: 'folder',
285 color: '#788C5D',
286 oneLiner: <>Single-file prompts invoked with <C>/name</C></>,
287 note: commandsNote,
288 when: <>User types <C>/command-name</C></>,
289 description: <>A file at <C>commands/deploy.md</C> creates <C>/deploy</C> the same way a skill at <C>skills/deploy/SKILL.md</C> does, and both can be auto-invoked by Claude. Skills use a directory with SKILL.md, letting you bundle reference docs, templates, or scripts alongside the prompt.</>,
290 tips: [<>Use <C>$ARGUMENTS</C> in the file to accept parameters: <C>/fix-issue 123</C></>, 'If a skill and command share a name, the skill takes precedence', 'New commands should usually be skills instead; commands remain supported'],
291 docsLink: '/en/skills',
292 children: [{
293 id: 'cmd-example',
294 label: 'fix-issue.md',
295 type: 'file',
296 icon: 'md',
297 color: '#788C5D',
298 badge: 'committed',
299 oneLiner: <>Invoked as <C>/fix-issue <number></C></>,
300 note: commandsNote,
301 description: [<>An example command for fixing a GitHub issue. Type <C>/fix-issue 123</C> and the <C>!`...`</C> line runs <C>gh issue view 123</C> in your shell, injecting the output into the prompt before Claude sees it.</>, <><C>$ARGUMENTS</C> substitutes whatever you typed after the command name. For positional access, use <C>$0</C> <C>$1</C> and so on.</>],
302 example: `---
303argument-hint: <issue-number>
304
305!\`gh issue view $ARGUMENTS\`
306
307Investigate and fix the issue above.
308
3091. Trace the bug to its root cause
3102. Implement the fix
3113. Write or update tests
3124. Summarize what you changed and why`
313 }]
314 }, {
315 id: 'output-styles',
316 label: 'output-styles/',
317 type: 'folder',
318 icon: 'folder',
319 color: '#5AA7A7',
320 oneLiner: 'Project-scoped output styles, if your team shares any',
321 when: 'Applied at session start when selected via the outputStyle setting',
322 description: <>Output styles are usually personal, so most live in <C>~/.claude/output-styles/</C>. Put one here if your team shares a style, like a review mode everyone uses. See <A href="#ce-global-output-styles">the Global tab</A> for the full explanation and example.</>,
323 docsLink: '/en/output-styles',
324 children: []
325 }, {
326 id: 'agents',
327 label: 'agents/',
328 type: 'folder',
329 icon: 'folder',
330 color: '#C46686',
331 oneLiner: 'Specialized subagents with their own context window',
332 when: 'Runs in its own context window when you or Claude invoke it',
333 description: 'Each markdown file defines a subagent with its own system prompt, tool access, and optionally its own model. Subagents run in a fresh context window, keeping the main conversation clean. Useful for parallel work or isolated tasks.',
334 tips: ['Each agent gets a fresh context window, separate from your main session', <>Restrict tool access per agent with the <C>tools:</C> frontmatter field</>, 'Type @ and pick an agent from the autocomplete to delegate directly'],
335 docsLink: '/en/sub-agents',
336 children: [{
337 id: 'agent-reviewer',
338 label: 'code-reviewer.md',
339 type: 'file',
340 icon: 'md',
341 color: '#C46686',
342 badge: 'committed',
343 oneLiner: 'Subagent for isolated code review',
344 when: 'Claude spawns it for review tasks, or you @-mention it from the autocomplete',
345 description: <>An example subagent restricted to read-only tools. The <C>description</C> frontmatter tells Claude when to delegate to it automatically; <C>tools:</C> limits it to Read, Grep, and Glob so it can inspect code but never edit. The body becomes the subagent's system prompt.</>,
346 example: `---
347name: code-reviewer
348description: Reviews code for correctness, security, and maintainability
349tools: Read, Grep, Glob
350
351You are a senior code reviewer. Review for:
352
3531. Correctness: logic errors, edge cases, null handling
3542. Security: injection, auth bypass, data exposure
3553. Maintainability: naming, complexity, duplication
356
357Every finding must include a concrete fix.`
358 }]
359 }, {
360 id: 'workflows',
361 label: 'workflows/',
362 type: 'folder',
363 icon: 'folder',
364 color: '#C46686',
365 oneLiner: 'Dynamic workflow scripts that orchestrate many subagents',
366 when: 'Loaded at startup; each file becomes a /<name> command',
367 description: <>Each <C>.js</C> file is a <A href="/en/workflows">dynamic workflow</A>: a script the runtime executes to spawn and coordinate many subagents. Workflows are written by Claude and saved here from <C>/workflows</C> rather than authored from scratch.</>,
368 tips: [<>Save a run from <C>/workflows</C> with <C>s</C> to create one of these</>, <>A project workflow takes precedence over a personal one in <C>~/.claude/workflows/</C> with the same name</>],
369 docsLink: '/en/workflows'
370 }, {
371 id: 'agent-memory',
372 label: 'agent-memory/',
373 type: 'folder',
374 icon: 'folder',
375 color: '#C46686',
376 badge: 'committed',
377 autogen: true,
378 oneLiner: 'Subagent persistent memory, separate from your main session auto memory',
379 when: 'First 200 lines (capped at 25KB) of MEMORY.md loaded into the subagent system prompt when it runs',
380 description: <>Subagents with <C>memory: project</C> in their frontmatter get a dedicated memory directory here. This is distinct from your <A href="/en/memory#auto-memory">main session auto memory</A> at <C>~/.claude/projects/</C>: each subagent reads and writes its own MEMORY.md, not yours.</>,
381 tips: [<>Only created for subagents that set the <C>memory:</C> frontmatter field</>, <>This directory holds project-scoped subagent memory, meant to be shared with your team. To keep memory out of version control use <C>memory: local</C>, which writes to <C>.claude/agent-memory-local/</C> instead. For cross-project memory use <C>memory: user</C>, which writes to <C>~/.claude/agent-memory/</C></>, <>The main session auto memory is a different feature; see <C>~/.claude/projects/</C> in the Global tab</>],
382 docsLink: '/en/sub-agents#enable-persistent-memory',
383 children: [{
384 id: 'agent-memory-sub',
385 label: '<agent-name>/',
386 type: 'folder',
387 icon: 'folder',
388 color: '#C46686',
389 autogen: true,
390 children: [{
391 id: 'agent-memory-md',
392 label: 'MEMORY.md',
393 type: 'file',
394 icon: 'md',
395 color: '#C46686',
396 badge: 'committed',
397 autogen: true,
398 oneLiner: 'The subagent writes and maintains this file automatically',
399 when: 'Loaded into the subagent system prompt when the subagent starts',
400 description: <>Works the same as your <A href="/en/memory#auto-memory">main auto memory</A>: the subagent creates and updates this file itself. You do not write it. The subagent reads it at the start of each task and writes back what it learns.</>,
401 example: `# code-reviewer memory
402
403## Patterns seen
404- Project uses custom Result<T, E> type, not exceptions
405- Auth middleware expects Bearer token in Authorization header
406- Tests use factory functions in test/factories/
407
408## Recurring issues
409- Missing null checks on API responses (src/api/*)
410- Unhandled promise rejections in background jobs`
411 }]
412 }]
413 }]
414 }]
415 },
416 global: {
417 label: '~/',
418 children: [{
419 id: 'claude-json',
420 label: '.claude.json',
421 type: 'file',
422 icon: 'json',
423 color: 'var(--ce-text-3)',
424 badge: 'local',
425 oneLiner: 'App state and UI preferences',
426 when: <>Read at session start for your preferences and MCP servers. Claude Code writes back to it when you change settings in <C>/config</C> or approve trust prompts</>,
427 description: <>Holds state that does not belong in settings.json: theme, OAuth session, per-project trust decisions, your personal MCP servers, and UI toggles. Mostly managed through <C>/config</C> rather than editing directly.</>,
428 tips: [<>IDE toggles like <C>autoConnectIde</C> and <C>externalEditorContext</C> live here, not in settings.json</>, <>The <C>projects</C> key tracks per-project state like trust-dialog acceptance and last-session metrics. Permission rules you approve in-session go to <C>.claude/settings.local.json</C> instead</>, <>MCP servers here are yours only: user scope applies across all projects, local scope is per-project but not committed. Team-shared servers go in <C>.mcp.json</C> at the project root instead</>],
429 example: `{
430 "autoConnectIde": true,
431 "externalEditorContext": true,
432 "mcpServers": {
433 "my-tools": {
434 "command": "npx",
435 "args": ["-y", "@example/mcp-server"]
436 }
437 }
438}`,
439 docsLink: '/en/settings#global-config-settings'
440 }, {
441 id: 'global-dot-claude',
442 label: '.claude/',
443 type: 'folder',
444 icon: 'folder',
445 color: 'var(--ce-accent)',
446 oneLiner: 'Your personal configuration across all projects',
447 description: 'The global counterpart to your project .claude/ directory. Files here apply to every project you work in and are never committed to any repository.',
448 children: [{
449 id: 'global-claude-md',
450 label: 'CLAUDE.md',
451 type: 'file',
452 icon: 'md',
453 color: '#6A9BCC',
454 badge: 'local',
455 oneLiner: 'Personal preferences across every project',
456 when: 'Loaded at the start of every session, in every project',
457 description: 'Your global instruction file. Loaded alongside the project CLAUDE.md at session start, so both are in context together. When instructions conflict, project-level instructions take priority. Keep this to preferences that apply everywhere: response style, commit format, personal conventions.',
458 tips: ['Keep it short since it loads into context for every project, alongside that project\'s own CLAUDE.md', 'Good for response style, commit format, and personal conventions'],
459 example: `# Global preferences
460
461- Keep explanations concise
462- Use conventional commit format
463- Show the terminal command to verify changes
464- Prefer composition over inheritance`,
465 docsLink: '/en/memory'
466 }, {
467 id: 'global-settings',
468 label: 'settings.json',
469 type: 'file',
470 icon: 'json',
471 color: 'var(--ce-text-3)',
472 badge: 'local',
473 oneLiner: 'Default settings for all projects',
474 when: 'Your defaults. Project and local settings.json override any keys you also set there',
475 description: [<>Same keys as project <C>settings.json</C>: permissions, hooks, model, environment variables, and the rest. Put settings here that you want in every project, like permissions you always allow, a preferred model, or a notification hook that runs regardless of which project you're in.</>, <>Settings follow a precedence order: project <C>settings.json</C> overrides any matching keys you set here. This is different from CLAUDE.md, where global and project files are both loaded into context rather than merged key by key.</>],
476 example: `{
477 "permissions": {
478 "allow": [
479 "Bash(git log *)",
480 "Bash(git diff *)"
481 ]
482 }
483}`,
484 docsLink: '/en/settings'
485 }, {
486 id: 'keybindings',
487 label: 'keybindings.json',
488 type: 'file',
489 icon: 'json',
490 color: 'var(--ce-text-3)',
491 badge: 'local',
492 oneLiner: 'Custom keyboard shortcuts',
493 when: 'Read at session start and hot-reloaded when you edit the file',
494 description: <>Rebind keyboard shortcuts in the interactive CLI. Run <C>/keybindings</C> to create or open this file with a schema reference. Ctrl+C, Ctrl+D, Ctrl+M, and Caps Lock are reserved and cannot be rebound.</>,
495 exampleIntro: <>This example binds <C>Ctrl+E</C> to open your external editor and unbinds <C>Ctrl+U</C> by setting it to <C>null</C>. The <C>context</C> field scopes bindings to a specific part of the CLI, here the main chat input.</>,
496 example: `{
497 "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
498 "$docs": "https://code.claude.com/docs/en/keybindings",
499 "bindings": [
500 {
501 "context": "Chat",
502 "bindings": {
503 "ctrl+e": "chat:externalEditor",
504 "ctrl+u": null
505 }
506 }
507 ]
508}`,
509 docsLink: '/en/keybindings'
510 }, {
511 id: 'themes',
512 label: 'themes/',
513 type: 'folder',
514 icon: 'folder',
515 color: '#5AA7A7',
516 oneLiner: 'Custom color themes',
517 when: <>Read at session start and hot-reloaded when files change. Listed in <C>/theme</C></>,
518 description: <>Each <C>.json</C> file defines a custom color theme: a built-in <C>base</C> preset plus an <C>overrides</C> map of color tokens. Create one interactively with <C>/theme</C> or write the JSON by hand. Selecting a custom theme stores <C>custom:<slug></C> as your theme preference.</>,
519 example: `{
520 "name": "Dracula",
521 "base": "dark",
522 "overrides": {
523 "claude": "#bd93f9",
524 "error": "#ff5555",
525 "success": "#50fa7b"
526 }
527}`,
528 docsLink: '/en/terminal-config#create-a-custom-theme',
529 children: []
530 }, {
531 id: 'global-projects',
532 label: 'projects/',
533 type: 'folder',
534 icon: 'folder',
535 color: '#E8A45C',
536 autogen: true,
537 oneLiner: "Auto memory: Claude's notes to itself, per project",
538 when: 'MEMORY.md loaded at session start; topic files read on demand',
539 description: 'Auto memory lets Claude accumulate knowledge across sessions without you writing anything. Claude saves notes as it works: build commands, debugging insights, architecture notes. Each project gets its own memory directory keyed by the repository path.',
540 tips: [<>On by default. Toggle with <C>/memory</C> or <C>autoMemoryEnabled</C> in settings</>, 'MEMORY.md is the index loaded each session. The first 200 lines, or 25KB, whichever comes first, are read', 'Topic files like debugging.md are read on demand, not at startup', 'These are plain markdown. Edit or delete them anytime'],
541 docsLink: '/en/memory#auto-memory',
542 children: [{
543 id: 'memory-dir',
544 label: '<project>/memory/',
545 type: 'folder',
546 icon: 'folder',
547 color: '#E8A45C',
548 autogen: true,
549 oneLiner: "Claude's accumulated knowledge for one project",
550 children: [{
551 id: 'memory-md',
552 label: 'MEMORY.md',
553 type: 'file',
554 icon: 'md',
555 color: '#E8A45C',
556 badge: 'local',
557 autogen: true,
558 oneLiner: 'Claude writes and maintains this file automatically',
559 when: 'First 200 lines (capped at 25KB) loaded at session start',
560 description: 'Claude creates and updates this file as it works; you do not write it yourself. It acts as an index that Claude reads at the start of every session, pointing to topic files for detail. You can edit or delete it, but Claude will keep updating it.',
561 example: `# Memory Index
562
563## Project
564- [build-and-test.md](build-and-test.md): npm run build (~45s), Vitest, dev server on 3001
565- [architecture.md](architecture.md): API client singleton, refresh-token auth
566
567## Reference
568- [debugging.md](debugging.md): auth token rotation and DB connection troubleshooting`,
569 docsLink: '/en/memory'
570 }, {
571 id: 'memory-topic',
572 label: 'debugging.md',
573 type: 'file',
574 icon: 'md',
575 color: '#E8A45C',
576 badge: 'local',
577 autogen: true,
578 oneLiner: 'Topic notes Claude writes when MEMORY.md gets long',
579 when: 'Claude reads this when a related task comes up',
580 description: 'An example of a topic file Claude creates when MEMORY.md grows too long. Claude picks the filename based on what it splits out: debugging.md, architecture.md, build-commands.md, or similar. You never create these yourself. Claude reads a topic file back only when the current task relates to it.',
581 example: `---
582name: Debugging patterns
583description: Auth token rotation and database connection troubleshooting for this project
584type: reference
585
586## Auth Token Issues
587- Refresh token rotation: old token invalidated immediately
588- If 401 after refresh: check clock skew between client and server
589
590## Database Connection Drops
591- Connection pool: max 10 in dev, 50 in prod
592- Always check \`docker compose ps\` first`
593 }]
594 }]
595 }, {
596 id: 'global-rules',
597 label: 'rules/',
598 type: 'folder',
599 icon: 'folder',
600 color: '#9B7BC4',
601 oneLiner: 'User-level rules that apply to every project',
602 when: <>Rules without <C>paths:</C> load at session start. Rules with <C>paths:</C> load when a matching file enters context</>,
603 description: 'Same as project .claude/rules/ but applies everywhere. Use this for conventions you want across all your work, like personal code style or commit message format.',
604 docsLink: '/en/memory#organize-rules-with-claude/rules/',
605 children: []
606 }, {
607 id: 'global-skills',
608 label: 'skills/',
609 type: 'folder',
610 icon: 'folder',
611 color: '#D4A843',
612 oneLiner: 'Personal skills available in every project',
613 when: <>Invoked with <C>/skill-name</C> in any project</>,
614 description: 'Skills you built for yourself that work everywhere. Same structure as project skills: each is a folder with SKILL.md, scoped to your user account instead of a single project.',
615 docsLink: '/en/skills',
616 children: []
617 }, {
618 id: 'global-commands',
619 label: 'commands/',
620 type: 'folder',
621 icon: 'folder',
622 color: '#788C5D',
623 oneLiner: 'Personal single-file commands available in every project',
624 note: commandsNote,
625 when: <>User types <C>/command-name</C> in any project</>,
626 description: 'Same as project commands/ but scoped to your user account. Each markdown file becomes a command available everywhere.',
627 docsLink: '/en/skills',
628 children: []
629 }, {
630 id: 'global-output-styles',
631 label: 'output-styles/',
632 type: 'folder',
633 icon: 'folder',
634 color: '#5AA7A7',
635 oneLiner: 'Custom system-prompt sections that adjust how Claude works',
636 when: 'Applied at session start when selected via the outputStyle setting',
637 description: [<>Each markdown file defines an output style: a section appended to the system prompt that, by default, also drops the built-in software-engineering task instructions. Use this to adapt Claude Code for uses beyond coding, or to add teaching or review modes.</>, <>Select a built-in or custom style with <C>/config</C> or the <C>outputStyle</C> key in settings. Styles here are available in every project; project-level styles with the same name take precedence.</>],
638 tips: ['Built-in styles Explanatory and Learning are included with Claude Code; custom styles go here', <>Set <C>keep-coding-instructions: true</C> in frontmatter to keep the default task instructions alongside your additions</>, 'Changes take effect on the next session since the system prompt is fixed at startup for caching'],
639 docsLink: '/en/output-styles',
640 children: [{
641 id: 'output-style-example',
642 label: 'teaching.md',
643 type: 'file',
644 icon: 'md',
645 color: '#5AA7A7',
646 badge: 'local',
647 oneLiner: 'Example style that adds explanations and leaves small changes for you',
648 when: <>Active when <C>outputStyle</C> in settings is set to <C>teaching</C></>,
649 description: <>This style appends instructions to the system prompt: Claude adds a "Why this approach" note after each task and leaves TODO(human) markers for changes under 10 lines instead of writing them itself. Select it by setting <C>outputStyle</C> to the filename without .md, or to the <C>name</C> field if you set one in frontmatter.</>,
650 example: `---
651description: Explains reasoning and asks you to implement small pieces
652keep-coding-instructions: true
653
654After completing each task, add a brief "Why this approach" note
655explaining the key design decision.
656
657When a change is under 10 lines, ask the user to implement it
658themselves by leaving a TODO(human) marker instead of writing it.`
659 }]
660 }, {
661 id: 'global-agents',
662 label: 'agents/',
663 type: 'folder',
664 icon: 'folder',
665 color: '#C46686',
666 oneLiner: 'Personal subagents available in every project',
667 when: 'Claude delegates or you @-mention in any project',
668 description: 'Subagents defined here are available across all your projects. Same format as project agents.',
669 docsLink: '/en/sub-agents',
670 children: []
671 }, {
672 id: 'global-workflows',
673 label: 'workflows/',
674 type: 'folder',
675 icon: 'folder',
676 color: '#C46686',
677 oneLiner: 'Personal dynamic workflows available in every project',
678 when: 'Loaded at startup; each file becomes a /<name> command',
679 description: <>Workflow scripts saved here are available across all your projects. A project workflow with the same name in <C>.claude/workflows/</C> takes precedence.</>,
680 docsLink: '/en/workflows',
681 children: []
682 }, {
683 id: 'global-agent-memory',
684 label: 'agent-memory/',
685 type: 'folder',
686 icon: 'folder',
687 color: '#C46686',
688 autogen: true,
689 oneLiner: <>Persistent memory for subagents with <C>memory: user</C></>,
690 when: 'Loaded into the subagent system prompt when the subagent starts',
691 description: <>Subagents with <C>memory: user</C> in their frontmatter store knowledge here that persists across all projects. For project-scoped subagent memory, see <C>.claude/agent-memory/</C> instead.</>,
692 docsLink: '/en/sub-agents#enable-persistent-memory',
693 children: []
694 }]
695 }]
696 }
697 }), []);
698 const BADGE_STYLES = useMemo(() => ({
699 committed: {
700 bg: 'rgba(85,138,66,0.08)',
701 color: 'var(--ce-badge-committed)',
702 border: 'rgba(85,138,66,0.15)',
703 label: 'committed'
704 },
705 gitignored: {
706 bg: 'rgba(217,119,87,0.06)',
707 color: 'var(--ce-badge-gitignored)',
708 border: 'rgba(217,119,87,0.15)',
709 label: 'gitignored'
710 },
711 local: {
712 bg: 'rgba(115,114,108,0.06)',
713 color: 'var(--ce-badge-local)',
714 border: 'rgba(115,114,108,0.12)',
715 label: 'local only'
716 },
717 autogen: {
718 bg: 'rgba(232,164,92,0.1)',
719 color: 'var(--ce-badge-autogen)',
720 border: 'rgba(232,164,92,0.2)',
721 label: 'Claude writes'
722 }
723 }), []);
724 const allNodes = useMemo(() => {
725 const flatten = (nodes, acc, path, parentId) => {
726 for (const node of nodes) {
727 const nextPath = [...path, node.label];
728 acc[node.id] = {
729 ...node,
730 path: nextPath,
731 parentId
732 };
733 if (node.children) flatten(node.children, acc, nextPath, node.id);
734 }
735 return acc;
736 };
737 const project = flatten(FILE_TREE.project.children, {}, [FILE_TREE.project.label]);
738 const global = flatten(FILE_TREE.global.children, {}, [FILE_TREE.global.label]);
739 for (const id in project) project[id].root = 'project';
740 for (const id in global) global[id].root = 'global';
741 return {
742 ...project,
743 ...global
744 };
745 }, [FILE_TREE]);
746 const allFolderIds = useMemo(() => Object.keys(allNodes).filter(id => allNodes[id].type === 'folder'), [allNodes]);
747 const DEFAULT_EXPANDED = ['dot-claude', 'rules', 'skills', 'skill-review', 'commands', 'agents', 'agent-memory', 'agent-memory-sub', 'global-dot-claude', 'global-output-styles', 'global-projects', 'memory-dir'];
748 const [mounted, setMounted] = useState(false);
749 const [activeRoot, setActiveRoot] = useState('project');
750 const [selectedId, setSelectedId] = useState('claude-md');
751 const [expandedFolders, setExpandedFolders] = useState(() => new Set(DEFAULT_EXPANDED));
752 const [forceMobile, setForceMobile] = useState(false);
753 const [copiedId, setCopiedId] = useState(null);
754 const [isFullscreen, setIsFullscreen] = useState(false);
755 const copyTimeoutRef = useRef(null);
756 const rootRef = useRef(null);
757 useEffect(() => {
758 setMounted(true);
759 const applyHash = scroll => {
760 const hash = window.location.hash.slice(1);
761 if (!hash.startsWith('ce-')) return;
762 const id = hash.slice(3);
763 const node = allNodes[id];
764 if (!node) return;
765 setActiveRoot(node.root);
766 setSelectedId(id);
767 setExpandedFolders(new Set(allFolderIds));
768 if (scroll && rootRef.current) rootRef.current.scrollIntoView({
769 behavior: 'smooth',
770 block: 'start'
771 });
772 };
773 applyHash(false);
774 const onHashChange = () => applyHash(true);
775 const onFsChange = () => setIsFullscreen(!!document.fullscreenElement);
776 window.addEventListener('hashchange', onHashChange);
777 document.addEventListener('fullscreenchange', onFsChange);
778 return () => {
779 if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
780 window.removeEventListener('hashchange', onHashChange);
781 document.removeEventListener('fullscreenchange', onFsChange);
782 };
783 }, []);
784 useEffect(() => {
785 if (!mounted || !rootRef.current) return;
786 const hash = window.location.hash.slice(1);
787 if (hash.startsWith('ce-') && allNodes[hash.slice(3)]) {
788 rootRef.current.scrollIntoView({
789 behavior: 'smooth',
790 block: 'start'
791 });
792 }
793 }, [mounted]);
794 if (!mounted) return null;
795 const selected = allNodes[selectedId];
796 const tree = FILE_TREE[activeRoot];
797 const isCopied = copiedId === selected.id;
798 const toggleFolder = id => {
799 const next = new Set(expandedFolders);
800 next.has(id) ? next.delete(id) : next.add(id);
801 setExpandedFolders(next);
802 };
803 const switchRoot = root => {
804 if (root === activeRoot) return;
805 setActiveRoot(root);
806 const firstId = FILE_TREE[root].children[0].id;
807 setSelectedId(firstId);
808 try {
809 history.replaceState(null, '', '#ce-' + firstId);
810 } catch (e) {}
811 };
812 const toggleFullscreen = () => {
813 if (!rootRef.current) return;
814 if (document.fullscreenElement) document.exitFullscreen(); else rootRef.current.requestFullscreen().catch(() => {});
815 };
816 const selectNode = n => {
817 setSelectedId(n.id);
818 if (n.type === 'folder' && !expandedFolders.has(n.id)) toggleFolder(n.id);
819 try {
820 history.replaceState(null, '', '#ce-' + n.id);
821 } catch (e) {}
822 };
823 const iconBtn = {
824 width: 28,
825 flexShrink: 0,
826 borderRadius: '6px',
827 border: 'none',
828 cursor: 'pointer',
829 background: 'transparent',
830 color: 'var(--ce-text-4)',
831 display: 'flex',
832 alignItems: 'center',
833 justifyContent: 'center'
834 };
835 const visibleFolderIds = allFolderIds.filter(id => allNodes[id].root === activeRoot);
836 const allExpanded = visibleFolderIds.every(id => expandedFolders.has(id));
837 const toggleAllFolders = () => {
838 const next = new Set(expandedFolders);
839 visibleFolderIds.forEach(id => allExpanded ? next.delete(id) : next.add(id));
840 setExpandedFolders(next);
841 };
842 const onTreeKeyDown = e => {
843 if (!['ArrowDown', 'ArrowUp', 'ArrowRight', 'ArrowLeft'].includes(e.key)) return;
844 const visible = [];
845 const walk = nodes => {
846 for (const n of nodes) {
847 visible.push(n.id);
848 if (n.children && expandedFolders.has(n.id)) walk(n.children);
849 }
850 };
851 walk(tree.children);
852 const i = visible.indexOf(selectedId);
853 if (i === -1) return;
854 e.preventDefault();
855 if (e.key === 'ArrowDown' && i < visible.length - 1) selectNode(allNodes[visible[i + 1]]); else if (e.key === 'ArrowUp' && i > 0) selectNode(allNodes[visible[i - 1]]); else if (e.key === 'ArrowRight' && selected.type === 'folder') {
856 if (!expandedFolders.has(selectedId)) toggleFolder(selectedId); else if (selected.children && selected.children.length) selectNode(allNodes[selected.children[0].id]);
857 } else if (e.key === 'ArrowLeft') {
858 if (selected.type === 'folder' && expandedFolders.has(selectedId)) toggleFolder(selectedId); else if (selected.parentId) selectNode(allNodes[selected.parentId]);
859 }
860 };
861 const copyExample = (id, text) => {
862 const done = () => {
863 setCopiedId(id);
864 if (copyTimeoutRef.current) clearTimeout(copyTimeoutRef.current);
865 copyTimeoutRef.current = setTimeout(() => setCopiedId(null), 2000);
866 };
867 const fallback = () => {
868 const ta = document.createElement('textarea');
869 ta.value = text;
870 ta.style.position = 'fixed';
871 ta.style.opacity = '0';
872 document.body.appendChild(ta);
873 ta.select();
874 try {
875 if (document.execCommand('copy')) done();
876 } catch (e) {}
877 document.body.removeChild(ta);
878 };
879 if (navigator.clipboard) {
880 navigator.clipboard.writeText(text).then(done, fallback);
881 } else {
882 fallback();
883 }
884 };
885 const renderIcon = (icon, color, size) => {
886 const sz = size || 14;
887 if (icon === 'folder') {
888 return <svg width={sz} height={sz} viewBox="0 0 14 14" fill="none">
889 <path d="M1.5 3.5a1 1 0 0 1 1-1h2.6l1 1.2h5.4a1 1 0 0 1 1 1v5.8a1 1 0 0 1-1 1h-9a1 1 0 0 1-1-1V3.5z" fill={color} fillOpacity="0.15" stroke={color} strokeWidth="1" />
890 </svg>;
891 }
892 if (icon === 'json') {
893 return <svg width={sz} height={sz} viewBox="0 0 14 14" fill="none">
894 <rect x="2" y="1.5" width="10" height="11" rx="1.5" fill={color} fillOpacity="0.15" stroke={color} strokeWidth="1" />
895 <text x="7" y="9" fontSize="6" fontFamily="monospace" fill={color} textAnchor="middle" fontWeight="700">{'{}'}</text>
896 </svg>;
897 }
898 return <svg width={sz} height={sz} viewBox="0 0 14 14" fill="none">
899 <rect x="2" y="1.5" width="10" height="11" rx="1.5" fill={color} fillOpacity="0.15" stroke={color} strokeWidth="1" />
900 <line x1="4.5" y1="5" x2="9.5" y2="5" stroke={color} strokeWidth="1" />
901 <line x1="4.5" y1="7" x2="9.5" y2="7" stroke={color} strokeWidth="1" />
902 <line x1="4.5" y1="9" x2="8" y2="9" stroke={color} strokeWidth="1" />
903 </svg>;
904 };
905 const renderNode = (node, depth) => {
906 const isFolder = node.type === 'folder';
907 const isExpanded = expandedFolders.has(node.id);
908 const isSelected = selectedId === node.id;
909 return <div key={node.id}>
910 <button role="treeitem" tabIndex={-1} onClick={() => selectNode(node)} aria-selected={isSelected} aria-expanded={isFolder ? isExpanded : undefined} style={{
911 display: 'flex',
912 alignItems: 'center',
913 gap: '5px',
914 width: '100%',
915 padding: `4px 8px 4px ${8 + depth * 16}px`,
916 background: isSelected ? 'var(--ce-accent-bg)' : 'transparent',
917 borderTop: 'none',
918 borderRight: 'none',
919 borderBottom: 'none',
920 borderLeft: isSelected ? '2px solid var(--ce-accent)' : '2px solid transparent',
921 outline: 'none',
922 cursor: 'pointer',
923 textAlign: 'left',
924 fontFamily: 'var(--ce-mono)',
925 fontSize: '13.5px',
926 color: isSelected ? 'var(--ce-accent)' : 'var(--ce-text-2)',
927 fontWeight: isSelected ? 550 : 400,
928 transition: 'all 0.1s'
929 }}>
930 {isFolder ? <span onClick={e => {
931 e.stopPropagation();
932 toggleFolder(node.id);
933 }} style={{
934 fontSize: '14px',
935 color: 'var(--ce-text-4)',
936 width: '20px',
937 height: '20px',
938 display: 'inline-flex',
939 alignItems: 'center',
940 justifyContent: 'center',
941 cursor: 'pointer',
942 borderRadius: '4px',
943 marginLeft: '-6px',
944 flexShrink: 0
945 }} onMouseEnter={e => {
946 e.currentTarget.style.background = 'var(--ce-arrow-hover)';
947 e.currentTarget.style.color = 'var(--ce-text-2)';
948 }} onMouseLeave={e => {
949 e.currentTarget.style.background = 'transparent';
950 e.currentTarget.style.color = 'var(--ce-text-4)';
951 }}>{isExpanded ? '▾' : '▸'}</span> : <span style={{
952 width: '14px',
953 flexShrink: 0
954 }} />}
955 {renderIcon(node.icon, node.color)}
956 <span style={{
957 flex: 1,
958 overflow: 'hidden',
959 textOverflow: 'ellipsis',
960 whiteSpace: 'nowrap'
961 }}>{node.label}</span>
962 {node.badge && BADGE_STYLES[node.badge] && <span title={BADGE_STYLES[node.badge].label} style={{
963 width: 6,
964 height: 6,
965 borderRadius: '50%',
966 background: BADGE_STYLES[node.badge].color,
967 flexShrink: 0,
968 opacity: 0.7
969 }} />}
970 </button>
971 {isFolder && isExpanded && node.children && <div role="group">{node.children.map(child => renderNode(child, depth + 1))}</div>}
972 </div>;
973 };
974 return <>
975 <style>{`
976 .ce-root {
977 --ce-mono: var(--font-mono, ui-monospace, monospace);
978 --ce-accent: #D97757;
979 --ce-accent-bg: rgba(217,119,87,0.06);
980 --ce-accent-border: rgba(217,119,87,0.12);
981 --ce-bg: #fff;
982 --ce-surface: #FAFAF7;
983 --ce-surface-hover: #F0EEE6;
984 --ce-border: #E8E6DC;
985 --ce-border-subtle: #F0EEE6;
986 --ce-text: #141413;
987 --ce-text-2: #5E5D59;
988 --ce-text-3: #73726C;
989 --ce-text-4: #9C9A92;
990 --ce-text-5: #B8B6AE;
991 --ce-sep: #D1CFC5;
992 --ce-code-header: #F5F4ED;
993 --ce-code-bg: #1A1918;
994 --ce-arrow-hover: rgba(0,0,0,0.08);
995 --ce-badge-committed: #3d6b2e;
996 --ce-badge-gitignored: #b85c3a;
997 --ce-badge-local: #5e5d59;
998 --ce-badge-autogen: #b07520;
999 --ce-when-text: #4a7fb5;
1000 }
1001 .dark .ce-root {
1002 --ce-bg: #1a1918;
1003 --ce-surface: #232221;
1004 --ce-surface-hover: #2e2d2b;
1005 --ce-border: #3a3936;
1006 --ce-border-subtle: #2e2d2b;
1007 --ce-text: #e8e6dc;
1008 --ce-text-2: #c4c2b8;
1009 --ce-text-3: #9c9a92;
1010 --ce-text-4: #73726c;
1011 --ce-text-5: #5e5d59;
1012 --ce-sep: #4a4946;
1013 --ce-code-header: #2e2d2b;
1014 --ce-code-bg: #0d0d0c;
1015 --ce-arrow-hover: rgba(255,255,255,0.08);
1016 --ce-badge-committed: #6fa85c;
1017 --ce-badge-gitignored: #e08a60;
1018 --ce-badge-local: #9c9a92;
1019 --ce-badge-autogen: #e8a45c;
1020 --ce-when-text: #8bb4e0;
1021 }
1022 .ce-mobile-fallback { display: none; border: 1px solid rgba(0,0,0,0.1); background: rgba(0,0,0,0.03); }
1023 .dark .ce-mobile-fallback { border-color: rgba(255,255,255,0.15); background: rgba(255,255,255,0.04); }
1024 @media (max-width: 700px) {
1025 .ce-root:not(.ce-force) { display: none !important; }
1026 .ce-mobile-fallback { display: block; }
1027 }
1028 `}</style>
1029 {!forceMobile && <div className="ce-mobile-fallback" style={{
1030 padding: '14px 16px',
1031 borderRadius: '8px',
1032 fontSize: '14px'
1033 }}>
1034 The interactive explorer works best on a larger screen. See the <a href="#file-reference" style={{
1035 color: '#D97757'
1036 }}>file reference table</a> below, or <button onClick={() => setForceMobile(true)} style={{
1037 border: 'none',
1038 background: 'none',
1039 padding: 0,
1040 color: '#D97757',
1041 textDecoration: 'underline',
1042 cursor: 'pointer',
1043 font: 'inherit'
1044 }}>show the explorer anyway</button>.
1045 </div>}
1046 <div ref={rootRef} className={forceMobile ? 'ce-root ce-force' : 'ce-root'} style={{
1047 borderRadius: isFullscreen ? 0 : '12px',
1048 border: '1px solid var(--ce-border)',
1049 background: 'var(--ce-bg)',
1050 display: 'flex',
1051 alignItems: 'stretch',
1052 overflow: 'hidden',
1053 fontFamily: 'var(--font-sans, -apple-system, sans-serif)',
1054 ...isFullscreen && ({
1055 height: '100vh'
1056 })
1057 }}>
1058 {}
1059 <div style={{
1060 width: 'min(240px, 35%)',
1061 minWidth: '180px',
1062 flexShrink: 0,
1063 borderRight: '1px solid var(--ce-border-subtle)',
1064 background: 'var(--ce-surface)',
1065 display: 'flex',
1066 flexDirection: 'column'
1067 }}>
1068 <div style={{
1069 padding: '8px 8px 4px',
1070 borderBottom: '1px solid var(--ce-border-subtle)',
1071 display: 'flex',
1072 gap: '4px'
1073 }}>
1074 {['project', 'global'].map(root => <button key={root} onClick={() => switchRoot(root)} style={{
1075 flex: 1,
1076 padding: '6px 0',
1077 borderRadius: '6px',
1078 border: 'none',
1079 cursor: 'pointer',
1080 fontFamily: 'var(--ce-mono)',
1081 fontSize: '11.5px',
1082 background: activeRoot === root ? 'var(--ce-accent-bg)' : 'transparent',
1083 color: activeRoot === root ? 'var(--ce-accent)' : 'var(--ce-text-4)',
1084 fontWeight: activeRoot === root ? 600 : 430
1085 }}>
1086 {root === 'project' ? 'Project' : 'Global (~/)'}
1087 </button>)}
1088 <button onClick={toggleAllFolders} title={allExpanded ? 'Collapse all' : 'Expand all'} style={{
1089 ...iconBtn,
1090 fontSize: 11
1091 }}>
1092 {allExpanded ? '⊟' : '⊞'}
1093 </button>
1094 <button onClick={toggleFullscreen} title={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} style={{
1095 ...iconBtn,
1096 fontSize: 13
1097 }}>
1098 {isFullscreen ? '⤡' : '⛶'}
1099 </button>
1100 </div>
1101 <div role="tree" aria-label="Configuration files" tabIndex={0} onKeyDown={onTreeKeyDown} style={{
1102 padding: '6px 0',
1103 overflowY: 'auto',
1104 flex: 1,
1105 outline: 'none'
1106 }}>
1107 {tree.children.map(node => renderNode(node, 0))}
1108 </div>
1109 </div>
1110
1111 {}
1112 <div style={{
1113 flex: 1,
1114 minWidth: 0,
1115 padding: '20px 24px',
1116 minHeight: '400px',
1117 overflowY: 'auto'
1118 }}>
1119 <span aria-live="polite" style={{
1120 position: 'absolute',
1121 width: 1,
1122 height: 1,
1123 overflow: 'hidden',
1124 clip: 'rect(0 0 0 0)'
1125 }}>{selected.label} selected</span>
1126 {}
1127 <div style={{
1128 fontFamily: 'var(--ce-mono)',
1129 fontSize: '11px',
1130 color: 'var(--ce-text-4)',
1131 marginBottom: '10px',
1132 cursor: 'default'
1133 }}>
1134 {selected.path.map((seg, i) => <span key={i}>
1135 <span style={{
1136 color: i === selected.path.length - 1 ? 'var(--ce-accent)' : 'var(--ce-text-4)'
1137 }}>{seg.replace(/\/$/, '')}</span>
1138 {i < selected.path.length - 1 && <span style={{
1139 color: 'var(--ce-sep)'
1140 }}> / </span>}
1141 </span>)}
1142 </div>
1143
1144 {}
1145 <div style={{
1146 display: 'flex',
1147 alignItems: 'flex-start',
1148 gap: '10px',
1149 marginBottom: '10px'
1150 }}>
1151 <span style={{
1152 flexShrink: 0,
1153 display: 'flex'
1154 }}>{renderIcon(selected.icon, selected.color, 24)}</span>
1155 <div style={{
1156 flex: 1,
1157 minWidth: 0
1158 }}>
1159 <div style={{
1160 fontSize: '22px',
1161 fontWeight: 600,
1162 color: 'var(--ce-text)',
1163 letterSpacing: '-0.3px',
1164 lineHeight: '26px'
1165 }}>{selected.label}</div>
1166 {selected.oneLiner && <div style={{
1167 fontSize: '15px',
1168 color: 'var(--ce-text-3)',
1169 marginTop: '3px'
1170 }}>{selected.oneLiner}</div>}
1171 </div>
1172 <div style={{
1173 display: 'flex',
1174 gap: '4px',
1175 flexShrink: 0
1176 }}>
1177 {[selected.autogen && 'autogen', selected.badge].filter(Boolean).map(k => {
1178 const s = BADGE_STYLES[k];
1179 if (!s) return null;
1180 return <span key={k} style={{
1181 fontFamily: 'var(--ce-mono)',
1182 fontSize: '10px',
1183 fontWeight: 600,
1184 textTransform: 'uppercase',
1185 letterSpacing: '0.3px',
1186 padding: '2px 6px',
1187 borderRadius: '4px',
1188 background: s.bg,
1189 color: s.color,
1190 border: `0.5px solid ${s.border}`
1191 }}>{s.label}</span>;
1192 })}
1193 </div>
1194 </div>
1195
1196 {}
1197 {selected.note && <div style={{
1198 padding: '10px 12px',
1199 borderRadius: '8px',
1200 marginBottom: '14px',
1201 background: 'rgba(217,119,87,0.06)',
1202 border: '1px solid rgba(217,119,87,0.2)',
1203 borderLeft: '3px solid var(--ce-accent)',
1204 fontSize: '15px',
1205 color: 'var(--ce-text-2)',
1206 lineHeight: 1.6
1207 }}>
1208 {selected.note}
1209 </div>}
1210
1211 {}
1212 {selected.when && <div style={{
1213 padding: '8px 12px',
1214 borderRadius: '6px',
1215 background: 'rgba(106,155,204,0.06)',
1216 border: '0.5px solid rgba(106,155,204,0.12)',
1217 fontSize: '15px',
1218 color: 'var(--ce-when-text)',
1219 marginBottom: '16px'
1220 }}>
1221 <div style={{
1222 fontSize: '10px',
1223 fontWeight: 700,
1224 textTransform: 'uppercase',
1225 letterSpacing: '0.4px',
1226 opacity: 0.65,
1227 marginBottom: '3px'
1228 }}>When it loads</div>
1229 <div style={{
1230 fontWeight: 500
1231 }}>{selected.when}</div>
1232 </div>}
1233
1234 {}
1235 {selected.description && <div style={{
1236 fontSize: '16px',
1237 color: 'var(--ce-text-2)',
1238 lineHeight: 1.65,
1239 marginBottom: '16px'
1240 }}>
1241 {Array.isArray(selected.description) ? selected.description.map((para, i) => <div key={i} style={{
1242 marginBottom: i < selected.description.length - 1 ? '12px' : 0
1243 }}>{para}</div>) : selected.description}
1244 </div>}
1245
1246 {}
1247 {selected.contains && selected.contains.length > 0 && <div style={{
1248 marginBottom: '16px'
1249 }}>
1250 <div style={{
1251 fontSize: '11px',
1252 fontWeight: 700,
1253 color: 'var(--ce-text-4)',
1254 textTransform: 'uppercase',
1255 letterSpacing: '0.4px',
1256 marginBottom: '8px'
1257 }}>Common keys</div>
1258 {selected.contains.map((item, i) => <div key={i} style={{
1259 display: 'flex',
1260 gap: '7px',
1261 fontSize: '15px',
1262 color: 'var(--ce-text-2)',
1263 lineHeight: 1.5,
1264 marginBottom: '5px'
1265 }}>
1266 <span style={{
1267 fontSize: '7px',
1268 color: 'var(--ce-text-4)',
1269 marginTop: '6px'
1270 }}>●</span>
1271 <span>{item}</span>
1272 </div>)}
1273 </div>}
1274
1275 {}
1276 {selected.tips && selected.tips.length > 0 && <div style={{
1277 padding: '12px 14px',
1278 borderRadius: '8px',
1279 background: 'var(--ce-surface)',
1280 border: '1px solid var(--ce-border-subtle)',
1281 marginBottom: '16px'
1282 }}>
1283 <div style={{
1284 fontSize: '11px',
1285 fontWeight: 700,
1286 color: 'var(--ce-accent)',
1287 textTransform: 'uppercase',
1288 letterSpacing: '0.4px',
1289 marginBottom: '6px'
1290 }}>Tips</div>
1291 {selected.tips.map((tip, i) => <div key={i} style={{
1292 display: 'flex',
1293 gap: '7px',
1294 fontSize: '14.5px',
1295 color: 'var(--ce-text-2)',
1296 marginBottom: i < selected.tips.length - 1 ? '5px' : 0
1297 }}>
1298 <span style={{
1299 fontSize: '7px',
1300 color: 'var(--ce-accent)',
1301 marginTop: '6px'
1302 }}>●</span>
1303 <span>{tip}</span>
1304 </div>)}
1305 </div>}
1306
1307 {}
1308 {selected.example && <div style={{
1309 marginBottom: '16px'
1310 }}>
1311 {selected.exampleIntro && <div style={{
1312 fontSize: '15px',
1313 color: 'var(--ce-text-2)',
1314 lineHeight: 1.6,
1315 marginBottom: '10px'
1316 }}>
1317 {selected.exampleIntro}
1318 </div>}
1319 <div style={{
1320 display: 'flex',
1321 justifyContent: 'space-between',
1322 alignItems: 'center',
1323 padding: '6px 10px',
1324 background: 'var(--ce-code-header)',
1325 border: '1px solid var(--ce-border)',
1326 borderRadius: '8px 8px 0 0'
1327 }}>
1328 <span style={{
1329 fontFamily: 'var(--ce-mono)',
1330 fontSize: '11px',
1331 fontWeight: 600,
1332 color: 'var(--ce-text-3)'
1333 }}>{selected.label}</span>
1334 <button onClick={() => copyExample(selected.id, selected.example)} style={{
1335 padding: '3px 8px',
1336 borderRadius: '4px',
1337 fontSize: '11px',
1338 fontWeight: 600,
1339 cursor: 'pointer',
1340 transition: 'all 0.15s',
1341 background: isCopied ? 'rgba(85,138,66,0.08)' : 'var(--ce-code-header)',
1342 border: isCopied ? '0.5px solid rgba(85,138,66,0.2)' : '0.5px solid var(--ce-border)',
1343 color: isCopied ? '#558A42' : 'var(--ce-text-3)'
1344 }}>
1345 {isCopied ? '✓ Copied' : 'Copy'}
1346 </button>
1347 </div>
1348 <pre style={{
1349 margin: 0,
1350 padding: '12px 14px',
1351 background: 'var(--ce-code-bg)',
1352 color: '#E8E6DC',
1353 fontFamily: 'var(--ce-mono)',
1354 fontSize: '13px',
1355 lineHeight: 1.65,
1356 borderRadius: '0 0 8px 8px',
1357 overflowX: 'auto',
1358 whiteSpace: 'pre'
1359 }}>{selected.example}</pre>
1360 </div>}
1361
1362 {}
1363 {selected.docsLink && <a href={selected.docsLink} style={{
1364 display: 'inline-flex',
1365 padding: '5px 12px',
1366 borderRadius: '6px',
1367 background: 'var(--ce-accent-bg)',
1368 border: '1px solid var(--ce-accent-border)',
1369 color: 'var(--ce-accent)',
1370 fontSize: '12px',
1371 fontWeight: 600,
1372 textDecoration: 'none'
1373 }}>Full docs →</a>}
1374
1375 {}
1376 {selected.children && selected.children.length > 0 && <div style={{
1377 marginTop: '20px'
1378 }}>
1379 <div style={{
1380 fontSize: '11px',
1381 fontWeight: 700,
1382 color: 'var(--ce-text-4)',
1383 textTransform: 'uppercase',
1384 letterSpacing: '0.4px',
1385 marginBottom: '8px'
1386 }}>Contents</div>
1387 <div style={{
1388 display: 'flex',
1389 flexDirection: 'column',
1390 gap: '4px'
1391 }}>
1392 {selected.children.map(child => <button key={child.id} onClick={() => selectNode(child)} style={{
1393 display: 'flex',
1394 alignItems: 'center',
1395 gap: '8px',
1396 padding: '6px 8px',
1397 width: '100%',
1398 background: 'var(--ce-surface)',
1399 borderRadius: '6px',
1400 border: 'none',
1401 cursor: 'pointer',
1402 textAlign: 'left',
1403 transition: 'background 0.1s'
1404 }} onMouseEnter={e => e.currentTarget.style.background = 'var(--ce-surface-hover)'} onMouseLeave={e => e.currentTarget.style.background = 'var(--ce-surface)'}>
1405 {renderIcon(child.icon, child.color, 13)}
1406 <span style={{
1407 fontFamily: 'var(--ce-mono)',
1408 fontSize: '12px',
1409 color: 'var(--ce-text-2)'
1410 }}>{child.label}</span>
1411 {child.oneLiner && <span style={{
1412 fontSize: '11px',
1413 color: 'var(--ce-text-4)',
1414 overflow: 'hidden',
1415 textOverflow: 'ellipsis',
1416 whiteSpace: 'nowrap'
1417 }}>{child.oneLiner}</span>}
1418 </button>)}
1419 </div>
1420 </div>}
1421 </div>
1422 </div>
1423 </>;
1424};
1425
1426Claude Code reads instructions, settings, skills, subagents, and memory from your project directory and from `~/.claude` in your home directory. Commit project files to git to share them with your team; files in `~/.claude` are personal configuration that applies across all your projects.9Claude Code reads instructions, settings, skills, subagents, and memory from your project directory and from `~/.claude` in your home directory. Commit project files to git to share them with your team; files in `~/.claude` are personal configuration that applies across all your projects.
1427 10
1428On Windows, `~/.claude` resolves to `%USERPROFILE%\.claude`. If you set [`CLAUDE_CONFIG_DIR`](/en/env-vars), every `~/.claude` path on this page lives under that directory instead.11On Windows, `~/.claude` resolves to `%USERPROFILE%\.claude`. If you set [`CLAUDE_CONFIG_DIR`](/en/env-vars), every `~/.claude` path on this page lives under that directory instead.
1440 16
1441Click files in the tree to see what each one does, when it loads, and an example.17Click files in the tree to see what each one does, when it loads, and an example.
1442 18
1443<ClaudeExplorer />
1444
1445## What's not shown19## What's not shown
1446 20
1447The explorer covers files you author and edit. A few related files live elsewhere:21The explorer covers files you author and edit. A few related files live elsewhere:
1492| [`CLAUDE.md`](#ce-claude-md) | Project and global | ✓ | Instructions loaded every session | [Memory](/en/memory) |66| [`CLAUDE.md`](#ce-claude-md) | Project and global | ✓ | Instructions loaded every session | [Memory](/en/memory) |
1493| [`rules/*.md`](#ce-rules) | Project and global | ✓ | Topic-scoped instructions, optionally path-gated | [Rules](/en/memory#organize-rules-with-claude/rules/) |67| [`rules/*.md`](#ce-rules) | Project and global | ✓ | Topic-scoped instructions, optionally path-gated | [Rules](/en/memory#organize-rules-with-claude/rules/) |
1494| [`settings.json`](#ce-settings-json) | Project and global | ✓ | Permissions, hooks, env vars, model defaults | [Settings](/en/settings) |68| [`settings.json`](#ce-settings-json) | Project and global | ✓ | Permissions, hooks, env vars, model defaults | [Settings](/en/settings) |
1495| [`settings.local.json`](#ce-settings-local-json) | Project only | | Your personal overrides, auto-gitignored | [Settings scopes](/en/settings#settings-files) |69| [`settings.local.json`](#ce-settings-local-json) | Project only | | Your personal overrides, gitignored when Claude Code creates it | [Settings scopes](/en/settings#settings-files) |
1496| [`.mcp.json`](#ce-mcp-json) | Project only | ✓ | Team-shared MCP servers | [MCP scopes](/en/mcp#mcp-installation-scopes) |70| [`.mcp.json`](#ce-mcp-json) | Project only | ✓ | Team-shared MCP servers | [MCP scopes](/en/mcp#mcp-installation-scopes) |
1497| [`.worktreeinclude`](#ce-worktreeinclude) | Project only | ✓ | Gitignored files to copy into new worktrees | [Worktrees](/en/worktrees#copy-gitignored-files-into-worktrees) |71| [`.worktreeinclude`](#ce-worktreeinclude) | Project only | ✓ | Gitignored files to copy into new worktrees | [Worktrees](/en/worktrees#copy-gitignored-files-into-worktrees) |
1498| [`skills/<name>/SKILL.md`](#ce-skills) | Project and global | ✓ | Reusable prompts invoked with `/name` or auto-invoked | [Skills](/en/skills) |72| [`skills/<name>/SKILL.md`](#ce-skills) | Project and global | ✓ | Reusable prompts invoked with `/name` or auto-invoked | [Skills](/en/skills) |