Skip to content

fix(cli): reverse on Free runs billing subscribe credited to the run - #7046

Merged
miguel-heygen merged 4 commits into
mainfrom
fix/reverse-free-upgrade-page
Nov 3, 2026
Merged

miguel-heygen merged 4 commits into
mainfrom
fix/reverse-free-upgrade-page

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Nov 2, 2026 •

Copy link
Copy Markdown
Collaborator

What

On a Free account, the reverse skill now runs npx hyperframes billing subscribe --feature reverse --session <id>, which opens the plans page in the person's browser and waits until they are on Pro, so the run goes on by itself. No bare link and no hand-written open command.

billing subscribe takes --feature and --session and puts them on the plans page as feature and rs, the same fields reverse.upgrade_url carries, so the purchase is still credited to the run. reverse start prints the exact command as reverse.subscribe_command on Free, and a blocked Free account now gets that command as its error's fix.

Why

The page link alone left the agent to open it, quote the &, and guess when the person was done. billing subscribe already opens the page and polls for the subscription; it only lacked the run's attribution.

Testing

fails without the fix: packages/cli/src/commands/billing.test.ts > "opens the plans page credited to the feature and run that sent the person"; packages/cli/src/commands/reverse/start.test.ts > "stops a Free account the server blocks, with the subscribe command as the fix, after saving the session"

On the devbox: 17 passed in the billing and reverse tests, 3 runs in a row; with the old billing.ts and start.ts 3 fail. skills-manifest.json regenerated; oxfmt applied.

Size

A small change across one command, one flag pair, the skill text and its test; it has no other carrier.

Server link vs local link

The server's upgrade_url is the pricing page plus exactly feature and rs, and it sends none while purchases are closed to the caller. The local form builds the same two fields on the same page, so the blocked-Free fix carries what the server link would. The difference: when the server sends no link, the local command still opens the plans page, where the page itself decides whether to offer a purchase.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes at 7ddb5a3.

Blocker 1: no fails without the fix: line. This is a fix(skills) PR, and the Testing section only says "Skill text only". A fix PR has to name a test that fails without the fix. Either add a skill eval or fixture that fails on main and name it on that line, or retitle it as a non-fix (for example docs(skills):/feat(skills):) if no test can carry it.

Blocker 2: the open commands drop the run's credit. reverse.upgrade_url looks like https://hyperframes.studio/pricing?feature=reverse&rs=…. Taken at its word, the instruction "Open it with open, xdg-open or start" gives start https://…?feature=reverse&rs=… on Windows. cmd splits that at &, so the browser opens without rs, which is exactly the parameter that "credits the purchase to this run". An unquoted open/xdg-open in a POSIX shell also backgrounds at &. Spell the commands out with quoting: open "<url>", xdg-open "<url>", and on Windows start "" "<url>" (the empty title is needed because start treats a first quoted argument as the window title).

Minor: "when there is no browser on this machine (SSH, a remote box)" doesn't tell the agent how to check. Giving the same signals the CLI uses (SSH_CONNECTION/SSH_TTY, BROWSER=none, or the open command failing) would make it deterministic. Falling back to printing the link whenever the open command fails would cover it.

The manifest hash bump matches a one-file skill text change.

@miguel-heygen miguel-heygen changed the title fix(skills): reverse on Free opens the upgrade page for the person docs(skills): reverse on Free opens the upgrade page with a quoted link Nov 2, 2026

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at ebced71. Both blockers are resolved:

  • Fix-test line: the PR is retitled docs(skills):. It changes only skill text, so the "fails without the fix:" rule no longer applies.
  • URL quoting: the skill now quotes the URL (open "<url>", xdg-open "<url>", start "" "<url>"), so &rs=… stays on the link and the purchase is still credited to the run. The SSH/no-browser fallback is now spelled out too: SSH_CONNECTION/SSH_TTY, BROWSER=none, or the open command failing.
  • Manifest: I recomputed the hash with buildManifest at this head and got reverse-any-video = 83dfae84850777c2 (5 files), which matches the committed manifest. The CI manifest job was skipped, so this local check is the evidence.

Non-blocking: start "" "<url>" is cmd syntax. In PowerShell, start is Start-Process, which rejects an empty first argument. That falls through to the "open command fails → print the link" path, so it degrades safely. A PowerShell form (Start-Process "<url>") could be a follow-up.

@miguel-heygen miguel-heygen changed the title docs(skills): reverse on Free opens the upgrade page with a quoted link fix(cli): reverse on Free runs billing subscribe credited to the run Nov 2, 2026
@mintlify

mintlify Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
hyperframes 🟢 Ready View Preview Nov 3, 2026, 5:26 AM

💡 Tip: Enable Automations to automatically generate PRs for you.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes at 9490d27. The design works: billing subscribe opens the page, polls for Pro and now carries feature/rs, and the session id is regex-validated (rvs_<uuid>), so it can't inject anything into the printed command. The fails without the fix: line is present. But two required checks fail because of this diff:

Blocker 1: skill size budget (Preflight lint, in both Windows render verification and preview-regression).
✗ reverse-any-video/SKILL.md is 5178 B, over its 5120 B budget. The rewritten "if it refuses…" sentence adds 58 B. Trim it, for example: "if it refuses, run its fix (billing subscribe waits for the upgrade), then start again."

Blocker 2: comment ratchet (Comments workflow).
RAISED comment share: packages/cli/src/commands/reverse/start.ts is 1.0% (1/104), at the base 0.0% (0/92). The cause is the new /** The command that opens the plans page… */ doc comment on subscribeCommand. Drop it; the name already says what it does.

Please confirm (not blocking on its own): reverseUpgradeUrl prefers the server's upgrade_url and falls back to a locally built pageUrl("plans", { feature, rs: sessionId }). The blocked-Free fix and subscribe_command now always use the local form, so whatever the server puts in its upgrade_url beyond feature/rs is dropped on the main purchase path. If the server link is exactly those two fields on the same pricing base, this is fine. Please say so in the body or point to the server code. If it isn't, pass the server URL through (for example a --url on billing subscribe, or have the command read the session's saved link).

Non-blocking: billing subscribe polls for up to 600 s, while agent shells often cut a tool call at about 120 s. The skill's "if the command times out, run it again" covers that. A hint to run it with a long timeout or in the background would avoid the restart loop.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving at 48c2ff0. Both blockers from my last review are fixed, and I checked them at this head:

  • Skill size: SKILL.md is 5115 B, under the 5120 B budget. Preview-regression's preflight lint, the same check that failed before, is green on this head.
  • Comment ratchet: the doc comment on subscribeCommand is gone, and the Comments workflow is green.
  • Manifest: I recomputed buildManifest here and got reverse-any-video = 860b235e1216b0cb (5 files), which matches the committed manifest.
  • Server link vs local link: answered in the body. The server's upgrade_url is the pricing page plus exactly feature and rs, which is what billing subscribe --feature reverse --session <id> builds, so attribution is unchanged.

The fails without the fix: line is present. CI and the Windows render verification were still running at review time; the Windows lane's preflight is the lint step that now passes elsewhere.

@miguel-heygen
miguel-heygen added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit 3baf81f Nov 3, 2026
118 of 119 checks passed
@miguel-heygen
miguel-heygen deleted the fix/reverse-free-upgrade-page branch November 3, 2026 06:03
@miguel-heygen miguel-heygen mentioned this pull request Nov 3, 2026
1 task done

This branch was successfully deployed

1 active deployment
staging - docs — 48c2ff03 Deployed Nov 3, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant