Skip to content
Documentation
Hook

Hooks

What openwiki runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
openwiki
141 command2 hooks
Install
> /plugin marketplace add SoulKyu/openwiki-cc
> /plugin install openwiki@openwiki-cc

Ships with openwiki. Installing the plugin gets these hooks.

Where it lives

  • hooks/openwiki-gate.shGitHub
    Read the script
    #!/usr/bin/env sh
    # openwiki gate — spawn the wiki refresh only when source actually changed.
    #
    # Reproduces the wiki's Step 0 no-op check (getUpdateNoopStatus) in pure shell,
    # so a Stop/SessionEnd hook that fires every turn costs a few git commands
    # instead of a full frontier-model run that spins up only to find nothing to do.
    #
    # Install: copy to .claude/hooks/openwiki-gate.sh, then in .claude/settings.json:
    #   { "hooks": { "Stop": [ { "hooks": [
    #     { "type": "command", "command": "sh .claude/hooks/openwiki-gate.sh" } ] } ] } }
    set -eu
    
    [ -n "${OPENWIKI_HOOK:-}" ] && exit 0                   # child run: never re-trigger
    git rev-parse --git-dir >/dev/null 2>&1 || exit 0       # not a git repo → nothing to do
    
    meta=openwiki/.last-update.json
    head=$(git rev-parse HEAD 2>/dev/null) || exit 0
    # ponytail: sed-parse gitHead out of the flat JSON; jq if the shape ever nests.
    last=$([ -f "$meta" ] && sed -n 's/.*"gitHead":[[:space:]]*"\([^"]*\)".*/\1/p' "$meta" | head -1 || true)
    dirty=$(git status --short --untracked-files=all | grep -v 'openwiki/\.last-update\.json$' || true)
    
    # No recorded gitHead → upstream skips the no-op check → let claude decide.
    if [ -n "$last" ] && [ -z "$dirty" ]; then
      [ "$head" = "$last" ] && exit 0                        # HEAD unchanged + clean tree
      # HEAD moved but tree clean: skip when every changed path is under openwiki/.
      [ -z "$(git diff --name-only "$last..$head" | grep -v '^openwiki/' || true)" ] && exit 0
    fi
    
    OPENWIKI_HOOK=1 setsid claude -p '/openwiki:wiki update' --permission-mode acceptEdits >/dev/null 2>&1 &
    
  • hooks/test_gate.shGitHub
    Read the script
    #!/usr/bin/env sh
    # Self-check for openwiki-gate.sh. Stubs claude/setsid so nothing real runs.
    # Run: sh hooks/test_gate.sh   (exits non-zero on first failed assertion)
    set -eu
    gate=$(cd "$(dirname "$0")" && pwd)/openwiki-gate.sh
    tmp=$(mktemp -d)
    trap 'cd /; rm -rf "$tmp"' EXIT
    
    # Stubs on PATH: setsid execs its args; claude records that it was invoked.
    mkdir "$tmp/bin"
    printf '#!/bin/sh\nexec "$@"\n' > "$tmp/bin/setsid"
    printf '#!/bin/sh\ntouch "$SPAWNED"\n' > "$tmp/bin/claude"
    chmod +x "$tmp/bin/setsid" "$tmp/bin/claude"
    export PATH="$tmp/bin:$PATH"
    
    repo="$tmp/repo"; mkdir "$repo"; cd "$repo"
    git init -q && git config user.email t@t && git config user.name t
    echo hello > file.txt && git add . && git commit -qm init
    H=$(git rev-parse HEAD)
    mkdir openwiki
    
    run() {                                   # run() <label> <expect: spawn|skip>
      export SPAWNED="$tmp/spawned"; rm -f "$SPAWNED"
      sh "$gate"
      i=0; while [ ! -f "$SPAWNED" ] && [ $i -lt 20 ]; do sleep 0.05; i=$((i+1)); done
      got=skip; [ -f "$SPAWNED" ] && got=spawn
      if [ "$got" = "$2" ]; then echo "ok   - $1 ($got)"; else
        echo "FAIL - $1: expected $2, got $got"; exit 1; fi
    }
    
    # no meta → upstream skips no-op check → spawn
    run "no metadata file" spawn
    
    # meta HEAD==head, clean tree → skip
    printf '{"gitHead": "%s"}\n' "$H" > openwiki/.last-update.json
    run "clean tree, HEAD unchanged" skip
    
    # dirty source file → spawn
    echo change >> file.txt
    run "dirty source file" spawn
    git checkout -q file.txt
    
    # untracked openwiki/ file → spawn (only .last-update.json is excused in the tree)
    echo x > openwiki/page.md
    run "untracked openwiki/ file in tree" spawn
    rm openwiki/page.md
    
    # HEAD moved, source commit → spawn
    echo more >> file.txt && git commit -qam second
    run "HEAD moved with source change" spawn
    
    # record new head, HEAD-only-openwiki commit → skip
    printf '{"gitHead": "%s"}\n' "$(git rev-parse HEAD)" > openwiki/.last-update.json
    git add openwiki/.last-update.json && git commit -qm "openwiki: page" \
      && echo p > openwiki/p.md && git add openwiki/p.md && git commit -qm "openwiki only"
    run "HEAD moved but only openwiki/ paths" skip
    
    echo "all passed"
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

Ships withopenwiki

A native Claude Code and OpenAI Codex port of OpenWiki — an agent that generates and maintains a documentation wiki (openwiki/) for any repository.

Get the whole plugin
Stats
14
Stars
2
Forks
Maintained
Maintenance
Shell
Language
2mo ago
Last commit
2mo ago
Created

Repo: SoulKyu/openwiki-cc