A UserPromptSubmit hook for Codex. It enriches each incoming user message before the main Codex agent handles it.
The hook adds a <prompt-enhance> context block with:
- a rewritten English version of the current user request when the full enhancer runs;
- project context such as current working directory, Git root, branch, status, and nearby project docs;
- relevant local memory lines from Codex memory files;
- recent session continuity from the last 3 completed user/assistant turns.
It is designed to be safe for open-source use. No API keys, private endpoints, or machine-specific paths are included.
See docs/usage-visual-guide.md for the full visual walkthrough.
The hook has two modes.
full mode runs a lightweight Codex sub-process using model gpt-5.4 and reasoning effort medium. This happens when:
- the session has no completed user/assistant turns;
- the current prompt is long;
- the current prompt is multi-line;
- the current prompt contains a code block;
- the current prompt contains a concrete path or URL;
PROMPT_ENHANCE_FORCE_FULL=1is set.
fast-session-context mode does not call a model. It returns immediately when:
- the transcript has completed session turns;
- the current prompt is a short single-line follow-up.
In fast mode the hook injects the current user message plus the latest 3 completed session turns. Each turn contains:
user_message: preserved in full for each of the latest 3 turns;agent_reply_summary: only the first 1-3 non-empty lines of the assistant reply.
The same prepared context is also passed to the prompt-enhance agent before full mode runs. This keeps full mode and fast mode consistent.
From this repository:
python3 scripts/install.pyBy default it installs into $CODEX_HOME, or ~/.codex if CODEX_HOME is not set.
You can install elsewhere:
python3 scripts/install.py --codex-home /path/to/.codexThe installer writes:
hooks/prompt_enhance_user_prompt.pyagents/prompt-enhance.tomlprompts/prompt-rewriter.md- a merged
hooks.jsonentry forUserPromptSubmit
Existing hooks.json content is preserved and backed up before writing.
Run the local tests:
python3 -m unittest discover -s testsRun a hook dry run without a transcript. It should choose full mode:
printf '%s' '{"hook_event_name":"UserPromptSubmit","prompt":"new task","cwd":"'"$PWD"'"}' \
| PROMPT_ENHANCE_DRY_RUN=1 python3 hooks/prompt_enhance_user_prompt.pyRun a dry run with a transcript path from Codex. A short follow-up should choose fast mode when the transcript has completed user/assistant turns:
printf '%s' '{"hook_event_name":"UserPromptSubmit","prompt":"continue","cwd":"'"$PWD"'","transcript_path":"/path/to/rollout.jsonl"}' \
| PROMPT_ENHANCE_DRY_RUN=1 python3 hooks/prompt_enhance_user_prompt.pyEnvironment variables:
CODEX_HOME: Codex config directory. Defaults to~/.codex.PROMPT_ENHANCE_MODEL: model used for full mode. Defaults togpt-5.4.PROMPT_ENHANCE_REASONING: reasoning effort used for full mode. Defaults tomedium.PROMPT_ENHANCE_TIMEOUT_SECONDS: timeout for full mode. Defaults to120.PROMPT_ENHANCE_RULES: prompt rewriting rules file. Defaults to$CODEX_HOME/prompts/prompt-rewriter.md.PROMPT_ENHANCE_MAX_SESSION_TURNS: completed session turns to include. Defaults to3.PROMPT_ENHANCE_AGENT_REPLY_SUMMARY_LINES: assistant reply lines kept per turn. Defaults to3, clamped to1..3.PROMPT_ENHANCE_AGENT_REPLY_SUMMARY_CHARS: maximum characters for each assistant reply summary. Defaults to900.PROMPT_ENHANCE_MAX_SESSION_CONTEXT_CHARS: maximum characters for formatted recent session context. Defaults to12000.PROMPT_ENHANCE_FORCE_FULL=1: always use full mode.PROMPT_ENHANCE_DRY_RUN=1: do not call Codex; print the context that would be used.
The installed agent file is agents/prompt-enhance.toml. It uses:
name = "prompt-enhance"model = "gpt-5.4"model_reasoning_effort = "medium"sandbox_mode = "read-only"
If your Codex setup uses an agent registry, add an entry similar to:
[agents."prompt-enhance"]
path = "/path/to/.codex/agents/prompt-enhance.toml"
model_profile = "prompt_enhance_secondary"
reasoning_profile = "medium"
description = "Rewrite incoming user prompts into clear execution context before the main agent sees them."UserPromptSubmit can add hookSpecificOutput.additionalContext before the main agent receives the user message. It does not replace the original user message. The main agent sees the original prompt plus this extra context block.