From 9a833d5ab1402f21aee7622b1d27bf6ed054f7b6 Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Wed, 8 Apr 2026 17:40:12 +0100 Subject: [PATCH 1/3] docs: add AGENTS.md and CLAUDE.md for AI agent guidance Closes #34 --- AGENTS.md | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 1 + 2 files changed, 111 insertions(+) create mode 100644 AGENTS.md create mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9e7872d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,110 @@ +# js-tts-wrapper — AI Agent Development Guide + +## Project Overview + +js-tts-wrapper is a unified TypeScript/JavaScript TTS library that abstracts 14+ cloud and local providers (Azure, Google, Polly, ElevenLabs, OpenAI, PlayHT, Watson, WitAI, UpliftAI, ModelsLab, SherpaONNX, eSpeak, SAPI). It targets both Node.js and browser environments. + +**Key Technologies:** +- TypeScript +- Rollup (browser bundle), tsc (CJS/ESM) +- Jest (unit tests) +- Biome (lint/format — `src/utils`, `src/ssml`, `src/markdown` only) + +## Project Structure + +``` +src/ +├── core/ # AbstractTTSClient base class, playback, SSML utils +├── engines/ # One file per provider (azure.ts, elevenlabs.ts, etc.) +├── ssml/ # Fluent SSML builder +├── utils/ # Audio conversion, fetch, environment detection +├── factory.ts # createTTSClient() factory (Node) +├── factory-browser.ts# createBrowserTTSClient() factory (browser) +├── browser.ts # Browser entry point +├── index.ts # Main entry point +└── types.ts # Shared interfaces (SpeakOptions, UnifiedVoice, etc.) + +__tests__/ # Jest unit tests +test/ # Engine integration tests (require credentials) +scripts/ # Build, packaging, and setup scripts +examples/ # Usage examples +dist/ # Compiled output (do not edit) +``` + +## Adding a New Engine + +1. Create `src/engines/.ts` — extend `AbstractTTSClient` +2. Define credential and options interfaces (extend `TTSCredentials` and `SpeakOptions`) +3. Set `this.capabilities = { browserSupported: true/false, nodeSupported: true/false }` +4. Implement required abstract methods: `synthToBytes()`, `synthToBytestream()`, `_getVoices()` +5. Add the engine to `factory.ts`, `factory-browser.ts`, and `src/browser.ts` exports +6. Add engine type to the `SupportedTTS` union in `src/types.ts` + +## Browser Safety + +Never use static `import('node:...')` in code that ends up in the browser bundle. Use the `new Function` pattern to hide dynamic Node.js imports from bundlers: + +```ts +// Wrong — breaks Turbopack/Vite +const fs = await import(`node:${name}`); + +// Correct — opaque to static analysis +const fs = await (new Function('m', 'return import(m)'))('node:fs'); +``` + +Guard Node.js-only code paths with `typeof window !== 'undefined'` checks. + +## Development Workflow + +### 1. Issue Creation +Every piece of work starts with a GitHub issue. + +### 2. Branch Strategy +Create a branch from `main` referencing the issue number: +```bash +git checkout -b feat/42-new-engine-name +``` + +### 3. Build & Test +```bash +npm run build # Full build (CJS + ESM + browser bundle) +npm run lint # Biome lint +npm run test # Jest unit tests +``` + +Ensure `npm run build` passes before opening a PR. + +### 4. Pull Request +- PR against `main` +- Reference the issue number in the PR description + +### 5. Release Process +Maintainers release by bumping the version locally and pushing the tag: +```bash +npm version patch # or minor / major +git push --follow-tags +``` + +## Key Interfaces + +```ts +// Core base class — all engines extend this +AbstractTTSClient // src/core/abstract-tts.ts + +// Shared types +SpeakOptions // rate, pitch, volume, format, rawSSML +UnifiedVoice // id, name, gender, language, ... +TTSCredentials // base credentials type +WordBoundaryCallback +``` + +## Build Outputs + +| Format | Location | Use | +|--------|----------|-----| +| CJS | `dist/cjs/` | Node.js `require()` | +| ESM | `dist/esm/` | Node.js `import`, bundlers | +| Browser bundle | `dist/js-tts-wrapper.browser.js` | Browser UMD | +| Types | `dist/*.d.ts` | TypeScript | + +Publishing happens from `dist/` (see `scripts/package.cjs`). diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md From af6396a1b7a597b7d715f4ae7d638b19bcb09fd6 Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Wed, 8 Apr 2026 17:44:08 +0100 Subject: [PATCH 2/3] docs: document current release process in AGENTS.md --- AGENTS.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9e7872d..828695d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,11 +79,9 @@ Ensure `npm run build` passes before opening a PR. - Reference the issue number in the PR description ### 5. Release Process -Maintainers release by bumping the version locally and pushing the tag: -```bash -npm version patch # or minor / major -git push --follow-tags -``` +1. Bump `package.json` version and commit to `main` +2. Create a GitHub Release via the UI (or `gh release create vX.Y.Z --title vX.Y.Z --generate-notes`) +3. The `Test and Publish` workflow triggers on the release event, runs tests, then publishes to npm via OIDC trusted publishing ## Key Interfaces From c3b0f22ec055082b1e0424734ef7c4be740a9db3 Mon Sep 17 00:00:00 2001 From: Owen McGirr Date: Wed, 8 Apr 2026 17:45:20 +0100 Subject: [PATCH 3/3] docs: fix release process description in AGENTS.md --- AGENTS.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 828695d..7736e0e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -79,9 +79,8 @@ Ensure `npm run build` passes before opening a PR. - Reference the issue number in the PR description ### 5. Release Process -1. Bump `package.json` version and commit to `main` -2. Create a GitHub Release via the UI (or `gh release create vX.Y.Z --title vX.Y.Z --generate-notes`) -3. The `Test and Publish` workflow triggers on the release event, runs tests, then publishes to npm via OIDC trusted publishing +1. Create a GitHub Release with a version tag (e.g. `gh release create v0.1.73 --title v0.1.73 --generate-notes`) +2. The `Test and Publish` workflow triggers on the release event, runs tests, publishes to npm via OIDC trusted publishing, then commits the version bump back to `main` automatically ## Key Interfaces