rules

package
v0.2.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 27, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package rules implements the Go-coded validation rules that layer on top of the embedded JSON schemas. These catch the cases that do not round-trip cleanly through pure JSON Schema: reserved marketplace names, duplicate-hooks declarations, agents-as-bare-directory, and missing-recommended-fields warnings.

Every rule has a stable identifier (HANKO001, HANKO002, ...) so CI users can pin or ignore specific rules without relying on wording. The identifiers are documented in docs/rules.md.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AgentsAsBareDirectory

func AgentsAsBareDirectory(manifest any) []report.Finding

AgentsAsBareDirectory flags `"agents": "./agents"` or similar patterns where the value is a string pointing at a directory rather than explicit `.md` file paths. The docs example shows a directory string works, but the official validator rejects it (issue #44777). Rule ID: HANKO002.

func Apply

func Apply(rs []Rule, manifest any) []report.Finding

Apply runs every rule in the list against the manifest and flattens the findings in rule order. A convenience so callers do not have to loop.

func AuthorMissing

func AuthorMissing(manifest any) []report.Finding

AuthorMissing is a warning for plugins with no `author` field. Claude Desktop's `listAvailablePlugins` validator refuses to load a catalog if any plugin is missing its author (issue #33068), which affects every user of that marketplace. Rule ID: HANKO003.

func DuplicateHooksDeclaration

func DuplicateHooksDeclaration(manifest any) []report.Finding

DuplicateHooksDeclaration flags the common v2.1+ footgun where a plugin declares `"hooks": "./hooks/hooks.json"` in plugin.json. Claude Code auto-loads that path by convention, so the explicit declaration causes a double-load error. Rule ID: HANKO001.

func DuplicatePluginNames

func DuplicatePluginNames(manifest any) []report.Finding

DuplicatePluginNames flags marketplace catalogs where the plugins array contains two or more entries with the same name. Rule ID: HANKO103.

func ImpersonationPattern

func ImpersonationPattern(manifest any) []report.Finding

ImpersonationPattern flags marketplace names that look like official Anthropic listings. Warning by default, promoted to error by the strict-anthropic overlay in rules.ForMarketplace("anthropic"). Rule ID: HANKO102.

func MarketplaceNames

func MarketplaceNames() []string

MarketplaceNames returns the list of names recognized by ForMarketplace. Used by the CLI help text so docs and code cannot drift.

func ReservedMarketplaceName

func ReservedMarketplaceName(manifest any) []report.Finding

ReservedMarketplaceName flags marketplace.json files whose top-level name is on the reserved list. Rule ID: HANKO101.

func VersionMissing

func VersionMissing(manifest any) []report.Finding

VersionMissing is a warning for plugins that omit `version`. The field is optional per docs but Claude Code's install cache keys on it, so users of a version-less plugin silently miss updates. Rule ID: HANKO004.

Types

type Kind

type Kind int

Kind distinguishes plugin-manifest rules from marketplace-manifest rules when dispatching the right rule set.

const (
	// KindPlugin applies rules relevant to plugin.json files.
	KindPlugin Kind = iota
	// KindMarketplace applies rules relevant to marketplace.json files.
	KindMarketplace
)

type Rule

type Rule func(manifest any) []report.Finding

Rule is the function shape every check implements. It receives the decoded manifest (typically a map[string]any) and returns any findings. Rules must not mutate the input.

type Set

type Set struct {
	Plugin      []Rule
	Marketplace []Rule
}

Set collects rules by kind so the validator can ask for the right set by manifest type.

func Base

func Base() Set

Base returns the default rule set applied to every manifest. Marketplace overlays (anthropic strict, buildwithclaude, cc-marketplace) add on top.

func BuildWithClaude

func BuildWithClaude() Set

BuildWithClaude is reserved for future rules once their CONTRIBUTING conventions stabilise. Currently a pass-through to Base.

func CCMarketplace

func CCMarketplace() Set

CCMarketplace layers the cc-marketplace rules: version and description are required (not optional). Same replace-not-append discipline as StrictAnthropic: VersionMissing is swapped for its strict variant so HANKO004 and HANKO004-strict cannot both fire.

func ClaudeMarketplaces

func ClaudeMarketplaces() Set

ClaudeMarketplaces is auto-discovery only and imposes no rules beyond the base schema. Declared explicitly so the ForMarketplace switch does not rely on fallthrough, and so future rules can land here without touching the CLI help strings.

func ForMarketplace

func ForMarketplace(name string) Set

ForMarketplace returns the rule set for a given marketplace name. Unknown names fall back to Base so `--marketplace anything` is a no-op rather than a hard error.

func StrictAnthropic

func StrictAnthropic() Set

StrictAnthropic layers the strict Anthropic submission rules: `author` is an error (not warning) because Claude Desktop's listAvailablePlugins validator refuses to load catalogs with missing authors (issue #33068). The overlay REPLACES the softer AuthorMissing rule rather than appending beside it, so a single missing-author manifest produces HANKO003-strict only, not both HANKO003 and HANKO003-strict.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL