@softspark/ai-toolkit 4.31.0 → 4.32.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +21 -19
  3. package/app/.claude-plugin/plugin.json +1 -1
  4. package/app/claude-app/hooks/hooks.json +4 -2
  5. package/app/claude-app/skills/ai-toolkit-rules/SKILL.md +30 -16
  6. package/app/hooks/quality-gate.sh +9 -2
  7. package/app/hooks.json +4 -2
  8. package/app/rules/common/git-team.md +33 -0
  9. package/app/rules/common/git-workflow.md +6 -20
  10. package/app/rules/common/performance.md +25 -1
  11. package/app/rules/common/testing.md +7 -1
  12. package/app/skills/analyze/scripts/complexity.py +3 -0
  13. package/app/skills/deploy/scripts/pre_deploy_check.py +13 -6
  14. package/app/skills/docs/scripts/doc-inventory.py +3 -0
  15. package/app/skills/explain/scripts/dependency-graph.py +3 -0
  16. package/app/skills/migrate/scripts/migration-status.py +3 -0
  17. package/app/skills/refactor/scripts/refactor-scan.py +3 -0
  18. package/benchmarks/ecosystem-doctor-snapshot.json +17 -15
  19. package/bin/ai-toolkit.js +2 -0
  20. package/kb/procedures/sop-maintenance.md +6 -3
  21. package/kb/reference/cli-reference.md +3 -2
  22. package/kb/reference/global-install-model.md +16 -3
  23. package/kb/reference/hooks-catalog.md +5 -3
  24. package/kb/reference/language-rules.md +28 -10
  25. package/kb/reference/plugin-pack-conventions.md +3 -3
  26. package/kb/reference/unique-features.md +2 -1
  27. package/llms-full.txt +63 -25
  28. package/manifest.json +2 -2
  29. package/package.json +5 -2
  30. package/scripts/benchmark_ecosystem.py +0 -1
  31. package/scripts/check_split.py +11 -9
  32. package/scripts/claude_app.py +5 -7
  33. package/scripts/codex_skill_adapter.py +4 -12
  34. package/scripts/compile_slm.py +10 -26
  35. package/scripts/doctor.py +322 -0
  36. package/scripts/evaluate_skills.py +1 -1
  37. package/scripts/frontmatter.py +452 -29
  38. package/scripts/generate_augment_rules.py +4 -4
  39. package/scripts/generate_cursor_mdc.py +2 -3
  40. package/scripts/generate_language_rules_skills.py +8 -14
  41. package/scripts/generate_llms_txt.py +1 -15
  42. package/scripts/generate_opencode_agents.py +0 -1
  43. package/scripts/generate_opencode_skills.py +2 -20
  44. package/scripts/generate_windsurf_rules.py +0 -1
  45. package/scripts/generator_base.py +0 -1
  46. package/scripts/inject_hook_cli.py +15 -2
  47. package/scripts/inject_mcp_cli.py +1 -2
  48. package/scripts/install.py +32 -1
  49. package/scripts/install_git_hooks.py +0 -1
  50. package/scripts/install_steps/ai_tools.py +65 -25
  51. package/scripts/install_steps/markers.py +6 -6
  52. package/scripts/install_steps/skill_scope.py +188 -0
  53. package/scripts/instruction_core.py +5 -8
  54. package/scripts/merge-hooks.py +13 -3
  55. package/scripts/pack_codebase.py +1 -1
  56. package/scripts/plugin.py +128 -16
  57. package/scripts/surface_manifest.py +6 -7
  58. package/scripts/validate.py +180 -11
