@softspark/ai-toolkit 4.3.3 → 4.4.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,60 @@ Versioning follows [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## v4.4.1 - Codex hook output compatibility fix (2026-05-25)
11
+
12
+ Patch release. Fixes Codex `UserPromptSubmit` hook JSON validation failures and visible hook-context noise while preserving hook side effects.
13
+
14
+ ### Fixed
15
+
16
+ - **Codex `UserPromptSubmit` default output** - generated Codex hooks now keep `user-prompt-submit.sh` in quiet plain-text mode, preserving search-first flag side effects without emitting visible `additionalContext` in the Codex TUI.
17
+ - **Event-specific JSON context** - `hook_emit_context` can include `hookSpecificOutput.hookEventName`, and `user-prompt-submit.sh` emits `"UserPromptSubmit"` with `additionalContext` when JSON context mode is explicitly enabled.
18
+ - **Prompt hook output corruption** - `user-prompt-submit.sh` now suppresses filesystem redirection errors when search-first state writes are blocked by sandboxing or local permissions, keeping JSON output parseable.
19
+ - **Usage tracking tracebacks** - `track-usage.sh` now treats stats writes as best-effort and suppresses Python tracebacks when `~/.softspark/ai-toolkit/stats.json` cannot be written.
20
+
21
+ ### Verification
22
+
23
+ - `bats tests/test_hooks.bats --filter 'track-usage|user-prompt-submit|post-tool-use'`
24
+ - `python3 scripts/validate.py --strict`
25
+
26
+ ## v4.4.0 - native editor skill pointers and hook governance hardening (2026-05-25)
27
+
28
+ Minor release. Adds native skill pointer generation for more editor surfaces and hardens search-first governance so quiet hooks still inject model context without noisy transcript output.
29
+
30
+ ### Added
31
+
32
+ - **Native editor skill pointers** - Added Cursor, Windsurf, and Cline skill pointer generators so supported editors can discover the ai-toolkit skill catalog through their native skill directories.
33
+ - **Shared skill pointer builder** - Added `scripts/skill_pointer.py` to keep generated skill pointer metadata consistent across editor-specific generators.
34
+ - **Release coverage** - Added generator and hook tests covering the new skill pointer outputs, quiet JSON `UserPromptSubmit` context, and noisy Codex search-first log fallback.
35
+
36
+ ### Changed
37
+
38
+ - **Editor registry and install flow** - Updated supported-tool metadata and install behavior for Cursor, Windsurf, and Cline native skill pointer targets.
39
+ - **Codex hook generation** - `scripts/generate_codex_hooks.py` now emits quiet JSON context for `user-prompt-submit.sh`, matching Claude Code's installed hook behavior.
40
+ - **Hook runtime documentation** - Updated the hooks catalog, Codex compatibility notes, global install model, supported tools registry, and maintenance SOP with the new runtime behavior.
41
+
42
+ ### Fixed
43
+
44
+ - **Quiet hook context injection** - `_hook-io.sh` now lets `AI_TOOLKIT_HOOK_FORMAT=json` emit `hookSpecificOutput.additionalContext` even when `AI_TOOLKIT_HOOK_QUIET=1` is set.
45
+ - **Search-first false positives in Codex** - `stop-search-check.sh` now scans a larger recent Codex log window and recognizes both `ToolCall: mcp__...__smart_query` and `tool.name="smart_query"` log shapes.
46
+ - **Installed runtime drift** - Claude and Codex hook manifests now install `UserPromptSubmit` with `AI_TOOLKIT_HOOK_QUIET=1 AI_TOOLKIT_HOOK_FORMAT=json`.
47
+
48
+ ### Ecosystem
49
+
50
+ - **Snapshot refresh** - Refreshed the ecosystem doctor snapshot after upstream documentation/content drift review and generator updates.
51
+
52
+ ### Verification
53
+
54
+ - `bats tests/test_generators.bats`
55
+ - `bats tests/test_cli.bats`
56
+ - `bats tests/test_skills_native.bats tests/test_native_surfaces.bats`
57
+ - `bats tests/test_hooks.bats tests/test_search_first_flow.bats`
58
+ - `bats tests/test_install.bats tests/test_codex.bats`
59
+ - `python3 scripts/validate.py --strict`
60
+ - `git diff --check`
61
+
62
+ ---
63
+
10
64
  ## v4.3.3 - silent hook context roll-forward (2026-05-21)
11
65
 
12
66
  Patch release. Rolls forward the quiet-hook release with a stricter default: non-blocking plain-text hook context is now silent even when a runtime uses a stale or manually copied command without `AI_TOOLKIT_HOOK_QUIET=1`.
package/README.md CHANGED
@@ -6,16 +6,17 @@
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-1144%20passing-success)](tests/)
9
+ [![Tests](https://img.shields.io/badge/tests-1151%20passing-success)](tests/)
10
10
 
11
- ## What's New in v4.3.3
11
+ ## What's New in v4.4.1
12
12
 
13
- Patch release. Rolls forward quiet hook handling so informational hook context stays out of the visible chat window even with stale or manually copied hook commands.
13
+ Patch release. Fixes Codex `UserPromptSubmit` hook output validation and visible hook-context noise while preserving hook side effects.
14
14
 
15
- - **Silent hook context by default**: `SessionStart`, `UserPromptSubmit`, and other non-blocking plain-text context output now require `AI_TOOLKIT_HOOK_VERBOSE=1`.
16
- - **Side effects preserved**: search-first flags, session-state reset, stale-flag cleanup, and blocking decisions still run without printing reminder text.
17
- - **Runtime refresh applied**: installed hook scripts and Codex/Claude hook config pick up the silent default.
18
- - **Test coverage updated**: hook tests now cover default silence and verbose opt-in, bringing the suite to 1144 tests.
15
+ - **Codex-safe prompt hook defaults**: generated Codex hooks keep `UserPromptSubmit` side effects quiet without emitting visible `additionalContext` in the TUI.
16
+ - **Event-specific hook context**: JSON context output now includes `hookSpecificOutput.hookEventName` when enabled, matching Codex's event-specific schema.
17
+ - **Silent best-effort stats**: `track-usage.sh` no longer leaks Python tracebacks when local stats writes are blocked.
18
+ - **Sandbox-safe search flags**: search-first flag write failures no longer corrupt JSON hook output.
19
+ - **Release coverage updated**: hook regression coverage now includes blocked state and stats writes; suite count is 1151 tests.
19
20
 
20
21
  See [CHANGELOG.md](CHANGELOG.md) for full history.
21
22
 
@@ -101,11 +102,11 @@ See [CLI Reference](kb/reference/cli-reference.md) for all commands and options.
101
102
  | Platform | Config Files | Scope |
102
103
  |----------|-------------|-------|
103
104
  | Claude Code | `~/.claude/` | global |
104
- | Cursor | `.cursor/rules/*.mdc` + `.cursor/mcp.json` | project (`~/.cursor/mcp.json` for MCP only) |
105
- | Windsurf | `~/.codeium/.../global_rules.md` + `.windsurf/rules/*.md` | global + project |
105
+ | Cursor | `.cursor/rules/*.mdc` + `.cursor/mcp.json` + `.cursor/skills/*` | project (`~/.cursor/mcp.json` for MCP only) |
106
+ | Windsurf | `~/.codeium/.../global_rules.md` + `~/.codeium/windsurf/skills/*` + `.windsurf/rules/*.md` | global + project |
106
107
  | Gemini CLI | `~/.gemini/GEMINI.md` | global |
107
108
  | GitHub Copilot | `.github/copilot-instructions.md` | project |
108
- | Cline | `~/Documents/Cline/Rules/*.md` + `.clinerules/*.md` | global + project |
109
+ | Cline | `~/.cline/rules/*.md` + `~/.cline/skills/*` + `.clinerules/*.md` | global + project |
109
110
  | Roo Code | `~/.roo/rules/*.md` + `.roomodes` + `.roo/rules/*.md` | global rules + project |
110
111
  | Aider | `~/.aider.conf.yml` + `.aider.conf.yml` + `CONVENTIONS.md` | global + project |
111
112
  | Augment | `~/.augment/rules/*.md` + `.augment/rules/ai-toolkit-*.md` | global + project |
@@ -148,7 +149,7 @@ ai-toolkit/
148
149
  │ └── ARCHITECTURE.md # Full system design
149
150
  ├── kb/ # Reference docs, procedures, plans
150
151
  ├── scripts/ # Validation, install, evaluation scripts
151
- ├── tests/ # Bats test suite (1144 tests)
152
+ ├── tests/ # Bats test suite (1151 tests)
152
153
  └── CHANGELOG.md
153
154
  ```
154
155
 
@@ -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.3.3",
4
+ "version": "4.4.1",
5
5
  "author": {
6
6
  "name": "SoftSpark",
7
7
  "url": "https://github.com/softspark"
@@ -356,7 +356,7 @@ Lead Session (You)
356
356
  Language rules are propagated to **all configured editors** — not just Claude. `dir_rules_shared.build_language_rules()` reads `app/rules/<lang>/*.md`, strips frontmatter, and returns combined content per language. Each directory-based generator (Cursor, Windsurf, Cline, Roo, Augment, Antigravity, Codex) emits `ai-toolkit-lang-<lang>` files in its native format. Registered custom rules (`~/.softspark/ai-toolkit/rules/`) are similarly propagated as `ai-toolkit-custom-<name>` files via `build_registered_rules()`.
357
357
 
358
358
  ### Codex Integration
359
- Codex receives `AGENTS.md`, `.agents/rules/*.md`, optional `.agents/skills/*`, and `.codex/hooks.json`. `generate_codex_hooks.py` emits only Codex-supported lifecycle events and prefixes commands with `AI_TOOLKIT_HOOK_QUIET=1`, so informational hook context is not shown at session start or prompt submit while side effects and blocking Stop decisions still run. Claude's bundled `UserPromptSubmit` hook also runs in quiet mode for the same reason.
359
+ Codex receives `AGENTS.md`, `.agents/rules/*.md`, optional `.agents/skills/*`, and `.codex/hooks.json`. `generate_codex_hooks.py` emits only Codex-supported lifecycle events and prefixes commands with `AI_TOOLKIT_HOOK_QUIET=1`, so informational hook output is not shown at session start or prompt submit while side effects and blocking Stop decisions still run. The `UserPromptSubmit` governance hook also sets `AI_TOOLKIT_HOOK_FORMAT=json` so proactive `additionalContext` reaches the model quietly. Claude's bundled `UserPromptSubmit` hook uses the same quiet JSON context path.
360
360
 
361
361
  ### opencode Integration (v2.5.0+)
362
362
  opencode is the 11th supported editor. Five generators handle its integration surface:
@@ -57,13 +57,18 @@ hook_new_content() {
57
57
  }
58
58
 
59
59
  hook_emit_context() {
60
- local message="$1"
61
- if [ "${AI_TOOLKIT_HOOK_QUIET:-0}" = "1" ]; then
62
- return 0
63
- fi
60
+ local event="${2:+$1}"
61
+ local message="${2:-$1}"
64
62
  if [ "${AI_TOOLKIT_HOOK_FORMAT:-}" = "json" ]; then
65
- jq -nc --arg msg "$message" \
66
- '{"hookSpecificOutput":{"additionalContext":$msg},"suppressOutput":true}'
63
+ if [ -n "$event" ]; then
64
+ jq -nc --arg event "$event" --arg msg "$message" \
65
+ '{"hookSpecificOutput":{"hookEventName":$event,"additionalContext":$msg},"suppressOutput":true}'
66
+ else
67
+ jq -nc --arg msg "$message" \
68
+ '{"hookSpecificOutput":{"additionalContext":$msg},"suppressOutput":true}'
69
+ fi
70
+ elif [ "${AI_TOOLKIT_HOOK_QUIET:-0}" = "1" ]; then
71
+ return 0
67
72
  elif [ "${AI_TOOLKIT_HOOK_VERBOSE:-0}" = "1" ]; then
68
73
  printf '%s\n' "$message"
69
74
  fi
@@ -59,7 +59,10 @@ try:
59
59
  with log_path.open("rb") as handle:
60
60
  handle.seek(0, 2)
61
61
  size = handle.tell()
62
- handle.seek(max(0, size - 2_000_000))
62
+ # Codex logs can be noisy between the search call and Stop hook
63
+ # execution, especially when skill loading emits repeated warnings.
64
+ # Keep this bounded, but large enough to avoid false positives.
65
+ handle.seek(max(0, size - 20_000_000))
63
66
  lines = handle.read().decode("utf-8", errors="replace").splitlines()
64
67
  except OSError:
65
68
  sys.exit(1)
@@ -22,10 +22,10 @@ SKILL_NAME=$(printf '%s' "$PROMPT_TEXT" | grep -oE '^/[a-z][a-z0-9-]*' | head -1
22
22
  [ -z "$SKILL_NAME" ] && exit 0
23
23
 
24
24
  # Ensure directory exists
25
- mkdir -p "$(dirname "$STATS_FILE")"
25
+ mkdir -p "$(dirname "$STATS_FILE")" 2>/dev/null || true
26
26
 
27
27
  # Atomic update via python3
28
- python3 - "$STATS_FILE" "$SKILL_NAME" <<'PY'
28
+ python3 - "$STATS_FILE" "$SKILL_NAME" 2>/dev/null <<'PY' || true
29
29
  import json
30
30
  import sys
31
31
  import os
@@ -28,9 +28,9 @@ mkdir -p "$STATE_DIR" 2>/dev/null
28
28
  if [ "$PROMPT_LEN" -gt 30 ] && \
29
29
  [ "${CLAUDE_SKIP_SEARCH_FIRST:-0}" != "1" ] && \
30
30
  ai_toolkit_has_search_provider; then
31
- printf '%s\n%s\n' "$(date -u +%s)" "$PROMPT_TEXT" > "$FLAG" 2>/dev/null
31
+ { printf '%s\n%s\n' "$(date -u +%s)" "$PROMPT_TEXT" > "$FLAG"; } 2>/dev/null
32
32
  else
33
- rm -f "$FLAG" 2>/dev/null
33
+ { rm -f "$FLAG"; } 2>/dev/null
34
34
  fi
35
35
 
36
36
  if ai_toolkit_has_search_provider; then
@@ -50,6 +50,6 @@ else
50
50
  UserPromptSubmit: apply KB-first research, keep changes minimal, and update tests/docs when behavior changes."
51
51
  fi
52
52
 
53
- hook_emit_context "$CONTEXT_MSG"
53
+ hook_emit_context "UserPromptSubmit" "$CONTEXT_MSG"
54
54
 
55
55
  exit 0
package/app/hooks.json CHANGED
@@ -103,7 +103,7 @@
103
103
  "hooks": [
104
104
  {
105
105
  "type": "command",
106
- "command": "AI_TOOLKIT_HOOK_QUIET=1 \"$HOME/.softspark/ai-toolkit/hooks/user-prompt-submit.sh\""
106
+ "command": "AI_TOOLKIT_HOOK_QUIET=1 AI_TOOLKIT_HOOK_FORMAT=json \"$HOME/.softspark/ai-toolkit/hooks/user-prompt-submit.sh\""
107
107
  }
108
108
  ]
109
109
  },
@@ -1,5 +1,5 @@
1
1
  {
2
- "last_run": "2026-05-21T08:27:23Z",
2
+ "last_run": "2026-05-25T11:12:53Z",
3
3
  "schema_version": 1,
4
4
  "tools": {
5
5
  "aider": {
@@ -24,14 +24,21 @@
24
24
  }
25
25
  },
26
26
  "augment": {
27
- "docs_hash": "8be23f4fb78816c3",
27
+ "docs_hash": "2546ce56fc2d92e4",
28
28
  "headings": [
29
+ "Admin",
30
+ "Auggie CLI",
29
31
  "Code",
32
+ "Cosmos",
30
33
  "Documentation Index",
34
+ "Getting Started",
31
35
  "Introduction",
36
+ "Models &amp; Pricing",
32
37
  "On this page",
33
38
  "Other automation",
39
+ "Other clients",
34
40
  "Review",
41
+ "Troubleshooting",
35
42
  "\u200bAuggie CLI",
36
43
  "\u200bAutomate your SDLC",
37
44
  "\u200bCosmos",
@@ -58,7 +65,7 @@
58
65
  }
59
66
  },
60
67
  "claude-code": {
61
- "docs_hash": "0518086bd4527849",
68
+ "docs_hash": "78dbdbf9b1b09fe8",
62
69
  "headings": [
63
70
  "Documentation Index",
64
71
  "On this page",
@@ -105,15 +112,20 @@
105
112
  "slash command": true,
106
113
  "sub-agent": true
107
114
  },
108
- "version": "2.1.146 (Claude Code)"
115
+ "version": "2.1.150 (Claude Code)"
109
116
  },
110
117
  "cline": {
111
- "docs_hash": "c2ce2443743365fa",
118
+ "docs_hash": "0d30b8f46cb45976",
112
119
  "headings": [
113
120
  "API Reference",
121
+ "Best Practices",
114
122
  "CLI",
115
123
  "Cline Overview",
124
+ "Configurations",
116
125
  "Documentation Index",
126
+ "Features",
127
+ "Getting Started",
128
+ "IDE Specific Features",
117
129
  "JetBrains Plugin",
118
130
  "Kanban",
119
131
  "Observability",
@@ -121,6 +133,8 @@
121
133
  "SDK",
122
134
  "Security &amp; Governance",
123
135
  "Team Management",
136
+ "Troubleshooting",
137
+ "Usage",
124
138
  "VS Code Extension",
125
139
  "\u200bAgent Core (SDK)",
126
140
  "\u200bApplications",
@@ -142,7 +156,7 @@
142
156
  }
143
157
  },
144
158
  "codex-cli": {
145
- "docs_hash": "70f184b6cdd1f765",
159
+ "docs_hash": "8cad495445dd03e0",
146
160
  "headings": [
147
161
  "About",
148
162
  "Contributing",
@@ -161,7 +175,7 @@
161
175
  "Packages 0",
162
176
  "Provide feedback",
163
177
  "Quickstart",
164
- "Releases 795",
178
+ "Releases 799",
165
179
  "Repository files navigation",
166
180
  "Resources",
167
181
  "Saved searches",
@@ -191,10 +205,10 @@
191
205
  "mcp_servers": false,
192
206
  "sandbox": true
193
207
  },
194
- "version": "codex-cli 0.132.0"
208
+ "version": "codex-cli 0.133.0"
195
209
  },
196
210
  "cursor": {
197
- "docs_hash": "60edb30c9ddcdadd",
211
+ "docs_hash": "56c9209877480e01",
198
212
  "headings": [],
199
213
  "markers": {
200
214
  ".cursor/rules": false,
@@ -210,7 +224,7 @@
210
224
  }
211
225
  },
212
226
  "gemini-cli": {
213
- "docs_hash": "c6aab087667f7717",
227
+ "docs_hash": "6a47f9b11ff1527d",
214
228
  "headings": [
215
229
  "Breadcrumbs",
216
230
  "Directory actions",
@@ -249,7 +263,7 @@
249
263
  }
250
264
  },
251
265
  "github-copilot": {
252
- "docs_hash": "ab274112faeec90f",
266
+ "docs_hash": "a5b81592ca646743",
253
267
  "headings": [
254
268
  "About Copilot auto model selection",
255
269
  "About Copilot integrations",
@@ -281,7 +295,7 @@
281
295
  }
282
296
  },
283
297
  "google-antigravity": {
284
- "docs_hash": "2c48c702b9e592a7",
298
+ "docs_hash": "6f089d2c7caabceb",
285
299
  "headings": [],
286
300
  "markers": {
287
301
  "AGENTS.md": false,
@@ -297,7 +311,7 @@
297
311
  }
298
312
  },
299
313
  "opencode": {
300
- "docs_hash": "5277673e235393f7",
314
+ "docs_hash": "74eb2d934df9b613",
301
315
  "headings": [
302
316
  "Add features",
303
317
  "Ask questions",
@@ -357,18 +371,23 @@
357
371
  }
358
372
  },
359
373
  "windsurf": {
360
- "docs_hash": "fa29ba621f291d81",
374
+ "docs_hash": "eddf51fabbcaa0a3",
361
375
  "headings": [
376
+ "Accounts",
362
377
  "Advanced",
378
+ "Agent Command Center",
363
379
  "App Deploys",
364
380
  "Cascade",
365
381
  "Context Awareness",
366
382
  "Documentation Index",
383
+ "Editor",
367
384
  "MCP",
368
385
  "Memories",
369
386
  "On this page",
370
387
  "Recommended Plugins",
388
+ "Security",
371
389
  "Terminal",
390
+ "Troubleshooting",
372
391
  "Usage",
373
392
  "Welcome to Windsurf",
374
393
  "Workflows",
@@ -390,11 +409,13 @@
390
409
  "AGENTS.md": true,
391
410
  "Cascade": true,
392
411
  "MCP": true,
412
+ "SKILL.md": false,
393
413
  "always_on": false,
394
414
  "glob": true,
395
415
  "hooks": true,
396
416
  "memories": true,
397
417
  "model_decision": false,
418
+ "skills": true,
398
419
  "windsurfrules": false,
399
420
  "workflows": true
400
421
  }
@@ -3,9 +3,9 @@ title: "SOP: Claude Toolkit Maintenance"
3
3
  category: procedures
4
4
  service: ai-toolkit
5
5
  tags: [sop, maintenance, agents, skills, install]
6
- version: "3.0.0"
6
+ version: "3.0.1"
7
7
  created: "2026-03-23"
8
- last_updated: "2026-04-23"
8
+ last_updated: "2026-05-25"
9
9
  description: "Standard operating procedures for installing, maintaining, and evolving the ai-toolkit."
10
10
  ---
11
11
 
@@ -34,7 +34,7 @@ ai-toolkit install --local --editors all # all supported editor
34
34
  ai-toolkit install --local --editors cursor,aider # specific editors only
35
35
  ```
36
36
 
37
- Supported editors: `cursor`, `windsurf`, `cline`, `roo`, `aider`, `augment`, `copilot`, `antigravity`, `codex`.
37
+ Supported editors: `cursor`, `windsurf`, `cline`, `roo`, `aider`, `augment`, `copilot`, `antigravity`, `codex`, `gemini`, `opencode`.
38
38
 
39
39
  To restrict which language rules are injected, use `--lang`:
40
40
 
@@ -202,6 +202,43 @@ Manual path:
202
202
 
203
203
  Use `PreToolUse` for blocking validations, `PostToolUse` for non-blocking feedback, `UserPromptSubmit` for prompt governance, and `PreCompact` / `SessionEnd` for context preservation and handoff.
204
204
 
205
+ ## Troubleshooting Rule Enforcement in Claude Code
206
+
207
+ Use this when Claude appears to ignore `CLAUDE.md`, `.claude/rules/*.md`, output styles, or search-first rules.
208
+
209
+ 1. **Check current Claude docs first.** Confirm the live contract for memory, settings, output styles, and hooks:
210
+ - `https://code.claude.com/docs/en/memory`
211
+ - `https://code.claude.com/docs/en/settings`
212
+ - `https://code.claude.com/docs/en/output-styles`
213
+ - `https://code.claude.com/docs/en/hooks`
214
+ 2. **Verify instruction loading.** Run `/memory` in Claude Code and confirm the expected `CLAUDE.md`, `CLAUDE.local.md`, and `.claude/rules/*.md` files are listed. Remember that Claude Code reads `CLAUDE.md`, not `AGENTS.md`, unless `CLAUDE.md` imports it.
215
+ 3. **Verify the active output style.** Check `.claude/settings.local.json` or `/config`. Output style changes apply after `/clear` or a new session.
216
+ 4. **Inspect installed hooks.** Ensure `~/.claude/settings.json` contains the ai-toolkit `UserPromptSubmit` and `Stop` entries. The governance hook must run with `AI_TOOLKIT_HOOK_QUIET=1 AI_TOOLKIT_HOOK_FORMAT=json` so it injects `additionalContext` without noisy transcript output.
217
+ 5. **Reproduce the hook path directly.**
218
+ ```bash
219
+ printf '{"session_id":"debug","prompt":"debug this technical rule issue"}' \
220
+ | AI_TOOLKIT_SEARCH_FIRST=strict AI_TOOLKIT_HOOK_QUIET=1 AI_TOOLKIT_HOOK_FORMAT=json \
221
+ ~/.softspark/ai-toolkit/hooks/user-prompt-submit.sh
222
+ ```
223
+ The output must be valid JSON with `hookSpecificOutput.additionalContext`.
224
+ 6. **Check corrective enforcement.** If the assistant still skips required research, `stop-search-check.sh` should block Stop with the search-first message. If it does not, inspect `~/.softspark/ai-toolkit/state/search-required-*.flag` and the Codex/Claude transcript logs.
225
+ 7. **Repair drift.** Run:
226
+ ```bash
227
+ ai-toolkit update --only hooks
228
+ python3 scripts/ecosystem_doctor.py --tool claude-code --format text
229
+ scripts/validate.py
230
+ ```
231
+
232
+ ## Verification
233
+
234
+ After changing rule-enforcement behavior, run at minimum:
235
+
236
+ ```bash
237
+ bats tests/test_hooks.bats tests/test_search_first_flow.bats
238
+ bats tests/test_install.bats tests/test_codex.bats
239
+ python3 scripts/validate.py --strict
240
+ ```
241
+
205
242
  ## Managing Plugins
206
243
 
207
244
  ```bash
@@ -105,11 +105,11 @@ Machine (global) Project (local)
105
105
  **`ai-toolkit update`** — re-apply after `npm install -g @softspark/ai-toolkit@latest` or after `add-rule` / `remove-rule`. Same as `install` but semantically correct for update flows.
106
106
 
107
107
  **`ai-toolkit install --local`** — run per project. Always installs Claude Code configs (CLAUDE.md, settings.local.json, constitution.md, language rules). Editor configs are opt-in via `--editors`:
108
- - `--editors all` — install all 9 editors (Cursor, Windsurf, Cline, Roo, Aider, Augment, Copilot, Antigravity, Codex)
108
+ - `--editors all` — install all 11 editors (Cursor, Windsurf, Cline, Roo, Aider, Augment, Copilot, Antigravity, Codex, Gemini, opencode)
109
109
  - `--editors cursor,aider` — install only selected editors
110
110
  - (no flag) — auto-detect from existing project files; `update --local` picks up whatever editors already have configs
111
111
 
112
- Each editor gets directory-based format (`.cursor/rules/*.mdc`, `.windsurf/rules/*.md`, `.clinerules/*.md`, `.roo/rules/*.md`, `.augment/rules/ai-toolkit-*.md`, `.agent/rules/*.md`, `CONVENTIONS.md`). Codex local install additionally generates `AGENTS.md`, `.agents/rules/*.md`, `.agents/skills/*`, and `.codex/hooks.json`. Hooks are global-only — not merged into project settings except for editor-native local hook files such as Codex `.codex/hooks.json`. Experimental plugin packs can also layer a global Codex target in `HOME` (`~/AGENTS.md`, `~/.agents/`, `~/.codex/hooks.json`) when installed with `ai-toolkit plugin install --editor codex`.
112
+ Each editor gets directory-based format (`.cursor/rules/*.mdc`, `.windsurf/rules/*.md`, `.clinerules/*.md`, `.roo/rules/*.md`, `.augment/rules/ai-toolkit-*.md`, `.agent/rules/*.md`, `CONVENTIONS.md`). Full-profile installs also emit native skill pointer catalogues for Cursor, Windsurf, and Cline. Codex local install additionally generates `AGENTS.md`, `.agents/rules/*.md`, `.agents/skills/*`, and `.codex/hooks.json`. Hooks are global-only — not merged into project settings except for editor-native local hook files such as Codex `.codex/hooks.json`. Experimental plugin packs can also layer a global Codex target in `HOME` (`~/AGENTS.md`, `~/.agents/`, `~/.codex/hooks.json`) when installed with `ai-toolkit plugin install --editor codex`.
113
113
 
114
114
  If a project already has `.mcp.json`, local install mirrors its `mcpServers` entries into `.claude/settings.local.json` plus any selected editors with project-scoped native MCP files (`.cursor/mcp.json`, `.github/mcp.json`).
115
115
 
@@ -3,9 +3,9 @@ title: "AI Toolkit - Codex CLI Compatibility"
3
3
  category: reference
4
4
  service: ai-toolkit
5
5
  tags: [codex, compatibility, install, skills, hooks]
6
- version: "1.0.2"
6
+ version: "1.0.3"
7
7
  created: "2026-04-12"
8
- last_updated: "2026-05-21"
8
+ last_updated: "2026-05-25"
9
9
  description: "Reference for how ai-toolkit maps Claude-oriented skills, hooks, and plugin packs to Codex CLI."
10
10
  ---
11
11
 
@@ -110,10 +110,27 @@ This means Claude-only events such as `TaskCompleted`, `TeammateIdle`,
110
110
  `~/.codex/hooks.json` (global layer). Non-Codex events are silently skipped.
111
111
  `remove-hook` cleans both Claude and Codex targets.
112
112
 
113
- Generated Codex hook commands include `AI_TOOLKIT_HOOK_QUIET=1`. This keeps
114
- non-blocking reminders and startup context out of the visible Codex hook output
115
- while preserving hook side effects and blocking decisions such as search-first
116
- Stop enforcement.
113
+ Generated Codex hook commands include `AI_TOOLKIT_HOOK_QUIET=1`. The generated
114
+ `UserPromptSubmit` governance hook does not set `AI_TOOLKIT_HOOK_FORMAT=json`
115
+ by default because Codex currently renders `additionalContext` as visible hook
116
+ context in the TUI. This keeps prompt-submit output quiet while preserving hook
117
+ side effects and blocking decisions such as search-first Stop enforcement.
118
+
119
+ Codex `UserPromptSubmit` JSON output is event-specific. When emitting context,
120
+ the hook must include the event name alongside the context:
121
+
122
+ ```json
123
+ {
124
+ "hookSpecificOutput": {
125
+ "hookEventName": "UserPromptSubmit",
126
+ "additionalContext": "..."
127
+ },
128
+ "suppressOutput": true
129
+ }
130
+ ```
131
+
132
+ Older `{"hookSpecificOutput":{"additionalContext":"..."}}` output can be valid
133
+ JSON but fail newer Codex event-output validation.
117
134
 
118
135
  Plain-text informational hook context is also silent by default in the shared
119
136
  hook helper. Set `AI_TOOLKIT_HOOK_VERBOSE=1` only when debugging hook output
@@ -133,6 +150,8 @@ Known limits:
133
150
  so `stop-search-check.sh` also checks `~/.codex/log/codex-tui.log` for
134
151
  `smart_query`, `hybrid_search_kb`, `crag_search`, `multi_hop_search`, and
135
152
  `verify_answer` calls after the search-first flag timestamp before blocking.
153
+ The scan is bounded to a recent log window, but sized to tolerate noisy Codex
154
+ skill-loader output between the search call and the Stop hook.
136
155
 
137
156
  These are runtime platform limits, not installation defects.
138
157
 
@@ -60,10 +60,10 @@ The `--profile` flag controls how much of each editor's native surface is activa
60
60
  `ai-toolkit install --editors <name>` can write global files only for editors
61
61
  with documented, file-based config surfaces:
62
62
 
63
- - `windsurf`: `~/.codeium/windsurf/memories/global_rules.md`
63
+ - `windsurf`: `~/.codeium/windsurf/memories/global_rules.md` plus `~/.codeium/windsurf/skills/ai-toolkit-skill-catalogue/SKILL.md`
64
64
  - `gemini`: `~/.gemini/GEMINI.md`
65
65
  - `augment`: `~/.augment/rules/ai-toolkit.md`
66
- - `cline`: `~/Documents/Cline/Rules/ai-toolkit-*.md`
66
+ - `cline`: `~/.cline/rules/ai-toolkit-*.md` plus `~/.cline/skills/ai-toolkit-skill-catalogue/SKILL.md`
67
67
  - `roo`: `~/.roo/rules/ai-toolkit-*.md`
68
68
  - `aider`: `~/.aider.conf.yml` plus `~/.aider-ai-toolkit-CONVENTIONS.md` when the YAML file does not already exist
69
69
  - `codex`: `~/AGENTS.md`, `~/.agents/rules/*`, `~/.agents/skills/*`, `~/.codex/hooks.json`
@@ -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.3"
6
+ version: "1.5.6"
7
7
  created: "2026-03-27"
8
- last_updated: "2026-05-21"
8
+ last_updated: "2026-05-25"
9
9
  description: "Complete reference of all ai-toolkit hooks: events, scripts, installation, and runtime behavior."
10
10
  ---
11
11
 
@@ -112,11 +112,30 @@ and can provide a lightweight governance reminder: plan mode for architectural
112
112
  work, evidence-first debugging, KB-first research, and validation expectations.
113
113
 
114
114
  Skipped when `TOOLKIT_HOOK_PROFILE=minimal`. The bundled `app/hooks.json`
115
- registers this command with `AI_TOOLKIT_HOOK_QUIET=1`, so it still arms or
116
- clears the per-session search-first flag but suppresses the informational
117
- reminder output. In plain-text mode, informational reminders are silent by
118
- default and require `AI_TOOLKIT_HOOK_VERBOSE=1`; JSON hook output remains
119
- available with `AI_TOOLKIT_HOOK_FORMAT=json`.
115
+ registers this command with `AI_TOOLKIT_HOOK_QUIET=1 AI_TOOLKIT_HOOK_FORMAT=json`.
116
+ This keeps the hook visually quiet (`suppressOutput: true`) while still
117
+ injecting event-specific JSON context before Claude starts working in runtimes
118
+ that consume hidden context:
119
+
120
+ ```json
121
+ {
122
+ "hookSpecificOutput": {
123
+ "hookEventName": "UserPromptSubmit",
124
+ "additionalContext": "..."
125
+ },
126
+ "suppressOutput": true
127
+ }
128
+ ```
129
+
130
+ That context is the proactive half of search-first enforcement; the paired
131
+ `stop-search-check.sh` remains the corrective half. In plain-text mode,
132
+ informational reminders are silent by default and require
133
+ `AI_TOOLKIT_HOOK_VERBOSE=1`.
134
+
135
+ Codex-generated hooks intentionally run this script without
136
+ `AI_TOOLKIT_HOOK_FORMAT=json` by default because Codex renders
137
+ `additionalContext` visibly in the TUI; the search-first flag side effect still
138
+ arms the corrective Stop hook.
120
139
 
121
140
  ### UserPromptSubmit (usage tracking) — `track-usage.sh`
122
141
 
@@ -127,7 +146,7 @@ available with `AI_TOOLKIT_HOOK_FORMAT=json`.
127
146
  | Script | `~/.softspark/ai-toolkit/hooks/track-usage.sh` |
128
147
  | Fires | Before Claude starts working on a submitted prompt |
129
148
 
130
- **Action:** Records skill invocations (slash commands like `/commit`, `/review`) to `~/.softspark/ai-toolkit/stats.json` for local usage analytics. Non-slash prompts are ignored.
149
+ **Action:** Records skill invocations (slash commands like `/commit`, `/review`) to `~/.softspark/ai-toolkit/stats.json` for local usage analytics. Non-slash prompts are ignored. Stats writes are best-effort and stay silent if the local state path is not writable.
131
150
 
132
151
  ### PostToolUse (edit feedback) — `post-tool-use.sh`
133
152
 
@@ -393,7 +412,7 @@ First-match-wins per file. Built-in runners: `bats`, `pytest`, `vitest`, `jest`.
393
412
  | Script | `~/.softspark/ai-toolkit/hooks/search-tracker.sh` |
394
413
  | Fires | After any search-style tool call |
395
414
 
396
- **Action:** Clears `~/.softspark/ai-toolkit/state/search-required-<session_id>.flag` (per-session, keyed by `session_id` from the hook stdin payload, falling back to `transcript_path` basename, then `default`). Pairs with `user-prompt-submit.sh` (sets the flag on long technical prompts only when a search provider is detected or strict mode is enabled) and `stop-search-check.sh` (blocks Stop if the calling session's flag is still set). Search provider detection parses actual MCP server names from `mcpServers`, `mcp_servers`, or `mcp` config blocks; hook matchers and permission allowlists do not count as providers. Together the hooks enforce the global CLAUDE.md GOLDEN RULE without breaking offline/no-RAG installs and without cross-session interference when multiple Claude Code windows run in parallel.
415
+ **Action:** Clears `~/.softspark/ai-toolkit/state/search-required-<session_id>.flag` (per-session, keyed by `session_id` from the hook stdin payload, falling back to `transcript_path` basename, then `default`). Pairs with `user-prompt-submit.sh` (sets the flag on long technical prompts only when a search provider is detected or strict mode is enabled) and `stop-search-check.sh` (blocks Stop if the calling session's flag is still set). Search provider detection parses actual MCP server names from `mcpServers`, `mcp_servers`, or `mcp` config blocks; hook matchers and permission allowlists do not count as providers. Codex Stop enforcement also scans the recent `~/.codex/log/codex-tui.log` window for `ToolCall: mcp__...__smart_query` and `tool.name="smart_query"`-style entries because Codex MCP tool calls may not fire the shared `PostToolUse` tracker. Together the hooks enforce the global CLAUDE.md GOLDEN RULE without breaking offline/no-RAG installs and without cross-session interference when multiple Claude Code windows run in parallel.
397
416
 
398
417
  Non-blocking (exit 0). Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
399
418
 
@@ -444,7 +463,7 @@ Non-blocking (exit 0). Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
444
463
  | `scripts/test_cohesion.py` | Resolves changed paths → test commands via cohesion map. First-match-wins. Stdlib-only. |
445
464
  | `app/hooks/test-cohesion-map.json` | Toolkit-default path → tests mapping (used when no project map exists). |
446
465
  | `app/hooks/_locate-toolkit.sh` | Shared bash helper that exports `$TOOLKIT_DIR` for hooks needing scripts/. |
447
- | `app/hooks/_hook-io.sh` | Shared bash helper that normalizes hook payloads across Claude, Augment, Gemini, Windsurf, and Cursor-style JSON. Honors `AI_TOOLKIT_HOOK_QUIET=1` and `AI_TOOLKIT_HOOK_VERBOSE=1` for non-blocking context output. |
466
+ | `app/hooks/_hook-io.sh` | Shared bash helper that normalizes hook payloads across Claude, Augment, Gemini, Windsurf, and Cursor-style JSON. JSON context output takes precedence over `AI_TOOLKIT_HOOK_QUIET=1`, so quiet hooks can still emit `additionalContext` with `suppressOutput: true`; plain-text output requires `AI_TOOLKIT_HOOK_VERBOSE=1`. |
448
467
  | `app/hooks/_search-capability.sh` | Shared bash helper that enables search-first blocking only when RAG/Web is configured or strict mode is requested. |
449
468
 
450
469
  ## Runtime Profiles