@leiboss/dsh-voiceover 0.0.0-stage → 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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +187 -2
  3. package/client/client.js +985 -0
  4. package/cordis.patch.yml +13 -0
  5. package/dist/api.d.ts +52 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +301 -0
  8. package/dist/api.js.map +1 -0
  9. package/dist/cli.d.ts +40 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +303 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/client.js +985 -0
  14. package/dist/http-types.d.ts +26 -0
  15. package/dist/http-types.d.ts.map +1 -0
  16. package/dist/http-types.js +2 -0
  17. package/dist/http-types.js.map +1 -0
  18. package/dist/index.d.ts +60 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +410 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/llm.d.ts +60 -0
  23. package/dist/llm.d.ts.map +1 -0
  24. package/dist/llm.js +113 -0
  25. package/dist/llm.js.map +1 -0
  26. package/dist/operations.d.ts +41 -0
  27. package/dist/operations.d.ts.map +1 -0
  28. package/dist/operations.js +77 -0
  29. package/dist/operations.js.map +1 -0
  30. package/dist/panel.d.ts +42 -0
  31. package/dist/panel.d.ts.map +1 -0
  32. package/dist/panel.js +212 -0
  33. package/dist/panel.js.map +1 -0
  34. package/dist/pipeline.d.ts +141 -0
  35. package/dist/pipeline.d.ts.map +1 -0
  36. package/dist/pipeline.js +519 -0
  37. package/dist/pipeline.js.map +1 -0
  38. package/dist/prompts.d.ts +58 -0
  39. package/dist/prompts.d.ts.map +1 -0
  40. package/dist/prompts.js +169 -0
  41. package/dist/prompts.js.map +1 -0
  42. package/dist/serve-entry.d.ts +3 -0
  43. package/dist/serve-entry.d.ts.map +1 -0
  44. package/dist/serve-entry.js +11 -0
  45. package/dist/serve-entry.js.map +1 -0
  46. package/dist/snapshot.d.ts +48 -0
  47. package/dist/snapshot.d.ts.map +1 -0
  48. package/dist/snapshot.js +82 -0
  49. package/dist/snapshot.js.map +1 -0
  50. package/dist/subtitle.d.ts +49 -0
  51. package/dist/subtitle.d.ts.map +1 -0
  52. package/dist/subtitle.js +163 -0
  53. package/dist/subtitle.js.map +1 -0
  54. package/dist/types.d.ts +148 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +10 -0
  57. package/dist/types.js.map +1 -0
  58. package/dist/util.d.ts +16 -0
  59. package/dist/util.d.ts.map +1 -0
  60. package/dist/util.js +47 -0
  61. package/dist/util.js.map +1 -0
  62. package/dist/validate.d.ts +15 -0
  63. package/dist/validate.d.ts.map +1 -0
  64. package/dist/validate.js +186 -0
  65. package/dist/validate.js.map +1 -0
  66. package/dist/version.d.ts +3 -0
  67. package/dist/version.d.ts.map +1 -0
  68. package/dist/version.js +3 -0
  69. package/dist/version.js.map +1 -0
  70. package/package.json +83 -3
  71. package/schemas/manifest.schema.json +132 -0
  72. package/schemas/outline.schema.json +40 -0
