first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
# `commands/convert` — `runConvert`
## Purpose
`runConvert` is a deliberately thin wrapper around `runProcess`. It validates
the small `ConvertOptions` surface (`format`, `bitDepth`, `signal`) and
forwards into the shared decode/encode path with no pipeline ops. Keeping it
this thin means the format mapping, codec lookup, abort handling, and error
translation live in exactly one place — the `process` command — which the
spec calls out as the single source of truth for streaming through
`audio-core`/`audio-codecs`/`audio-engine-server`.
## Features
- Zod-strict validation of `ConvertOptions`.
- Optional explicit `format` overriding extension detection.
- Optional `bitDepth` forwarded to the codec encoder where supported.
- Pre-aborted signal short-circuits via `runProcess`.
## Usage: Basic
```ts
import { AudioCLI } from "@suaveplan/audio-cli";
const cli = new AudioCLI();
await cli.convert("input.wav", "output.flac");
```
## Usage: Advanced
```ts
import { runConvert } from "@suaveplan/audio-cli/commands/convert";
await runConvert(cli, "input.wav", "output.aiff", { bitDepth: 24 });
```
## API Reference
- `runConvert(cli, input, output, opts?): Promise<void>`
- `ConvertOptions` — `{ format?, bitDepth?, signal? }`
- `ConvertOptionsSchema` — Zod boundary validation.
## Implementation Notes
Because the implementation forwards into `runProcess`, every error code that
`runProcess` produces (`INPUT_NOT_FOUND`, `BAD_OUTPUT`, `PIPELINE_FAILED`,
`ABORTED`) is reachable from `convert` as well. The empty pipeline path is
not a special case in `runProcess`: an empty edit chain just means
"decode → re-encode", which is exactly the conversion semantic.
The Zod schema is `strict()`, so a typo in an option key (`{ formt: "wav" }`)
fails fast at the boundary with `AUDIO_CLI.INVALID_ARGS` rather than being
silently dropped. The `bitDepth` field is constrained to the union
`8 | 16 | 24 | 32` so encoders that only accept those depths receive a
correctly-typed value. Passing an `AbortSignal` that is already aborted at
call time short-circuits inside `runProcess` before any file is opened, so
`convert` participates in the same SIGINT contract as every other command.
`convert` is the cheapest way to migrate a file between formats in shell
pipelines: it skips the planner and the op chain entirely, so a file with
no edits goes straight through the codec stack. For copying with an op
chain attached, prefer the `process` command directly — `convert` is
deliberately a forward-only wrapper with a smaller option surface.