package/CHANGELOG.md CHANGED
@@ -7,6 +7,127 @@ Versioning follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## v4.32.1 - Plugin removal leaves nothing behind (2026-09-04)
11
+
12
+ Both fixes come from running the post-release SOPs on v4.32.0 in an isolated
13
+ sandbox; both defects predate that release (identical on v4.31.0).
14
+
15
+ ### Fixed
16
+
17
+ - **`plugin remove` deletes the hooks and scripts a pack installed.** The
18
+ Claude and Codex install paths copied `hooks/plugin-<pack>-*` and
19
+ `plugin-scripts/<pack>/*` into `~/.softspark/ai-toolkit` but never recorded
20
+ them in `shared_asset_ownership`, so removal found no owner and preserved
21
+ every file as "untracked": each pack left 4-5 files behind. Install now
22
+ records sha256/mode/inode for what it copied; removal deletes only entries
23
+ this editor consumes that no other editor still uses and that are unchanged
24
+ on disk, preserves an edited file with a `WARN preserved changed plugin
25
+ asset` line, and drops the empty `plugin-scripts/<pack>/` directory.
26
+ `tests/test_plugin_asset_removal.bats` covers install, zero-residue removal,
27
+ user-edited preservation, two-editor sharing, and reinstall.
28
+ - **Five skill scripts answer `--help`.** `doc-inventory.py`,
29
+ `dependency-graph.py`, `migration-status.py`, `refactor-scan.py`, and
30
+ `complexity.py` treated `--help` as a path and returned a JSON error.
31
+ `tests/test_skill_scripts_help.bats` now probes every documented
32
+ `${CLAUDE_SKILL_DIR}` invocation with `--help` (exit 0, no traceback), the
33
+ same check as post-release SOP Phase 4b. The probe uses `perl alarm` as its
34
+ hang guard, not GNU `timeout`, which the macOS CI runner does not have.
35
+ - **`pre_deploy_check.py` no longer crashes on Linux.** It probed for docker
36
+ by running the shell builtin `command -v` through `subprocess`, which only
37
+ works on macOS (a `/usr/bin/command` binary exists there); on Linux it raised
38
+ `FileNotFoundError` before any check ran. Now `shutil.which`. Caught by the
39
+ new `--help` probe on the Ubuntu CI runner, which is the point of that test.
40
+ - **Test count.** Bats increased from 1966 to 1972.
41
+
42
+ ## v4.32.0 - Context budget: scoped rules, scoped language skills, doctor budget checks (2026-09-04)
43
+
44
+ ### Added
45
+
46
+ - **`install --language-skills detected|all`.** Language knowledge skills
47
+ (`<lang>-rules`, `<lang>-patterns`) for languages no registered project uses
48
+ are turned off through `skillOverrides` in `~/.claude/settings.json`. The
49
+ entries the toolkit wrote are tracked in `state.json` and restored when a
50
+ newly registered project brings the language back; a user's own override is
51
+ never touched; with no registered project on disk nothing is disabled. `all`
52
+ restores everything and persists the choice.
53
+ - **`doctor` check 12, Context Budget.** Estimated resident tokens of the
54
+ model-visible skill listing (against `skillListingBudgetFraction`), the agent
55
+ listing, and always-loaded user memory, plus skills with zero recorded use in
56
+ both Claude Code's counters and the toolkit's `stats.json`. Read-only; prints
57
+ the `skillOverrides` key to paste.
58
+ - **`doctor` check 13, Permission Rules.** Warns on `permissions.allow`
59
+ wildcards that pre-approve execution or writes: interpreters, task runners,
60
+ package installs, `gh api`, `curl`/`wget`, `git fetch`/`pull`, destructive
61
+ commands, `find -exec`. Never edits.
62
+ - **`validate.py` skill description budget.** Error over 1024 characters (the
63
+ Agent Skills cap), warning over 400, and an error for an unquoted description
64
+ containing `: ` or ` #` (strict YAML drops every field, `allowed-tools`
65
+ included). Applied to plugin-pack skills too.
66
+ - **`git-team` common rule.** Branching, pull-request, and review conventions
67
+ moved out of `git-workflow` into a rule that ships with `--profile strict`
68
+ only, via a new `profiles:` frontmatter gate. See `DECISIONS.md`.
69
+ - **One frontmatter parser.** `scripts/frontmatter.py` now parses the whole
70
+ toolkit subset (scalars, quoted scalars, `>-`/`|` blocks, block and flow
71
+ lists, nested maps) strictly and is the only parser; twelve private
72
+ strip/parse copies in `validate.py`, `doctor.py`, `install_steps/ai_tools.py`,
73
+ `claude_app.py`, `compile_slm.py`, `surface_manifest.py`, `instruction_core.py`,
74
+ `check_split.py`, `codex_skill_adapter.py`, `generate_opencode_skills.py`, and
75
+ `generate_language_rules_skills.py` are gone. Every shipped `app/` and `kb/`
76
+ Markdown file parses under the strict grammar (pytest corpus test).
77
+ - **Repo dev tooling, stdlib runtime.** `requirements-dev.txt` + `pytest.ini`
78
+ + `mypy.ini` (pytest, ruff, mypy) and a `python-quality` CI job:
79
+ `npm run test:py` (348 pytest tests under `tests/python/`), `npm run lint:py`
80
+ (ruff `E,F`, rule set in `package.json`), `npm run typecheck:py` (mypy
81
+ `--strict` over an allowlist). No `pyproject.toml`: the toolkit's own
82
+ `quality-gate.sh` reads one as "Python project, run `ruff check .`", which
83
+ is not what an npm-first repo wants. Nothing is added to the published
84
+ package or to user machines. See `DECISIONS.md` for why no runtime
85
+ dependency.
86
+
87
+ ### Changed
88
+
89
+ - **Common rules are path-scoped from their source.** `app/rules/common/*.md`
90
+ may declare `paths:`; the generated `.claude/rules/ai-toolkit-*.md` copies it.
91
+ `testing` and `performance` load only for matching files; `coding-style`,
92
+ `git-workflow`, and `security` stay always-on. The `.claude/CLAUDE.md` index
93
+ now lists which rules are always-on and which are path-scoped instead of
94
+ claiming lazy loading for all of them.
95
+ - **Stop hooks `quality-check.sh` and `save-session.sh` run with
96
+ `"async": true`.** Both are advisory and always exit 0; the linter was the
97
+ bulk of a 3.3 s median Stop chain. `quality-gate.sh` (exit 2) and
98
+ `stop-search-check.sh` stay synchronous.
99
+ - **`git-workflow` is the solo-safe core** (commit format, no secrets, `main`
100
+ deployable, tags, recovery). Version 2.0.0.
101
+
102
+ ### Fixed
103
+
104
+ - **`quality-gate.sh` runs ruff only for projects that configured it.** A bare
105
+ `pyproject.toml` (build metadata, pytest/mypy tables) used to trigger
106
+ `ruff check .` on every Stop under whatever ruff configuration the machine
107
+ resolves; found when this repository's own gate went red on 348 unrelated
108
+ findings. Ruff now needs `ruff.toml`, `.ruff.toml`, or a `[tool.ruff]` table.
109
+ - **Codex/DSH skill sync no longer flattens nested frontmatter.** Native
110
+ (non-adapted) skills had their frontmatter re-rendered line by line, which
111
+ turned a `hooks:` block into stray top-level `PreToolUse:` / `- matcher:`
112
+ lines. The frontmatter now passes through verbatim.
113
+ - **Hook merge de-duplicates legacy untagged toolkit hooks by command identity.**
114
+ Scheduling fields (`async`, `timeout`, `statusMessage`, ...) no longer defeat
115
+ the match, so adding one in `app/hooks.json` does not leave existing installs
116
+ running the old and the new copy side by side. Fixed in both
117
+ `scripts/merge-hooks.py` and `scripts/inject_hook_cli.py`.
118
+ - **Test count.** Bats increased from 1931 to 1966; 348 pytest tests added under
119
+ `tests/python/` (run by the new `python-quality` CI job).
120
+
121
+ ### Ecosystem
122
+
123
+ - Ecosystem doctor run for this minor release: 12 tools drifted since the
124
+ v4.30.3 snapshot, all class A (content edits with no heading delta) or class
125
+ C (Cline gained a "Resources" heading, Codex CLI a "ChatGPT Work" heading;
126
+ neither adds a surface the toolkit integrates). Tracked versions moved:
127
+ Claude Code 2.1.252 -> 2.1.260 (its hooks documentation now lists the
128
+ `async` command-hook field this release relies on), Codex CLI 0.151.0 ->
129
+ 0.153.2. No generator changed; snapshot refreshed.
130
+
10
131
  ## v4.31.0 - Toolkit rules reach every editor (2026-09-03)