@@ -0,0 +1,13 @@
1
+ # Mounts the engine and the product in one install.
2
+ #
3
+ # The engine entry deliberately reuses the engine bundle's own id (`dsh-tts`), so
4
+ # installing both `@leiboss/dsh-tts` and `@leiboss/dsh-voiceover` merges into one
5
+ # entry instead of mounting the engine twice (two `ctx.provide('tts')` calls in
6
+ # one scope would throw on the second one).
7
+ - insert:
8
+ - id: dsh-tts
9
+ name: '@leiboss/dsh-tts'
10
+ config: {}
11
+ - id: dsh-voiceover
12
+ name: '@leiboss/dsh-voiceover'
13
+ config: {}
package/dist/api.d.ts ADDED
@@ -0,0 +1,52 @@
1
+ import type { StyleProfile } from './pipeline.ts';
2
+ /** Collaborators the API needs; the CLI wires them to the real pipeline. */
3
+ export interface ApiContext {
4
+ outputDir: string;
5
+ token: string;
6
+ version: string;
7
+ startedAt: number;
8
+ synthesize(input: {
9
+ text: string;
10
+ voice?: string;
11
+ rate?: string;
12
+ }): Promise<{
13
+ filePath: string;
14
+ format: string;
15
+ durationMs: number;
16
+ timingQuality: 'exact' | 'estimated';
17
+ engine: string;
18
+ }>;
19
+ createProject(input: {
20
+ sourcePath?: string;
21
+ sourceText?: string;
22
+ title?: string;
23
+ voice?: string;
24
+ rate?: string;
25
+ style?: StyleProfile;
26
+ }): Promise<{
27
+ projectId: string;
28
+ }>;
29
+ rerunProject(projectId: string, chapter?: string): Promise<void>;
30
+ doctor(): Promise<unknown>;
31
+ }
32
+ /** One request, already read into memory. */
33
+ export interface ApiRequest {
34
+ method: string;
35
+ url: string;
36
+ headers: Record<string, string | string[] | undefined>;
37
+ body?: Buffer;
38
+ }
39
+ /** One response. `body` is always a Buffer so callers can stream it verbatim. */
40
+ export interface ApiResponse {
41
+ status: number;
42
+ headers: Record<string, string>;
43
+ body: Buffer;
44
+ }
45
+ declare const CHAPTER: RegExp;
46
+ /**
47
+ * Dispatch one request. Never throws: every failure becomes a JSON response.
48
+ */
49
+ export declare function handleRequest(context: ApiContext, request: ApiRequest): Promise<ApiResponse>;
50
+ /** Re-exported so the CLI can share the chapter pattern. */
51
+ export { CHAPTER };
52
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAGjD,4EAA4E;AAC5E,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAC1E,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,OAAO,GAAG,WAAW,CAAA;QACpC,MAAM,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;IACF,aAAa,CAAC,KAAK,EAAE;QACnB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,YAAY,CAAA;KACrB,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAC3B;AAED,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;CACb;AASD,QAAA,MAAM,OAAO,QAAoB,CAAA;AAoJjC;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAgIlG;AAQD,4DAA4D;AAC5D,OAAO,EAAE,OAAO,EAAE,CAAA"}
package/dist/api.js ADDED
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Daemon API: the same operations the DSH plugin exposes, reachable by any
3
+ * process on this machine (scripts, other agents, an editor task).
4
+ *
5
+ * Everything here is a pure function of (`ApiContext`, request) so it can be
6
+ * exercised without sockets; `cli.ts` is the only place that binds a port.
7
+ *
8
+ * Auth: a bearer token is mandatory. The daemon refuses to start without one,
9
+ * and every route except `/healthz` requires it.
10
+ */
11
+ import { createHash, timingSafeEqual } from 'node:crypto';
12
+ import { readFile } from 'node:fs/promises';
13
+ import { join, resolve } from 'node:path';
14
+ import { projectSnapshot } from "./snapshot.js";
15
+ /** Largest accepted JSON body for a create call. */
16
+ const MAX_BODY_BYTES = 5 * 1024 * 1024;
17
+ /** Longest text accepted for one-shot synthesis. */
18
+ const MAX_TTS_CHARS = 10_000;
19
+ const STYLES = new Set(['lecture', 'news', 'story', 'docs']);
20
+ const PROJECT_ID = /^[0-9a-f]{8,24}$/;
21
+ const CHAPTER = /^ch-[0-9]{2,3}$/;
22
+ /** JSON response helper. */
23
+ function json(status, body) {
24
+ const payload = Buffer.from(`${JSON.stringify(body)}\n`, 'utf8');
25
+ return {
26
+ status,
27
+ headers: {
28
+ 'content-type': 'application/json; charset=utf-8',
29
+ 'content-length': String(payload.length),
30
+ 'cache-control': 'no-store',
31
+ },
32
+ body: payload,
33
+ };
34
+ }
35
+ /** Constant-time bearer check: compare digests so lengths always match. */
36
+ function authorized(headers, token) {
37
+ const raw = headers.authorization;
38
+ const value = Array.isArray(raw) ? raw[0] : raw;
39
+ if (typeof value !== 'string' || !value.startsWith('Bearer '))
40
+ return false;
41
+ const expected = createHash('sha256').update(token).digest();
42
+ const actual = createHash('sha256').update(value.slice('Bearer '.length).trim()).digest();
43
+ return timingSafeEqual(expected, actual);
44
+ }
45
+ /** Parse a JSON body, tolerating an empty one. */
46
+ function parseJson(body) {
47
+ if (body === undefined || body.length === 0)
48
+ return {};
49
+ if (body.length > MAX_BODY_BYTES)
50
+ return undefined;
51
+ try {
52
+ const value = JSON.parse(body.toString('utf8'));
53
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
54
+ ? value
55
+ : undefined;
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
61
+ /** Parse `Range: bytes=start-end` against a known size. */
62
+ function parseRange(header, size) {
63
+ if (header === undefined)
64
+ return undefined;
65
+ const match = /^bytes=(\d*)-(\d*)$/.exec(header.trim());
66
+ if (match === null)
67
+ return 'invalid';
68
+ const startRaw = match[1] ?? '';
69
+ const endRaw = match[2] ?? '';
70
+ if (startRaw === '' && endRaw === '')
71
+ return 'invalid';
72
+ if (startRaw === '') {
73
+ const suffix = Number(endRaw);
74
+ if (!Number.isFinite(suffix) || suffix <= 0)
75
+ return 'invalid';
76
+ return { start: Math.max(0, size - suffix), end: size - 1 };
77
+ }
78
+ const start = Number(startRaw);
79
+ const end = endRaw === '' ? size - 1 : Math.min(Number(endRaw), size - 1);
80
+ if (!Number.isFinite(start) || !Number.isFinite(end) || start > end || start >= size)
81
+ return 'invalid';
82
+ return { start, end };
83
+ }
84
+ /** Serve a file with optional single-range support. */
85
+ async function serveFile(filePath, contentType, rangeHeader) {
86
+ let bytes;
87
+ try {
88
+ bytes = await readFile(filePath);
89
+ }
90
+ catch {
91
+ return json(404, { error: 'not found' });
92
+ }
93
+ const range = parseRange(rangeHeader, bytes.length);
94
+ if (range === 'invalid') {
95
+ return {
96
+ status: 416,
97
+ headers: { 'content-range': `bytes */${bytes.length}`, 'content-type': 'application/json' },
98
+ body: Buffer.from(`${JSON.stringify({ error: 'invalid range' })}\n`),
99
+ };
100
+ }
101
+ if (range === undefined) {
102
+ return {
103
+ status: 200,
104
+ headers: {
105
+ 'content-type': contentType,
106
+ 'content-length': String(bytes.length),
107
+ 'accept-ranges': 'bytes',
108
+ 'cache-control': 'no-store',
109
+ },
110
+ body: bytes,
111
+ };
112
+ }
113
+ const slice = bytes.subarray(range.start, range.end + 1);
114
+ return {
115
+ status: 206,
116
+ headers: {
117
+ 'content-type': contentType,
118
+ 'content-length': String(slice.length),
119
+ 'content-range': `bytes ${range.start}-${range.end}/${bytes.length}`,
120
+ 'accept-ranges': 'bytes',
121
+ 'cache-control': 'no-store',
122
+ },
123
+ body: slice,
124
+ };
125
+ }
126
+ /**
127
+ * Map a synthesis failure onto an HTTP answer.
128
+ *
129
+ * Throttling is not a client error: the request was fine, the upstream is busy.
130
+ * Answering 429 with `Retry-After` lets a caller back off instead of treating it
131
+ * as a bad request and giving up.
132
+ */
133
+ function synthesisFailure(error) {
134
+ const message = error instanceof Error ? error.message.slice(0, 300) : 'synthesis failed';
135
+ const code = typeof error === 'object' && error !== null && 'code' in error
136
+ ? String(error.code ?? '')
137
+ : '';
138
+ if (code === 'UPSTREAM_THROTTLED' || /\\b429\\b|too many requests|rate limit/i.test(message)) {
139
+ const payload = Buffer.from(`${JSON.stringify({ error: message, code: 'UPSTREAM_THROTTLED' })}\n`);
140
+ return {
141
+ status: 429,
142
+ headers: {
143
+ 'content-type': 'application/json; charset=utf-8',
144
+ 'retry-after': '30',
145
+ 'cache-control': 'no-store',
146
+ 'content-length': String(payload.length),
147
+ },
148
+ body: payload,
149
+ };
150
+ }
151
+ return json(422, { error: message });
152
+ }
153
+ /** Resolve a chapter artifact inside one project, refusing escapes. */
154
+ function artifactPath(outputDir, projectId, name) {
155
+ if (!PROJECT_ID.test(projectId))
156
+ return undefined;
157
+ const projectDir = resolve(outputDir, projectId);
158
+ const target = resolve(projectDir, 'audio', name);
159
+ if (!target.startsWith(`${projectDir}/`) && !target.startsWith(`${projectDir}\\`))
160
+ return undefined;
161
+ return target;
162
+ }
163
+ /**
164
+ * Dispatch one request. Never throws: every failure becomes a JSON response.
165
+ */
166
+ export async function handleRequest(context, request) {
167
+ const url = new URL(request.url, 'http://localhost');
168
+ const path = url.pathname;
169
+ if (path === '/healthz') {
170
+ return json(200, {
171
+ ok: true,
172
+ version: context.version,
173
+ uptimeMs: Date.now() - context.startedAt,
174
+ });
175
+ }
176
+ if (!authorized(request.headers, context.token)) {
177
+ return json(401, { error: 'unauthorized', hint: 'send Authorization: Bearer <token>' });
178
+ }
179
+ if (path === '/v1/doctor' && request.method === 'GET') {
180
+ return json(200, await context.doctor());
181
+ }
182
+ if (path === '/v1/tts' && request.method === 'POST') {
183
+ const body = parseJson(request.body);
184
+ if (body === undefined)
185
+ return json(400, { error: 'invalid JSON body' });
186
+ const text = typeof body.text === 'string' ? body.text : '';
187
+ if (text.trim().length === 0)
188
+ return json(400, { error: 'text is required' });
189
+ if (text.length > MAX_TTS_CHARS) {
190
+ return json(413, { error: `text exceeds ${MAX_TTS_CHARS} characters` });
191
+ }
192
+ const voice = typeof body.voice === 'string' ? body.voice : undefined;
193
+ const rate = typeof body.rate === 'string' ? body.rate : undefined;
194
+ try {
195
+ const result = await context.synthesize({ text, ...(voice === undefined ? {} : { voice }), ...(rate === undefined ? {} : { rate }) });
196
+ return json(200, result);
197
+ }
198
+ catch (error) {
199
+ return synthesisFailure(error);
200
+ }
201
+ }
202
+ if (path === '/v1/voiceover' && request.method === 'POST') {
203
+ const body = parseJson(request.body);
204
+ if (body === undefined)
205
+ return json(400, { error: 'invalid JSON body' });
206
+ const sourcePath = typeof body.sourcePath === 'string' ? body.sourcePath : undefined;
207
+ const sourceText = typeof body.sourceText === 'string' ? body.sourceText : undefined;
208
+ if ((sourcePath === undefined) === (sourceText === undefined)) {
209
+ return json(400, { error: 'provide exactly one of sourcePath or sourceText' });
210
+ }
211
+ if (sourceText !== undefined && sourceText.length > MAX_BODY_BYTES) {
212
+ return json(413, { error: 'sourceText is too large' });
213
+ }
214
+ const styleRaw = typeof body.style === 'string' ? body.style : undefined;
215
+ if (styleRaw !== undefined && !STYLES.has(styleRaw)) {
216
+ return json(400, { error: 'style must be lecture, news, story or docs' });
217
+ }
218
+ try {
219
+ const created = await context.createProject({
220
+ ...(sourcePath === undefined ? {} : { sourcePath }),
221
+ ...(sourceText === undefined ? {} : { sourceText }),
222
+ ...(typeof body.title === 'string' ? { title: body.title } : {}),
223
+ ...(typeof body.voice === 'string' ? { voice: body.voice } : {}),
224
+ ...(typeof body.rate === 'string' ? { rate: body.rate } : {}),
225
+ ...(styleRaw === undefined ? {} : { style: styleRaw }),
226
+ });
227
+ return json(202, { projectId: created.projectId, statusUrl: `/v1/projects/${created.projectId}` });
228
+ }
229
+ catch (error) {
230
+ return json(422, { error: error instanceof Error ? error.message.slice(0, 300) : 'create failed' });
231
+ }
232
+ }
233
+ const projectMatch = /^\/v1\/projects\/([0-9a-f]{8,24})(\/.*)?$/.exec(path);
234
+ if (projectMatch !== null) {
235
+ const projectId = projectMatch[1] ?? '';
236
+ const rest = projectMatch[2] ?? '';
237
+ if (rest === '' && request.method === 'GET') {
238
+ const snapshot = await projectSnapshot(context.outputDir, projectId);
239
+ return snapshot === undefined ? json(404, { error: 'unknown project' }) : json(200, snapshot);
240
+ }
241
+ if (rest === '/manifest' && request.method === 'GET') {
242
+ const filePath = join(resolve(context.outputDir, projectId), 'manifest.json');
243
+ try {
244
+ const manifest = await readFile(filePath, 'utf8');
245
+ return {
246
+ status: 200,
247
+ headers: { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' },
248
+ body: Buffer.from(manifest, 'utf8'),
249
+ };
250
+ }
251
+ catch {
252
+ return json(404, { error: 'manifest is not ready' });
253
+ }
254
+ }
255
+ if (rest === '/rerun' && request.method === 'POST') {
256
+ const snapshot = await projectSnapshot(context.outputDir, projectId);
257
+ if (snapshot === undefined)
258
+ return json(404, { error: 'unknown project' });
259
+ const body = parseJson(request.body);
260
+ if (body === undefined)
261
+ return json(400, { error: 'invalid JSON body' });
262
+ const chapter = typeof body.chapter === 'string' ? body.chapter : undefined;
263
+ if (chapter !== undefined && !CHAPTER.test(chapter)) {
264
+ return json(400, { error: 'chapter must look like ch-03' });
265
+ }
266
+ try {
267
+ await context.rerunProject(projectId, chapter);
268
+ return json(202, { ok: true, projectId, ...(chapter === undefined ? {} : { chapter }) });
269
+ }
270
+ catch (error) {
271
+ return json(422, { error: error instanceof Error ? error.message.slice(0, 300) : 'rerun failed' });
272
+ }
273
+ }
274
+ const audioMatch = /^\/audio\/(ch-[0-9]{2,3})\.(mp3|wav)$/.exec(rest);
275
+ if (audioMatch !== null && request.method === 'GET') {
276
+ const fileName = `${audioMatch[1]}.${audioMatch[2]}`;
277
+ const filePath = artifactPath(context.outputDir, projectId, fileName);
278
+ if (filePath === undefined)
279
+ return json(400, { error: 'bad chapter' });
280
+ return serveFile(filePath, audioMatch[2] === 'wav' ? 'audio/wav' : 'audio/mpeg', rangeOf(request));
281
+ }
282
+ const subtitleMatch = /^\/subtitles\/(ch-[0-9]{2,3})(\.est)?\.srt$/.exec(rest);
283
+ if (subtitleMatch !== null && request.method === 'GET') {
284
+ const fileName = `${subtitleMatch[1]}${subtitleMatch[2] ?? ''}.srt`;
285
+ const filePath = artifactPath(context.outputDir, projectId, fileName);
286
+ if (filePath === undefined)
287
+ return json(400, { error: 'bad chapter' });
288
+ return serveFile(filePath, 'text/plain; charset=utf-8', undefined);
289
+ }
290
+ return json(404, { error: 'unknown endpoint' });
291
+ }
292
+ return json(404, { error: 'unknown endpoint' });
293
+ }
294
+ /** Read the `Range` header defensively. */
295
+ function rangeOf(request) {
296
+ const raw = request.headers.range;
297
+ return Array.isArray(raw) ? raw[0] : raw;
298
+ }
299
+ /** Re-exported so the CLI can share the chapter pattern. */
300
+ export { CHAPTER };
301
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `dsh-voiceover serve` — the daemon entry.
4
+ *
5
+ * Same pipeline, same operations, different door: a local HTTP API so scripts
6
+ * and agents outside DSH can synthesize a line, build a project, watch it, and
7
+ * fetch audio/subtitles. The port binds to loopback by default and the daemon
8
+ * refuses to start without a bearer token.
9
+ */
10
+ import { createServer } from 'node:http';
11
+ import { TtsService } from '@leiboss/dsh-tts';
12
+ import { type ApiContext } from './api.ts';
13
+ import { type StyleProfile } from './pipeline.ts';
14
+ /** Parsed command line. */
15
+ interface Options {
16
+ port: number;
17
+ host: string;
18
+ outputDir: string;
19
+ token?: string;
20
+ voice: string;
21
+ rate: string;
22
+ style: StyleProfile;
23
+ llmBaseUrl?: string;
24
+ llmModel: string;
25
+ llmKey?: string;
26
+ chapterChars?: number;
27
+ }
28
+ /** Resolve options from flags, the environment, and defaults. */
29
+ declare function resolveOptions(argv: readonly string[], env: NodeJS.ProcessEnv): Options;
30
+ /** Start the daemon. Returns the listening server for tests. */
31
+ export declare function start(options: Options, inject?: {
32
+ engine?: TtsService;
33
+ }): Promise<{
34
+ server: ReturnType<typeof createServer>;
35
+ context: ApiContext;
36
+ }>;
37
+ /** CLI entry. */
38
+ export declare function main(): Promise<void>;
39
+ export { resolveOptions };
40
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AACH,OAAO,EAAE,YAAY,EAA6C,MAAM,WAAW,CAAA;AAInF,OAAO,EAAiB,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAGzD,OAAO,EAA8D,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAO7G,2BAA2B;AAC3B,UAAU,OAAO;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,YAAY,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AA2ED,iEAAiE;AACjE,iBAAS,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAsBhF;AAuCD,gEAAgE;AAChE,wBAAsB,KAAK,CACzB,OAAO,EAAE,OAAO,EAChB,MAAM,GAAE;IAAE,MAAM,CAAC,EAAE,UAAU,CAAA;CAAO,GACnC,OAAO,CAAC;IAAE,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,CAAC,CA2H3E;AAED,iBAAiB;AACjB,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAoC1C;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}