tars-renderer 1.1.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tars (hellotars.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -93,6 +93,15 @@ tars-renderer agent-guide
93
93
 
94
94
  or click **Copy agent instructions** on the portal and paste them into the agent. The agent never needs keys: you approve its sign-in in your own browser, and the CLI only ever shows a masked token (`trp_ab12…`).
95
95
 
96
+ ### Add the skill to Claude Code or Codex
97
+
98
+ ```sh
99
+ npx -y tars-renderer skill install # Claude Code and Codex, for all your projects
100
+ npx -y tars-renderer skill install --repo # only this repo (.claude/skills, .codex/skills)
101
+ ```
102
+
103
+ Once the skill is added, just ask your agent to "render this Remotion project". It knows the whole workflow (version check, build, upload, estimate, render, download), always asks before spending money, and never handles keys. The portal's **CLI & Agents** page can also copy the skill, download it, or give you a prompt that makes the agent save it itself.
104
+
96
105
  ## Commands
97
106
 
98
107
  Every command accepts `--help` and `--json`. `<project>` takes a project slug or id.
@@ -176,4 +185,4 @@ Without `--yes`, any step that would ask (upload, render, delete) stops with exi
176
185
 
177
186
  ---
178
187
 
179
- **Tars Renderer:** [tars-renderer.vercel.app](https://tars-renderer.vercel.app) (invite-only). Requires Node.js 18+.
188
+ **Tars Renderer:** [tars-renderer.vercel.app](https://tars-renderer.vercel.app) (invite-only). Requires Node.js 18+. Licensed under the [MIT License](./LICENSE).
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "tars-renderer",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Command line for the Tars Renderer: upload Remotion builds, render on AWS Lambda, download the MP4.",
5
5
  "homepage": "https://tars-renderer.vercel.app",
6
+ "author": "Tars (https://hellotars.com)",
7
+ "license": "MIT",
6
8
  "type": "module",
7
9
  "bin": {
8
10
  "tars-renderer": "tars-renderer.mjs"
9
11
  },
10
12
  "files": [
11
13
  "tars-renderer.mjs",
12
- "README.md"
14
+ "README.md",
15
+ "LICENSE",
16
+ "skill/SKILL.md"
13
17
  ],
14
18
  "engines": {
15
19
  "node": ">=18"
@@ -24,7 +28,6 @@
24
28
  "video",
25
29
  "ai-agent"
26
30
  ],
27
- "license": "UNLICENSED",
28
31
  "publishConfig": {
29
32
  "access": "public"
30
33
  }
package/skill/SKILL.md ADDED
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: tars-renderer
3
+ description: Render Remotion videos in the cloud with Tars Renderer (the team's AWS Lambda render farm) through the `tars-renderer` CLI. Use when the user wants to render or export a Remotion composition to MP4, upload a Remotion build, check cost or render progress, list or download renders, or sign in to Tars Renderer from the terminal.
4
+ ---
5
+
6
+ # Tars Renderer
7
+
8
+ Tars Renderer renders Remotion projects on AWS Lambda for the Tars team: upload a built project, pick a composition, get an MP4 back. You drive it with the `tars-renderer` CLI. The portal is https://tars-renderer.vercel.app. The user never needs AWS keys.
9
+
10
+ ## Ground rules
11
+
12
+ - **Never ask for or handle secrets.** Sign-in happens in the user's browser. Don't open, read, print or copy anything in `~/.tars-renderer/`. The CLI only ever shows a masked token (`trp_ab12…`); if you see a full one, stop and tell the user to sign that device out on the portal's CLI & Agents page.
13
+ - **Cost needs a yes.** Always run `estimate` first, tell the user the cost, output size and frames, and only start the render (with `--yes`) after they agree.
14
+ - **Test small first.** For a first or experimental render, suggest `--res 360p --seconds 0-5`.
15
+ - **Don't change the user's code**, except pinning Remotion versions (step 2), and only after they agree.
16
+ - **Read results with `--json`.** One JSON document goes to stdout; progress and logs go to stderr.
17
+ - **On failure, stop and explain** what happened and what you suggest. Don't loop on retries.
18
+
19
+ ## Workflow
20
+
21
+ ### 1. Make sure the CLI is ready
22
+
23
+ ```sh
24
+ tars-renderer doctor --json
25
+ ```
26
+
27
+ - `command not found`: install it with `npm i -g tars-renderer` (Node.js 18+), or prefix commands with `npx -y tars-renderer`.
28
+ - Exit code **4** (not signed in): ask the user to run `tars-renderer login` themselves. A browser tab opens; they check that the code matches and click Approve. Wait for them, then run `doctor` again.
29
+ - Access denied: the user's work email isn't on the allowlist; they can request access on the portal.
30
+
31
+ ### 2. Check the Remotion version
32
+
33
+ The renderer supports Remotion **4.0.535** exactly. In the project folder run `npx remotion versions`. If anything differs:
34
+
35
+ 1. Detect the package manager from the lockfile (npm, pnpm, yarn or bun).
36
+ 2. Propose pinning `remotion` and every `@remotion/*` package to exactly 4.0.535 (npm: `npm i --save-exact remotion@4.0.535 @remotion/cli@4.0.535 …`; pnpm: `pnpm add --save-exact`; yarn: `yarn add --exact`; bun: `bun add --exact`).
37
+ 3. Run it only after the user agrees, then check again.
38
+
39
+ ### 3. Build
40
+
41
+ Find the entry file that calls `registerRoot` (usually `src/index.ts`, `src/index.tsx` or `remotion/index.ts`), then:
42
+
43
+ ```sh
44
+ npx remotion bundle src/index.ts --out-dir build
45
+ ```
46
+
47
+ The `build` folder must contain `index.html` and `bundle.js`.
48
+
49
+ ### 4. Pick or create the project
50
+
51
+ ```sh
52
+ tars-renderer projects --mine --json
53
+ ```
54
+
55
+ Reuse a project for this repo if one exists (match by name). Otherwise ask the user for a name, then:
56
+
57
+ ```sh
58
+ tars-renderer create "<name>" --json # returns the project slug
59
+ ```
60
+
61
+ ### 5. Upload
62
+
63
+ ```sh
64
+ tars-renderer upload build --project <slug> --yes --json
65
+ ```
66
+
67
+ Only changed files are sent, so re-uploading is fast. The JSON lists the compositions found. Uploads are refused while a render of that project is running; wait for it to finish.
68
+
69
+ ### 6. Choose and estimate
70
+
71
+ ```sh
72
+ tars-renderer comps <slug> --json
73
+ tars-renderer estimate <slug> <composition> --res 1080p --json
74
+ ```
75
+
76
+ Ask the user which composition and settings to use if they didn't say. Options: `--res 360p|720p|1080p|4k`, `--quality draft|standard|high`, `--seconds a-b` or `--frames a-b`, `--muted`, `--keep 1-day|3-days|7-days|30-days|forever`. Report `estimateUsd`, the output size and the frames, and any `blockedReason` (monthly budget, per-person cap, or too many renders running).
77
+
78
+ ### 7. Render, then download
79
+
80
+ After the user agrees to the cost:
81
+
82
+ ```sh
83
+ tars-renderer render <slug> <composition> [same options] --yes --watch --json
84
+ tars-renderer download <renderId> --out <file>.mp4 --json
85
+ ```
86
+
87
+ `--watch` follows progress until the render is done (exit 0) or fails (exit 1). Tell the user where the file was saved. They can also watch it on the portal's Renders page.
88
+
89
+ ## Exit codes
90
+
91
+ | Code | Meaning | What to do |
92
+ |---|---|---|
93
+ | 0 | OK | Continue |
94
+ | 1 | Error | Read `error` in the JSON, explain it, stop |
95
+ | 2 | Bad usage | Fix the command (check `tars-renderer <command> --help`) |
96
+ | 3 | Confirmation needed | Show the user the details, re-run with `--yes` only if they agree |
97
+ | 4 | Not signed in | Ask the user to run `tars-renderer login` |
98
+
99
+ ## Common problems
100
+
101
+ | Message | Fix |
102
+ |---|---|
103
+ | `This build uses Remotion X` | Pin to 4.0.535 (step 2), rebuild, upload again |
104
+ | `index.html and bundle.js not found` | Pass the `build` folder, not the project root |
105
+ | `A render of this project is running` | Wait for it, then upload |
106
+ | Over budget / too many renders | Tell the user; an admin can raise limits on the portal's Usage & limits page |
107
+ | Render failed | Show the error from `tars-renderer status <id> --json`; try 360p with a short range |
108
+
109
+ ## Other useful commands
110
+
111
+ `tars-renderer renders --mine --json` (recent renders), `tars-renderer status <id> --json`, `tars-renderer link <id>` (24-hour share link), `tars-renderer logout` (`--all` signs out every device), `tars-renderer --help`.
package/tars-renderer.mjs CHANGED
@@ -12,7 +12,7 @@ import { setMaxListeners } from "node:events";
12
12
  import { setTimeout as delay } from "node:timers/promises";
13
13
  import { fileURLToPath } from "node:url";
14
14
 
15
- export const VERSION = "1.1.0";
15
+ export const VERSION = "1.1.1";
16
16
 
17
17
  /** The Tars Renderer portal. `login` signs in here unless another portal is passed (development, staging). */
18
18
  export const DEFAULT_PORTAL = "https://tars-renderer.vercel.app";
@@ -72,7 +72,7 @@ const notLoggedIn = () =>
72
72
 
73
73
  // ---------------------------------------------------------------- pure helpers (exported for tests)
74
74
 
75
- const BOOLEAN = new Set(["json", "yes", "help", "watch", "mine", "muted", "rehash", "all", "local", "purge"]);
75
+ const BOOLEAN = new Set(["json", "yes", "help", "watch", "mine", "muted", "rehash", "all", "local", "purge", "repo"]);
76
76
  const ALIASES = { h: "help", y: "yes" };
77
77
 
78
78
  /** `--x value`, `--x=value`, boolean `--x`, `-h`/`-y`, `--` ends options. A non-boolean flag without a value is `true`. */
@@ -1625,6 +1625,40 @@ Exit codes: 0 ok, 1 error (read "error" in the JSON), 2 bad usage, 3 confirmatio
1625
1625
  Never print or log the CLI token (kept in the OS credential store, or ~/.tars-renderer/config.json).
1626
1626
  `;
1627
1627
 
1628
+ // ---------------------------------------------------------------- agent skill
1629
+
1630
+ /** SKILL.md ships inside this package (cli/skill/SKILL.md), so the skill always matches the CLI version. */
1631
+ export function readSkill() {
1632
+ return fs.readFileSync(new URL("./skill/SKILL.md", import.meta.url), "utf8");
1633
+ }
1634
+
1635
+ /** Where each agent looks for skills: user-wide under ~, or per repo under the current folder (--repo). */
1636
+ export function skillTargets(forAgent, project, home = os.homedir(), cwd = process.cwd()) {
1637
+ const base = project ? cwd : home;
1638
+ const all = { claude: path.join(base, ".claude", "skills", "tars-renderer"), codex: path.join(base, ".codex", "skills", "tars-renderer") };
1639
+ if (forAgent === "all") return all;
1640
+ if (!(forAgent in all)) throw usage(`--for must be claude, codex or all, got "${forAgent}"`);
1641
+ return { [forAgent]: all[forAgent] };
1642
+ }
1643
+
1644
+ async function cmdSkill(_, f) {
1645
+ const action = _[0] ?? "show";
1646
+ if (action === "show") return done({ skill: readSkill() }, (d) => process.stdout.write(d.skill));
1647
+ if (action !== "install") throw usage(`Unknown action "${action}". Use: tars-renderer skill install | show`);
1648
+ const targets = skillTargets(typeof f.for === "string" ? f.for : "all", !!f.repo);
1649
+ const skill = readSkill();
1650
+ const installed = Object.entries(targets).map(([agent, dir]) => {
1651
+ fs.mkdirSync(dir, { recursive: true });
1652
+ const file = path.join(dir, "SKILL.md");
1653
+ fs.writeFileSync(file, skill);
1654
+ return { agent, file };
1655
+ });
1656
+ done({ ok: true, installed }, () => {
1657
+ for (const i of installed) say(`${green("✔")} ${i.agent === "claude" ? "Claude Code" : "Codex"}: ${i.file}`);
1658
+ say(dim(" Start a new agent session, then ask it to render your Remotion project."));
1659
+ });
1660
+ }
1661
+
1628
1662
  async function cmdAgentGuide(_, f) {
1629
1663
  const cfg = loadConfig();
1630
1664
  const portal = (typeof f.portal === "string" ? f.portal : cfg.portal)?.replace(/\/+$/, "");
@@ -1779,6 +1813,21 @@ hashes every file (SHA-256), shows what changed and asks before uploading. Hashe
1779
1813
  summary: "Delete a project and its uploaded files",
1780
1814
  run: cmdDeleteProject,
1781
1815
  },
1816
+ skill: {
1817
+ args: [],
1818
+ optArgs: ["action"],
1819
+ flags: ["for=", "repo"],
1820
+ usage: "skill [install|show] [--for claude|codex|all] [--repo]",
1821
+ summary: "Add the Tars Renderer skill to Claude Code / Codex",
1822
+ help: `Installs the agent skill, so your coding agent knows how to use Tars Renderer in every session.
1823
+
1824
+ install write SKILL.md for your agents (default: Claude Code and Codex)
1825
+ show print the skill (default)
1826
+ --for <agent> claude, codex or all (default all)
1827
+ --repo install into this repo (.claude/skills, .codex/skills) instead of your home folder`,
1828
+ examples: ["npx tars-renderer skill install", "tars-renderer skill install --for claude --repo"],
1829
+ run: cmdSkill,
1830
+ },
1782
1831
  "agent-guide": {
1783
1832
  args: [],
1784
1833
  flags: ["portal="],