|
#!/usr/bin/env bash |
|
# Install grok-turn-index into ~/.grok for Grok Build TUI. |
|
# Supports nested project layout OR flat gist layout (scripts__name). |
|
set -euo pipefail |
|
|
|
SRC="$(cd "$(dirname "$0")" && pwd)" |
|
GROK_HOME="${GROK_HOME:-$HOME/.grok}" |
|
PLUGIN_DST="${GROK_HOME}/plugins/turn-index" |
|
HOOKS_DST="${GROK_HOME}/hooks/turn-index.json" |
|
AGENTS_DST="${GROK_HOME}/AGENTS.md" |
|
|
|
stage="$(mktemp -d)" |
|
cleanup() { rm -rf "$stage"; } |
|
trap cleanup EXIT |
|
|
|
echo "==> Assembling plugin tree" |
|
mkdir -p "$stage"/{scripts,commands,hooks,skills/turns} |
|
|
|
if [[ -d "$SRC/scripts" ]]; then |
|
# Nested layout |
|
cp -a "$SRC/plugin.json" "$stage/" |
|
cp -a "$SRC/scripts/." "$stage/scripts/" |
|
cp -a "$SRC/commands/." "$stage/commands/" 2>/dev/null || true |
|
cp -a "$SRC/hooks/." "$stage/hooks/" 2>/dev/null || true |
|
cp -a "$SRC/skills/." "$stage/skills/" 2>/dev/null || true |
|
cp -a "$SRC/AGENTS.md" "$stage/" 2>/dev/null || true |
|
cp -a "$SRC/README.md" "$stage/" 2>/dev/null || true |
|
cp -a "$SRC/LICENSE" "$stage/" 2>/dev/null || true |
|
else |
|
# Flat gist layout: dir__path__file |
|
cp "$SRC/plugin.json" "$stage/" |
|
cp "$SRC/AGENTS.md" "$stage/" 2>/dev/null || true |
|
cp "$SRC/README.md" "$stage/" 2>/dev/null || true |
|
cp "$SRC/LICENSE" "$stage/" 2>/dev/null || true |
|
for f in "$SRC"/scripts__*; do |
|
[[ -e "$f" ]] || continue |
|
cp "$f" "$stage/scripts/${f##*scripts__}" |
|
done |
|
for f in "$SRC"/commands__*; do |
|
[[ -e "$f" ]] || continue |
|
cp "$f" "$stage/commands/${f##*commands__}" |
|
done |
|
for f in "$SRC"/hooks__*; do |
|
[[ -e "$f" ]] || continue |
|
cp "$f" "$stage/hooks/${f##*hooks__}" |
|
done |
|
for f in "$SRC"/skills__*; do |
|
[[ -e "$f" ]] || continue |
|
# skills__turns__SKILL.md → skills/turns/SKILL.md |
|
rel="${f##*skills__}" |
|
rel="${rel//__//}" |
|
mkdir -p "$stage/skills/$(dirname "$rel")" |
|
cp "$f" "$stage/skills/$rel" |
|
done |
|
fi |
|
|
|
chmod +x "$stage/scripts/"* 2>/dev/null || true |
|
|
|
echo "==> Installing plugin → ${PLUGIN_DST}" |
|
mkdir -p "${GROK_HOME}/plugins" "${GROK_HOME}/hooks" "${GROK_HOME}/plugin-data/turn-index" |
|
rm -rf "${PLUGIN_DST}" |
|
mkdir -p "${PLUGIN_DST}" |
|
cp -a "$stage"/. "${PLUGIN_DST}/" |
|
|
|
echo "==> Writing global hooks → ${HOOKS_DST}" |
|
TEMPLATE="${PLUGIN_DST}/hooks/global-hooks.template.json" |
|
if [[ -f "$TEMPLATE" ]]; then |
|
sed "s|__PLUGIN_ROOT__|${PLUGIN_DST}|g" "$TEMPLATE" > "${HOOKS_DST}" |
|
else |
|
# Fallback portable plugin-root form |
|
cat > "${HOOKS_DST}" << HOOKS |
|
{ |
|
"hooks": { |
|
"SessionStart": [{"hooks": [{"type": "command", "command": "${PLUGIN_DST}/scripts/rebuild-index", "timeout": 15}]}], |
|
"UserPromptSubmit": [{"hooks": [{"type": "command", "command": "${PLUGIN_DST}/scripts/on-prompt-submit", "timeout": 5}]}], |
|
"Stop": [{"hooks": [{"type": "command", "command": "${PLUGIN_DST}/scripts/on-turn-stop", "timeout": 10}]}] |
|
} |
|
} |
|
HOOKS |
|
fi |
|
|
|
echo "==> Installing AGENTS.md turn-label rules → ${AGENTS_DST}" |
|
if [[ -f "${AGENTS_DST}" ]] && ! grep -q 'Turn numbers (always on)' "${AGENTS_DST}" 2>/dev/null; then |
|
{ |
|
echo "" |
|
echo "<!-- begin turn-index -->" |
|
cat "${PLUGIN_DST}/AGENTS.md" |
|
echo "<!-- end turn-index -->" |
|
} >> "${AGENTS_DST}" |
|
echo " (appended to existing AGENTS.md)" |
|
elif [[ -f "${PLUGIN_DST}/AGENTS.md" ]]; then |
|
cp "${PLUGIN_DST}/AGENTS.md" "${AGENTS_DST}" |
|
fi |
|
|
|
cat > "${PLUGIN_DST}/config-snippet.toml" << SNIP |
|
# Optional: append to ~/.grok/config.toml |
|
[ui.notifications] |
|
condition = "always" |
|
events = ["turn_complete", "approval_required"] |
|
|
|
[[ui.notifications.hooks]] |
|
command = "${PLUGIN_DST}/scripts/notify-turn" |
|
events = ["turn_complete"] |
|
only_unfocused = false |
|
timeout_secs = 5 |
|
SNIP |
|
|
|
echo "" |
|
echo "Install complete." |
|
echo "" |
|
echo "Next steps:" |
|
echo " 1. grok plugin install ${PLUGIN_DST} --trust" |
|
echo " 2. Ensure [plugins].enabled includes \"turn-index\" in ~/.grok/config.toml" |
|
echo " 3. /hooks → r (or start a new Grok session)" |
|
echo " 4. /turns and /turn <n>" |
|
echo " 5. Replies should end with: ### 🔖 Turn N" |