{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "properties": {
        "default_configuration": {
            "type": "string",
            "description": "The build configuration to fall back on when neither `--configuration` nor a persisted selection names one: a tag declared on rules. When rules carry tags and this names none of them, the first declared tag is used and a warning is logged.",
            "default": ""
        },
        "project": {
            "$ref": "#/$defs/ProjectConfig",
            "description": "The [project] section: project-wide server options.",
            "default": {
                "cache_dir": "",
                "logging_dir": "",
                "enable_indexing": true,
                "readonly": "off",
                "idle_timeout_ms": 3000,
                "test_hooks": false,
                "stateful_worker_count": 2,
                "min_stateless_worker_count": 1
            }
        },
        "tracker": {
            "$ref": "#/$defs/TrackerConfig",
            "description": "The [tracker] section: background polling of files.",
            "default": {
                "workspace_poll_seconds": 30
            }
        },
        "hover": {
            "$ref": "#/$defs/HoverOptions",
            "description": "The [hover] section: hover rendering options.",
            "default": {
                "parse_comment_as_markdown": true,
                "show_aka": true
            }
        },
        "inlay_hints": {
            "$ref": "#/$defs/InlayHintsOptions",
            "description": "The [inlay_hints] section: inlay hint options.",
            "default": {
                "enabled": true,
                "parameters": true,
                "deduced_types": true,
                "designators": true,
                "block_end": false,
                "default_arguments": false,
                "type_name_limit": 32
            }
        },
        "code_completion": {
            "$ref": "#/$defs/CodeCompletionOptions",
            "description": "The [code_completion] section: code completion options.",
            "default": {
                "enable_keyword_snippet": false,
                "enable_function_arguments_snippet": false,
                "enable_template_arguments_snippet": false,
                "insert_paren_in_function_call": false,
                "bundle_overloads": true,
                "limit": 0
            }
        },
        "rules": {
            "type": "array",
            "items": {
                "$ref": "#/$defs/ConfigRule"
            },
            "description": "File-pattern rules that adjust compilation flags ([[rules]] in clice.toml).",
            "default": []
        }
    },
    "additionalProperties": false,
    "$defs": {
        "ProjectConfig": {
            "type": "object",
            "properties": {
                "cache_dir": {
                    "type": "string",
                    "description": "Directory for the unified on-disk cache (PCH, PCM and index artifacts). Empty defaults to `${workspace}/.clice`, which keeps itself out of version control and backups via generated .gitignore and CACHEDIR.TAG markers (a `.clice/config.toml` stays visible to Git; backup tools honoring CACHEDIR.TAG skip the whole directory); an explicitly configured directory is never marked. The resolved path is printed at startup.",
                    "default": ""
                },
                "logging_dir": {
                    "type": "string",
                    "description": "Directory for log files; empty derives `${cache_dir}/logs`. Each server session logs into its own timestamped subdirectory.",
                    "default": ""
                },
                "enable_indexing": {
                    "type": "boolean",
                    "description": "Build the background index that serves cross-TU features (find references, workspace symbols, ...).",
                    "default": true
                },
                "readonly": {
                    "type": "string",
                    "enum": [
                        "off",
                        "on",
                        "auto"
                    ],
                    "description": "Read-only serving for open files: \"off\" targets a full AST for every open file — builds are pulled by the first request that needs them, with the index answering in the meantime; \"on\" never builds a PCH — reads serve from the index alone (a cold file jumps the indexing queue), while completion and signature help still compile on demand without a preamble; \"auto\" starts every file as \"on\", switches it to \"off\" at the first edit intent (edit, completion, signature help, context switch), and falls back to \"off\" for a file the index cannot serve. Feature routing always answers from the best source currently available.",
                    "default": "off"
                },
                "idle_timeout_ms": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Idle delay in milliseconds before background indexing starts.",
                    "default": 3000
                },
                "test_hooks": {
                    "type": "boolean",
                    "description": "Enable the clice/internal test hooks used by the test harness.",
                    "default": false
                },
                "stateful_worker_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4294967295,
                    "description": "Number of stateful workers — they hold ASTs in memory and serve queries (hover, semantic tokens, ...); `0` is invalid and falls back to the default.",
                    "default": 2
                },
                "stateless_worker_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4294967295,
                    "description": "Number of stateless workers started — they handle ephemeral tasks (PCH/PCM builds, completion, signature help, background indexing) — and the most that background indexing keeps busy at once; defaults to half the machine's physical cores, at least 2. `0` is invalid and falls back to that default."
                },
                "min_stateless_worker_count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 4294967295,
                    "description": "Lower bound for dynamic stateless-worker scaling; `0` is invalid and falls back to the default.",
                    "default": 1
                },
                "max_stateless_worker_count": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Upper bound for dynamic stateless-worker scaling, which only interactive work that finds every worker busy reaches; `0` means the machine's physical cores, which is also the default."
                }
            },
            "additionalProperties": false
        },
        "TrackerConfig": {
            "type": "object",
            "properties": {
                "workspace_poll_seconds": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Longest interval in seconds between two background looks at a workspace file: the interval doubles at every look that finds the file unchanged, up to this. 0 disables background polling, compilation databases included.",
                    "default": 30
                }
            },
            "additionalProperties": false
        },
        "HoverOptions": {
            "type": "object",
            "properties": {
                "parse_comment_as_markdown": {
                    "type": "boolean",
                    "description": "Render the hover card as markdown; `false` produces plain text for clients that cannot display it.",
                    "default": true
                },
                "show_aka": {
                    "type": "boolean",
                    "description": "Show the desugared form of a type, e.g. `vector<int>::size_type (aka unsigned long)`.",
                    "default": true
                }
            },
            "additionalProperties": false
        },
        "InlayHintsOptions": {
            "type": "object",
            "properties": {
                "enabled": {
                    "type": "boolean",
                    "description": "Master switch: `false` disables all inlay hints.",
                    "default": true
                },
                "parameters": {
                    "type": "boolean",
                    "description": "Parameter name hints at call sites, e.g. `draw(width: 800, height: 600)`, including `&` markers for arguments passed by mutable reference.",
                    "default": true
                },
                "deduced_types": {
                    "type": "boolean",
                    "description": "Deduced type hints for `auto` variables, structured bindings and deduced return types.",
                    "default": true
                },
                "designators": {
                    "type": "boolean",
                    "description": "Field designator hints in aggregate initialization, e.g. `.x=` and `.y=` in `Point{1, 2}`.",
                    "default": true
                },
                "block_end": {
                    "type": "boolean",
                    "description": "`// name` hints after the closing brace of long blocks (functions, types, namespaces, control flow).",
                    "default": false
                },
                "default_arguments": {
                    "type": "boolean",
                    "description": "Show the default arguments a call omitted, abbreviated when long.",
                    "default": false
                },
                "type_name_limit": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Byte budget for rendered hint text: over-long deduced types fall back to a sugared spelling or are dropped, over-long default arguments are abbreviated. `0` means no limit.",
                    "default": 32
                }
            },
            "additionalProperties": false
        },
        "CodeCompletionOptions": {
            "type": "object",
            "properties": {
                "enable_keyword_snippet": {
                    "type": "boolean",
                    "description": "Complete statements such as `if` and `for` as snippets with placeholders for their parts; otherwise only the keyword is inserted. Ignored for clients without snippet support.",
                    "default": false
                },
                "enable_function_arguments_snippet": {
                    "type": "boolean",
                    "description": "Insert function arguments as a snippet when completing a call. For functions this applies to individually listed overloads, so it requires `bundle_overloads = false`; function-like macros have no overload sets and always take the snippet. Ignored for clients without snippet support.",
                    "default": false
                },
                "enable_template_arguments_snippet": {
                    "type": "boolean",
                    "description": "Insert template arguments as a snippet when completing a class, alias or variable template. Ignored for clients without snippet support.",
                    "default": false
                },
                "insert_paren_in_function_call": {
                    "type": "boolean",
                    "description": "Insert parentheses when completing a function call, unless the name is already followed by one; with snippet support the cursor lands between them.",
                    "default": false
                },
                "bundle_overloads": {
                    "type": "boolean",
                    "description": "Collapse an overload set into a single completion item.",
                    "default": true
                },
                "limit": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 4294967295,
                    "description": "Maximum number of completion items (not yet implemented).",
                    "default": 0
                }
            },
            "additionalProperties": false
        },
        "ConfigRule": {
            "type": "object",
            "properties": {
                "patterns": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Glob patterns selecting the files this rule applies to. A relative pattern is anchored at this configuration file's directory (`..` segments allowed), or at the workspace root for a rule passed through initializationOptions; an absolute pattern or one starting with `**` matches the file's absolute path. `*` matches within a path segment, `?` a single character, `**` any number of segments, `{a,b}` alternatives, `[0-9]` a character range, `[!...]` a negated range. Omitted means every file.",
                    "default": []
                },
                "configuration": {
                    "type": "string",
                    "description": "Build configuration tag. A tagged rule applies only while that configuration is active; an untagged rule always applies. The distinct tags form the configuration menu; `--configuration`, the persisted selection and `default_configuration` pick the active one, in that order.",
                    "default": ""
                },
                "compile_commands": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Compilation databases, in priority order: a compile_commands.json or a directory containing one, relative to this configuration file (to the workspace root for a rule passed through initializationOptions). All of them load, and every entry applies to its own file whatever the patterns say; the patterns and the order decide which entry a file present in several databases gets by default. A rule without patterns names the workspace's databases. When no rule declares a source, every compile_commands.json in the workspace root and its immediate subdirectories loads, and so do the ones in the directories above a file when it is opened.",
                    "default": []
                },
                "default_command": {
                    "anyOf": [
                        {
                            "type": "string"
                        },
                        {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    ],
                    "description": "The compile command for matching files without a database entry, without the source file: a string tokenized like a shell command line, or an argv array. It runs from the directory of the configuration file it was read from (the workspace root for a rule passed through initializationOptions), and the matching source files on disk join the background index (unless the rule turns `index` off) — enumerated at startup and again on every workspace poll, so a file created later compiles when opened and joins the index within a poll period. Omitted means none.",
                    "default": ""
                },
                "append": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Compilation flags appended for matching files, e.g. `[\"-std=c++20\", \"-DNDEBUG\"]`.",
                    "default": []
                },
                "remove": {
                    "type": "array",
                    "items": {
                        "type": "string"
                    },
                    "description": "Compilation flags removed for matching files, e.g. `[\"-Wall\"]`.",
                    "default": []
                },
                "index": {
                    "type": "boolean",
                    "description": "Whether matching translation units join the background index. `false` keeps them out; they still compile when opened and still host the headers they include. Any matching rule saying `false` wins.",
                    "default": true
                },
                "lint": {
                    "type": "boolean",
                    "description": "Whether `clice lint` checks matching files. `false` keeps them out: their findings are dropped and a translation unit they head is not parsed, unless `--index` needs it for the index. Files outside the workspace are never checked. Any matching rule saying `false` wins.",
                    "default": true
                },
                "format": {
                    "type": "boolean",
                    "description": "Whether `clice format` formats matching files. `false` keeps them out. Files outside the workspace are never formatted. Any matching rule saying `false` wins.",
                    "default": true
                }
            },
            "additionalProperties": false
        }
    }
}

