Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion scripts/check-core-skills.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,45 @@ test("reverse builds the project with init --video and asks for the run's total
);
assert.match(
start,
/add up what each refused step\s+needs, and run `npx hyperframes billing (?:top-up|add-credits) --needed <total>(?: --skill reverse-any-video)?` once for that total/,
/add up what each refused step\s+needs, and give them `npx hyperframes billing (?:top-up|add-credits) --needed <total>(?: --skill reverse-any-video)?` to run once for that total/,
);
assert.doesNotMatch(read("SKILL.md"), /copy the video into the project/);
assert.match(read("SKILL.md"), /`init --video` put the video in/);
});

test("reverse hands every purchase to the person instead of running billing itself", () => {
const read = (path) =>
readFileSync(new URL(`../skills/reverse-any-video/${path}`, import.meta.url), "utf8");
const start = read("references/start.md");
const section = (heading) => start.split(`## ${heading}`)[1].split("\n## ")[0];
assert.match(
read("SKILL.md"),
/give the person its upgrade link and `fix` to run themselves \(you never run `billing`\)/,
);
assert.match(start, /You run every command except `billing`, which\s+is theirs/);
assert.doesNotMatch(start, /you run every command,/);
const outOfCredits = section("Out of credits mid-run");
assert.match(
outOfCredits,
/If any refusal prints no amount, the total is unknown:\s+give plain `billing add-credits` once instead, for the whole run/,
);
assert.doesNotMatch(
outOfCredits,
/for that one|for each (?:refused )?step|one per (?:refused )?step(?!\.)/,
);
for (const heading of ["Signed in on Free", "Out of credits mid-run"]) {
const text = section(heading);
assert.match(text, /never run a `billing` command yourself/, heading);
assert.match(text, /for them to run|to run once for that total/, heading);
const rest = text.replace("never run a `billing` command yourself", "");
assert.doesNotMatch(
rest,
/\b(?:run|execute|launch)\b[^.\n]{0,60}(?:`(?:npx hyperframes )?billing|`reverse\.subscribe_command`)/i,
heading,
);
}
});

test("flags a skill that never reports its own run", () => {
assert.deepEqual(
beaconProblems("slideshow", "Run `npx hyperframes events --skill=slideshow` first."),
Expand Down
2 changes: 1 addition & 1 deletion skills-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"files": 76
},
"reverse-any-video": {
"hash": "e4c3ac45f5deb337",
"hash": "f94599be483b10df",
"files": 5
},
"slideshow": {
Expand Down
2 changes: 1 addition & 1 deletion skills/reverse-any-video/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: Rebuild any video file as an editable HyperFrames project - motion

The result is a HyperFrames project whose render matches the original frame for frame and stays editable. Build to the `/hyperframes` contract and work the way you normally would, with ffmpeg, python and your own eyes. Reverse videos the person has the right to use.

Reverse is a HyperFrames Pro feature. Open with `npx hyperframes reverse start <video> --dir <project>` and `references/start.md`; if it refuses, run its `fix` (`billing subscribe` opens the plans page, where the person sees the price and decides, and waits for the upgrade), then start again. Given a link, run `npx hyperframes auth status` before downloading it. Resuming (a `REVERSE.md` or half-built project) opens the same. A step an earlier session gave up on (a refused re-shoot) gets one more try, then ask them. If it ran under a credit limit, ask whether that limit still holds. Rebuild the video as it is; remix it only when the person asks.
Reverse is a HyperFrames Pro feature. Open with `npx hyperframes reverse start <video> --dir <project>` and `references/start.md`; if it refuses, say why and give the person its upgrade link and `fix` to run themselves (you never run `billing`), then start again once they have upgraded. Given a link, run `npx hyperframes auth status` before downloading it. Resuming (a `REVERSE.md` or half-built project) opens the same. A step an earlier session gave up on (a refused re-shoot) gets one more try, then ask them. If it ran under a credit limit, ask whether that limit still holds. Rebuild the video as it is; remix it only when the person asks.

## The original decides the frame

Expand Down
43 changes: 21 additions & 22 deletions skills/reverse-any-video/references/start.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Opening a Reverse

What the person reads at the start, and when credits run out mid-run. Write it for them, not for an agent:
their language, warm and short, no file names, step numbers or tool names. They type nothing: you run every command,
and any page they need (sign-in, upgrade, add-on credits) goes in your message as a plain link they can click, in case the
browser did not open.
their language, warm and short, no file names, step numbers or tool names. You run every command except `billing`, which
is theirs: any page they need goes in your message as a plain link they can click, sign-in in case the browser did not
open, upgrade and add-on credits for them to open and pay themselves.

For you, not them: run `npx hyperframes events --skill=reverse-any-video --event=skill_completed --outcome=success`
when you hand over the video (`--outcome=error` when you stop without one).
Expand Down Expand Up @@ -38,19 +38,18 @@ one. Never sign in with an API key to get past Pro: that signs in a HeyGen app a

## Signed in on Free

Reverse is part of Pro. Say why in one line, then run the `reverse.subscribe_command` from `reverse start` exactly as
printed (`npx hyperframes billing subscribe --feature reverse --skill reverse-any-video --session <id>`): it opens the plans page in the person's
browser, where they see the price and decide; payment happens only there, by them. It credits the purchase to this run
and waits until they are on Pro, so the run goes on by itself. Start nothing
before it finishes. Give the `reverse.upgrade_url`, when it isn't `null`, as a link in the same message. For example:
Reverse is part of Pro. Upgrading is the person's to do: never run a `billing` command yourself. Say why in one line and
give them the `reverse.upgrade_url` as a link, and the `reverse.subscribe_command` exactly as printed
(`npx hyperframes billing subscribe --feature reverse --skill reverse-any-video --session <id>`) for them to run instead
if they prefer: either opens the plans page, where they see the price and decide. Start nothing until they say they are
on Pro, then run `reverse start` again. For example:

> Reverse is part of HyperFrames Pro: it re-shoots the people in your video with HeyGen. I've opened the upgrade page in
> your browser (or open it here: <upgrade_url>) and I'll carry on as soon as you're subscribed.
> Reverse is part of HyperFrames Pro: it re-shoots the people in your video with HeyGen. Upgrade here: <upgrade_url>
> (or run `<subscribe_command>`), then tell me and I'll carry on.

When `reverse start` refuses the run (it exits with an error whose `fix` is that command), run the `fix` the same way,
then run `reverse start` again. When `subscribe_command` is `null` (or the refusal names no command), a plan can't be
purchased right now: say so plainly, give no link, run nothing, and stop. If the command times out, tell the person
and run it again once they say they are ready.
When `reverse start` refuses the run (it exits with an error whose `fix` is that command), do the same with its `fix`.
When `subscribe_command` and `upgrade_url` are `null` (or the refusal names no command), a plan can't be purchased right
now: say so plainly, give no link, and stop.

## Signed in on Pro

Expand All @@ -63,15 +62,15 @@ or at the end of a run. `reverse start` and `auth status` are for the sign-in: d

## Out of credits mid-run

A refused step prints what it needs and the command that fixes it (buy add-on credits, or pick a plan). Shots are launched all
at once, so several refuse together: wait until every launched step has answered, add up what each refused step
needs, and run `npx hyperframes billing add-credits --needed <total> --skill reverse-any-video` once for that total, never one step at a time. If a
refusal prints no amount, run plain `billing add-credits` for that one. It opens the add-on credits page, where they see the
price, and waits until the balance covers the total; give the refusal's `url` (on an older CLI, the link in its `fix`) as a
link in the same message. Then relaunch every refused step, keeping the plan whole.
A refused step prints what it needs and the command that fixes it (buy add-on credits, or pick a plan). Buying is the
person's to do: never run a `billing` command yourself. Shots are launched all at once, so several refuse together: wait
until every launched step has answered, add up what each refused step needs, and give them `npx hyperframes billing add-credits --needed <total> --skill reverse-any-video` to run once for that total, never one step at a time, with the
refusal's `url` (on an older CLI, the link in its `fix`) as a link. If any refusal prints no amount, the total is unknown:
give plain `billing add-credits` once instead, for the whole run, never one per step. Either opens the add-on credits page, where they see the price. When they say their
balance is topped up, relaunch every refused step, keeping the plan whole.

> Three steps need 633 credits together and you have 30. I've opened the add-on credits page in your browser (or open it here:
> <url>); I'll pick up right where I stopped once your balance covers them.
> Three steps need 633 credits together and you have 30. Add credits here: <url> (or run
> `npx hyperframes billing add-credits --needed 633 --skill reverse-any-video`), then tell me and I'll pick up right where I stopped.

## Handing it over

Expand Down
Loading