11
132
 
12
133
  ### Added
package/README.md CHANGED
@@ -6,25 +6,25 @@
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-114-brightgreen)](app/skills/)
8
8
  [![Agents](https://img.shields.io/badge/agents-44-blue)](app/agents/)
9
- [![Tests](https://img.shields.io/badge/tests-1931%20passing-success)](tests/)
10
-
11
- ## What's New in v4.31.0
12
-
13
- **v4.31.0** corrects the post-release health check for the managed DSH and
14
- plugin-owned MCP release:
15
-
16
- - `ai-toolkit doctor` now extracts `1.0.80` from the official Copilot CLI output
17
- `GitHub Copilot CLI 1.0.80.` instead of treating sentence punctuation as an
18
- invalid SemVer suffix.
19
- - Complete-token validation remains fail closed for malformed versions such as
20
- `1.2.3.4`, invalid prerelease identifiers, and leading-zero numeric fields.
21
- - The DSH cold-add regression keeps its legacy-timeout coverage with macOS CI
22
- process-startup headroom, removing the release-blocking timing flake.
23
- - Release tags now require green Ubuntu and macOS branch CI for the exact commit
24
- before the publish workflow can start.
25
- - The release retains the explicit DSH lifecycle, plugin-owned MCP/rules, portable
26
- recovery gates, and the exact DSH package set published in v4.30.2. Test count:
27
- 1920 -> 1931.
9
+ [![Tests](https://img.shields.io/badge/tests-1972%20passing-success)](tests/)
10
+
11
+ ## What's New in v4.32.1
12
+
13
+ **v4.32.1** fixes two defects the post-release SOPs found on v4.32.0 (both
14
+ older than that release):
15
+
16
+ - `ai-toolkit plugin remove` now deletes the hooks and scripts a pack
17
+ installed under `~/.softspark/ai-toolkit`. Install records what it copied;
18
+ removal deletes only unchanged, unshared files and names anything it
19
+ preserves. Every pack used to leave 4-5 files behind.
20
+ - Five skill scripts (`doc-inventory`, `dependency-graph`, `migration-status`,
21
+ `refactor-scan`, `complexity`) answer `--help` instead of treating it as a
22
+ path; a new test probes every documented skill script with `--help`.
23
+ - Still in this train from v4.32.0: path-scoped common rules, language skills
24
+ scoped to your registered projects (`--language-skills`), `doctor` Context
25
+ Budget and Permission Rules checks, one strict frontmatter parser, and the
26
+ `git-team` rule for `--profile strict`. Test count: 1966 -> 1972 bats +
27
+ 348 pytest.
28
28
 
29
29
  See [CHANGELOG.md](CHANGELOG.md) for full history.
30
30
 
@@ -62,6 +62,8 @@ npx @softspark/ai-toolkit install
62
62
 
63
63
  **That's it.** Claude Code picks up 114 skills, 44 agents, quality hooks, and the safety constitution automatically.
64
64
 
65
+ Language knowledge skills (`rust-rules`, `kotlin-patterns`, ...) are scoped to the languages your registered projects use: once you have run `ai-toolkit install --local` in at least one project, the global install turns the other languages' skills off through `skillOverrides` in `~/.claude/settings.json` so their descriptions stop loading into every session. A new project in a new language turns its skills back on. `ai-toolkit install --language-skills all` keeps every language skill on and remembers that choice; `ai-toolkit doctor` shows the resulting context budget.
66
+
65
67
  **Windows:** WSL is the recommended runtime. Native Windows works when Git Bash is available for hook scripts; dependency hints cover `winget`, Chocolatey, and Scoop. See [Windows Support](kb/reference/windows-support.md).
66
68
 
67
69
  ### Update
@@ -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.31.0",
6
+ "version": "4.32.1",
7
7
  "author": {
8
8
  "name": "SoftSpark",
9
9
  "url": "https://github.com/softspark"
@@ -151,7 +151,8 @@
151
151
  "hooks": [
152
152
  {
153
153
  "type": "command",
154
- "command": "AI_TOOLKIT_DIR=\"${CLAUDE_PLUGIN_ROOT}\" \"${CLAUDE_PLUGIN_ROOT}/hooks/quality-check.sh\""
154
+ "command": "AI_TOOLKIT_DIR=\"${CLAUDE_PLUGIN_ROOT}\" \"${CLAUDE_PLUGIN_ROOT}/hooks/quality-check.sh\"",
155
+ "async": true
155
156
  }
156
157
  ]
157
158
  },
@@ -160,7 +161,8 @@
160
161
  "hooks": [
161
162
  {
162
163
  "type": "command",
163
- "command": "AI_TOOLKIT_DIR=\"${CLAUDE_PLUGIN_ROOT}\" \"${CLAUDE_PLUGIN_ROOT}/hooks/save-session.sh\""
164
+ "command": "AI_TOOLKIT_DIR=\"${CLAUDE_PLUGIN_ROOT}\" \"${CLAUDE_PLUGIN_ROOT}/hooks/save-session.sh\"",
165
+ "async": true
164
166
  }
165
167
  ]
166
168
  },
@@ -207,27 +207,22 @@ Default response mode for this project is **concise**. The `brand-voice` skill (
207
207
  - Magic numbers/strings: use named constants.
208
208
  - Mutable global state: use dependency injection instead.
209
209
 
210
- ## Source: `app/rules/common/git-workflow.md`
211
-
212
- # Git Workflow Rules
210
+ ## Source: `app/rules/common/git-team.md`
213
211
 
214
- ## Commit Messages
215
- - Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.
216
- - First line: imperative mood, max 72 chars (`feat: add user registration endpoint`).
217
- - Body (optional): explain *why*, not *what*. The diff shows what.
218
- - Reference tickets: `fix: prevent duplicate orders (PROJ-456)`.
212
+ # Git Team Workflow Rules
219
213
 
220
- ## Commit Practices
221
- - Commit small, atomic changes. One commit = one logical change.
222
- - Never commit: secrets, `.env` files, build artifacts, large binaries.
223
- - Never commit broken code to `main`. Use feature branches.
224
- - Squash fixup commits before merging to keep history clean.
214
+ These rules assume more than one person merges into `main`. They ship only with
215
+ the `strict` profile; a solo maintainer who commits straight to `main` is not
216
+ doing anything wrong, and a reviewer that keeps flagging "use a feature branch"
217
+ in that setting is noise. The solo-safe core (commit format, no secrets, no
218
+ force-push) lives in `git-workflow`.
225
219
 
226
220
  ## Branching
227
- - `main` is always deployable. Protect it with required reviews and CI.
228
- - Feature branches: `feat/user-registration`, `fix/order-total-calc`.
221
+ - Protect `main` with required reviews and CI. Never commit broken code to it.
222
+ - Work on feature branches: `feat/user-registration`, `fix/order-total-calc`.
223
+ - Rebase feature branches on `main` before opening a PR to keep linear history.
224
+ - Squash fixup commits before merging to keep history clean.
229
225
  - Delete branches after merge. Stale branches are clutter.
230
- - Rebase feature branches on main before PR to keep linear history.
231
226
 
232
227
  ## Pull Requests
233
228
  - Keep PRs small: <400 lines changed. Split large features into stacked PRs.
@@ -240,6 +235,25 @@ Default response mode for this project is **concise**. The `brand-voice` skill (
240
235
  - Approve with comments if nits only. Block for: bugs, security, missing tests.
241
236
  - Respond to reviews within 24 hours. Do not let PRs rot.
242
237
 
238
+ ## Source: `app/rules/common/git-workflow.md`
239
+
240
+ # Git Workflow Rules
241
+
242
+ Solo-safe core: everything here holds whether one person or twenty merge into
243
+ `main`. Branching, pull-request, and review conventions for teams live in
244
+ `git-team` and ship only with the `strict` profile.
245
+
246
+ ## Commit Messages
247
+ - Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.
248
+ - First line: imperative mood, max 72 chars (`feat: add user registration endpoint`).
249
+ - Body (optional): explain *why*, not *what*. The diff shows what.
250
+ - Reference tickets: `fix: prevent duplicate orders (PROJ-456)`.
251
+
252
+ ## Commit Practices
253
+ - Commit small, atomic changes. One commit = one logical change.
254
+ - Never commit: secrets, `.env` files, build artifacts, large binaries.
255
+ - `main` is always deployable: run the project's gates before every commit that lands there.
256
+
243
257
  ## Tags and Releases
244
258
  - Use semantic versioning: MAJOR.MINOR.PATCH.
245
259
  - Tag releases: `git tag v1.2.3`. Automate changelog from commits.
@@ -98,8 +98,15 @@ if [ -f .claude/test-cohesion-map.json ] || \
98
98
  fi
99
99
 
100
100
  if [ -f pyproject.toml ] || [ -f setup.py ]; then
101
- if require_command ruff; then
102
- run_required "ruff found errors" "head -30" ruff check .
101
+ # Lint only what the project itself configured. A bare pyproject.toml
102
+ # (build metadata, pytest/mypy tables) says nothing about ruff, and running
103
+ # `ruff check .` under whatever config the machine resolves turns the Stop
104
+ # gate red on findings the project never signed up for (v4.32.0 postmortem:
105
+ # 348 findings in a repo whose ruff rule set lives in a package.json script).
106
+ if [ -f ruff.toml ] || [ -f .ruff.toml ] || grep -qs '^\[tool\.ruff' pyproject.toml; then
107
+ if require_command ruff; then
108
+ run_required "ruff found errors" "head -30" ruff check .
109
+ fi
103
110
  fi
104
111
  if [ -d src ] && [ "$PROFILE" = "strict" ]; then
105
112
  if require_command mypy; then
package/app/hooks.json CHANGED
@@ -167,7 +167,8 @@
167
167
  "hooks": [
168
168
  {
169
169
  "type": "command",
170
- "command": "\"$HOME/.softspark/ai-toolkit/hooks/quality-check.sh\""
170
+ "command": "\"$HOME/.softspark/ai-toolkit/hooks/quality-check.sh\"",
171
+ "async": true
171
172
  }
172
173
  ]
173
174
  },
@@ -177,7 +178,8 @@
177
178
  "hooks": [
178
179
  {
179
180
  "type": "command",
180
- "command": "\"$HOME/.softspark/ai-toolkit/hooks/save-session.sh\""
181
+ "command": "\"$HOME/.softspark/ai-toolkit/hooks/save-session.sh\"",
182
+ "async": true
181
183
  }
182
184
  ]
183
185
  },
@@ -0,0 +1,33 @@
1
+ ---
2
+ language: common
3
+ category: git-team
4
+ version: "1.0.0"
5
+ profiles:
6
+ - "strict"
7
+ ---
8
+
9
+ # Git Team Workflow Rules
10
+
11
+ These rules assume more than one person merges into `main`. They ship only with
12
+ the `strict` profile; a solo maintainer who commits straight to `main` is not
13
+ doing anything wrong, and a reviewer that keeps flagging "use a feature branch"
14
+ in that setting is noise. The solo-safe core (commit format, no secrets, no
15
+ force-push) lives in `git-workflow`.
16
+
17
+ ## Branching
18
+ - Protect `main` with required reviews and CI. Never commit broken code to it.
19
+ - Work on feature branches: `feat/user-registration`, `fix/order-total-calc`.
20
+ - Rebase feature branches on `main` before opening a PR to keep linear history.
21
+ - Squash fixup commits before merging to keep history clean.
22
+ - Delete branches after merge. Stale branches are clutter.
23
+
24
+ ## Pull Requests
25
+ - Keep PRs small: <400 lines changed. Split large features into stacked PRs.
26
+ - PR title follows conventional commit format.
27
+ - Include: summary, test plan, and screenshots/recordings for UI changes.
28
+ - Require at least one approval before merge.
29
+
30
+ ## Code Review
31
+ - Review for: correctness, security, performance, readability.
32
+ - Approve with comments if nits only. Block for: bugs, security, missing tests.
33
+ - Respond to reviews within 24 hours. Do not let PRs rot.
@@ -1,11 +1,15 @@
1
1
  ---
2
2
  language: common
3
3
  category: git-workflow
4
- version: "1.0.0"
4
+ version: "2.0.0"
5
5
  ---
6
6
 
7
7
  # Git Workflow Rules
8
8
 
9
+ Solo-safe core: everything here holds whether one person or twenty merge into
10
+ `main`. Branching, pull-request, and review conventions for teams live in
11
+ `git-team` and ship only with the `strict` profile.
12
+
9
13
  ## Commit Messages
10
14
  - Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.
11
15
  - First line: imperative mood, max 72 chars (`feat: add user registration endpoint`).
@@ -15,25 +19,7 @@ version: "1.0.0"
15
19
  ## Commit Practices
16
20
  - Commit small, atomic changes. One commit = one logical change.
17
21
  - Never commit: secrets, `.env` files, build artifacts, large binaries.
18
- - Never commit broken code to `main`. Use feature branches.
19
- - Squash fixup commits before merging to keep history clean.
20
-
21
- ## Branching
22
- - `main` is always deployable. Protect it with required reviews and CI.
23
- - Feature branches: `feat/user-registration`, `fix/order-total-calc`.
24
- - Delete branches after merge. Stale branches are clutter.
25
- - Rebase feature branches on main before PR to keep linear history.
26
-
27
- ## Pull Requests
28
- - Keep PRs small: <400 lines changed. Split large features into stacked PRs.
29
- - PR title follows conventional commit format.
30
- - Include: summary, test plan, and screenshots/recordings for UI changes.
31
- - Require at least one approval before merge.
32
-
33
- ## Code Review
34
- - Review for: correctness, security, performance, readability.
35
- - Approve with comments if nits only. Block for: bugs, security, missing tests.
36
- - Respond to reviews within 24 hours. Do not let PRs rot.
22
+ - `main` is always deployable: run the project's gates before every commit that lands there.
37
23
 
38
24
  ## Tags and Releases
39
25
  - Use semantic versioning: MAJOR.MINOR.PATCH.
@@ -1,7 +1,31 @@
1
1
  ---
2
2
  language: common
3
3
  category: performance
4
- version: "1.0.0"
4
+ version: "1.1.0"
5
+ paths:
6
+ - "**/*.py"
7
+ - "**/*.ts"
8
+ - "**/*.tsx"
9
+ - "**/*.js"
10
+ - "**/*.jsx"
11
+ - "**/*.mjs"
12
+ - "**/*.cjs"
13
+ - "**/*.go"
14
+ - "**/*.rs"
15
+ - "**/*.java"
16
+ - "**/*.kt"
17
+ - "**/*.kts"
18
+ - "**/*.swift"
19
+ - "**/*.dart"
20
+ - "**/*.cs"
21
+ - "**/*.php"
22
+ - "**/*.cpp"
23
+ - "**/*.cc"
24
+ - "**/*.cxx"
25
+ - "**/*.hpp"
26
+ - "**/*.h"
27
+ - "**/*.rb"
28
+ - "**/*.sql"
5
29
  ---
6
30
 
7
31
  # Universal Performance Rules
@@ -1,7 +1,13 @@
1
1
  ---
2
2
  language: common
3
3
  category: testing
4
- version: "1.0.0"
4
+ version: "1.1.0"
5
+ paths:
6
+ - "**/*.test.*"
7
+ - "**/*.spec.*"
8
+ - "**/test_*"
9
+ - "**/*_test.*"
10
+ - "**/tests/**"
5
11
  ---
6
12
 
7
13
  # Universal Testing Rules
@@ -125,6 +125,9 @@ def _summary(root: Path, all_files: list[Path]) -> tuple[int, int]:
125
125
 
126
126
  def main() -> None:
127
127
  """Entry point: analyse directory and print text report to stdout."""
128
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
129
+ print("Usage: complexity.py [directory]\n\nReport per-file code complexity for directory (default: cwd).")
130
+ return
128
131
  root = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path.cwd().resolve()
129
132
  now = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
130
133
 
@@ -16,6 +16,7 @@ Usage::
16
16
  from __future__ import annotations
17
17
 
18
18
  import json
19
+ import shutil
19
20
  import subprocess
20
21
  import sys
21
22
  from datetime import datetime, timezone
@@ -50,12 +51,15 @@ def _git_branch() -> str:
50
51
 
51
52
 
52
53
  def _docker_available() -> bool:
53
- """Return True if the ``docker`` command is on PATH."""
54
- result = _run(["command", "-v", "docker"])
55
- # Fallback: just try docker --version
56
- if result.returncode != 0:
57
- result = _run(["docker", "--version"])
58
- return result.returncode == 0
54
+ """Return True if the ``docker`` command is on PATH.
55
+
56
+ ``command -v`` is a shell builtin; running it through ``subprocess`` only
57
+ worked on macOS, which ships a ``/usr/bin/command`` binary. On Linux it
58
+ raised ``FileNotFoundError`` before any check ran (v4.32.1).
59
+ """
60
+ if shutil.which("docker") is None:
61
+ return False
62
+ return _run(["docker", "--version"]).returncode == 0
59
63
 
60
64
 
61
65
  def _docker_services_running() -> bool:
@@ -155,6 +159,9 @@ def _run_checks(env: str) -> _CheckCollector:
155
159
 
156
160
  def main() -> None:
157
161
  """Entry point: run checks and print JSON result to stdout."""
162
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
163
+ print("Usage: pre_deploy_check.py [environment]\n\nRun pre-deployment checks for environment (default: staging) and print JSON.")
164
+ return
158
165
  env = sys.argv[1] if len(sys.argv) > 1 else "staging"
159
166
  branch = _git_branch()
160
167
  collector = _run_checks(env)
@@ -130,6 +130,9 @@ def get_mtime(filepath: str) -> float:
130
130
 
131
131
 
132
132
  def main():
133
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
134
+ print("Usage: doc-inventory.py [directory]\n\nInventory documentation files under directory (default: cwd) as JSON.")
135
+ return
133
136
  root = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else os.getcwd()
134
137
  if not os.path.isdir(root):
135
138
  print(json.dumps({"error": f"Not a directory: {root}"}))
@@ -159,6 +159,9 @@ def generate_mermaid(target_name: str, imports: list, imported_by: list) -> str:
159
159
 
160
160
 
161
161
  def main():
162
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
163
+ print("Usage: dependency-graph.py <file_or_directory>\n\nPrint the import/dependency graph of a file or directory as JSON.")
164
+ return
162
165
  if len(sys.argv) < 2:
163
166
  print(json.dumps({"error": "Usage: dependency-graph.py <file_or_directory>"}))
164
167
  sys.exit(1)
@@ -182,6 +182,9 @@ def detect(project_dir: Path) -> dict[str, object]:
182
182
 
183
183
  def main() -> None:
184
184
  """Entry point: detect migration tool and print JSON result to stdout."""
185
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
186
+ print("Usage: migration-status.py [project_dir]\n\nDetect the migration tool in project_dir (default: cwd) and report its status as JSON.")
187
+ return
185
188
  project_dir = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path.cwd()
186
189
  if not project_dir.is_dir():
187
190
  print(json.dumps({"error": f"Not a directory: {project_dir}"}))
@@ -154,6 +154,9 @@ def analyze_file(filepath: str, project_root: str) -> dict:
154
154
 
155
155
 
156
156
  def main():
157
+ if len(sys.argv) > 1 and sys.argv[1] in ("-h", "--help"):
158
+ print("Usage: refactor-scan.py <file_or_directory>\n\nScan a file or directory for refactoring candidates and print JSON.")
159
+ return
157
160
  if len(sys.argv) < 2:
158
161
  print(json.dumps({"error": "Usage: refactor-scan.py <file_or_directory>"}))
159
162
  sys.exit(1)