chore: import upstream snapshot with attribution
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Has been cancelled
Publish Python SDK / publish-pypi (push) Has been cancelled
Publish TypeScript SDK / publish-npm (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# Babysit Command
|
||||
|
||||
Owns a PR end-to-end through review: ship it, wait for the automatic review round, and if it
|
||||
isn't already clean, drive fix → reply → resolve → re-review cycles until Greptile reports 5/5
|
||||
and there are zero open comment threads.
|
||||
|
||||
## When to use
|
||||
|
||||
- The user says "babysit this PR", "keep working the reviews until it's clean", or similar
|
||||
- As the natural follow-up to `/ship` when the user wants the review loop automated rather than
|
||||
manually re-triggering reviews and answering comments themselves
|
||||
|
||||
## Inputs
|
||||
|
||||
Needs a PR number. If none is given and there's no open PR for the current branch, run `/ship`
|
||||
first (which includes the `origin/staging` sync check — see `.cursor/commands/ship.md`) to
|
||||
create one.
|
||||
|
||||
## Definition of "clean"
|
||||
|
||||
Both must hold:
|
||||
1. The latest Greptile summary comment reports **Confidence Score: 5/5**
|
||||
2. `reviewThreads` (GraphQL, see below) has **zero threads with `isResolved: false`**
|
||||
|
||||
Do not stop early on "no new comments this round" alone — a thread can be open from an earlier
|
||||
round. Always check both conditions freshly after every push.
|
||||
|
||||
## Loop
|
||||
|
||||
1. **Check current state** before doing anything:
|
||||
```bash
|
||||
gh pr view <n> --json comments -q '[.comments[] | select(.author.login=="greptile-apps")] | last | .body'
|
||||
gh api graphql -f query='
|
||||
query { repository(owner: "<owner>", name: "<repo>") { pullRequest(number: <n>) {
|
||||
reviewThreads(first: 50) { pageInfo { hasNextPage endCursor } nodes { id isResolved path line
|
||||
comments(first: 5) { nodes { id databaseId author { login } body } } } } } } }'
|
||||
```
|
||||
`[.comments[]] | last | .body`, not `... | .body | tail -1` — the latter pipes every matching
|
||||
comment's full multi-line body through the pipeline and keeps only the final *line* of that
|
||||
combined output (usually the "Reviews (n): Last reviewed commit..." footer), not the last
|
||||
*comment*, so it silently misses the actual "Confidence Score: X/5" line.
|
||||
`reviewThreads(first: 50)` is a single page — check `pageInfo.hasNextPage`. If `true`, don't
|
||||
stop yet: re-run the same query with `after: "<endCursor>"` and keep paging until
|
||||
`hasNextPage` is `false` before evaluating "clean." A PR with more than 50 threads is rare but
|
||||
stopping on a partial page would silently miss unresolved ones past the cutoff.
|
||||
If Greptile is 5/5 and every thread across all pages has `isResolved: true`, stop — report the
|
||||
outcome (see "Reporting" below) and skip the rest of this list.
|
||||
|
||||
2. **If no review has run yet** (fresh PR, no Greptile/Cursor comments): they usually run
|
||||
automatically on PR open — confirm via `gh pr checks <n>` (look for `Cursor Bugbot` /
|
||||
`Greptile Review`) and wait for that first round before doing anything else.
|
||||
|
||||
3. **If a review round has landed and it isn't clean**: for every thread where
|
||||
`isResolved: false`, triage the finding on its own merits — this is the part that requires
|
||||
judgment, not a mechanical loop:
|
||||
- **Real bug**: fix it in the cleanest way available. Match the codebase's existing
|
||||
conventions for that kind of problem before inventing a new one (e.g. an SSRF-prone
|
||||
user-supplied-host fetch should use whatever `validateUrlWithDNS`/`secureFetchWithPinnedIP`
|
||||
pattern the rest of the codebase already uses for that exact situation — grep for a sibling
|
||||
integration solving the same problem first). Never patch around a finding with a
|
||||
workaround, a broad try/catch, or a suppression comment — fix the actual cause.
|
||||
- **False positive**: don't change code. Reply with the specific reason it doesn't apply
|
||||
(cite the type definition, the established pattern it matches, or the doc it follows) so
|
||||
the reviewer bot and a human skimming later both understand why it was left as-is.
|
||||
- **Already fixed by an earlier finding in the same round**: note that and resolve without a
|
||||
duplicate code change.
|
||||
|
||||
4. **Reply to every thread individually** before resolving it — never resolve silently:
|
||||
```bash
|
||||
gh api repos/<owner>/<repo>/pulls/<n>/comments/<databaseId>/replies -f body="<what was done and why>"
|
||||
```
|
||||
Then resolve via GraphQL (needs the thread `id` from step 1, not the comment id):
|
||||
```bash
|
||||
gh api graphql -f query='mutation { resolveReviewThread(input: {threadId: "<threadId>"}) { thread { isResolved } } }'
|
||||
```
|
||||
|
||||
5. **Before pushing, re-run the full sync check from `/ship` step 2** — not just the log command,
|
||||
the whole check-and-recover flow (stash WIP if needed, rebase, verify the rebase didn't just
|
||||
cleanly replay stray commits, cherry-pick rebuild if it did or if it conflicted). A babysit
|
||||
loop spanning a long session is exactly the scenario where a branch can drift, and pushing
|
||||
review fixes on top of undetected drift is how an oversized PR happens even after the branch
|
||||
was fixed once. Then run the repo's pre-ship checks — not just lint/typecheck/boundary-
|
||||
validation, but also the conditional `/cleanup` (UI changes) and `/db-migrate`
|
||||
(schema/migration changes) gates from `.agents/skills/ship/SKILL.md` steps 4 and 5 (Cursor's
|
||||
own 7-step `ship.md` doesn't carry those steps, but a review-fix round is still a code change
|
||||
and can trip either gate just as easily as the original commit did).
|
||||
|
||||
6. **Commit and push** the round's fixes as one commit — `--force-with-lease` whenever step 5's
|
||||
sync check rewrote history, which includes a plain `git rebase origin/staging` that completed
|
||||
with no conflicts, not only the cherry-pick rebuild path; both rewrite commits already
|
||||
published to the remote, so a plain `git push` can be rejected either way — then run `/ship`
|
||||
step 7's post-push verify — not just before
|
||||
the first push, every push in the loop (the Cursor `/ship` has 7 steps; the Claude Code skill
|
||||
version's equivalent is step 9 — see `.agents/skills/babysit/SKILL.md` if working from that copy):
|
||||
```bash
|
||||
git fetch origin staging && git log --oneline --reverse origin/staging..HEAD
|
||||
gh pr view <n> --json commits -q '.commits[].messageHeadline'
|
||||
```
|
||||
`--reverse` matches `git log`'s newest-first default to the PR commit list's oldest-first
|
||||
order — without it a positional comparison can spuriously fail on any multi-commit branch.
|
||||
These two lists must describe the same commits. A review loop runs many pushes across many
|
||||
rounds; checking sync only before the push (step 5) and never after is how a bad push or a
|
||||
PR whose commit history quietly went stale between rounds goes unnoticed.
|
||||
|
||||
7. **Re-trigger review** by posting `@greptile` and `@cursor review` as **two separate PR
|
||||
comments** — never combine them into one comment, each bot only responds to its own mention:
|
||||
```bash
|
||||
gh pr comment <n> --body "@greptile"
|
||||
gh pr comment <n> --body "@cursor review"
|
||||
```
|
||||
|
||||
8. **Wait for the new round**, then go back to step 1. Never busy-poll in a sleep loop — pace the
|
||||
wait to roughly how long Greptile/Cursor take (1–3 minutes).
|
||||
|
||||
9. **Stop conditions**: clean state reached (see above), or the same unresolved finding survives
|
||||
two consecutive rounds with no new information (surface it to the user instead of looping
|
||||
forever), or the user interrupts.
|
||||
|
||||
## Reporting
|
||||
|
||||
When the loop ends, summarize: how many rounds it took, what was actually fixed (one line each),
|
||||
what was pushed back on as a false positive and why, and the final Greptile score / thread count.
|
||||
|
||||
## Hard rules
|
||||
|
||||
- Never post the two re-review mentions as a single combined comment.
|
||||
- Never resolve a thread without replying to it first.
|
||||
- Never fix a finding with a hacky workaround — if the clean fix isn't obvious, find the sibling
|
||||
pattern elsewhere in the codebase solving the same class of problem and match it.
|
||||
- Never silently drop a finding — every thread gets either a code fix or a reasoned reply.
|
||||
- Always re-run the `/ship`-style sync check before every push in the loop, not just the first.
|
||||
Reference in New Issue
Block a user