@softspark/ai-toolkit 3.1.0 → 3.1.1
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 +12 -0
- package/README.md +6 -27
- package/app/.claude-plugin/plugin.json +1 -1
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/install_steps/project_registry.py +38 -5
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v3.1.1 — Windows install fix (2026-04-29)
|
|
11
|
+
|
|
12
|
+
Patch release. `ai-toolkit install --local` crashed on Windows before doing any work because `scripts/install_steps/project_registry.py` imported `fcntl` (POSIX-only) at module load, raising `ModuleNotFoundError: No module named 'fcntl'`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Windows install crash** — `project_registry` now imports `fcntl` and `msvcrt` defensively (try/except → `None`) and `_registry_lock()` selects between `fcntl.flock` (POSIX) and `msvcrt.locking` (Windows) at runtime. POSIX semantics unchanged; Windows acquires the lock with `LK_NBLCK` + 30 s deadline + 10 ms retry backoff.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **Windows compat regression test** — `tests/test_windows_support.bats` now blocks `import fcntl` via a custom `meta_path` finder, stubs `msvcrt`, and forces the Windows branch of `_registry_lock` so future regressions are caught on the POSIX CI runners without needing a Windows machine.
|
|
21
|
+
|
|
10
22
|
## v3.1.0 — Global Editor Install Alignment (2026-04-28)
|
|
11
23
|
|
|
12
24
|
Minor release aligning global and project-local editor configuration with the current documented surfaces for all supported editors.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<img src="assets/ai-toolkit-readme-hero.png" alt="ai-toolkit 3 README hero showing one toolkit for 12 AI editors" width="900">
|
|
@@ -14,33 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
|
-
## What's New in v3.1.
|
|
17
|
+
## What's New in v3.1.1
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Patch release fixing the Windows install crash introduced when project registration started using a POSIX-only file lock.
|
|
20
20
|
|
|
21
|
-
- `ai-toolkit install --
|
|
22
|
-
- `
|
|
23
|
-
- `ai-toolkit install --editors aider` safely creates `~/.aider.conf.yml` only when absent and refreshes `~/.aider-ai-toolkit-CONVENTIONS.md`.
|
|
24
|
-
- Roo Code now has project MCP sync via `.roo/mcp.json` from the canonical `.mcp.json`.
|
|
25
|
-
- Cursor rules are explicitly project-local; Cursor MCP remains supported at project/global scope through `.cursor/mcp.json`.
|
|
26
|
-
|
|
27
|
-
### Carried from v3.0.0 (feature release)
|
|
28
|
-
|
|
29
|
-
- **Deep coverage: every editor at 100% of its native surface.** New generators emit hooks, sub-agents, custom commands, and skill pointers per editor: `generate_cursor_agents.py`, `generate_cursor_hooks.py`, `generate_windsurf_hooks.py`, `generate_gemini_commands.py`, `generate_gemini_hooks.py`, `generate_gemini_skills.py`, `generate_augment_agents.py`, `generate_augment_commands.py`, `generate_augment_hooks.py`, `generate_augment_skills.py`, `generate_codex_skills.py`.
|
|
30
|
-
- **`--profile full`** turns on every native surface across all supported editors in one flag. `minimal` / `standard` / `strict` retain prior semantics but `standard` now also wires Gemini hooks and the Copilot directory layout (see Breaking Changes).
|
|
31
|
-
- **Codex skill mirroring** uses Codex's native `.agents/skills/` discovery path. `--editors codex` installs translated skills there; `--codex-skills` explicitly refreshes the same catalog.
|
|
32
|
-
- **58 new bats tests** covering native surface generators plus per-editor suites for aider, antigravity, augment, claude-code, cline, codex, copilot, cursor, gemini, opencode, roo, windsurf.
|
|
33
|
-
- **Skill quality pass** (folded in from the 2.12 work that is now skipped): 62 skills upgraded to 4-5 / 5 on the meta-architect audit; `add_gotcha` added as a fifth mutation strategy.
|
|
34
|
-
|
|
35
|
-
### Breaking changes (from 3.0.0)
|
|
36
|
-
|
|
37
|
-
- `--profile standard` now installs **Gemini hooks** automatically. To opt out, use `--profile minimal` or pass `--skip gemini-hooks`.
|
|
38
|
-
- Copilot now uses the **directory layout** (`.github/copilot/`) instead of a single monolithic file. Existing single-file installs are preserved but new installs emit the directory form.
|
|
39
|
-
- `2.13.0` is skipped. Upgrade path is `2.12.x` → `3.0.0`.
|
|
40
|
-
|
|
41
|
-
### Non-breaking additions (opt-in)
|
|
42
|
-
|
|
43
|
-
- `.windsurf/hooks.json`, `.cursor/hooks.json`, `.cursor/agents/`, `.augment/agents/`, `.augment/commands/`, and `.gemini/commands/` are **only emitted when you opt in** via `--profile full`. Codex skills are emitted under `.agents/skills/` whenever the Codex editor target is selected, matching Codex's native discovery path.
|
|
21
|
+
- **Windows install no longer crashes** — `ai-toolkit install --local` on Windows hit `ModuleNotFoundError: No module named 'fcntl'` before doing any work. The project registry now selects `fcntl` (POSIX) or `msvcrt.locking` (Windows) at runtime; POSIX semantics are unchanged.
|
|
22
|
+
- **Regression test on POSIX CI** — `tests/test_windows_support.bats` simulates the missing-`fcntl` scenario and exercises the Windows lock branch via a stubbed `msvcrt`, so this regression is caught without a Windows runner.
|
|
44
23
|
|
|
45
24
|
See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
46
25
|
|
|
@@ -173,7 +152,7 @@ ai-toolkit/
|
|
|
173
152
|
│ └── ARCHITECTURE.md # Full system design
|
|
174
153
|
├── kb/ # Reference docs, procedures, plans
|
|
175
154
|
├── scripts/ # Validation, install, evaluation scripts
|
|
176
|
-
├── tests/ # Bats test suite (
|
|
155
|
+
├── tests/ # Bats test suite (974 tests)
|
|
177
156
|
└── CHANGELOG.md
|
|
178
157
|
```
|
|
179
158
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-toolkit",
|
|
3
3
|
"description": "Professional-grade Claude Code toolkit with persona presets, skill security auditor, expanded lifecycle hooks, experimental opt-in plugin packs, benchmark harvesting, and multi-tool support.",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.1",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SoftSpark",
|
|
7
7
|
"url": "https://github.com/softspark"
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.1",
|
|
4
4
|
"description": "AI coding toolkit: 112 skills, 44 agents, 12-editor write-through (Claude, Cursor, Windsurf, Copilot, Gemini, Cline, Roo, Aider, Augment, Antigravity, Codex, opencode), machine-enforced safety constitution, SARIF audit, signed npm provenance.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -9,7 +9,6 @@ Stdlib-only — no external dependencies.
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
11
|
import contextlib
|
|
12
|
-
import fcntl
|
|
13
12
|
import json
|
|
14
13
|
import os
|
|
15
14
|
import sys
|
|
@@ -19,6 +18,16 @@ from datetime import datetime, timezone
|
|
|
19
18
|
from pathlib import Path
|
|
20
19
|
from typing import Any, Generator
|
|
21
20
|
|
|
21
|
+
try:
|
|
22
|
+
import fcntl # POSIX-only
|
|
23
|
+
except ImportError:
|
|
24
|
+
fcntl = None # type: ignore[assignment]
|
|
25
|
+
|
|
26
|
+
try:
|
|
27
|
+
import msvcrt # Windows-only
|
|
28
|
+
except ImportError:
|
|
29
|
+
msvcrt = None # type: ignore[assignment]
|
|
30
|
+
|
|
22
31
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
23
32
|
from paths import PROJECTS_FILE
|
|
24
33
|
|
|
@@ -26,24 +35,48 @@ from paths import PROJECTS_FILE
|
|
|
26
35
|
_LOAD_RETRIES = 3
|
|
27
36
|
_LOAD_RETRY_DELAY = 0.05 # 50ms
|
|
28
37
|
|
|
38
|
+
# Registry lock acquisition timeout (seconds)
|
|
39
|
+
_LOCK_TIMEOUT = 30.0
|
|
40
|
+
_LOCK_RETRY_DELAY = 0.01
|
|
41
|
+
|
|
29
42
|
|
|
30
43
|
@contextlib.contextmanager
|
|
31
44
|
def _registry_lock() -> Generator[None, None, None]:
|
|
32
45
|
"""Exclusive file lock for read-modify-write on projects.json.
|
|
33
46
|
|
|
34
47
|
Prevents concurrent processes from interleaving loads and saves,
|
|
35
|
-
which can silently drop entries.
|
|
48
|
+
which can silently drop entries. Cross-platform: POSIX uses
|
|
49
|
+
fcntl.flock, Windows uses msvcrt.locking.
|
|
36
50
|
"""
|
|
37
51
|
path = _registry_path()
|
|
38
52
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
39
53
|
lock_path = path.with_suffix(".lock")
|
|
40
54
|
fd = os.open(str(lock_path), os.O_CREAT | os.O_RDWR)
|
|
41
55
|
try:
|
|
42
|
-
|
|
56
|
+
if os.name == "nt":
|
|
57
|
+
deadline = time.monotonic() + _LOCK_TIMEOUT
|
|
58
|
+
while True:
|
|
59
|
+
try:
|
|
60
|
+
msvcrt.locking(fd, msvcrt.LK_NBLCK, 1)
|
|
61
|
+
break
|
|
62
|
+
except OSError:
|
|
63
|
+
if time.monotonic() > deadline:
|
|
64
|
+
raise
|
|
65
|
+
time.sleep(_LOCK_RETRY_DELAY)
|
|
66
|
+
else:
|
|
67
|
+
fcntl.flock(fd, fcntl.LOCK_EX)
|
|
43
68
|
yield
|
|
44
69
|
finally:
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
try:
|
|
71
|
+
if os.name == "nt":
|
|
72
|
+
with contextlib.suppress(OSError):
|
|
73
|
+
os.lseek(fd, 0, 0)
|
|
74
|
+
with contextlib.suppress(OSError):
|
|
75
|
+
msvcrt.locking(fd, msvcrt.LK_UNLCK, 1)
|
|
76
|
+
else:
|
|
77
|
+
fcntl.flock(fd, fcntl.LOCK_UN)
|
|
78
|
+
finally:
|
|
79
|
+
os.close(fd)
|
|
47
80
|
|
|
48
81
|
|
|
49
82
|
def _registry_path() -> Path:
|