@shotstack/cli 0.1.3 → 0.3.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Shotstack CLI
2
2
 
3
- Command-line interface for the [Shotstack](https://shotstack.io) video rendering API. Built for humans and AI coding agents.
3
+ Command-line interface for the [Shotstack](https://shotstack.io) video rendering API. Built for humans and AI agents.
4
4
 
5
5
  ```sh
6
6
  shotstack render template.json
@@ -16,7 +16,7 @@ npm i -g @shotstack/cli
16
16
  # one-shot via npx
17
17
  npx @shotstack/cli render template.json
18
18
 
19
- # one-shot via bun (~100x faster than npx for cached invocations)
19
+ # one-shot via bun
20
20
  bunx @shotstack/cli render template.json
21
21
  ```
22
22
 
@@ -27,7 +27,7 @@ All three install paths use the same `@shotstack/cli` package on npm.
27
27
  Set your API key as an environment variable:
28
28
 
29
29
  ```sh
30
- export SHOTSTACK_API_KEY=sk_...
30
+ export SHOTSTACK_API_KEY=...
31
31
  ```
32
32
 
33
33
  Get a key at <https://shotstack.io>.
@@ -50,11 +50,13 @@ SHOTSTACK_ENV=stage shotstack render template.json
50
50
 
51
51
  ### `shotstack render <file>`
52
52
 
53
- Submits a Shotstack Edit JSON to the render API. Returns a render ID.
53
+ Submits a Shotstack Edit JSON to the render API. Returns a render ID. With `--watch`, polls until the render reaches a terminal state and prints the output URL — equivalent to `render` followed by `status --watch` but in one command.
54
54
 
55
55
  ```sh
56
56
  shotstack render my-template.json
57
57
  shotstack render my-template.json --output json
58
+ shotstack render my-template.json --watch # submit + poll until done
59
+ shotstack render my-template.json --watch --output json
58
60
  ```
59
61
 
60
62
  ### `shotstack status <id>`
@@ -67,6 +69,24 @@ shotstack status 01ja7-x8m2k-... --watch
67
69
  shotstack status 01ja7-x8m2k-... --output json
68
70
  ```
69
71
 
72
+ ### `shotstack studio <file>`
73
+
74
+ Opens a `shotstack.studio` URL that loads the Edit JSON in the browser-based editor. By default, posts the JSON to the share API and emits a short URL like `https://shotstack.studio/s/abc12345` — clean, shareable, expires in 30 days. Falls back to inline base64url encoding if the share API is unreachable.
75
+
76
+ No render API key required; no render credits charged. Use to hand a generated edit off to a human for review or quick tweaks before rendering.
77
+
78
+ ```sh
79
+ shotstack studio my-template.json
80
+ # → opens browser silently with https://shotstack.studio/s/<slug>
81
+
82
+ shotstack studio my-template.json --copy # also copies URL to clipboard
83
+ shotstack studio my-template.json --no-open # print URL, don't open browser
84
+ shotstack studio my-template.json --no-shorten # emit base64url inline (offline / debug)
85
+ shotstack studio my-template.json --output json # emit {"url":"...","shortened":true} on stdout
86
+ ```
87
+
88
+ When a browser can be launched, the command is silent — the URL only opens in the browser. On a headless server (no `$DISPLAY`, no `xdg-open`), the URL is printed to stdout instead so you can copy it elsewhere.
89
+
70
90
  ### `shotstack feedback`
71
91
 
72
92
  Opens a pre-filled GitHub issue with a sanitised dossier of your last 5 CLI invocations (render IDs, errors, exit codes). API keys and signed URLs are stripped at write time. You review and submit in your browser; nothing is transmitted automatically. Inspect the log at `~/.shotstack/log.jsonl`.
package/SKILL.md CHANGED
@@ -4,26 +4,25 @@ description: |
4
4
  Render video and poll render status via the Shotstack API.
5
5
  Use when generating clips, building automated video pipelines, or orchestrating
6
6
  cloud video renders from a script, agent, or CI workflow.
7
- NOT for: real-time streaming, live broadcasting, or in-browser editing UIs.
7
+ NOT for: real-time streaming, or live broadcasting.
8
8
  license: Apache-2.0
9
9
  ---
10
10
 
11
11
  # Shotstack CLI
12
12
 
13
- Two commands for the Shotstack video rendering API. `render` submits a timeline JSON and returns a render ID; `status` polls a render until done.
13
+ Two commands for the Shotstack video rendering API. `render` submits an Edit JSON and returns a render ID; `status` polls a render until done.
14
14
 
15
15
  ## Authentication
16
16
 
17
17
  ```sh
18
- export SHOTSTACK_API_KEY=sk_...
18
+ export SHOTSTACK_API_KEY=...
19
19
  ```
20
20
 
21
- Get a key at <https://dashboard.shotstack.io>. Without a key, every command exits with code 1.
21
+ Get a key at <https://app.shotstack.io>. Without a key, every command exits with code 1.
22
22
 
23
23
  ## Environments
24
24
 
25
25
  ```
26
- --env dev → https://api.shotstack.io/edit/dev
27
26
  --env stage → https://api.shotstack.io/edit/stage (test credits, free)
28
27
  --env v1 → https://api.shotstack.io/edit/v1 (production, default)
29
28
  ```
@@ -33,179 +32,53 @@ Use `--env stage` for experimentation. Stage is free; v1 charges real credits. O
33
32
  ## Quickstart
34
33
 
35
34
  ```sh
36
- # Submit. Use --output json so the ID is parseable.
37
- shotstack render template.json --output json --env stage
35
+ # Submit + poll in one command (most agent flows want this).
36
+ shotstack render template.json --watch
37
+ # → done https://shotstack-api-v1-output.s3.amazonaws.com/.../01ja7-x8m2k-39rzv-cmvxve.mp4
38
+
39
+ # Submit only (returns ID).
40
+ shotstack render template.json --output json
38
41
  # → {"id":"01ja7-x8m2k-39rzv-cmvxve"}
39
42
 
40
- # Poll until terminal state.
41
- shotstack status 01ja7-x8m2k-39rzv-cmvxve --watch --env stage
42
- # → done https://shotstack-api-stage-output.s3.amazonaws.com/.../out.mp4
43
+ # Poll an existing render to terminal state.
44
+ shotstack status 01ja7-x8m2k-39rzv-cmvxve --watch
45
+ # → done https://shotstack-api-v1-output.s3.amazonaws.com/.../01ja7-x8m2k-39rzv-cmvxve.mp4
43
46
  ```
44
47
 
45
- ## Three CLI rules
46
-
47
- 1. **Pipe → `--output json`.** Default output is human-readable. When parsing programmatically or piping to another command, always pass `--output json`. The text format is not stable across versions.
48
-
49
- 2. **Use `--watch`, not a polling loop.** `shotstack status <id> --watch` exits when the render reaches `done` (exit 0) or `failed` (exit 1). Don't write `while true; do ...; sleep 3; done`.
50
-
51
- 3. **Fetch the current docs before generating timeline JSON.** The Shotstack API evolves; LLM training data is often stale. Pull <https://shotstack.io/docs/guide/llms-full.txt> for the current schema and examples before composing a timeline from scratch.
52
-
53
- ## Authoring timeline JSON
54
-
55
- These are the conventions agents most often get wrong. Read this section before generating any timeline JSON.
56
-
57
- ### Before composing JSON: check the schema
58
-
59
- Don't invent property names or enum values. The Shotstack schema is published — fetch one of these before composing JSON from scratch:
60
-
61
- - <https://shotstack.io/docs/api/api.bundled.json> — single-file JSON Schema. Machine-validatable; load it once and validate locally instead of round-tripping the API.
62
- - <https://shotstack.io/docs/api/> — interactive HTML reference. Fastest for human scanning.
63
- - <https://shotstack.io/docs/guide/llms-full.txt> — single-file LLM-friendly version of the full guide + reference.
64
- - <https://github.com/shotstack/oas-api-definition/tree/main/schemas> — raw OpenAPI YAML, source of truth.
48
+ ## Hand-off to a human before rendering
65
49
 
66
- CSS naming conventions (`alignment`, `vertical: "center"`) **do not** apply. The spec uses precise names that often differ from web/CSS instincts:
50
+ When a human is in the loop and may want to tweak the result, prefer **`shotstack studio <file>`** over `shotstack render`. By default it posts the JSON to the share API and opens `https://shotstack.studio/s/<slug>` in the browser — a short, shareable URL. No API key, no render credits charged. The human can play, edit, and decide whether to render.
67
51
 
68
- | You'd guess (wrong) | API uses (right) |
69
- |---|---|
70
- | `alignment` | `align` |
71
- | `align.vertical: "center"` | `align.vertical: "middle"` |
72
- | `font.name` | `font.family` |
73
- | `duration` | `length` |
74
- | `transitions: [...]` (array) | `transition: { in, out }` (object) |
75
- | `fit: "cover"` (CSS instinct: scale+crop maintaining aspect) | `fit: "crop"` — Shotstack's `cover` STRETCHES without maintaining aspect ratio |
76
-
77
- When the API rejects a property, the error message names the field — fix and retry. Don't guess twice.
78
-
79
- ### Track ordering is REVERSED
80
-
81
- `timeline.tracks` is an array. **The first element (`tracks[0]`) is the TOP layer; the last element is the BOTTOM layer.** This is opposite to most z-index conventions.
82
-
83
- > "Tracks are layered on top of each other in the same order they are added to the array with the top most track layered over the top of those below it." — [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/guidelines/)
84
-
85
- Practical rule: **put captions, overlays, and titles in early tracks; put video/image backgrounds in later tracks.**
86
-
87
- ```json
88
- {
89
- "timeline": {
90
- "tracks": [
91
- { "clips": [/* TOP — captions */] },
92
- { "clips": [/* MIDDLE — title overlay */] },
93
- { "clips": [/* BOTTOM — background video */] }
94
- ]
95
- }
96
- }
52
+ ```sh
53
+ shotstack studio template.json # opens browser + prints short URL
54
+ shotstack studio template.json --no-open # headless: just print the URL
55
+ shotstack studio template.json --no-shorten # emit base64url URL inline (offline / debug)
56
+ shotstack studio template.json --output json # piping: {"url":"...","shortened":true}, no browser
97
57
  ```
98
58
 
99
- ### Smart clip strings
59
+ On headless systems (no `xdg-open`, no `$DISPLAY`) the browser launch silently no-ops; the URL is still printed. Safe to run anywhere.
100
60
 
101
- These string values are accepted in addition to numbers:
61
+ If the share API is unreachable, the command falls back to the inline base64url form automatically and prints a stderr warning. Shares expire after 30 days.
102
62
 
103
- | Where | Value | Meaning |
104
- |---|---|---|
105
- | `clip.start` | `"auto"` | Start when the previous clip on the same track finishes |
106
- | `clip.start` | `"alias://<name>"` | Inherit start from another clip with `alias: "<name>"` |
107
- | `clip.length` | `"auto"` | Play for the full duration of the asset |
108
- | `clip.length` | `"end"` | Play until the end of the timeline |
109
- | `clip.length` | `"alias://<name>"` | Inherit length from another clip |
63
+ Use `render` only when you're confident the JSON is final, or there's no human to review.
110
64
 
111
- The `alias://` protocol is also used in `rich-caption` `src` to auto-transcribe a referenced audio/video clip — see `references/rich-caption.md`.
65
+ ## Four CLI rules
112
66
 
113
- ### Public HTTPS URLs only
67
+ 1. **Pipe → `--output json`.** Default output is human-readable. When parsing programmatically or piping to another command, always pass `--output json`.
114
68
 
115
- All asset `src` URLs must be publicly accessible HTTPS. **No local file paths, no `data:` URIs, no signed URLs that expire mid-render.** The render workers fetch assets from the public internet.
69
+ 2. **Use `--watch`, not a polling loop.** `shotstack render <file> --watch` submits and polls in one shot; `shotstack status <id> --watch` polls an existing render. Both exit when terminal: `done` (exit 0) or `failed` (exit 1). Don't write `while true; do ...; sleep 3; done`.
116
70
 
117
- For test renders without your own assets, use the placeholder library at <https://shotstack-assets.s3.amazonaws.com/> — see `references/asset-library.md`.
71
+ 3. **Fetch the current schema and docs before generating Edit JSON.** The Shotstack API evolves; LLM training data is often stale. Pull <https://shotstack.io/docs/api/api.edit.json> and <https://shotstack.io/docs/guide/llms-full.txt> for the current schema and guides before composing an Edit from scratch.
118
72
 
119
- ### Don't overlap clips on the same track
73
+ 4. **Hand off to a human via `studio` when uncertain.** Don't burn render credits iterating. Generate JSON → `shotstack studio` → human reviews/tweaks → render only when right.
120
74
 
121
- Clips on the same track must not have overlapping `start`/`length` ranges. Overlapping clips flicker because the engine can't decide which to display. Put parallel content on separate tracks.
122
-
123
- ### Output resolution
124
-
125
- Pick `output.resolution` (preset) OR `output.size.width`+`output.size.height` (custom):
126
-
127
- | Preset | Pixels @ fps |
128
- |---|---|
129
- | `preview` | 512×288 @ 15 |
130
- | `mobile` | 640×360 @ 25 |
131
- | `sd` | 1024×576 @ 25 |
132
- | `hd` | 1280×720 @ 25 (default) |
133
- | `1080` | 1920×1080 @ 25 |
134
-
135
- Custom sizes must be divisible by 2.
136
-
137
- ## Asset types
138
-
139
- The render API supports many asset types. Use only the **current** ones; the deprecated ones still parse but should not be used in new templates.
140
-
141
- ### Current
142
-
143
- | Type | Purpose |
144
- |---|---|
145
- | `video` | Video file (mp4, mov, webm). |
146
- | `image` | Static image (jpg, png). |
147
- | `audio` | Audio clip placed at a specific time on the timeline. |
148
- | `rich-text` | Styled text overlay with full typography control. **Use this instead of `text`/`html`/`title`.** |
149
- | `svg` | Vector graphics from raw SVG markup. See `references/svg.md`. |
150
- | `rich-caption` | Word-level animated captions sourced from audio, video, or subtitle files. See `references/rich-caption.md`. |
151
- | `luma` | Luma matte for masking effects. |
152
- | `image-to-video` | **AI**: animate a still image into a short video clip. Billed per generation. |
153
- | `text-to-image` | **AI**: generate an image from a text prompt. Billed per generation. |
154
-
155
- `timeline.soundtrack` is a separate top-level field (not an asset type) for a single background music track. `timeline.fonts[]` is a separate field for custom font URLs.
156
-
157
- ### Deprecated — do not use
158
-
159
- `text`, `title`, `caption`, `html`, `shape`. They still parse but produce inferior output. Replace with:
160
-
161
- | If you'd use… | Use instead |
162
- |---|---|
163
- | `text` or `title` | `rich-text` |
164
- | `caption` | `rich-caption` |
165
- | `html` | `rich-text` |
166
- | `shape` | `svg` with `<rect>`, `<circle>`, `<polygon>` etc. |
167
-
168
- ### AI-generated assets
169
-
170
- `image-to-video` and `text-to-image` are billed per generation **even when invoked through the sandbox stage endpoint** (which is otherwise free). They are async — the render submits the AI job and waits. Renders containing AI assets take longer.
171
-
172
- ## Fonts
173
-
174
- Prefer **custom Google Fonts via `timeline.fonts[]`** over the built-in font list. The Studio SDK exposes ~400 Google Fonts. See `references/fonts.md` for the URL pattern and the built-in fallback list.
175
-
176
- Per the [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/rich-text/#custom-fonts), custom fonts give you the full Google Fonts catalogue with predictable rendering. System fonts like `Arial`, `Helvetica`, and `Times New Roman` are NOT installed and will fail with "Font not found".
177
-
178
- ```json
179
- {
180
- "timeline": {
181
- "fonts": [
182
- { "src": "https://fonts.gstatic.com/s/montserrat/v31/JTUSjIg1_i6t8kCHKm45xW5rygbi49c.ttf" }
183
- ],
184
- "tracks": [
185
- {
186
- "clips": [{
187
- "asset": {
188
- "type": "rich-text",
189
- "text": "Hello",
190
- "font": { "family": "JTUSjIg1_i6t8kCHKm45xW5rygbi49c", "size": 60, "color": "#ffffff" }
191
- },
192
- "start": 0, "length": 3
193
- }]
194
- }
195
- ]
196
- }
197
- }
198
- ```
75
+ ## Authoring Edit JSON
199
76
 
200
- The `font.family` value is the **font file basename** (without `.ttf`/`.otf`).
77
+ The conventions agents most often get wrong (track order is reversed, asset type names, font allowlist, smart strings) live in the shared agent-core guide:
201
78
 
202
- ## Top 5 mistakes
79
+ **See [`shared/agent-core.md`](shared/agent-core.md)** before composing any Edit JSON.
203
80
 
204
- 1. **Reverse track order.** `tracks[0]` is the TOP layer, not the bottom. Captions go in early tracks; backgrounds go in late tracks.
205
- 2. **System fonts.** `Arial`, `Helvetica`, `Times New Roman`, etc. are not installed. Use Google Fonts via `timeline.fonts[]` (preferred) or one of the built-in fonts in `references/fonts.md`.
206
- 3. **Captions fill the whole frame.** A `rich-caption` clip without `width`, `height`, and `fit: "none"` covers the entire output. Use a named preset from `references/rich-caption.md`.
207
- 4. **`<text>` inside an SVG asset.** Raw `<text>` is unsupported. Use a `rich-text` asset for any text content; reserve SVG for shapes only.
208
- 5. **Composing custom caption styles when presets exist.** The five named presets (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) cover the common styles. Use one verbatim from `references/rich-caption.md` unless the user asks for something specific.
81
+ This file is also delivered to chat-based clients (Claude.ai, ChatGPT) via the Shotstack MCP server, so the conventions stay identical across surfaces.
209
82
 
210
83
  ## Exit codes
211
84
 
@@ -220,16 +93,18 @@ The `font.family` value is the **font file basename** (without `.ttf`/`.otf`).
220
93
  Authoritative sources, in order of preference:
221
94
 
222
95
  - `shotstack --help` and `shotstack <command> --help` — current CLI flag listing
223
- - <https://shotstack.io/docs/api/api.bundled.json> — JSON Schema for the render API (machine-validatable)
96
+ - [`shared/agent-core.md`](shared/agent-core.md) — Edit JSON authoring conventions (shared with MCP server)
97
+ - <https://shotstack.io/docs/api/api.edit.json> — OpenAPI Schema for the render API (machine-validatable)
224
98
  - <https://shotstack.io/docs/guide/llms-full.txt> — full API docs in LLM-friendly single file
225
99
  - <https://github.com/shotstack/oas-api-definition/tree/main/schemas> — raw OpenAPI YAML, source of truth for property names and enums
226
- - <https://shotstack.io/docs/api/> — interactive HTML reference
100
+ - <https://shotstack.io/docs/guide/> — interactive HTML docs and guides
101
+ - <https://shotstack.io/docs/api/> — interactive HTML API reference
227
102
  - <https://github.com/shotstack/shotstack-cli> — CLI source
228
103
 
229
104
  This skill ships sub-references for the gnarly bits:
230
105
 
231
- - [`references/timeline.md`](references/timeline.md) — track layering, transitions, soundtrack vs audio
232
- - [`references/rich-caption.md`](references/rich-caption.md) — sizing per resolution, default style, the 5 named presets, alias pattern
106
+ - [`references/timeline.md`](references/timeline.md) — track layering, transitions, background music via audio assets
107
+ - [`references/caption.md`](references/caption.md) — sizing per resolution, default style, the 5 named presets, alias pattern (asset type: `rich-caption`)
233
108
  - [`references/svg.md`](references/svg.md) — required attrs, supported elements
234
109
  - [`references/fonts.md`](references/fonts.md) — built-in fonts, Google Fonts URL pattern, custom-font workflow
235
110
  - [`references/asset-library.md`](references/asset-library.md) — placeholder videos, images, music
package/dist/shotstack.js CHANGED
@@ -1,26 +1,26 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as CE}from"node:module";var WE=Object.create;var{getPrototypeOf:DE,defineProperty:m,getOwnPropertyNames:FE}=Object;var kE=Object.prototype.hasOwnProperty;function VE(E){return this[E]}var AE,xE,bE=(E,f,R)=>{var $=E!=null&&typeof E==="object";if($){var S=f?AE??=new WeakMap:xE??=new WeakMap,T=S.get(E);if(T)return T}R=E!=null?WE(DE(E)):{};let L=f||!E||!E.__esModule?m(R,"default",{value:E,enumerable:!0}):R;for(let _ of FE(E))if(!kE.call(L,_))m(L,_,{get:VE.bind(E,_),enumerable:!0});if($)S.set(E,L);return L};var X=(E,f)=>()=>(f||E((f={exports:{}}).exports,f),f.exports);var Q=CE(import.meta.url);var K=X((uE)=>{class u extends Error{constructor(E,f,R){super(R);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=f,this.exitCode=E,this.nestedError=void 0}}class d extends u{constructor(E){super(1,"commander.invalidArgument",E);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}}uE.CommanderError=u;uE.InvalidArgumentError=d});var N=X((sE)=>{var{InvalidArgumentError:vE}=K();class p{constructor(E,f){switch(this.description=f||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,E[0]){case"<":this.required=!0,this._name=E.slice(1,-1);break;case"[":this.required=!1,this._name=E.slice(1,-1);break;default:this.required=!0,this._name=E;break}if(this._name.length>3&&this._name.slice(-3)==="...")this.variadic=!0,this._name=this._name.slice(0,-3)}name(){return this._name}_concatValue(E,f){if(f===this.defaultValue||!Array.isArray(f))return[E];return f.concat(E)}default(E,f){return this.defaultValue=E,this.defaultValueDescription=f,this}argParser(E){return this.parseArg=E,this}choices(E){return this.argChoices=E.slice(),this.parseArg=(f,R)=>{if(!this.argChoices.includes(f))throw new vE(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(f,R);return f},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}}function rE(E){let f=E.name()+(E.variadic===!0?"...":"");return E.required?"<"+f+">":"["+f+"]"}sE.Argument=p;sE.humanReadableArgName=rE});var h=X((nE)=>{var{humanReadableArgName:gE}=N();class o{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands(E){let f=E.commands.filter(($)=>!$._hidden),R=E._getHelpCommand();if(R&&!R._hidden)f.push(R);if(this.sortSubcommands)f.sort(($,S)=>{return $.name().localeCompare(S.name())});return f}compareOptions(E,f){let R=($)=>{return $.short?$.short.replace(/^-/,""):$.long.replace(/^--/,"")};return R(E).localeCompare(R(f))}visibleOptions(E){let f=E.options.filter(($)=>!$.hidden),R=E._getHelpOption();if(R&&!R.hidden){let $=R.short&&E._findOption(R.short),S=R.long&&E._findOption(R.long);if(!$&&!S)f.push(R);else if(R.long&&!S)f.push(E.createOption(R.long,R.description));else if(R.short&&!$)f.push(E.createOption(R.short,R.description))}if(this.sortOptions)f.sort(this.compareOptions);return f}visibleGlobalOptions(E){if(!this.showGlobalOptions)return[];let f=[];for(let R=E.parent;R;R=R.parent){let $=R.options.filter((S)=>!S.hidden);f.push(...$)}if(this.sortOptions)f.sort(this.compareOptions);return f}visibleArguments(E){if(E._argsDescription)E.registeredArguments.forEach((f)=>{f.description=f.description||E._argsDescription[f.name()]||""});if(E.registeredArguments.find((f)=>f.description))return E.registeredArguments;return[]}subcommandTerm(E){let f=E.registeredArguments.map((R)=>gE(R)).join(" ");return E._name+(E._aliases[0]?"|"+E._aliases[0]:"")+(E.options.length?" [options]":"")+(f?" "+f:"")}optionTerm(E){return E.flags}argumentTerm(E){return E.name()}longestSubcommandTermLength(E,f){return f.visibleCommands(E).reduce((R,$)=>{return Math.max(R,f.subcommandTerm($).length)},0)}longestOptionTermLength(E,f){return f.visibleOptions(E).reduce((R,$)=>{return Math.max(R,f.optionTerm($).length)},0)}longestGlobalOptionTermLength(E,f){return f.visibleGlobalOptions(E).reduce((R,$)=>{return Math.max(R,f.optionTerm($).length)},0)}longestArgumentTermLength(E,f){return f.visibleArguments(E).reduce((R,$)=>{return Math.max(R,f.argumentTerm($).length)},0)}commandUsage(E){let f=E._name;if(E._aliases[0])f=f+"|"+E._aliases[0];let R="";for(let $=E.parent;$;$=$.parent)R=$.name()+" "+R;return R+f+" "+E.usage()}commandDescription(E){return E.description()}subcommandDescription(E){return E.summary()||E.description()}optionDescription(E){let f=[];if(E.argChoices)f.push(`choices: ${E.argChoices.map((R)=>JSON.stringify(R)).join(", ")}`);if(E.defaultValue!==void 0){if(E.required||E.optional||E.isBoolean()&&typeof E.defaultValue==="boolean")f.push(`default: ${E.defaultValueDescription||JSON.stringify(E.defaultValue)}`)}if(E.presetArg!==void 0&&E.optional)f.push(`preset: ${JSON.stringify(E.presetArg)}`);if(E.envVar!==void 0)f.push(`env: ${E.envVar}`);if(f.length>0)return`${E.description} (${f.join(", ")})`;return E.description}argumentDescription(E){let f=[];if(E.argChoices)f.push(`choices: ${E.argChoices.map((R)=>JSON.stringify(R)).join(", ")}`);if(E.defaultValue!==void 0)f.push(`default: ${E.defaultValueDescription||JSON.stringify(E.defaultValue)}`);if(f.length>0){let R=`(${f.join(", ")})`;if(E.description)return`${E.description} ${R}`;return R}return E.description}formatHelp(E,f){let R=f.padWidth(E,f),$=f.helpWidth||80,S=2,T=2;function L(U,P){if(P){let C=`${U.padEnd(R+2)}${P}`;return f.wrap(C,$-2,R+2)}return U}function _(U){return U.join(`
3
- `).replace(/^/gm," ".repeat(2))}let I=[`Usage: ${f.commandUsage(E)}`,""],w=f.commandDescription(E);if(w.length>0)I=I.concat([f.wrap(w,$,0),""]);let y=f.visibleArguments(E).map((U)=>{return L(f.argumentTerm(U),f.argumentDescription(U))});if(y.length>0)I=I.concat(["Arguments:",_(y),""]);let q=f.visibleOptions(E).map((U)=>{return L(f.optionTerm(U),f.optionDescription(U))});if(q.length>0)I=I.concat(["Options:",_(q),""]);if(this.showGlobalOptions){let U=f.visibleGlobalOptions(E).map((P)=>{return L(f.optionTerm(P),f.optionDescription(P))});if(U.length>0)I=I.concat(["Global Options:",_(U),""])}let Y=f.visibleCommands(E).map((U)=>{return L(f.subcommandTerm(U),f.subcommandDescription(U))});if(Y.length>0)I=I.concat(["Commands:",_(Y),""]);return I.join(`
4
- `)}padWidth(E,f){return Math.max(f.longestOptionTermLength(E,f),f.longestGlobalOptionTermLength(E,f),f.longestSubcommandTermLength(E,f),f.longestArgumentTermLength(E,f))}wrap(E,f,R,$=40){let T=new RegExp(`[\\n][${" \\f\\t\\v   -    \uFEFF"}]+`);if(E.match(T))return E;let L=f-R;if(L<$)return E;let _=E.slice(0,R),I=E.slice(R).replace(`\r
2
+ import{createRequire as hf}from"node:module";var sf=Object.create;var{getPrototypeOf:kf,defineProperty:m,getOwnPropertyNames:Df}=Object;var Ff=Object.prototype.hasOwnProperty;function Af(f){return this[f]}var Vf,bf,xf=(f,r,E)=>{var t=f!=null&&typeof f==="object";if(t){var S=r?Vf??=new WeakMap:bf??=new WeakMap,R=S.get(f);if(R)return R}E=f!=null?sf(kf(f)):{};let w=r||!f||!f.__esModule?m(E,"default",{value:f,enumerable:!0}):E;for(let T of Df(f))if(!Ff.call(w,T))m(w,T,{get:Af.bind(f,T),enumerable:!0});if(t)S.set(f,w);return w};var M=(f,r)=>()=>(r||f((r={exports:{}}).exports,r),r.exports);var N=hf(import.meta.url);var Z=M((Cf)=>{class V extends Error{constructor(f,r,E){super(E);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name,this.code=r,this.exitCode=f,this.nestedError=void 0}}class d extends V{constructor(f){super(1,"commander.invalidArgument",f);Error.captureStackTrace(this,this.constructor),this.name=this.constructor.name}}Cf.CommanderError=V;Cf.InvalidArgumentError=d});var H=M((gf)=>{var{InvalidArgumentError:cf}=Z();class e{constructor(f,r){switch(this.description=r||"",this.variadic=!1,this.parseArg=void 0,this.defaultValue=void 0,this.defaultValueDescription=void 0,this.argChoices=void 0,f[0]){case"<":this.required=!0,this._name=f.slice(1,-1);break;case"[":this.required=!1,this._name=f.slice(1,-1);break;default:this.required=!0,this._name=f;break}if(this._name.length>3&&this._name.slice(-3)==="...")this.variadic=!0,this._name=this._name.slice(0,-3)}name(){return this._name}_concatValue(f,r){if(r===this.defaultValue||!Array.isArray(r))return[f];return r.concat(f)}default(f,r){return this.defaultValue=f,this.defaultValueDescription=r,this}argParser(f){return this.parseArg=f,this}choices(f){return this.argChoices=f.slice(),this.parseArg=(r,E)=>{if(!this.argChoices.includes(r))throw new cf(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(r,E);return r},this}argRequired(){return this.required=!0,this}argOptional(){return this.required=!1,this}}function nf(f){let r=f.name()+(f.variadic===!0?"...":"");return f.required?"<"+r+">":"["+r+"]"}gf.Argument=e;gf.humanReadableArgName=nf});var b=M((df)=>{var{humanReadableArgName:mf}=H();class p{constructor(){this.helpWidth=void 0,this.sortSubcommands=!1,this.sortOptions=!1,this.showGlobalOptions=!1}visibleCommands(f){let r=f.commands.filter((t)=>!t._hidden),E=f._getHelpCommand();if(E&&!E._hidden)r.push(E);if(this.sortSubcommands)r.sort((t,S)=>{return t.name().localeCompare(S.name())});return r}compareOptions(f,r){let E=(t)=>{return t.short?t.short.replace(/^-/,""):t.long.replace(/^--/,"")};return E(f).localeCompare(E(r))}visibleOptions(f){let r=f.options.filter((t)=>!t.hidden),E=f._getHelpOption();if(E&&!E.hidden){let t=E.short&&f._findOption(E.short),S=E.long&&f._findOption(E.long);if(!t&&!S)r.push(E);else if(E.long&&!S)r.push(f.createOption(E.long,E.description));else if(E.short&&!t)r.push(f.createOption(E.short,E.description))}if(this.sortOptions)r.sort(this.compareOptions);return r}visibleGlobalOptions(f){if(!this.showGlobalOptions)return[];let r=[];for(let E=f.parent;E;E=E.parent){let t=E.options.filter((S)=>!S.hidden);r.push(...t)}if(this.sortOptions)r.sort(this.compareOptions);return r}visibleArguments(f){if(f._argsDescription)f.registeredArguments.forEach((r)=>{r.description=r.description||f._argsDescription[r.name()]||""});if(f.registeredArguments.find((r)=>r.description))return f.registeredArguments;return[]}subcommandTerm(f){let r=f.registeredArguments.map((E)=>mf(E)).join(" ");return f._name+(f._aliases[0]?"|"+f._aliases[0]:"")+(f.options.length?" [options]":"")+(r?" "+r:"")}optionTerm(f){return f.flags}argumentTerm(f){return f.name()}longestSubcommandTermLength(f,r){return r.visibleCommands(f).reduce((E,t)=>{return Math.max(E,r.subcommandTerm(t).length)},0)}longestOptionTermLength(f,r){return r.visibleOptions(f).reduce((E,t)=>{return Math.max(E,r.optionTerm(t).length)},0)}longestGlobalOptionTermLength(f,r){return r.visibleGlobalOptions(f).reduce((E,t)=>{return Math.max(E,r.optionTerm(t).length)},0)}longestArgumentTermLength(f,r){return r.visibleArguments(f).reduce((E,t)=>{return Math.max(E,r.argumentTerm(t).length)},0)}commandUsage(f){let r=f._name;if(f._aliases[0])r=r+"|"+f._aliases[0];let E="";for(let t=f.parent;t;t=t.parent)E=t.name()+" "+E;return E+r+" "+f.usage()}commandDescription(f){return f.description()}subcommandDescription(f){return f.summary()||f.description()}optionDescription(f){let r=[];if(f.argChoices)r.push(`choices: ${f.argChoices.map((E)=>JSON.stringify(E)).join(", ")}`);if(f.defaultValue!==void 0){if(f.required||f.optional||f.isBoolean()&&typeof f.defaultValue==="boolean")r.push(`default: ${f.defaultValueDescription||JSON.stringify(f.defaultValue)}`)}if(f.presetArg!==void 0&&f.optional)r.push(`preset: ${JSON.stringify(f.presetArg)}`);if(f.envVar!==void 0)r.push(`env: ${f.envVar}`);if(r.length>0)return`${f.description} (${r.join(", ")})`;return f.description}argumentDescription(f){let r=[];if(f.argChoices)r.push(`choices: ${f.argChoices.map((E)=>JSON.stringify(E)).join(", ")}`);if(f.defaultValue!==void 0)r.push(`default: ${f.defaultValueDescription||JSON.stringify(f.defaultValue)}`);if(r.length>0){let E=`(${r.join(", ")})`;if(f.description)return`${f.description} ${E}`;return E}return f.description}formatHelp(f,r){let E=r.padWidth(f,r),t=r.helpWidth||80,S=2,R=2;function w(I,u){if(u){let A=`${I.padEnd(E+2)}${u}`;return r.wrap(A,t-2,E+2)}return I}function T(I){return I.join(`
3
+ `).replace(/^/gm," ".repeat(2))}let $=[`Usage: ${r.commandUsage(f)}`,""],_=r.commandDescription(f);if(_.length>0)$=$.concat([r.wrap(_,t,0),""]);let y=r.visibleArguments(f).map((I)=>{return w(r.argumentTerm(I),r.argumentDescription(I))});if(y.length>0)$=$.concat(["Arguments:",T(y),""]);let U=r.visibleOptions(f).map((I)=>{return w(r.optionTerm(I),r.optionDescription(I))});if(U.length>0)$=$.concat(["Options:",T(U),""]);if(this.showGlobalOptions){let I=r.visibleGlobalOptions(f).map((u)=>{return w(r.optionTerm(u),r.optionDescription(u))});if(I.length>0)$=$.concat(["Global Options:",T(I),""])}let P=r.visibleCommands(f).map((I)=>{return w(r.subcommandTerm(I),r.subcommandDescription(I))});if(P.length>0)$=$.concat(["Commands:",T(P),""]);return $.join(`
4
+ `)}padWidth(f,r){return Math.max(r.longestOptionTermLength(f,r),r.longestGlobalOptionTermLength(f,r),r.longestSubcommandTermLength(f,r),r.longestArgumentTermLength(f,r))}wrap(f,r,E,t=40){let R=new RegExp(`[\\n][${" \\f\\t\\v   -    \uFEFF"}]+`);if(f.match(R))return f;let w=r-E;if(w<t)return f;let T=f.slice(0,E),$=f.slice(E).replace(`\r
5
5
  `,`
6
- `),w=" ".repeat(R),q=`\\s${"​"}`,Y=new RegExp(`
7
- |.{1,${L-1}}([${q}]|$)|[^${q}]+?([${q}]|$)`,"g"),U=I.match(Y)||[];return _+U.map((P,C)=>{if(P===`
8
- `)return"";return(C>0?w:"")+P.trimEnd()}).join(`
9
- `)}}nE.Help=o});var O=X((pE)=>{var{InvalidArgumentError:lE}=K();class e{constructor(E,f){this.flags=E,this.description=f||"",this.required=E.includes("<"),this.optional=E.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(E),this.mandatory=!1;let R=dE(E);if(this.short=R.shortFlag,this.long=R.longFlag,this.negate=!1,this.long)this.negate=this.long.startsWith("--no-");this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default(E,f){return this.defaultValue=E,this.defaultValueDescription=f,this}preset(E){return this.presetArg=E,this}conflicts(E){return this.conflictsWith=this.conflictsWith.concat(E),this}implies(E){let f=E;if(typeof E==="string")f={[E]:!0};return this.implied=Object.assign(this.implied||{},f),this}env(E){return this.envVar=E,this}argParser(E){return this.parseArg=E,this}makeOptionMandatory(E=!0){return this.mandatory=!!E,this}hideHelp(E=!0){return this.hidden=!!E,this}_concatValue(E,f){if(f===this.defaultValue||!Array.isArray(f))return[E];return f.concat(E)}choices(E){return this.argChoices=E.slice(),this.parseArg=(f,R)=>{if(!this.argChoices.includes(f))throw new lE(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(f,R);return f},this}name(){if(this.long)return this.long.replace(/^--/,"");return this.short.replace(/^-/,"")}attributeName(){return mE(this.name().replace(/^no-/,""))}is(E){return this.short===E||this.long===E}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class a{constructor(E){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,E.forEach((f)=>{if(f.negate)this.negativeOptions.set(f.attributeName(),f);else this.positiveOptions.set(f.attributeName(),f)}),this.negativeOptions.forEach((f,R)=>{if(this.positiveOptions.has(R))this.dualOptions.add(R)})}valueFromOption(E,f){let R=f.attributeName();if(!this.dualOptions.has(R))return!0;let $=this.negativeOptions.get(R).presetArg,S=$!==void 0?$:!1;return f.negate===(S===E)}}function mE(E){return E.split("-").reduce((f,R)=>{return f+R[0].toUpperCase()+R.slice(1)})}function dE(E){let f,R,$=E.split(/[ |,]+/);if($.length>1&&!/^[[<]/.test($[1]))f=$.shift();if(R=$.shift(),!f&&/^-[^-]$/.test(R))f=R,R=void 0;return{shortFlag:f,longFlag:R}}pE.Option=e;pE.DualOptions=a});var EE=X((ff)=>{function aE(E,f){if(Math.abs(E.length-f.length)>3)return Math.max(E.length,f.length);let R=[];for(let $=0;$<=E.length;$++)R[$]=[$];for(let $=0;$<=f.length;$++)R[0][$]=$;for(let $=1;$<=f.length;$++)for(let S=1;S<=E.length;S++){let T=1;if(E[S-1]===f[$-1])T=0;else T=1;if(R[S][$]=Math.min(R[S-1][$]+1,R[S][$-1]+1,R[S-1][$-1]+T),S>1&&$>1&&E[S-1]===f[$-2]&&E[S-2]===f[$-1])R[S][$]=Math.min(R[S][$],R[S-2][$-2]+1)}return R[E.length][f.length]}function Ef(E,f){if(!f||f.length===0)return"";f=Array.from(new Set(f));let R=E.startsWith("--");if(R)E=E.slice(2),f=f.map((L)=>L.slice(2));let $=[],S=3,T=0.4;if(f.forEach((L)=>{if(L.length<=1)return;let _=aE(E,L),I=Math.max(E.length,L.length);if((I-_)/I>T){if(_<S)S=_,$=[L];else if(_===S)$.push(L)}}),$.sort((L,_)=>L.localeCompare(_)),R)$=$.map((L)=>`--${L}`);if($.length>1)return`
10
- (Did you mean one of ${$.join(", ")}?)`;if($.length===1)return`
11
- (Did you mean ${$[0]}?)`;return""}ff.suggestSimilar=Ef});var SE=X((If)=>{var $f=Q("node:events").EventEmitter,v=Q("node:child_process"),M=Q("node:path"),r=Q("node:fs"),J=Q("node:process"),{Argument:Sf,humanReadableArgName:Tf}=N(),{CommanderError:s}=K(),{Help:_f}=h(),{Option:fE,DualOptions:Lf}=O(),{suggestSimilar:RE}=EE();class t extends $f{constructor(E){super();this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=E||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:(f)=>J.stdout.write(f),writeErr:(f)=>J.stderr.write(f),getOutHelpWidth:()=>J.stdout.isTTY?J.stdout.columns:void 0,getErrHelpWidth:()=>J.stderr.isTTY?J.stderr.columns:void 0,outputError:(f,R)=>R(f)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings(E){return this._outputConfiguration=E._outputConfiguration,this._helpOption=E._helpOption,this._helpCommand=E._helpCommand,this._helpConfiguration=E._helpConfiguration,this._exitCallback=E._exitCallback,this._storeOptionsAsProperties=E._storeOptionsAsProperties,this._combineFlagAndOptionalValue=E._combineFlagAndOptionalValue,this._allowExcessArguments=E._allowExcessArguments,this._enablePositionalOptions=E._enablePositionalOptions,this._showHelpAfterError=E._showHelpAfterError,this._showSuggestionAfterError=E._showSuggestionAfterError,this}_getCommandAndAncestors(){let E=[];for(let f=this;f;f=f.parent)E.push(f);return E}command(E,f,R){let $=f,S=R;if(typeof $==="object"&&$!==null)S=$,$=null;S=S||{};let[,T,L]=E.match(/([^ ]+) *(.*)/),_=this.createCommand(T);if($)_.description($),_._executableHandler=!0;if(S.isDefault)this._defaultCommandName=_._name;if(_._hidden=!!(S.noHelp||S.hidden),_._executableFile=S.executableFile||null,L)_.arguments(L);if(this._registerCommand(_),_.parent=this,_.copyInheritedSettings(this),$)return this;return _}createCommand(E){return new t(E)}createHelp(){return Object.assign(new _f,this.configureHelp())}configureHelp(E){if(E===void 0)return this._helpConfiguration;return this._helpConfiguration=E,this}configureOutput(E){if(E===void 0)return this._outputConfiguration;return Object.assign(this._outputConfiguration,E),this}showHelpAfterError(E=!0){if(typeof E!=="string")E=!!E;return this._showHelpAfterError=E,this}showSuggestionAfterError(E=!0){return this._showSuggestionAfterError=!!E,this}addCommand(E,f){if(!E._name)throw Error(`Command passed to .addCommand() must have a name
12
- - specify the name in Command constructor or using .name()`);if(f=f||{},f.isDefault)this._defaultCommandName=E._name;if(f.noHelp||f.hidden)E._hidden=!0;return this._registerCommand(E),E.parent=this,E._checkForBrokenPassThrough(),this}createArgument(E,f){return new Sf(E,f)}argument(E,f,R,$){let S=this.createArgument(E,f);if(typeof R==="function")S.default($).argParser(R);else S.default(R);return this.addArgument(S),this}arguments(E){return E.trim().split(/ +/).forEach((f)=>{this.argument(f)}),this}addArgument(E){let f=this.registeredArguments.slice(-1)[0];if(f&&f.variadic)throw Error(`only the last argument can be variadic '${f.name()}'`);if(E.required&&E.defaultValue!==void 0&&E.parseArg===void 0)throw Error(`a default value for a required argument is never used: '${E.name()}'`);return this.registeredArguments.push(E),this}helpCommand(E,f){if(typeof E==="boolean")return this._addImplicitHelpCommand=E,this;E=E??"help [command]";let[,R,$]=E.match(/([^ ]+) *(.*)/),S=f??"display help for command",T=this.createCommand(R);if(T.helpOption(!1),$)T.arguments($);if(S)T.description(S);return this._addImplicitHelpCommand=!0,this._helpCommand=T,this}addHelpCommand(E,f){if(typeof E!=="object")return this.helpCommand(E,f),this;return this._addImplicitHelpCommand=!0,this._helpCommand=E,this}_getHelpCommand(){if(this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))){if(this._helpCommand===void 0)this.helpCommand(void 0,void 0);return this._helpCommand}return null}hook(E,f){let R=["preSubcommand","preAction","postAction"];if(!R.includes(E))throw Error(`Unexpected value for event passed to hook : '${E}'.
13
- Expecting one of '${R.join("', '")}'`);if(this._lifeCycleHooks[E])this._lifeCycleHooks[E].push(f);else this._lifeCycleHooks[E]=[f];return this}exitOverride(E){if(E)this._exitCallback=E;else this._exitCallback=(f)=>{if(f.code!=="commander.executeSubCommandAsync")throw f};return this}_exit(E,f,R){if(this._exitCallback)this._exitCallback(new s(E,f,R));J.exit(E)}action(E){let f=(R)=>{let $=this.registeredArguments.length,S=R.slice(0,$);if(this._storeOptionsAsProperties)S[$]=this;else S[$]=this.opts();return S.push(this),E.apply(this,S)};return this._actionHandler=f,this}createOption(E,f){return new fE(E,f)}_callParseArg(E,f,R,$){try{return E.parseArg(f,R)}catch(S){if(S.code==="commander.invalidArgument"){let T=`${$} ${S.message}`;this.error(T,{exitCode:S.exitCode,code:S.code})}throw S}}_registerOption(E){let f=E.short&&this._findOption(E.short)||E.long&&this._findOption(E.long);if(f){let R=E.long&&this._findOption(E.long)?E.long:E.short;throw Error(`Cannot add option '${E.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${R}'
14
- - already used by option '${f.flags}'`)}this.options.push(E)}_registerCommand(E){let f=($)=>{return[$.name()].concat($.aliases())},R=f(E).find(($)=>this._findCommand($));if(R){let $=f(this._findCommand(R)).join("|"),S=f(E).join("|");throw Error(`cannot add command '${S}' as already have command '${$}'`)}this.commands.push(E)}addOption(E){this._registerOption(E);let f=E.name(),R=E.attributeName();if(E.negate){let S=E.long.replace(/^--no-/,"--");if(!this._findOption(S))this.setOptionValueWithSource(R,E.defaultValue===void 0?!0:E.defaultValue,"default")}else if(E.defaultValue!==void 0)this.setOptionValueWithSource(R,E.defaultValue,"default");let $=(S,T,L)=>{if(S==null&&E.presetArg!==void 0)S=E.presetArg;let _=this.getOptionValue(R);if(S!==null&&E.parseArg)S=this._callParseArg(E,S,_,T);else if(S!==null&&E.variadic)S=E._concatValue(S,_);if(S==null)if(E.negate)S=!1;else if(E.isBoolean()||E.optional)S=!0;else S="";this.setOptionValueWithSource(R,S,L)};if(this.on("option:"+f,(S)=>{let T=`error: option '${E.flags}' argument '${S}' is invalid.`;$(S,T,"cli")}),E.envVar)this.on("optionEnv:"+f,(S)=>{let T=`error: option '${E.flags}' value '${S}' from env '${E.envVar}' is invalid.`;$(S,T,"env")});return this}_optionEx(E,f,R,$,S){if(typeof f==="object"&&f instanceof fE)throw Error("To add an Option object use addOption() instead of option() or requiredOption()");let T=this.createOption(f,R);if(T.makeOptionMandatory(!!E.mandatory),typeof $==="function")T.default(S).argParser($);else if($ instanceof RegExp){let L=$;$=(_,I)=>{let w=L.exec(_);return w?w[0]:I},T.default(S).argParser($)}else T.default($);return this.addOption(T)}option(E,f,R,$){return this._optionEx({},E,f,R,$)}requiredOption(E,f,R,$){return this._optionEx({mandatory:!0},E,f,R,$)}combineFlagAndOptionalValue(E=!0){return this._combineFlagAndOptionalValue=!!E,this}allowUnknownOption(E=!0){return this._allowUnknownOption=!!E,this}allowExcessArguments(E=!0){return this._allowExcessArguments=!!E,this}enablePositionalOptions(E=!0){return this._enablePositionalOptions=!!E,this}passThroughOptions(E=!0){return this._passThroughOptions=!!E,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(E=!0){if(this.options.length)throw Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!E,this}getOptionValue(E){if(this._storeOptionsAsProperties)return this[E];return this._optionValues[E]}setOptionValue(E,f){return this.setOptionValueWithSource(E,f,void 0)}setOptionValueWithSource(E,f,R){if(this._storeOptionsAsProperties)this[E]=f;else this._optionValues[E]=f;return this._optionValueSources[E]=R,this}getOptionValueSource(E){return this._optionValueSources[E]}getOptionValueSourceWithGlobals(E){let f;return this._getCommandAndAncestors().forEach((R)=>{if(R.getOptionValueSource(E)!==void 0)f=R.getOptionValueSource(E)}),f}_prepareUserArgs(E,f){if(E!==void 0&&!Array.isArray(E))throw Error("first parameter to parse must be array or undefined");if(f=f||{},E===void 0&&f.from===void 0){if(J.versions?.electron)f.from="electron";let $=J.execArgv??[];if($.includes("-e")||$.includes("--eval")||$.includes("-p")||$.includes("--print"))f.from="eval"}if(E===void 0)E=J.argv;this.rawArgs=E.slice();let R;switch(f.from){case void 0:case"node":this._scriptPath=E[1],R=E.slice(2);break;case"electron":if(J.defaultApp)this._scriptPath=E[1],R=E.slice(2);else R=E.slice(1);break;case"user":R=E.slice(0);break;case"eval":R=E.slice(1);break;default:throw Error(`unexpected parse option { from: '${f.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);return this._name=this._name||"program",R}parse(E,f){let R=this._prepareUserArgs(E,f);return this._parseCommand([],R),this}async parseAsync(E,f){let R=this._prepareUserArgs(E,f);return await this._parseCommand([],R),this}_executeSubCommand(E,f){f=f.slice();let R=!1,$=[".js",".ts",".tsx",".mjs",".cjs"];function S(w,y){let q=M.resolve(w,y);if(r.existsSync(q))return q;if($.includes(M.extname(y)))return;let Y=$.find((U)=>r.existsSync(`${q}${U}`));if(Y)return`${q}${Y}`;return}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let T=E._executableFile||`${this._name}-${E._name}`,L=this._executableDir||"";if(this._scriptPath){let w;try{w=r.realpathSync(this._scriptPath)}catch(y){w=this._scriptPath}L=M.resolve(M.dirname(w),L)}if(L){let w=S(L,T);if(!w&&!E._executableFile&&this._scriptPath){let y=M.basename(this._scriptPath,M.extname(this._scriptPath));if(y!==this._name)w=S(L,`${y}-${E._name}`)}T=w||T}R=$.includes(M.extname(T));let _;if(J.platform!=="win32")if(R)f.unshift(T),f=$E(J.execArgv).concat(f),_=v.spawn(J.argv[0],f,{stdio:"inherit"});else _=v.spawn(T,f,{stdio:"inherit"});else f.unshift(T),f=$E(J.execArgv).concat(f),_=v.spawn(J.execPath,f,{stdio:"inherit"});if(!_.killed)["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach((y)=>{J.on(y,()=>{if(_.killed===!1&&_.exitCode===null)_.kill(y)})});let I=this._exitCallback;_.on("close",(w)=>{if(w=w??1,!I)J.exit(w);else I(new s(w,"commander.executeSubCommandAsync","(close)"))}),_.on("error",(w)=>{if(w.code==="ENOENT"){let y=L?`searched for local subcommand relative to directory '${L}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",q=`'${T}' does not exist
15
- - if '${E._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
6
+ `),_=" ".repeat(E),U=`\\s${"​"}`,P=new RegExp(`
7
+ |.{1,${w-1}}([${U}]|$)|[^${U}]+?([${U}]|$)`,"g"),I=$.match(P)||[];return T+I.map((u,A)=>{if(u===`
8
+ `)return"";return(A>0?_:"")+u.trimEnd()}).join(`
9
+ `)}}df.Help=p});var x=M((rr)=>{var{InvalidArgumentError:pf}=Z();class a{constructor(f,r){this.flags=f,this.description=r||"",this.required=f.includes("<"),this.optional=f.includes("["),this.variadic=/\w\.\.\.[>\]]$/.test(f),this.mandatory=!1;let E=fr(f);if(this.short=E.shortFlag,this.long=E.longFlag,this.negate=!1,this.long)this.negate=this.long.startsWith("--no-");this.defaultValue=void 0,this.defaultValueDescription=void 0,this.presetArg=void 0,this.envVar=void 0,this.parseArg=void 0,this.hidden=!1,this.argChoices=void 0,this.conflictsWith=[],this.implied=void 0}default(f,r){return this.defaultValue=f,this.defaultValueDescription=r,this}preset(f){return this.presetArg=f,this}conflicts(f){return this.conflictsWith=this.conflictsWith.concat(f),this}implies(f){let r=f;if(typeof f==="string")r={[f]:!0};return this.implied=Object.assign(this.implied||{},r),this}env(f){return this.envVar=f,this}argParser(f){return this.parseArg=f,this}makeOptionMandatory(f=!0){return this.mandatory=!!f,this}hideHelp(f=!0){return this.hidden=!!f,this}_concatValue(f,r){if(r===this.defaultValue||!Array.isArray(r))return[f];return r.concat(f)}choices(f){return this.argChoices=f.slice(),this.parseArg=(r,E)=>{if(!this.argChoices.includes(r))throw new pf(`Allowed choices are ${this.argChoices.join(", ")}.`);if(this.variadic)return this._concatValue(r,E);return r},this}name(){if(this.long)return this.long.replace(/^--/,"");return this.short.replace(/^-/,"")}attributeName(){return af(this.name().replace(/^no-/,""))}is(f){return this.short===f||this.long===f}isBoolean(){return!this.required&&!this.optional&&!this.negate}}class ff{constructor(f){this.positiveOptions=new Map,this.negativeOptions=new Map,this.dualOptions=new Set,f.forEach((r)=>{if(r.negate)this.negativeOptions.set(r.attributeName(),r);else this.positiveOptions.set(r.attributeName(),r)}),this.negativeOptions.forEach((r,E)=>{if(this.positiveOptions.has(E))this.dualOptions.add(E)})}valueFromOption(f,r){let E=r.attributeName();if(!this.dualOptions.has(E))return!0;let t=this.negativeOptions.get(E).presetArg,S=t!==void 0?t:!1;return r.negate===(S===f)}}function af(f){return f.split("-").reduce((r,E)=>{return r+E[0].toUpperCase()+E.slice(1)})}function fr(f){let r,E,t=f.split(/[ |,]+/);if(t.length>1&&!/^[[<]/.test(t[1]))r=t.shift();if(E=t.shift(),!r&&/^-[^-]$/.test(E))r=E,E=void 0;return{shortFlag:r,longFlag:E}}rr.Option=a;rr.DualOptions=ff});var rf=M((wr)=>{function Sr(f,r){if(Math.abs(f.length-r.length)>3)return Math.max(f.length,r.length);let E=[];for(let t=0;t<=f.length;t++)E[t]=[t];for(let t=0;t<=r.length;t++)E[0][t]=t;for(let t=1;t<=r.length;t++)for(let S=1;S<=f.length;S++){let R=1;if(f[S-1]===r[t-1])R=0;else R=1;if(E[S][t]=Math.min(E[S-1][t]+1,E[S][t-1]+1,E[S-1][t-1]+R),S>1&&t>1&&f[S-1]===r[t-2]&&f[S-2]===r[t-1])E[S][t]=Math.min(E[S][t],E[S-2][t-2]+1)}return E[f.length][r.length]}function Rr(f,r){if(!r||r.length===0)return"";r=Array.from(new Set(r));let E=f.startsWith("--");if(E)f=f.slice(2),r=r.map((w)=>w.slice(2));let t=[],S=3,R=0.4;if(r.forEach((w)=>{if(w.length<=1)return;let T=Sr(f,w),$=Math.max(f.length,w.length);if(($-T)/$>R){if(T<S)S=T,t=[w];else if(T===S)t.push(w)}}),t.sort((w,T)=>w.localeCompare(T)),E)t=t.map((w)=>`--${w}`);if(t.length>1)return`
10
+ (Did you mean one of ${t.join(", ")}?)`;if(t.length===1)return`
11
+ (Did you mean ${t[0]}?)`;return""}wr.suggestSimilar=Rr});var Rf=M((Ur)=>{var $r=N("node:events").EventEmitter,h=N("node:child_process"),q=N("node:path"),C=N("node:fs"),L=N("node:process"),{Argument:_r,humanReadableArgName:yr}=H(),{CommanderError:O}=Z(),{Help:Lr}=b(),{Option:Ef,DualOptions:Ir}=x(),{suggestSimilar:tf}=rf();class v extends $r{constructor(f){super();this.commands=[],this.options=[],this.parent=null,this._allowUnknownOption=!1,this._allowExcessArguments=!0,this.registeredArguments=[],this._args=this.registeredArguments,this.args=[],this.rawArgs=[],this.processedArgs=[],this._scriptPath=null,this._name=f||"",this._optionValues={},this._optionValueSources={},this._storeOptionsAsProperties=!1,this._actionHandler=null,this._executableHandler=!1,this._executableFile=null,this._executableDir=null,this._defaultCommandName=null,this._exitCallback=null,this._aliases=[],this._combineFlagAndOptionalValue=!0,this._description="",this._summary="",this._argsDescription=void 0,this._enablePositionalOptions=!1,this._passThroughOptions=!1,this._lifeCycleHooks={},this._showHelpAfterError=!1,this._showSuggestionAfterError=!0,this._outputConfiguration={writeOut:(r)=>L.stdout.write(r),writeErr:(r)=>L.stderr.write(r),getOutHelpWidth:()=>L.stdout.isTTY?L.stdout.columns:void 0,getErrHelpWidth:()=>L.stderr.isTTY?L.stderr.columns:void 0,outputError:(r,E)=>E(r)},this._hidden=!1,this._helpOption=void 0,this._addImplicitHelpCommand=void 0,this._helpCommand=void 0,this._helpConfiguration={}}copyInheritedSettings(f){return this._outputConfiguration=f._outputConfiguration,this._helpOption=f._helpOption,this._helpCommand=f._helpCommand,this._helpConfiguration=f._helpConfiguration,this._exitCallback=f._exitCallback,this._storeOptionsAsProperties=f._storeOptionsAsProperties,this._combineFlagAndOptionalValue=f._combineFlagAndOptionalValue,this._allowExcessArguments=f._allowExcessArguments,this._enablePositionalOptions=f._enablePositionalOptions,this._showHelpAfterError=f._showHelpAfterError,this._showSuggestionAfterError=f._showSuggestionAfterError,this}_getCommandAndAncestors(){let f=[];for(let r=this;r;r=r.parent)f.push(r);return f}command(f,r,E){let t=r,S=E;if(typeof t==="object"&&t!==null)S=t,t=null;S=S||{};let[,R,w]=f.match(/([^ ]+) *(.*)/),T=this.createCommand(R);if(t)T.description(t),T._executableHandler=!0;if(S.isDefault)this._defaultCommandName=T._name;if(T._hidden=!!(S.noHelp||S.hidden),T._executableFile=S.executableFile||null,w)T.arguments(w);if(this._registerCommand(T),T.parent=this,T.copyInheritedSettings(this),t)return this;return T}createCommand(f){return new v(f)}createHelp(){return Object.assign(new Lr,this.configureHelp())}configureHelp(f){if(f===void 0)return this._helpConfiguration;return this._helpConfiguration=f,this}configureOutput(f){if(f===void 0)return this._outputConfiguration;return Object.assign(this._outputConfiguration,f),this}showHelpAfterError(f=!0){if(typeof f!=="string")f=!!f;return this._showHelpAfterError=f,this}showSuggestionAfterError(f=!0){return this._showSuggestionAfterError=!!f,this}addCommand(f,r){if(!f._name)throw Error(`Command passed to .addCommand() must have a name
12
+ - specify the name in Command constructor or using .name()`);if(r=r||{},r.isDefault)this._defaultCommandName=f._name;if(r.noHelp||r.hidden)f._hidden=!0;return this._registerCommand(f),f.parent=this,f._checkForBrokenPassThrough(),this}createArgument(f,r){return new _r(f,r)}argument(f,r,E,t){let S=this.createArgument(f,r);if(typeof E==="function")S.default(t).argParser(E);else S.default(E);return this.addArgument(S),this}arguments(f){return f.trim().split(/ +/).forEach((r)=>{this.argument(r)}),this}addArgument(f){let r=this.registeredArguments.slice(-1)[0];if(r&&r.variadic)throw Error(`only the last argument can be variadic '${r.name()}'`);if(f.required&&f.defaultValue!==void 0&&f.parseArg===void 0)throw Error(`a default value for a required argument is never used: '${f.name()}'`);return this.registeredArguments.push(f),this}helpCommand(f,r){if(typeof f==="boolean")return this._addImplicitHelpCommand=f,this;f=f??"help [command]";let[,E,t]=f.match(/([^ ]+) *(.*)/),S=r??"display help for command",R=this.createCommand(E);if(R.helpOption(!1),t)R.arguments(t);if(S)R.description(S);return this._addImplicitHelpCommand=!0,this._helpCommand=R,this}addHelpCommand(f,r){if(typeof f!=="object")return this.helpCommand(f,r),this;return this._addImplicitHelpCommand=!0,this._helpCommand=f,this}_getHelpCommand(){if(this._addImplicitHelpCommand??(this.commands.length&&!this._actionHandler&&!this._findCommand("help"))){if(this._helpCommand===void 0)this.helpCommand(void 0,void 0);return this._helpCommand}return null}hook(f,r){let E=["preSubcommand","preAction","postAction"];if(!E.includes(f))throw Error(`Unexpected value for event passed to hook : '${f}'.
13
+ Expecting one of '${E.join("', '")}'`);if(this._lifeCycleHooks[f])this._lifeCycleHooks[f].push(r);else this._lifeCycleHooks[f]=[r];return this}exitOverride(f){if(f)this._exitCallback=f;else this._exitCallback=(r)=>{if(r.code!=="commander.executeSubCommandAsync")throw r};return this}_exit(f,r,E){if(this._exitCallback)this._exitCallback(new O(f,r,E));L.exit(f)}action(f){let r=(E)=>{let t=this.registeredArguments.length,S=E.slice(0,t);if(this._storeOptionsAsProperties)S[t]=this;else S[t]=this.opts();return S.push(this),f.apply(this,S)};return this._actionHandler=r,this}createOption(f,r){return new Ef(f,r)}_callParseArg(f,r,E,t){try{return f.parseArg(r,E)}catch(S){if(S.code==="commander.invalidArgument"){let R=`${t} ${S.message}`;this.error(R,{exitCode:S.exitCode,code:S.code})}throw S}}_registerOption(f){let r=f.short&&this._findOption(f.short)||f.long&&this._findOption(f.long);if(r){let E=f.long&&this._findOption(f.long)?f.long:f.short;throw Error(`Cannot add option '${f.flags}'${this._name&&` to command '${this._name}'`} due to conflicting flag '${E}'
14
+ - already used by option '${r.flags}'`)}this.options.push(f)}_registerCommand(f){let r=(t)=>{return[t.name()].concat(t.aliases())},E=r(f).find((t)=>this._findCommand(t));if(E){let t=r(this._findCommand(E)).join("|"),S=r(f).join("|");throw Error(`cannot add command '${S}' as already have command '${t}'`)}this.commands.push(f)}addOption(f){this._registerOption(f);let r=f.name(),E=f.attributeName();if(f.negate){let S=f.long.replace(/^--no-/,"--");if(!this._findOption(S))this.setOptionValueWithSource(E,f.defaultValue===void 0?!0:f.defaultValue,"default")}else if(f.defaultValue!==void 0)this.setOptionValueWithSource(E,f.defaultValue,"default");let t=(S,R,w)=>{if(S==null&&f.presetArg!==void 0)S=f.presetArg;let T=this.getOptionValue(E);if(S!==null&&f.parseArg)S=this._callParseArg(f,S,T,R);else if(S!==null&&f.variadic)S=f._concatValue(S,T);if(S==null)if(f.negate)S=!1;else if(f.isBoolean()||f.optional)S=!0;else S="";this.setOptionValueWithSource(E,S,w)};if(this.on("option:"+r,(S)=>{let R=`error: option '${f.flags}' argument '${S}' is invalid.`;t(S,R,"cli")}),f.envVar)this.on("optionEnv:"+r,(S)=>{let R=`error: option '${f.flags}' value '${S}' from env '${f.envVar}' is invalid.`;t(S,R,"env")});return this}_optionEx(f,r,E,t,S){if(typeof r==="object"&&r instanceof Ef)throw Error("To add an Option object use addOption() instead of option() or requiredOption()");let R=this.createOption(r,E);if(R.makeOptionMandatory(!!f.mandatory),typeof t==="function")R.default(S).argParser(t);else if(t instanceof RegExp){let w=t;t=(T,$)=>{let _=w.exec(T);return _?_[0]:$},R.default(S).argParser(t)}else R.default(t);return this.addOption(R)}option(f,r,E,t){return this._optionEx({},f,r,E,t)}requiredOption(f,r,E,t){return this._optionEx({mandatory:!0},f,r,E,t)}combineFlagAndOptionalValue(f=!0){return this._combineFlagAndOptionalValue=!!f,this}allowUnknownOption(f=!0){return this._allowUnknownOption=!!f,this}allowExcessArguments(f=!0){return this._allowExcessArguments=!!f,this}enablePositionalOptions(f=!0){return this._enablePositionalOptions=!!f,this}passThroughOptions(f=!0){return this._passThroughOptions=!!f,this._checkForBrokenPassThrough(),this}_checkForBrokenPassThrough(){if(this.parent&&this._passThroughOptions&&!this.parent._enablePositionalOptions)throw Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`)}storeOptionsAsProperties(f=!0){if(this.options.length)throw Error("call .storeOptionsAsProperties() before adding options");if(Object.keys(this._optionValues).length)throw Error("call .storeOptionsAsProperties() before setting option values");return this._storeOptionsAsProperties=!!f,this}getOptionValue(f){if(this._storeOptionsAsProperties)return this[f];return this._optionValues[f]}setOptionValue(f,r){return this.setOptionValueWithSource(f,r,void 0)}setOptionValueWithSource(f,r,E){if(this._storeOptionsAsProperties)this[f]=r;else this._optionValues[f]=r;return this._optionValueSources[f]=E,this}getOptionValueSource(f){return this._optionValueSources[f]}getOptionValueSourceWithGlobals(f){let r;return this._getCommandAndAncestors().forEach((E)=>{if(E.getOptionValueSource(f)!==void 0)r=E.getOptionValueSource(f)}),r}_prepareUserArgs(f,r){if(f!==void 0&&!Array.isArray(f))throw Error("first parameter to parse must be array or undefined");if(r=r||{},f===void 0&&r.from===void 0){if(L.versions?.electron)r.from="electron";let t=L.execArgv??[];if(t.includes("-e")||t.includes("--eval")||t.includes("-p")||t.includes("--print"))r.from="eval"}if(f===void 0)f=L.argv;this.rawArgs=f.slice();let E;switch(r.from){case void 0:case"node":this._scriptPath=f[1],E=f.slice(2);break;case"electron":if(L.defaultApp)this._scriptPath=f[1],E=f.slice(2);else E=f.slice(1);break;case"user":E=f.slice(0);break;case"eval":E=f.slice(1);break;default:throw Error(`unexpected parse option { from: '${r.from}' }`)}if(!this._name&&this._scriptPath)this.nameFromFilename(this._scriptPath);return this._name=this._name||"program",E}parse(f,r){let E=this._prepareUserArgs(f,r);return this._parseCommand([],E),this}async parseAsync(f,r){let E=this._prepareUserArgs(f,r);return await this._parseCommand([],E),this}_executeSubCommand(f,r){r=r.slice();let E=!1,t=[".js",".ts",".tsx",".mjs",".cjs"];function S(_,y){let U=q.resolve(_,y);if(C.existsSync(U))return U;if(t.includes(q.extname(y)))return;let P=t.find((I)=>C.existsSync(`${U}${I}`));if(P)return`${U}${P}`;return}this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let R=f._executableFile||`${this._name}-${f._name}`,w=this._executableDir||"";if(this._scriptPath){let _;try{_=C.realpathSync(this._scriptPath)}catch(y){_=this._scriptPath}w=q.resolve(q.dirname(_),w)}if(w){let _=S(w,R);if(!_&&!f._executableFile&&this._scriptPath){let y=q.basename(this._scriptPath,q.extname(this._scriptPath));if(y!==this._name)_=S(w,`${y}-${f._name}`)}R=_||R}E=t.includes(q.extname(R));let T;if(L.platform!=="win32")if(E)r.unshift(R),r=Sf(L.execArgv).concat(r),T=h.spawn(L.argv[0],r,{stdio:"inherit"});else T=h.spawn(R,r,{stdio:"inherit"});else r.unshift(R),r=Sf(L.execArgv).concat(r),T=h.spawn(L.execPath,r,{stdio:"inherit"});if(!T.killed)["SIGUSR1","SIGUSR2","SIGTERM","SIGINT","SIGHUP"].forEach((y)=>{L.on(y,()=>{if(T.killed===!1&&T.exitCode===null)T.kill(y)})});let $=this._exitCallback;T.on("close",(_)=>{if(_=_??1,!$)L.exit(_);else $(new O(_,"commander.executeSubCommandAsync","(close)"))}),T.on("error",(_)=>{if(_.code==="ENOENT"){let y=w?`searched for local subcommand relative to directory '${w}'`:"no directory for search for local subcommand, use .executableDir() to supply a custom directory",U=`'${R}' does not exist
15
+ - if '${f._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
16
16
  - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
17
- - ${y}`;throw Error(q)}else if(w.code==="EACCES")throw Error(`'${T}' not executable`);if(!I)J.exit(1);else{let y=new s(1,"commander.executeSubCommandAsync","(error)");y.nestedError=w,I(y)}}),this.runningCommand=_}_dispatchSubcommand(E,f,R){let $=this._findCommand(E);if(!$)this.help({error:!0});let S;return S=this._chainOrCallSubCommandHook(S,$,"preSubcommand"),S=this._chainOrCall(S,()=>{if($._executableHandler)this._executeSubCommand($,f.concat(R));else return $._parseCommand(f,R)}),S}_dispatchHelpCommand(E){if(!E)this.help();let f=this._findCommand(E);if(f&&!f._executableHandler)f.help();return this._dispatchSubcommand(E,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){if(this.registeredArguments.forEach((E,f)=>{if(E.required&&this.args[f]==null)this.missingArgument(E.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)return;if(this.args.length>this.registeredArguments.length)this._excessArguments(this.args)}_processArguments(){let E=(R,$,S)=>{let T=$;if($!==null&&R.parseArg){let L=`error: command-argument value '${$}' is invalid for argument '${R.name()}'.`;T=this._callParseArg(R,$,S,L)}return T};this._checkNumberOfArguments();let f=[];this.registeredArguments.forEach((R,$)=>{let S=R.defaultValue;if(R.variadic){if($<this.args.length){if(S=this.args.slice($),R.parseArg)S=S.reduce((T,L)=>{return E(R,L,T)},R.defaultValue)}else if(S===void 0)S=[]}else if($<this.args.length){if(S=this.args[$],R.parseArg)S=E(R,S,R.defaultValue)}f[$]=S}),this.processedArgs=f}_chainOrCall(E,f){if(E&&E.then&&typeof E.then==="function")return E.then(()=>f());return f()}_chainOrCallHooks(E,f){let R=E,$=[];if(this._getCommandAndAncestors().reverse().filter((S)=>S._lifeCycleHooks[f]!==void 0).forEach((S)=>{S._lifeCycleHooks[f].forEach((T)=>{$.push({hookedCommand:S,callback:T})})}),f==="postAction")$.reverse();return $.forEach((S)=>{R=this._chainOrCall(R,()=>{return S.callback(S.hookedCommand,this)})}),R}_chainOrCallSubCommandHook(E,f,R){let $=E;if(this._lifeCycleHooks[R]!==void 0)this._lifeCycleHooks[R].forEach((S)=>{$=this._chainOrCall($,()=>{return S(this,f)})});return $}_parseCommand(E,f){let R=this.parseOptions(f);if(this._parseOptionsEnv(),this._parseOptionsImplied(),E=E.concat(R.operands),f=R.unknown,this.args=E.concat(f),E&&this._findCommand(E[0]))return this._dispatchSubcommand(E[0],E.slice(1),f);if(this._getHelpCommand()&&E[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(E[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(f),this._dispatchSubcommand(this._defaultCommandName,E,f);if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName)this.help({error:!0});this._outputHelpIfRequested(R.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let $=()=>{if(R.unknown.length>0)this.unknownOption(R.unknown[0])},S=`command:${this.name()}`;if(this._actionHandler){$(),this._processArguments();let T;if(T=this._chainOrCallHooks(T,"preAction"),T=this._chainOrCall(T,()=>this._actionHandler(this.processedArgs)),this.parent)T=this._chainOrCall(T,()=>{this.parent.emit(S,E,f)});return T=this._chainOrCallHooks(T,"postAction"),T}if(this.parent&&this.parent.listenerCount(S))$(),this._processArguments(),this.parent.emit(S,E,f);else if(E.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",E,f);if(this.listenerCount("command:*"))this.emit("command:*",E,f);else if(this.commands.length)this.unknownCommand();else $(),this._processArguments()}else if(this.commands.length)$(),this.help({error:!0});else $(),this._processArguments()}_findCommand(E){if(!E)return;return this.commands.find((f)=>f._name===E||f._aliases.includes(E))}_findOption(E){return this.options.find((f)=>f.is(E))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach((E)=>{E.options.forEach((f)=>{if(f.mandatory&&E.getOptionValue(f.attributeName())===void 0)E.missingMandatoryOptionValue(f)})})}_checkForConflictingLocalOptions(){let E=this.options.filter((R)=>{let $=R.attributeName();if(this.getOptionValue($)===void 0)return!1;return this.getOptionValueSource($)!=="default"});E.filter((R)=>R.conflictsWith.length>0).forEach((R)=>{let $=E.find((S)=>R.conflictsWith.includes(S.attributeName()));if($)this._conflictingOption(R,$)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach((E)=>{E._checkForConflictingLocalOptions()})}parseOptions(E){let f=[],R=[],$=f,S=E.slice();function T(_){return _.length>1&&_[0]==="-"}let L=null;while(S.length){let _=S.shift();if(_==="--"){if($===R)$.push(_);$.push(...S);break}if(L&&!T(_)){this.emit(`option:${L.name()}`,_);continue}if(L=null,T(_)){let I=this._findOption(_);if(I){if(I.required){let w=S.shift();if(w===void 0)this.optionMissingArgument(I);this.emit(`option:${I.name()}`,w)}else if(I.optional){let w=null;if(S.length>0&&!T(S[0]))w=S.shift();this.emit(`option:${I.name()}`,w)}else this.emit(`option:${I.name()}`);L=I.variadic?I:null;continue}}if(_.length>2&&_[0]==="-"&&_[1]!=="-"){let I=this._findOption(`-${_[1]}`);if(I){if(I.required||I.optional&&this._combineFlagAndOptionalValue)this.emit(`option:${I.name()}`,_.slice(2));else this.emit(`option:${I.name()}`),S.unshift(`-${_.slice(2)}`);continue}}if(/^--[^=]+=/.test(_)){let I=_.indexOf("="),w=this._findOption(_.slice(0,I));if(w&&(w.required||w.optional)){this.emit(`option:${w.name()}`,_.slice(I+1));continue}}if(T(_))$=R;if((this._enablePositionalOptions||this._passThroughOptions)&&f.length===0&&R.length===0){if(this._findCommand(_)){if(f.push(_),S.length>0)R.push(...S);break}else if(this._getHelpCommand()&&_===this._getHelpCommand().name()){if(f.push(_),S.length>0)f.push(...S);break}else if(this._defaultCommandName){if(R.push(_),S.length>0)R.push(...S);break}}if(this._passThroughOptions){if($.push(_),S.length>0)$.push(...S);break}$.push(_)}return{operands:f,unknown:R}}opts(){if(this._storeOptionsAsProperties){let E={},f=this.options.length;for(let R=0;R<f;R++){let $=this.options[R].attributeName();E[$]=$===this._versionOptionName?this._version:this[$]}return E}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((E,f)=>Object.assign(E,f.opts()),{})}error(E,f){if(this._outputConfiguration.outputError(`${E}
17
+ - ${y}`;throw Error(U)}else if(_.code==="EACCES")throw Error(`'${R}' not executable`);if(!$)L.exit(1);else{let y=new O(1,"commander.executeSubCommandAsync","(error)");y.nestedError=_,$(y)}}),this.runningCommand=T}_dispatchSubcommand(f,r,E){let t=this._findCommand(f);if(!t)this.help({error:!0});let S;return S=this._chainOrCallSubCommandHook(S,t,"preSubcommand"),S=this._chainOrCall(S,()=>{if(t._executableHandler)this._executeSubCommand(t,r.concat(E));else return t._parseCommand(r,E)}),S}_dispatchHelpCommand(f){if(!f)this.help();let r=this._findCommand(f);if(r&&!r._executableHandler)r.help();return this._dispatchSubcommand(f,[],[this._getHelpOption()?.long??this._getHelpOption()?.short??"--help"])}_checkNumberOfArguments(){if(this.registeredArguments.forEach((f,r)=>{if(f.required&&this.args[r]==null)this.missingArgument(f.name())}),this.registeredArguments.length>0&&this.registeredArguments[this.registeredArguments.length-1].variadic)return;if(this.args.length>this.registeredArguments.length)this._excessArguments(this.args)}_processArguments(){let f=(E,t,S)=>{let R=t;if(t!==null&&E.parseArg){let w=`error: command-argument value '${t}' is invalid for argument '${E.name()}'.`;R=this._callParseArg(E,t,S,w)}return R};this._checkNumberOfArguments();let r=[];this.registeredArguments.forEach((E,t)=>{let S=E.defaultValue;if(E.variadic){if(t<this.args.length){if(S=this.args.slice(t),E.parseArg)S=S.reduce((R,w)=>{return f(E,w,R)},E.defaultValue)}else if(S===void 0)S=[]}else if(t<this.args.length){if(S=this.args[t],E.parseArg)S=f(E,S,E.defaultValue)}r[t]=S}),this.processedArgs=r}_chainOrCall(f,r){if(f&&f.then&&typeof f.then==="function")return f.then(()=>r());return r()}_chainOrCallHooks(f,r){let E=f,t=[];if(this._getCommandAndAncestors().reverse().filter((S)=>S._lifeCycleHooks[r]!==void 0).forEach((S)=>{S._lifeCycleHooks[r].forEach((R)=>{t.push({hookedCommand:S,callback:R})})}),r==="postAction")t.reverse();return t.forEach((S)=>{E=this._chainOrCall(E,()=>{return S.callback(S.hookedCommand,this)})}),E}_chainOrCallSubCommandHook(f,r,E){let t=f;if(this._lifeCycleHooks[E]!==void 0)this._lifeCycleHooks[E].forEach((S)=>{t=this._chainOrCall(t,()=>{return S(this,r)})});return t}_parseCommand(f,r){let E=this.parseOptions(r);if(this._parseOptionsEnv(),this._parseOptionsImplied(),f=f.concat(E.operands),r=E.unknown,this.args=f.concat(r),f&&this._findCommand(f[0]))return this._dispatchSubcommand(f[0],f.slice(1),r);if(this._getHelpCommand()&&f[0]===this._getHelpCommand().name())return this._dispatchHelpCommand(f[1]);if(this._defaultCommandName)return this._outputHelpIfRequested(r),this._dispatchSubcommand(this._defaultCommandName,f,r);if(this.commands.length&&this.args.length===0&&!this._actionHandler&&!this._defaultCommandName)this.help({error:!0});this._outputHelpIfRequested(E.unknown),this._checkForMissingMandatoryOptions(),this._checkForConflictingOptions();let t=()=>{if(E.unknown.length>0)this.unknownOption(E.unknown[0])},S=`command:${this.name()}`;if(this._actionHandler){t(),this._processArguments();let R;if(R=this._chainOrCallHooks(R,"preAction"),R=this._chainOrCall(R,()=>this._actionHandler(this.processedArgs)),this.parent)R=this._chainOrCall(R,()=>{this.parent.emit(S,f,r)});return R=this._chainOrCallHooks(R,"postAction"),R}if(this.parent&&this.parent.listenerCount(S))t(),this._processArguments(),this.parent.emit(S,f,r);else if(f.length){if(this._findCommand("*"))return this._dispatchSubcommand("*",f,r);if(this.listenerCount("command:*"))this.emit("command:*",f,r);else if(this.commands.length)this.unknownCommand();else t(),this._processArguments()}else if(this.commands.length)t(),this.help({error:!0});else t(),this._processArguments()}_findCommand(f){if(!f)return;return this.commands.find((r)=>r._name===f||r._aliases.includes(f))}_findOption(f){return this.options.find((r)=>r.is(f))}_checkForMissingMandatoryOptions(){this._getCommandAndAncestors().forEach((f)=>{f.options.forEach((r)=>{if(r.mandatory&&f.getOptionValue(r.attributeName())===void 0)f.missingMandatoryOptionValue(r)})})}_checkForConflictingLocalOptions(){let f=this.options.filter((E)=>{let t=E.attributeName();if(this.getOptionValue(t)===void 0)return!1;return this.getOptionValueSource(t)!=="default"});f.filter((E)=>E.conflictsWith.length>0).forEach((E)=>{let t=f.find((S)=>E.conflictsWith.includes(S.attributeName()));if(t)this._conflictingOption(E,t)})}_checkForConflictingOptions(){this._getCommandAndAncestors().forEach((f)=>{f._checkForConflictingLocalOptions()})}parseOptions(f){let r=[],E=[],t=r,S=f.slice();function R(T){return T.length>1&&T[0]==="-"}let w=null;while(S.length){let T=S.shift();if(T==="--"){if(t===E)t.push(T);t.push(...S);break}if(w&&!R(T)){this.emit(`option:${w.name()}`,T);continue}if(w=null,R(T)){let $=this._findOption(T);if($){if($.required){let _=S.shift();if(_===void 0)this.optionMissingArgument($);this.emit(`option:${$.name()}`,_)}else if($.optional){let _=null;if(S.length>0&&!R(S[0]))_=S.shift();this.emit(`option:${$.name()}`,_)}else this.emit(`option:${$.name()}`);w=$.variadic?$:null;continue}}if(T.length>2&&T[0]==="-"&&T[1]!=="-"){let $=this._findOption(`-${T[1]}`);if($){if($.required||$.optional&&this._combineFlagAndOptionalValue)this.emit(`option:${$.name()}`,T.slice(2));else this.emit(`option:${$.name()}`),S.unshift(`-${T.slice(2)}`);continue}}if(/^--[^=]+=/.test(T)){let $=T.indexOf("="),_=this._findOption(T.slice(0,$));if(_&&(_.required||_.optional)){this.emit(`option:${_.name()}`,T.slice($+1));continue}}if(R(T))t=E;if((this._enablePositionalOptions||this._passThroughOptions)&&r.length===0&&E.length===0){if(this._findCommand(T)){if(r.push(T),S.length>0)E.push(...S);break}else if(this._getHelpCommand()&&T===this._getHelpCommand().name()){if(r.push(T),S.length>0)r.push(...S);break}else if(this._defaultCommandName){if(E.push(T),S.length>0)E.push(...S);break}}if(this._passThroughOptions){if(t.push(T),S.length>0)t.push(...S);break}t.push(T)}return{operands:r,unknown:E}}opts(){if(this._storeOptionsAsProperties){let f={},r=this.options.length;for(let E=0;E<r;E++){let t=this.options[E].attributeName();f[t]=t===this._versionOptionName?this._version:this[t]}return f}return this._optionValues}optsWithGlobals(){return this._getCommandAndAncestors().reduce((f,r)=>Object.assign(f,r.opts()),{})}error(f,r){if(this._outputConfiguration.outputError(`${f}
18
18
  `,this._outputConfiguration.writeErr),typeof this._showHelpAfterError==="string")this._outputConfiguration.writeErr(`${this._showHelpAfterError}
19
19
  `);else if(this._showHelpAfterError)this._outputConfiguration.writeErr(`
20
- `),this.outputHelp({error:!0});let R=f||{},$=R.exitCode||1,S=R.code||"commander.error";this._exit($,S,E)}_parseOptionsEnv(){this.options.forEach((E)=>{if(E.envVar&&E.envVar in J.env){let f=E.attributeName();if(this.getOptionValue(f)===void 0||["default","config","env"].includes(this.getOptionValueSource(f)))if(E.required||E.optional)this.emit(`optionEnv:${E.name()}`,J.env[E.envVar]);else this.emit(`optionEnv:${E.name()}`)}})}_parseOptionsImplied(){let E=new Lf(this.options),f=(R)=>{return this.getOptionValue(R)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(R))};this.options.filter((R)=>R.implied!==void 0&&f(R.attributeName())&&E.valueFromOption(this.getOptionValue(R.attributeName()),R)).forEach((R)=>{Object.keys(R.implied).filter(($)=>!f($)).forEach(($)=>{this.setOptionValueWithSource($,R.implied[$],"implied")})})}missingArgument(E){let f=`error: missing required argument '${E}'`;this.error(f,{code:"commander.missingArgument"})}optionMissingArgument(E){let f=`error: option '${E.flags}' argument missing`;this.error(f,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(E){let f=`error: required option '${E.flags}' not specified`;this.error(f,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(E,f){let R=(T)=>{let L=T.attributeName(),_=this.getOptionValue(L),I=this.options.find((y)=>y.negate&&L===y.attributeName()),w=this.options.find((y)=>!y.negate&&L===y.attributeName());if(I&&(I.presetArg===void 0&&_===!1||I.presetArg!==void 0&&_===I.presetArg))return I;return w||T},$=(T)=>{let L=R(T),_=L.attributeName();if(this.getOptionValueSource(_)==="env")return`environment variable '${L.envVar}'`;return`option '${L.flags}'`},S=`error: ${$(E)} cannot be used with ${$(f)}`;this.error(S,{code:"commander.conflictingOption"})}unknownOption(E){if(this._allowUnknownOption)return;let f="";if(E.startsWith("--")&&this._showSuggestionAfterError){let $=[],S=this;do{let T=S.createHelp().visibleOptions(S).filter((L)=>L.long).map((L)=>L.long);$=$.concat(T),S=S.parent}while(S&&!S._enablePositionalOptions);f=RE(E,$)}let R=`error: unknown option '${E}'${f}`;this.error(R,{code:"commander.unknownOption"})}_excessArguments(E){if(this._allowExcessArguments)return;let f=this.registeredArguments.length,R=f===1?"":"s",S=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${f} argument${R} but got ${E.length}.`;this.error(S,{code:"commander.excessArguments"})}unknownCommand(){let E=this.args[0],f="";if(this._showSuggestionAfterError){let $=[];this.createHelp().visibleCommands(this).forEach((S)=>{if($.push(S.name()),S.alias())$.push(S.alias())}),f=RE(E,$)}let R=`error: unknown command '${E}'${f}`;this.error(R,{code:"commander.unknownCommand"})}version(E,f,R){if(E===void 0)return this._version;this._version=E,f=f||"-V, --version",R=R||"output the version number";let $=this.createOption(f,R);return this._versionOptionName=$.attributeName(),this._registerOption($),this.on("option:"+$.name(),()=>{this._outputConfiguration.writeOut(`${E}
21
- `),this._exit(0,"commander.version",E)}),this}description(E,f){if(E===void 0&&f===void 0)return this._description;if(this._description=E,f)this._argsDescription=f;return this}summary(E){if(E===void 0)return this._summary;return this._summary=E,this}alias(E){if(E===void 0)return this._aliases[0];let f=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)f=this.commands[this.commands.length-1];if(E===f._name)throw Error("Command alias can't be the same as its name");let R=this.parent?._findCommand(E);if(R){let $=[R.name()].concat(R.aliases()).join("|");throw Error(`cannot add alias '${E}' to command '${this.name()}' as already have command '${$}'`)}return f._aliases.push(E),this}aliases(E){if(E===void 0)return this._aliases;return E.forEach((f)=>this.alias(f)),this}usage(E){if(E===void 0){if(this._usage)return this._usage;let f=this.registeredArguments.map((R)=>{return Tf(R)});return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?f:[]).join(" ")}return this._usage=E,this}name(E){if(E===void 0)return this._name;return this._name=E,this}nameFromFilename(E){return this._name=M.basename(E,M.extname(E)),this}executableDir(E){if(E===void 0)return this._executableDir;return this._executableDir=E,this}helpInformation(E){let f=this.createHelp();if(f.helpWidth===void 0)f.helpWidth=E&&E.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return f.formatHelp(this,f)}_getHelpContext(E){E=E||{};let f={error:!!E.error},R;if(f.error)R=($)=>this._outputConfiguration.writeErr($);else R=($)=>this._outputConfiguration.writeOut($);return f.write=E.write||R,f.command=this,f}outputHelp(E){let f;if(typeof E==="function")f=E,E=void 0;let R=this._getHelpContext(E);this._getCommandAndAncestors().reverse().forEach((S)=>S.emit("beforeAllHelp",R)),this.emit("beforeHelp",R);let $=this.helpInformation(R);if(f){if($=f($),typeof $!=="string"&&!Buffer.isBuffer($))throw Error("outputHelp callback must return a string or a Buffer")}if(R.write($),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",R),this._getCommandAndAncestors().forEach((S)=>S.emit("afterAllHelp",R))}helpOption(E,f){if(typeof E==="boolean"){if(E)this._helpOption=this._helpOption??void 0;else this._helpOption=null;return this}return E=E??"-h, --help",f=f??"display help for command",this._helpOption=this.createOption(E,f),this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption(E){return this._helpOption=E,this}help(E){this.outputHelp(E);let f=J.exitCode||0;if(f===0&&E&&typeof E!=="function"&&E.error)f=1;this._exit(f,"commander.help","(outputHelp)")}addHelpText(E,f){let R=["beforeAll","before","after","afterAll"];if(!R.includes(E))throw Error(`Unexpected value for position to addHelpText.
22
- Expecting one of '${R.join("', '")}'`);let $=`${E}Help`;return this.on($,(S)=>{let T;if(typeof f==="function")T=f({error:S.error,command:S.command});else T=f;if(T)S.write(`${T}
23
- `)}),this}_outputHelpIfRequested(E){let f=this._getHelpOption();if(f&&E.find(($)=>f.is($)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function $E(E){return E.map((f)=>{if(!f.startsWith("--inspect"))return f;let R,$="127.0.0.1",S="9229",T;if((T=f.match(/^(--inspect(-brk)?)$/))!==null)R=T[1];else if((T=f.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(R=T[1],/^\d+$/.test(T[3]))S=T[3];else $=T[3];else if((T=f.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)R=T[1],$=T[3],S=T[4];if(R&&S!=="0")return`${R}=${$}:${parseInt(S)+1}`;return f})}If.Command=t});var IE=X((Uf)=>{var{Argument:TE}=N(),{Command:c}=SE(),{CommanderError:yf,InvalidArgumentError:_E}=K(),{Help:Jf}=h(),{Option:LE}=O();Uf.program=new c;Uf.createCommand=(E)=>new c(E);Uf.createOption=(E,f)=>new LE(E,f);Uf.createArgument=(E,f)=>new TE(E,f);Uf.Command=c;Uf.Option=LE;Uf.Argument=TE;Uf.Help=Jf;Uf.CommanderError=yf;Uf.InvalidArgumentError=_E;Uf.InvalidOptionArgumentError=_E});var wE=bE(IE(),1),{program:X0,createCommand:z0,createArgument:Z0,createOption:j0,CommanderError:B0,InvalidArgumentError:Q0,InvalidOptionArgumentError:K0,Command:G,Argument:H0,Option:N0,Help:W0}=wE.default;import{readFile as gf}from"node:fs/promises";import{resolve as nf}from"node:path";var yE={name:"@shotstack/cli",version:"0.1.3",description:"Command-line interface for the Shotstack video rendering API.",license:"Apache-2.0",homepage:"https://github.com/shotstack/shotstack-cli",repository:{type:"git",url:"git+https://github.com/shotstack/shotstack-cli.git"},bugs:{url:"https://github.com/shotstack/shotstack-cli/issues"},type:"module",bin:{shotstack:"dist/shotstack.js"},files:["dist/shotstack.js","SKILL.md","references"],scripts:{start:"bun run src/index.ts",build:"bun build src/index.ts --target=node --minify --outfile=dist/shotstack.js --banner='#!/usr/bin/env node' && chmod +x dist/shotstack.js",prepack:"bun run build",typecheck:"tsc --noEmit",test:"bun test"},dependencies:{commander:"^12.1.0"},devDependencies:{"@types/bun":"latest",typescript:"^5.6.0"}};var H=yE.version,JE=`shotstack-cli/${H} (${process.platform}-${process.arch})`;class z extends Error{status;body;constructor(E,f,R){super(R);this.status=E;this.body=f;this.name="ApiError"}get isTransient(){return this.status>=500||this.status===429}}function W(E){let f=E.env.baseUrl.replace(/\/$/,"");async function R($,S,T){let L=await fetch(`${f}${S}`,{method:$,headers:{"x-api-key":E.apiKey,"x-shotstack-origin":"cli","x-shotstack-environment":E.env.name,"user-agent":JE,...T!==void 0?{"content-type":"application/json"}:{}},body:T!==void 0?JSON.stringify(T):void 0}),_=await L.text(),I=_?Hf(_):void 0;if(!L.ok)throw new z(L.status,I??_,`${$} ${S} → ${L.status} ${L.statusText}`);return I}return{post:($,S)=>R("POST",$,S),get:($)=>R("GET",$)}}function Hf(E){try{return JSON.parse(E)}catch{return E}}class Z extends Error{constructor(){super("SHOTSTACK_API_KEY is not set. Get a key at https://shotstack.io.");this.name="MissingApiKeyError"}}function D(){let E=process.env.SHOTSTACK_API_KEY?.trim();if(!E)throw new Z;return E}var UE={dev:"https://api.shotstack.io/edit/dev",stage:"https://api.shotstack.io/edit/stage",v1:"https://api.shotstack.io/edit/v1"},j=Object.keys(UE);class B extends Error{constructor(E){super(`Invalid environment "${E}". Use one of: ${j.join(", ")}.`);this.name="InvalidEnvError"}}function F(E){let f=process.env.SHOTSTACK_API_BASE_URL?.trim();if(f)return{name:"custom",baseUrl:f};let R=E??process.env.SHOTSTACK_ENV?.trim()??"v1";if(!Nf(R))throw new B(R);return{name:R,baseUrl:UE[R]}}function Nf(E){return j.includes(E)}function k(E){if(E==="json")return"json";return"text"}function V(E,f,R){if(E==="json")console.log(JSON.stringify(f));else console.log(R)}import{mkdir as Wf,appendFile as Df,stat as GE,readFile as Ff,writeFile as YE}from"node:fs/promises";import{join as g,dirname as kf}from"node:path";import{homedir as qE}from"node:os";var Vf=1e6,Af=500000,ME=2000;function A(){if(process.platform==="win32"){let E=process.env.APPDATA??g(qE(),"AppData","Roaming");return g(E,"shotstack","log.jsonl")}return g(qE(),".shotstack","log.jsonl")}function xf(E,f=new Date){let R={ts:f.toISOString(),cmd:E.cmd,args:E.args.map(rf),exit:E.exit,durationMs:E.durationMs};if(E.renderId)R.renderId=E.renderId;if(E.response!==void 0)R.response=tf(n(E.response));if(E.error)R.error=bf(E.error);return R}function bf(E){return{name:E.name,message:typeof E.message==="string"?i(E.message):String(E.message)}}function Cf(E){if(E instanceof Error)return{name:E.name,message:E.message};if(E===void 0||E===null)return;return{name:"Unknown",message:String(E)}}async function PE(E,f=A()){let R=xf(E),$=JSON.stringify(R)+`
24
- `;if(await Wf(kf(f),{recursive:!0,mode:448}),!await uf(f))await YE(f,"",{mode:384});await Df(f,$),await hf(f)}async function uf(E){try{return await GE(E),!0}catch{return!1}}async function hf(E){let f=await GE(E).catch(()=>null);if(!f||f.size<=Vf)return;let R=await Ff(E),$=R.subarray(Math.max(0,R.length-Af)),S=$.indexOf(10),T=S>=0?$.subarray(S+1):$;await YE(E,T,{mode:384})}var Of=/^https?:\/\//i,vf=/(https?:\/\/[^\s'"<>]+?)\?[^\s'"<>]*?(?:Signature|X-Amz-[A-Za-z0-9-]*)=[^\s'"<>]*/gi;function i(E){return E.replace(vf,"$1?[redacted-signed]")}function rf(E){if(typeof E!=="string")return E;if(E.startsWith("-"))return E;if(Of.test(E))return i(E);if(/[\/\\]/.test(E))return sf(E);return E}function sf(E){let f=E.split(/[\/\\]/);return f[f.length-1]||E}function n(E){if(typeof E==="string")return i(E);if(Array.isArray(E))return E.map(n);if(E&&typeof E==="object"){let f={};for(let[R,$]of Object.entries(E))f[R]=n($);return f}return E}function tf(E){let f=JSON.stringify(E);if(f===void 0||f.length<=ME)return E;return f.slice(0,ME)+"...[truncated]"}async function x(E,f,R){let $=Date.now();try{let S=await R(),T=S.exitCode??0;if(await PE({cmd:E,args:f,exit:T,durationMs:Date.now()-$,renderId:S.renderId,response:S.response}).catch(()=>{}),T!==0)process.exit(T)}catch(S){let T=cf(S),L=S instanceof z?S.body:void 0;throw await PE({cmd:E,args:f,exit:T,durationMs:Date.now()-$,response:L,error:Cf(S)}).catch(()=>{}),S}}function cf(E){if(E instanceof z)return E.isTransient?2:1;if(E instanceof Z||E instanceof B)return 1;if(E instanceof Error&&E.code==="ENOENT")return 1;return 2}function b(E){let f=process.argv.slice(2),R=f.indexOf(E);return R>=0?f.slice(R+1):f}var XE=new G("render").description("Submit a Shotstack timeline JSON to the render API").argument("<file>","Path to a Shotstack timeline JSON file").option("--env <name>",`Environment: ${j.join(" | ")}`).option("--output <format>","Output format: text | json","text").action(async(E,f)=>{await x("render",b("render"),async()=>{let R=k(f.output),$=D(),S=F(f.env),T=nf(process.cwd(),E),L=await gf(T,"utf8"),_=JSON.parse(L),w=await W({apiKey:$,env:S}).post("/render",_),y=w.response.id;return V(R,{id:y},y),{renderId:y,response:w.response}})});var lf=new Set(["done","failed"]),mf=3000,zE=new G("status").description("Poll the status of a Shotstack render").argument("<id>","Render ID returned by `shotstack render`").option("--watch","Poll continuously until the render reaches a terminal state").option("--env <name>",`Environment: ${j.join(" | ")}`).option("--output <format>","Output format: text | json","text").action(async(E,f)=>{await x("status",b("status"),async()=>{let R=k(f.output),$=D(),S=F(f.env),T=W({apiKey:$,env:S});while(!0){let _=(await T.get(`/render/${encodeURIComponent(E)}`)).response;if(V(R,_,df(_)),!f.watch||lf.has(_.status)){let I=_.status==="failed"?1:0;return{renderId:_.id,response:_,exitCode:I}}await pf(mf)}})});function df(E){let f=[E.status];if(E.url)f.push(E.url);if(E.error)f.push(`error: ${E.error}`);return f.join(" ")}function pf(E){return new Promise((f)=>setTimeout(f,E))}import{readFile as of,writeFile as ef,mkdtemp as af}from"node:fs/promises";import{tmpdir as E0}from"node:os";import{join as ZE}from"node:path";import{spawn as f0}from"node:child_process";var jE="https://github.com/shotstack/shotstack-cli/issues/new?template=bug.yml",R0=6000,HE=5,NE=new G("feedback").description("Open a pre-filled GitHub issue with a flight-recorder dossier from your last 5 invocations").action(async()=>{let E=await $0(HE),f=S0(E),R=_0(E),$=`&title=${encodeURIComponent(R)}`,S=`${jE}${$}&body=${encodeURIComponent(f)}`;if(S.length<=R0){KE(S),console.log("Opened browser with pre-filled issue. Review before submitting.");return}let T=await af(ZE(E0(),"shotstack-feedback-")),L=ZE(T,"dossier.md");await ef(L,f),KE(`${jE}${$}`),console.log(`Dossier too large to inline. Saved to: ${L}`),console.log("Drag the file into the issue body, or paste its contents.")});async function $0(E){let f=A(),R;try{R=await of(f,"utf8")}catch{return[]}let S=R.split(`
25
- `).filter((L)=>L.trim().length>0).slice(-E).reverse(),T=[];for(let L of S)try{T.push(JSON.parse(L))}catch{}return T}function S0(E){let f=[];if(f.push("## Environment"),f.push(`- Shotstack CLI: ${H}`),f.push(`- OS: ${process.platform}-${process.arch}`),f.push(""),f.push(`## Last ${HE} invocations (most recent first)`),f.push(""),E.length===0)f.push("_No recorded invocations._");else for(let R of E){let $=(R.args??[]).join(" "),S=`### ${R.ts} — shotstack ${R.cmd}${$?" "+$:""}`;if(f.push(S),f.push(`- Exit: ${R.exit} Duration: ${R.durationMs}ms`),R.renderId)f.push(`- Render ID: ${R.renderId}`);if(R.response!==void 0){let T=typeof R.response==="string"?R.response:JSON.stringify(R.response);f.push(`- Response: ${T}`)}if(R.error)f.push(`- Error: ${R.error.name}: ${R.error.message}`);f.push("")}return f.push(`[full log at ${A()}]`),f.push(""),f.push("## What I expected vs what happened"),f.push("<!-- Describe the issue, request, or question here. -->"),f.join(`
26
- `)}var BE=80,T0="Feedback from shotstack CLI";function _0(E){let f=E.find((S)=>S.error);if(f&&f.error)return l(`${f.cmd}: ${f.error.name} — ${f.error.message}`);let R=E.find((S)=>QE(S.response)!==null);if(R){let S=QE(R.response);return l(`Render failed: ${S}`)}let $=E.find((S)=>S.exit!==0);if($)return l(`${$.cmd} exited ${$.exit}`);return T0}function QE(E){if(!E||typeof E!=="object"||Array.isArray(E))return null;let f=E;if(f.state!=="failed")return null;return typeof f.error==="string"&&f.error.length>0?f.error:"unknown error"}function l(E){return E.length<=BE?E:E.slice(0,BE-1)+"…"}function KE(E){let f=process.platform==="win32",R=process.platform==="darwin"?"open":f?"cmd":"xdg-open",S=f0(R,f?["/c","start","",E]:[E],{stdio:"ignore",detached:!0});S.on("error",()=>{console.error(`Could not open browser. Visit: ${E}`)}),S.unref()}var L0=new G().name("shotstack").description("Command-line interface for the Shotstack video rendering API").version(H).addCommand(XE).addCommand(zE).addCommand(NE);try{await L0.parseAsync(process.argv)}catch(E){process.exit(I0(E))}function I0(E){if(E instanceof Z||E instanceof B)return console.error(E.message),1;if(E instanceof z){if(console.error(E.message),E.body)console.error(typeof E.body==="string"?E.body:JSON.stringify(E.body));return E.isTransient?2:1}if(E instanceof Error){if("code"in E&&E.code==="ENOENT")return console.error(E.message),1;return console.error(E.message),2}return console.error(String(E)),2}
20
+ `),this.outputHelp({error:!0});let E=r||{},t=E.exitCode||1,S=E.code||"commander.error";this._exit(t,S,f)}_parseOptionsEnv(){this.options.forEach((f)=>{if(f.envVar&&f.envVar in L.env){let r=f.attributeName();if(this.getOptionValue(r)===void 0||["default","config","env"].includes(this.getOptionValueSource(r)))if(f.required||f.optional)this.emit(`optionEnv:${f.name()}`,L.env[f.envVar]);else this.emit(`optionEnv:${f.name()}`)}})}_parseOptionsImplied(){let f=new Ir(this.options),r=(E)=>{return this.getOptionValue(E)!==void 0&&!["default","implied"].includes(this.getOptionValueSource(E))};this.options.filter((E)=>E.implied!==void 0&&r(E.attributeName())&&f.valueFromOption(this.getOptionValue(E.attributeName()),E)).forEach((E)=>{Object.keys(E.implied).filter((t)=>!r(t)).forEach((t)=>{this.setOptionValueWithSource(t,E.implied[t],"implied")})})}missingArgument(f){let r=`error: missing required argument '${f}'`;this.error(r,{code:"commander.missingArgument"})}optionMissingArgument(f){let r=`error: option '${f.flags}' argument missing`;this.error(r,{code:"commander.optionMissingArgument"})}missingMandatoryOptionValue(f){let r=`error: required option '${f.flags}' not specified`;this.error(r,{code:"commander.missingMandatoryOptionValue"})}_conflictingOption(f,r){let E=(R)=>{let w=R.attributeName(),T=this.getOptionValue(w),$=this.options.find((y)=>y.negate&&w===y.attributeName()),_=this.options.find((y)=>!y.negate&&w===y.attributeName());if($&&($.presetArg===void 0&&T===!1||$.presetArg!==void 0&&T===$.presetArg))return $;return _||R},t=(R)=>{let w=E(R),T=w.attributeName();if(this.getOptionValueSource(T)==="env")return`environment variable '${w.envVar}'`;return`option '${w.flags}'`},S=`error: ${t(f)} cannot be used with ${t(r)}`;this.error(S,{code:"commander.conflictingOption"})}unknownOption(f){if(this._allowUnknownOption)return;let r="";if(f.startsWith("--")&&this._showSuggestionAfterError){let t=[],S=this;do{let R=S.createHelp().visibleOptions(S).filter((w)=>w.long).map((w)=>w.long);t=t.concat(R),S=S.parent}while(S&&!S._enablePositionalOptions);r=tf(f,t)}let E=`error: unknown option '${f}'${r}`;this.error(E,{code:"commander.unknownOption"})}_excessArguments(f){if(this._allowExcessArguments)return;let r=this.registeredArguments.length,E=r===1?"":"s",S=`error: too many arguments${this.parent?` for '${this.name()}'`:""}. Expected ${r} argument${E} but got ${f.length}.`;this.error(S,{code:"commander.excessArguments"})}unknownCommand(){let f=this.args[0],r="";if(this._showSuggestionAfterError){let t=[];this.createHelp().visibleCommands(this).forEach((S)=>{if(t.push(S.name()),S.alias())t.push(S.alias())}),r=tf(f,t)}let E=`error: unknown command '${f}'${r}`;this.error(E,{code:"commander.unknownCommand"})}version(f,r,E){if(f===void 0)return this._version;this._version=f,r=r||"-V, --version",E=E||"output the version number";let t=this.createOption(r,E);return this._versionOptionName=t.attributeName(),this._registerOption(t),this.on("option:"+t.name(),()=>{this._outputConfiguration.writeOut(`${f}
21
+ `),this._exit(0,"commander.version",f)}),this}description(f,r){if(f===void 0&&r===void 0)return this._description;if(this._description=f,r)this._argsDescription=r;return this}summary(f){if(f===void 0)return this._summary;return this._summary=f,this}alias(f){if(f===void 0)return this._aliases[0];let r=this;if(this.commands.length!==0&&this.commands[this.commands.length-1]._executableHandler)r=this.commands[this.commands.length-1];if(f===r._name)throw Error("Command alias can't be the same as its name");let E=this.parent?._findCommand(f);if(E){let t=[E.name()].concat(E.aliases()).join("|");throw Error(`cannot add alias '${f}' to command '${this.name()}' as already have command '${t}'`)}return r._aliases.push(f),this}aliases(f){if(f===void 0)return this._aliases;return f.forEach((r)=>this.alias(r)),this}usage(f){if(f===void 0){if(this._usage)return this._usage;let r=this.registeredArguments.map((E)=>{return yr(E)});return[].concat(this.options.length||this._helpOption!==null?"[options]":[],this.commands.length?"[command]":[],this.registeredArguments.length?r:[]).join(" ")}return this._usage=f,this}name(f){if(f===void 0)return this._name;return this._name=f,this}nameFromFilename(f){return this._name=q.basename(f,q.extname(f)),this}executableDir(f){if(f===void 0)return this._executableDir;return this._executableDir=f,this}helpInformation(f){let r=this.createHelp();if(r.helpWidth===void 0)r.helpWidth=f&&f.error?this._outputConfiguration.getErrHelpWidth():this._outputConfiguration.getOutHelpWidth();return r.formatHelp(this,r)}_getHelpContext(f){f=f||{};let r={error:!!f.error},E;if(r.error)E=(t)=>this._outputConfiguration.writeErr(t);else E=(t)=>this._outputConfiguration.writeOut(t);return r.write=f.write||E,r.command=this,r}outputHelp(f){let r;if(typeof f==="function")r=f,f=void 0;let E=this._getHelpContext(f);this._getCommandAndAncestors().reverse().forEach((S)=>S.emit("beforeAllHelp",E)),this.emit("beforeHelp",E);let t=this.helpInformation(E);if(r){if(t=r(t),typeof t!=="string"&&!Buffer.isBuffer(t))throw Error("outputHelp callback must return a string or a Buffer")}if(E.write(t),this._getHelpOption()?.long)this.emit(this._getHelpOption().long);this.emit("afterHelp",E),this._getCommandAndAncestors().forEach((S)=>S.emit("afterAllHelp",E))}helpOption(f,r){if(typeof f==="boolean"){if(f)this._helpOption=this._helpOption??void 0;else this._helpOption=null;return this}return f=f??"-h, --help",r=r??"display help for command",this._helpOption=this.createOption(f,r),this}_getHelpOption(){if(this._helpOption===void 0)this.helpOption(void 0,void 0);return this._helpOption}addHelpOption(f){return this._helpOption=f,this}help(f){this.outputHelp(f);let r=L.exitCode||0;if(r===0&&f&&typeof f!=="function"&&f.error)r=1;this._exit(r,"commander.help","(outputHelp)")}addHelpText(f,r){let E=["beforeAll","before","after","afterAll"];if(!E.includes(f))throw Error(`Unexpected value for position to addHelpText.
22
+ Expecting one of '${E.join("', '")}'`);let t=`${f}Help`;return this.on(t,(S)=>{let R;if(typeof r==="function")R=r({error:S.error,command:S.command});else R=r;if(R)S.write(`${R}
23
+ `)}),this}_outputHelpIfRequested(f){let r=this._getHelpOption();if(r&&f.find((t)=>r.is(t)))this.outputHelp(),this._exit(0,"commander.helpDisplayed","(outputHelp)")}}function Sf(f){return f.map((r)=>{if(!r.startsWith("--inspect"))return r;let E,t="127.0.0.1",S="9229",R;if((R=r.match(/^(--inspect(-brk)?)$/))!==null)E=R[1];else if((R=r.match(/^(--inspect(-brk|-port)?)=([^:]+)$/))!==null)if(E=R[1],/^\d+$/.test(R[3]))S=R[3];else t=R[3];else if((R=r.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/))!==null)E=R[1],t=R[3],S=R[4];if(E&&S!=="0")return`${E}=${t}:${parseInt(S)+1}`;return r})}Ur.Command=v});var _f=M((ur)=>{var{Argument:wf}=H(),{Command:c}=Rf(),{CommanderError:Pr,InvalidArgumentError:Tf}=Z(),{Help:qr}=b(),{Option:$f}=x();ur.program=new c;ur.createCommand=(f)=>new c(f);ur.createOption=(f,r)=>new $f(f,r);ur.createArgument=(f,r)=>new wf(f,r);ur.Command=c;ur.Option=$f;ur.Argument=wf;ur.Help=qr;ur.CommanderError=Pr;ur.InvalidArgumentError=Tf;ur.InvalidOptionArgumentError=Tf});var yf=xf(_f(),1),{program:bE,createCommand:xE,createArgument:hE,createOption:CE,CommanderError:OE,InvalidArgumentError:vE,InvalidOptionArgumentError:cE,Command:J,Argument:nE,Option:iE,Help:gE}=yf.default;import{readFile as ar}from"node:fs/promises";import{resolve as fE}from"node:path";var Lf={name:"@shotstack/cli",version:"0.3.0",description:"Command-line interface for the Shotstack video rendering API.",license:"Apache-2.0",homepage:"https://github.com/shotstack/shotstack-cli",repository:{type:"git",url:"git+https://github.com/shotstack/shotstack-cli.git"},bugs:{url:"https://github.com/shotstack/shotstack-cli/issues"},type:"module",bin:{shotstack:"dist/shotstack.js"},files:["dist/shotstack.js","SKILL.md","references"],scripts:{start:"bun run src/index.ts",build:"bun build src/index.ts --target=node --minify --outfile=dist/shotstack.js --banner='#!/usr/bin/env node' && chmod +x dist/shotstack.js",prepack:"bun run build",typecheck:"tsc --noEmit",test:"bun test"},dependencies:{commander:"^12.1.0"},devDependencies:{"@types/bun":"latest",typescript:"^5.6.0"}};var Q=Lf.version,If=`shotstack-cli/${Q} (${process.platform}-${process.arch})`;class j extends Error{status;body;constructor(f,r,E){super(E);this.status=f;this.body=r;this.name="ApiError"}get isTransient(){return this.status>=500||this.status===429}}function K(f){let r=f.env.baseUrl.replace(/\/$/,"");async function E(t,S,R){let w=await fetch(`${r}${S}`,{method:t,headers:{"x-api-key":f.apiKey,"x-shotstack-origin":"cli","x-shotstack-environment":f.env.name,"user-agent":If,...R!==void 0?{"content-type":"application/json"}:{}},body:R!==void 0?JSON.stringify(R):void 0}),T=await w.text(),$=T?Wr(T):void 0;if(!w.ok)throw new j(w.status,$??T,`${t} ${S} → ${w.status} ${w.statusText}`);return $}return{post:(t,S)=>E("POST",t,S),get:(t)=>E("GET",t)}}function Wr(f){try{return JSON.parse(f)}catch{return f}}class Y extends Error{constructor(){super("SHOTSTACK_API_KEY is not set. Get a key at https://shotstack.io.");this.name="MissingApiKeyError"}}function W(){let f=process.env.SHOTSTACK_API_KEY?.trim();if(!f)throw new Y;return f}var Uf={dev:"https://api.shotstack.io/edit/dev",stage:"https://api.shotstack.io/edit/stage",v1:"https://api.shotstack.io/edit/v1"},G=Object.keys(Uf);class X extends Error{constructor(f){super(`Invalid environment "${f}". Use one of: ${G.join(", ")}.`);this.name="InvalidEnvError"}}function s(f){let r=process.env.SHOTSTACK_API_BASE_URL?.trim();if(r)return{name:"custom",baseUrl:r};let E=f??process.env.SHOTSTACK_ENV?.trim()??"v1";if(!sr(E))throw new X(E);return{name:E,baseUrl:Uf[E]}}function sr(f){return G.includes(f)}function B(f){if(f==="json")return"json";return"text"}function z(f,r,E){if(f==="json")console.log(JSON.stringify(r));else console.log(E)}import{mkdir as kr,appendFile as Dr,stat as uf,readFile as Fr,writeFile as Mf}from"node:fs/promises";import{join as n,dirname as Ar}from"node:path";import{homedir as Jf}from"node:os";var Vr=1e6,br=500000,Pf=2000;function k(){if(process.platform==="win32"){let f=process.env.APPDATA??n(Jf(),"AppData","Roaming");return n(f,"shotstack","log.jsonl")}return n(Jf(),".shotstack","log.jsonl")}function xr(f,r=new Date){let E={ts:r.toISOString(),cmd:f.cmd,args:f.args.map(ir),exit:f.exit,durationMs:f.durationMs};if(f.renderId)E.renderId=f.renderId;if(f.response!==void 0)E.response=or(i(f.response));if(f.error)E.error=hr(f.error);return E}function hr(f){return{name:f.name,message:typeof f.message==="string"?g(f.message):String(f.message)}}function Cr(f){if(f instanceof Error)return{name:f.name,message:f.message};if(f===void 0||f===null)return;return{name:"Unknown",message:String(f)}}async function qf(f,r=k()){let E=xr(f),t=JSON.stringify(E)+`
24
+ `;if(await kr(Ar(r),{recursive:!0,mode:448}),!await Or(r))await Mf(r,"",{mode:384});await Dr(r,t),await vr(r)}async function Or(f){try{return await uf(f),!0}catch{return!1}}async function vr(f){let r=await uf(f).catch(()=>null);if(!r||r.size<=Vr)return;let E=await Fr(f),t=E.subarray(Math.max(0,E.length-br)),S=t.indexOf(10),R=S>=0?t.subarray(S+1):t;await Mf(f,R,{mode:384})}var cr=/^https?:\/\//i,nr=/(https?:\/\/[^\s'"<>]+?)\?[^\s'"<>]*?(?:Signature|X-Amz-[A-Za-z0-9-]*)=[^\s'"<>]*/gi;function g(f){return f.replace(nr,"$1?[redacted-signed]")}function ir(f){if(typeof f!=="string")return f;if(f.startsWith("-"))return f;if(cr.test(f))return g(f);if(/[\/\\]/.test(f))return gr(f);return f}function gr(f){let r=f.split(/[\/\\]/);return r[r.length-1]||f}function i(f){if(typeof f==="string")return g(f);if(Array.isArray(f))return f.map(i);if(f&&typeof f==="object"){let r={};for(let[E,t]of Object.entries(f))r[E]=i(t);return r}return f}function or(f){let r=JSON.stringify(f);if(r===void 0||r.length<=Pf)return f;return r.slice(0,Pf)+"...[truncated]"}async function D(f,r,E){let t=Date.now();try{let S=await E(),R=S.exitCode??0;if(await qf({cmd:f,args:r,exit:R,durationMs:Date.now()-t,renderId:S.renderId,response:S.response}).catch(()=>{}),R!==0)process.exit(R)}catch(S){let R=lr(S),w=S instanceof j?S.body:void 0;throw await qf({cmd:f,args:r,exit:R,durationMs:Date.now()-t,response:w,error:Cr(S)}).catch(()=>{}),S}}function lr(f){if(f instanceof j)return f.isTransient?2:1;if(f instanceof Y||f instanceof X)return 1;if(f instanceof Error&&f.code==="ENOENT")return 1;return 2}function F(f){let r=process.argv.slice(2),E=r.indexOf(f);return E>=0?r.slice(E+1):r}var mr=new Set(["done","failed"]),dr=3000,jf=new J("status").description("Poll the status of a Shotstack render").argument("<id>","Render ID returned by `shotstack render`").option("--watch","Poll continuously until the render reaches a terminal state").option("--env <name>",`Environment: ${G.join(" | ")}`).option("--output <format>","Output format: text | json","text").action(async(f,r)=>{await D("status",F("status"),async()=>{let E=B(r.output),t=W(),S=s(r.env),R=K({apiKey:t,env:S}),w=await o(R,f,E,r.watch===!0),T=w.status==="failed"?1:0;return{renderId:w.id,response:w,exitCode:T}})});async function o(f,r,E,t){while(!0){let R=(await f.get(`/render/${encodeURIComponent(r)}`)).response;if(z(E,R,er(R)),!t||mr.has(R.status))return R;await pr(dr)}}function er(f){let r=[f.status];if(f.url)r.push(f.url);if(f.error)r.push(`error: ${f.error}`);return r.join(" ")}function pr(f){return new Promise((r)=>setTimeout(r,f))}var Yf=new J("render").description("Submit a Shotstack Edit JSON to the render API").argument("<file>","Path to a Shotstack Edit JSON file").option("--env <name>",`Environment: ${G.join(" | ")}`).option("--watch","After submitting, poll until the render reaches a terminal state").option("--output <format>","Output format: text | json","text").action(async(f,r)=>{await D("render",F("render"),async()=>{let E=B(r.output),t=W(),S=s(r.env),R=fE(process.cwd(),f),w=await ar(R,"utf8"),T=JSON.parse(w),$=K({apiKey:t,env:S}),_=await $.post("/render",T),y=_.response.id;if(!r.watch)return z(E,{id:y},y),{renderId:y,response:_.response};let U=await o($,y,E,!0),P=U.status==="failed"?1:0;return{renderId:y,response:U,exitCode:P}})});import{readFile as rE,writeFile as EE,mkdtemp as tE}from"node:fs/promises";import{tmpdir as SE}from"node:os";import{join as Gf}from"node:path";import{spawn as RE}from"node:child_process";var Xf="https://github.com/shotstack/shotstack-cli/issues/new?template=bug.yml",wE=6000,Zf=5,Qf=new J("feedback").description("Open a pre-filled GitHub issue with a flight-recorder dossier from your last 5 invocations").action(async()=>{let f=await TE(Zf),r=$E(f),E=yE(f),t=`&title=${encodeURIComponent(E)}`,S=`${Xf}${t}&body=${encodeURIComponent(r)}`;if(S.length<=wE){Nf(S),console.log("Opened browser with pre-filled issue. Review before submitting.");return}let R=await tE(Gf(SE(),"shotstack-feedback-")),w=Gf(R,"dossier.md");await EE(w,r),Nf(`${Xf}${t}`),console.log(`Dossier too large to inline. Saved to: ${w}`),console.log("Drag the file into the issue body, or paste its contents.")});async function TE(f){let r=k(),E;try{E=await rE(r,"utf8")}catch{return[]}let S=E.split(`
25
+ `).filter((w)=>w.trim().length>0).slice(-f).reverse(),R=[];for(let w of S)try{R.push(JSON.parse(w))}catch{}return R}function $E(f){let r=[];if(r.push("## Environment"),r.push(`- Shotstack CLI: ${Q}`),r.push(`- OS: ${process.platform}-${process.arch}`),r.push(""),r.push(`## Last ${Zf} invocations (most recent first)`),r.push(""),f.length===0)r.push("_No recorded invocations._");else for(let E of f){let t=(E.args??[]).join(" "),S=`### ${E.ts} — shotstack ${E.cmd}${t?" "+t:""}`;if(r.push(S),r.push(`- Exit: ${E.exit} Duration: ${E.durationMs}ms`),E.renderId)r.push(`- Render ID: ${E.renderId}`);if(E.response!==void 0){let R=typeof E.response==="string"?E.response:JSON.stringify(E.response);r.push(`- Response: ${R}`)}if(E.error)r.push(`- Error: ${E.error.name}: ${E.error.message}`);r.push("")}return r.push(`[full log at ${k()}]`),r.push(""),r.push("## What I expected vs what happened"),r.push("<!-- Describe the issue, request, or question here. -->"),r.join(`
26
+ `)}var Bf=80,_E="Feedback from shotstack CLI";function yE(f){let r=f.find((S)=>S.error);if(r&&r.error)return l(`${r.cmd}: ${r.error.name} — ${r.error.message}`);let E=f.find((S)=>zf(S.response)!==null);if(E){let S=zf(E.response);return l(`Render failed: ${S}`)}let t=f.find((S)=>S.exit!==0);if(t)return l(`${t.cmd} exited ${t.exit}`);return _E}function zf(f){if(!f||typeof f!=="object"||Array.isArray(f))return null;let r=f;if(r.state!=="failed")return null;return typeof r.error==="string"&&r.error.length>0?r.error:"unknown error"}function l(f){return f.length<=Bf?f:f.slice(0,Bf-1)+"…"}function Nf(f){let r=process.platform==="win32",E=process.platform==="darwin"?"open":r?"cmd":"xdg-open",S=RE(E,r?["/c","start","",f]:[f],{stdio:"ignore",detached:!0});S.on("error",()=>{console.error(`Could not open browser. Visit: ${f}`)}),S.unref()}import{readFile as LE}from"node:fs/promises";import{resolve as IE}from"node:path";import{spawn as Hf,execSync as UE}from"node:child_process";var Kf="https://shotstack.studio",JE=`${Kf}/api/share`,PE=3000,qE=6000,Wf=new J("studio").description("Open the Edit JSON in the shotstack.studio web editor. By default, posts the JSON to the share API and returns a short URL.").argument("<file>","Path to a Shotstack Edit JSON file").option("--copy","Copy the URL to the clipboard").option("--no-open","Do not try to open the URL in a browser").option("--no-shorten","Skip the share API; emit a base64url URL inline").option("--output <format>","Output format: text | json","text").action(async(f,r)=>{let E=B(r.output),t=IE(process.cwd(),f),S=await LE(t,"utf8"),R=JSON.parse(S);YE(R);let{url:w,shortened:T}=await uE(R,{shorten:r.shorten});if(!T&&w.length>qE)console.error(`warning: encoded URL is ${w.length} characters; large templates may exceed browser URL limits.`);if(r.copy)await GE(w);let $=r.open&&NE()&&BE(w);if(E==="json"||!$)z(E,{url:w,shortened:T},w)});async function uE(f,r={}){if(r.shorten!==!1){let t=await jE(f);if(t)return{url:t,shortened:!0};console.error("warning: could not reach the shotstack.studio share API; falling back to inline URL.")}return{url:ME(f),shortened:!1}}function ME(f){let r=Buffer.from(JSON.stringify(f),"utf8").toString("base64url");return`${Kf}/#json=${r}`}async function jE(f){try{let r=await fetch(JE,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(f),signal:AbortSignal.timeout(PE)});if(!r.ok)return null;return(await r.json()).url??null}catch{return null}}function YE(f){if(!f||typeof f!=="object")throw Error("Template must be a JSON object.");if(!("timeline"in f))throw Error("Template missing required field: timeline.");if(!("output"in f))throw Error("Template missing required field: output.")}async function GE(f){let{cmd:r,args:E}=XE();await new Promise((t,S)=>{let R=Hf(r,E,{stdio:["pipe","ignore","ignore"]});R.on("error",S),R.on("exit",(w)=>w===0?t():S(Error(`${r} exited ${w}`))),R.stdin.end(f)})}function XE(){if(process.platform==="darwin")return{cmd:"pbcopy",args:[]};if(process.platform==="win32")return{cmd:"clip",args:[]};return{cmd:"xclip",args:["-selection","clipboard"]}}function BE(f){let{cmd:r,args:E}=zE(f);try{let t=Hf(r,E,{detached:!0,stdio:"ignore"});return t.on("error",()=>{}),t.unref(),!0}catch{return!1}}function zE(f){if(process.platform==="win32")return{cmd:"cmd",args:["/c","start","",f]};if(process.platform==="darwin")return{cmd:"open",args:[f]};return{cmd:"xdg-open",args:[f]}}function NE(){if(process.platform==="darwin"||process.platform==="win32")return!0;if(!process.env.DISPLAY&&!process.env.WAYLAND_DISPLAY)return!1;try{return UE("command -v xdg-open",{stdio:"ignore"}),!0}catch{return!1}}var ZE=new J().name("shotstack").description("Command-line interface for the Shotstack video rendering API").version(Q).addCommand(Yf).addCommand(jf).addCommand(Wf).addCommand(Qf);try{await ZE.parseAsync(process.argv)}catch(f){process.exit(QE(f))}function QE(f){if(f instanceof Y||f instanceof X)return console.error(f.message),1;if(f instanceof j){if(console.error(f.message),f.body)console.error(typeof f.body==="string"?f.body:JSON.stringify(f.body));return f.isTransient?2:1}if(f instanceof Error){if("code"in f&&f.code==="ENOENT")return console.error(f.message),1;return console.error(f.message),2}return console.error(String(f)),2}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shotstack/cli",
3
- "version": "0.1.3",
3
+ "version": "0.3.0",
4
4
  "description": "Command-line interface for the Shotstack video rendering API.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/shotstack/shotstack-cli",
@@ -30,7 +30,7 @@ https://shotstack-assets.s3.amazonaws.com/images/waterfall.jpeg
30
30
 
31
31
  ## Music
32
32
 
33
- Royalty-free tracks from the Unminus library, hosted on Shotstack's CDN. Suitable for `timeline.soundtrack` or as audio assets.
33
+ Royalty-free tracks from the Unminus library, hosted on Shotstack's CDN. Use as `audio` assets on a dedicated track. (`timeline.soundtrack` is deprecated — use `audio` with `length: "end"` instead.)
34
34
 
35
35
  ```
36
36
  https://shotstack-assets.s3.amazonaws.com/music/unminus/white.mp3
@@ -1,7 +1,9 @@
1
- # Rich-caption guide
1
+ # Caption guide
2
2
 
3
3
  Word-level animated captions. The most failure-prone asset type — read this fully before composing one.
4
4
 
5
+ The asset type to use is **`rich-caption`** (Shotstack's name for word-level captions). The deprecated `caption` type still parses but produces inferior output — always use `rich-caption`.
6
+
5
7
  ## Contents
6
8
 
7
9
  - The five named presets (use these verbatim when possible)
@@ -31,7 +33,7 @@ White Montserrat, uppercase, with subtle drop shadow. Slides each word down on a
31
33
  "type": "rich-caption",
32
34
  "src": "alias://audio",
33
35
  "font": { "family": "JTUSjIg1_i6t8kCHKm45xW5rygbi49c", "size": 88, "color": "#ffffff", "opacity": 1, "weight": 700 },
34
- "wordAnimation": { "style": "slide", "direction": "down" },
36
+ "animation": { "style": "slide", "direction": "down" },
35
37
  "border": { "width": 0, "color": "#000000", "opacity": 1, "radius": 18 },
36
38
  "style": { "textTransform": "uppercase" },
37
39
  "padding": { "top": 25, "right": 0, "bottom": 0, "left": 0 },
@@ -58,7 +60,7 @@ Inter, black text on white pill background. Active word greys out. Clean editori
58
60
  "type": "rich-caption",
59
61
  "src": "alias://audio",
60
62
  "font": { "family": "UcCo3FwrK3iLTfvlaQc78lA2", "size": 52, "color": "#000000", "opacity": 1, "weight": 700 },
61
- "wordAnimation": { "style": "fade" },
63
+ "animation": { "style": "fade" },
62
64
  "border": { "width": 0, "color": "#000000", "opacity": 1, "radius": 18 },
63
65
  "style": { "textTransform": "none" },
64
66
  "padding": { "top": 25, "right": 0, "bottom": 15, "left": 0 },
@@ -83,7 +85,7 @@ Luckiest Guy, white with thick black stroke, rotated -7.5°, active word gets a
83
85
  "type": "rich-caption",
84
86
  "src": "alias://audio",
85
87
  "font": { "family": "_gP_1RrxsjcxVyin9l9n_j2RStR3qDpraA", "size": 52, "color": "#ffffff", "opacity": 1, "weight": 700 },
86
- "wordAnimation": { "style": "highlight" },
88
+ "animation": { "style": "highlight" },
87
89
  "border": { "width": 0, "color": "#000000", "opacity": 1, "radius": 18 },
88
90
  "style": { "textTransform": "uppercase" },
89
91
  "padding": { "top": 0, "right": 0, "bottom": 0, "left": 0 },
@@ -112,7 +114,7 @@ Montserrat, white with thin stroke and shadow, active word in soft pink. Romanti
112
114
  "type": "rich-caption",
113
115
  "src": "alias://audio",
114
116
  "font": { "family": "JTUSjIg1_i6t8kCHKm45xW5rygbi49c", "size": 36, "color": "#ffffff", "opacity": 1, "weight": 700 },
115
- "wordAnimation": { "style": "highlight" },
117
+ "animation": { "style": "highlight" },
116
118
  "border": { "width": 0, "color": "#000000", "opacity": 1, "radius": 18 },
117
119
  "style": { "textTransform": "none" },
118
120
  "padding": { "top": 15, "right": 0, "bottom": 0, "left": 0 },
@@ -142,7 +144,7 @@ Bangers, white with very thick black stroke, active word turns blue. High-energy
142
144
  "type": "rich-caption",
143
145
  "src": "alias://audio",
144
146
  "font": { "family": "FeVQS0BTqb0h60ACL5la2bxii28", "size": 84, "color": "#ffffff", "opacity": 1, "weight": 700 },
145
- "wordAnimation": { "style": "pop" },
147
+ "animation": { "style": "pop" },
146
148
  "border": { "width": 0, "color": "#000000", "opacity": 1, "radius": 18 },
147
149
  "style": { "textTransform": "none" },
148
150
  "padding": { "top": 35, "right": 0, "bottom": 0, "left": 0 },
@@ -182,7 +184,7 @@ Rich-caption transcribes audio to produce word-level timing. Three ways to sourc
182
184
  | `src` value | Behaviour |
183
185
  |---|---|
184
186
  | `alias://<name>` | Auto-transcribe a referenced audio/video/text-to-speech clip. Set `alias: "<name>"` on the source clip. **Preferred for sync.** |
185
- | Subtitle file URL | Use existing `.srt`, `.vtt`, `.ttml`, or `.dfxp` file. No auto-transcription. |
187
+ | Subtitle file URL | Use existing `.srt` or `.vtt` file. No auto-transcription. |
186
188
  | Audio/video file URL | Auto-transcribe a standalone media file. Use when there's no source clip on the timeline. |
187
189
 
188
190
  The `alias://` form keeps the captions in sync with the source clip even when you change its `start` or `length`.
@@ -210,7 +212,7 @@ If none of the five presets fits, copy the closest preset and modify. The proper
210
212
  | Group | Properties |
211
213
  |---|---|
212
214
  | `font` | `family`, `size`, `color`, `opacity`, `weight` |
213
- | `wordAnimation` | `style`: `fade`, `slide`, `highlight`, `pop`. `direction` for slide: `up`, `down`, `left`, `right`. |
215
+ | `animation` | `style`: `fade`, `slide`, `highlight`, `pop`. `direction` for slide: `up`, `down`, `left`, `right`. |
214
216
  | `border` | `width`, `color`, `opacity`, `radius` |
215
217
  | `padding` | `top`, `right`, `bottom`, `left` (numbers) |
216
218
  | `stroke` | `width`, `color`, `opacity` (text outline) |
@@ -1,6 +1,6 @@
1
1
  # Fonts guide
2
2
 
3
- The Shotstack render engine ships a small built-in font set; everything else must be loaded as a custom font via `timeline.fonts[]`. Per the [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/rich-text/#custom-fonts), **prefer custom Google Fonts** for predictable rendering and full typographic range.
3
+ The Shotstack render engine ships a small built-in font set; everything else must be loaded as a custom font via `timeline.fonts[]`. Per the [Shotstack docs](https://shotstack.io/docs/guide/architecting-an-application/rich-text.md), **prefer custom Google Fonts** for predictable rendering and full typographic range.
4
4
 
5
5
  ## Contents
6
6
 
package/references/svg.md CHANGED
@@ -57,46 +57,97 @@ Standard fill, stroke, and transform attributes work: `fill`, `fill-opacity`, `s
57
57
 
58
58
  Animated SVGs are not rendered — only the static initial frame is used.
59
59
 
60
- ## Worked example: lower-third bar
60
+ ## Worked example: speech bubble for a testimonial
61
+
62
+ Speech bubbles are an example "rich-text can't do this" case — a rounded body with a tail pointing at the speaker requires a `<path>`. Pair the SVG bubble with a `rich-text` clip for the quote inside it.
61
63
 
62
64
  ```json
63
65
  {
64
66
  "timeline": {
65
67
  "tracks": [
66
68
  {
67
- "clips": [{
68
- "asset": {
69
- "type": "rich-text",
70
- "text": "Jane Smith — CEO",
71
- "font": { "family": "JTUSjIg1_i6t8kCHKm45xW5rygbi49c", "size": 48, "color": "#ffffff" }
72
- },
73
- "start": 0, "length": 5,
74
- "offset": { "x": -0.2, "y": -0.35 }
75
- }]
69
+ "clips": [
70
+ {
71
+ "asset": {
72
+ "type": "rich-text",
73
+ "text": "This changed our workflow completely.",
74
+ "font": {
75
+ "family": "JTUSjIg1_i6t8kCHKm45xW5rygbi49c",
76
+ "size": 44,
77
+ "color": "#0f172a",
78
+ "weight": 600
79
+ },
80
+ "align": {
81
+ "horizontal": "center",
82
+ "vertical": "middle"
83
+ }
84
+ },
85
+ "start": 0.5,
86
+ "length": 4,
87
+ "width": 540,
88
+ "height": 160,
89
+ "offset": {
90
+ "x": 0.235,
91
+ "y": 0.373
92
+ }
93
+ }
94
+ ]
76
95
  },
77
96
  {
78
- "clips": [{
79
- "asset": {
80
- "type": "svg",
81
- "src": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1920 200\" width=\"1920\" height=\"200\"><rect x=\"0\" y=\"0\" width=\"1920\" height=\"200\" fill=\"#000000\" fill-opacity=\"0.7\"/></svg>"
82
- },
83
- "start": 0, "length": 5,
84
- "offset": { "x": 0, "y": -0.35 }
85
- }]
97
+ "clips": [
98
+ {
99
+ "asset": {
100
+ "type": "svg",
101
+ "src": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 600 220\" width=\"600\" height=\"220\"><path d=\"M 40 0 H 560 Q 600 0 600 40 V 140 Q 600 180 560 180 H 200 L 160 220 L 170 180 H 40 Q 0 180 0 140 V 40 Q 0 0 40 0 Z\" fill=\"#ffffff\" stroke=\"#0f172a\" stroke-width=\"4\"/></svg>"
102
+ },
103
+ "start": 0.5,
104
+ "length": 4,
105
+ "width": 600,
106
+ "height": 220,
107
+ "offset": {
108
+ "x": 0.235,
109
+ "y": 0.356
110
+ },
111
+ "transition": {
112
+ "in": "fade",
113
+ "out": "fade"
114
+ }
115
+ }
116
+ ]
86
117
  },
87
118
  {
88
- "clips": [{
89
- "asset": { "type": "video", "src": "https://shotstack-assets.s3.amazonaws.com/footage/beach.mp4" },
90
- "start": 0, "length": 5
91
- }]
119
+ "clips": [
120
+ {
121
+ "asset": {
122
+ "type": "image",
123
+ "src": "https://shotstack-assets.s3.amazonaws.com/images/business-man.jpg"
124
+ },
125
+ "start": 0,
126
+ "length": 5,
127
+ "fit": "crop"
128
+ }
129
+ ]
92
130
  }
93
131
  ]
94
132
  },
95
- "output": { "format": "mp4", "resolution": "1080" }
133
+ "output": {
134
+ "format": "mp4",
135
+ "resolution": "1080"
136
+ }
96
137
  }
97
138
  ```
98
139
 
99
- Track order: text on top, semi-transparent black bar in the middle, video on the bottom.
140
+ Track order: rich-text quote on top, SVG bubble in the middle, talking-head video at the bottom. The `<path>` `d` attribute draws a rounded rectangle (40px corner radius via `Q` curves) with a triangular tail at the bottom pointing toward the speaker. `stroke` gives the bubble an outline; `fill="#ffffff"` makes the body opaque.
141
+
142
+ Position the bubble with `offset` so the tail points at the subject's head. Adjust the path's tail coordinates (`L 160 220 L 170 180`) to point left/right/up depending on where the speaker is in frame.
143
+
144
+ Other patterns SVG is right for:
145
+
146
+ - **Tutorial highlight rings** — `<circle>` with `fill="none"` and a thick `stroke`, positioned over a UI element.
147
+ - **Brand badges** — small geometric lockups using `<rect>`/`<polygon>` plus `transform`.
148
+ - **Decorative dividers** — wavy lines or geometric frames between scenes.
149
+
150
+ If you only need a coloured rectangle behind text, **don't reach for SVG** — `rich-text` already supports `background.color`/`opacity`/`borderRadius`. Reserve SVG for shapes rich-text can't produce.
100
151
 
101
152
  ## When to use SVG vs rich-text
102
153
 
@@ -1,6 +1,6 @@
1
1
  # Timeline conventions
2
2
 
3
- Detailed guide to track layering, the soundtrack vs audio distinction, and `timeline.fonts[]`. Read this when building any non-trivial timeline JSON.
3
+ Detailed guide to track layering, background music (via `audio` assets — `timeline.soundtrack` is deprecated), and `timeline.fonts[]`. Read this when building any non-trivial Edit JSON.
4
4
 
5
5
  ## Contents
6
6
 
@@ -17,7 +17,7 @@ The single most counter-intuitive Shotstack convention.
17
17
 
18
18
  `timeline.tracks` is an array. **The first element is the TOP layer (foreground); the last is the BOTTOM (background).** The order of the JSON array IS the visual stacking order, top-to-bottom.
19
19
 
20
- Per the [official docs](https://shotstack.io/docs/guide/architecting-an-application/guidelines/):
20
+ Per the [official docs](https://shotstack.io/docs/guide/getting-started/core-concepts.md):
21
21
 
22
22
  > Tracks are layered on top of each other in the same order they are added to the array with the top most track layered over the top of those below it.
23
23
 
@@ -72,29 +72,32 @@ If you put the video first and the captions last, the video covers the captions
72
72
  | Title card on video | Title clip in early track, video in later track |
73
73
  | Picture-in-picture | PiP video in early track, main video in later track |
74
74
 
75
- ## Soundtrack vs audio asset
75
+ ## Background music: use `audio`, not `timeline.soundtrack`
76
76
 
77
- There are two ways to add audio. Pick the right one.
78
-
79
- | Use `timeline.soundtrack` when | Use `audio` asset when |
80
- |---|---|
81
- | One background music track for the entire timeline | Sound effects at specific times |
82
- | Loop or fade the music | Voiceover synced to specific clips |
83
- | You don't need to control timing | Multiple audio sources at different times |
77
+ `timeline.soundtrack` is **deprecated**. Always use an `audio` asset on its own track with `length: "end"`. The audio asset path supports keyframes, custom timing, multi-clip mixing, and the full effect set; soundtrack does not.
84
78
 
85
79
  ```json
86
80
  {
87
81
  "timeline": {
88
- "soundtrack": {
89
- "src": "https://shotstack-assets.s3.amazonaws.com/music/unminus/palmtrees.mp3",
90
- "effect": "fadeOut"
91
- },
92
- "tracks": [/* ... */]
82
+ "tracks": [
83
+ /* ...other tracks... */
84
+ {
85
+ "clips": [{
86
+ "asset": {
87
+ "type": "audio",
88
+ "src": "https://shotstack-assets.s3.amazonaws.com/music/unminus/palmtrees.mp3",
89
+ "effect": "fadeOut"
90
+ },
91
+ "start": 0,
92
+ "length": "end"
93
+ }]
94
+ }
95
+ ]
93
96
  }
94
97
  }
95
98
  ```
96
99
 
97
- Soundtrack supported `effect` values: `fadeIn`, `fadeOut`, `fadeInFadeOut`.
100
+ `asset.effect` on audio accepts `fadeIn`, `fadeOut`, or `fadeInFadeOut` (same enum the deprecated soundtrack used).
98
101
 
99
102
  ## `timeline.fonts[]` for custom fonts
100
103
 
@@ -131,7 +134,7 @@ See `references/fonts.md` for the full pattern.
131
134
 
132
135
  ## Common track-layout patterns
133
136
 
134
- **Slideshow:** images in one track, soundtrack for music. One image per clip; use `start: "auto"` to chain them.
137
+ **Slideshow:** images in one track, an `audio` asset on a separate track with `length: "end"` for the background music. One image per clip; use `start: "auto"` to chain them.
135
138
 
136
139
  **Voiceover with captions:** captions in track[0], audio in track[1] (with `alias` for the captions to reference), video/image in track[2].
137
140
 
@@ -13,7 +13,7 @@ Common errors and the fix for each. If your error isn't here, run `shotstack fee
13
13
  - "Invalid asset URL"
14
14
  - "Render failed" with no other detail
15
15
  - Render takes much longer than expected
16
- - Stage credits exhausted
16
+ - Credits exhausted on stage environment
17
17
 
18
18
  ## "Unknown property: alignment" (and similar)
19
19
 
@@ -28,7 +28,7 @@ You used a property name from CSS or HTML instinct — `alignment`, `font.name`,
28
28
  | `duration` | `length` |
29
29
  | `transitions: [...]` (array) | `transition: { in, out }` (object) |
30
30
 
31
- Always check <https://shotstack.io/docs/api/api.bundled.json> (JSON Schema) or <https://shotstack.io/docs/guide/llms-full.txt> before composing timeline JSON. Don't guess from CSS conventions.
31
+ Always check <https://shotstack.io/docs/api/api.edit.json> (OpenAPI Schema) or <https://shotstack.io/docs/guide/llms-full.txt> before composing Edit JSON. Don't guess from CSS conventions.
32
32
 
33
33
  ## "Invalid option: expected one of top|middle|bottom"
34
34
 
@@ -61,7 +61,7 @@ You used a font name that isn't in the built-in list and didn't load it via `tim
61
61
 
62
62
  A `rich-caption` clip without `width`, `height`, and `fit: "none"` defaults to filling the entire output.
63
63
 
64
- **Fix:** use one of the five named presets in `references/rich-caption.md` (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) which include the right dimensions, or set `width`/`height`/`fit: "none"` explicitly on your clip.
64
+ **Fix:** use one of the five named presets in `references/caption.md` (Nico, Kai, Kapow, Lovely Little Lychee, Rizz) which include the right dimensions, or set `width`/`height`/`fit: "none"` explicitly on your clip.
65
65
 
66
66
  ## Timeline renders but layers are wrong
67
67
 
@@ -91,11 +91,11 @@ Renders containing AI-generation assets (`text-to-image`, `image-to-video`) take
91
91
 
92
92
  **Fix:** if you're iterating quickly, render with `output.resolution: "preview"` first (512×288 @ 15fps) to validate the timeline shape before spending credits on full-resolution output.
93
93
 
94
- ## Stage credits exhausted
94
+ ## Credits exhausted on stage environment
95
95
 
96
- The `stage` environment uses test credits. They reset on a regular cadence but can be exhausted if you run many renders.
96
+ The `stage` environment uses no credits, but you do require a positive credit balance to make use of the sandbox.
97
97
 
98
- **Fix:** wait for the reset, or run against `--env v1` (production credits, real money). Check current credit balance at <https://dashboard.shotstack.io>.
98
+ **Fix:** add more credits to your account. Check current credit balance at <https://app.shotstack.io>.
99
99
 
100
100
  ## Filing a useful bug report
101
101