a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package hooks
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io"
|
|
"os"
|
|
)
|
|
|
|
// RunCodex handles the Codex hook wire shape. Codex support is deliberately
|
|
// soft-only: PreToolUse is forced through ModeEnrich, PostToolUse only emits
|
|
// additionalContext, and UserPromptSubmit re-surfaces prompt-relevant graph
|
|
// symbols on every turn. No branch ever denies a tool call.
|
|
func RunCodex(port int) {
|
|
data, err := io.ReadAll(os.Stdin)
|
|
if err != nil {
|
|
return
|
|
}
|
|
runCodex(data, port)
|
|
}
|
|
|
|
func runCodex(data []byte, port int) {
|
|
var peek struct {
|
|
HookEventName string `json:"hook_event_name"`
|
|
ToolName string `json:"tool_name"`
|
|
}
|
|
if err := json.Unmarshal(data, &peek); err != nil {
|
|
return
|
|
}
|
|
|
|
switch {
|
|
case peek.HookEventName == "PreToolUse" && peek.ToolName == "Bash":
|
|
runPreToolUse(data, port, ModeEnrich)
|
|
case peek.HookEventName == "PreToolUse" && codexMCPReadPreToolUseTool(peek.ToolName):
|
|
runCodexMCPReadPreToolUse(data)
|
|
case peek.HookEventName == "PostToolUse" && peek.ToolName == "Bash":
|
|
runCodexPostToolUse(data)
|
|
case peek.HookEventName == "UserPromptSubmit":
|
|
// Re-surface graph symbols relevant to the prompt on every turn.
|
|
// Codex forgets MCP tools as context grows, so a SessionStart
|
|
// orientation alone fades; this lands a fresh, prompt-specific
|
|
// nudge at the top of each turn (the wire shape is shared with
|
|
// Claude Code — hookSpecificOutput.additionalContext).
|
|
runUserPromptSubmit(data)
|
|
}
|
|
}
|
|
|
|
func codexMCPReadPreToolUseTool(toolName string) bool {
|
|
switch toolName {
|
|
case gortexReadFileTool, gortexEditingContextTool:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func runCodexMCPReadPreToolUse(data []byte) {
|
|
var input HookInput
|
|
if err := json.Unmarshal(data, &input); err != nil {
|
|
return
|
|
}
|
|
if input.HookEventName != "PreToolUse" || !codexMCPReadPreToolUseTool(input.ToolName) {
|
|
return
|
|
}
|
|
|
|
ctx := gortexReadNudge(input.ToolName, input.ToolInput)
|
|
if ctx == "" {
|
|
return
|
|
}
|
|
emitPreToolUse(HookOutput{
|
|
HookSpecificOutput: &HookSpecificOutput{
|
|
HookEventName: "PreToolUse",
|
|
AdditionalContext: ctx,
|
|
},
|
|
})
|
|
}
|
|
|
|
func runCodexPostToolUse(data []byte) {
|
|
var input postHookInput
|
|
if err := json.Unmarshal(data, &input); err != nil {
|
|
return
|
|
}
|
|
if input.HookEventName != "PostToolUse" || input.ToolName != "Bash" {
|
|
return
|
|
}
|
|
|
|
cmd, _ := input.ToolInput["command"].(string)
|
|
classification := classifyBashCommand(cmd)
|
|
switch classification.Action {
|
|
case BashActionGrepLike:
|
|
// Codex wraps grep/rg/ag in Bash. Re-label that narrow shape as Grep so
|
|
// the existing PostToolUse enrichment can parse path:line output and do
|
|
// the graph lookup without changing Claude Code behavior.
|
|
input.ToolName = "Grep"
|
|
case BashActionFindName:
|
|
input.ToolName = "Glob"
|
|
case BashActionReadSource:
|
|
if classification.Path == "" {
|
|
return
|
|
}
|
|
if input.ToolInput == nil {
|
|
input.ToolInput = make(map[string]any)
|
|
}
|
|
input.ToolName = "Read"
|
|
input.ToolInput["file_path"] = classification.Path
|
|
default:
|
|
return
|
|
}
|
|
|
|
normalized, err := json.Marshal(input)
|
|
if err != nil {
|
|
return
|
|
}
|
|
runPostToolUse(normalized)
|
|
}
|