@softspark/ai-toolkit 4.2.0 → 4.2.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,35 @@ Versioning follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## v4.2.1 - Claude Code hook enforcement and README cleanup (2026-05-12)
11
+
12
+ Patch release. Tightens Claude Code runtime enforcement, fixes duplicated hook cleanup during install/update, and removes the README hero image for release.
13
+
14
+ ### Changed
15
+
16
+ - **Stop quality gate** - Registered `quality-gate.sh` for `Stop` in addition to `TaskCompleted`, so final Claude Code responses are blocked when supported lint/type checks fail.
17
+ - **README release surface** - Removed the README hero image block while keeping badges and release notes intact.
18
+ - **Runtime guidance** - Clarified in `CLAUDE.md` that Claude Code consumes `CLAUDE.md`, settings, hooks, skills, and agents, while `AGENTS.md` is generated for Codex/OpenCode/Gemini compatibility.
19
+
20
+ ### Fixed
21
+
22
+ - **Quality gate exit codes** - Reworked shell pipelines so `ruff`, `tsc`, `dart analyze`, `phpstan`, and `go test` failures are not masked by output truncation.
23
+ - **Hook merge cleanup** - `scripts/merge-hooks.py` now removes legacy untagged ai-toolkit hook entries matching current toolkit hook signatures while preserving custom hooks.
24
+
25
+ ### Ecosystem
26
+
27
+ - Refreshed `benchmarks/ecosystem-doctor-snapshot.json` for current editor/runtime docs. Claude Code now exposes `Stop` in docs; the toolkit already supported `Stop` hooks, and this release registers the strict quality gate there.
28
+
29
+ ### Verification
30
+
31
+ - `python3 scripts/ecosystem_doctor.py --offline --check`: no drift.
32
+ - `python3 scripts/validate.py --strict`: 0 errors, 0 warnings.
33
+ - `python3 scripts/audit_skills.py --ci`: HIGH 0, WARN 0.
34
+ - `npm test`: 1049/1049 passing.
35
+ - `npm --cache /tmp/ai-toolkit-npm-cache pack --dry-run`: `softspark-ai-toolkit-4.2.1.tgz`.
36
+
37
+ ---
38
+
10
39
  ## v4.2.0 - SEO GEO pipeline and release gate hardening (2026-05-07)
11
40
 
12
41
  Minor release. Adds AI pipeline, content citability, and topical authority guidance to `seo-validate` from PR #9 by @fakenso, and keeps the release gate fixes prepared for v4.1.1 in the same unreleased train.
