claudecode-linter 2.1.144 → 2.1.148-patch.2
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 +27 -1
- package/README.md +24 -6
- package/contracts/agent-frontmatter.schema.json +287 -0
- package/contracts/command-frontmatter.schema.json +219 -0
- package/contracts/hooks.schema.json +275 -0
- package/contracts/mcp.schema.json +302 -0
- package/contracts/settings.schema.json +2495 -0
- package/contracts/skill-frontmatter.schema.json +378 -0
- package/dist/contracts.js +77 -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 +71 -8
- package/dist/linters/claude-md.js +15 -3
- package/dist/linters/command-md.js +67 -5
- package/dist/linters/hooks-json.js +24 -0
- package/dist/linters/mcp-json.js +33 -2
- package/dist/linters/settings-json.js +316 -29
- package/dist/linters/skill-md.js +142 -11
- package/dist/plugin-schema.js +19 -0
- package/dist/utils/effort.js +29 -0
- package/dist/utils/frontmatter-keys.js +67 -0
- package/package.json +9 -3
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EFFORT_LEVELS } from "../contracts.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validate a frontmatter `effort` value against the Claude Code contract.
|
|
4
|
+
*
|
|
5
|
+
* Claude Code's frontmatter Zod schema types `effort` as a permissive scalar
|
|
6
|
+
* (`anyOf[string,number,boolean,null]`), but the field's own `.describe()`
|
|
7
|
+
* string in the bundle reads:
|
|
8
|
+
* "Thinking effort for the model: `low`, `medium`, `high`, `max`, or an integer."
|
|
9
|
+
*
|
|
10
|
+
* So a valid `effort` is either one of the named levels (EFFORT_LEVELS) or an
|
|
11
|
+
* integer. Anything else — a non-integer number, a boolean, an unknown string,
|
|
12
|
+
* null — is reported. Returns a human-readable reason when invalid, or null
|
|
13
|
+
* when the value is acceptable.
|
|
14
|
+
*/
|
|
15
|
+
export function invalidEffortReason(value) {
|
|
16
|
+
const valid = [...EFFORT_LEVELS].join(", ");
|
|
17
|
+
if (typeof value === "string") {
|
|
18
|
+
if (EFFORT_LEVELS.has(value))
|
|
19
|
+
return null;
|
|
20
|
+
return `"effort" string must be one of: ${valid} (got "${value}")`;
|
|
21
|
+
}
|
|
22
|
+
if (typeof value === "number") {
|
|
23
|
+
if (Number.isInteger(value))
|
|
24
|
+
return null;
|
|
25
|
+
return `"effort" number must be an integer (got ${value})`;
|
|
26
|
+
}
|
|
27
|
+
return `"effort" must be one of: ${valid}, or an integer (got ${JSON.stringify(value)})`;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=effort.js.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SKILL_FRONTMATTER, AGENT_FRONTMATTER, COMMAND_FRONTMATTER, } from "../contracts.js";
|
|
2
|
+
import { loadSkillFrontmatterSchema, loadAgentFrontmatterSchema, loadCommandFrontmatterSchema, } from "../plugin-schema.js";
|
|
3
|
+
// Census-extraction sets (scripts/extract-contracts.ts). Used only as a
|
|
4
|
+
// fallback when the auto-extracted frontmatter schema is unavailable — the
|
|
5
|
+
// census extractor lags the schema walker (e.g. it was missing `effort`).
|
|
6
|
+
const CENSUS_FALLBACK = {
|
|
7
|
+
skill: SKILL_FRONTMATTER,
|
|
8
|
+
agent: AGENT_FRONTMATTER,
|
|
9
|
+
command: COMMAND_FRONTMATTER,
|
|
10
|
+
};
|
|
11
|
+
const SCHEMA_LOADERS = {
|
|
12
|
+
skill: loadSkillFrontmatterSchema,
|
|
13
|
+
agent: loadAgentFrontmatterSchema,
|
|
14
|
+
command: loadCommandFrontmatterSchema,
|
|
15
|
+
};
|
|
16
|
+
const keyCache = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* Known frontmatter keys for an artifact — the union of the auto-extracted
|
|
19
|
+
* schema's property names (authoritative, complete, kept in sync with Claude
|
|
20
|
+
* Code's Zod) and the census-contract set. Union rather than schema-only so a
|
|
21
|
+
* key known to *either* extraction is never mis-flagged: `no-unknown-
|
|
22
|
+
* frontmatter` is advisory and a false positive is the only real harm.
|
|
23
|
+
*/
|
|
24
|
+
function knownKeys(kind) {
|
|
25
|
+
const cached = keyCache.get(kind);
|
|
26
|
+
if (cached)
|
|
27
|
+
return cached;
|
|
28
|
+
const merged = new Set(CENSUS_FALLBACK[kind]);
|
|
29
|
+
const schema = SCHEMA_LOADERS[kind]();
|
|
30
|
+
if (schema)
|
|
31
|
+
for (const k of schema.knownFields)
|
|
32
|
+
merged.add(k);
|
|
33
|
+
keyCache.set(kind, merged);
|
|
34
|
+
return merged;
|
|
35
|
+
}
|
|
36
|
+
const ARTIFACT_LABEL = {
|
|
37
|
+
skill: "skill",
|
|
38
|
+
agent: "agent",
|
|
39
|
+
command: "command",
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Classify `key` relative to `self` (the artifact being linted).
|
|
43
|
+
*
|
|
44
|
+
* `extraKnown` lets a caller treat a few extra keys as known-for-self (some
|
|
45
|
+
* linters historically accept hyphenated aliases the contract set lists in a
|
|
46
|
+
* canonicalized form, e.g. `allowed-tools` / `argument-hint`).
|
|
47
|
+
*/
|
|
48
|
+
export function classifyUnknownFrontmatterKey(key, self, extraKnown = new Set()) {
|
|
49
|
+
// Known for the current artifact — not unknown at all.
|
|
50
|
+
if (knownKeys(self).has(key) || extraKnown.has(key))
|
|
51
|
+
return null;
|
|
52
|
+
// Valid for some *other* markdown artifact → misplacement.
|
|
53
|
+
for (const kind of ["skill", "agent", "command"]) {
|
|
54
|
+
if (kind === self)
|
|
55
|
+
continue;
|
|
56
|
+
if (knownKeys(kind).has(key)) {
|
|
57
|
+
return { kind: "owned-by-other", owner: kind };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Valid nowhere → genuinely unfamiliar; callers stay silent.
|
|
61
|
+
return { kind: "unknown-everywhere" };
|
|
62
|
+
}
|
|
63
|
+
/** Human-readable label for an artifact kind ("skill", "agent", "command"). */
|
|
64
|
+
export function artifactLabel(kind) {
|
|
65
|
+
return ARTIFACT_LABEL[kind];
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=frontmatter-keys.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudecode-linter",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.148-patch.2",
|
|
4
4
|
"description": "Standalone linter for Claude Code plugins and configuration files",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -26,6 +26,12 @@
|
|
|
26
26
|
"contracts/plugin.schema.json",
|
|
27
27
|
"contracts/lsp.schema.json",
|
|
28
28
|
"contracts/monitors.schema.json",
|
|
29
|
+
"contracts/settings.schema.json",
|
|
30
|
+
"contracts/skill-frontmatter.schema.json",
|
|
31
|
+
"contracts/agent-frontmatter.schema.json",
|
|
32
|
+
"contracts/command-frontmatter.schema.json",
|
|
33
|
+
"contracts/mcp.schema.json",
|
|
34
|
+
"contracts/hooks.schema.json",
|
|
29
35
|
".claudecode-lint.defaults.yaml",
|
|
30
36
|
"README.md"
|
|
31
37
|
],
|
|
@@ -65,9 +71,9 @@
|
|
|
65
71
|
"acorn": "^8.16.0",
|
|
66
72
|
"acorn-walk": "^8.3.5",
|
|
67
73
|
"knip": "^6.0.5",
|
|
68
|
-
"npm-check-updates": "^
|
|
74
|
+
"npm-check-updates": "^22.2.0",
|
|
69
75
|
"tsx": "^4.21.0",
|
|
70
76
|
"typescript": "^6.0.2",
|
|
71
|
-
"vitest": "4.1.
|
|
77
|
+
"vitest": "4.1.7"
|
|
72
78
|
}
|
|
73
79
|
}
|