README.md is for humans (install, features, links). This file is for coding agents editing the plugin or debugging hook behavior. Keep changes aligned with both; do not duplicate the full README here.
Inspired by oh-my-openagent. Upstream handoff/Ralph/boulder behavior is ported and adapted for Grok Composer + grok plugin.
| Is | Is not |
|---|---|
A Grok plugin (plugin.json, hooks/hooks.json, bundled skills/rules) |
A standalone CLI or application users run from this repo |
Go hook binary (bin/omg-hook-*) + thin hooks/run-hook.sh |
User application code |
Install target: grok plugin install github:mihazs/oh-my-grok --trust |
Global copies under ~/.grok/hooks/ (deprecated; plugin-only) |
After install, Grok loads hooks from GROK_PLUGIN_ROOT (installed copy under ~/.grok/installed-plugins/oh-my-grok-*, often symlinked to a local clone).
plugin.json
hooks/hooks.json → SessionStart, UserPromptSubmit, Pre/PostToolUse, Stop, SessionEnd
hooks/run-hook.sh → dispatches to bin/omg-hook-<os>-<arch>
cmd/omg-hook + internal/ → all hook logic (see docs/superpowers/plans/2026-06-02-go-hooks-migration.md)
cmd/user_prompt.go → single merged additionalContext (do not split into multiple JSON hooks)
cmd/stop.go → ralph → boulder → todo → lsp → plan.md (first block wins)
internal/skillgate/ → catalog, PreTool gate, reminders
internal/intentgate/ → keyword modes
internal/prometheus/ → /plan, plan-mode PreTool guard
internal/hashline/ → read cache, LINE#ID PreTool guard
internal/lsp/ → diagnostics stash, post-tool + Stop
internal/ralph/ → /ralph-loop, /ulw-loop, /cancel-ralph
internal/boulder/ → boulder + todo continuation + todo enforcer state
skills/*/SKILL.md → user-invocable workflows (discovered by grok inspect)
rules/*.md → injected on every UserPromptSubmit (with workspace AGENTS.md)
superpowers skills are bundled at vendor/superpowers/skills/ (plugin.json skills paths). Do not register duplicate oh-my-grok hooks globally. Refresh vendor: task vendor:superpowers.
| Location | Owner | Examples |
|---|---|---|
~/.grok/ |
Grok harness | installed-plugins/, state/skill-gate/, state/hashline/, state/lsp-diagnostics/, state/todo-enforcer/, state/stop-continuation/, sessions/ |
.omg/ (per workspace) |
oh-my-grok runtime | boulder.json, plans/, todos/, ralph-loop.local.md, handoffs/ |
Analogous to omo’s .omo/ in OpenCode workspaces. Never store plugin source or session catalogs under .omg/.
| Skill | Command | Hook involvement |
|---|---|---|
agent-skill-gate |
(meta; Read before mutating) | session-start, user-prompt, pre-tool-use, post-tool-read |
ralph-loop |
/ralph-loop "task" |
user-prompt, stop |
ulw-loop |
/ulw-loop "task" |
same + Oracle verification pending |
cancel-ralph |
/cancel-ralph |
clears .omg/ralph-loop.local.md |
handoff |
/handoff |
user-prompt injects PHASE 0–4 instructions |
prometheus-plan |
/plan, /prometheus |
user-prompt + pre-tool-use |
hashline-edit |
(workflow) | hashline package, post-tool-read |
ast-grep |
MCP tools | .mcp.json + vendor/ast-grep-mcp |
lsp |
MCP + hook stash | post-tool-lsp, Stop step 4 (optional node) |
User-facing pause/resume: /stop-continuation, /resume-continuation (see rules/12-todo-boulder.md).
Full event map and stop priority: hooks/README.md (read when touching Stop or UserPromptSubmit).
| Task | Read first |
|---|---|
| Install / publish / repo URL | README.md, docs/installation.md |
Hook events, stop chain, .omg/ layout |
hooks/README.md |
| Skill-gate behavior | skills/agent-skill-gate/SKILL.md, rules/00-agent-skill-gate.md |
| Ralph / ultrawork | skills/ralph-loop/SKILL.md, skills/ulw-loop/SKILL.md, rules/10-ralph-loop.md |
| Boulder + todos | rules/12-todo-boulder.md, internal/boulder/ |
| Handoff format | skills/handoff/SKILL.md, rules/11-handoff.md |
| IntentGate / Prometheus / hashline / LSP | hooks/lib/{intent-gate,prometheus,hashline,lsp}.sh, docs/configuration.md |
| ast-grep MCP build | scripts/build-mcp-runtimes.sh, vendor/ast-grep-mcp/ |
| Remove stale global install | scripts/remove-global-overlays.sh |
Do not paste entire skill bodies into this file. Load the path from grok inspect when implementing.
- Clone repo; set
export GROK_PLUGIN_ROOT="$(pwd)"for local hook tests. - Edit
hooks/,skills/, orrules/— see decision table below. - Run smoke tests (required before claiming done):
cd oh-my-grok
grok plugin validate .
export GROK_PLUGIN_ROOT="$(pwd)"
bash hooks/test-ralph-loop.sh
bash hooks/test-ulw-loop.sh
bash hooks/test-todo-boulder.sh
bash hooks/test-stop-verify.sh
bash hooks/test-using-superpowers-first-prompt.sh
bash hooks/test-handoff.sh
bash hooks/test-workspace-context.sh
bash hooks/test-intent-gate.sh
bash hooks/test-prometheus.sh
bash hooks/test-hashline.sh
bash hooks/test-lsp.sh- Refresh install:
grok plugin update oh-my-grok(orgrok plugin install "$(pwd)" --trust). - New Grok session or TUI Hooks reload (
Ctrl+L) — hooks do not always hot-reload mid-session.
Optional E2E: bash hooks/test-inline-skill-gate.sh (needs grok CLI + trusted workspace).
| You need to… | Edit | Avoid |
|---|---|---|
| New slash command or prompt injection | hooks/lib/*.sh, wire in user-prompt.sh |
Extra UserPromptSubmit JSON in hooks.json (overwrites context) |
| New lifecycle hook event | hooks/hooks.json + new script under hooks/ |
Duplicate manifest under ~/.grok/hooks/ |
| Agent-facing workflow / phases | skills/<name>/SKILL.md |
Long prose only in rules/ without a skill |
| Always-on Composer rules | rules/*.md (keep short) |
30+ “don’t” lines without “do” alternatives |
| Workspace file paths (boulder, todos) | internal/boulder/ constants + docs |
Hardcoded /home/... paths anywhere in repo |
| Stop continuation order | hooks/lib/stop-chain.sh only |
Second Stop hook registration |
| IntentGate keyword modes | hooks/lib/intent-gate.sh, rules/13-intent-gate.md |
Duplicate mode logic in user-prompt.sh |
| Prometheus plan mode | hooks/lib/prometheus.sh, skills/prometheus-plan/ |
Allow non-.omg writes while plan mode active |
| Hashline LINE#ID guard | hooks/lib/hashline.sh, hashline.py, post-tool-read.sh |
Second PreToolUse hook in hooks.json |
| LSP stash + Stop block | hooks/lib/lsp.sh, post-tool-lsp.sh |
Inline LSP calls in stop-hook.sh |
| ast-grep / lsp MCP dist | scripts/build-mcp-runtimes.sh, vendor/* |
Commit node_modules (run build script) |
| Todo enforcer cooldown | internal/boulder/todos.go, internal/cmd/stop.go |
Ad-hoc sleep in stop handler |
| Feature smoke test | hooks/test-<feature>.sh |
Skipping tests when adding hooks/lib/*.sh |
Pair every don’t with a do in rules (e.g. don’t add global ~/.grok/hooks/*.json → do install via grok plugin install).
- SessionStart (
session-start.sh) — runsgrok inspect, caches catalog at~/.grok/state/skill-gate/<session>/all-skills.json, injects skill list + rules path. - UserPromptSubmit (
user-prompt.sh) —build_prompt_reminder()nudges unloaded skills each prompt. - PreToolUse (
pre-tool-mutate.sh) — onWrite/StrReplace/EditNotebook/Delete, deny if catalog is non-empty and noSKILL.mdwas Read this session (skills.loadedempty). - PostToolUse (
post-tool-read.sh) — when agent Reads a catalogSKILL.md, append skill id toskills.loaded. - Fail-open — empty catalog: allow edits after Reading meta-skill
agent-skill-gate.
Agent workflow: grok inspect → Read matching skills → announce Using <name> to <purpose> → mutating tools.
Human detail: docs/skills.md. Full meta-skill: skills/agent-skill-gate/SKILL.md.
- One JSON context per event —
user-prompt.shmerges allUserPromptSubmitparts; never add a second manifest entry for the same event. - Stop order — only change in
hooks/lib/stop-chain.sh; updatehooks/README.md+ tests. - New slash command — add
hooks/lib/<feature>.sh, source fromuser-prompt.sh, addskills/<name>/SKILL.mdwithuser_invocable: true, addhooks/test-<feature>.sh. - Workspace paths — constants in
internal/boulder/; never hardcode user home directories in tracked files. - Docs — human guides in
docs/andREADME.md; this file stays hook/skill oriented.
Human docs: docs/installation.md, docs/skills.md, docs/configuration.md. Roadmap: ROADMAP.md.
- Create
hooks/lib/my-feature.shwithcollect_user_prompt_my_feature()returning context text. - In
user-prompt.sh:sourcethe lib, call collector, pass intoemit_user_prompt_context. - Add
hooks/test-my-feature.shwithGROK_PLUGIN_ROOTset and stdin JSON fixture. - Document in
hooks/README.mdUserPromptSubmit list.
- Add
skills/my-skill/SKILL.mdwith frontmattername,description,user_invocable: true. - If the skill needs prompt injection, wire a collector in
user-prompt.sh(pattern:handoff.sh,ralph-loop.sh). - Run
grok plugin validate .and hook smoke tests.
- Shell:
bash,set -euo pipefail; hook entry viahooks/run-hook.sh. - Search: use
rg, notgrep, in docs and agent instructions for this repo. - Paths in repo: machine-agnostic (
$(pwd),oh-my-grok/); author metadata inplugin.json/ LICENSE is fine; no contributor home directories in source. - Hook JSON output: one
additionalContextper event per manifest path;user-prompt.shmerges parts. - Tests: temp dirs use
.omg/subdirs; do not depend on a specific user workspace path. - Go hooks (
internal/boulder/, etc.) stay compatible with omo boulder schema where possible.
- Registering the same hooks in
~/.grok/hooks/*.jsonand the plugin (double Stop / UserPromptSubmit). - Adding legacy
user-prompt-*.shhooks tohooks.json(merged handler exists). - Changing stop order without updating
hooks/README.mdand tests. - Documenting only
~/.grok/for boulder/ralph state — user workspaces use.omg/. - Bloating this AGENTS.md past ~150 lines; link to
hooks/README.mdand skills instead.
- CI hook smoke tests pass (same as
.github/workflows/ci.yml; skiptest-inline-skill-gate.sh) -
grok plugin validate .passes (local; Grok CLI not in CI) - All
hooks/test-*.shscripts pass withGROK_PLUGIN_ROOTset (except inline E2E) - Conventional commit message if the change should appear in the next release
- Do not bump
plugin.jsonversion — release-please handles it via Release PR - No leaked home-directory paths in tracked files
-
hooks/hooks.jsonuses${GROK_PLUGIN_ROOT}for commands - New skill has frontmatter
name+descriptiontriggers;user_invocable: trueif slash command
Human install docs: README.md. Hook internals: hooks/README.md.