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
68 lines
2.9 KiB
Go
68 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/zzet/gortex/internal/hooks"
|
|
)
|
|
|
|
var (
|
|
hookPort int
|
|
hookMode string
|
|
hookAgent string
|
|
)
|
|
|
|
var hookCmd = &cobra.Command{
|
|
Use: "hook",
|
|
Short: "Agent hook handler (Claude Code by default; --agent for Gemini / Antigravity / Hermes / Kimi)",
|
|
Hidden: true, // Not for direct user invocation.
|
|
Run: func(_ *cobra.Command, _ []string) {
|
|
// --agent selects the hook wire protocol. Empty (the default) is the
|
|
// Claude Code format; protocol-specific agents branch below, and the
|
|
// remaining external agents share the hookSpecificOutput.additionalContext
|
|
// wire shape.
|
|
switch hookAgent {
|
|
case "hermes":
|
|
// Hermes (NousResearch hermes-agent) sends
|
|
// snake_case events and expects an action/message decision shape, so
|
|
// it gets its own dispatcher.
|
|
hooks.RunHermes(hookPort, hooks.ParseMode(hookMode))
|
|
return
|
|
case "pi":
|
|
// Pi (earendil-works/pi) has no MCP; its Gortex extension
|
|
// shells `gortex hook --agent=pi`, sending a normalized event
|
|
// envelope on stdin and applying the PiDecision read back.
|
|
hooks.RunPi(hookPort, hooks.ParseMode(hookMode))
|
|
return
|
|
case "codex":
|
|
// Codex support is intentionally soft-only: the adapter installs
|
|
// Bash PreToolUse/PostToolUse plus a UserPromptSubmit hook that emit
|
|
// additionalContext without ever denying the tool call.
|
|
hooks.RunCodex(hookPort)
|
|
return
|
|
case "kimi":
|
|
// Kimi Code CLI: UserPromptSubmit / PreToolUse / Stop /
|
|
// SubagentStart. Soft guidance rides Kimi's plain-stdout context
|
|
// channel; an indexed whole-file read is blocked via the documented
|
|
// hookSpecificOutput.permissionDecision shape.
|
|
hooks.RunKimi(hookPort, hooks.ParseMode(hookMode))
|
|
return
|
|
case "", "claude":
|
|
// Claude Code — handled below.
|
|
default:
|
|
hooks.RunExternalAgent()
|
|
return
|
|
}
|
|
hooks.Run(hookPort, hooks.ParseMode(hookMode))
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
hookCmd.Flags().IntVar(&hookPort, "port", 8765, "Gortex web server port")
|
|
hookCmd.Flags().StringVar(&hookMode, "mode", "deny",
|
|
"hook posture: 'deny' (redirect Grep/Glob/Read of indexed source), 'enrich' (never deny; PostToolUse appends graph context), 'consult-unlock' (deny fallback reads until the graph is queried once this session), or 'nudge' (soft-deny once per burst of non-symbolic calls)")
|
|
hookCmd.Flags().StringVar(&hookAgent, "agent", "",
|
|
"hook wire protocol: empty/'claude' (Claude Code PreToolUse/UserPromptSubmit), 'codex' (Codex Bash PreToolUse/PostToolUse + UserPromptSubmit soft context), 'kimi' (Kimi Code CLI UserPromptSubmit/PreToolUse/Stop/SubagentStart; plain-stdout context, permissionDecision deny for indexed reads), 'hermes' (NousResearch hermes-agent pre_tool_call/pre_llm_call), 'pi' (earendil-works/pi extension bridge — normalized PiEvent envelope in, PiDecision out), or 'gemini'/'antigravity' (emits hookSpecificOutput.additionalContext). Default (empty) is the Claude Code format.")
|
|
rootCmd.AddCommand(hookCmd)
|
|
}
|