@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 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: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
  [![Skills](https://img.shields.io/badge/skills-112-brightgreen)](app/skills/)
8
8
  [![Agents](https://img.shields.io/badge/agents-44-blue)](app/agents/)
9
- [![Tests](https://img.shields.io/badge/tests-973%20passing-success)](tests/)
9
+ [![Tests](https://img.shields.io/badge/tests-974%20passing-success)](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.0
17
+ ## What's New in v3.1.1
18
18
 
19
- **3.1.0 aligns global and project-local editor installs** with the current documented config surfaces for all 12 supported tools.
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 --editors cline` now writes documented global rules under `~/Documents/Cline/Rules/`.
22
- - `ai-toolkit install --editors roo` now writes documented global rules under `~/.roo/rules/`.
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 (973 tests)
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.0",
4
+ "version": "3.1.1",
5
5
  "author": {
6
6
  "name": "SoftSpark",
7
7
  "url": "https://github.com/softspark"
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "3.1.0",
2
+ "version": "3.1.1",
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": "3.1.0",
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
- fcntl.flock(fd, fcntl.LOCK_EX)
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
- fcntl.flock(fd, fcntl.LOCK_UN)
46
- os.close(fd)
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: