@deepdub/agent-plugin 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.
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "deepdub-agent-plugins",
3
+ "interface": {
4
+ "displayName": "Deepdub Agent Plugins"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "deepdub-tts",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./plugin"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Productivity"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: deepdub-tts
3
+ description: Add Deepdub text-to-speech, voice cloning, streaming speech, voice presets, or Deepdub SDK/API usage to JavaScript, Python, REST, or CLI projects. Use when the user mentions Deepdub, TTS, text-to-speech, speech synthesis, voice generation, voicePromptId, voiceReference, audio streaming, or generating audio files.
4
+ ---
5
+
6
+ # Deepdub TTS
7
+
8
+ This repository keeps the canonical skill at `plugin/skills/deepdub-tts/SKILL.md`.
9
+
10
+ When this skill is selected, read and follow `plugin/skills/deepdub-tts/SKILL.md`. Use `plugin/skills/deepdub-tts/reference.md` for API details and `plugin/skills/deepdub-tts/examples.md` for snippets.
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/claude-code-plugin-marketplace.json",
3
+ "name": "deepdub-agent-plugins",
4
+ "owner": {
5
+ "name": "Deepdub",
6
+ "email": "support@deepdub.ai"
7
+ },
8
+ "description": "Deepdub plugins and skills for adding expressive text-to-speech to software projects.",
9
+ "version": "0.1.0",
10
+ "plugins": [
11
+ {
12
+ "name": "deepdub-tts",
13
+ "description": "Add Deepdub text-to-speech to JavaScript, Python, CLI, and REST projects.",
14
+ "version": "0.1.0",
15
+ "author": {
16
+ "name": "Deepdub",
17
+ "email": "support@deepdub.ai"
18
+ },
19
+ "homepage": "https://docs.deepdub.ai",
20
+ "repository": "https://github.com/deepdub-ai/deepdub-agent-plugin",
21
+ "license": "MIT",
22
+ "keywords": ["deepdub", "tts", "voice-ai", "speech-synthesis"],
23
+ "category": "AI",
24
+ "tags": ["tts", "audio", "javascript", "python", "cli"],
25
+ "source": "./plugin"
26
+ }
27
+ ]
28
+ }
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: deepdub-tts
3
+ description: Add Deepdub text-to-speech, voice cloning, streaming speech, voice presets, or Deepdub SDK/API usage to JavaScript, Python, REST, or CLI projects. Use when the user mentions Deepdub, TTS, text-to-speech, speech synthesis, voice generation, voicePromptId, voiceReference, audio streaming, or generating audio files.
4
+ ---
5
+
6
+ # Deepdub TTS
7
+
8
+ This repository keeps the canonical skill at `plugin/skills/deepdub-tts/SKILL.md`.
9
+
10
+ When this skill is selected, read and follow `plugin/skills/deepdub-tts/SKILL.md`. Use `plugin/skills/deepdub-tts/reference.md` for API details and `plugin/skills/deepdub-tts/examples.md` for snippets.
package/AGENTS.md ADDED
@@ -0,0 +1,14 @@
1
+ # Deepdub Agent Plugin Repository
2
+
3
+ This repository packages Deepdub TTS guidance for Claude Code, Codex, and Cursor.
4
+
5
+ Keep these surfaces in sync when changing behavior:
6
+
7
+ - `plugin/skills/deepdub-tts/` is the canonical portable skill.
8
+ - `plugin/.claude-plugin/plugin.json` is the Claude Code plugin manifest.
9
+ - `plugin/.codex-plugin/plugin.json` is the Codex plugin manifest.
10
+ - `.claude-plugin/marketplace.json` and `.agents/plugins/marketplace.json` are local marketplace catalogs.
11
+ - `.cursor/skills/deepdub-tts/SKILL.md` and `.agents/skills/deepdub-tts/SKILL.md` are repository discovery wrappers.
12
+ - `bin/deepdub-agent-kit.js` is the npm CLI for local install, scaffolding, and terminal TTS.
13
+
14
+ Do not commit real Deepdub API keys. Use `DEEPDUB_API_KEY` in examples and `.env.example` files.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Deepdub
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,153 @@
1
+ # Deepdub Agent Plugin
2
+
3
+ Claude Code, Codex, and Cursor skills for adding Deepdub text-to-speech to JavaScript, Python, REST, and CLI projects.
4
+
5
+ The goal is simple: ask your coding agent to add speech generation, and it should know the right SDK, env vars, voice presets, streaming tradeoffs, and error handling without making you paste docs.
6
+
7
+ ## What Is Included
8
+
9
+ - Claude Code plugin: `plugin/.claude-plugin/plugin.json`
10
+ - Codex plugin: `plugin/.codex-plugin/plugin.json`
11
+ - Portable skill: `plugin/skills/deepdub-tts/SKILL.md`
12
+ - Cursor project skill wrapper: `.cursor/skills/deepdub-tts/SKILL.md`
13
+ - Codex project skill wrapper: `.agents/skills/deepdub-tts/SKILL.md`
14
+ - Marketplace catalogs for local testing:
15
+ - Claude Code: `.claude-plugin/marketplace.json`
16
+ - Codex: `.agents/plugins/marketplace.json`
17
+ - npm CLI: `deepdub-agent-kit`
18
+ - Runnable JavaScript and Python examples under `examples/`
19
+
20
+ ## Fastest Use
21
+
22
+ Run a TTS demo from the terminal:
23
+
24
+ ```bash
25
+ npx @deepdub/agent-plugin tts \
26
+ --text "Hello from Deepdub" \
27
+ --out hello.mp3
28
+ ```
29
+
30
+ If `DEEPDUB_API_KEY` is not set, the CLI uses Deepdub's public rate-limited trial key for that demo. For real projects:
31
+
32
+ ```bash
33
+ export DEEPDUB_API_KEY=dd-your-api-key
34
+ ```
35
+
36
+ ## Install Skills Locally
37
+
38
+ Install the skill into the current project for Cursor, Codex, and Claude Code:
39
+
40
+ ```bash
41
+ npx @deepdub/agent-plugin install --agent all --scope project
42
+ ```
43
+
44
+ Install globally for your user:
45
+
46
+ ```bash
47
+ npx @deepdub/agent-plugin install --agent all --scope user
48
+ ```
49
+
50
+ Use `--link` while developing this repository, or `--force` to replace an existing installed copy.
51
+
52
+ ## Scaffold A Tiny App
53
+
54
+ JavaScript:
55
+
56
+ ```bash
57
+ npx @deepdub/agent-plugin scaffold --language js --out ./deepdub-demo
58
+ cd deepdub-demo
59
+ npm install
60
+ DEEPDUB_API_KEY=dd-your-api-key npm run tts -- "Welcome to Deepdub"
61
+ ```
62
+
63
+ Python:
64
+
65
+ ```bash
66
+ npx @deepdub/agent-plugin scaffold --language python --out ./deepdub-demo
67
+ cd deepdub-demo
68
+ pip install -r requirements.txt
69
+ DEEPDUB_API_KEY=dd-your-api-key python tts.py "Welcome to Deepdub"
70
+ ```
71
+
72
+ ## Claude Code Marketplace
73
+
74
+ Install from the public GitHub repository:
75
+
76
+ ```bash
77
+ claude plugin marketplace add https://github.com/deepdub-ai/deepdub-agent-plugin
78
+ claude plugin install deepdub-tts@deepdub-agent-plugins
79
+ ```
80
+
81
+ During local development, add this repository as a marketplace from disk:
82
+
83
+ ```bash
84
+ claude plugin marketplace add ./path/to/deepdub-agent-plugin
85
+ claude plugin install deepdub-tts@deepdub-agent-plugins
86
+ ```
87
+
88
+ Or test the plugin directly:
89
+
90
+ ```bash
91
+ claude --plugin-dir ./plugin
92
+ ```
93
+
94
+ After installation, use prompts like:
95
+
96
+ ```text
97
+ Use Deepdub TTS to add a /tts endpoint that returns MP3 bytes.
98
+ Use Deepdub TTS to create a CLI command that saves speech to a file.
99
+ Use Deepdub TTS to stream WAV chunks from a WebSocket connection.
100
+ ```
101
+
102
+ ## Codex Marketplace
103
+
104
+ Codex can read the repo marketplace at `.agents/plugins/marketplace.json`. For a local marketplace:
105
+
106
+ ```bash
107
+ codex plugin marketplace add ./path/to/deepdub-agent-plugin
108
+ ```
109
+
110
+ You can also use the repo skill directly from `.agents/skills/deepdub-tts/`.
111
+
112
+ ## Cursor Skill
113
+
114
+ Cursor discovers project skills from `.cursor/skills/`. This repo includes a wrapper skill that points to the canonical skill in `plugin/skills/deepdub-tts/`.
115
+
116
+ For use in another project:
117
+
118
+ ```bash
119
+ npx @deepdub/agent-plugin install --agent cursor --scope project --project /path/to/project
120
+ ```
121
+
122
+ ## CLI Reference
123
+
124
+ ```bash
125
+ deepdub-agent-kit --help
126
+ deepdub-agent-kit doctor
127
+ deepdub-agent-kit install --agent cursor,codex --scope project
128
+ deepdub-agent-kit scaffold --language js --out ./deepdub-demo
129
+ deepdub-agent-kit voices --api-key dd-your-api-key
130
+ deepdub-agent-kit tts --text "Hello" --voice-prompt-id 50a537cf-1ec8-4714-b07e-c589ab76be4b --out output.mp3
131
+ ```
132
+
133
+ ## Development
134
+
135
+ ```bash
136
+ npm install
137
+ npm run smoke
138
+ npm run doctor
139
+ ```
140
+
141
+ Validate Claude Code metadata if you have Claude Code installed:
142
+
143
+ ```bash
144
+ claude plugin validate ./plugin
145
+ ```
146
+
147
+ ## Deepdub Docs
148
+
149
+ - Documentation index: https://docs.deepdub.ai/llms.txt
150
+ - Quickstart: https://docs.deepdub.ai/quickstart.md
151
+ - JavaScript SDK: https://www.npmjs.com/package/@deepdub/node
152
+ - Python SDK: https://docs.deepdub.ai/sdk.md
153
+ - Voice presets: https://docs.deepdub.ai/voice-presets.md
@@ -0,0 +1,419 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const fs = require("node:fs");
6
+ const os = require("node:os");
7
+ const path = require("node:path");
8
+
9
+ const PACKAGE_ROOT = path.resolve(__dirname, "..");
10
+ const SKILL_SOURCE = path.join(PACKAGE_ROOT, "plugin", "skills", "deepdub-tts");
11
+ const TRIAL_API_KEY = "dd-00000000000000000000000065c9cbfe";
12
+ const DEFAULT_VOICE_PROMPT_ID = "50a537cf-1ec8-4714-b07e-c589ab76be4b";
13
+
14
+ function printHelp() {
15
+ console.log(`Deepdub Agent Kit
16
+
17
+ Usage:
18
+ deepdub-agent-kit install [--agent all|cursor,codex,claude] [--scope project|user] [--project .] [--force] [--link]
19
+ deepdub-agent-kit scaffold --language js|python [--out ./deepdub-demo]
20
+ deepdub-agent-kit tts --text "Hello" [--voice-prompt-id ID] [--out output.mp3] [--api-key KEY] [--eu]
21
+ deepdub-agent-kit voices [--api-key KEY] [--eu]
22
+ deepdub-agent-kit doctor
23
+
24
+ Aliases:
25
+ dd-agent
26
+
27
+ Examples:
28
+ npx @deepdub/agent-plugin install --agent all --scope project
29
+ npx @deepdub/agent-plugin scaffold --language js --out ./deepdub-demo
30
+ npx @deepdub/agent-plugin tts --text "Hello from Deepdub" --out hello.mp3
31
+ `);
32
+ }
33
+
34
+ function parseArgs(argv) {
35
+ const args = { _: [] };
36
+
37
+ for (let index = 0; index < argv.length; index += 1) {
38
+ const token = argv[index];
39
+
40
+ if (!token.startsWith("--")) {
41
+ args._.push(token);
42
+ continue;
43
+ }
44
+
45
+ const [rawKey, inlineValue] = token.slice(2).split(/=(.*)/s, 2);
46
+ const key = rawKey.trim();
47
+
48
+ if (inlineValue !== undefined) {
49
+ args[key] = inlineValue;
50
+ continue;
51
+ }
52
+
53
+ const next = argv[index + 1];
54
+ if (!next || next.startsWith("--")) {
55
+ args[key] = true;
56
+ continue;
57
+ }
58
+
59
+ args[key] = next;
60
+ index += 1;
61
+ }
62
+
63
+ return args;
64
+ }
65
+
66
+ function getArg(args, ...keys) {
67
+ for (const key of keys) {
68
+ if (args[key] !== undefined) return args[key];
69
+ }
70
+ return undefined;
71
+ }
72
+
73
+ function listArg(value, fallback) {
74
+ if (!value || value === true) return fallback;
75
+ return String(value)
76
+ .split(",")
77
+ .map((item) => item.trim().toLowerCase())
78
+ .filter(Boolean);
79
+ }
80
+
81
+ function ensureDir(dirPath) {
82
+ fs.mkdirSync(dirPath, { recursive: true });
83
+ }
84
+
85
+ function copyOrLinkSkill(destination, options) {
86
+ ensureDir(path.dirname(destination));
87
+
88
+ if (fs.existsSync(destination)) {
89
+ if (!options.force) {
90
+ console.log(
91
+ `skip ${destination} (already exists; pass --force to replace)`
92
+ );
93
+ return;
94
+ }
95
+ fs.rmSync(destination, { recursive: true, force: true });
96
+ }
97
+
98
+ if (options.link) {
99
+ fs.symlinkSync(SKILL_SOURCE, destination, "dir");
100
+ console.log(`linked ${destination}`);
101
+ return;
102
+ }
103
+
104
+ fs.cpSync(SKILL_SOURCE, destination, { recursive: true });
105
+ console.log(`installed ${destination}`);
106
+ }
107
+
108
+ function install(args) {
109
+ const requested = listArg(getArg(args, "agent", "agents"), ["all"]);
110
+ const agents = requested.includes("all")
111
+ ? ["cursor", "codex", "claude"]
112
+ : requested;
113
+ const scope = String(getArg(args, "scope") || "project").toLowerCase();
114
+ const projectRoot = path.resolve(
115
+ String(getArg(args, "project") || process.cwd())
116
+ );
117
+ const options = {
118
+ force: Boolean(args.force),
119
+ link: Boolean(args.link),
120
+ };
121
+
122
+ const destinations = {
123
+ cursor:
124
+ scope === "user"
125
+ ? path.join(os.homedir(), ".cursor", "skills", "deepdub-tts")
126
+ : path.join(projectRoot, ".cursor", "skills", "deepdub-tts"),
127
+ codex:
128
+ scope === "user"
129
+ ? path.join(os.homedir(), ".agents", "skills", "deepdub-tts")
130
+ : path.join(projectRoot, ".agents", "skills", "deepdub-tts"),
131
+ claude:
132
+ scope === "user"
133
+ ? path.join(os.homedir(), ".claude", "skills", "deepdub-tts")
134
+ : path.join(projectRoot, ".claude", "skills", "deepdub-tts"),
135
+ };
136
+
137
+ for (const agent of agents) {
138
+ if (!destinations[agent]) {
139
+ throw new Error(
140
+ `Unknown agent "${agent}". Use cursor, codex, claude, or all.`
141
+ );
142
+ }
143
+ copyOrLinkSkill(destinations[agent], options);
144
+ }
145
+ }
146
+
147
+ function detectLanguage(args) {
148
+ const explicit = getArg(args, "language", "lang");
149
+ if (explicit) return String(explicit).toLowerCase();
150
+ if (fs.existsSync(path.join(process.cwd(), "pyproject.toml")))
151
+ return "python";
152
+ if (fs.existsSync(path.join(process.cwd(), "requirements.txt")))
153
+ return "python";
154
+ return "js";
155
+ }
156
+
157
+ function writeIfMissing(filePath, content, force) {
158
+ ensureDir(path.dirname(filePath));
159
+ if (fs.existsSync(filePath) && !force) {
160
+ console.log(`skip ${filePath} (already exists; pass --force to replace)`);
161
+ return;
162
+ }
163
+ fs.writeFileSync(filePath, content);
164
+ console.log(`wrote ${filePath}`);
165
+ }
166
+
167
+ function jsScaffold() {
168
+ return `import { writeFile } from "node:fs/promises";
169
+ import { DeepdubClient } from "@deepdub/node";
170
+
171
+ const deepdub = new DeepdubClient(process.env.DEEPDUB_API_KEY, {
172
+ protocol: "http",
173
+ eu: process.env.DD_EU === "1",
174
+ });
175
+
176
+ const text = process.argv.slice(2).join(" ") || "Hello from Deepdub.";
177
+ const voicePromptId =
178
+ process.env.DEEPDUB_VOICE_PROMPT_ID ||
179
+ "${DEFAULT_VOICE_PROMPT_ID}";
180
+
181
+ const audio = await deepdub.tts(text, {
182
+ voicePromptId,
183
+ locale: process.env.DEEPDUB_LOCALE || "en-US",
184
+ format: "mp3",
185
+ });
186
+
187
+ await writeFile("output.mp3", audio);
188
+ console.log(\`Generated output.mp3 (\${audio.length} bytes)\`);
189
+ `;
190
+ }
191
+
192
+ function pythonScaffold() {
193
+ return `import os
194
+ import sys
195
+ from pathlib import Path
196
+
197
+ from deepdub import DeepdubClient
198
+
199
+
200
+ client = DeepdubClient()
201
+
202
+ text = " ".join(sys.argv[1:]) or "Hello from Deepdub."
203
+ voice_prompt_id = os.getenv(
204
+ "DEEPDUB_VOICE_PROMPT_ID",
205
+ "${DEFAULT_VOICE_PROMPT_ID}",
206
+ )
207
+
208
+ audio = client.tts(
209
+ text=text,
210
+ voice_prompt_id=voice_prompt_id,
211
+ locale=os.getenv("DEEPDUB_LOCALE", "en-US"),
212
+ format="mp3",
213
+ )
214
+
215
+ Path("output.mp3").write_bytes(audio)
216
+ print(f"Generated output.mp3 ({len(audio)} bytes)")
217
+ `;
218
+ }
219
+
220
+ function scaffold(args) {
221
+ const language = detectLanguage(args);
222
+ const outDir = path.resolve(String(getArg(args, "out") || "./deepdub-demo"));
223
+ const force = Boolean(args.force);
224
+
225
+ if (
226
+ language === "js" ||
227
+ language === "javascript" ||
228
+ language === "ts" ||
229
+ language === "typescript"
230
+ ) {
231
+ writeIfMissing(
232
+ path.join(outDir, "package.json"),
233
+ `${JSON.stringify(
234
+ {
235
+ type: "module",
236
+ scripts: {
237
+ tts: "node ./tts.mjs",
238
+ },
239
+ dependencies: {
240
+ "@deepdub/node": "^2.0.0",
241
+ },
242
+ },
243
+ null,
244
+ 2
245
+ )}\n`,
246
+ force
247
+ );
248
+ writeIfMissing(path.join(outDir, "tts.mjs"), jsScaffold(), force);
249
+ writeIfMissing(
250
+ path.join(outDir, ".env.example"),
251
+ `DEEPDUB_API_KEY=dd-your-api-key
252
+ DEEPDUB_VOICE_PROMPT_ID=${DEFAULT_VOICE_PROMPT_ID}
253
+ DEEPDUB_LOCALE=en-US
254
+ DD_EU=0
255
+ `,
256
+ force
257
+ );
258
+ console.log(
259
+ `\nNext: cd ${outDir} && npm install && DEEPDUB_API_KEY=... npm run tts -- "Hello"`
260
+ );
261
+ return;
262
+ }
263
+
264
+ if (language === "py" || language === "python") {
265
+ writeIfMissing(path.join(outDir, "requirements.txt"), "deepdub\n", force);
266
+ writeIfMissing(path.join(outDir, "tts.py"), pythonScaffold(), force);
267
+ writeIfMissing(
268
+ path.join(outDir, ".env.example"),
269
+ `DEEPDUB_API_KEY=dd-your-api-key
270
+ DEEPDUB_VOICE_PROMPT_ID=${DEFAULT_VOICE_PROMPT_ID}
271
+ DEEPDUB_LOCALE=en-US
272
+ DD_EU=0
273
+ `,
274
+ force
275
+ );
276
+ console.log(
277
+ `\nNext: cd ${outDir} && pip install -r requirements.txt && DEEPDUB_API_KEY=... python tts.py "Hello"`
278
+ );
279
+ return;
280
+ }
281
+
282
+ throw new Error(`Unsupported language "${language}". Use js or python.`);
283
+ }
284
+
285
+ function loadDeepdubSdk() {
286
+ try {
287
+ return require("@deepdub/node");
288
+ } catch (error) {
289
+ throw new Error(
290
+ "Missing @deepdub/node. Run npm install, or use npx @deepdub/agent-plugin."
291
+ );
292
+ }
293
+ }
294
+
295
+ function apiKeyFromArgs(args) {
296
+ const key = getArg(args, "api-key", "apiKey") || process.env.DEEPDUB_API_KEY;
297
+ if (key) return String(key);
298
+ if (args["no-trial"]) {
299
+ throw new Error("Set DEEPDUB_API_KEY or pass --api-key.");
300
+ }
301
+ console.warn(
302
+ "DEEPDUB_API_KEY is not set; using Deepdub's public rate-limited trial key for this demo."
303
+ );
304
+ return TRIAL_API_KEY;
305
+ }
306
+
307
+ async function tts(args) {
308
+ const text = getArg(args, "text", "t") || args._.slice(1).join(" ");
309
+ if (!text) throw new Error('Pass text with --text "Hello".');
310
+
311
+ const { DeepdubClient } = loadDeepdubSdk();
312
+ const format = String(getArg(args, "format") || "mp3");
313
+ const out = path.resolve(
314
+ String(getArg(args, "out", "output") || `deepdub-output.${format}`)
315
+ );
316
+ const client = new DeepdubClient(apiKeyFromArgs(args), {
317
+ protocol: "http",
318
+ eu: Boolean(args.eu) || process.env.DD_EU === "1",
319
+ });
320
+
321
+ const params = {
322
+ locale: String(
323
+ getArg(args, "locale") || process.env.DEEPDUB_LOCALE || "en-US"
324
+ ),
325
+ format,
326
+ };
327
+
328
+ const voiceReference = getArg(args, "voice-reference", "voiceReference");
329
+ if (voiceReference) {
330
+ params.voiceReference = String(voiceReference);
331
+ } else {
332
+ params.voicePromptId = String(
333
+ getArg(args, "voice-prompt-id", "voicePromptId") ||
334
+ process.env.DEEPDUB_VOICE_PROMPT_ID ||
335
+ DEFAULT_VOICE_PROMPT_ID
336
+ );
337
+ }
338
+
339
+ const sampleRate = getArg(args, "sample-rate", "sampleRate");
340
+ if (sampleRate) params.sampleRate = Number(sampleRate);
341
+
342
+ const model = getArg(args, "model");
343
+ if (model) params.model = String(model);
344
+
345
+ const audio = await client.tts(String(text), params);
346
+ ensureDir(path.dirname(out));
347
+ fs.writeFileSync(out, audio);
348
+ console.log(`Generated ${out} (${audio.length} bytes)`);
349
+ }
350
+
351
+ async function voices(args) {
352
+ const { DeepdubClient } = loadDeepdubSdk();
353
+ const client = new DeepdubClient(apiKeyFromArgs(args), {
354
+ protocol: "http",
355
+ eu: Boolean(args.eu) || process.env.DD_EU === "1",
356
+ });
357
+ const response = await client.listVoices();
358
+ const voicesList = response.voicePrompts || [];
359
+
360
+ if (args.json) {
361
+ console.log(JSON.stringify(response, null, 2));
362
+ return;
363
+ }
364
+
365
+ for (const voice of voicesList) {
366
+ console.log(`${voice.id}: ${voice.name || voice.title || "Untitled"}`);
367
+ }
368
+ console.log(`\n${voicesList.length} voices`);
369
+ }
370
+
371
+ function doctor() {
372
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
373
+ console.log(`node: ${process.version}`);
374
+ console.log(
375
+ `skill: ${fs.existsSync(SKILL_SOURCE) ? "ok" : "missing"} (${SKILL_SOURCE})`
376
+ );
377
+ console.log(
378
+ `DEEPDUB_API_KEY: ${process.env.DEEPDUB_API_KEY ? "set" : "not set"}`
379
+ );
380
+ console.log(`Node 18+: ${nodeMajor >= 18 ? "ok" : "upgrade required"}`);
381
+
382
+ try {
383
+ require.resolve("@deepdub/node");
384
+ console.log("@deepdub/node: installed");
385
+ } catch (error) {
386
+ console.log("@deepdub/node: not installed yet");
387
+ }
388
+ }
389
+
390
+ async function main() {
391
+ const args = parseArgs(process.argv.slice(2));
392
+ const command = args._[0];
393
+
394
+ if (!command || command === "help" || args.help || args.h) {
395
+ printHelp();
396
+ return;
397
+ }
398
+
399
+ if (command === "install") {
400
+ install(args);
401
+ } else if (command === "scaffold") {
402
+ scaffold(args);
403
+ } else if (command === "tts") {
404
+ await tts(args);
405
+ } else if (command === "voices") {
406
+ await voices(args);
407
+ } else if (command === "doctor") {
408
+ doctor();
409
+ } else {
410
+ throw new Error(
411
+ `Unknown command "${command}". Run deepdub-agent-kit --help.`
412
+ );
413
+ }
414
+ }
415
+
416
+ main().catch((error) => {
417
+ console.error(`error: ${error.message}`);
418
+ process.exit(1);
419
+ });
@@ -0,0 +1,4 @@
1
+ DEEPDUB_API_KEY=dd-your-api-key
2
+ DEEPDUB_VOICE_PROMPT_ID=50a537cf-1ec8-4714-b07e-c589ab76be4b
3
+ DEEPDUB_LOCALE=en-US
4
+ DD_EU=0
@@ -0,0 +1,9 @@
1
+ {
2
+ "type": "module",
3
+ "scripts": {
4
+ "tts": "node ./tts.mjs"
5
+ },
6
+ "dependencies": {
7
+ "@deepdub/node": "^2.0.0"
8
+ }
9
+ }