Claude Code plugin that delegates boring, low-risk tasks (bulk i18n, trivial style tweaks) to the Gemini CLI — a transparent Claude ⇄ Gemini pipeline.
SaferSkills independently audited Borderline (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Borderline exists to offload boring, safe work to the Antigravity CLI (`agy`) so Claude can stay focused on what needs judgment. Communication must be transparent: always tell the user what you delegated, in which mode, and what you reviewed.
Operating requirement: this flow launchesagyviaBashwithout asking for permission on every step, so Claude must run with--dangerously-skip-permissions. Otherwise every call prompts for confirmation and the pipeline stops being transparent.
`agy` is agentic — and the fix is structural. Left alone, agy takes the current directory as its workspace and explores it (lists files, reads README, opens scripts) before answering, even with a concrete prompt and even when told not to. Each read is a request against agy's rate-limit, so a context-free translation ends up scanning the repo and burning quota. The wrapper (delegate.sh) defeats this by running agy from an empty scratch directory in `--text`: no workspace → nothing to scan → no divagation, no wasted requests. Always go through the wrapper.Long context "just works" — pass big prompts on stdin, not as an argument. A command line is capped by the OS (ARG_MAX, ~1 MB on macOS). The old wrapper handed the whole prompt toagy -p "<prompt>", so a large i18n batch or a long document blew that ceiling and the call failed or hung ("Argument list too long", mis-reported as a rate-limit). The wrapper now streams the prompt to `agy --print` on stdin, which has no size limit. For content so large it can't even fit ondelegate.sh's own command line, write it to a temp file and pass `@/path/to/file` (or pipe it and pass-); the wrapper reads the file and streams it in. A 1.3 MB prompt that is impossible via-pgoes through cleanly this way.
A stuck call always returns control. agy's own--print-timeoutbounds the model wait but not input ingestion or a silent rate-limit stall, so it can hang far past it. The wrapper adds a hard wall-clock watchdog (--print-timeout+ 30 s): if agy overruns, it is killed and you get aborderline: HARD TIMEOUT …line instead of an indefinite hang.
DO delegate — mechanical, repetitive, verifiable at a glance:
locales/*.json, .po, messages.*).DON'T delegate — keep it in Claude:
When in doubt, don't delegate: do it yourself.
| Mode | When | What it does |
|---|---|---|
--text | Small / context-free work (one color, one string, a batch of strings to translate) | runs agy from an empty scratch dir so it can't scan the repo; returns text only, you apply it with Edit/Write |
--edit | Bulk file work (mass i18n across files, replacements across many files) | runs agy in the repo; it reads and writes the named files itself, scoped to those files |
Prefer `--text` for translations. Don't point agy at repo files — that's exactly what triggers its agentic scanning and burns the rate-limit. Paste the source content inline in the prompt, ask for the translated output only, and let Claude write the file. Because --text runs agy from an empty directory, divagation is structurally impossible. Reach for --edit only when the volume of files makes inlining impractical.
Always call the wrapper (it centralizes flags, the anti-exploration preamble, model and mode):
# Preferred for translations: inline the source, get output only, you write the file.
"${CLAUDE_PLUGIN_ROOT}/scripts/delegate.sh" --text 'Translate this JSON object to neutral Spanish. Output ONLY the translated JSON, same keys/order, do NOT touch {var} placeholders or HTML tags:
{"save":"Save","cancel":"Cancel","items":"You have {n} items"}'# Bulk across files when inlining is impractical.
"${CLAUDE_PLUGIN_ROOT}/scripts/delegate.sh" --edit "Translate ALL keys in locales/en.json and write locales/es.json with the same keys, neutral Spanish, without touching {var} placeholders or HTML tags. Operate only on those two files."# Tiny text answer.
"${CLAUDE_PLUGIN_ROOT}/scripts/delegate.sh" --text "Give me only the hex of a blue 20% darker than #3B82F6. Reply with the value only."# LARGE content (big i18n batch, long document): don't inline it on the command line —
# write it to a temp file (Write tool) and pass the path with '@'. No size limit.
"${CLAUDE_PLUGIN_ROOT}/scripts/delegate.sh" --text @/tmp/borderline-batch.txtFor long prompts, always prefer `@file` (write the source + instructions to a temp file, pass its path). Inlining a very large prompt as a quoted argument can exceed the shell's ARG_MAX and fail before the script even runs; @file (and - for stdin) sidestep that entirely and stream the content to agy on stdin.
Rules when building the prompt for agy:
--edit), output format, what NOT to touch(placeholders {var}, %s, tags, keys, ordering).
--text, ask for the result only (no explanations) so you can apply it cleanly,and include the source content inline so agy needs no repo access.
--edit, name the input and output files and the success criteria, and remind itto operate only on those files.
Tunables (env vars, optional): BORDERLINE_MODEL (default Gemini 3.5 Flash (High)), BORDERLINE_TIMEOUT (default 2m), BORDERLINE_CLI (default agy), BORDERLINE_THROTTLE_MS (sleep before the call; set 3000–5000 for batch i18n).
agy rate-limits by request frequency, and the throttle is silent: no 429, no message — the call just hangs and returns empty. The wrapper bounds this two ways: agy's own --print-timeout, and a hard wall-clock watchdog (--print-timeout + 30 s) that kills agy if it overruns, so the call can never hang the agent indefinitely. You'll see either borderline: HARD TIMEOUT … (agy had to be killed) or borderline: agy returned EMPTY … (agy gave up on its own) — both mean the same thing: a silent rate-limit. When you see it: do not hammer-retry (worsens it), do not run calls concurrently (frequency is what triggers the block), let agy rest several minutes, then send one call. For batches, set BORDERLINE_THROTTLE_MS=3000–5000 and prefer one big `--text` batch over many small calls. Healthy calls return in ~4–17 s regardless of size.
After delegating, verify before accepting:
git diff --stat then git diff of the touched files.If it's not git, Read the files agy was supposed to change.
placeholders must stay intact. For style, the value must be the requested one.
npm run lint, tsc --noEmit, etc.).instructions. Never let dubious work through.
Always close with one or two lines stating:
--edit/--text).Example: "Delegated to agy (--edit mode) the translation of 142 keys into `locales/es.json`. Reviewed the diff: keys aligned with `en.json`, placeholders intact, `lint` OK."
agy: command not found / exit 127 → the Antigravity CLI is not installed/on PATH.Do NOT try to install it yourself. It requires the user to sign in, so an unattended install would be useless. Just hand the user the URL and ask them to install it and sign in, then retry: https://antigravity.google/product/antigravity-cli . (Override the binary with BORDERLINE_CLI if it lives elsewhere.)
borderline: agy returned EMPTY … or borderline: HARD TIMEOUT … → silent rate-limit(see the Rate-limit section). Stop, let agy rest minutes, send one call. Don't retry-storm or run calls concurrently. Run one delegation at a time.
Argument list too long → the prompt exceeded the shell's ARG_MAX as an inline argument.Don't inline huge prompts: write the content to a temp file and pass @/path/to/file (the wrapper streams it to agy on stdin, which has no size limit).
--edit (which runs in the repo) for something that should have been --text. For context-free work always use --text — it runs agy from an empty dir so there's nothing to scan.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.