FeatureAgents/AgentsGitFlowController ↗★ 0
agents-gitflow-guard
A configurable branch-role guard for AI coding agents (DSH / Claude Code / Codex / OpenCode / Antigravity / Pi) — integration/preview/production/archive, each with its own update rules
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:FeatureAgents/AgentsGitFlowController说明文档
阅读完整 README ↗Configuration Reference
Branch roles — the model behind the checks
Only integration is required. Every other role is optional — configure what your flow actually uses, and each entry is an exact branch name or a regex pattern.
feature branches ──(free)──> integration (integration branch; updates via PR/MR)
│
├──> preview (optional; env endpoints; updates via PR/MR)
│
└──> production (optional; PR/MR + only you click merge)
archive (optional; you archive after release)
| role | config key | required? | enforced behavior |
|---|---|---|---|
| feature | featurePattern | — | free: commit / push / sync / rebase |
| integration | branches.integration | always | no direct push (default pr); features merge in via PR/MR |
| preview | branches.preview (array) | optional | no direct push; updates via PR/MR only (env endpoints) |
| production | branches.production (array) | optional | PR/MR only; merge by user only (mergeBy: "user") |
| archive | branches.archive (array) | optional | archive PR/MR may be created by agents; the merge stays user-hand only |
Customizing branch names & rules — any naming works
Small team (solo / 2–3 devs) — minimal: integration only:
{
"enabled": true,
"featurePattern": "feature/[\\w-]+",
"branches": { "integration": ["develop"] }
}
Larger team (multiple preview envs + production + archive):
{
"enabled": true,
"featurePattern": "(topic|feature)/[\\w-]+",
"branches": {
"integration": ["develop", "topic/[\\w-]+"],
"preview": {
"branches": ["ita1", "itb1", "itb2", "sg", "vb", "r1-conf", "r1-ope", "r2-conf", "r2-ope"],
"update": "pr"
},
"production": {
"branches": ["prd-conf", "prd-ope"],
"update": "pr",
"mergeBy": "user"
},
"archive": ["main"]
}
}
Full field reference
{
"enabled": true, // opt-in: file exists AND enabled=true
"featurePattern": "feature/[\\w-]+", // JS regex matching your working/feature branches
"branches": {
"integration": { "branches": ["develop"], "update": "pr" }, // REQUIRED
"preview": { "branches": ["ita1"], "update": "pr" }, // optional
"production": { "branches": ["prd"], "update": "pr", "mergeBy": "user" }, // optional
"archive": ["main"] // optional
},
"locale": "en", // optional: message language — any registered locale ('en'/'zh' built-in); unknown values warn in status and fall back to English
"strict": false, // optional: fail-closed — invalid config / internal errors block instead of warn-and-allow
"ci": { "enabled": true } // optional: gh pr checks logged as reference
}
-
Roles accept either an array (shorthand) or an object
{ branches, update?, mergeBy? }. -
update:pr(default) = updates only via PR/MR;flexible= allow direct/local merges (small teams). -
mergeBy(production):user(default) = only you click merge;anyone= allow PR merge through. -
Each branch entry is an exact name or a regex (auto-detected). Regex safety: branch patterns are authored by you and compiled as-is — avoid catastrophic-backtracking constructs (e.g. nested quantifiers like
(\w+)+) infeaturePatternand branch entries. -
Language: messages are English by default; add
"locale": "zh"for Chinese, or pass--localeto anygitflow-guardsubcommand (priority: CLI flag > project config > English). All user-facing text follows the locale — including CLI framework messages such as--help, unknown-command notices, and the empty-audit line. -
Custom locales: downstream packages can add a language at runtime —
import { registerLocale } from 'agents-gitflow-guard', callregisterLocale('fr', frDict)with a dictionary covering exactly the same keys as built-in English (validated on registration), then set"locale": "fr"in the project config to activate it.import { registerLocale, MESSAGE_KEYS } from 'agents-gitflow-guard' // MESSAGE_KEYS lists every key a dictionary must define (same set as built-in English); // registration throws if a key is missing or extra. const fr = { /* one entry per MESSAGE_KEYS, e.g. */ 'deny.header': ({ why }) => `[gitflow-guard] bloqué : ${why}` } registerLocale('fr', fr) -
Unknown locales: an unregistered
"locale"value falls back to English during interception (by design — hooks never stall on wording), so a typo is easy to miss; the one-line warning shows up ingitflow-guard status. -
Validation:
integrationis required; overlapping role entries are rejected; invalid regex is rejected. Any error disables the plugin for that project (reported) rather than applying a half-guessed setup. -
Strict mode: by default a broken config warns on stderr once and lets the command pass (fail-open, so a typo can't wedge your tooling).
"strict": trueflips config errors and internal errors to block (fail-closed) — for high-risk repos. A missing file or explicitenabled: falsestays silent either way.