claudecode-linter 2.1.143 → 2.1.148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,7 @@ rules:
24
24
 
25
25
  # ── SKILL.md ─────────────────────────────────────────────
26
26
  skill-md/valid-frontmatter: error
27
+ skill-md/schema-valid: error
27
28
  skill-md/name-required: error
28
29
  skill-md/name-kebab-case: error
29
30
  skill-md/name-max-length: error
@@ -37,10 +38,11 @@ rules:
37
38
 
38
39
  # ── Agent .md ────────────────────────────────────────────
39
40
  agent-md/valid-frontmatter: error
41
+ agent-md/schema-valid: error
40
42
  agent-md/name-required: error
41
43
  agent-md/name-format: error
42
44
  agent-md/description-required: error
43
- agent-md/description-examples: warning
45
+ agent-md/description-routing-guidance: warning
44
46
  agent-md/model-required: error
45
47
  agent-md/model-valid: warning
46
48
  agent-md/color-required: error
@@ -51,6 +53,7 @@ rules:
51
53
 
52
54
  # ── Command .md ──────────────────────────────────────────
53
55
  command-md/valid-frontmatter: error
56
+ command-md/schema-valid: error
54
57
  command-md/description-required: error
55
58
  command-md/allowed-tools-valid: warning
56
59
  command-md/body-present: warning
@@ -72,9 +75,19 @@ rules:
72
75
  settings-json/scope-field: warning
73
76
  settings-json/no-unknown-fields: warning
74
77
  settings-json/permissions-object: error
78
+ settings-json/permissions-unknown-field: warning
79
+ settings-json/permissions-default-mode: warning
80
+ settings-json/permissions-disable-bypass: warning
81
+ settings-json/permissions-field-type: warning
75
82
  settings-json/allow-array: error
76
83
  settings-json/allow-known-tools: warning
77
84
  settings-json/deny-array: error
85
+ settings-json/ask-array: error
86
+ settings-json/permission-rule-syntax: error
87
+ settings-json/permission-rule-pattern: error
88
+ settings-json/sandbox-object: error
89
+ settings-json/sandbox-unknown-field: warning
90
+ settings-json/sandbox-field-type: warning
78
91
  settings-json/env-object: error
79
92
  settings-json/env-string-values: warning
80
93
  settings-json/plugins-object: error
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  Standalone linter for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) plugins and configuration files.
9
9
 
10
- Validates `plugin.json`, `SKILL.md`, agent/command markdown, `hooks.json`, `mcp.json`, `settings.json`, `CLAUDE.md`, `.lsp.json`, and `monitors/monitors.json` files. plugin.json/lsp.json/monitors.json are checked against JSON Schemas auto-extracted from Claude Code's runtime Zod validators — failures the linter reports are the same failures Claude Code would raise at session start.
10
+ Validates `plugin.json`, `SKILL.md`, agent/command markdown, `hooks.json`, `mcp.json`, `settings.json`, `CLAUDE.md`, `.lsp.json`, and `monitors/monitors.json` files. plugin.json, settings.json, the agent/skill/command frontmatter, .lsp.json and monitors.json are checked against JSON Schemas auto-extracted from Claude Code's runtime Zod validators — failures the linter reports are the same failures Claude Code would raise at session start.
11
11
 
12
12
  ![demo](assets/demo.gif)
13
13
 
@@ -74,6 +74,24 @@ claudecode-linter --fix path/to/plugin/
74
74
  claudecode-linter --fix-dry-run path/to/plugin/
75
75
  ```
76
76
 
77
+ ### Detect
78
+
79
+ Print which Claude Code artifact types a path contains — one machine-readable
80
+ type per line — and set the exit code (`0` if any found, `1` if none). Intended
81
+ for a generic git hook that gates the linter on "is this repo a Claude Code
82
+ plugin?":
83
+
84
+ ```bash
85
+ # one artifact type per line
86
+ claudecode-linter --detect path/to/repo/
87
+
88
+ # JSON array
89
+ claudecode-linter --detect --output json path/to/repo/
90
+
91
+ # git hook: only lint repos that actually contain Claude Code artifacts
92
+ claudecode-linter --detect . >/dev/null 2>&1 && claudecode-linter .
93
+ ```
94
+
77
95
  ### Example Output
78
96
 
79
97
  ```
@@ -112,11 +130,11 @@ No issues found.
112
130
  | Type | Files | Rules |
113
131
  |------|-------|-------|
114
132
  | plugin-json | `.claude-plugin/plugin.json` | 13 |
