claudecode-linter 2.1.144 → 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.
- package/.claudecode-lint.defaults.yaml +14 -1
- package/README.md +24 -6
- package/contracts/agent-frontmatter.schema.json +147 -0
- package/contracts/command-frontmatter.schema.json +93 -0
- package/contracts/settings.schema.json +2212 -0
- package/contracts/skill-frontmatter.schema.json +182 -0
- package/dist/contracts.js +64 -1
- package/dist/discovery.js +26 -2
- package/dist/fixers/settings-json.js +7 -6
- package/dist/index.js +23 -7
- package/dist/linters/agent-md.js +43 -8
- package/dist/linters/claude-md.js +15 -3
- package/dist/linters/command-md.js +31 -5
- package/dist/linters/mcp-json.js +9 -2
- package/dist/linters/settings-json.js +316 -29
- package/dist/linters/skill-md.js +101 -11
- package/dist/plugin-schema.js +12 -0
- package/dist/utils/frontmatter-keys.js +38 -0
- package/package.json +7 -3
|
@@ -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-
|
|
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
|
|
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
|

|
|
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` |
|
|
116
|
-
| agent-md | `agents/*.md` |
|
|
117
|
-
| command-md | `commands/*.md` |
|
|
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` |
|
|
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
|
|
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
|
+
}
|