claudecode-linter 2.1.148 → 2.1.149
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 +13 -0
- package/README.md +90 -3
- package/contracts/agent-frontmatter.schema.json +141 -1
- package/contracts/command-frontmatter.schema.json +127 -1
- package/contracts/hooks.schema.json +275 -0
- package/contracts/mcp.schema.json +302 -0
- package/contracts/settings.schema.json +285 -2
- package/contracts/skill-frontmatter.schema.json +197 -1
- package/dist/config.js +13 -8
- package/dist/contracts.js +20 -1
- package/dist/formatters/human.js +3 -2
- package/dist/index.js +72 -12
- package/dist/linters/agent-md.js +29 -1
- package/dist/linters/command-md.js +37 -1
- package/dist/linters/hooks-json.js +24 -0
- package/dist/linters/mcp-json.js +24 -0
- package/dist/linters/skill-md.js +41 -0
- package/dist/plugin-schema.js +17 -8
- package/dist/utils/asset-path.js +56 -0
- package/dist/utils/effort.js +29 -0
- package/dist/utils/frontmatter-keys.js +32 -3
- package/dist/utils/frontmatter.js +1 -1
- package/dist/utils/safe-write.js +36 -0
- package/dist/utils/terminal.js +18 -0
- package/package.json +3 -1
|
@@ -32,6 +32,10 @@ rules:
|
|
|
32
32
|
skill-md/description-max-length: error
|
|
33
33
|
skill-md/description-no-angle-brackets: error
|
|
34
34
|
skill-md/description-trigger-phrases: warning
|
|
35
|
+
skill-md/model-valid: warning
|
|
36
|
+
skill-md/effort-valid: warning
|
|
37
|
+
skill-md/allowed-tools-valid: warning
|
|
38
|
+
skill-md/frontmatter-field-type: warning
|
|
35
39
|
skill-md/no-unknown-frontmatter: warning
|
|
36
40
|
skill-md/body-word-count: warning
|
|
37
41
|
skill-md/body-has-headers: info
|
|
@@ -45,6 +49,9 @@ rules:
|
|
|
45
49
|
agent-md/description-routing-guidance: warning
|
|
46
50
|
agent-md/model-required: error
|
|
47
51
|
agent-md/model-valid: warning
|
|
52
|
+
agent-md/permission-mode-valid: warning
|
|
53
|
+
agent-md/effort-valid: warning
|
|
54
|
+
agent-md/max-turns-valid: warning
|
|
48
55
|
agent-md/color-required: error
|
|
49
56
|
agent-md/color-valid: warning
|
|
50
57
|
agent-md/system-prompt-present: error
|
|
@@ -55,11 +62,16 @@ rules:
|
|
|
55
62
|
command-md/valid-frontmatter: error
|
|
56
63
|
command-md/schema-valid: error
|
|
57
64
|
command-md/description-required: error
|
|
65
|
+
command-md/name-format: warning
|
|
66
|
+
command-md/model-valid: warning
|
|
67
|
+
command-md/effort-valid: warning
|
|
68
|
+
command-md/frontmatter-field-type: warning
|
|
58
69
|
command-md/allowed-tools-valid: warning
|
|
59
70
|
command-md/body-present: warning
|
|
60
71
|
|
|
61
72
|
# ── hooks.json ───────────────────────────────────────────
|
|
62
73
|
hooks-json/valid-json: error
|
|
74
|
+
hooks-json/schema-valid: error
|
|
63
75
|
hooks-json/root-hooks-key: error
|
|
64
76
|
hooks-json/valid-event-names: error
|
|
65
77
|
hooks-json/hook-type-required: error
|
|
@@ -98,6 +110,7 @@ rules:
|
|
|
98
110
|
# ── mcp.json ─────────────────────────────────────────────
|
|
99
111
|
mcp-json/scope-file-name: warning
|
|
100
112
|
mcp-json/valid-json: error
|
|
113
|
+
mcp-json/schema-valid: error
|
|
101
114
|
mcp-json/servers-required: error
|
|
102
115
|
mcp-json/servers-object: error
|
|
103
116
|
mcp-json/server-name-kebab: info
|
package/README.md
CHANGED
|
@@ -23,6 +23,17 @@ Or run directly:
|
|
|
23
23
|
npx claudecode-linter ~/projects/my-plugin/
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
+
Or build it from a clone of this repository — there is no `dist/` until you build:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
git clone https://github.com/retif/claudecode-linter
|
|
30
|
+
cd claudecode-linter
|
|
31
|
+
npm ci && npm run build # install dependencies, compile to dist/
|
|
32
|
+
node dist/index.js path/to/plugin/
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Commands elsewhere in this README are written as `claudecode-linter …` (the global / `npx` install); from a clone, that is `node dist/index.js …`.
|
|
36
|
+
|
|
26
37
|
## Usage
|
|
27
38
|
|
|
28
39
|
### Lint
|
|
@@ -130,9 +141,9 @@ No issues found.
|
|
|
130
141
|
| Type | Files | Rules |
|
|
131
142
|
|------|-------|-------|
|
|
132
143
|
| plugin-json | `.claude-plugin/plugin.json` | 13 |
|
|
133
|
-
| skill-md | `skills/*/SKILL.md` |
|
|
134
|
-
| agent-md | `agents/*.md` |
|
|
135
|
-
| command-md | `commands/*.md` |
|
|
144
|
+
| skill-md | `skills/*/SKILL.md` | 16 |
|
|
145
|
+
| agent-md | `agents/*.md` | 20 |
|
|
146
|
+
| command-md | `commands/*.md` | 10 |
|
|
136
147
|
| hooks-json | `hooks/hooks.json` | 9 |
|
|
137
148
|
| settings-json | `.claude-plugin/settings.json` | 25 |
|
|
138
149
|
| mcp-json | `.claude-plugin/mcp.json` | 16 |
|
|
@@ -211,6 +222,82 @@ Formatting is powered by [prettier](https://prettier.io/) for consistent JSON an
|
|
|
211
222
|
| 1 | Lint errors found |
|
|
212
223
|
| 2 | Fatal error |
|
|
213
224
|
|
|
225
|
+
## Running on untrusted plugins
|
|
226
|
+
|
|
227
|
+
claudecode-linter is a **static analyzer** — it parses and validates the artifacts it inspects, it never executes them. There is no `eval`, no `child_process`, no declared hooks are run, and no MCP servers are spawned. Linting **trusted** code needs no special isolation.
|
|
228
|
+
|
|
229
|
+
For **untrusted** plugins — especially with `--fix`, which writes files back to disk — run the linter sandboxed. claudecode-linter is verified to run correctly fully confined: no network, a read-only root filesystem, all Linux capabilities dropped, `no-new-privileges`, a non-root UID, and only the target directory mounted.
|
|
230
|
+
|
|
231
|
+
### The Docker image
|
|
232
|
+
|
|
233
|
+
Two multi-arch (`linux/amd64`, `linux/arm64`) images are published to the GitHub Container Registry — two separate packages, each with its own `:latest` rolling tag and `:<version>` tag:
|
|
234
|
+
|
|
235
|
+
| Image | Built from | Notes |
|
|
236
|
+
|-------|-----------|-------|
|
|
237
|
+
| `ghcr.io/retif/node-claudecode-linter` | `Dockerfile` — `node:24-alpine` | default |
|
|
238
|
+
| `ghcr.io/retif/bun-claudecode-linter` | `Dockerfile.compile` — `bun build --compile` single executable | smaller (~44 MB compressed) |
|
|
239
|
+
|
|
240
|
+
**Pull a published image:**
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
docker pull ghcr.io/retif/node-claudecode-linter # default (node:24-alpine)
|
|
244
|
+
docker pull ghcr.io/retif/bun-claudecode-linter # smaller (bun --compile)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Or build it locally** from a checkout of this repo:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
docker build -t node-claudecode-linter . # default (Dockerfile)
|
|
251
|
+
docker build -f Dockerfile.compile -t bun-claudecode-linter . # smaller variant
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Both images behave identically. The `docker run` recipes below use `ghcr.io/retif/node-claudecode-linter`; substitute `ghcr.io/retif/bun-claudecode-linter` or a locally-built tag as you prefer.
|
|
255
|
+
|
|
256
|
+
### Sandboxed invocation
|
|
257
|
+
|
|
258
|
+
**Docker — read-only lint:**
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
docker run --rm --network none --read-only --tmpfs /tmp \
|
|
262
|
+
--user "$(id -u):$(id -g)" --cap-drop ALL --security-opt no-new-privileges \
|
|
263
|
+
-v "$PWD":/work:ro -w /work ghcr.io/retif/node-claudecode-linter /work
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Docker — `--fix`:** the mount must be read-write so fixes can be written back. Otherwise identical, plus the `--fix` flag:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
docker run --rm --network none --read-only --tmpfs /tmp \
|
|
270
|
+
--user "$(id -u):$(id -g)" --cap-drop ALL --security-opt no-new-privileges \
|
|
271
|
+
-v "$PWD":/work -w /work ghcr.io/retif/node-claudecode-linter --fix /work
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
All four recipes here are verified. On Linux without Docker, [bubblewrap](https://github.com/containers/bubblewrap) (`bwrap`) gives the equivalent boundary: `--unshare-all` cuts network (confirmed: `ECONNREFUSED` inside the sandbox), and nothing is writable except — for `--fix` — the target directory (confirmed: a write outside it is refused).
|
|
275
|
+
|
|
276
|
+
**bwrap — read-only (lint):**
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
bwrap \
|
|
280
|
+
--ro-bind / / --dev /dev --proc /proc --tmpfs /tmp \
|
|
281
|
+
--unshare-all --die-with-parent \
|
|
282
|
+
--chdir "$PWD" \
|
|
283
|
+
claudecode-linter "$PWD"
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**bwrap — read-write (`--fix`):** the later `--bind` overrides the read-only root for just the target directory:
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
bwrap \
|
|
290
|
+
--ro-bind / / --bind "$PWD" "$PWD" \
|
|
291
|
+
--dev /dev --proc /proc --tmpfs /tmp \
|
|
292
|
+
--unshare-all --die-with-parent \
|
|
293
|
+
--chdir "$PWD" \
|
|
294
|
+
claudecode-linter --fix "$PWD"
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
`--ro-bind / /` can be replaced with explicit per-path `--ro-bind` entries (e.g. just `/usr`, `/nix`, and the target) for least-read-authority.
|
|
298
|
+
|
|
299
|
+
See [`SECURITY.md`](SECURITY.md) for the full security model, the audited input-handling hardening, and how to report a vulnerability.
|
|
300
|
+
|
|
214
301
|
## Versioning
|
|
215
302
|
|
|
216
303
|
This linter's version tracks the Claude Code version it was extracted from:
|
|
@@ -1,18 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extractedFromClaudeCodeVersion": "2.1.146",
|
|
3
|
-
"extractedAt": "2026-05-
|
|
3
|
+
"extractedAt": "2026-05-22T08:49:59.765Z",
|
|
4
4
|
"schema": {
|
|
5
5
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
6
6
|
"title": "Claude Code agent .md frontmatter",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
9
|
"name": {
|
|
10
|
+
"anyOf": [
|
|
11
|
+
{
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "number"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "boolean"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "null"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
10
24
|
"description": "Agent identifier. Required — this is how the Agent tool and `--agent` flag address it."
|
|
11
25
|
},
|
|
12
26
|
"description": {
|
|
27
|
+
"anyOf": [
|
|
28
|
+
{
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "number"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "boolean"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "null"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
13
41
|
"description": "When to use this agent. Required — shown in the Agent tool listing."
|
|
14
42
|
},
|
|
15
43
|
"model": {
|
|
44
|
+
"anyOf": [
|
|
45
|
+
{
|
|
46
|
+
"type": "string"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "number"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "boolean"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"type": "null"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
16
58
|
"description": "Model override for this agent. Use `inherit` to match the spawning conversation."
|
|
17
59
|
},
|
|
18
60
|
"tools": {
|
|
@@ -70,12 +112,54 @@
|
|
|
70
112
|
"description": "Tools removed from the default set. Ignored if `tools` is set."
|
|
71
113
|
},
|
|
72
114
|
"color": {
|
|
115
|
+
"anyOf": [
|
|
116
|
+
{
|
|
117
|
+
"type": "string"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"type": "number"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"type": "boolean"
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
"type": "null"
|
|
127
|
+
}
|
|
128
|
+
],
|
|
73
129
|
"description": "@internal — display color in the agents UI"
|
|
74
130
|
},
|
|
75
131
|
"effort": {
|
|
132
|
+
"anyOf": [
|
|
133
|
+
{
|
|
134
|
+
"type": "string"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "number"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "boolean"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"type": "null"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
76
146
|
"description": "Thinking effort: `low`, `medium`, `high`, `max`, or an integer."
|
|
77
147
|
},
|
|
78
148
|
"permissionMode": {
|
|
149
|
+
"anyOf": [
|
|
150
|
+
{
|
|
151
|
+
"type": "string"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"type": "number"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"type": "boolean"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"type": "null"
|
|
161
|
+
}
|
|
162
|
+
],
|
|
79
163
|
"description": "Permission mode the agent runs in."
|
|
80
164
|
},
|
|
81
165
|
"mcpServers": {
|
|
@@ -126,15 +210,71 @@
|
|
|
126
210
|
"description": "Skills preloaded for this agent."
|
|
127
211
|
},
|
|
128
212
|
"initialPrompt": {
|
|
213
|
+
"anyOf": [
|
|
214
|
+
{
|
|
215
|
+
"type": "string"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"type": "number"
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"type": "boolean"
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"type": "null"
|
|
225
|
+
}
|
|
226
|
+
],
|
|
129
227
|
"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
228
|
},
|
|
131
229
|
"memory": {
|
|
230
|
+
"anyOf": [
|
|
231
|
+
{
|
|
232
|
+
"type": "string"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"type": "number"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"type": "boolean"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"type": "null"
|
|
242
|
+
}
|
|
243
|
+
],
|
|
132
244
|
"description": "Memory scope: `user`, `project`, or `local`."
|
|
133
245
|
},
|
|
134
246
|
"background": {
|
|
247
|
+
"anyOf": [
|
|
248
|
+
{
|
|
249
|
+
"type": "string"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"type": "number"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"type": "boolean"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"type": "null"
|
|
259
|
+
}
|
|
260
|
+
],
|
|
135
261
|
"description": "If true, the agent runs in the background by default."
|
|
136
262
|
},
|
|
137
263
|
"isolation": {
|
|
264
|
+
"anyOf": [
|
|
265
|
+
{
|
|
266
|
+
"type": "string"
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"type": "number"
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
"type": "boolean"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"type": "null"
|
|
276
|
+
}
|
|
277
|
+
],
|
|
138
278
|
"description": "Filesystem isolation: `worktree` runs in a temporary git worktree."
|
|
139
279
|
}
|
|
140
280
|
},
|
|
@@ -1,18 +1,60 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extractedFromClaudeCodeVersion": "2.1.146",
|
|
3
|
-
"extractedAt": "2026-05-
|
|
3
|
+
"extractedAt": "2026-05-22T08:49:59.767Z",
|
|
4
4
|
"schema": {
|
|
5
5
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
6
6
|
"title": "Claude Code command .md frontmatter",
|
|
7
7
|
"type": "object",
|
|
8
8
|
"properties": {
|
|
9
9
|
"name": {
|
|
10
|
+
"anyOf": [
|
|
11
|
+
{
|
|
12
|
+
"type": "string"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"type": "number"
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"type": "boolean"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"type": "null"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
10
24
|
"description": "Display name. Defaults to the filename without extension."
|
|
11
25
|
},
|
|
12
26
|
"description": {
|
|
27
|
+
"anyOf": [
|
|
28
|
+
{
|
|
29
|
+
"type": "string"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "number"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"type": "boolean"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"type": "null"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
13
41
|
"description": "One-line summary shown in listings and the Skill tool."
|
|
14
42
|
},
|
|
15
43
|
"model": {
|
|
44
|
+
"anyOf": [
|
|
45
|
+
{
|
|
46
|
+
"type": "string"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"type": "number"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"type": "boolean"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"type": "null"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
16
58
|
"description": "Model override (`haiku`, `sonnet`, `opus`, or a full ID). Use `inherit` to match the parent conversation."
|
|
17
59
|
},
|
|
18
60
|
"allowed-tools": {
|
|
@@ -43,6 +85,20 @@
|
|
|
43
85
|
"description": "Tools available to the model while this file is active. Comma-separated string or YAML list."
|
|
44
86
|
},
|
|
45
87
|
"argument-hint": {
|
|
88
|
+
"anyOf": [
|
|
89
|
+
{
|
|
90
|
+
"type": "string"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"type": "number"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"type": "boolean"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"type": "null"
|
|
100
|
+
}
|
|
101
|
+
],
|
|
46
102
|
"description": "Placeholder text shown after the slash command name."
|
|
47
103
|
},
|
|
48
104
|
"arguments": {
|
|
@@ -73,18 +129,88 @@
|
|
|
73
129
|
"description": "@internal — typed variant of argument-hint; argument-hint is the documented form"
|
|
74
130
|
},
|
|
75
131
|
"disable-model-invocation": {
|
|
132
|
+
"anyOf": [
|
|
133
|
+
{
|
|
134
|
+
"type": "string"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"type": "number"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
"type": "boolean"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"type": "null"
|
|
144
|
+
}
|
|
145
|
+
],
|
|
76
146
|
"description": "If true, the model cannot invoke this via the Skill tool; only users can type the slash command."
|
|
77
147
|
},
|
|
78
148
|
"user-invocable": {
|
|
149
|
+
"anyOf": [
|
|
150
|
+
{
|
|
151
|
+
"type": "string"
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"type": "number"
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
"type": "boolean"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"type": "null"
|
|
161
|
+
}
|
|
162
|
+
],
|
|
79
163
|
"description": "If false, hides the slash command from users; only the model can invoke it via the Skill tool."
|
|
80
164
|
},
|
|
81
165
|
"effort": {
|
|
166
|
+
"anyOf": [
|
|
167
|
+
{
|
|
168
|
+
"type": "string"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"type": "number"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"type": "boolean"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"type": "null"
|
|
178
|
+
}
|
|
179
|
+
],
|
|
82
180
|
"description": "Thinking effort for the model: `low`, `medium`, `high`, `max`, or an integer."
|
|
83
181
|
},
|
|
84
182
|
"shell": {
|
|
183
|
+
"anyOf": [
|
|
184
|
+
{
|
|
185
|
+
"type": "string"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"type": "number"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"type": "boolean"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"type": "null"
|
|
195
|
+
}
|
|
196
|
+
],
|
|
85
197
|
"description": "Shell for `!`-command blocks: `bash` or `powershell`. Defaults to bash regardless of platform."
|
|
86
198
|
},
|
|
87
199
|
"version": {
|
|
200
|
+
"anyOf": [
|
|
201
|
+
{
|
|
202
|
+
"type": "string"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"type": "number"
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
"type": "boolean"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"type": "null"
|
|
212
|
+
}
|
|
213
|
+
],
|
|
88
214
|
"description": "@internal — bookkeeping, not surfaced to users"
|
|
89
215
|
}
|
|
90
216
|
},
|