@softspark/ai-toolkit 4.9.0 → 4.10.0
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 +13 -0
- package/README.md +8 -8
- package/app/.claude-plugin/plugin.json +1 -1
- package/app/constitution.md +1 -1
- package/app/hooks/_session-paths.sh +40 -0
- package/app/hooks/pre-compact.sh +6 -4
- package/app/hooks/save-session.sh +4 -2
- package/app/hooks/session-end.sh +7 -6
- package/app/hooks/session-start.sh +3 -1
- package/app/hooks.json +0 -10
- package/kb/reference/architecture-overview.md +0 -1
- package/kb/reference/hooks-catalog.md +19 -22
- package/kb/reference/opencode-compatibility.md +1 -1
- package/kb/reference/supported-tools-registry.md +1 -1
- package/kb/reference/unique-features.md +0 -1
- package/llms-full.txt +21 -26
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/scripts/generate_augment_hooks.py +0 -1
- package/scripts/generate_codex_hooks.py +0 -5
- package/scripts/generate_cursor_hooks.py +0 -1
- package/scripts/generate_devin_hooks.py +0 -5
- package/scripts/generate_gemini_hooks.py +0 -5
- package/scripts/generate_opencode_plugin.py +1 -2
- package/scripts/generate_windsurf_hooks.py +0 -3
- package/app/hooks/session-context.sh +0 -63
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,19 @@ Versioning follows [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## v4.10.0 — Per-repo session storage outside the repo + drop dead session-context hook (2026-06-17)
|
|
11
|
+
|
|
12
|
+
Minor release. Session lifecycle hooks stop writing auto-generated files into each project's `.claude/` directory and store them per-repo under `~/.softspark/ai-toolkit/`. The dead `session-context.sh` hook (write-only, no consumer) is removed across all editor generators. Test count: 1197 → 1195.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Session lifecycle hooks store artifacts outside the repo.** `save-session.sh`, `session-end.sh`, `session-start.sh`, and `pre-compact.sh` now read/write the auto-generated session files (`session-context.md`, `session-end.md`, `session-context.md.checkpoints`, `decisions.md`) under `~/.softspark/ai-toolkit/sessions/<repo-key>/` instead of the project's `.claude/` directory. `<repo-key>` is the git work-tree root path (fallback: cwd) with `/` replaced by `-`, keyed per repo so projects stay isolated. Stops these files from piling up in every repository. New shared helper `app/hooks/_session-paths.sh` is the single source of path resolution. No migration of pre-existing in-repo files: the new store starts fresh, old `.claude/session-*.md` left for the user to delete.
|
|
16
|
+
- **Constitution Art. I §5** updated to point proactive checkpointing at the per-repo session store.
|
|
17
|
+
|
|
18
|
+
### Removed
|
|
19
|
+
- **Dropped the dead `session-context.sh` hook.** It fired on `SessionStart` and wrote an environment snapshot (`~/.softspark/ai-toolkit/sessions/<id>.json`: pwd, git branch/status, node/python versions) that no hook, script, or tool ever read — pure write-only dead code (Constitution Art. VI.1). Removed the script, its `app/hooks.json` wiring, its entries across all 7 editor hook generators (cursor, windsurf, codex, devin, augment, gemini, opencode), its tests, and its catalog/overview docs. Editors that had it as the sole entry for an event (windsurf `post_setup_worktree`, codex `PostCompact`, gemini `BeforeModel`, devin `SessionStart`) drop that event. Not related to the session-storage change above — it never wrote to the repo.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
10
23
|
## v4.9.0 - Epistemic integrity rules + deep-research skill + custom-rule leak fix (2026-06-15)
|
|
11
24
|
|
|
12
25
|
Minor release. Adds a constitution article on injection resistance and grounding, a new web-research methodology skill, and an anti-sycophancy/formatting pass across the voice layer. Also fixes a leak where a maintainer's personal registered rules were baked into the toolkit's own committed editor files. Skill count: 107 → 108. Constitution: 6 → 7 articles. Test count: 1196 → 1197.
|
package/README.md
CHANGED
|
@@ -6,16 +6,16 @@
|
|
|
6
6
|
[](LICENSE)
|
|
7
7
|
[](app/skills/)
|
|
8
8
|
[](app/agents/)
|
|
9
|
-
[](tests/)
|
|
10
10
|
|
|
11
|
-
## What's New in v4.
|
|
11
|
+
## What's New in v4.10.0
|
|
12
12
|
|
|
13
|
-
v4.
|
|
13
|
+
v4.10.0 gets auto-generated session files out of your repositories and removes a dead lifecycle hook.
|
|
14
14
|
|
|
15
|
-
- **
|
|
16
|
-
-
|
|
17
|
-
- **
|
|
18
|
-
- **
|
|
15
|
+
- **Per-repo session storage outside the repo**: `save-session.sh`, `session-end.sh`, `session-start.sh`, and `pre-compact.sh` now keep `session-context.md`, `session-end.md`, checkpoints, and `decisions.md` under `~/.softspark/ai-toolkit/sessions/<repo-key>/` instead of each project's `.claude/` — no more generated files piling up in every repo. Keyed per repo (git root with `/` → `-`) so projects stay isolated.
|
|
16
|
+
- **No silent migration**: the new store starts fresh; pre-existing in-repo `.claude/session-*.md` are left for you to delete.
|
|
17
|
+
- **Dropped the dead `session-context.sh` hook**: it wrote a `${SESSION}.json` environment snapshot nobody ever read (Constitution Art. VI.1). Removed across `app/hooks.json` and all 7 editor hook generators (cursor, windsurf, codex, devin, augment, gemini, opencode).
|
|
18
|
+
- **Test count**: 1197 → 1195.
|
|
19
19
|
|
|
20
20
|
See [CHANGELOG.md](CHANGELOG.md) for full history.
|
|
21
21
|
|
|
@@ -148,7 +148,7 @@ ai-toolkit/
|
|
|
148
148
|
│ └── ARCHITECTURE.md # Full system design
|
|
149
149
|
├── kb/ # Reference docs, procedures, plans
|
|
150
150
|
├── scripts/ # Validation, install, evaluation scripts
|
|
151
|
-
├── tests/ # Bats test suite (
|
|
151
|
+
├── tests/ # Bats test suite (1195 tests)
|
|
152
152
|
└── CHANGELOG.md
|
|
153
153
|
```
|
|
154
154
|
|
|
@@ -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.
|
|
4
|
+
"version": "4.10.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "SoftSpark",
|
|
7
7
|
"url": "https://github.com/softspark"
|
package/app/constitution.md
CHANGED
|
@@ -21,7 +21,7 @@ status: IMMUTABLE
|
|
|
21
21
|
- Exceeding limits requires explicit user override
|
|
22
22
|
|
|
23
23
|
### Section 5: Proactive Context Checkpointing
|
|
24
|
-
- During multi-step tasks (>5 tool calls),
|
|
24
|
+
- During multi-step tasks (>5 tool calls), append milestones to the per-repo session-context store after each major milestone. Auto-generated session files live under `~/.softspark/ai-toolkit/sessions/<repo-root-with-/-as->/` (the repo work-tree root path with `/` replaced by `-`), NOT inside the project repo. Append agent checkpoints to `session-context.md.checkpoints` in that directory; the Stop hook folds them into the session summary
|
|
25
25
|
- Checkpoint MUST include: current objective, completed steps, pending steps, files modified, key decisions
|
|
26
26
|
- Minimum frequency: after every completed task phase, workflow stage, or subagent handoff
|
|
27
27
|
- Agent SHOULD checkpoint before any risky or destructive operation
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# _session-paths.sh — shared per-repo session storage paths for lifecycle hooks.
|
|
3
|
+
#
|
|
4
|
+
# All auto-generated session artifacts live OUTSIDE the project repo, under a
|
|
5
|
+
# per-repo subdirectory of ~/.softspark/ai-toolkit/sessions/. This keeps generated
|
|
6
|
+
# files (session context, handoff note, checkpoints, decisions) from polluting
|
|
7
|
+
# every project's .claude/ directory.
|
|
8
|
+
#
|
|
9
|
+
# Usage (in a hook script):
|
|
10
|
+
# source "$(dirname "$0")/_session-paths.sh"
|
|
11
|
+
# Then use the exported SESSION_* paths.
|
|
12
|
+
#
|
|
13
|
+
# Repo key: the git work-tree root (fallback: cwd) with "/" replaced by "-",
|
|
14
|
+
# mirroring Claude Code's own ~/.claude/projects/<encoded-path> convention so the
|
|
15
|
+
# location is derivable by an agent, not an opaque hash.
|
|
16
|
+
|
|
17
|
+
_session_repo_root() {
|
|
18
|
+
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
19
|
+
local top
|
|
20
|
+
top="$(git rev-parse --show-toplevel 2>/dev/null)"
|
|
21
|
+
if [ -n "$top" ]; then
|
|
22
|
+
printf '%s' "$top"
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
fi
|
|
26
|
+
pwd
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
SESSION_REPO_ROOT="$(_session_repo_root)"
|
|
30
|
+
SESSION_REPO_KEY="${SESSION_REPO_ROOT//\//-}"
|
|
31
|
+
SESSION_DIR="$HOME/.softspark/ai-toolkit/sessions/$SESSION_REPO_KEY"
|
|
32
|
+
SESSION_CONTEXT_FILE="$SESSION_DIR/session-context.md"
|
|
33
|
+
SESSION_CHECKPOINTS_FILE="$SESSION_DIR/session-context.md.checkpoints"
|
|
34
|
+
SESSION_END_FILE="$SESSION_DIR/session-end.md"
|
|
35
|
+
SESSION_DECISIONS_FILE="$SESSION_DIR/decisions.md"
|
|
36
|
+
|
|
37
|
+
export SESSION_REPO_ROOT SESSION_REPO_KEY SESSION_DIR
|
|
38
|
+
export SESSION_CONTEXT_FILE SESSION_CHECKPOINTS_FILE SESSION_END_FILE SESSION_DECISIONS_FILE
|
|
39
|
+
|
|
40
|
+
unset -f _session_repo_root
|
package/app/hooks/pre-compact.sh
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
# shellcheck source=_profile-check.sh
|
|
10
10
|
source "$(dirname "$0")/_profile-check.sh"
|
|
11
|
+
# shellcheck source=_session-paths.sh
|
|
12
|
+
source "$(dirname "$0")/_session-paths.sh"
|
|
11
13
|
|
|
12
14
|
# ---------------------------------------------------------------------------
|
|
13
15
|
# 1. Mandatory reload reminder (highest priority — always survives)
|
|
@@ -32,9 +34,9 @@ fi
|
|
|
32
34
|
# ---------------------------------------------------------------------------
|
|
33
35
|
# 3. Current task state (medium priority — what we're doing)
|
|
34
36
|
# ---------------------------------------------------------------------------
|
|
35
|
-
if [ -f "
|
|
37
|
+
if [ -f "$SESSION_CONTEXT_FILE" ]; then
|
|
36
38
|
echo "=== Session Context ==="
|
|
37
|
-
cat "
|
|
39
|
+
cat "$SESSION_CONTEXT_FILE"
|
|
38
40
|
echo "======================="
|
|
39
41
|
fi
|
|
40
42
|
|
|
@@ -55,10 +57,10 @@ fi
|
|
|
55
57
|
# ---------------------------------------------------------------------------
|
|
56
58
|
# 5. Key decisions file (if user has been noting decisions this session)
|
|
57
59
|
# ---------------------------------------------------------------------------
|
|
58
|
-
if [ -f "
|
|
60
|
+
if [ -f "$SESSION_DECISIONS_FILE" ]; then
|
|
59
61
|
echo "=== Key Decisions This Session ==="
|
|
60
62
|
# Only show last 10 lines to keep token budget tight
|
|
61
|
-
tail -10 "
|
|
63
|
+
tail -10 "$SESSION_DECISIONS_FILE"
|
|
62
64
|
echo "=================================="
|
|
63
65
|
fi
|
|
64
66
|
|
|
@@ -6,16 +6,18 @@
|
|
|
6
6
|
|
|
7
7
|
# shellcheck source=_profile-check.sh
|
|
8
8
|
source "$(dirname "$0")/_profile-check.sh"
|
|
9
|
+
# shellcheck source=_session-paths.sh
|
|
10
|
+
source "$(dirname "$0")/_session-paths.sh"
|
|
9
11
|
|
|
10
12
|
# Read from stdin (Claude Code passes JSON with .session_id, .last_assistant_message)
|
|
11
13
|
INPUT=$(cat)
|
|
12
14
|
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
13
15
|
LAST_MSG=$(echo "$INPUT" | jq -r '.last_assistant_message // "No summary available"' 2>/dev/null | head -5)
|
|
14
16
|
|
|
15
|
-
SESSION_FILE="
|
|
17
|
+
SESSION_FILE="$SESSION_CONTEXT_FILE"
|
|
16
18
|
|
|
17
19
|
if [ -n "$SESSION_ID" ]; then
|
|
18
|
-
mkdir -p
|
|
20
|
+
mkdir -p "$SESSION_DIR"
|
|
19
21
|
|
|
20
22
|
# Gather git state for richer context
|
|
21
23
|
GIT_BRANCH=""
|
package/app/hooks/session-end.sh
CHANGED
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
# shellcheck source=_profile-check.sh
|
|
9
9
|
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
+
# shellcheck source=_session-paths.sh
|
|
11
|
+
source "$(dirname "$0")/_session-paths.sh"
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
HANDOFF_FILE="$STATE_DIR/session-end.md"
|
|
13
|
+
SESSION_FILE="$SESSION_CONTEXT_FILE"
|
|
14
|
+
HANDOFF_FILE="$SESSION_END_FILE"
|
|
14
15
|
STAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || date)"
|
|
15
16
|
|
|
16
|
-
mkdir -p "$
|
|
17
|
+
mkdir -p "$SESSION_DIR"
|
|
17
18
|
|
|
18
19
|
{
|
|
19
20
|
echo "# Session End Snapshot"
|
|
@@ -28,9 +29,9 @@ mkdir -p "$STATE_DIR"
|
|
|
28
29
|
} > "$HANDOFF_FILE"
|
|
29
30
|
|
|
30
31
|
if [ -f "$SESSION_FILE" ]; then
|
|
31
|
-
echo "SessionEnd: wrote
|
|
32
|
+
echo "SessionEnd: wrote $HANDOFF_FILE and preserved existing session-context for the next session."
|
|
32
33
|
else
|
|
33
|
-
echo "SessionEnd: wrote .
|
|
34
|
+
echo "SessionEnd: wrote $HANDOFF_FILE. Consider persisting open tasks in the session-context file before ending long workstreams."
|
|
34
35
|
fi
|
|
35
36
|
|
|
36
37
|
exit 0
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
# shellcheck source=_locate-toolkit.sh
|
|
8
8
|
source "$(dirname "$0")/_locate-toolkit.sh"
|
|
9
|
+
# shellcheck source=_session-paths.sh
|
|
10
|
+
source "$(dirname "$0")/_session-paths.sh"
|
|
9
11
|
|
|
10
12
|
emit_context() {
|
|
11
13
|
[ "${AI_TOOLKIT_HOOK_QUIET:-0}" = "1" ] && return 0
|
|
@@ -51,7 +53,7 @@ if [ -n "$VERSION_MSG" ]; then
|
|
|
51
53
|
fi
|
|
52
54
|
|
|
53
55
|
# 3. Load session context (if available)
|
|
54
|
-
SESSION_FILE="
|
|
56
|
+
SESSION_FILE="$SESSION_CONTEXT_FILE"
|
|
55
57
|
if [ -f "$SESSION_FILE" ] && [ "${AI_TOOLKIT_HOOK_QUIET:-0}" != "1" ] && [ "${AI_TOOLKIT_HOOK_VERBOSE:-0}" = "1" ]; then
|
|
56
58
|
printf '%s\n' "=== Session Context ==="
|
|
57
59
|
cat "$SESSION_FILE"
|
package/app/hooks.json
CHANGED
|
@@ -20,16 +20,6 @@
|
|
|
20
20
|
"command": "\"$HOME/.softspark/ai-toolkit/hooks/mcp-health.sh\""
|
|
21
21
|
}
|
|
22
22
|
]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"_source": "ai-toolkit",
|
|
26
|
-
"matcher": "startup|compact",
|
|
27
|
-
"hooks": [
|
|
28
|
-
{
|
|
29
|
-
"type": "command",
|
|
30
|
-
"command": "\"$HOME/.softspark/ai-toolkit/hooks/session-context.sh\""
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
23
|
}
|
|
34
24
|
],
|
|
35
25
|
"Notification": [
|
|
@@ -269,7 +269,6 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
|
|
|
269
269
|
|------|---------|--------|--------|
|
|
270
270
|
| SessionStart | Session start + compact | `session-start.sh` | MANDATORY rules reminder + session context + instincts |
|
|
271
271
|
| SessionStart | Session start | `mcp-health.sh` | Check MCP runtime availability |
|
|
272
|
-
| SessionStart | Session start | `session-context.sh` | Capture environment snapshot |
|
|
273
272
|
| Notification | Claude waiting for input | *(inline)* | macOS desktop notification |
|
|
274
273
|
| PreToolUse | Before Bash | `guard-destructive.sh` | Block destructive commands |
|
|
275
274
|
| PreToolUse | Before file ops (Bash, Read, Edit, Write, MultiEdit, Glob, Grep, NotebookEdit, mcp\_filesystem) | `guard-path.sh` | Block wrong-user path hallucination |
|
|
@@ -47,13 +47,21 @@ ai-toolkit update # re-copies scripts, re-merges (idempotent)
|
|
|
47
47
|
**Actions:**
|
|
48
48
|
1. Injects MANDATORY reminder to follow CLAUDE.md rules
|
|
49
49
|
2. Injects REMINDER about tests and documentation
|
|
50
|
-
3. Loads session context from
|
|
50
|
+
3. Loads session context from the per-repo session store (if exists)
|
|
51
51
|
4. Loads active instincts from `.claude/instincts/*.md` (if any)
|
|
52
52
|
|
|
53
53
|
By default the hook performs session-state reset, stale search-flag cleanup, and
|
|
54
54
|
update notification side effects without printing informational stdout. Set
|
|
55
|
-
`AI_TOOLKIT_HOOK_VERBOSE=1` to print the startup reminders and loaded context
|
|
56
|
-
|
|
55
|
+
`AI_TOOLKIT_HOOK_VERBOSE=1` to print the startup reminders and loaded context for
|
|
56
|
+
debugging; `AI_TOOLKIT_HOOK_QUIET=1` keeps it silent explicitly.
|
|
57
|
+
|
|
58
|
+
> **Session storage:** auto-generated session artifacts (context, handoff note,
|
|
59
|
+
> checkpoints, decisions) are stored **outside the project repo** under
|
|
60
|
+
> `~/.softspark/ai-toolkit/sessions/<repo-key>/`, where `<repo-key>` is the git
|
|
61
|
+
> work-tree root path (fallback: cwd) with `/` replaced by `-` (mirrors Claude
|
|
62
|
+
> Code's own `~/.claude/projects/` convention). This keeps generated files from
|
|
63
|
+
> piling up in every project's `.claude/` directory. Path resolution lives in the
|
|
64
|
+
> shared helper `app/hooks/_session-paths.sh`.
|
|
57
65
|
|
|
58
66
|
### Notification — `notify-waiting.sh`
|
|
59
67
|
|
|
@@ -192,10 +200,10 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
192
200
|
| Script | `~/.softspark/ai-toolkit/hooks/save-session.sh` |
|
|
193
201
|
| Fires | After every Claude response |
|
|
194
202
|
|
|
195
|
-
**Action:** Writes enriched session context to
|
|
203
|
+
**Action:** Writes enriched session context to the per-repo session store (`~/.softspark/ai-toolkit/sessions/<repo-key>/session-context.md`) for cross-session persistence. Captures:
|
|
196
204
|
- Session ID and last assistant message (first 5 lines)
|
|
197
205
|
- Git branch, uncommitted change count, and diff stat (last 5 lines)
|
|
198
|
-
- Agent-written checkpoints from
|
|
206
|
+
- Agent-written checkpoints from `session-context.md.checkpoints` in the same store (if present — written by proactive checkpointing per Constitution Art. I §5)
|
|
199
207
|
|
|
200
208
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
201
209
|
|
|
@@ -263,9 +271,9 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
263
271
|
**Actions (prioritized — higher priority items survive tighter token budgets):**
|
|
264
272
|
1. **Mandatory reload reminder** — always emitted, instructs Claude to re-read CLAUDE.md and active tasks
|
|
265
273
|
2. **Active instincts** — lists each instinct with confidence score and pattern name from `.claude/instincts/*.md`
|
|
266
|
-
3. **Session context** — preserves task state from
|
|
274
|
+
3. **Session context** — preserves task state from the per-repo session store (if exists)
|
|
267
275
|
4. **Git working state** — branch name, uncommitted change count, last commit (if inside a git repo)
|
|
268
|
-
5. **Key decisions** — last 10 lines from
|
|
276
|
+
5. **Key decisions** — last 10 lines from `decisions.md` in the per-repo session store (if exists)
|
|
269
277
|
|
|
270
278
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
271
279
|
|
|
@@ -278,7 +286,7 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
278
286
|
| Script | `~/.softspark/ai-toolkit/hooks/session-end.sh` |
|
|
279
287
|
| Fires | When a Claude session ends |
|
|
280
288
|
|
|
281
|
-
**Action:** Writes
|
|
289
|
+
**Action:** Writes `session-end.md` to the per-repo session store (`~/.softspark/ai-toolkit/sessions/<repo-key>/`) with a lightweight handoff note for the next session and reminds the next session to review preserved context.
|
|
282
290
|
|
|
283
291
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
284
292
|
|
|
@@ -351,17 +359,6 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
351
359
|
|
|
352
360
|
**Action:** Non-blocking (always exits 0). Inspects Bash commands containing `git commit`. Extracts the commit message from the `-m` flag and checks it against Conventional Commits format (`type: description`, where type is one of feat/fix/docs/refactor/test/chore/ci/perf/style/revert). Emits an advisory warning if the message does not match — the commit is not blocked, only nudged. Commands without `git commit` or without a `-m` message (e.g. interactive commits) are ignored.
|
|
353
361
|
|
|
354
|
-
### SessionStart — `session-context.sh`
|
|
355
|
-
|
|
356
|
-
| Field | Value |
|
|
357
|
-
|-------|-------|
|
|
358
|
-
| Event | `SessionStart` |
|
|
359
|
-
| Matcher | *(all)* |
|
|
360
|
-
| Script | `~/.softspark/ai-toolkit/hooks/session-context.sh` |
|
|
361
|
-
| Fires | Session start |
|
|
362
|
-
|
|
363
|
-
**Action:** Captures an environment snapshot to `~/.softspark/ai-toolkit/sessions/current-context.json`. Records working directory, git branch, git status summary, Node.js version, Python version, and timestamp. Used by other hooks and tools to access session metadata without re-running discovery commands. Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
364
|
-
|
|
365
362
|
---
|
|
366
363
|
|
|
367
364
|
## New Hooks (Constitution Art. VI Enforcement)
|
|
@@ -520,8 +517,8 @@ commands explicitly silent, and Codex-generated hooks plus Claude's bundled
|
|
|
520
517
|
├── _locate-toolkit.sh # NEW: shared $TOOLKIT_DIR locator
|
|
521
518
|
├── _hook-io.sh # NEW: shared multi-editor payload/output adapter
|
|
522
519
|
├── _search-capability.sh # NEW: capability-aware search-first enforcement
|
|
520
|
+
├── _session-paths.sh # NEW: per-repo session storage path resolver
|
|
523
521
|
├── session-start.sh
|
|
524
|
-
├── session-context.sh
|
|
525
522
|
├── guard-destructive.sh
|
|
526
523
|
├── guard-path.sh
|
|
527
524
|
├── guard-config.sh
|
|
@@ -549,7 +546,7 @@ commands explicitly silent, and Codex-generated hooks plus Claude's bundled
|
|
|
549
546
|
|
|
550
547
|
~/.claude/settings.json
|
|
551
548
|
└── hooks: # Hook definitions referencing ~/.softspark/ai-toolkit/hooks/
|
|
552
|
-
├── SessionStart → session-start.sh, mcp-health.sh
|
|
549
|
+
├── SessionStart → session-start.sh, mcp-health.sh
|
|
553
550
|
├── Notification → notify-waiting.sh
|
|
554
551
|
├── PreToolUse → guard-destructive.sh, guard-path.sh, guard-config.sh, commit-quality.sh, revert-guard.sh
|
|
555
552
|
├── UserPromptSubmit → user-prompt-submit.sh, track-usage.sh
|
|
@@ -590,7 +587,7 @@ Windsurf rebranded to Devin Desktop (2026-06-02); the Cascade agent — and its
|
|
|
590
587
|
Devin CLI uses a **Claude-compatible** hook format (docs.devin.ai/cli/extensibility/hooks). Key facts driving the generator:
|
|
591
588
|
|
|
592
589
|
- **Standalone file shape:** in `.devin/hooks.v1.json` the entire file IS the hooks object — no top-level `"hooks"` wrapper key (unlike `.claude/settings.json`).
|
|
593
|
-
- **Events:** Claude-style PascalCase — `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop
|
|
590
|
+
- **Events:** Claude-style PascalCase — `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop`. `post_cascade_response` maps to `Stop` (which carries no response text on stdin).
|
|
594
591
|
- **Matchers:** regex against the Devin **tool name** (`read`, `edit`, `exec`, `grep`, `glob`, `mcp__<server>__<tool>`) — NOT Claude's `Bash`/`Edit`, so the shared guards reliably fire.
|
|
595
592
|
- **Block contract:** the guard scripts emit `{"decision":"block","reason":...}` on stdout (plain mode) AND exit 2 — Devin honors both. Hooks run **without** `AI_TOOLKIT_HOOK_FORMAT=json` because Devin expects the flat `{"decision","reason"}` shape, not Claude's `hookSpecificOutput` envelope.
|
|
596
593
|
- **Stdin payload:** flat `{ "hook_event_name", "tool_name", "tool_input" }` — already handled by `_hook-io.sh` via its `.tool_name` / `.tool_input.*` branches, so no normalizer change was needed.
|
|
@@ -79,7 +79,7 @@ Each command file carries the prompt in its markdown body (built from the SKILL.
|
|
|
79
79
|
|
|
80
80
|
| opencode event | Bash hook(s) |
|
|
81
81
|
|----------------------------|--------------------------------------------------------------------|
|
|
82
|
-
| `session.created` | `session-start.sh` + `
|
|
82
|
+
| `session.created` | `session-start.sh` + `mcp-health.sh` |
|
|
83
83
|
| `session.compacted` | `pre-compact.sh` + `pre-compact-save.sh` (PreCompact equivalent) |
|
|
84
84
|
| `session.deleted` | `session-end.sh` + `save-session.sh` |
|
|
85
85
|
| `message.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
@@ -170,7 +170,7 @@ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed b
|
|
|
170
170
|
| Config paths | `AGENTS.md`, `.agents/skills/*/SKILL.md`, `.codex/hooks.json`, `.codex/config.toml` (project layers, root→cwd, closest wins, trusted projects only), `~/.codex/config.toml` |
|
|
171
171
|
| Our generators | `scripts/generate_codex.py`, `scripts/generate_codex_hooks.py`, `scripts/generate_codex_skills.py` (opt-in via `--codex-skills`) |
|
|
172
172
|
| Rules delivery | Universal coding rules are inlined into `AGENTS.md` (Codex reads instructions only from AGENTS.md, not `.agents/rules/`); language rules ship as `<lang>-rules` skills under `.agents/skills/`. |
|
|
173
|
-
| Tracked hook events | Upstream canonical (codex-rs `HookEventName` enum): `PreToolUse`, `PostToolUse`, `PermissionRequest`, `PreCompact`, `PostCompact`, `SessionStart`, `UserPromptSubmit`, `SubagentStart`, `SubagentStop`, `Stop` (10 events). We wire
|
|
173
|
+
| Tracked hook events | Upstream canonical (codex-rs `HookEventName` enum): `PreToolUse`, `PostToolUse`, `PermissionRequest`, `PreCompact`, `PostCompact`, `SessionStart`, `UserPromptSubmit`, `SubagentStart`, `SubagentStop`, `Stop` (10 events). We wire 9 of these to shared toolkit hook scripts, mirroring the Claude Code mapping in `app/hooks.json`. `PostCompact` is not wired (its only hook was the removed environment-snapshot probe). |
|
|
174
174
|
| Tracked handler types | `command` (emitted by default); `prompt` and `agent` available upstream but authored by hand |
|
|
175
175
|
| Other capabilities | `AGENTS.md`, `config.toml`, `mcp_servers`, sandbox policies, `.agents/skills/*/SKILL.md` (native Codex skill discovery path) |
|
|
176
176
|
| Version probe | `codex --version` |
|
|
@@ -27,7 +27,6 @@ Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are
|
|
|
27
27
|
|-------|--------|--------|
|
|
28
28
|
| SessionStart | `session-start.sh` | MANDATORY rules reminder + session context + instincts + reset session-edit state |
|
|
29
29
|
| SessionStart | `mcp-health.sh` | Check MCP server command availability (non-blocking warning) |
|
|
30
|
-
| SessionStart | `session-context.sh` | Capture environment snapshot to `~/.softspark/ai-toolkit/sessions/current-context.json` |
|
|
31
30
|
| Notification | `notify-waiting.sh` | Cross-platform desktop notification |
|
|
32
31
|
| PreToolUse | `guard-destructive.sh` | Block `rm -rf`, `DROP TABLE`, etc. |
|
|
33
32
|
| PreToolUse | `guard-path.sh` | Block wrong-user path hallucination |
|
package/llms-full.txt
CHANGED
|
@@ -6501,7 +6501,6 @@ Agents (code-reviewer, debugger, devops-implementer, ...)
|
|
|
6501
6501
|
|------|---------|--------|--------|
|
|
6502
6502
|
| SessionStart | Session start + compact | `session-start.sh` | MANDATORY rules reminder + session context + instincts |
|
|
6503
6503
|
| SessionStart | Session start | `mcp-health.sh` | Check MCP runtime availability |
|
|
6504
|
-
| SessionStart | Session start | `session-context.sh` | Capture environment snapshot |
|
|
6505
6504
|
| Notification | Claude waiting for input | *(inline)* | macOS desktop notification |
|
|
6506
6505
|
| PreToolUse | Before Bash | `guard-destructive.sh` | Block destructive commands |
|
|
6507
6506
|
| PreToolUse | Before file ops (Bash, Read, Edit, Write, MultiEdit, Glob, Grep, NotebookEdit, mcp\_filesystem) | `guard-path.sh` | Block wrong-user path hallucination |
|
|
@@ -9043,13 +9042,21 @@ ai-toolkit update # re-copies scripts, re-merges (idempotent)
|
|
|
9043
9042
|
**Actions:**
|
|
9044
9043
|
1. Injects MANDATORY reminder to follow CLAUDE.md rules
|
|
9045
9044
|
2. Injects REMINDER about tests and documentation
|
|
9046
|
-
3. Loads session context from
|
|
9045
|
+
3. Loads session context from the per-repo session store (if exists)
|
|
9047
9046
|
4. Loads active instincts from `.claude/instincts/*.md` (if any)
|
|
9048
9047
|
|
|
9049
9048
|
By default the hook performs session-state reset, stale search-flag cleanup, and
|
|
9050
9049
|
update notification side effects without printing informational stdout. Set
|
|
9051
|
-
`AI_TOOLKIT_HOOK_VERBOSE=1` to print the startup reminders and loaded context
|
|
9052
|
-
|
|
9050
|
+
`AI_TOOLKIT_HOOK_VERBOSE=1` to print the startup reminders and loaded context for
|
|
9051
|
+
debugging; `AI_TOOLKIT_HOOK_QUIET=1` keeps it silent explicitly.
|
|
9052
|
+
|
|
9053
|
+
> **Session storage:** auto-generated session artifacts (context, handoff note,
|
|
9054
|
+
> checkpoints, decisions) are stored **outside the project repo** under
|
|
9055
|
+
> `~/.softspark/ai-toolkit/sessions/<repo-key>/`, where `<repo-key>` is the git
|
|
9056
|
+
> work-tree root path (fallback: cwd) with `/` replaced by `-` (mirrors Claude
|
|
9057
|
+
> Code's own `~/.claude/projects/` convention). This keeps generated files from
|
|
9058
|
+
> piling up in every project's `.claude/` directory. Path resolution lives in the
|
|
9059
|
+
> shared helper `app/hooks/_session-paths.sh`.
|
|
9053
9060
|
|
|
9054
9061
|
### Notification — `notify-waiting.sh`
|
|
9055
9062
|
|
|
@@ -9188,10 +9195,10 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
9188
9195
|
| Script | `~/.softspark/ai-toolkit/hooks/save-session.sh` |
|
|
9189
9196
|
| Fires | After every Claude response |
|
|
9190
9197
|
|
|
9191
|
-
**Action:** Writes enriched session context to
|
|
9198
|
+
**Action:** Writes enriched session context to the per-repo session store (`~/.softspark/ai-toolkit/sessions/<repo-key>/session-context.md`) for cross-session persistence. Captures:
|
|
9192
9199
|
- Session ID and last assistant message (first 5 lines)
|
|
9193
9200
|
- Git branch, uncommitted change count, and diff stat (last 5 lines)
|
|
9194
|
-
- Agent-written checkpoints from
|
|
9201
|
+
- Agent-written checkpoints from `session-context.md.checkpoints` in the same store (if present — written by proactive checkpointing per Constitution Art. I §5)
|
|
9195
9202
|
|
|
9196
9203
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
9197
9204
|
|
|
@@ -9259,9 +9266,9 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
9259
9266
|
**Actions (prioritized — higher priority items survive tighter token budgets):**
|
|
9260
9267
|
1. **Mandatory reload reminder** — always emitted, instructs Claude to re-read CLAUDE.md and active tasks
|
|
9261
9268
|
2. **Active instincts** — lists each instinct with confidence score and pattern name from `.claude/instincts/*.md`
|
|
9262
|
-
3. **Session context** — preserves task state from
|
|
9269
|
+
3. **Session context** — preserves task state from the per-repo session store (if exists)
|
|
9263
9270
|
4. **Git working state** — branch name, uncommitted change count, last commit (if inside a git repo)
|
|
9264
|
-
5. **Key decisions** — last 10 lines from
|
|
9271
|
+
5. **Key decisions** — last 10 lines from `decisions.md` in the per-repo session store (if exists)
|
|
9265
9272
|
|
|
9266
9273
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
9267
9274
|
|
|
@@ -9274,7 +9281,7 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
9274
9281
|
| Script | `~/.softspark/ai-toolkit/hooks/session-end.sh` |
|
|
9275
9282
|
| Fires | When a Claude session ends |
|
|
9276
9283
|
|
|
9277
|
-
**Action:** Writes
|
|
9284
|
+
**Action:** Writes `session-end.md` to the per-repo session store (`~/.softspark/ai-toolkit/sessions/<repo-key>/`) with a lightweight handoff note for the next session and reminds the next session to review preserved context.
|
|
9278
9285
|
|
|
9279
9286
|
Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
9280
9287
|
|
|
@@ -9347,17 +9354,6 @@ Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
|
9347
9354
|
|
|
9348
9355
|
**Action:** Non-blocking (always exits 0). Inspects Bash commands containing `git commit`. Extracts the commit message from the `-m` flag and checks it against Conventional Commits format (`type: description`, where type is one of feat/fix/docs/refactor/test/chore/ci/perf/style/revert). Emits an advisory warning if the message does not match — the commit is not blocked, only nudged. Commands without `git commit` or without a `-m` message (e.g. interactive commits) are ignored.
|
|
9349
9356
|
|
|
9350
|
-
### SessionStart — `session-context.sh`
|
|
9351
|
-
|
|
9352
|
-
| Field | Value |
|
|
9353
|
-
|-------|-------|
|
|
9354
|
-
| Event | `SessionStart` |
|
|
9355
|
-
| Matcher | *(all)* |
|
|
9356
|
-
| Script | `~/.softspark/ai-toolkit/hooks/session-context.sh` |
|
|
9357
|
-
| Fires | Session start |
|
|
9358
|
-
|
|
9359
|
-
**Action:** Captures an environment snapshot to `~/.softspark/ai-toolkit/sessions/current-context.json`. Records working directory, git branch, git status summary, Node.js version, Python version, and timestamp. Used by other hooks and tools to access session metadata without re-running discovery commands. Skipped when `TOOLKIT_HOOK_PROFILE=minimal`.
|
|
9360
|
-
|
|
9361
9357
|
---
|
|
9362
9358
|
|
|
9363
9359
|
## New Hooks (Constitution Art. VI Enforcement)
|
|
@@ -9516,8 +9512,8 @@ commands explicitly silent, and Codex-generated hooks plus Claude's bundled
|
|
|
9516
9512
|
├── _locate-toolkit.sh # NEW: shared $TOOLKIT_DIR locator
|
|
9517
9513
|
├── _hook-io.sh # NEW: shared multi-editor payload/output adapter
|
|
9518
9514
|
├── _search-capability.sh # NEW: capability-aware search-first enforcement
|
|
9515
|
+
├── _session-paths.sh # NEW: per-repo session storage path resolver
|
|
9519
9516
|
├── session-start.sh
|
|
9520
|
-
├── session-context.sh
|
|
9521
9517
|
├── guard-destructive.sh
|
|
9522
9518
|
├── guard-path.sh
|
|
9523
9519
|
├── guard-config.sh
|
|
@@ -9545,7 +9541,7 @@ commands explicitly silent, and Codex-generated hooks plus Claude's bundled
|
|
|
9545
9541
|
|
|
9546
9542
|
~/.claude/settings.json
|
|
9547
9543
|
└── hooks: # Hook definitions referencing ~/.softspark/ai-toolkit/hooks/
|
|
9548
|
-
├── SessionStart → session-start.sh, mcp-health.sh
|
|
9544
|
+
├── SessionStart → session-start.sh, mcp-health.sh
|
|
9549
9545
|
├── Notification → notify-waiting.sh
|
|
9550
9546
|
├── PreToolUse → guard-destructive.sh, guard-path.sh, guard-config.sh, commit-quality.sh, revert-guard.sh
|
|
9551
9547
|
├── UserPromptSubmit → user-prompt-submit.sh, track-usage.sh
|
|
@@ -9586,7 +9582,7 @@ Windsurf rebranded to Devin Desktop (2026-06-02); the Cascade agent — and its
|
|
|
9586
9582
|
Devin CLI uses a **Claude-compatible** hook format (docs.devin.ai/cli/extensibility/hooks). Key facts driving the generator:
|
|
9587
9583
|
|
|
9588
9584
|
- **Standalone file shape:** in `.devin/hooks.v1.json` the entire file IS the hooks object — no top-level `"hooks"` wrapper key (unlike `.claude/settings.json`).
|
|
9589
|
-
- **Events:** Claude-style PascalCase — `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop
|
|
9585
|
+
- **Events:** Claude-style PascalCase — `PreToolUse`, `PostToolUse`, `UserPromptSubmit`, `Stop`. `post_cascade_response` maps to `Stop` (which carries no response text on stdin).
|
|
9590
9586
|
- **Matchers:** regex against the Devin **tool name** (`read`, `edit`, `exec`, `grep`, `glob`, `mcp__<server>__<tool>`) — NOT Claude's `Bash`/`Edit`, so the shared guards reliably fire.
|
|
9591
9587
|
- **Block contract:** the guard scripts emit `{"decision":"block","reason":...}` on stdout (plain mode) AND exit 2 — Devin honors both. Hooks run **without** `AI_TOOLKIT_HOOK_FORMAT=json` because Devin expects the flat `{"decision","reason"}` shape, not Claude's `hookSpecificOutput` envelope.
|
|
9592
9588
|
- **Stdin payload:** flat `{ "hook_event_name", "tool_name", "tool_input" }` — already handled by `_hook-io.sh` via its `.tool_name` / `.tool_input.*` branches, so no normalizer change was needed.
|
|
@@ -11057,7 +11053,7 @@ Each command file carries the prompt in its markdown body (built from the SKILL.
|
|
|
11057
11053
|
|
|
11058
11054
|
| opencode event | Bash hook(s) |
|
|
11059
11055
|
|----------------------------|--------------------------------------------------------------------|
|
|
11060
|
-
| `session.created` | `session-start.sh` + `
|
|
11056
|
+
| `session.created` | `session-start.sh` + `mcp-health.sh` |
|
|
11061
11057
|
| `session.compacted` | `pre-compact.sh` + `pre-compact-save.sh` (PreCompact equivalent) |
|
|
11062
11058
|
| `session.deleted` | `session-end.sh` + `save-session.sh` |
|
|
11063
11059
|
| `message.updated` | `user-prompt-submit.sh` + `track-usage.sh` |
|
|
@@ -12062,7 +12058,7 @@ The canonical data lives in **`scripts/ecosystem_tools.json`** and is consumed b
|
|
|
12062
12058
|
| Config paths | `AGENTS.md`, `.agents/skills/*/SKILL.md`, `.codex/hooks.json`, `.codex/config.toml` (project layers, root→cwd, closest wins, trusted projects only), `~/.codex/config.toml` |
|
|
12063
12059
|
| Our generators | `scripts/generate_codex.py`, `scripts/generate_codex_hooks.py`, `scripts/generate_codex_skills.py` (opt-in via `--codex-skills`) |
|
|
12064
12060
|
| Rules delivery | Universal coding rules are inlined into `AGENTS.md` (Codex reads instructions only from AGENTS.md, not `.agents/rules/`); language rules ship as `<lang>-rules` skills under `.agents/skills/`. |
|
|
12065
|
-
| Tracked hook events | Upstream canonical (codex-rs `HookEventName` enum): `PreToolUse`, `PostToolUse`, `PermissionRequest`, `PreCompact`, `PostCompact`, `SessionStart`, `UserPromptSubmit`, `SubagentStart`, `SubagentStop`, `Stop` (10 events). We wire
|
|
12061
|
+
| Tracked hook events | Upstream canonical (codex-rs `HookEventName` enum): `PreToolUse`, `PostToolUse`, `PermissionRequest`, `PreCompact`, `PostCompact`, `SessionStart`, `UserPromptSubmit`, `SubagentStart`, `SubagentStop`, `Stop` (10 events). We wire 9 of these to shared toolkit hook scripts, mirroring the Claude Code mapping in `app/hooks.json`. `PostCompact` is not wired (its only hook was the removed environment-snapshot probe). |
|
|
12066
12062
|
| Tracked handler types | `command` (emitted by default); `prompt` and `agent` available upstream but authored by hand |
|
|
12067
12063
|
| Other capabilities | `AGENTS.md`, `config.toml`, `mcp_servers`, sandbox policies, `.agents/skills/*/SKILL.md` (native Codex skill discovery path) |
|
|
12068
12064
|
| Version probe | `codex --version` |
|
|
@@ -12244,7 +12240,6 @@ Hook logic lives in `app/hooks/*.sh` — not inline JSON one-liners. Scripts are
|
|
|
12244
12240
|
|-------|--------|--------|
|
|
12245
12241
|
| SessionStart | `session-start.sh` | MANDATORY rules reminder + session context + instincts + reset session-edit state |
|
|
12246
12242
|
| SessionStart | `mcp-health.sh` | Check MCP server command availability (non-blocking warning) |
|
|
12247
|
-
| SessionStart | `session-context.sh` | Capture environment snapshot to `~/.softspark/ai-toolkit/sessions/current-context.json` |
|
|
12248
12243
|
| Notification | `notify-waiting.sh` | Cross-platform desktop notification |
|
|
12249
12244
|
| PreToolUse | `guard-destructive.sh` | Block `rm -rf`, `DROP TABLE`, etc. |
|
|
12250
12245
|
| PreToolUse | `guard-path.sh` | Block wrong-user path hallucination |
|
package/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@softspark/ai-toolkit",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.10.0",
|
|
4
4
|
"description": "AI coding toolkit: 108 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",
|
|
@@ -33,7 +33,6 @@ CODEX_HOOKS: dict[str, list[tuple[str, str]]] = {
|
|
|
33
33
|
"SessionStart": [
|
|
34
34
|
("startup|resume", "session-start.sh"),
|
|
35
35
|
("startup|resume", "mcp-health.sh"),
|
|
36
|
-
("startup|resume", "session-context.sh"),
|
|
37
36
|
],
|
|
38
37
|
"PreToolUse": [
|
|
39
38
|
("Bash", "guard-destructive.sh"),
|
|
@@ -67,10 +66,6 @@ CODEX_HOOKS: dict[str, list[tuple[str, str]]] = {
|
|
|
67
66
|
("", "pre-compact.sh"),
|
|
68
67
|
("", "pre-compact-save.sh"),
|
|
69
68
|
],
|
|
70
|
-
"PostCompact": [
|
|
71
|
-
# Re-establish working context after compaction.
|
|
72
|
-
("", "session-context.sh"),
|
|
73
|
-
],
|
|
74
69
|
"Stop": [
|
|
75
70
|
("", "quality-check.sh"),
|
|
76
71
|
("", "save-session.sh"),
|
|
@@ -61,11 +61,6 @@ DEVIN_HOOKS: dict[str, list[tuple[str, list[str]]]] = {
|
|
|
61
61
|
"Stop": [
|
|
62
62
|
("", ["quality-check.sh", "save-session.sh", "stop-search-check.sh"]),
|
|
63
63
|
],
|
|
64
|
-
# Cascade's post_setup_worktree has no Devin equivalent; session-context
|
|
65
|
-
# moves to SessionStart (Devin fires SessionStart when a session begins).
|
|
66
|
-
"SessionStart": [
|
|
67
|
-
("", ["session-context.sh"]),
|
|
68
|
-
],
|
|
69
64
|
}
|
|
70
65
|
|
|
71
66
|
|
|
@@ -40,7 +40,6 @@ GEMINI_HOOKS: dict[str, list[tuple[str, str]]] = {
|
|
|
40
40
|
"SessionStart": [
|
|
41
41
|
("", "session-start.sh"),
|
|
42
42
|
("", "mcp-health.sh"),
|
|
43
|
-
("", "session-context.sh"),
|
|
44
43
|
],
|
|
45
44
|
"BeforeTool": [
|
|
46
45
|
# run_shell_command covers Bash-equivalent destructive patterns
|
|
@@ -67,10 +66,6 @@ GEMINI_HOOKS: dict[str, list[tuple[str, str]]] = {
|
|
|
67
66
|
("", "save-session.sh"),
|
|
68
67
|
("", "stop-search-check.sh"),
|
|
69
68
|
],
|
|
70
|
-
"BeforeModel": [
|
|
71
|
-
# Light-weight observability slot. Reuses the session-context probe.
|
|
72
|
-
("", "session-context.sh"),
|
|
73
|
-
],
|
|
74
69
|
"SessionEnd": [
|
|
75
70
|
("", "session-end.sh"),
|
|
76
71
|
],
|
|
@@ -11,7 +11,7 @@ opencode lifecycle events. Coverage map:
|
|
|
11
11
|
|
|
12
12
|
opencode event -> ai-toolkit Bash hook(s)
|
|
13
13
|
---------------------------------------------------------------
|
|
14
|
-
session.created -> session-start.sh +
|
|
14
|
+
session.created -> session-start.sh + mcp-health.sh
|
|
15
15
|
session.compacted -> pre-compact.sh + pre-compact-save.sh
|
|
16
16
|
session.deleted -> session-end.sh + save-session.sh
|
|
17
17
|
message.updated -> user-prompt-submit.sh + track-usage.sh
|
|
@@ -79,7 +79,6 @@ export const AiToolkitHooks = async ({ $, project, directory, worktree }) => ({
|
|
|
79
79
|
switch (event.type) {
|
|
80
80
|
case "session.created":
|
|
81
81
|
await runHook($, "session-start.sh", payload);
|
|
82
|
-
await runHook($, "session-context.sh", payload);
|
|
83
82
|
await runHook($, "mcp-health.sh", payload);
|
|
84
83
|
break;
|
|
85
84
|
case "session.compacted":
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# session-context.sh — Capture session context at start for later reference.
|
|
3
|
-
#
|
|
4
|
-
# Fires on: SessionStart
|
|
5
|
-
# Saves environment snapshot to JSON for cross-hook and cross-session use.
|
|
6
|
-
# Skipped when TOOLKIT_HOOK_PROFILE=minimal.
|
|
7
|
-
|
|
8
|
-
# shellcheck source=_profile-check.sh
|
|
9
|
-
source "$(dirname "$0")/_profile-check.sh"
|
|
10
|
-
|
|
11
|
-
# Read from stdin (Claude Code passes JSON with .session_id)
|
|
12
|
-
INPUT=$(cat)
|
|
13
|
-
SESSION=$(echo "$INPUT" | jq -r '.session_id // empty' 2>/dev/null)
|
|
14
|
-
[ -z "$SESSION" ] && SESSION="$$"
|
|
15
|
-
SESSIONS_DIR="$HOME/.softspark/ai-toolkit/sessions"
|
|
16
|
-
mkdir -p "$SESSIONS_DIR"
|
|
17
|
-
|
|
18
|
-
CONTEXT_FILE="$SESSIONS_DIR/${SESSION}.json"
|
|
19
|
-
|
|
20
|
-
# Gather context
|
|
21
|
-
WORKDIR="$(pwd)"
|
|
22
|
-
GIT_BRANCH=""
|
|
23
|
-
GIT_STATUS=""
|
|
24
|
-
if command -v git >/dev/null 2>&1 && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
|
|
25
|
-
GIT_BRANCH=$(git branch --show-current 2>/dev/null || echo "detached")
|
|
26
|
-
GIT_STATUS=$(git status --short 2>/dev/null | head -20)
|
|
27
|
-
fi
|
|
28
|
-
|
|
29
|
-
NODE_VERSION=""
|
|
30
|
-
if command -v node >/dev/null 2>&1; then
|
|
31
|
-
NODE_VERSION=$(node --version 2>/dev/null)
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
PYTHON_VERSION=""
|
|
35
|
-
if command -v python3 >/dev/null 2>&1; then
|
|
36
|
-
PYTHON_VERSION=$(python3 --version 2>/dev/null | awk '{print $2}')
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
CURRENT_DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
40
|
-
|
|
41
|
-
# Write JSON using python3 for proper escaping
|
|
42
|
-
python3 - "$CONTEXT_FILE" "$WORKDIR" "$GIT_BRANCH" "$GIT_STATUS" "$CURRENT_DATE" "$NODE_VERSION" "$PYTHON_VERSION" <<'PY'
|
|
43
|
-
import json
|
|
44
|
-
import sys
|
|
45
|
-
import os
|
|
46
|
-
|
|
47
|
-
context_file = sys.argv[1]
|
|
48
|
-
data = {
|
|
49
|
-
"pwd": sys.argv[2],
|
|
50
|
-
"git_branch": sys.argv[3],
|
|
51
|
-
"git_status": sys.argv[4],
|
|
52
|
-
"date": sys.argv[5],
|
|
53
|
-
"node_version": sys.argv[6],
|
|
54
|
-
"python_version": sys.argv[7],
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
tmp = context_file + ".tmp"
|
|
58
|
-
with open(tmp, "w") as f:
|
|
59
|
-
json.dump(data, f, indent=2)
|
|
60
|
-
os.replace(tmp, context_file)
|
|
61
|
-
PY
|
|
62
|
-
|
|
63
|
-
exit 0
|