@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 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: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)
7
7
  [![Skills](https://img.shields.io/badge/skills-109-brightgreen)](app/skills/)
8
8
  [![Agents](https://img.shields.io/badge/agents-44-blue)](app/agents/)
9
- [![Tests](https://img.shields.io/badge/tests-1637%20passing-success)](tests/)
9
+ [![Tests](https://img.shields.io/badge/tests-1640%20passing-success)](tests/)
10
10
 
11
- ## What's New in v4.25.1
11
+ ## What's New in v4.26.0
12
12
 
13
- **v4.25.1** fixes the CVE scanner path exercised by the published-package smoke test:
13
+ **v4.26.0** declares and enforces the Python floor the scripts already needed:
14
14
 
15
- - Legacy npm audit `advisories` are normalized alongside the modern
16
- `vulnerabilities` response.
17
- - HIGH advisories now produce findings and the documented non-zero exit code
18
- instead of a false clean result.
19
- - The post-release scanner fixture now exercises accessibility, SEO, HIPAA, and
20
- a deliberately vulnerable npm dependency with their real CLI flags.
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 (1637 tests)
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.25.1",
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-19T14:01:09Z",
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": "0f7df1fdf4962938",
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": "5bba2a625b109b69",
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": "3d4394d0bf5dd8c1",
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.235 (Claude Code)"
176
+ "version": "2.1.238 (Claude Code)"
177
177
  },
178
178
  "cline": {
179
- "docs_hash": "bf058b01d03e0455",
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": "61aea7a06c8c6355",
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.147.0"
365
+ "version": "codex-cli 0.148.0"
366
366
  },
367
367
  "cursor": {
368
- "docs_hash": "793ca4e25e676e17",
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": "f343c5f7c60fefcf",
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": "79d741f4e3273f8d",
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": "8cbf9aaffb6b57bf",
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": "b112229db465d2e4",
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": "fddce54b82ac479e",
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
@@ -4,6 +4,7 @@ service: ai-toolkit
4
4
  category: howto
5
5
  tags: [howto, guides]
6
6
  last_updated: "2026-03-25"
7
+ description: "Section index for ai-toolkit howto. No documents are filed here yet; new ones follow the howto template."
7
8
  ---
8
9
 
9
10
  # How-To Guides
@@ -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
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.25.1",
2
+ "version": "4.26.0",
3
3
  "components": {
4
4
  "agents": {
5
5
  "description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softspark/ai-toolkit",
3
- "version": "4.25.1",
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",
@@ -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
  # ---------------------------------------------------------------------------
@@ -33,7 +33,7 @@ REQUIRED = [
33
33
  {
34
34
  "name": "python3",
35
35
  "check": "python3",
36
- "min_version": "3.8",
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",