115
- | skill-md | `skills/*/SKILL.md` | 11 |
116
- | agent-md | `agents/*.md` | 13 |
117
- | command-md | `commands/*.md` | 5 |
133
+ | skill-md | `skills/*/SKILL.md` | 12 |
134
+ | agent-md | `agents/*.md` | 17 |
135
+ | command-md | `commands/*.md` | 6 |
118
136
  | hooks-json | `hooks/hooks.json` | 9 |
119
- | settings-json | `.claude-plugin/settings.json` | 14 |
137
+ | settings-json | `.claude-plugin/settings.json` | 25 |
120
138
  | mcp-json | `.claude-plugin/mcp.json` | 16 |
121
139
  | claude-md | `CLAUDE.md` | 10 |
122
140
  | lsp-json | `.lsp.json` | 3 |
@@ -124,7 +142,7 @@ No issues found.
124
142
 
125
143
  ## Schema-derived rules
126
144
 
127
- `plugin-json/schema-valid`, `lsp-json/schema-valid`, and `monitors-json/schema-valid` validate against JSON Schemas that are *auto-extracted from Claude Code's cli.js bundle* — same Zod schemas that the runtime calls `.safeParse(content)` on. This catches:
145
+ Seven `*/schema-valid` rules — for `plugin-json`, `settings-json`, `skill-md`, `agent-md`, `command-md`, `lsp-json` and `monitors-json` validate against JSON Schemas that are *auto-extracted from Claude Code's cli.js bundle* — the same Zod schemas the runtime calls `.safeParse(content)` on. This catches:
128
146
 
129
147
  - **Missing required fields** (e.g., LSP server without `extensionToLanguage`)
130
148
  - **Wrong field types** (e.g., `name: 42` instead of a string)
