Back to catalogue
ContextSessionStartSessionStartOn Claude Code session start· non-blocking
GitHub context loader
Open PRs and CI status loaded before you ask
At session start, injects the repository GitHub state via the gh CLI: open pull requests (up to 5) and check status for the current branch PR. Local git context tells the agent where the working tree is; this hook covers the blind spot of what is happening on GitHub. Silent no-op when gh is missing, unauthenticated, or the repo has no GitHub remote.
What does the GitHub context loader hook do?
GitHub context loader is a Claude Code SessionStart hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. Open PRs and CI status loaded before you ask.
Use cases
- Resuming work with awareness of PRs awaiting review
- Reacting to failing CI checks without being asked to look
- Avoiding duplicate work on changes already in an open PR
Tags
#context#github#ci#productivity
settings.json fragment
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/session-start-github-context.mjs"
}
]
}
]
}
}Script · .claude/hooks/session-start-github-context.mjs
#!/usr/bin/env node
// Injecte l'état GitHub (PRs ouvertes, checks de la branche) au démarrage de session (SessionStart)
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
function defaultExec(cmd) {
try {
return execSync(cmd, { encoding: 'utf8', timeout: 10_000, stdio: 'pipe' }).trim();
} catch {
return '';
}
}
export function run(_input, { exec = defaultExec } = {}) {
// Silencieux si gh absent, non authentifié ou dépôt sans remote GitHub
const prs = exec('gh pr list --state open --limit 5');
const checks = exec('gh pr checks 2>/dev/null');
if (!prs && !checks) return null;
const lines = ['## GitHub Context'];
if (prs) lines.push('### Open PRs', '```', prs, '```');
if (checks) lines.push('### Checks on current branch PR', '```', checks, '```');
return {
hookSpecificOutput: {
hookEventName: 'SessionStart',
additionalContext: lines.join('\n'),
},
};
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
if (result) process.stdout.write(JSON.stringify(result));
}