- Add 6 agent definitions (devils-advocate, implementer, proponent, research-lens, spike-runner, verifier) for specialized AI team workflows - Add 4 team slash commands (battle-test, debate, dev-loop, spikes) - Add openspec-journal.py processor + pre-compaction hook script - Update settings.json and .mcp.json for agent team support
65 lines
2.3 KiB
Bash
Executable file
65 lines
2.3 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Pre-compact hook for the OpenSpec journal.
|
|
#
|
|
# Emits a `context.compacted` event into the journal of the most recently
|
|
# active OpenSpec change, if one exists. Stays silent (exit 0) when there
|
|
# is nothing to log so it does not block compaction.
|
|
#
|
|
# Claude Code wires this as a `PreCompact` hook. Other agent clients can
|
|
# call the same script from an equivalent lifecycle hook; set
|
|
# OPEN_SPEC_JOURNAL_AGENT to label the emitted event, for example:
|
|
#
|
|
# OPEN_SPEC_JOURNAL_AGENT=Codex /abs/path/to/scripts/openspec-journal-precompact-hook.sh
|
|
#
|
|
# Wire via `~/.claude/settings.json` or `.claude/settings.json`:
|
|
#
|
|
# {
|
|
# "hooks": {
|
|
# "PreCompact": [
|
|
# {"hooks": [{"type": "command",
|
|
# "command": "/abs/path/to/scripts/openspec-journal-precompact-hook.sh"
|
|
# }]}
|
|
# ]
|
|
# }
|
|
# }
|
|
#
|
|
# The script is intentionally tolerant: any failure (no repo, no active
|
|
# change, journal helper missing) is silently ignored so compaction is
|
|
# never blocked by journaling.
|
|
|
|
set -u
|
|
|
|
repo_root="$(git rev-parse --show-toplevel 2>/dev/null || true)"
|
|
[ -n "${repo_root}" ] || exit 0
|
|
|
|
helper="${repo_root}/scripts/openspec-journal.py"
|
|
changes_dir="${repo_root}/openspec/changes"
|
|
agent="${OPEN_SPEC_JOURNAL_AGENT:-Claude Code}"
|
|
[ -x "${helper}" ] && [ -d "${changes_dir}" ] || exit 0
|
|
|
|
# Pick the most recently modified non-archive journal.
|
|
journal=$(find "${changes_dir}" -mindepth 2 -maxdepth 3 -name journal.jsonl \
|
|
-not -path "*/archive/*" -print 2>/dev/null \
|
|
| xargs -I {} stat -f '%m {}' {} 2>/dev/null \
|
|
| sort -rn | head -n 1 | awk '{ $1=""; print substr($0,2) }')
|
|
|
|
[ -n "${journal}" ] || exit 0
|
|
|
|
# Only journal compactions for changes touched in the last 6 hours; older
|
|
# trails belong to changes the user has likely moved on from.
|
|
journal_mtime=$(stat -f '%m' "${journal}" 2>/dev/null || stat -c '%Y' "${journal}" 2>/dev/null || true)
|
|
now=$(date +%s 2>/dev/null || true)
|
|
case "${journal_mtime}" in ''|*[!0-9]*) exit 0 ;; esac
|
|
case "${now}" in ''|*[!0-9]*) exit 0 ;; esac
|
|
if [ "$((now - journal_mtime))" -gt 21600 ]; then
|
|
exit 0
|
|
fi
|
|
|
|
change=$(basename "$(dirname "${journal}")")
|
|
|
|
"${helper}" "${change}" context.compacted \
|
|
input="${agent} PreCompact hook fired during ${change}." \
|
|
output="Context compaction observed; chat continuation may follow." \
|
|
>/dev/null 2>&1 || true
|
|
|
|
exit 0
|