grip_hook.integrations¶
grip_hook.integrations ¶
Wire grip into the coding agents on this machine.
grip agents looks for the agents a developer has installed (a binary on PATH or a
configuration directory under the home directory) and writes, inside the repository, the
file each one reads: a rule block in AGENTS.md for Codex and the other agents that
honour it, GEMINI.md for Gemini CLI, CLAUDE.md plus the plugin enablement in
.claude/settings.json for Claude Code, and a rules file for Cursor, Windsurf, Cline and
Copilot. Every write is marked so the same command can update or remove it later. Nothing
is written outside the repository and nothing is sent anywhere.
START
module-attribute
¶
First line of a block grip manages inside a file the developer owns.
RULES
module-attribute
¶
RULES = '## grip\n\nThis repository uses [grip](https://guilyx.github.io/grip/): the developer must pass a\nfive-question quiz about their own diff before it goes upstream.\n\nBefore `git push`, run `grip check --unpushed`. If it exits 1, run `grip ask --unpushed`,\nshow the developer the questions verbatim, wait for their answers, then run\n`grip grade --answers -` with the answers as a JSON list of five strings. Never answer\nthe questions yourself, never hint, and never open the diff to help them. Push only after\n`grip check --unpushed` exits 0. If `grip` is missing, install it with\n`curl -fsSL https://raw.githubusercontent.com/guilyx/grip/main/install.sh | sh`.\n'
The instructions every agent gets, as Markdown.
AGENTS
module-attribute
¶
AGENTS: tuple[Agent, ...] = (Agent('agents-md', 'AGENTS.md readers', (), (), (_AGENTS_MD,), always=True), Agent('claude-code', 'Claude Code', ('claude',), ('.claude',), (Target('CLAUDE.md', Kind.BLOCK), Target('.claude/settings.json', Kind.SETTINGS))), Agent('codex', 'Codex CLI', ('codex',), ('.codex',), (_AGENTS_MD,)), Agent('gemini', 'Gemini CLI', ('gemini',), ('.gemini',), (Target('GEMINI.md', Kind.BLOCK),)), Agent('cursor', 'Cursor', ('cursor',), ('.cursor',), (Target('.cursor/rules/grip.mdc', Kind.FILE, '---\ndescription: grip quiz before push\nalwaysApply: true\n---\n'),)), Agent('windsurf', 'Windsurf', ('windsurf',), ('.codeium/windsurf',), (Target('.windsurf/rules/grip.md', Kind.FILE, '---\ntrigger: always_on\n---\n'),)), Agent('cline', 'Cline', (), ('.cline', '.vscode/extensions/saoudrizwan.claude-dev*'), (Target('.clinerules/grip.md', Kind.FILE),)), Agent('copilot', 'GitHub Copilot', ('copilot',), ('.copilot', '.vscode/extensions/github.copilot*'), (Target('.github/copilot-instructions.md', Kind.BLOCK),)), Agent('opencode', 'OpenCode', ('opencode',), ('.config/opencode',), (_AGENTS_MD,)))
Every agent grip agents can configure, in display order.
Kind ¶
Bases: StrEnum
How grip writes to a target file.
Source code in src/grip_hook/integrations.py
BLOCK
class-attribute
instance-attribute
¶
A marked block appended to a file the developer owns (AGENTS.md).
FILE
class-attribute
instance-attribute
¶
A whole file grip owns (.cursor/rules/grip.mdc).
SETTINGS
class-attribute
instance-attribute
¶
Keys merged into a JSON settings file (.claude/settings.json).
Target
dataclass
¶
One file an agent reads, relative to the repository root with / separators.
Source code in src/grip_hook/integrations.py
frontmatter
class-attribute
instance-attribute
¶
Prepended to whole files: the agent's own metadata header.
Agent
dataclass
¶
A coding agent grip knows how to configure.
Source code in src/grip_hook/integrations.py
Action ¶
Bases: StrEnum
What happened to one target file.
Source code in src/grip_hook/integrations.py
Change
dataclass
¶
The outcome for one target file.
Source code in src/grip_hook/integrations.py
agents
instance-attribute
¶
Display names of the agents that read this file.
agent ¶
Look an agent up by its command-line key.
Source code in src/grip_hook/integrations.py
is_installed ¶
is_installed(target: Agent, home: Path | None = None, which: Callable[[str], str | None] | None = None) -> bool
Whether target looks installed: a binary on PATH or a directory under home.
Source code in src/grip_hook/integrations.py
detect ¶
The agents that look installed, plus the always-on generic AGENTS.md.
Source code in src/grip_hook/integrations.py
block ¶
apply ¶
apply(root: Path, agents: Iterable[Agent], *, remove: bool = False, dry_run: bool = False) -> list[Change]
Write (or remove) every target of agents under root.
A file shared by several agents, like AGENTS.md, is written once. With dry_run
nothing is touched and the actions say what would happen.