package/README.md CHANGED
@@ -6,22 +6,16 @@
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
7
7
  [![Skills](https://img.shields.io/badge/skills-107-brightgreen)](app/skills/)
8
8
  [![Agents](https://img.shields.io/badge/agents-44-blue)](app/agents/)
9
- [![Tests](https://img.shields.io/badge/tests-1047%20passing-success)](tests/)
9
+ [![Tests](https://img.shields.io/badge/tests-1049%20passing-success)](tests/)
10
10
 
11
- <p align="center">
12
- <img src="assets/ai-toolkit-readme-hero.png" alt="ai-toolkit 3 README hero showing one toolkit for 12 AI editors" width="900">
13
- </p>
11
+ ## What's New in v4.2.1
14
12
 
15
- ---
16
-
17
- ## What's New in v4.2.0
18
-
19
- SEO/GEO release focused on AI citation readiness and stricter release gates.
13
+ Patch release focused on making Claude Code rule enforcement harder to bypass and cleaning the release-facing README.
20
14
 
21
- - **AI pipeline guidance**: `seo-validate` now includes Google AI pipeline, Query Fan Out, and content citability references.
22
- - **Topical authority checks**: new `--scope topical` covers cluster structure, internal links, orphan pages, slugs, and cannibalization.
23
- - **Expanded GEO heuristics**: Category 6 now checks chunk boundaries, hedging, decision frameworks, freshness, and author quality.
24
- - **Release gate parity**: CI and `prepublishOnly` now run strict validation, and the URL rule test is hermetic.
15
+ - **Stop quality gate**: `quality-gate.sh` now runs on `Stop` as well as `TaskCompleted`, blocking final responses when lint/type checks fail.
16
+ - **Reliable hook failures**: shell pipelines in the quality gate now preserve the failing tool exit code instead of hiding errors behind `head`.
17
+ - **Cleaner installs**: hook merging now strips legacy untagged ai-toolkit duplicates while preserving user-owned hooks.
18
+ - **README cleanup**: removed the hero image block for a lighter release README.
25
19
 
26
20
  See [CHANGELOG.md](CHANGELOG.md) for full history.
27
21
 
@@ -131,7 +125,7 @@ See [CLI Reference](kb/reference/cli-reference.md) for all commands and options.
131
125
  | `skills/` (hybrid) | 30 | Slash commands with agent knowledge base |
132
126
  | `skills/` (knowledge) | 45 | Domain knowledge auto-loaded by agents (includes 13 `<lang>-rules` skills) |
133
127
  | `agents/` | 44 | Specialized agents across 10 categories |
134
- | `hooks/` | 21 global + 5 skill-scoped | Quality gates, path safety, prompt governance, session lifecycle |
128
+ | `hooks/` | 22 global + 5 skill-scoped | Quality gates, path safety, prompt governance, session lifecycle |
135
129
  | `plugins/` | 11 packs | Opt-in domain bundles (security, research, frontend, enterprise, 6 language packs) |
136
130
  | `constitution.md` | 6 articles | Machine-enforced safety rules |
137
131
  | `rules/` | auto-injected | Language-specific and custom rules injected into your configs |
@@ -147,14 +141,14 @@ ai-toolkit/
147
141
  │ ├── agents/ # 44 agent definitions
148
142
  │ ├── skills/ # 107 skills (task / hybrid / knowledge)
149
143
  │ ├── rules/ # Auto-injected into your CLAUDE.md
150
- │ ├── hooks/ # Hook scripts (21 entries, 12 lifecycle events)
144
+ │ ├── hooks/ # Hook scripts (22 entries, 12 lifecycle events)
151
145
  │ ├── plugins/ # 11 experimental plugin packs (opt-in)
152
146
  │ ├── output-styles/ # System prompt output style overrides
153
147
  │ ├── constitution.md # 6 immutable safety articles
154
148
  │ └── ARCHITECTURE.md # Full system design
155
149
  ├── kb/ # Reference docs, procedures, plans
156
150
  ├── scripts/ # Validation, install, evaluation scripts
157
- ├── tests/ # Bats test suite (1047 tests)
151
+ ├── tests/ # Bats test suite (1049 tests)
158
152
  └── CHANGELOG.md
159
153
  ```
160
154
 
@@ -166,7 +160,7 @@ ai-toolkit/
166
160
 
167
161
  **Machine-enforced constitution** — 6-article safety constitution enforced via `PreToolUse` hooks that actually block `rm -rf`, `DROP TABLE`, and irreversible operations. Not just documentation.
168
162
 
169
- **21 lifecycle hooks** — Executable scripts across 12 events (SessionStart → SessionEnd). Guards, governance, quality gates, session persistence, MCP health checks. See [Hooks Catalog](kb/reference/hooks-catalog.md).
163
+ **22 lifecycle hooks** — Executable scripts across 12 events (SessionStart → SessionEnd). Guards, governance, quality gates, session persistence, MCP health checks. See [Hooks Catalog](kb/reference/hooks-catalog.md).
170
164
 
171
165
  **Security scanning** — `/skill-audit` for code-level risks, `/cve-scan` for dependency CVEs. Both CI-ready with exit codes.
172
166
 
@@ -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": "4.2.0",
4
+ "version": "4.2.1",
5
5
  "author": {
6
6
  "name": "SoftSpark",
7
7
  "url": "https://github.com/softspark"
@@ -8,7 +8,7 @@ Universal multi-agent system for software development. Works across all reposito
8
8
  |-----------|-------|
9
9
  | Agents | See agents catalog |
10
10
  | Skills | See skills catalog |
11
- | Hooks | 12 events / 21 entries (SessionStart ×3, Notification ×1, PreToolUse ×4, UserPromptSubmit ×2, PostToolUse ×2, Stop ×2, TaskCompleted ×1, TeammateIdle ×1, SubagentStart ×1, SubagentStop ×1, PreCompact ×2, SessionEnd ×1) |
11
+ | Hooks | 12 events / 22 entries (SessionStart ×3, Notification ×1, PreToolUse ×4, UserPromptSubmit ×2, PostToolUse ×2, Stop ×3, TaskCompleted ×1, TeammateIdle ×1, SubagentStart ×1, SubagentStop ×1, PreCompact ×2, SessionEnd ×1) |
12
12
 
13
13
  ---
14
14
 
@@ -1,48 +1,60 @@
1
1
  #!/usr/bin/env bash
2
2
  # quality-gate.sh — Block task completion if lint/type errors found.
3
3
  #
4
- # Fires on: TaskCompleted
5
- # Exit 2 = block completion. Skipped when TOOLKIT_HOOK_PROFILE=minimal.
4
+ # Fires on: Stop, TaskCompleted
5
+ # Exit 2 = block completion/stop. Skipped when TOOLKIT_HOOK_PROFILE=minimal.
6
6
  # Strict profile also runs mypy.
7
7
 
8
8
  # shellcheck source=_profile-check.sh
9
9
  source "$(dirname "$0")/_profile-check.sh"
10
10
 
11
- if [ -f pyproject.toml ] || [ -f setup.py ]; then
12
- ruff check . 2>&1 | head -30
13
- exit_code=$?
11
+ run_required() {
12
+ local label="$1"
13
+ local preview_cmd="$2"
14
+ shift 2
15
+
16
+ local tmp
17
+ tmp="$(mktemp "${TMPDIR:-/tmp}/ai-toolkit-quality.XXXXXX")"
18
+ "$@" >"$tmp" 2>&1
19
+ local exit_code=$?
20
+ eval "$preview_cmd" <"$tmp"
21
+ rm -f "$tmp"
22
+
14
23
  if [ $exit_code -ne 0 ]; then
15
- echo "QUALITY GATE FAILED: ruff found errors. Fix them before completing." >&2
24
+ echo "QUALITY GATE FAILED: ${label}. Fix it before completing." >&2
16
25
  exit 2
17
26
  fi
27
+ }
28
+
29
+ require_command() {
30
+ local command_name="$1"
31
+ if command -v "$command_name" >/dev/null 2>&1; then
32
+ return 0
33
+ fi
34
+ echo "QUALITY GATE SKIPPED: ${command_name} is not installed." >&2
35
+ return 1
36
+ }
37
+
38
+ if [ -f pyproject.toml ] || [ -f setup.py ]; then
39
+ if require_command ruff; then
40
+ run_required "ruff found errors" "head -30" ruff check .
41
+ fi
18
42
  if [ -d src ] && [ "$PROFILE" = "strict" ]; then
19
- mypy --strict src/ 2>&1 | tail -5
20
- exit_code=$?
21
- if [ $exit_code -ne 0 ]; then
22
- echo "QUALITY GATE FAILED: mypy found type errors." >&2
23
- exit 2
43
+ if require_command mypy; then
44
+ run_required "mypy found type errors" "tail -5" mypy --strict src/
24
45
  fi
25
46
  fi
26
47
  elif [ -f package.json ] && [ -f tsconfig.json ]; then
27
- npx tsc --noEmit 2>&1 | tail -10
28
- exit_code=$?
29
- if [ $exit_code -ne 0 ]; then
30
- echo "QUALITY GATE FAILED: TypeScript compilation errors." >&2
31
- exit 2
48
+ if require_command npx; then
49
+ run_required "TypeScript compilation errors" "tail -10" npx tsc --noEmit
32
50
  fi
33
51
  elif [ -f pubspec.yaml ]; then
34
- dart analyze 2>&1 | tail -10
35
- exit_code=$?
36
- if [ $exit_code -ne 0 ]; then
37
- echo "QUALITY GATE FAILED: Dart analysis issues." >&2
38
- exit 2
52
+ if require_command dart; then
53
+ run_required "Dart analysis issues" "tail -10" dart analyze
39
54
  fi
40
55
  elif [ -f go.mod ]; then
41
- go vet ./... 2>&1 | tail -10
42
- exit_code=$?
43
- if [ $exit_code -ne 0 ]; then
44
- echo "QUALITY GATE FAILED: Go vet issues." >&2
45
- exit 2
56
+ if require_command go; then
57
+ run_required "Go vet issues" "tail -10" go vet ./...
46
58
  fi
47
59
  fi
48
60
 
package/app/hooks.json CHANGED
@@ -150,6 +150,16 @@
150
150
  "command": "\"$HOME/.softspark/ai-toolkit/hooks/save-session.sh\""
151
151
  }
152
152
  ]
153
+ },
154
+ {
155
+ "_source": "ai-toolkit",
156
+ "matcher": "",
157
+ "hooks": [
158
+ {
159
+ "type": "command",
160
+ "command": "\"$HOME/.softspark/ai-toolkit/hooks/quality-gate.sh\""
161
+ }
162
+ ]
153
163
  }
154
164
  ],
155
165
  "TaskCompleted": [
@@ -1,5 +1,5 @@
1
1
  {
2
- "last_run": "2026-05-06T08:17:20Z",
2
+ "last_run": "2026-05-12T10:01:38Z",
3
3
  "schema_version": 1,
4
4
  "tools": {
5
5
  "aider": {
@@ -24,10 +24,10 @@
24
24
  }
25
25
  },
26
26
  "augment": {
27
- "docs_hash": "ac138d99235e1f3e",
27
+ "docs_hash": "b746d5dbbc5a2936",
28
28
  "headings": [
29
29
  "Agent",
30
- "Code Completions",
30
+ "Chat",
31
31
  "Documentation Index",
32
32
  "Introduction",
33
33
  "\u200bAuggie CLI",
@@ -57,7 +57,7 @@
57
57
  }
58
58
  },
59
59
  "claude-code": {
60
- "docs_hash": "789113e1bc4cd34c",
60
+ "docs_hash": "9e0292a9f92392e0",
61
61
  "headings": [
62
62
  "Claude Code overview",
63
63
  "Documentation Index",
@@ -85,7 +85,7 @@
85
85
  "SessionEnd": false,
86
86
  "SessionStart": false,
87
87
  "Setup": true,
88
- "Stop": false,
88
+ "Stop": true,
89
89
  "StopFailure": false,
90
90
  "SubagentStart": false,
91
91
  "SubagentStop": false,
@@ -103,10 +103,10 @@
103
103
  "slash command": true,
104
104
  "sub-agent": true
105
105
  },
106
- "version": "2.1.131 (Claude Code)"
106
+ "version": "2.1.139 (Claude Code)"
107
107
  },
108
108
  "cline": {
109
- "docs_hash": "b4009dc8e6d40af9",
109
+ "docs_hash": "b59e8836b3217cdb",
110
110
  "headings": [
111
111
  "Cline CLI",
112
112
  "Cline Documentation",
@@ -137,7 +137,7 @@
137
137
  }
138
138
  },
139
139
  "codex-cli": {
140
- "docs_hash": "c6b51936294d38e7",
140
+ "docs_hash": "3f963da56d00add9",
141
141
  "headings": [
142
142
  "About",
143
143
  "Contributing",
@@ -156,7 +156,7 @@
156
156
  "Packages 0",
157
157
  "Provide feedback",
158
158
  "Quickstart",
159
- "Releases 765",
159
+ "Releases 784",
160
160
  "Repository files navigation",
161
161
  "Resources",
162
162
  "Saved searches",
@@ -186,10 +186,10 @@
186
186
  "mcp_servers": false,
187
187
  "sandbox": true
188
188
  },
189
- "version": "codex-cli 0.128.0"
189
+ "version": "codex-cli 0.130.0"
190
190
  },
191
191
  "cursor": {
192
- "docs_hash": "8ed1f5cf7441b6c0",
192
+ "docs_hash": "705adfd617433088",
193
193
  "headings": [],
194
194
  "markers": {
195
195
  ".cursor/rules": false,
@@ -205,7 +205,7 @@
205
205
  }
206
206
  },
207
207
  "gemini-cli": {
208
- "docs_hash": "21a2f14121ff27fa",
208
+ "docs_hash": "93694630a3d04327",
209
209
  "headings": [
210
210
  "Breadcrumbs",
211
211
  "Directory actions",
@@ -244,7 +244,7 @@
244
244
  }
245
245
  },
246
246
  "github-copilot": {
247
- "docs_hash": "99a5ab7bd5f7556f",
247
+ "docs_hash": "d9b9fcdfe3b67469",
248
248
  "headings": [
249
249
  "About Copilot auto model selection",
250
250
  "About Copilot integrations",
@@ -292,7 +292,7 @@
292
292
  }
293
293
  },
294
294
  "opencode": {
295
- "docs_hash": "fe845a4bffb6371b",
295
+ "docs_hash": "c1c8ba8f6b2e7ddf",
296
296
  "headings": [
297
297
  "Add features",
298
298
  "Ask questions",
@@ -353,7 +353,7 @@
353
353
  }
354
354
  },
355
355
  "windsurf": {
356
- "docs_hash": "9b2879646f041aea",
356
+ "docs_hash": "66295add1d0f0645",
357
357
  "headings": [
358
358
  "Advanced",
359
359
  "App Deploys",
@@ -3,9 +3,9 @@ title: "AI Toolkit - Architecture Overview"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [architecture, overview, design, structure]
6
- version: "1.4.4"
6
+ version: "1.4.5"
7
7
  created: "2026-03-23"
8
- last_updated: "2026-04-15"
8
+ last_updated: "2026-05-12"
9
9
  description: "Architecture of ai-toolkit: directory layout, global install model, editor-aware MCP install, Codex translation layer, skill tiers, and integration with projects."
10
10
  ---
11
11
 
@@ -264,7 +264,7 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
264
264
 
265
265
  ## Quality Hooks
266
266
 
267
- 21 entries across 12 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
267
+ 22 entries across 12 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
268
268
 
269
269
  | Hook | Trigger | Script | Action |
270
270
  |------|---------|--------|--------|
@@ -282,6 +282,7 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
282
282
  | PostToolUse | After any tool | `governance-capture.sh` | Log security-sensitive operations |
283
283
  | Stop | After response | `quality-check.sh` | Multi-language lint |
284
284
  | Stop | After response | `save-session.sh` | Persist session context |
285
+ | Stop | Before final stop | `quality-gate.sh` | Block final response on lint/type errors |
285
286
  | TaskCompleted | Agent Teams: task done | `quality-gate.sh` | Block completion on errors |
286
287
  | TeammateIdle | Agent Teams: idle | *(inline)* | Completeness reminder |
287
288
  | SubagentStart | Subagent spawn | `subagent-start.sh` | Scope reminder for subagents |
@@ -3,9 +3,9 @@ title: "Hooks Catalog"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [hooks, quality, safety, enforcement, settings.json]
6
- version: "1.5.0"
6
+ version: "1.5.1"
7
7
  created: "2026-03-27"
8
- last_updated: "2026-04-24"
8
+ last_updated: "2026-05-12"
9
9
  description: "Complete reference of all ai-toolkit hooks: events, scripts, installation, and runtime behavior."
10
10
  ---
11
11
 
@@ -13,7 +13,7 @@ description: "Complete reference of all ai-toolkit hooks: events, scripts, insta
13
13
 
14
14
  ## Overview
15
15
 
16
- ai-toolkit provides 21 global hook entries across 12 lifecycle events that enforce quality, safety, and workflow rules across all Claude Code sessions. Hooks are merged into `~/.claude/settings.json` on install, with logic in standalone scripts at `~/.softspark/ai-toolkit/hooks/`.
16
+ ai-toolkit provides 22 global hook entries across 12 lifecycle events that enforce quality, safety, and workflow rules across all Claude Code sessions. Hooks are merged into `~/.claude/settings.json` on install, with logic in standalone scripts at `~/.softspark/ai-toolkit/hooks/`.
17
17
 
18
18
  ## Supported Surface
19
19
 
@@ -164,6 +164,19 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
164
164
 
165
165
  Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
166
166
 
167
+ ### Stop (quality gate) — `quality-gate.sh`
168
+
169
+ | Field | Value |
170
+ |-------|-------|
171
+ | Event | `Stop` |
172
+ | Matcher | *(all)* |
173
+ | Script | `~/.softspark/ai-toolkit/hooks/quality-gate.sh` |
174
+ | Fires | Before Claude is allowed to finish a response |
175
+
176
+ **Action:** Runs lint/typecheck. **Blocks stopping (exit 2)** if errors found, so Claude must continue and fix the issues. Missing local tooling is reported as skipped rather than blocking the session.
177
+
178
+ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
179
+
167
180
  ### TaskCompleted — `quality-gate.sh`
168
181
 
169
182
  | Field | Value |
@@ -362,7 +375,7 @@ Set in `.claude/settings.local.json`:
362
375
  ├── PreToolUse → guard-destructive.sh, guard-path.sh, guard-config.sh, commit-quality.sh
363
376
  ├── UserPromptSubmit → user-prompt-submit.sh, track-usage.sh
364
377
  ├── PostToolUse → post-tool-use.sh, governance-capture.sh
365
- ├── Stop → quality-check.sh, save-session.sh
378
+ ├── Stop → quality-check.sh, save-session.sh, quality-gate.sh
366
379
  ├── TaskCompleted → quality-gate.sh
367
380
  ├── TeammateIdle → echo (inline)
368
381
  ├── SubagentStart → subagent-start.sh
@@ -4,7 +4,7 @@ category: reference
4
4
  service: ai-toolkit
5
5
  tags: [features, differentiators, constitution, hooks, security, tdd, memory]
6
6
  created: "2026-04-13"
7
- last_updated: "2026-04-13"
7
+ last_updated: "2026-05-12"
8
8
  description: "Detailed description of ai-toolkit's unique features: constitution enforcement, hooks system, security scanning, effort budgeting, quality gates, and more."
9
9
  ---
10
10
 
@@ -12,7 +12,7 @@ description: "Detailed description of ai-toolkit's unique features: constitution
12
12
 
13
13
  ## 1. Machine-Enforced Constitution
14
14
 
15
- Unlike other toolkits that put safety rules in documentation only, ai-toolkit enforces a 5-article constitution via `PreToolUse` hooks. The hook actually **blocks** execution of:
15
+ Unlike other toolkits that put safety rules in documentation only, ai-toolkit enforces a 6-article constitution via hooks. The hooks actually **block** execution of:
16
16
  - Mass deletion (`rm -rf`, `DROP TABLE`)
17
17
  - Blind overwrites of uncommitted work
18
18
  - Any action that could cause irreversible data loss
@@ -21,7 +21,7 @@ Unlike other toolkits that put safety rules in documentation only, ai-toolkit en
21
21
 
22
22
  Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are copied to `~/.softspark/ai-toolkit/hooks/` on install and referenced from `~/.claude/settings.json`. Easy to read, debug, and extend.
23
23
 
24
- **12 lifecycle events / 21 global hook entries:**
24
+ **12 lifecycle events / 22 global hook entries:**
25
25
 
26
26
  | Event | Script | Action |
27
27
  |-------|--------|--------|
@@ -39,6 +39,7 @@ Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are
39
39
  | PostToolUse | `governance-capture.sh` | Log security-sensitive operations to JSONL |
40
40
  | Stop | `quality-check.sh` | Multi-language lint (ruff/tsc/phpstan/dart/go) |
41
41
  | Stop | `save-session.sh` | Persist session context for cross-session continuity |
42
+ | Stop | `quality-gate.sh` | Block final response on lint/type errors |
42
43
  | TaskCompleted | `quality-gate.sh` | Block task completion on lint/type errors |
43
44
  | SubagentStart | `subagent-start.sh` | Narrow-scope reminder for spawned subagents |
44
45
  | SubagentStop | `subagent-stop.sh` | Completion checklist for subagent handoff |
package/llms-full.txt CHANGED
@@ -6091,9 +6091,9 @@ title: "AI Toolkit - Architecture Overview"
6091
6091
  category: reference
6092
6092
  service: ai-toolkit
6093
6093
  tags: [architecture, overview, design, structure]
6094
- version: "1.4.4"
6094
+ version: "1.4.5"
6095
6095
  created: "2026-03-23"
6096
- last_updated: "2026-04-15"
6096
+ last_updated: "2026-05-12"
6097
6097
  description: "Architecture of ai-toolkit: directory layout, global install model, editor-aware MCP install, Codex translation layer, skill tiers, and integration with projects."
6098
6098
  ---
6099
6099
 
@@ -6352,7 +6352,7 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
6352
6352
 
6353
6353
  ## Quality Hooks
6354
6354
 
6355
- 21 entries across 12 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
6355
+ 22 entries across 12 lifecycle events. See [hooks-catalog.md](hooks-catalog.md) for full details.
6356
6356
 
6357
6357
  | Hook | Trigger | Script | Action |
6358
6358
  |------|---------|--------|--------|
@@ -6370,6 +6370,7 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
6370
6370
  | PostToolUse | After any tool | `governance-capture.sh` | Log security-sensitive operations |
6371
6371
  | Stop | After response | `quality-check.sh` | Multi-language lint |
6372
6372
  | Stop | After response | `save-session.sh` | Persist session context |
6373
+ | Stop | Before final stop | `quality-gate.sh` | Block final response on lint/type errors |
6373
6374
  | TaskCompleted | Agent Teams: task done | `quality-gate.sh` | Block completion on errors |
6374
6375
  | TeammateIdle | Agent Teams: idle | *(inline)* | Completeness reminder |
6375
6376
  | SubagentStart | Subagent spawn | `subagent-start.sh` | Scope reminder for subagents |
@@ -8757,9 +8758,9 @@ title: "Hooks Catalog"
8757
8758
  category: reference
8758
8759
  service: ai-toolkit
8759
8760
  tags: [hooks, quality, safety, enforcement, settings.json]
8760
- version: "1.5.0"
8761
+ version: "1.5.1"
8761
8762
  created: "2026-03-27"
8762
- last_updated: "2026-04-24"
8763
+ last_updated: "2026-05-12"
8763
8764
  description: "Complete reference of all ai-toolkit hooks: events, scripts, installation, and runtime behavior."
8764
8765
  ---
8765
8766
 
@@ -8767,7 +8768,7 @@ description: "Complete reference of all ai-toolkit hooks: events, scripts, insta
8767
8768
 
8768
8769
  ## Overview
8769
8770
 
8770
- ai-toolkit provides 21 global hook entries across 12 lifecycle events that enforce quality, safety, and workflow rules across all Claude Code sessions. Hooks are merged into `~/.claude/settings.json` on install, with logic in standalone scripts at `~/.softspark/ai-toolkit/hooks/`.
8771
+ ai-toolkit provides 22 global hook entries across 12 lifecycle events that enforce quality, safety, and workflow rules across all Claude Code sessions. Hooks are merged into `~/.claude/settings.json` on install, with logic in standalone scripts at `~/.softspark/ai-toolkit/hooks/`.
8771
8772
 
8772
8773
  ## Supported Surface
8773
8774
 
@@ -8918,6 +8919,19 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
8918
8919
 
8919
8920
  Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
8920
8921
 
8922
+ ### Stop (quality gate) — `quality-gate.sh`
8923
+
8924
+ | Field | Value |
8925
+ |-------|-------|
8926
+ | Event | `Stop` |
8927
+ | Matcher | *(all)* |
8928
+ | Script | `~/.softspark/ai-toolkit/hooks/quality-gate.sh` |
8929
+ | Fires | Before Claude is allowed to finish a response |
8930
+
8931
+ **Action:** Runs lint/typecheck. **Blocks stopping (exit 2)** if errors found, so Claude must continue and fix the issues. Missing local tooling is reported as skipped rather than blocking the session.
8932
+
8933
+ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
8934
+
8921
8935
  ### TaskCompleted — `quality-gate.sh`
8922
8936
 
8923
8937
  | Field | Value |
@@ -9116,7 +9130,7 @@ Set in `.claude/settings.local.json`:
9116
9130
  ├── PreToolUse → guard-destructive.sh, guard-path.sh, guard-config.sh, commit-quality.sh
9117
9131
  ├── UserPromptSubmit → user-prompt-submit.sh, track-usage.sh
9118
9132
  ├── PostToolUse → post-tool-use.sh, governance-capture.sh
9119
- ├── Stop → quality-check.sh, save-session.sh
9133
+ ├── Stop → quality-check.sh, save-session.sh, quality-gate.sh
9120
9134
  ├── TaskCompleted → quality-gate.sh
9121
9135
  ├── TeammateIdle → echo (inline)
9122
9136
  ├── SubagentStart → subagent-start.sh
@@ -11749,7 +11763,7 @@ category: reference
11749
11763
  service: ai-toolkit
11750
11764
  tags: [features, differentiators, constitution, hooks, security, tdd, memory]
11751
11765
  created: "2026-04-13"
11752
- last_updated: "2026-04-13"
11766
+ last_updated: "2026-05-12"
11753
11767
  description: "Detailed description of ai-toolkit's unique features: constitution enforcement, hooks system, security scanning, effort budgeting, quality gates, and more."
11754
11768
  ---
11755
11769
 
@@ -11757,7 +11771,7 @@ description: "Detailed description of ai-toolkit's unique features: constitution
11757
11771
 
11758
11772
  ## 1. Machine-Enforced Constitution
11759
11773
 
11760
- Unlike other toolkits that put safety rules in documentation only, ai-toolkit enforces a 5-article constitution via `PreToolUse` hooks. The hook actually **blocks** execution of:
11774
+ Unlike other toolkits that put safety rules in documentation only, ai-toolkit enforces a 6-article constitution via hooks. The hooks actually **block** execution of:
11761
11775
  - Mass deletion (`rm -rf`, `DROP TABLE`)
11762
11776
  - Blind overwrites of uncommitted work
11763
11777
  - Any action that could cause irreversible data loss
@@ -11766,7 +11780,7 @@ Unlike other toolkits that put safety rules in documentation only, ai-toolkit en
11766
11780
 
11767
11781
  Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are copied to `~/.softspark/ai-toolkit/hooks/` on install and referenced from `~/.claude/settings.json`. Easy to read, debug, and extend.
11768
11782
 
11769
- **12 lifecycle events / 21 global hook entries:**
11783
+ **12 lifecycle events / 22 global hook entries:**
11770
11784
 
11771
11785
  | Event | Script | Action |
11772
11786
  |-------|--------|--------|
@@ -11784,6 +11798,7 @@ Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are
11784
11798
  | PostToolUse | `governance-capture.sh` | Log security-sensitive operations to JSONL |
11785
11799
  | Stop | `quality-check.sh` | Multi-language lint (ruff/tsc/phpstan/dart/go) |
11786
11800
  | Stop | `save-session.sh` | Persist session context for cross-session continuity |
11801
+ | Stop | `quality-gate.sh` | Block final response on lint/type errors |
11787
11802
  | TaskCompleted | `quality-gate.sh` | Block task completion on lint/type errors |
11788
11803
  | SubagentStart | `subagent-start.sh` | Narrow-scope reminder for spawned subagents |
11789
11804
  | SubagentStop | `subagent-stop.sh` | Completion checklist for subagent handoff |
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.2.0",
2
+ "version": "4.2.1",
3
3
  "components": {
4
4
  "agents": {
5
5
  "description": "44 specialized agents (orchestrator, backend, frontend, security, devops, etc.)",
@@ -16,7 +16,7 @@
16
16
  "tags": ["core", "skills", "commands"]
17
17
  },
18
18
  "hooks": {
19
- "description": "21 global hook entries across 12 lifecycle events + 5 skill-scoped lifecycle hooks",
19
+ "description": "22 global hook entries across 12 lifecycle events + 5 skill-scoped lifecycle hooks",
20
20
  "path": "app/hooks.json + app/hooks/*.sh",
21
21
  "target": "~/.claude/settings.json (merge) + ~/.softspark/ai-toolkit/hooks/ (copy)",
22
22
  "type": "merge+copy",
@@ -30,7 +30,7 @@
30
30
  "tags": ["plugins", "packs", "experimental"]
31
31
  },
32
32
  "constitution": {
33
- "description": "5-article machine-enforced safety constitution",
33
+ "description": "6-article machine-enforced safety constitution",
34
34
  "path": "app/constitution.md",
35
35
  "target": ".claude/constitution.md",
36
36
  "type": "symlink",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softspark/ai-toolkit",
3
- "version": "4.2.0",
3
+ "version": "4.2.1",
4
4
  "description": "AI coding toolkit: 107 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",
@@ -65,11 +65,49 @@ def _is_toolkit_entry(entry: dict) -> bool:
65
65
  return False
66
66
 
67
67
 
68
- def strip_toolkit(hooks: dict) -> dict:
69
- """Remove all entries tagged with _source == SOURCE_TAG."""
68
+ def _entry_signature(entry: dict) -> tuple:
69
+ """Return the behavior-defining parts of a hook entry.
70
+
71
+ Older ai-toolkit installs wrote hook entries without ``_source``. Matching
72
+ on the event, matcher, and handler payload lets current installs remove
73
+ those legacy duplicates while preserving unrelated user hooks.
74
+ """
75
+ handlers = []
76
+ for hook in entry.get("hooks", []):
77
+ if not isinstance(hook, dict):
78
+ handlers.append(hook)
79
+ continue
80
+ handlers.append(tuple(sorted(
81
+ (key, value)
82
+ for key, value in hook.items()
83
+ if key != "_source"
84
+ )))
85
+ return (entry.get("matcher", ""), tuple(handlers))
86
+
87
+
88
+ def strip_toolkit(hooks: dict, toolkit_hooks: dict | None = None) -> dict:
89
+ """Remove entries tagged with ai-toolkit or matching legacy toolkit hooks."""
90
+ legacy_signatures: dict[str, set[tuple]] = {}
91
+ if toolkit_hooks:
92
+ for event, entries in toolkit_hooks.items():
93
+ legacy_signatures[event] = {
94
+ _entry_signature(entry)
95
+ for entry in entries
96
+ if isinstance(entry, dict)
97
+ }
98
+
70
99
  result = {}
71
100
  for event, entries in hooks.items():
72
- filtered = [e for e in entries if not _is_toolkit_entry(e)]
101
+ signatures = legacy_signatures.get(event, set())
102
+ filtered = [
103
+ e
104
+ for e in entries
105
+ if not _is_toolkit_entry(e)
106
+ and not (
107
+ isinstance(e, dict)
108
+ and _entry_signature(e) in signatures
109
+ )
110
+ ]
73
111
  if filtered:
74
112
  result[event] = filtered
75
113
  return result
@@ -85,7 +123,7 @@ def merge(toolkit_hooks: dict, target_hooks: dict) -> dict:
85
123
  Returns:
86
124
  Merged hooks dictionary with old toolkit entries replaced by new ones.
87
125
  """
88
- merged = strip_toolkit(target_hooks)
126
+ merged = strip_toolkit(target_hooks, toolkit_hooks)
89
127
  for event, entries in toolkit_hooks.items():
90
128
  if event not in merged:
91
129
  merged[event] = []