@softspark/ai-toolkit 4.25.1 → 4.26.0
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/CHANGELOG.md +51 -0
- package/README.md +15 -10
- package/app/.claude-plugin/plugin.json +1 -1
- package/benchmarks/ecosystem-doctor-snapshot.json +14 -14
- package/bin/ai-toolkit.js +60 -0
- package/kb/best-practices/README.md +1 -0
- package/kb/howto/README.md +1 -0
- package/kb/troubleshooting/README.md +1 -0
- package/llms-full.txt +3 -0
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/_common.py +27 -0
- package/scripts/check_deps.py +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,57 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v4.26.0 — Python floor is declared and enforced (2026-08-21)
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Python preflight in the CLI.** `bin/ai-toolkit.js` now verifies `python3`
|
|
15
|
+
exists and reports at least 3.11 before spawning any script, and prints a
|
|
16
|
+
platform-specific fix (`brew install python@3.13` on macOS) instead of a
|
|
17
|
+
traceback from deep inside `scripts/`. The check is lazy and memoized, so
|
|
18
|
+
`help` and `--version` still run without a Python interpreter.
|
|
19
|
+
- **Matching floor check in `scripts/_common.py`.** Every entry point imports
|
|
20
|
+
`_common` first, so `python3 scripts/install.py` run directly fails with the
|
|
21
|
+
same message rather than a `TypeError` from whichever module happens to use
|
|
22
|
+
3.11+ syntax.
|
|
23
|
+
- **CI import sweep.** The `python-syntax` job now runs on a `['3.11', '3.13']`
|
|
24
|
+
matrix and imports every module under `scripts/` on each. `py_compile` only
|
|
25
|
+
catches syntax, which is exactly why a 3.10-only construct shipped: version-
|
|
26
|
+
gated runtime features surface on import, not on compile.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
|
|
30
|
+
- **`ai-toolkit update --local` crashed on macOS system Python.** `/usr/bin/python3`
|
|
31
|
+
is 3.9 on every Mac, and `scripts/mcp_editors.py` uses
|
|
32
|
+
`@dataclass(frozen=True, slots=True)` (3.10+), so the install path died with
|
|
33
|
+
`TypeError: dataclass() got an unexpected keyword argument 'slots'` while
|
|
34
|
+
importing `install_steps/ai_tools.py`. The interpreter is now rejected up
|
|
35
|
+
front with instructions.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **`scripts/check_deps.py` declares Python >= 3.11**, up from a `min_version`
|
|
40
|
+
of `3.8` that never matched what the scripts actually needed, and its reason
|
|
41
|
+
string calls out the macOS 3.9 trap.
|
|
42
|
+
- **Requirements are documented.** README gained a Requirements note above the
|
|
43
|
+
install snippet; `CLAUDE.md` records the three places the floor is declared
|
|
44
|
+
(`bin/ai-toolkit.js`, `scripts/_common.py`, `scripts/check_deps.py`) and the
|
|
45
|
+
CI matrix that guards it.
|
|
46
|
+
|
|
47
|
+
### Ecosystem
|
|
48
|
+
|
|
49
|
+
- Snapshot refreshed: 11 tools drifted, all class A (content reworded, no
|
|
50
|
+
heading delta). Claude Code 2.1.235 → 2.1.238 and Codex CLI 0.147.0 → 0.148.0
|
|
51
|
+
are upstream patch bumps with no new surface, so no generator changed.
|
|
52
|
+
|
|
53
|
+
### Tests
|
|
54
|
+
|
|
55
|
+
- Three CLI regression tests: a stale `python3` shim exits 1 with the version
|
|
56
|
+
message, a missing `python3` exits 1 instead of crashing, and `help` still
|
|
57
|
+
works with no interpreter on PATH. Test count: 1637 → 1640.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
10
61
|
## v4.25.1 — npm advisories count again (2026-08-19)
|
|
11
62
|
|
|
12
63
|
### Fixed
|
package/README.md
CHANGED
|
@@ -6,18 +6,19 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
|
-
## What's New in v4.
|
|
11
|
+
## What's New in v4.26.0
|
|
12
12
|
|
|
13
|
-
**v4.
|
|
13
|
+
**v4.26.0** declares and enforces the Python floor the scripts already needed:
|
|
14
14
|
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
15
|
+
- `ai-toolkit` now checks `python3` before running anything and requires 3.11+.
|
|
16
|
+
- macOS `/usr/bin/python3` is 3.9, which used to crash `update --local` with a
|
|
17
|
+
raw `dataclass() got an unexpected keyword argument 'slots'` traceback. You
|
|
18
|
+
now get the version, the requirement, and `brew install python@3.13`.
|
|
19
|
+
- `python3 scripts/*.py` run directly fails the same way, via `_common.py`.
|
|
20
|
+
- CI runs the syntax check plus a full import sweep on both 3.11 and 3.13, so a
|
|
21
|
+
version-gated runtime feature cannot slip through `py_compile` again.
|
|
21
22
|
|
|
22
23
|
See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
23
24
|
|
|
@@ -40,6 +41,10 @@ See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
|
40
41
|
|
|
41
42
|
## Install
|
|
42
43
|
|
|
44
|
+
**Requirements:** Node.js >= 18 and Python >= 3.11.
|
|
45
|
+
|
|
46
|
+
> **macOS:** `/usr/bin/python3` is Python 3.9 and will not run the toolkit. Install a supported one with `brew install python@3.13` and make sure `which python3` no longer points at `/usr/bin/python3`.
|
|
47
|
+
|
|
43
48
|
```bash
|
|
44
49
|
# Option A: install globally (once per machine)
|
|
45
50
|
npm install -g @softspark/ai-toolkit
|
|
@@ -183,7 +188,7 @@ ai-toolkit/
|
|
|
183
188
|
│ └── ARCHITECTURE.md # Full system design
|
|
184
189
|
├── kb/ # Reference docs, procedures, plans
|
|
185
190
|
├── scripts/ # Validation, install, evaluation scripts
|
|
186
|
-
├── tests/ # Bats and Python test suite (
|
|
191
|
+
├── tests/ # Bats and Python test suite (1640 tests)
|
|
187
192
|
└── CHANGELOG.md
|
|
188
193
|
```
|
|
189
194
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "ai-toolkit",
|
|
4
4
|
"displayName": "AI Toolkit",
|
|
5
5
|
"description": "Professional-grade engineering skills, agents, rules, and lifecycle guardrails for Claude Code, Claude Chat, and Cowork.",
|
|
6
|
-
"version": "4.
|
|
6
|
+
"version": "4.26.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "SoftSpark",
|
|
9
9
|
"url": "https://github.com/softspark"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"last_run": "2026-08-
|
|
2
|
+
"last_run": "2026-08-21T08:34:52Z",
|
|
3
3
|
"schema_version": 1,
|
|
4
4
|
"tools": {
|
|
5
5
|
"aider": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"augment": {
|
|
27
|
-
"docs_hash": "
|
|
27
|
+
"docs_hash": "516d8db28cb3ec63",
|
|
28
28
|
"headings": [
|
|
29
29
|
"Admin",
|
|
30
30
|
"Auggie CLI",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
}
|
|
67
67
|
},
|
|
68
68
|
"claude-app": {
|
|
69
|
-
"docs_hash": "
|
|
69
|
+
"docs_hash": "7e06a1985d5bb822",
|
|
70
70
|
"headings": [
|
|
71
71
|
"Add global and folder instructions",
|
|
72
72
|
"Availability",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
"claude-code": {
|
|
110
|
-
"docs_hash": "
|
|
110
|
+
"docs_hash": "2b3d6b11c4be766f",
|
|
111
111
|
"headings": [
|
|
112
112
|
"Core concepts",
|
|
113
113
|
"Documentation Index",
|
|
@@ -173,10 +173,10 @@
|
|
|
173
173
|
"userConfig": false,
|
|
174
174
|
"workflows": true
|
|
175
175
|
},
|
|
176
|
-
"version": "2.1.
|
|
176
|
+
"version": "2.1.238 (Claude Code)"
|
|
177
177
|
},
|
|
178
178
|
"cline": {
|
|
179
|
-
"docs_hash": "
|
|
179
|
+
"docs_hash": "f93d3a8437c1165f",
|
|
180
180
|
"headings": [
|
|
181
181
|
"API Reference",
|
|
182
182
|
"Best Practices",
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
}
|
|
224
224
|
},
|
|
225
225
|
"codex-cli": {
|
|
226
|
-
"docs_hash": "
|
|
226
|
+
"docs_hash": "fc1c7e43bec9f748",
|
|
227
227
|
"headings": [
|
|
228
228
|
"API",
|
|
229
229
|
"API Reference",
|
|
@@ -362,10 +362,10 @@
|
|
|
362
362
|
"plugin marketplace": false,
|
|
363
363
|
"sandbox": true
|
|
364
364
|
},
|
|
365
|
-
"version": "codex-cli 0.
|
|
365
|
+
"version": "codex-cli 0.148.0"
|
|
366
366
|
},
|
|
367
367
|
"cursor": {
|
|
368
|
-
"docs_hash": "
|
|
368
|
+
"docs_hash": "2abfadb030c12d07",
|
|
369
369
|
"headings": [
|
|
370
370
|
"Agent",
|
|
371
371
|
"CLI",
|
|
@@ -397,7 +397,7 @@
|
|
|
397
397
|
}
|
|
398
398
|
},
|
|
399
399
|
"gemini-cli": {
|
|
400
|
-
"docs_hash": "
|
|
400
|
+
"docs_hash": "a2c9759e0296670d",
|
|
401
401
|
"headings": [
|
|
402
402
|
"Breadcrumbs",
|
|
403
403
|
"Directory actions",
|
|
@@ -438,7 +438,7 @@
|
|
|
438
438
|
"version": "0.55.1"
|
|
439
439
|
},
|
|
440
440
|
"github-copilot": {
|
|
441
|
-
"docs_hash": "
|
|
441
|
+
"docs_hash": "ab9b7f5b4b692e05",
|
|
442
442
|
"headings": [
|
|
443
443
|
"About Copilot auto model selection",
|
|
444
444
|
"About Copilot automations",
|
|
@@ -475,7 +475,7 @@
|
|
|
475
475
|
}
|
|
476
476
|
},
|
|
477
477
|
"google-antigravity": {
|
|
478
|
-
"docs_hash": "
|
|
478
|
+
"docs_hash": "9fe532d247c3e361",
|
|
479
479
|
"headings": [],
|
|
480
480
|
"markers": {
|
|
481
481
|
"AGENTS.md": false,
|
|
@@ -502,7 +502,7 @@
|
|
|
502
502
|
}
|
|
503
503
|
},
|
|
504
504
|
"opencode": {
|
|
505
|
-
"docs_hash": "
|
|
505
|
+
"docs_hash": "4287f7d767dda4a8",
|
|
506
506
|
"headings": [
|
|
507
507
|
"Add features",
|
|
508
508
|
"Ask questions",
|
|
@@ -564,7 +564,7 @@
|
|
|
564
564
|
}
|
|
565
565
|
},
|
|
566
566
|
"windsurf": {
|
|
567
|
-
"docs_hash": "
|
|
567
|
+
"docs_hash": "60e25f8cb4c381be",
|
|
568
568
|
"headings": [
|
|
569
569
|
"Accounts",
|
|
570
570
|
"Advanced",
|
package/bin/ai-toolkit.js
CHANGED
|
@@ -12,6 +12,9 @@ const fs = require('fs');
|
|
|
12
12
|
const TOOLKIT_DIR = path.dirname(__dirname);
|
|
13
13
|
const CWD = process.cwd();
|
|
14
14
|
|
|
15
|
+
/** Minimum Python the toolkit scripts require: [major, minor]. */
|
|
16
|
+
const PYTHON_MIN = [3, 11];
|
|
17
|
+
|
|
15
18
|
if (!process.env.HOME) {
|
|
16
19
|
console.error('Error: HOME environment variable is not set');
|
|
17
20
|
process.exit(1);
|
|
@@ -139,6 +142,60 @@ function scriptPath(scriptName) {
|
|
|
139
142
|
return path.join(TOOLKIT_DIR, 'scripts', scriptName);
|
|
140
143
|
}
|
|
141
144
|
|
|
145
|
+
/** Memoized result of requirePython(); null until the first check runs. */
|
|
146
|
+
let pythonOk = null;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Verify `python3` exists and is >= PYTHON_MIN before any script is spawned.
|
|
150
|
+
* Without this the caller sees a raw traceback from deep inside scripts/
|
|
151
|
+
* (e.g. `dataclass() got an unexpected keyword argument 'slots'` on Python
|
|
152
|
+
* 3.9, which is what macOS ships as /usr/bin/python3).
|
|
153
|
+
* Exits with an actionable message when the interpreter is missing or too old.
|
|
154
|
+
*/
|
|
155
|
+
function requirePython() {
|
|
156
|
+
if (pythonOk) return;
|
|
157
|
+
const probe = spawnSync('python3', ['-c', 'import sys; sys.stdout.write("%d.%d.%d" % sys.version_info[:3])'], {
|
|
158
|
+
encoding: 'utf8',
|
|
159
|
+
});
|
|
160
|
+
const want = PYTHON_MIN.join('.');
|
|
161
|
+
|
|
162
|
+
if (probe.error || probe.status !== 0) {
|
|
163
|
+
console.error(`Error: python3 not found on PATH — ai-toolkit requires Python >= ${want}`);
|
|
164
|
+
console.error(pythonHint());
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const found = probe.stdout.trim();
|
|
169
|
+
const [major, minor] = found.split('.').map(Number);
|
|
170
|
+
if (major < PYTHON_MIN[0] || (major === PYTHON_MIN[0] && minor < PYTHON_MIN[1])) {
|
|
171
|
+
console.error(`Error: ai-toolkit requires Python >= ${want}, found ${found}`);
|
|
172
|
+
console.error(pythonHint());
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
pythonOk = true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Platform-specific instructions for installing a supported Python.
|
|
180
|
+
* @returns {string} Multi-line hint text
|
|
181
|
+
*/
|
|
182
|
+
function pythonHint() {
|
|
183
|
+
const lines = [];
|
|
184
|
+
if (process.platform === 'darwin') {
|
|
185
|
+
lines.push('macOS ships Python 3.9 as /usr/bin/python3. Install a newer one:');
|
|
186
|
+
lines.push(' brew install python@3.13');
|
|
187
|
+
lines.push('Then make sure it comes first on PATH (`which python3` should not be /usr/bin/python3).');
|
|
188
|
+
} else if (process.platform === 'win32') {
|
|
189
|
+
lines.push('Install Python 3.11+ and make sure `python3` resolves to it:');
|
|
190
|
+
lines.push(' winget install Python.Python.3.13');
|
|
191
|
+
} else {
|
|
192
|
+
lines.push('Install Python 3.11+ via your package manager, e.g.:');
|
|
193
|
+
lines.push(' sudo apt install python3.13 # Debian/Ubuntu');
|
|
194
|
+
lines.push(' sudo dnf install python3.13 # Fedora/RHEL');
|
|
195
|
+
}
|
|
196
|
+
return lines.join('\n');
|
|
197
|
+
}
|
|
198
|
+
|
|
142
199
|
/**
|
|
143
200
|
* Execute a generator script synchronously via python3, returning its stdout.
|
|
144
201
|
* Exits the process on failure.
|
|
@@ -147,6 +204,7 @@ function scriptPath(scriptName) {
|
|
|
147
204
|
* @returns {Buffer} stdout output
|
|
148
205
|
*/
|
|
149
206
|
function runGenerator(scriptName, extraArgs = []) {
|
|
207
|
+
requirePython();
|
|
150
208
|
try {
|
|
151
209
|
return execFileSync('python3', [scriptPath(scriptName), ...extraArgs], { cwd: TOOLKIT_DIR });
|
|
152
210
|
} catch (err) {
|
|
@@ -162,6 +220,7 @@ function runGenerator(scriptName, extraArgs = []) {
|
|
|
162
220
|
* @param {{ cwd?: string }} [opts={}] - Options (cwd override)
|
|
163
221
|
*/
|
|
164
222
|
function run(script, args = [], opts = {}) {
|
|
223
|
+
requirePython();
|
|
165
224
|
const result = spawnSync('python3', [script, ...args], {
|
|
166
225
|
stdio: 'inherit',
|
|
167
226
|
cwd: opts.cwd || CWD,
|
|
@@ -178,6 +237,7 @@ function run(script, args = [], opts = {}) {
|
|
|
178
237
|
* @param {...string} flags - Flags to pass: --rules, --hooks, --mcp
|
|
179
238
|
*/
|
|
180
239
|
function propagateGlobal(...flags) {
|
|
240
|
+
requirePython();
|
|
181
241
|
const result = spawnSync('python3', [scriptPath('propagate_global.py'), ...flags], {
|
|
182
242
|
stdio: 'inherit',
|
|
183
243
|
cwd: CWD,
|
|
@@ -4,6 +4,7 @@ service: ai-toolkit
|
|
|
4
4
|
category: best-practices
|
|
5
5
|
tags: [best-practices, guidelines]
|
|
6
6
|
last_updated: "2026-03-25"
|
|
7
|
+
description: "Section index for ai-toolkit best-practices. No documents are filed here yet; new ones follow the best-practices template."
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
# Best Practices
|
package/kb/howto/README.md
CHANGED
|
@@ -4,6 +4,7 @@ service: ai-toolkit
|
|
|
4
4
|
category: troubleshooting
|
|
5
5
|
tags: [troubleshooting, debugging]
|
|
6
6
|
last_updated: "2026-03-25"
|
|
7
|
+
description: "Section index for ai-toolkit troubleshooting. No documents are filed here yet; new ones follow the troubleshooting template."
|
|
7
8
|
---
|
|
8
9
|
|
|
9
10
|
# Troubleshooting
|
package/llms-full.txt
CHANGED
|
@@ -243,6 +243,7 @@ service: ai-toolkit
|
|
|
243
243
|
category: best-practices
|
|
244
244
|
tags: [best-practices, guidelines]
|
|
245
245
|
last_updated: "2026-03-25"
|
|
246
|
+
description: "Section index for ai-toolkit best-practices. No documents are filed here yet; new ones follow the best-practices template."
|
|
246
247
|
---
|
|
247
248
|
|
|
248
249
|
# Best Practices
|
|
@@ -5081,6 +5082,7 @@ service: ai-toolkit
|
|
|
5081
5082
|
category: howto
|
|
5082
5083
|
tags: [howto, guides]
|
|
5083
5084
|
last_updated: "2026-03-25"
|
|
5085
|
+
description: "Section index for ai-toolkit howto. No documents are filed here yet; new ones follow the howto template."
|
|
5084
5086
|
---
|
|
5085
5087
|
|
|
5086
5088
|
# How-To Guides
|
|
@@ -16129,6 +16131,7 @@ service: ai-toolkit
|
|
|
16129
16131
|
category: troubleshooting
|
|
16130
16132
|
tags: [troubleshooting, debugging]
|
|
16131
16133
|
last_updated: "2026-03-25"
|
|
16134
|
+
description: "Section index for ai-toolkit troubleshooting. No documents are filed here yet; new ones follow the troubleshooting template."
|
|
16132
16135
|
---
|
|
16133
16136
|
|
|
16134
16137
|
# Troubleshooting
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.26.0",
|
|
4
4
|
"description": "AI coding toolkit: 109 skills, 44 agents, 12 developer-tool integrations, recoverable native tool-output filtering, Claude Chat/Cowork export, safety constitution, SARIF audit, and signed npm provenance.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
package/scripts/_common.py
CHANGED
|
@@ -20,8 +20,35 @@ from __future__ import annotations
|
|
|
20
20
|
import os
|
|
21
21
|
import platform
|
|
22
22
|
import shutil
|
|
23
|
+
import sys
|
|
23
24
|
from pathlib import Path
|
|
24
25
|
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
# Python version floor
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
# Kept in sync with PYTHON_MIN in bin/ai-toolkit.js and the python3 entry in
|
|
30
|
+
# scripts/check_deps.py. Checked here because _common is imported first by
|
|
31
|
+
# every entry point, so a stale interpreter fails with this message instead of
|
|
32
|
+
# a traceback from whichever module happens to use 3.11+ syntax.
|
|
33
|
+
PYTHON_MIN = (3, 11)
|
|
34
|
+
|
|
35
|
+
if sys.version_info < PYTHON_MIN:
|
|
36
|
+
_want = ".".join(str(n) for n in PYTHON_MIN)
|
|
37
|
+
_found = ".".join(str(n) for n in sys.version_info[:3])
|
|
38
|
+
sys.stderr.write(
|
|
39
|
+
"Error: ai-toolkit requires Python >= {}, found {} ({})\n".format(
|
|
40
|
+
_want, _found, sys.executable
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
if sys.platform == "darwin":
|
|
44
|
+
sys.stderr.write(
|
|
45
|
+
"macOS ships Python 3.9 as /usr/bin/python3. Install a newer one:\n"
|
|
46
|
+
" brew install python@3.13\n"
|
|
47
|
+
)
|
|
48
|
+
else:
|
|
49
|
+
sys.stderr.write("Install Python 3.11+ via your package manager.\n")
|
|
50
|
+
sys.exit(1)
|
|
51
|
+
|
|
25
52
|
# ---------------------------------------------------------------------------
|
|
26
53
|
# Re-exports from frontmatter module
|
|
27
54
|
# ---------------------------------------------------------------------------
|
package/scripts/check_deps.py
CHANGED
|
@@ -33,7 +33,7 @@ REQUIRED = [
|
|
|
33
33
|
{
|
|
34
34
|
"name": "python3",
|
|
35
35
|
"check": "python3",
|
|
36
|
-
"min_version": "3.
|
|
36
|
+
"min_version": "3.11",
|
|
37
37
|
"packages": {
|
|
38
38
|
"brew": "python3",
|
|
39
39
|
"apt": "python3",
|
|
@@ -45,7 +45,7 @@ REQUIRED = [
|
|
|
45
45
|
"choco": "python",
|
|
46
46
|
"scoop": "python",
|
|
47
47
|
},
|
|
48
|
-
"reason": "All toolkit scripts run on Python 3 (stdlib only, no pip needed)",
|
|
48
|
+
"reason": "All toolkit scripts run on Python 3.11+ (stdlib only, no pip needed). macOS /usr/bin/python3 is 3.9 and will not work.",
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
"name": "git",
|