@@ -0,0 +1,147 @@
1
+ {
2
+ "extractedFromClaudeCodeVersion": "2.1.146",
3
+ "extractedAt": "2026-05-21T21:04:24.810Z",
4
+ "schema": {
5
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
6
+ "title": "Claude Code agent .md frontmatter",
7
+ "type": "object",
8
+ "properties": {
9
+ "name": {
10
+ "description": "Agent identifier. Required — this is how the Agent tool and `--agent` flag address it."
11
+ },
12
+ "description": {
13
+ "description": "When to use this agent. Required — shown in the Agent tool listing."
14
+ },
15
+ "model": {
16
+ "description": "Model override for this agent. Use `inherit` to match the spawning conversation."
17
+ },
18
+ "tools": {
19
+ "anyOf": [
20
+ {
21
+ "anyOf": [
22
+ {
23
+ "type": "string"
24
+ },
25
+ {
26
+ "type": "number"
27
+ },
28
+ {
29
+ "type": "boolean"
30
+ },
31
+ {
32
+ "type": "null"
33
+ }
34
+ ]
35
+ },
36
+ {
37
+ "type": "array",
38
+ "items": {
39
+ "type": "string"
40
+ }
41
+ }
42
+ ],
43
+ "description": "Tools available to this agent. Replaces the default set."
44
+ },
45
+ "disallowedTools": {
46
+ "anyOf": [
47
+ {
48
+ "anyOf": [
49
+ {
50
+ "type": "string"
51
+ },
52
+ {
53
+ "type": "number"
54
+ },
55
+ {
56
+ "type": "boolean"
57
+ },
58
+ {
59
+ "type": "null"
60
+ }
61
+ ]
62
+ },
63
+ {
64
+ "type": "array",
65
+ "items": {
66
+ "type": "string"
67
+ }
68
+ }
69
+ ],
70
+ "description": "Tools removed from the default set. Ignored if `tools` is set."
71
+ },
72
+ "color": {
73
+ "description": "@internal — display color in the agents UI"
74
+ },
75
+ "effort": {
76
+ "description": "Thinking effort: `low`, `medium`, `high`, `max`, or an integer."
77
+ },
78
+ "permissionMode": {
79
+ "description": "Permission mode the agent runs in."
80
+ },
81
+ "mcpServers": {
82
+ "description": "MCP servers to connect when this agent runs."
83
+ },
84
+ "hooks": {
85
+ "description": "Hooks registered while this agent runs."
86
+ },
87
+ "maxTurns": {
88
+ "anyOf": [
89
+ {
90
+ "type": "number"
91
+ },
92
+ {
93
+ "type": "string"
94
+ },
95
+ {
96
+ "type": "null"
97
+ }
98
+ ],
99
+ "description": "Maximum conversation turns before the agent stops."
100
+ },
101
+ "skills": {
102
+ "anyOf": [
103
+ {
104
+ "anyOf": [
105
+ {
106
+ "type": "string"
107
+ },
108
+ {
109
+ "type": "number"
110
+ },
111
+ {
112
+ "type": "boolean"
113
+ },
114
+ {
115
+ "type": "null"
116
+ }
117
+ ]
118
+ },
119
+ {
120
+ "type": "array",
121
+ "items": {
122
+ "type": "string"
123
+ }
124
+ }
125
+ ],
126
+ "description": "Skills preloaded for this agent."
127
+ },
128
+ "initialPrompt": {
129
+ "description": "Auto-submitted first message when this agent runs as the main session (via `--agent` or settings). Not read when spawned as a subagent."
130
+ },
131
+ "memory": {
132
+ "description": "Memory scope: `user`, `project`, or `local`."
133
+ },
134
+ "background": {
135
+ "description": "If true, the agent runs in the background by default."
136
+ },
137
+ "isolation": {
138
+ "description": "Filesystem isolation: `worktree` runs in a temporary git worktree."
139
+ }
140
+ },
141
+ "required": [
142
+ "name",
143
+ "description"
144
+ ],
145
+ "description": "Claude Code agent .md YAML frontmatter. Validates the structure of known fields; the object is intentionally permissive — unknown frontmatter keys are not schema errors (Claude Code still loads the agent), they are reported by the advisory agent-md/no-unknown-frontmatter rule."
146
+ }
147
+ }
@@ -0,0 +1,93 @@
1
+ {
2
+ "extractedFromClaudeCodeVersion": "2.1.146",
3
+ "extractedAt": "2026-05-21T21:04:24.812Z",
4
+ "schema": {
5
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
6
+ "title": "Claude Code command .md frontmatter",
7
+ "type": "object",
8
+ "properties": {
9
+ "name": {
10
+ "description": "Display name. Defaults to the filename without extension."
11
+ },
12
+ "description": {
13
+ "description": "One-line summary shown in listings and the Skill tool."
14
+ },
15
+ "model": {
16
+ "description": "Model override (`haiku`, `sonnet`, `opus`, or a full ID). Use `inherit` to match the parent conversation."
17
+ },
18
+ "allowed-tools": {
19
+ "anyOf": [
20
+ {
21
+ "anyOf": [
22
+ {
23
+ "type": "string"
24
+ },
25
+ {
26
+ "type": "number"
27
+ },
28
+ {
29
+ "type": "boolean"
30
+ },
31
+ {
32
+ "type": "null"
33
+ }
34
+ ]
35
+ },
36
+ {
37
+ "type": "array",
38
+ "items": {
39
+ "type": "string"
40
+ }
41
+ }
42
+ ],
43
+ "description": "Tools available to the model while this file is active. Comma-separated string or YAML list."
44
+ },
45
+ "argument-hint": {
46
+ "description": "Placeholder text shown after the slash command name."
47
+ },
48
+ "arguments": {
49
+ "anyOf": [
50
+ {
51
+ "anyOf": [
52
+ {
53
+ "type": "string"
54
+ },
55
+ {
56
+ "type": "number"
57
+ },
58
+ {
59
+ "type": "boolean"
60
+ },
61
+ {
62
+ "type": "null"
63
+ }
64
+ ]
65
+ },
66
+ {
67
+ "type": "array",
68
+ "items": {
69
+ "type": "string"
70
+ }
71
+ }
72
+ ],
73
+ "description": "@internal — typed variant of argument-hint; argument-hint is the documented form"
74
+ },
75
+ "disable-model-invocation": {
76
+ "description": "If true, the model cannot invoke this via the Skill tool; only users can type the slash command."
77
+ },
78
+ "user-invocable": {
79
+ "description": "If false, hides the slash command from users; only the model can invoke it via the Skill tool."
80
+ },
81
+ "effort": {
82
+ "description": "Thinking effort for the model: `low`, `medium`, `high`, `max`, or an integer."
83
+ },
84
+ "shell": {
85
+ "description": "Shell for `!`-command blocks: `bash` or `powershell`. Defaults to bash regardless of platform."
86
+ },
87
+ "version": {
88
+ "description": "@internal — bookkeeping, not surfaced to users"
89
+ }
90
+ },
91
+ "description": "Claude Code slash-command .md YAML frontmatter. Validates the structure of known fields; the object is intentionally permissive — unknown frontmatter keys are not schema errors (Claude Code still loads the command), they are reported by the advisory command-md/no-unknown-frontmatter rule."
92
+ }
93
+ }