ClaudeMods
☰
ZH-CN
● 0 人在线 · 浏览 0 次
赞助提交作品
GitHub 仓库 · 发布者 ccdwyer

stack-traffic-control

一个 Claude Code mod,充当 gh stack 的出发板:提供 `/stack` 面板、提示符上方的一行状态,以及一个 Bash 防护钩子,把原始 force-push、rebase 和 PR 基础分支编辑重定向到 gh stack。

已翻译

关于这个 mod

Stack Traffic Control 是面向使用 GitHub 官方堆叠 PR 扩展 gh stack 的仓库的 Claude Code mod。/stack 命令会打开一个面板,从顶到底列出堆栈;对每个分支显示其 PR 编号、CI 检查状态、是否已就绪、需要 rebase、正在排队或已经落地,还会显示未推送的提交和未提交的更改,并提供刷新按钮。提示符上方的一行指示器会显示你在堆栈中的当前位置;位于堆叠分支时还会显示 rebase 警告。防护钩子会像 shell 一样解析 Bash 命令(引号、转义、重定向、heredoc、; && || |、子 shell、替换、bash -c 和 eval,以及 env/sudo/xargs 等包装器和 cd/pushd/git -C 目录跟踪),拒绝与堆栈工作流冲突的原始命令,并向模型显示准确的 gh stack 等价命令。受保护的操作包括对堆栈分支和主干执行 force-push 与删除、rebase 到主干或层级、rebase 或 merge 风格的 pull、对堆栈 PR 执行 gh pr edit --base,以及为堆栈分支执行 gh pr create。当堆栈文件无法读取、目录状态无法确定、命令行无法解析,或一行命令先切换分支再 push 时,它会默认拒绝。它遵守 push refspec、push.default、branch.*.rebase、pull.rebase、pull.ff 和 git -c 覆盖项。已知限制都有文档说明;它是安全网,不是沙箱。需要安装 GitHub CLI 及 gh extension install github/gh-stack,并通过 ccdwyer-mods 插件市场安装。

安装

请先查看作者 README 确认 marketplace 和插件名称;命令可能随仓库结构改变。

claude plugin marketplace add ccdwyer/stack-traffic-control
claude plugin install stack-traffic-control
原文 / README

Stack Traffic Control

Stack Traffic Control demo

The band above the prompt, the /stack departure board, and a raw force-push refused with the gh stack alternative. MP4

A Claude Code mod that acts as a departure board for gh stack, GitHub's official stacked-PR extension.

  • /stack opens a pane listing the stack top to bottom. For each branch it shows the PR number, CI checks (✓ ✗ …), and whether the branch is ready, needs a rebase, is queued or has landed. It also shows unpushed commits (↑, or unpublished for a branch that has never been pushed) and uncommitted changes (✎). A refresh button updates it.

  • Above the prompt, when you're on a stacked branch: 🛫 stack 2/4 · feature-b · 1 needs rebase.

  • Guard. In a repo that uses gh stack, some raw commands are refused, and the model is shown the exact gh stack command to use instead and why. The repo's stack file (<git-common-dir>/gh-stack) decides what is protected: every branch of every stack, and their trunks, are protected from force-pushes and deletes, whichever branch you're on. Rebase, pull and PR rules apply when you're on a stacked branch.

    | Raw command | Use instead | |---|---| | git push --force / -f / --force-with-lease / +refspec / --mirror / glob refspecs / --delete hitting a stack branch | gh stack push, gh stack submit --auto, gh stack sync --prune | | git rebase onto the trunk, a layer or @{u} (also --onto=, or a bare git rebase) | gh stack rebase (--downstack, --upstack, --no-trunk) | | git pull that would rebase or merge (flags and pull.rebase / pull.ff config; fast-forward-only pulls pass) | gh stack sync | | gh pr edit --base on a stack PR | gh stack submit --auto / gh stack modify | | gh pr create for a stack branch | gh stack submit --auto |

    These commands still run, with a note attached for the model:

    • A rebase that stays inside the branch (git rebase -i HEAD~3) runs, with a reminder to follow up with gh stack rebase --upstack.
    • git rebase --continue, --abort and --skip run, with a reminder about the gh stack rebase equivalents.

    These pass untouched:

    • force-pushing tags or unrelated branches
    • PRs whose head isn't a stack branch
    • PRs in another repo (--repo)
    • anything run off a stack

    The guard reads the Bash line the way a shell would. It looks inside:

    • quoting, escapes, line continuations and redirections. Quoted heredoc bodies are data. In unquoted heredocs and redirect targets, $( … ) is checked.
    • ;, &&, || and |
    • subshells ( … ), groups { … }, if/while bodies, and $( … ) / backtick substitutions
    • bash -c '…' and eval
    • wrappers: env, sudo, nohup, time, nice, command, exec, xargs, timeout
    • cd / pushd (including ~ and options), env -C, sudo -D, git -C, --git-dir and --work-tree. A cd inside a pipeline, a background job or an if body is handled the way the shell handles it. It also remembers where the Bash tool's persistent shell is across calls.

    It fails closed in four cases, but only in repos that use gh stack:

    • The stack file can't be checked or read. The command is refused with the reason rather than allowed.
    • A cd leaves the directory unknowable (cd -, cd $X, a cd that may not have run). Git steps are refused until a literal cd settles it.
    • The line can't be read (a substitution as the program, an unbalanced quote) and could push, rebase, pull or edit a PR. It is refused, and the model is asked to run that step as a plain command.
    • A line switches branch and then pushes. It is refused, and the model is asked to split it, because the push can't be checked against a branch it isn't on yet.

    The guard also follows:

    • configured push refspecs (remote.<name>.push, remote.<name>.mirror) and push.default, including upstream
    • branch.<name>.rebase, pull.rebase and pull.ff, plus git -c overrides
    • GIT_DIR / GIT_WORK_TREE prefixes
    • git rebase <upstream> <branch>, which rewrites <branch> whatever HEAD is

    Known limits, as a safety net and not a sandbox:

    • a program name hidden in a variable ($GIT push -f)
    • a script run as bash script.sh / source with no git text on the line
    • git aliases
    • git reset --hard and git merge on a stacked branch, which aren't checked

"Needs rebase" combines gh stack's own flag with a check that each layer contains its parent layer's tip. Repos that have never used gh stack (no stack file) are never looked into further, so the guard costs nothing there.

Requirements

  • GitHub CLI with the stack extension: gh extension install github/gh-stack

Install

/plugin marketplace add ccdwyer/claude-mods
/plugin install stack-traffic-control@ccdwyer-mods
/reload-plugins

Develop

claude plugin validate .
claude plugin test .

What it hooks

Events this mod hooks, as claude plugin validate reads the module:

  • session.start
  • command.run{command=stack}
  • turn.complete
  • tool.call{tool=Bash}
  • ui.render{component=AbovePrompt}
  • ui.render{component=Pane
  • requestId=stack-board}

Engine calls it makes: $.clock.now (via lookAt, stackAt), $.command.register, $.env.get (via shellContext), $.process.run (via run), $.state.get, $.state.set, $.ui.open, $.ui.resolve.

A tool.call hook sits in the middle of every tool call: it can see the call, refuse it, or add context to its result. This mod uses that only for the behaviour described above.

Privacy

It uses your existing GitHub CLI (gh, with the gh stack extension) to read your stack and pull request status from GitHub, under your own account. Nothing is sent anywhere else.

The mod collects no analytics or telemetry, and its author receives no data from it.

Full policy: PRIVACY.md.

License

MIT

更多类似作品