Repository navigation
feat: Add the jam router and four Jam skills - #22
Conversation
…proof-table, video-to-jam - jam: routes a bare jam.dev link or a vague ask to the right skill after reading the Jam; a clear ask still goes straight to its own skill. /jam works too. - jam-to-tasks, jam-to-ticket, jam-proof-table, video-to-jam: new skills. - jam-fix hands a narrated multi-ask walkthrough to jam-to-tasks. - check.mjs: jam anywhere in the name marks a Jam skill; the router table must name every skill and only real ones. Tests for both, the feedback-section drift, the one-mention cap, and the exact ChatGPT package contents.
f751bf1 to
873963f
Compare
| Read the Jam's details first: the `getDetails` MCP tool, or | ||
| `jam get jam <id> --json`. Then route by what it holds: | ||
|
|
||
| - A narrated walkthrough that asks for several changes: `jam-to-tasks`. |
There was a problem hiding this comment.
🔴 Narrated walkthroughs lose their task route
For a bare link, jam routes a narrated walkthrough using only details, without reading its transcript. Multiple spoken requests can be invisible there, so the walkthrough falls through to a question or bug diagnosis.
Learn more
Jam details contain metadata about the recording, while the spoken requests are in the video transcript. The router handles vague requests and bare links before loading another skill. It currently decides whether several changes were requested after reading only details, so it lacks the evidence needed for that decision. The transcript step shows where the actual spoken requests are obtained.
Example: A user pastes only a video Jam link. The speaker asks for a pricing fix and a checkout change, but the title merely says “Feedback.” Details alone cannot distinguish it from a single-bug report, so the router can miss jam-to-tasks.
Recommended fix: For video Jams with narration and no clear user ask, retrieve the transcript before deciding between jam-to-tasks, jam-fix, and a clarification question; handle unavailable captions explicitly.
Was this helpful? React with 👍 or 👎 to provide feedback.
| `integrations` lists the tickets Jam's own integrations already filed for | ||
| it, each with `id` and `url`. Then search the tracker for the Jam's id and | ||
| full URL, then for two or three words from its title. Tracker search is | ||
| fuzzy and returns near misses: a match is a ticket whose body or | ||
| attachments hold this Jam's id. On a match, return that ticket and stop. | ||
| That also answers "was this Jam ever ticketed?". Add the new Jam to the | ||
| existing ticket only when the user asks. |
There was a problem hiding this comment.
🔴 Existing ticket hides unfiled problems
When a Jam contains several problems and one is already ticketed, jam-to-ticket stops at that match. Other problems never get their own tickets.
Learn more
A narrated Jam can describe several unrelated problems. The one-problem-per-ticket step requires a separate ticket for each. Duplicate checking currently stops on the first match for the Jam ID, even if that match covers only one problem. That leaves other problems without tickets.
Example: A recording describes a broken price and a failed sign-in. The existing price ticket links to the recording. The lookup finds it and stops, so the sign-in ticket is never created.
Recommended fix: Enumerate the problems before deciding whether to stop. Compare each existing ticket with its corresponding problem and create tickets only for those still unfiled; retain the read-only answer path when the user only asks whether a ticket exists.
Was this helpful? React with 👍 or 👎 to provide feedback.
| ```bash | ||
| jam get jam "$ID" --json # reads back, type, duration | ||
| jam get frames "$ID" --at 48000 --size medium --out "$(mktemp -d)" # outside the repo | ||
| ``` | ||
|
|
||
| Open the frame at the moment the claim shows up; `--at` must be below the | ||
| Jam's `duration`. A blank page, a single frozen frame, or the wrong tab is | ||
| not proof. Record it again with `jam-proof` and say that you did. |
There was a problem hiding this comment.
🟡 Screenshot and replay proof cannot be checked
When a row links a screenshot or replay Jam, jam-proof-table asks for video frames it cannot provide. Valid proof is rejected instead of checked through screenshots or events.
Learn more
Jam recordings have different visual capabilities: video Jams have frames, screenshot Jams have screenshots, and replay Jams have neither. The type guidance already distinguishes these cases. This skill fetches frames for every Jam and treats unavailable or unsuitable visuals as failed proof.
Example: A completed annotation is filed as a screenshot Jam. The proof table tries jam get frames on its ID, which cannot return a video frame, rather than opening the screenshot that shows the annotation.
Recommended fix: Inspect the type returned by jam get jam before verification. Use frames for video, screenshots for screenshot Jams, and recorded events, console, or network for replay Jams. Mark unsupported evidence unconfirmed instead of treating the Jam as a bad recording.
Was this helpful? React with 👍 or 👎 to provide feedback.
| ## 2. Read the whole transcript | ||
|
|
||
| ```bash | ||
| jam get transcript "$ID" --json # WebVTT in the "transcript" field |
There was a problem hiding this comment.
🟡 Silent Jam tasks stall at transcript
For a silent Jam with several written requests, jam-to-tasks proceeds to jam get transcript, which has no captions. Its later coverage check also requires a transcript, leaving those requests without a workable completion path.
Learn more
The no-narration branch treats title, description, and comments as the requests. A silent recording or screenshot has no transcript, yet the next step unconditionally reads one and the coverage check demands rereading it. The documented caption error is final with the microphone off.
Example: A screenshot Jam's description lists two UI changes. It is not a single failure, so it remains in this skill. Transcript retrieval fails permanently, and the prescribed task-list and final coverage steps have no source to read.
Recommended fix: Branch explicitly on Jam type and narration availability. For silent Jams, extract and verify coverage against title, description and comments, and use screenshots when available rather than requesting video frames.
Was this helpful? React with 👍 or 👎 to provide feedback.
Why
A Jam pasted with no ask, or with "take a look at this jam", matched no skill well. A narrated feedback walkthrough landed in
jam-fixand got diagnosed as one bug, and a Jam the user could not open still startedjam-fix. The plugin also had no skill for turning a Jam into tasks or a ticket, listing proof at the end of a run, or splitting a video someone already has into Jams.What changed
jamrouter: it reads the Jam, then loads the skill that fits. A walkthrough with several asks goes tojam-to-tasks, a bug tojam-fix, and a Jam it cannot open stops with a message. Its description covers only a bare link, a vague ask and/jam(/jam:jamfrom the plugin), so a clear ask still goes straight to its own skill.jam-to-tasks,jam-to-ticket,jam-proof-table,video-to-jam.jam-fixhands a walkthrough with several asks tojam-to-taskswhen that skill is installed. The ChatGPT package shipsjam-fixwithout it.scripts/check.mjs:jamanywhere in a skill's name marks a Jam skill (was thejam-prefix), and the router's table must name every skill and only skills that exist.CONTRIBUTING.md:jamis the one single-word skill name."$(cat file)", andghtakes--body-file. A transcript quote such as "Pro shows $29" would otherwise post as "Pro shows 9".jaminstead of installing it. The check that keeps setup blocks identical now keys on that block; it matched nothing after Fix skills.sh audit findings #18.mktemp -d, outside the repo.jam-to-taskscommits only when asked.Review guide
LOGICskills/jam/SKILL.md: the description's trigger scope, the routing table, and the bare-link branchLOGICskills/jam-to-tasks/SKILL.md: the trust line, step 6 (show the list, then work), and commits only on requestLOGICskills/jam-to-ticket/SKILL.md: the duplicate check, one ticket per problem,--body-fileLOGICscripts/check.mjs: Jam-skill detection and the router table checkLOGICskills/video-to-jam/SKILL.md,skills/jam-proof-table/SKILL.mdMECHANICALskills/jam-fix/SKILL.md(handoff line), README list entries, CHANGELOG,agents/openai.yamlTESTscripts/check.test.mjs,scripts/package-chatgpt.test.mjsVerification
Headless Claude Code,
claude-opus-5-5, with only this plugin's skills loaded and shell, edit and write tools blocked. 105 runs: each case with/jamtyped, with the router and no/jam, and without the router, 3 runs each where the router matters.jam-to-tasks/jamjam-fix/jamjam-fixjam-fix/jamjam-fix, thenjam-to-ticket/jamnpm testNot verified:
jam-fixcannot finish in 8 turns, sojam-proofis never reached.Compatibility
Additive. Existing skills keep their names and triggers. The ChatGPT package still holds
jam-fixandjam-to-e2e, now asserted exactly. No CLI bundle resync:jam-proofandjam-annotateare unchanged.Security
jam-to-tasksandjam-to-ticket.jam-to-ticketkeeps tokens, cookies and personal data from network bodies out of tickets.video-to-jamtranscribes on the machine, and asks before uploading a full recording or attaching a Playwright trace (cookies, headers, bodies). It pinswhisper-ctranslate2@0.5.8.jam-proof-tableandvideo-to-jamask before creating a folder on a Viewer account, which can change seat billing.jam-to-tasksacts on the narration of a Jam the user hands it, including one someone else recorded. That is the skill's job.jam-to-ticketdoes not check whether a GitHub repo is public; the user picks the tracker.Rollback
Revert the merge on
masterbefore av*tag:npx skills addfollowsmaster. After a tag, revert and release a patch.server.jsonis unchanged, so the MCP Registry is not involved.