<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Marius</title>
    <description>The latest articles on DEV Community by Marius (@mariusd).</description>
    <link>https://dev.to/mariusd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4202449%2F7002954f-8e05-4a9f-bf6e-c9a75fd63db5.jpg</url>
      <title>DEV Community: Marius</title>
      <link>https://dev.to/mariusd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mariusd"/>
    <language>en</language>
    <item>
      <title>I gave my coding agent my basketball videos and asked it to be my coach</title>
      <dc:creator>Marius</dc:creator>
      <pubDate>Fri, 23 Oct 2026 11:15:19 +0000</pubDate>
      <link>https://dev.to/mariusd/exit-code-3-means-its-the-agents-turn-an-agent-first-cli-for-sports-film-review-3pjk</link>
      <guid>https://dev.to/mariusd/exit-code-3-means-its-the-agents-turn-an-agent-first-cli-for-sports-film-review-3pjk</guid>
      <description>&lt;p&gt;&lt;em&gt;I wrote this post with Claude Code and posted it myself. The project was built with Claude Code too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I play in an adult rec basketball league. Nobody coaches us and nobody watches film. What we do have is a lot of phone video that nobody opens again.&lt;/p&gt;

&lt;p&gt;Claude Code can look at images, so I tried giving it frames from my own shooting drill and asking what it saw. On one training session it counted my set shots at 9 of 11 and my jump shots at 7 of 19, and all 8 jump shots in the last ten minutes were misses. I hadn't noticed that at all. (That session went through the basketball plugin's training mode; the steps below use the simpler frame-based mode.)&lt;/p&gt;

&lt;p&gt;The annoying part was everything around the review: pulling frames, cutting clips, making something my teammates would actually open on a phone. So I wrote a CLI for that part and called it &lt;a href="https://github.com/mariusDing/sports-video-coach" rel="noopener noreferrer"&gt;sports-video-coach&lt;/a&gt; (MIT).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsi7p43do5h24f4j7rw05.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsi7p43do5h24f4j7rw05.gif" alt="A real run on my own shooting drill: video in, the agent's film review, the coaching page out" width="720" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get back
&lt;/h2&gt;

&lt;p&gt;From one phone video:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a page for your phone with what to fix, a drill and a target to check next session for each problem, and the clips that show it&lt;/li&gt;
&lt;li&gt;a spoken version of the report, so you can listen on the way to practice&lt;/li&gt;
&lt;li&gt;an explained video: the clip pauses where it goes wrong, a ring marks the spot, a subtitle says why&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a &lt;a href="https://mariusding.github.io/sports-video-coach/demo/" rel="noopener noreferrer"&gt;demo page&lt;/a&gt; and its &lt;a href="https://mariusding.github.io/sports-video-coach/film.en.mp4" rel="noopener noreferrer"&gt;explained video&lt;/a&gt; (with sound) you can open without installing anything. The demo is a synthetic drill with a pre-written review, so it shows what the output looks like, not how good the agent is at basketball. For that you need your own video.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying it on your own video
&lt;/h2&gt;

&lt;p&gt;You need git, &lt;code&gt;uv&lt;/code&gt; (the tool needs Python 3.11; uv fetches it), ffmpeg and ffprobe on your PATH, and a coding agent (Claude Code, Codex, Cursor ...). Then paste this into the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Read https://github.com/mariusDing/sports-video-coach/blob/master/AGENTS.md, install the CLI with
`uv tool install --python 3.11 git+https://github.com/mariusDing/sports-video-coach` (it needs ffmpeg), then coach me on
my video &amp;lt;path to your video&amp;gt;: run
`sports-video-coach run &amp;lt;video&amp;gt; --sport basketball --focus "&amp;lt;my jersey number or what I wear&amp;gt;"`,
do each step it hands you (exit code 3) until it exits 0, and show me the coaching page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent installs it and starts the run. Whenever the CLI needs frames looked at or a file written, it pauses, the agent does that, and the run carries on. You may still need to approve the install or fix a missing tool. It uses some of your agent plan, like any other task.&lt;/p&gt;

