Skip to content

0.18.0

2026-08-07 · View on GitHub

skillsaw now lints two more plugin ecosystems — Agent Plugins v1 and OpenAI Codex — and the new skillsaw port command converts your existing Claude Code and Codex plugins to the vendor-neutral format in one pass. The default rule set got quieter: newer models don't trip over hedged prose the way older ones did, so the rules policing it moved to info severity or retired. And the Claude Code format rules now carry a claude- prefix to match codex-; every old name still works.

New platforms

  • Agent Plugins v1. agent-plugin-json-valid and agent-plugin-mcp-valid check portable plugin packages against the official 1.0.0 schemas: root plugin.json, optional mcp.json, path containment, MCP transport rules, and no embedded credentials — findings never echo the secret itself. Auto-enabled when a manifest declares the Agent Plugins schema. (#483)
  • OpenAI Codex plugins and marketplaces. Five codex-* rules cover .codex-plugin/plugin.json manifests, plugin structure, .agents/plugins/marketplace.json catalogs (with a suggested fix that appends missing registrations), and the optional agents/openai.yaml skill metadata. Discovery understands ownership: a Codex-only plugin is exempt from Claude format rules, dual-manifest plugins keep both sets, and a directory a marketplace registers but never gives a plugin.json is now reported instead of silently skipped. (#471)

Port your plugins to the portable format

$ skillsaw port --to agent-plugin .
✓ [plugins/release-notes] claude → plugin.json, mcp.json
✓ [plugins/issue-triage] codex → plugin.json

Summary:
  Ported:     2 plugins (2 plugin.json, 1 mcp.json)
  Catalog:    .agents/plugins/marketplace.json (2 entries)
  Validation: ✓ passed

✓ Converted 2 plugins to Agent Plugins v1

One command makes every plugin in a repository or marketplace installable by any Agent Plugins client. The port is additive — it writes a root plugin.json (and mcp.json when the plugin has a Claude MCP config, translating http to streamable-http and ${CLAUDE_PLUGIN_ROOT} to ${PLUGIN_ROOT}) and never touches the source format's files, so Claude Code and Codex keep working unchanged. Anything the portable format can't express is skipped with a note rather than mistranslated, every run ends with the Agent Plugins rules validating the output, and nothing that already exists is ever overwritten: foreign manifests are refused, existing catalogs and MCP files are left alone, and reruns are no-ops.

Because Agent Plugins defines a package rather than a marketplace, a multi-plugin port also writes Codex's .agents/plugins/marketplace.json so catalog-driven clients can discover the ported plugins (--marketplaces codex, the default; none to skip).

The opt-in agent-plugin-required rule makes the conversion a standing guarantee: a plugin missing the portable manifest is a lint finding with a SAFE autofix that runs the same conversion, and metadata drift between manifests or a missing portable MCP config is reported. Enable it in CI and no plugin merges without the vendor-neutral format.

Proven against real repositories before release: all 180 plugins in openai/plugins (existing catalog left untouched), all 40 in openshift-eng/ai-helpers (byte-identical to that repo's hand-written manifests), and all 40 in anthropics/claude-plugins-official. (#486)

New rules

  • content-description-routing (warning). A skill or agent description has one job: telling the model when to route to it. This rule flags descriptions with no when-to-use phrasing and descriptions that only restate the name. Both checks are configurable, and user-invoked skills (disable-model-invocation: true) are skipped since routing phrasing doesn't apply to them. (#479, #482)
  • coderabbit-schema-valid. Catches .coderabbit.yaml keys CodeRabbit silently ignores — review: instead of reviews: reverts the whole block to defaults with no error — and invalid reviews.profile values. (#442)

Quieter defaults

Anthropic's own official plugins break the hedging rules a hundred times over and work fine, so the defaults now reflect how current models actually behave:

  • content-weak-language, content-tautological, content-negative-only, and content-critical-position dropped from warning to info. (#484)
  • content-critical-position and content-actionability-score (attention-era heuristics) and skill-frontmatter (superseded by agentskill-valid, which inherited its autofix) are deprecated. They no longer run under enabled: auto and are gone from generated configs; enabled: true or --rule still runs them, with a warning that removal is coming. Those warnings are advisory — they never change the exit code, grade, badge, or baselines, so upgrading cannot break a strict: true CI run. The deprecated rules page explains why each rule went. (#484)

Checked against five real repositories before release: grades improve or hold on every one, and none changes exit code.

New names

The 13 Claude Code format rules are canonical under claude- prefixes: claude-plugin-json-required, claude-plugin-json-valid, claude-plugin-naming, claude-plugin-readme, claude-marketplace-json-valid, claude-marketplace-registration, claude-agent-frontmatter, claude-command-frontmatter, claude-command-naming, claude-command-name-format, claude-command-sections, claude-settings-dangerous, and claude-rules-valid. Cross-ecosystem rules (hooks-*, mcp-*, instruction-*, content and security) keep bare names.

Old names keep working everywhere a rule is named: config keys, --rule/--skip-rule, skillsaw explain, suppression comments, and existing baselines all resolve them. Plugin and custom rules can't claim a legacy name or skillsaw's reserved advisory ID — alias resolution would make them unaddressable, so they're skipped with a warning. (#484, #485)

The docs site matches: one Claude Code page for the renamed rules, Security (previously Hidden-Content Validation), a Hooks page, and stubs at every old rule and group URL.

Fixes

  • agentskill-valid's fix no longer orphans YAML anchors when filling an empty name; frontmatter fixes key off parsed fields instead of substring matches; security-hidden-instructions catches payloads hidden in [//]: # (...) link-label definitions; hooks-only plugins get lint coverage. (#478)
  • Symlink loops, embedded NULs, and overlong paths can no longer abort a lint run — all path resolution goes through safe_resolve(). (#480)
  • The APM rules match the current microsoft/apm spec: description is optional, .apm/extensions/ is a recognized primitive directory, and a consumer-only apm.yml no longer demands a phantom .apm/ directory. (#438, #440, #473)
  • mcp-valid-json warns on all five server names Claude Code reserves for built-ins, not just workspace — a user server shadowing one is silently ignored. (#439)
  • skillsaw baseline no longer buries deprecation warnings in the baseline, and skillsaw fix now shows them. (#484, #485)

Compatibility

  • Existing configs, baselines, suppression comments, and scripts need no changes. Fresh skillsaw init output uses the new names and omits deprecated rules.
  • JSON and SARIF report bodies count advisory deprecation notices as ordinary warnings even though the exit code ignores them — gate CI on the exit code, not on report warning counts.