Agents now start pre-mr-review on the work account themselves, through a Klaude delegate, and continue from its verdict. A council of models on my own accounts replaces the single reviewer before it, and adding a seat is one table row. Proof comes from T3's browser, with mp4 recordings, and capture-proof stays as the fallback. Ticket pages carry their own data, so index.html renders alone in T3's file viewer, and worktree threads share the main checkout's docs. A PreToolUse hook sends subagents in T3 threads to delegate_task. Blocker, proof, review and MR summary rules come from ideas in t3dotgg/tstack.
38 lines
2.0 KiB
Bash
Executable File
38 lines
2.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# PreToolUse hook: inside a T3 Code thread, subagents go through delegate_task, so T3 can
|
|
# show them, track them, and wake the parent. Blocks the native Agent and Workflow tools and
|
|
# shelling out to another agent CLI. Does nothing outside T3 Code.
|
|
#
|
|
# The escape is for when Gib asks for a native route by name: start the Agent or Workflow
|
|
# description with "native:", or prefix the command with T3_NATIVE_OK=1.
|
|
#
|
|
# web-fetch stays allowed because it stands in for a WebFetch tool, not a worker.
|
|
set -euo pipefail
|
|
|
|
[[ -n "${T3CODE_THREAD_ID:-}" ]] || exit 0
|
|
|
|
input="$(cat)"
|
|
tool="$(jq -r '.tool_name' <<<"$input")"
|
|
|
|
deny() {
|
|
jq -n --arg reason "$1" '{hookSpecificOutput: {hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: $reason}}'
|
|
exit 0
|
|
}
|
|
|
|
advice="This is a T3 Code thread, so use the delegate_task tool (load it with ToolSearch: select:mcp__t3-code__delegate_task). This overrides T3's note that native subagents are fine for the same provider. If you are a delegated child, do the work yourself."
|
|
|
|
case "$tool" in
|
|
Agent | Task | Workflow)
|
|
[[ "$(jq -r '.tool_input.subagent_type // ""' <<<"$input")" == "web-fetch" ]] && exit 0
|
|
[[ "$(jq -r '.tool_input.description // ""' <<<"$input")" == native:* ]] && exit 0
|
|
deny "$tool is blocked. $advice Only if Gib asked for a native agent by name: start the description with \"native:\"."
|
|
;;
|
|
Bash)
|
|
# Only a command position counts, so grep patterns and prose that mention these pass.
|
|
if jq -r '.tool_input.command // ""' <<<"$input" |
|
|
grep -qE '(^|[;&|(]|\$\()[[:space:]]*(timeout[[:space:]]+[^[:space:]]+[[:space:]]+)?(claude|clauded|claudedr|klaude|codex|opencode2?)[[:space:]]+([^;&|]*[[:space:]])?(-p|--print|exec|run)([[:space:]]|$)'; then
|
|
deny "Starting an agent CLI from the shell is blocked. $advice Only if Gib asked for this by name: prefix the command with T3_NATIVE_OK=1."
|
|
fi
|
|
;;
|
|
esac
|