Skip to content

Add user.prompt_submit and stop project hooks to code-rs#581

Open
voarsh2 wants to merge 1 commit intojust-every:mainfrom
voarsh2:codex-cli-userpromot-stop-hooks
Open

Add user.prompt_submit and stop project hooks to code-rs#581
voarsh2 wants to merge 1 commit intojust-every:mainfrom
voarsh2:codex-cli-userpromot-stop-hooks

Conversation

@voarsh2
Copy link
Copy Markdown

@voarsh2 voarsh2 commented May 6, 2026

Summary

This PR extends code-rs project hooks with two new lifecycle events:

  • user.prompt_submit
  • stop

The goal is to bring code-rs closer to upstream Codex hook behavior for
prompt-time context injection and end-of-turn continuation, while staying
inside the existing project-hook architecture.

What changed

New project hook events

Added support for:

  • user.prompt_submit
  • stop

For compatibility with upstream naming, UserPromptSubmit and Stop are
accepted as config aliases.

Prompt-submit semantics

user.prompt_submit now supports minimal upstream-inspired behavior:

  • exit 0: continue normally
  • exit 2 with non-empty stderr: block the prompt
  • non-empty stdout: inject developer context into model input before the turn starts

This enables integrations that need to add context at prompt time.

Stop semantics

stop now supports end-of-turn continuation:

  • exit 0: allow the turn to finish normally
  • exit 2 with non-empty stderr: treat stderr as a continuation prompt
  • multiple blocking stop hooks are joined with blank lines
  • stop-driven continuation is limited to one extra turn to avoid recursive loops

Hook payload enrichment

To support integrations that need richer lifecycle metadata, hook payloads now include:

  • session_id
  • turn_id where applicable
  • transcript_path
  • model

This applies to session.start, user.prompt_submit, and stop.

TUI fix

Also fixes a debug-build TUI assertion where a background event inserted during
prelude/startup could be tagged incorrectly and panic.

Validation

Focused tests

Passed:

  • cargo test -p code-core --test tool_hooks -- --nocapture
  • cargo test -p code-core project_hook_event_deserializes_upstream_aliases -- --nocapture

Coverage includes:

  • prompt-submit firing
  • blocked prompt-submit skipping model submission
  • prompt context injection reaching model input
  • stop firing
  • joined stop continuation prompts
  • loop guard behavior
  • session/stop metadata presence
  • no duplicate stop continuation prompt in follow-up requests

Build

Passed:

  • cargo build --bin code --bin code-tui --bin code-exec

Smoke validation

A built-binary smoke harness was used during development to verify:

  • user.prompt_submit fires
  • stop fires
  • injected prompt context reaches model input
  • stop continuation prompt reaches model input once

Non-goals

This PR does not add:

  • global hooks
  • full upstream Codex hook-runtime parity
  • tolerant parsing for older binaries that do not know these new event names

This stays within the existing project-hook framework.

Extend code-rs project hooks with two new lifecycle events:
- user.prompt_submit
- stop

This adds minimal upstream-inspired hook semantics for:
- blocking a user prompt via exit code 2 + stderr
- injecting prompt context into model input via stdout
- continuing a turn from a stop hook via stderr
- preventing recursive stop-hook continuation loops

Also enrich hook payloads with session/turn metadata needed by
adapter-backed integrations:
- session_id
- turn_id
- transcript_path
- model

Includes focused regression coverage for fire/block/injection/stop/
loop-guard behavior, plus a debug-build TUI fix for background-event
prelude insertion.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94f6820a7e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

"cwd": self.cwd.to_string_lossy(),
"model": self.client.get_model(),
"prompt": prompt,
"items": items,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bound prompt-hook payload before exporting to env

run_user_prompt_submit_hooks serializes the full items array into CODE_HOOK_PAYLOAD, and run_hook_command forwards that JSON verbatim as an environment variable; for multimodal prompts, InputItem::Image carries a base64 data URI that can be very large. On typical OS env-size limits, this can make hook process launch fail (E2BIG), so user.prompt_submit hooks silently stop working precisely when users attach screenshots/images. This is a regression in hook reliability for common image workflows and should be fixed by truncating/omitting large fields before env export.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants