Configuration
Skylos uses pyproject.toml for configuration. Run skylos init to generate a configuration file with sensible defaults, or add the [tool.skylos] section to an existing file.
Configuration File
[tool.skylos]
# Quality thresholds
complexity = 10
nesting = 3
max_args = 5
max_lines = 50
# Rules to ignore (by rule ID)
ignore = []
# AI model for --fix and --audit
model = "gpt-4.1"
[tool.skylos.whitelist]
# Glob patterns to ignore as unused
names = [
"handle_*",
"visit_*",
"*Plugin",
]
[tool.skylos.whitelist.documented]
# Patterns with reasons (recommended for teams)
"dark_logic" = "Called via globals() string manipulation"
"BasePlugin" = "Discovered via __subclasses__()"
[tool.skylos.whitelist.temporary]
# Temporary whitelist - warns when expired
"legacy_handler" = { reason = "Migration - JIRA-123", expires = "2026-03-01" }
[tool.skylos.overrides."src/plugins/*"]
# Per-path whitelist rules
whitelist = ["*Plugin", "*Handler"]
[tool.skylos.languages.typescript]
# Language-specific overrides
complexity = 15
nesting = 4
[tool.skylos.gate]
# Quality gate settings
fail_on_critical = true
max_security = 0
max_quality = 10
strict = false
Configuration Options
Quality Thresholds
| Option | Type | Default | Description |
|---|---|---|---|
complexity | int | 10 | Maximum cyclomatic complexity before flagging a function |
nesting | int | 3 | Maximum nesting depth before flagging |
max_args | int | 5 | Maximum function arguments before flagging |
max_lines | int | 50 | Maximum function length in lines |
Analysis Options
| Option | Type | Default | Description |
|---|---|---|---|
ignore | list | [] | List of rule IDs to suppress (e.g., ["SKY-L002", "SKY-Q301"]) |
model | string | "gpt-4.1" | LLM model for AI-powered features |
Gate Configuration
The [tool.skylos.gate] section controls the quality gate behavior when using --gate:
| Option | Type | Default | Description |
|---|---|---|---|
fail_on_critical | bool | true | Block deployment if CRITICAL security issues or secrets are found |
max_security | int | 0 | Maximum allowed security findings before gate fails |
max_quality | int | 10 | Maximum allowed quality findings before gate fails |
strict | bool | false | When true, prevents bypassing a failed gate interactively |
Whitelist Configuration
Suppress false positives permanently without cluttering your code with inline comments.
CLI Commands
# Add a glob pattern
skylos whitelist 'handle_*'
# Add with reason (recommended for teams)
skylos whitelist dark_logic --reason "Called via globals() in dispatcher"
# View current whitelist
skylos whitelist --show
Whitelist Sections
[tool.skylos.whitelist]
Simple glob patterns for names to ignore:
[tool.skylos.whitelist]
names = [
"handle_*", # Event handlers called via getattr
"visit_*", # AST visitor methods
"*Plugin", # Plugin classes discovered via __subclasses__
"*_callback", # Callback functions
]
[tool.skylos.whitelist.documented]
Patterns with reasons - shows up in skylos whitelist --show and helps teams understand why something is whitelisted:
[tool.skylos.whitelist.documented]
"dark_logic" = "Called via globals() string manipulation in trigger_blindspots()"
"BasePlugin" = "Discovered via __subclasses__() at runtime"
"legacy_api" = "Called by external service - do not remove"
[tool.skylos.whitelist.temporary]
Patterns with expiration dates - Skylos warns when these expire to prevent whitelist rot:
[tool.skylos.whitelist.temporary]
"legacy_handler" = { reason = "Migration in progress - JIRA-123", expires = "2026-03-01" }
"old_api_v1" = { reason = "Deprecated, removing in Q2", expires = "2026-06-30" }
[tool.skylos.overrides."path/*"]
Per-file or per-folder whitelist rules:
[tool.skylos.overrides."src/plugins/*"]
whitelist = ["*Plugin", "*Handler"]
[tool.skylos.overrides."src/events/*"]
whitelist = ["on_*", "*_listener"]
Inline Ignores
For one-off exceptions, use inline comments instead of config:
# Single line ignore
def dynamic_handler(): # skylos: ignore
pass
# Alternative syntaxes (all equivalent)
def another(): # noqa: skylos
pass
def yet_another(): # pragma: no skylos
pass
# Block ignore (multiple functions)
# skylos: ignore-start
def block_one():
pass
def block_two():
pass
# skylos: ignore-end
Whitelist Summary
| Want to... | Do this |
|---|---|
| Whitelist a pattern | skylos whitelist 'handle_*' or add to names = [] |
| Document why | skylos whitelist x --reason "why" or add to [tool.skylos.whitelist.documented] |
| Temporary whitelist | Add to [tool.skylos.whitelist.temporary] with expires date |
| Per-folder rules | Add [tool.skylos.overrides."path/*"] section |
| View all whitelists | skylos whitelist --show |
| Inline ignore | # skylos: ignore comment |
| Block ignore | # skylos: ignore-start ... # skylos: ignore-end |
Language-Specific Overrides
You can override global settings for specific languages under [tool.skylos.languages.<lang>]:
[tool.skylos.languages.typescript]
complexity = 15
nesting = 4
Currently supported languages for overrides: typescript.
Configuration Resolution
Skylos searches for pyproject.toml by walking up from the target path to the filesystem root. The first file containing [tool.skylos] is used. If no configuration is found, Skylos applies the built-in defaults.
This approach was chosen over per-directory configuration to keep analysis consistent across monorepos while still allowing project-level customization.
Default Excluded Folders
Skylos automatically excludes common non-source directories:
__pycache__
.git
.pytest_cache
.mypy_cache
.tox
htmlcov
.coverage
build
dist
*.egg-info
venv
.venv
To see the current exclusion list:
skylos . --list-default-excludes
To disable default exclusions:
skylos . --no-default-excludes
To force-include a normally excluded folder:
skylos . --include-folder venv