@mediaruntime/cli 0.1.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/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-08-16
4
+
5
+ - Add `run` with local uploads, frozen output aliases, safe waiting, and atomic canonical
6
+ ZIP downloads.
7
+ - Add `jobs list` and `jobs get` with human and URL-redacted JSON output.
8
+ - Add loopback-only `trigger` for correctly signed synthetic completion, failure, and
9
+ rejection webhooks.
10
+ - Publish stable exit codes, credential rules, and the CLI software design contract.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MediaRuntime
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # MediaRuntime CLI
2
+
3
+ Official command-line client for MediaRuntime. It submits media, waits for jobs, downloads
4
+ the canonical ZIP output bundle, inspects account jobs, and sends correctly signed
5
+ synthetic webhooks to a local receiver.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install --global @mediaruntime/cli
11
+ mediaruntime --version
12
+ ```
13
+
14
+ Node.js 20 or newer is required. Authenticated commands read the API key from the
15
+ environment; the hosted API URL is built in.
16
+
17
+ ```bash
18
+ export MEDIARUNTIME_API_KEY="sk_..."
19
+ ```
20
+
21
+ Do not pass credentials as command-line arguments. `--base-url` and
22
+ `MEDIARUNTIME_API_URL` are development/staging overrides, not normal client setup.
23
+
24
+ ## Run a job
25
+
26
+ ```bash
27
+ mediaruntime run ./launch.mp4 --output video.web --wait
28
+
29
+ mediaruntime run ./launch.mp4 \
30
+ --output video.streaming \
31
+ --output audio.transcription \
32
+ --metadata '{"asset_id":"launch-01"}' \
33
+ --idempotency-key 'asset:launch-01:v1' \
34
+ --download ./launch-01.zip
35
+ ```
36
+
37
+ `--download` implies `--wait`. The CLI streams the complete MediaRuntime ZIP bundle to a
38
+ temporary file, validates its advertised size and SHA-256 when available, and publishes
39
+ it atomically. Existing files are preserved unless `--force` is explicit. Signed download
40
+ URLs are never printed.
41
+
42
+ Supported frozen output aliases:
43
+
44
+ - `video.web`
45
+ - `video.streaming`
46
+ - `video.social`
47
+ - `audio.web`
48
+ - `audio.transcription`
49
+ - `image.web`
50
+
51
+ Use `--json` for one compact, URL-redacted machine-readable result. A caller-provided
52
+ `--idempotency-key` remains the durable deduplication mechanism across process restarts;
53
+ the SDK-generated invocation key only protects retries inside one live command.
54
+
55
+ ## Inspect jobs
56
+
57
+ ```bash
58
+ mediaruntime jobs list --limit 20
59
+ mediaruntime jobs list --status COMPLETED --json
60
+ mediaruntime jobs get job_123
61
+ mediaruntime jobs get job_123 --download ./job_123.zip
62
+ ```
63
+
64
+ Listing reads one page and prints an opaque next cursor when another page exists. Pass it
65
+ back with `--cursor`; the CLI does not decode or automatically walk pagination.
66
+
67
+ ## Test a local webhook receiver
68
+
69
+ Use the same webhook secret configured in the local application:
70
+
71
+ ```bash
72
+ export MEDIARUNTIME_WEBHOOK_SECRET="whsec_..."
73
+
74
+ mediaruntime trigger job.completed \
75
+ --to http://127.0.0.1:3000/webhooks/mediaruntime
76
+ ```
77
+
78
+ `trigger` supports `job.completed`, `job.failed`, and `job.rejected`. It signs the exact
79
+ JSON bytes with the production `X-Transcoder-*` HMAC protocol and sends them directly to
80
+ an explicit loopback URL. It does not call the MediaRuntime API, create a tunnel, register
81
+ a webhook, or follow redirects. `--secret-file` avoids environment configuration;
82
+ `--generate-secret` is an explicit local-harness mode and prints only the newly generated
83
+ secret.
84
+
85
+ See [the trigger security notes](docs/TRIGGER.md) for the complete local-delivery contract.
86
+
87
+ ## Exit codes
88
+
89
+ | Code | Meaning |
90
+ |---:|---|
91
+ | `0` | Command succeeded |
92
+ | `1` | Unexpected CLI error |
93
+ | `2` | Invalid arguments or missing configuration |
94
+ | `3` | Authentication, billing, or permission failure |
95
+ | `4` | Non-retryable API result or exhausted throttling |
96
+ | `5` | Connection, timeout, or exhausted server failure |
97
+ | `6` | Job ended as `FAILED`, `REJECTED`, or `PARTIAL` |
98
+ | `7` | Job wait timed out |
99
+ | `8` | Local trigger endpoint rejected the event |
100
+ | `9` | Bundle availability, integrity, redemption, or filesystem failure |
101
+ | `130` | Interrupted with `SIGINT` |
102
+
103
+ The full implementation contract is in [docs/CLI_SDD.md](docs/CLI_SDD.md).
104
+
105
+ ## Scope
106
+
107
+ The first release intentionally does not implement `listen`, `login`, credential storage,
108
+ or a webhook relay. Production completion continues to use the account destination under
109
+ Account → Webhooks. The ZIP remains the canonical completed-job result.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ import { ListJobsParams, JobPage, JobDetails, CreateJobParams, JobReceiptData, WaitForJobOptions } from '@mediaruntime/node';
2
+
3
+ interface JobsReadClient {
4
+ list(params?: ListJobsParams): Promise<JobPage>;
5
+ get(jobId: string): Promise<JobDetails>;
6
+ }
7
+
8
+ interface SubmittedJob extends JobReceiptData {
9
+ wait(options?: WaitForJobOptions): Promise<JobDetails>;
10
+ }
11
+ interface RunJobsClient {
12
+ create(params: CreateJobParams): Promise<SubmittedJob>;
13
+ }
14
+
15
+ declare const SUPPORTED_TRIGGER_EVENTS: readonly ["job.completed", "job.failed", "job.rejected"];
16
+ type TriggerEventType = (typeof SUPPORTED_TRIGGER_EVENTS)[number];
17
+ interface SyntheticEventOptions {
18
+ eventId: string;
19
+ jobId: string;
20
+ accountId: string;
21
+ timestamp: number;
22
+ }
23
+ declare function createSyntheticTerminalEvent(type: TriggerEventType, options: SyntheticEventOptions): Record<string, unknown>;
24
+
25
+ interface TriggerCommandDependencies {
26
+ env?: Readonly<Record<string, string | undefined>>;
27
+ fetch?: typeof globalThis.fetch;
28
+ now?: () => number;
29
+ randomUUID?: () => string;
30
+ randomBytes?: (size: number) => Uint8Array;
31
+ readFile?: (path: string, encoding: "utf8") => Promise<string>;
32
+ writeStdout?: (text: string) => void;
33
+ }
34
+ interface TriggerArguments {
35
+ type: TriggerEventType;
36
+ destination: URL;
37
+ secretFile?: string;
38
+ generateSecret: boolean;
39
+ jobId?: string;
40
+ accountId?: string;
41
+ json: boolean;
42
+ }
43
+ declare function parseTriggerArguments(args: string[]): TriggerArguments;
44
+ declare function runTriggerCommand(args: string[], dependencies?: TriggerCommandDependencies): Promise<number>;
45
+
46
+ interface SignedWebhook {
47
+ body: string;
48
+ headers: Record<string, string>;
49
+ }
50
+ declare function signSyntheticWebhook(payload: Readonly<Record<string, unknown>>, options: {
51
+ eventId: string;
52
+ timestamp: number;
53
+ secret: string;
54
+ }): SignedWebhook;
55
+
56
+ type CliJobsClient = RunJobsClient & JobsReadClient;
57
+ interface CliClient {
58
+ jobs: CliJobsClient;
59
+ }
60
+ interface CliDependencies {
61
+ createClient?(options: {
62
+ baseUrl?: string;
63
+ }): CliClient;
64
+ downloadBundle?(url: string, destination: string, options: {
65
+ force: boolean;
66
+ expectedSizeBytes?: number | null;
67
+ expectedSha256?: string | null;
68
+ }): Promise<void>;
69
+ writeStdout?(text: string): void;
70
+ writeStderr?(text: string): void;
71
+ }
72
+ declare function downloadBundleAtomically(url: string, destination: string, options: {
73
+ force: boolean;
74
+ expectedSizeBytes?: number | null;
75
+ expectedSha256?: string | null;
76
+ }): Promise<void>;
77
+ declare function executeCli(argv: string[], dependencies?: CliDependencies): Promise<number>;
78
+
79
+ export { type CliClient, type CliDependencies, createSyntheticTerminalEvent, downloadBundleAtomically, executeCli, parseTriggerArguments, runTriggerCommand, signSyntheticWebhook };