&lt;p&gt;For a pickup game or a drill filmed on a phone, &lt;code&gt;--sport basketball&lt;/code&gt; uses the frame-based review: no tracking, no GPU, no league. &lt;code&gt;--focus&lt;/code&gt; takes a jersey number or a description like "the player in red". Film from where that player is clearly visible; the agent can only judge what it can see.&lt;/p&gt;

&lt;p&gt;To build the demo on your own machine, run these two commands. It brings its own synthetic video and pre-written review, so no agent is involved. The audio needs internet; add &lt;code&gt;--offline&lt;/code&gt; for just the page and clips.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;uv tool &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--python&lt;/span&gt; 3.11 git+https://github.com/mariusDing/sports-video-coach
sports-video-coach demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything lands as local files. To get the page onto a phone, ask the agent for a single file with the audio and clips inside: &lt;code&gt;sports-video-coach html &amp;lt;folder&amp;gt; --share --out report.html&lt;/code&gt;, then send yourself that file. There is also &lt;code&gt;sports-video-coach run &amp;lt;folder&amp;gt; --publish&lt;/code&gt; for a hosted link (needs a Cloudflare account; anyone with the link can open it).&lt;/p&gt;

&lt;h2&gt;
  
  
  How the agent and the tool split the work
&lt;/h2&gt;

&lt;p&gt;In the generic workflow the CLI makes no model API calls and needs no API key. It extracts frames, cuts clips, builds the outputs and keeps track of which steps are done. When it needs someone to watch or write, it exits with code 3 and says exactly what file to write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;sports-video-coach run drill.mp4 &lt;span class="nt"&gt;--sport&lt;/span&gt; basketball
&lt;span class="go"&gt;frames: 4 sheets (0.5 s per tile) in .../run/frames
[run] waiting for the agent: review
&lt;/span&gt;&lt;span class="gp"&gt;...                                                   #&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent opens the frame sheets, writes &lt;code&gt;review.json&lt;/code&gt;, and runs &lt;code&gt;sports-video-coach run &amp;lt;folder&amp;gt;&lt;/code&gt; to carry on.&lt;/p&gt;

&lt;p&gt;I spent a while rewording the guides when reviews came back thin. Then I added a validator instead. If the review has fewer than three moments, the run won't build a page and says why:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;review.json: needs a `moments` list with at least 3 entries
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also checks that each moment has a what and a why, that its end comes after its start, and that it doesn't end more than a second past the video. None of that tells you whether the basketball advice is right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it falls short
&lt;/h2&gt;

&lt;p&gt;The agent looks at frame sheets, not the video itself. By default, clips up to 30 seconds get a frame every half second, up to 3 minutes one per second, and longer videos one every two seconds. You can make it denser with &lt;code&gt;--every&lt;/code&gt;. Very fast details, like the moment of release, can fall between frames.&lt;/p&gt;

&lt;p&gt;Frames go to your agent's model provider, same as anything else you show your agent. The narration text goes to Microsoft's online text-to-speech (edge-tts). Use jersey numbers, not names. If you don't want anything sent to Microsoft, run with &lt;code&gt;--artifacts html&lt;/code&gt;: you keep the page and the clips and skip the audio and the explained video.&lt;/p&gt;

&lt;p&gt;Player tracking and box scores are in the basketball plugin, which you run from a clone; the full pipeline is meant for a CUDA GPU. Other sports work through the generic mode, and &lt;code&gt;sports-video-coach new-plugin &amp;lt;name&amp;gt;&lt;/code&gt; gives you a starting point for your own.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/mariusDing/sports-video-coach" rel="noopener noreferrer"&gt;https://github.com/mariusDing/sports-video-coach&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I mostly use it for basketball. If you try it on something else, I'd like to hear what it gets wrong.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>ai</category>
      <category>python</category>
    </item>
  </channel>
</rss>
