HookStack
Back to catalogue
ContextUserPromptSubmit

Project conventions injection

The agent follows your conventions, unprompted

On every user prompt, automatically injects the project conventions (stack, style rules, constraints) by reading a conventions file, so the agent stays aligned without manual reminders.

What does the Project conventions injection hook do?

Project conventions injection is a Claude Code UserPromptSubmit hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. The agent follows your conventions, unprompted.

As a UserPromptSubmit hook it runs before the action completes, so it can block or adjust what Claude is about to do. Because it is a deterministic Node.js script, it executes on every matching event without relying on the model to remember — the guarantee that makes agentic workflows safe to automate.

Use cases

  • Code consistency
  • Agent onboarding
  • Team standards

Tags

#context#conventions#prompt#standards

settings.json fragment

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/inject-conventions.mjs",
            "type": "command"
          }
        ]
      }
    ]
  }
}

Script · .claude/hooks/inject-conventions.mjs

#!/usr/bin/env node
// @hookstack user-prompt-inject-conventions
// Injecte les règles d'agent dans chaque prompt (UserPromptSubmit)
import { existsSync, readFileSync } from "node:fs";
import { join } from "node:path";
import { fileURLToPath } from "node:url";

export function run({
	exists = existsSync,
	readFile = readFileSync,
	projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd(),
} = {}) {
	// Priorité : .claude/agent-rules.md > CONVENTIONS.md > absent (no-op)
	const candidates = [
		join(projectDir, ".claude", "agent-rules.md"),
		join(projectDir, "CONVENTIONS.md"),
	];

	const target = candidates.find(exists);
	if (!target) return null;

	const content = readFile(target, "utf8").trim();
	if (!content) return null;

	return `### Conventions du projet (injectées automatiquement)\n\n${content}\n`;
}

/* v8 ignore next 4 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
	const result = run();
	if (result) process.stdout.write(result);
}

Learn more

Related hooks