Skip to content

0.15.0

2026-07-03 · View on GitHub

Our biggest release ever: 42 commits, 378 files changed, ~18.5k insertions since v0.14.1. The headline is a full plugin architecture for distributing lint rules as PyPI packages, alongside the removal of the built-in LLM fix engine, a new dead-file detection rule, and a long list of autofix, correctness, security, and performance fixes.

Highlights

Plugin architecture (#312, #311, #313, #314)

Rules can now be distributed as ordinary pip-installable packages via skillsaw.plugins entry points — reviewable, versioned, and auditable, unlike repo-local custom rule files.

  • Rule plugins: any package exposing a skillsaw.plugins entry point contributes rules, namespaced and attributed (source: plugin:<name> in JSON output).
  • Extension points: plugins can register custom repo types (SKILLSAW_REPO_TYPES) and lint-tree contributors (SKILLSAW_TREE_CONTRIBUTORS), pulling new file types into the parse tree and content linting.
  • Plugin CLIs: skillsaw <name> dispatches to a plugin's skillsaw-<name> console script — registered plugins only; arbitrary executables on PATH are never run.
  • Management: new skillsaw plugins command, --no-plugins flag, and plugins: {disable: [...]} config block. A plugin that fails to load reports a plugin-load-error violation instead of aborting the lint.
  • GitHub Action: new plugins input installs plugins in CI (#314).
  • Docs: a full authoring guide (docs/plugins.md), a scaffold example under examples/plugins/, and a skillsaw-create-plugin skill.

⚠️ Breaking: LLM fix engine removed (#310)

The built-in LLM autofix path is gone in favor of coding agents (see the skillsaw-fix skill and per-rule skillsaw explain guidance):

  • Removed flags: skillsaw fix --llm/--ai, --model, --max-iterations, --all, -y/--yes, --workers, --patch-file, --apply-patch, and the hidden skillsaw lint --fix/--llm/--dry-run.
  • Removed pip extras: skillsaw[llm], [vertexai], [bedrock] (installing them now fails).
  • Removed rule API: AutofixConfidence.LLM, llm_fix_prompt, llm_fix_frontmatter — custom rules and plugins using them must update.
  • The llm: config section is now an ignored unknown-key warning; SKILLSAW_MODEL is ignored.

⚠️ Breaking: GitHub Action defaults to --no-custom-rules (#323)

For CI safety on untrusted PRs, the Action no longer executes repo-local .skillsaw-custom.py rules by default. Nothing fails — custom rules silently stop running. Set no-custom-rules: false to opt back in, or migrate to a rule plugin. The CLI default is unchanged, and custom-rule loading now prints a clear one-line colored warning (#359).

New rule: agentskill-unreferenced-files (#347)

Detects dead files in skill directories — files never referenced from SKILL.md or anything it transitively references. Warning severity, enabled: auto on skill/plugin/marketplace repos, with an exclude config parameter. Reachability is thorough: markdown links and text mentions (case-insensitive), directory mentions (./fonts, assets/fonts, fonts/), and Python import chains — both in .py helpers and inside fenced code blocks — are all followed transitively.

Spec compliance & validation

  • metadata.pluginRoot honored when resolving marketplace plugin sources, per the Claude Code marketplace spec — bare source names now resolve, with a root-relative fallback for marketplaces that mix styles; traversing/absolute pluginRoots are rejected (#355).
  • marketplace.json source validation per the current spec: duplicate plugin names, ../absolute paths, typed-source required fields, unknown source types (#338).
  • Frontmatter hooks scanned: hooks-dangerous and hooks-prohibited now inspect hooks: declared in skill/agent frontmatter, not just hooks JSON files (#346).
  • Hooks & MCP validation synced with current Claude Code docs — exec-form args, MCP timeout, MessageDisplay event, ws transport (#336).
  • Digit-leading skill names (e.g. 1password) now valid per the agentskills.io spec (#337).

Autofix reliability

  • SAFE autofix corruption fixed: path truncation from backtrackable lookarounds, and duplicate name: keys from non-converging frontmatter fixes (#325).
  • BOM and CRLF line endings preserved byte-exactly across autofix (#332).
  • agentskill-name autofix no longer folds inline YAML comments into the rename manifest; comments are preserved on the rewritten line (#352).
  • content-broken-internal-reference resolves percent-encoded links and never emits unparseable destinations (#350).

Rule accuracy

  • content-embedded-secrets: entropy gating + placeholder allowlist kills documentation-placeholder false positives (password = "changeme", <your-api-key>, ${VAR} templates). Structured high-confidence tokens (AKIA…, ghp_…, JWTs, private keys) are always reported. Configurable via entropy-threshold and additional-placeholders (#354).
  • **-glob exclude semantics fixed: **/templates/** now matches a top-level templates/ directory, matching gitignore semantics — a strict superset of the old behavior, applied to global, per-rule, and agentskill-unreferenced-files excludes (#353).
  • agentskill-description max length is configurable via max_length (#348).
  • Four small bug fixes from the #322 sweep: custom-rule abstract-class guard, @~/ imports, stacked disable-next-line, docs crash (#351).

Security & performance

  • ReDoS protection: config-driven banned-references regexes run under a wall-clock timeout (regex-timeout, default 2s) (#330).
  • promptfoo file:// references contained to the repo root — traversal, absolute paths, and symlink escapes are rejected (#349).
  • Fixed O(n²) behavior in markdown_doc._ContentMap.locate (#328).
  • Benchmarks vs 0.14.1: synthetic suite at parity; plugin discovery adds no measurable startup cost (--version/--help never touch entry points).

Docs & DX

  • "How to fix" guidance added to every builtin rule page — also surfaced through skillsaw explain, feeding agent-driven fix loops (#309).
  • SARIF output docs, exit-code reference, configuration reference, clean skillsaw add scaffolds, stale pin cleanup (#326).
  • CLI internals: __main__.py god module split into a cli/ package (#308); block hierarchy extracted to skillsaw.blocks (#307); single-source rule registration (#311).

Upgrade notes — what may change on your repo

  • agentskill-unreferenced-files may fire new warnings (auto-enabled on skill-type repos).
  • Expanded marketplace-json-valid and frontmatter-hooks scanning may surface new violations; plugins under metadata.pluginRoot are now discovered and linted.
  • A top-level templates/ directory is now excluded by default; digit- leading skill names and placeholder-shaped "secrets" no longer flagged.
  • skillsaw plugins now lists installed plugin packages (exit 0) instead of linting the plugins/ directory — update CI that relied on the old behavior.
  • Action users: custom rules require no-custom-rules: false (see above).

Known issues

  • The secrets entropy gate trades false positives for some false negatives on generic key = "value" assignments (e.g. long digit-only values, values containing allowlisted words like token); structured token detection is unaffected.