User-invoked safe git push. Confirms before setting first-time upstream and before pushing a diverged main/master, and refuses force pushes without explicit authorization. Self-contained — execute the inlined steps directly.
60
72%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./plugins/flowai/skills/push/SKILL.mdPush the current branch to its remote with a strict safety contract that reflects flowai's solo-maintainer-but-shared-repo norms. The skill never silently rewrites remote history, never pushes to a protected branch when the remote has diverged, and never sets an upstream without the user's explicit confirmation that the branch should track.
<step_by_step>
Identify Target Branch
git rev-parse --abbrev-ref HEAD to identify the current branch as <CURRENT>.<CURRENT>. If different, STOP and ask "You typed <typed> but the current branch is <CURRENT>. Push <CURRENT> or check out <typed> first?". Wait for an answer.<CURRENT>.Resolve Upstream
git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null to find the upstream of <CURRENT>.<CURRENT> has no upstream. Should I run git push --set-upstream origin <CURRENT>?". Wait for an answer.
--set-upstream origin <CURRENT>.Safety Checks
origin/main or origin/master, run git fetch origin <CURRENT> then git rev-list --left-right --count HEAD...@{u}. If the right count (commits the remote has and local does not) is > 0, ASK the user with EXACTLY two options: "Remote <CURRENT> is ahead by N commit(s) the local branch does not have. Force is REFUSED on protected branches even with explicit authorization. Pull and rebase first, or abort?". --force / --force-with-lease are NOT options — never present them, never run them, even if the user volunteers "force", "overwrite", or "yes I want to overwrite the remote". If the user pushes back, restate the refusal and re-offer pull-rebase / abort.git push (which will fail safely if non-fast-forward). DO NOT proactively suggest force.--force request: if the user has explicitly asked for --force, decline. Explain --force-with-lease and proceed only with per-push user authorization (see Rule 2).Push
GIT_PAGER=cat git push [--set-upstream origin <CURRENT>]. Stream stdout + stderr to the user. Do NOT silence error output.--force or --force-with-lease. Surface the failure and STOP.Post-Push Verification
git rev-parse @{u} and git rev-parse HEAD. Compare.<remote>, HEAD = <local>. Investigate before retrying."Await CI (FR-ATOM-PUSH.CI-AWAIT)
## CI/CD section.
No CI declared in AGENTS.md — skipping CI await. and continue to step 7 (`7. TOTAL STOPskipped, green, or not reached — stopped earlier).`).
Provider: or Status command:): STOP with ## CI/CD section is malformed — required keys: Provider, Status command. Found: <list of present keys>. Do NOT silently fall back. Do NOT continue to step 7.## CI/CD):
Poll interval: — seconds between status polls. Default 60. Accept integer seconds; a value <5 is treated as malformed and STOPs the atom.Wall-clock budget: — soft cap on total await time. Default 1800 (30 min). Accept integer seconds.ITER_CAP = max(1, ceil(<budget> / <poll interval>)). The iteration count — NOT wall-clock — bounds the cap so it stays deterministic across IDE-harness latencies. With defaults, ITER_CAP = 30; a project that sets Poll interval: 10 and Wall-clock budget: 60 gets ITER_CAP = 6.export SHA=$(git rev-parse HEAD). All CI commands below inherit $SHA from the agent's shell.Status command. Treat:
CI declared but no run was triggered by $SHA within 60 s — verify the workflow trigger configuration. Do NOT continue to step 7.ITER_CAP iterations × <poll interval> s sleep ≈ <wall-clock budget> wall-clock):
Status command.<poll interval> s. Re-invoke. Increment iteration counter.ITER_CAP iterations completed without a terminal status (exit 0 or 1), STOP with a loud single-line message: CI ANOMALY: <ITER_CAP> iterations × <poll interval>s = <budget>s elapsed without a terminal verdict. Run URL: <result of Run URL command if defined, otherwise "not available">. Last status exit: 2 (in-progress). Treat as an incident (hanging job, queue starvation, runner outage) — do NOT continue silently. Do NOT invoke investigate (no failed-job logs to feed it yet — the build is still running, not red). Do NOT continue to step 7. The user owns the next action: extend the budget by re-running the atom after raising Wall-clock budget, cancel the CI run, or investigate the runner.Logs command is defined in AGENTS.md, execute it. Capture stdout. Truncate to 12 KB (investigate can fetch more via the run URL if it needs to drill deeper).Run URL command is defined, execute it. Capture stdout as the run URL.@{u} == HEAD), so investigate's "Clean Baseline" precondition holds.investigate skill via the host IDE's skill-invocation primitive (Skill tool / /flowai:investigate slash command / inline expansion of its SKILL.md) with this prompt:
CI failed for commit $SHA on branch <CURRENT>. Run URL: <URL or "not available">. Failed-job logs (truncated to 12 KB):\n<LOGS or "not available">\nDiagnose the root cause. Do not apply a fix; report findings.investigate returns its report, STOP. Do NOT continue to step 7 — the push succeeded but the build is broken; the user owns the remediation decision.**7. TOTAL STOP
skipped, green, or not reached — stopped earlier).**</step_by_step>
b4ba256
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.