Skip to main content

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

OptionTypeDefaultDescription
complexityint10Maximum cyclomatic complexity before flagging a function
nestingint3Maximum nesting depth before flagging
max_argsint5Maximum function arguments before flagging
max_linesint50Maximum function length in lines

Analysis Options

OptionTypeDefaultDescription
ignorelist[]List of rule IDs to suppress (e.g., ["SKY-L002", "SKY-Q301"])
modelstring"gpt-4.1"LLM model for AI-powered features

Gate Configuration

The [tool.skylos.gate] section controls the quality gate behavior when using --gate:

OptionTypeDefaultDescription
fail_on_criticalbooltrueBlock deployment if CRITICAL security issues or secrets are found
max_securityint0Maximum allowed security findings before gate fails
max_qualityint10Maximum allowed quality findings before gate fails
strictboolfalseWhen 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 patternskylos whitelist 'handle_*' or add to names = []
Document whyskylos whitelist x --reason "why" or add to [tool.skylos.whitelist.documented]
Temporary whitelistAdd to [tool.skylos.whitelist.temporary] with expires date
Per-folder rulesAdd [tool.skylos.overrides."path/*"] section
View all whitelistsskylos 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