Feature: add `updatedPrompt` output field to `userPromptSubmitted` hook

Resolved 💬 0 comments Opened Jun 8, 2026 by trycatchkamal Closed Jun 8, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Summary

The userPromptSubmitted hook fires before the model sees the user's prompt, but its output is currently observational only - hooks can log the prompt and call external services, but cannot modify or replace the prompt text. This request proposes adding an updatedPrompt field to the hook's output schema so that custom logic can rewrite the prompt before it reaches the chosen model.

Current behaviour

Per the hooks documentation, userPromptSubmitted today supports:

| Capability | Supported? |
|---|---|
| Read the user's prompt from stdin JSON | ✅ |
| Log / audit the prompt | ✅ |
| Block the prompt | ❌ |
| Modify or replace the prompt text | ❌ |

From the tutorial:

The output of this hook is ignored.

Meanwhile, preToolUse already supports structured output that mutates the event before it proceeds:

{
  "permissionDecision": "allow",
  "modifiedArgs": { "command": "my-modified-command" }
}

There is a clear asymmetry: tool call inputs are mutable by hooks, but user prompt text is not.

Proposed Solution

Add an optional updatedPrompt field to the userPromptSubmitted hook output. When present, Copilot replaces the original prompt with the provided value before forwarding to the model. The user's selected model remains unchanged.

{
  "updatedPrompt": "optimised or transformed prompt text here"
}

If the field is absent or null, behaviour is identical to today - the original prompt passes through unchanged. This is a non-breaking change.

Example

A prompt-optimisation hook script (.github/hooks/optimise-prompt.sh):

#!/bin/bash
INPUT=$(cat)
ORIGINAL=$(echo "$INPUT" | jq -r '.prompt')

# Call your own optimisation service
OPTIMISED=$(curl -s -X POST https://your-service/optimise \
  -H "Content-Type: application/json" \
  -d "{\"prompt\": \"$ORIGINAL\"}" | jq -r '.result')

echo "{\"updatedPrompt\": \"$OPTIMISED\"}"

Registered in .github/hooks/hooks.json:

{
  "version": 1,
  "hooks": {
    "userPromptSubmitted": [
      {
        "type": "command",
        "bash": ".github/hooks/optimise-prompt.sh",
        "timeoutSec": 10
      }
    ]
  }
}

Alternative Solutions

| Alternative | Limitation |
|---|---|
| copilot-instructions.md | Static file - cannot run dynamic logic or call external services per prompt |
| Copilot Extensions (agent mode) | Requires @extension-name invocation - not transparent or automatic |
| Corporate HTTPS proxy | Requires persistent infrastructure; intercepts all traffic including auth tokens |
| Shell wrapper around CLI | Only transforms the first prompt; breaks interactive multi-turn sessions |

There is no current workaround that is both transparent to the user and safe to deploy in a team/enterprise environment

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

  • Prompt optimisation - compress, restructure, or enrich prompts via custom logic or a secondary model before forwarding to the user's selected model, reducing token cost and improving output quality
  • Alias / shorthand expansion - expand team-defined shorthand (e.g. /review-sec) into full structured instructions automatically
  • Sensitive data masking - detect and redact secrets, PII, or internal identifiers before they leave the developer's environment
  • Policy enforcement - enforce prompt structure standards across an organisation (e.g. always include a task type, always specify output format)
  • Dynamic context injection - prepend per-session context (current branch, linked issue, environment name) that changes at runtime and cannot be captured in static copilot-instructions.md

Additional Context

Related

  • anthropics/claude-code#27365 - identical request for Claude Code's UserPromptSubmit hook; the two tools are converging on the same hook pattern and parity here would be valuable

View original on GitHub ↗