This skill should be used when the user asks to "set my lineup", "start him for me", "swap him into my flex", "update my lineup on Yahoo", "fix my lineup before kickoff", "apply my lineup changes", or wants a lineup change actually applied on their fantasy platform. Drives the user's own logged-in browser session to set the lineup - Yahoo first, with ESPN and Sleeper variants. Always pauses for explicit confirmation before committing. It may do only the live-roster reading needed to turn a se...
Scanned 9/6/2026
Install to Claude Code
npx -y skills add derekrbreese/fantasy-football-skills --skill set-lineup --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Set Lineup?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/derekrbreese-set-lineup)More formats (shields.io, HTML) on the badges page.
---
name: set-lineup
description: This skill should be used when the user asks to "set my lineup", "start him for me", "swap him into my flex", "update my lineup on Yahoo", "fix my lineup before kickoff", "apply my lineup changes", or wants a lineup change actually applied on their fantasy platform. Drives the user's own logged-in browser session to set the lineup - Yahoo first, with ESPN and Sleeper variants. Always pauses for explicit confirmation before committing. It may do only the live-roster reading needed to turn a settled lineup intent into exact swaps and to verify the result. Not for standalone start/sit analysis without an execution request (lineup-strategy start-sit), cut decisions (waiver-wire drop-candidates), or add/drop transactions (roster-ops submit-waiver-claim).
---
# Set Lineup (Browser Playbook)
Set a lineup on the user's platform through their own logged-in browser session. Two phases, one hard gate: **never save a lineup change without explicit user confirmation.**
## Execution boundary
- Treat this as an execution skill, not a general advice skill. If the user already named the swaps, carry out those swaps.
- If the user asks you to "set my lineup" without naming the swaps, read the live roster and then run `lineup-strategy:start-sit` if it is installed. Its globally optimized, evidence-qualified recommendation becomes the proposed target lineup; it is not authorization to apply anything.
- If `lineup-strategy:start-sit` is unavailable, either ask the user to name the intended swaps or reproduce its full decision contract inline before returning to execution: optimize the whole legal lineup rather than filling slots greedily, honor locks and kickoff times, preserve late-swap optionality, timestamp the analysis, and require official status plus a second credible source for any injury-driven change. A page-visible projection or status tag alone is not enough. If the user is still debating broader ranges of outcomes or waiver implications, finish that read-only analysis before proceeding.
## Ground rules (all roster-ops skills)
- **The user's session is the auth.** Never ask for, read, store, or type usernames, passwords, or 2FA codes. If a login page, 2FA challenge, captcha, or "unusual activity" interstitial appears **at any point**, stop immediately and hand the browser back — do not attempt to solve or dismiss it. Never interact with password-manager UI, autofill prompts, or "stay signed in" dialogs; clicking an autofill suggestion is entering a credential. After any re-authentication, restart from the beginning of the execution phase and re-verify the league and team landmarks — do not assume the account, league, or in-progress form survived. If you were mid-transaction, first determine from the page whether it went through.
- **Never run unattended.** These skills require a human present to confirm each transaction. Do not run them on a schedule, in a loop, or as a background task. If asked to automate a recurring roster move, decline the automation and offer a reminder instead. Driving your own logged-in session interactively, with a human approving each action, is what keeps this within what platforms tolerate — it stops being that the moment nobody is watching.
- **Use the UI, never the API.** Do not call platform endpoints directly, execute page JavaScript, or use shell tools to reach the platform, even when the interface is uncooperative. If the UI cannot do it, stop and tell the user.
- **Act at human pace.** No rapid-fire clicking or searching. If a captcha or rate-limit page appears, stop and hand back — never attempt to work around one.
- **Handle platform dialogs deliberately.** A confirmation dialog raised as a direct result of a click the user already approved is part of that approved action: read it, verify it describes that transaction and nothing more, then accept. A dialog describing anything unapproved (an extra drop, a different player) is a stop — dismiss it and report its wording verbatim. Never accept a dialog you have not read. Cookie banners and promo overlays are not transactions; dismiss and continue.
- **Budget your actions.** If you have taken roughly 15 actions without reaching the intended screen, stop and hand back with a description of where you are, rather than continuing to hunt.
- **Navigate by goals and landmarks, not memorized selectors.** Platforms redesign constantly; find things by their visible text and structure ("the roster table", "the section labeled Bench"), and read the page when unsure.
- **Confirmation gate**: before any click that commits a change, show the user exactly what is about to change and wait for an explicit yes. Everything before that (navigation, reading, opening dialogs) is fair game.
- **The confirmation must post-date the summary.** It has to arrive in a user message *after* the summary read off the actual page, in the same turn as the click. An instruction given before the browser was open — including "and submit it" or "just do it" — authorizes building the change, never committing it. A reply that alters any term ("yes, but bench Moss instead") is a **modification, not a confirmation**: apply it, re-read the page, present a fresh summary, ask again.
- **Never retry a commit click.** If an action's result is unclear, re-read the page to find out whether it landed. Retry only on positive evidence the change is *absent*. If the page is ambiguous or mid-update, wait and re-read — never click again.
- **Every execution ends in one terminal state**: `verified-success` (the approved final lineup is visibly on the page), `verified-absent` (the approved change is visibly not present and the lineup is still at the pre-change baseline), or `unknown` (the page does not let you prove either state). Never retry from `unknown`.
- **Browser routing.** Honor a browser the user explicitly names. If `leagues.md` records a Preferred browser, use that when it has a signed-in session for the platform. Otherwise use any authenticated browser the current assistant already has. For Yahoo, do not call a connector or platform API as a substitute for the browser, and do not retry a connector that returned `403`, `unauthorized`, or an equivalent authorization failure during the same task. If no browser tooling is available, say so and walk the user through the clicks instead.
## Phase 1: Decide the lineup
1. Read `leagues.md` from the project root first — the fields that matter here are platform, scoring, starting slots, and playoff weeks. If the file is missing or those fields are blank, ask for them directly and suggest running the `fantasy-league-setup:league-config` skill to persist the answers. If `leagues.md` defines more than one league, use the one marked `(default)` unless the user names another.
2. Navigate to the roster (Phase 2 steps 1–2) and **read the current lineup from the page** — the page is the ground truth, not memory of past conversations. Record that full visible lineup as the baseline before proposing or applying anything.
3. If the user already named the exact moves, turn those instructions into a concrete target lineup and check only legality, locks, and page-visible injury/bye constraints.
4. If the user asked you to set the lineup without naming the swaps, run the `lineup-strategy:start-sit` method on the live baseline when available. Otherwise solve one global assignment across every eligible slot for this league's scoring — never greedily fill one row at a time — while treating locked players as fixed, keeping a late-starting interchangeable player in FLEX when close, and naming any conditional fallback before the earlier option locks. Timestamp the recommendation. For an injury-driven swap, a page tag is only the official-status input; obtain a second credible source before making the change decisive. Honor overrides — the user's call wins.
5. Present the recommendation or requested plan as a before/after list of only the slots that change. If the baseline already matches the intended lineup, say so and stop with `verified-success`.
## Phase 2: Execute on Yahoo
1. **Get to the team**: first check whether the user already has a tab open on the platform and use it — navigating fresh discards in-progress state and routes through the provider's general shell, where consent walls and the user's personal account details appear. Otherwise go to the sport-scoped entry point (`football.fantasysports.yahoo.com`) rather than browsing through the provider homepage. Ensure a desktop-width viewport (≥1280px) before starting; narrow windows change the swap mechanism entirely. Open the team matching the league name in `leagues.md`. Landmark: a page header with the team name and a navigation row containing "Roster".
2. **Open the roster for the right week and capture the baseline**: click Roster; verify the week selector shows the intended week. Landmark: a table of position slots (QB, RB, WR, TE, FLX/W-R-T, K, DEF) with a **Bench (BN)** section below the starters. Re-read the full visible starters and bench and keep that baseline handy for both confirmation and recovery.
3. **Determine the commit model before touching any player.** Read the roster page and look for a Save/Submit/Apply control governing the roster. If there is none, **every swap commits immediately**. When it cannot be determined, assume immediate commit — that is the fail-safe assumption, and it is the working assumption for Yahoo and Sleeper.
4. **⛔ CONFIRMATION GATE** — placed according to the commit model:
- **Immediate-commit UI (assume this unless a Save control is visible):** the gate comes **before the first swap** and covers the whole set. Read a final confirmation envelope that includes platform, league, team, week, the exact baseline-to-target slot moves, the immediate-commit nature of the UI, the fact that the sequence is only safely reversible while the page state remains clear, and that there is no queue to absorb a mistake. State that any partial failure will pause for a new user choice between completing the approved target and restoring the recorded baseline. Get an explicit yes, then re-read the same envelope from the live page before the first click. If anything changed after the user's yes — week, locks, player availability, baseline lineup, visible controls — stop and require a fresh confirmation on the new envelope.
- **Batched UI (a Save control exists):** stage all swaps, then read a final confirmation envelope that includes platform, league, team, week, the exact baseline-to-target slot moves, the Save control that will commit them, the fact that they remain reversible until Save, and that there is no queue impact. Get an explicit yes, re-read the staged page, and if anything changed after the yes, require fresh confirmation. If the user declines, navigate away without saving, verify the roster still matches the baseline, and report `verified-absent`.
5. **Swap players**: the goal is that player X ends up in slot Y. Depending on build and viewport this is a per-row position control that reveals eligible destinations, drag-and-drop of the row, or tap-source-then-tap-destination. Use whichever affordance is actually visible; if a row exposes no obvious control, read the page and describe its controls rather than guess-clicking. Locked players (games started) show a lock — skip them and tell the user. In immediate-commit flows, re-read the roster after each swap so you always know whether the page still matches the approved target path.
6. **Verify and recover safely**: re-read the roster page; confirm each intended player sits in the intended slot, and that no starting slot is empty. Clicking a control is not evidence it worked.
- If the approved target lineup is visibly present, report `verified-success`.
- If a batched Save was never clicked or visibly did not land and the roster still matches the baseline, report `verified-absent`.
- If an immediate-commit multi-swap sequence stops partway through but the current page state is still clear, show the user that exact state and the two bounded recovery paths: continue forward to the already-approved target lineup or revert fully to the recorded baseline. Read a fresh recovery envelope, obtain a new explicit confirmation, and then follow only the selected path using positively identified legal swaps without leaving a starting slot empty. Do not invent a third lineup. After recovery, verify again and report the resulting terminal state.
- If the page is ambiguous, mid-refresh, or otherwise does not let you prove whether the approved lineup or the baseline is on screen, stop and report `unknown`. Describe the last clearly observed lineup state and tell the user where to check. Do not retry from `unknown`.
Note: if the league has Yahoo's **"Start Active Players"** auto-swap enabled, Yahoo may move players on its own. A lineup differing from what was set is not necessarily a failed swap — read before concluding, and never "correct" an auto-move without asking.
## Platform variants
- **ESPN** (`fantasy.espn.com`): Roster page uses per-player **Move** buttons → legal slots show **Here** buttons. Changes generally apply immediately per swap, so apply the confirmation gate *before each Move/Here pair*, not just at the end. Landmark: Starters table above a labeled Bench table.
- **Sleeper** (`sleeper.com`): open the league → Team/Roster. The web app is drag-or-tap: tap a starter, tap the bench player to swap. Swaps commit immediately — there is no Submit Lineup control to gate on, so gate **before the first swap** per step 4. Landmark: starters listed by slot at top, "Bench" list below.
## Failure handling
- Page doesn't match these descriptions: don't guess-click. Read the page, describe what's visible, and ask the user to point at the right control if still ambiguous.
- Player missing from roster page: the user may be in the wrong league (multi-league accounts) — check the league name landmark before anything else.
- Lineup locked (kickoff passed): report which slots are locked; offer to set the remaining days' players only.
## Example run (fictional)
"Set my lineup for week 9" → leagues.md says Yahoo, "Gridiron Gazette". At Sunday 11:35 AM ET, the live roster shows TE Oren Vasquez on **bye** in the TE slot and RB Silas Okafor on the bench. A `lineup-strategy:start-sit` pass optimizes the full legal assignment before any swap is proposed; neither change below depends on unverified injury news.
> Recommendation: TE Harlan Pruitt in for Vasquez (bye); Okafor over Trask at RB2 (lead role, +3.2 proj). Two swaps, nothing else moves. No Save control on this roster page, so each swap commits the moment I make it — confirming both up front. Set it? — *user: yes* — Both swaps applied, then verified by re-reading the page: Pruitt TE, Okafor RB2, Vasquez and Trask to bench. Lineup is legal — no empty slots, no byes starting.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!