Skip to content

Commit 3df71f1

Browse files
committed
feat: ship release-ready BeatAPI client and CLI
1 parent c50cff2 commit 3df71f1

38 files changed

Lines changed: 5361 additions & 394 deletions

‎.env.example‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
BEATAPI_API_KEY=sk_your_key
22
BEATAPI_BASE_URL=https://api.beatapi.io
3-
3+
BEATAPI_API_KEY=
4+
BEATAPI_BASE_URL=https://api.beatapi.io

‎.github/workflows/ci.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
verify:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 22
19+
cache: npm
20+
- run: npm ci
21+
- run: npm run verify

‎.github/workflows/release.yml‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Publish npm packages
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
id-token: write
11+
12+
jobs:
13+
publish:
14+
runs-on: ubuntu-latest
15+
environment: npm
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: actions/setup-node@v4
19+
with:
20+
node-version: 22
21+
cache: npm
22+
registry-url: https://registry.npmjs.org
23+
- run: npm ci
24+
- run: npm run verify
25+
- run: npm publish --workspace beatapi-client
26+
env:
27+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
28+
- run: npm publish --workspace beatapi
29+
env:
30+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

‎.gitignore‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ node_modules/
44
!.env.example
55
coverage/
66
dist/
7+
*.tsbuildinfo
78
.worktrees/

‎CHANGELOG.md‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented here.
4+
5+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project uses [Semantic Versioning](https://semver.org/).
7+
8+
## [Unreleased]
9+
10+
## [0.1.0] - 2026-07-17
11+
12+
### Added
13+
14+
- Type-safe `beatapi-client` generated from the reviewed BeatAPI OpenAPI
15+
contract.
16+
- `beatapi` CLI with secure login, JSON output, and stderr progress.
17+
- Music Video automatic and manual shot workflows.
18+
- Ecommerce Video task creation and asynchronous task polling.
19+
- File upload, usage, workflow discovery, and webhook CRUD commands.
20+
- Structured errors, request IDs, bounded retries, CI, package checks, and npm
21+
release automation.
22+
23+
[Unreleased]: https://github.com/erickkkyt/beatapi-cli/compare/v0.1.0...HEAD
24+
[0.1.0]: https://github.com/erickkkyt/beatapi-cli/releases/tag/v0.1.0

‎CODE_OF_CONDUCT.md‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Contributor Covenant Code of Conduct
2+
3+
We are committed to a welcoming, harassment-free community for everyone.
4+
Contributors must communicate respectfully, accept constructive feedback, and
5+
focus discussion on improving BeatAPI users' experience.
6+
7+
Unacceptable behavior includes harassment, discrimination, threats, deliberate
8+
exposure of private information, and publishing credentials or private user
9+
media.
10+
11+
Project maintainers may remove or reject contributions and community
12+
participation that violate these expectations. Report conduct concerns
13+
privately through the repository owner's GitHub profile. Security issues belong
14+
in GitHub private vulnerability reporting instead of public issues.
15+
16+
This policy is adapted from the Contributor Covenant, version 2.1.

‎README.md‎

Lines changed: 163 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,184 @@
1-
# BeatAPI CLI
1+
# BeatAPI CLI and TypeScript Client
22

3-
A dependency-free Node.js command-line client for BeatAPI's public asynchronous
4-
video workflows.
3+
Official command-line interface and TypeScript client for BeatAPI's public
4+
asynchronous AI video workflows.
55

6-
This is an MVP scaffold. It is local-only and marked `private` until command
7-
behavior, package naming, authentication UX, and release ownership are reviewed.
6+
The repository contains two independently publishable npm packages:
87

9-
## Requirements
8+
- [`beatapi`](./packages/cli) — a human-, script-, and agent-friendly CLI.
9+
- [`beatapi-client`](./packages/client) — the typed runtime client shared by the
10+
CLI and the BeatAPI Codex plugin.
1011

11-
- Node.js 20 or newer
12-
- `BEATAPI_API_KEY` for authenticated commands
12+
Both packages are generated and tested against the reviewed OpenAPI snapshot in
13+
[`contract/beatapi.openapi.yaml`](./contract/beatapi.openapi.yaml). The lock file
14+
records the exact source commit and SHA-256 digest.
15+
16+
## Install the CLI
17+
18+
Node.js 20.19+ or 22.12+ is required.
19+
20+
```bash
21+
npm install --global beatapi
22+
beatapi auth login
23+
```
24+
25+
`auth login` reads the API key through hidden terminal input, validates it with
26+
`GET /v1/usage`, and saves it in the operating system credential manager.
27+
28+
For CI, containers, or short-lived shells:
1329

1430
```bash
1531
export BEATAPI_API_KEY="sk_your_key"
16-
npm link
17-
beatapi --help
32+
beatapi auth status
1833
```
1934

20-
## Commands
35+
Environment credentials take precedence over a saved credential. The CLI does
36+
not accept API keys as command-line arguments and never prints the key.
37+
38+
## Five-minute workflow
39+
40+
Create `music-video.json`:
41+
42+
```json
43+
{
44+
"images": ["https://media.example.com/reference.png"],
45+
"audio_url": "https://media.example.com/song.mp3",
46+
"prompt": "Cinematic nighttime performance with light trails.",
47+
"language": "en",
48+
"resolution": "720p",
49+
"compose_mode": "auto"
50+
}
51+
```
52+
53+
Then create and follow the task:
2154

2255
```bash
23-
beatapi workflows
56+
beatapi music-video create --file music-video.json
57+
beatapi tasks wait task_123 --interval 7000
58+
```
59+
60+
Command results are formatted JSON on stdout. Polling progress and errors use
61+
stderr, so output can be piped to `jq`, saved, or consumed by automation.
62+
63+
## Command reference
64+
65+
```text
66+
beatapi auth login
67+
beatapi auth status
68+
beatapi auth logout
69+
70+
beatapi workflows list
2471
beatapi usage
25-
beatapi file upload ./input.mp3
26-
beatapi music-video create --json ./music-video.json
27-
beatapi ecommerce-video create --json ./ecommerce-video.json
28-
beatapi task get task_123
29-
beatapi task wait task_123 --interval 7000 --attempts 120
72+
beatapi files upload ./input.mp3
73+
74+
beatapi music-video create --file ./music-video.json
75+
beatapi music-video shots edit TASK SHOT --prompt "New direction"
76+
beatapi music-video shots edit TASK SHOT --file ./shot-edit.json
77+
beatapi music-video shots media TASK SHOT
78+
beatapi music-video compose TASK --shot SHOT_1 --shot SHOT_2
79+
80+
beatapi ecommerce-video create --file ./ecommerce-video.json
81+
82+
beatapi tasks get TASK
83+
beatapi tasks wait TASK --interval 7000 --attempts 120
84+
85+
beatapi webhooks list
86+
beatapi webhooks create --file ./webhook.json
87+
beatapi webhooks get WEBHOOK
88+
beatapi webhooks update WEBHOOK --file ./webhook-update.json
89+
beatapi webhooks delete WEBHOOK
3090
```
3191

32-
Task creation JSON follows the canonical public contract at
33-
`../beatapi-examples/openapi/beatapi.yaml`.
92+
Use `beatapi --help` for the installed command summary. `--json` remains an
93+
alias for `--file` on JSON-input commands.
3494

35-
The CLI writes machine-readable result JSON to stdout. Polling progress and
36-
errors go to stderr so commands can be used in scripts.
95+
## TypeScript client
3796

38-
## Development
97+
```bash
98+
npm install beatapi-client
99+
```
100+
101+
```ts
102+
import { BeatAPIClient, BeatAPIError } from "beatapi-client";
103+
104+
const beatapi = new BeatAPIClient({
105+
apiKey: process.env.BEATAPI_API_KEY,
106+
});
107+
108+
try {
109+
const task = await beatapi.createEcommerceVideoTask({
110+
images: ["https://media.example.com/product.png"],
111+
duration: 15,
112+
prompt: "Fast vertical product launch ad.",
113+
aspect_ratio: "9:16",
114+
});
115+
116+
const result = await beatapi.waitForTask(task.id, {
117+
intervalMs: 7_000,
118+
onUpdate: ({ status }) => console.error(status),
119+
});
120+
121+
console.log(result.output?.media);
122+
} catch (error) {
123+
if (error instanceof BeatAPIError) {
124+
console.error(error.code, error.requestId);
125+
}
126+
throw error;
127+
}
128+
```
129+
130+
The client exposes every launch-contract operation: workflows, usage, file
131+
upload, music-video automatic and manual composition, ecommerce-video tasks,
132+
task polling, and webhook CRUD.
133+
134+
Retries are bounded and opt-in through method retry options. The client
135+
preserves BeatAPI error code, HTTP status, request ID, details, and
136+
`Retry-After` information.
137+
138+
## Security model
139+
140+
- API keys are read from `BEATAPI_API_KEY` or an OS credential manager.
141+
- macOS forces the native Keychain backend, Windows uses Credential Manager,
142+
and Linux uses Secret Service.
143+
- Unsupported systems fail closed and instruct the user to use the environment
144+
variable; the CLI does not fall back to plaintext or file-based storage.
145+
- API keys must never be committed, placed in JSON input files, pasted into
146+
issue reports, or passed as command arguments.
147+
- Webhook signing secrets are returned once by the API and should be stored
148+
with the same care as an API key.
149+
150+
See [SECURITY.md](./SECURITY.md) for reporting instructions.
151+
152+
## Contract and development
39153

40154
```bash
41-
npm run check
155+
npm ci
156+
npm run contract:check
157+
npm run check:generated
42158
npm test
159+
npm run verify
43160
```
44161

162+
Important scripts:
163+
164+
- `npm run contract:sync` copies the reviewed public contract snapshot.
165+
- `npm run generate:types` regenerates TypeScript definitions.
166+
- `npm run check:generated` proves generated definitions are current.
167+
- `npm run verify` runs contract, type, test, build, and package checks.
168+
169+
The canonical private contract is maintained in the BeatAPI product repository.
170+
This public repository contains only its reviewed, publication-safe snapshot.
171+
See [CONTRIBUTING.md](./CONTRIBUTING.md) before changing behavior.
172+
173+
## Publishing
174+
175+
GitHub Actions verifies every pull request. Publishing is triggered by a GitHub
176+
release or manually through the release workflow after the repository
177+
environment contains an `NPM_TOKEN` secret.
178+
179+
Release steps and ownership prerequisites are documented in
180+
[`docs/releasing.md`](./docs/releasing.md).
181+
182+
## License
183+
184+
MIT

‎bin/beatapi.mjs‎

Lines changed: 0 additions & 18 deletions
This file was deleted.

‎docs/releasing.md‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Release guide
2+
3+
## One-time setup
4+
5+
1. Create the public GitHub repository `erickkkyt/beatapi-cli`.
6+
2. Log in to npm with the BeatAPI publishing account.
7+
3. Publish or reserve both package names: `beatapi-client` and `beatapi`.
8+
4. In GitHub, create an environment named `npm`.
9+
5. Add an environment secret named `NPM_TOKEN` with publish access to both
10+
packages. Keep required reviewer protection enabled for production releases.
11+
12+
The package names were unregistered when this repository was prepared. npm
13+
names are first-come, first-served, so reserve them before announcing the
14+
release.
15+
16+
## Release checklist
17+
18+
1. Synchronize and review the public OpenAPI snapshot.
19+
2. Run `npm run verify` from a clean checkout.
20+
3. Confirm `npm audit --omit=dev` reports no known runtime vulnerabilities.
21+
4. Update `CHANGELOG.md` and both package versions together.
22+
5. Commit and push the release branch.
23+
6. Merge to `main` only after CI passes.
24+
7. Create a GitHub release tagged `vX.Y.Z`.
25+
8. Approve the protected `npm` environment deployment.
26+
9. Confirm both npm package pages and install the CLI in a clean temporary
27+
directory.
28+
10. Run `beatapi --version`, `beatapi --help`, and an authenticated
29+
`beatapi auth status` smoke test.
30+
31+
## Rollback
32+
33+
npm package versions are immutable. If a release is defective:
34+
35+
1. Deprecate the affected version with a clear message.
36+
2. Publish a corrected patch release.
37+
3. Mark the GitHub release as superseded and link to the patch.
38+
4. Revoke any credential that may have entered logs or artifacts.

0 commit comments

Comments
 (0)