{"_id":"@aethrekh/pisces-echo","name":"@aethrekh/pisces-echo","dist-tags":{"beta":"0.1.0-beta.0","latest":"0.1.0-beta.0"},"versions":{"0.1.0-beta.0":{"name":"@aethrekh/pisces-echo","version":"0.1.0-beta.0","description":"Echo — opt-in TTS for Pi sessions. Reads assistant responses aloud using platform system speech (no API key required).","keywords":["pi-package","pisces","echo","tts","voice"],"author":{"name":"Ashish Bagdane","email":"ashishbagdane1@gmail.com"},"license":"UNLICENSED","main":"dist/index.js","types":"dist/index.d.ts","publishConfig":{"access":"public"},"scripts":{"build":"tsc --project tsconfig.json","test":"jest","test:watch":"jest --watch","test:coverage":"jest --coverage","lint":"eslint src/**/*.ts","typecheck":"tsc --project tsconfig.json --noEmit","check":"pnpm run typecheck && pnpm run lint && pnpm run test:coverage"},"pi":{"extensions":["./dist/index.js"]},"peerDependencies":{"@earendil-works/pi-coding-agent":"*"},"devDependencies":{"@earendil-works/pi-coding-agent":"*","@earendil-works/pi-tui":"0.75.5"},"engines":{"node":">=18.0.0"},"repository":{"type":"git","url":"git+https://github.com/AshishBagdane/pisces.git"},"bugs":{"url":"https://github.com/AshishBagdane/pisces/issues"},"homepage":"https://github.com/AshishBagdane/pisces#readme","gitHead":"35e220e8a83a1632d3ea7d8a04a63e6adbd995ab","_id":"@aethrekh/pisces-echo@0.1.0-beta.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-LvREnAsceNzlr+IkOn1ZySXVm6PLEw0BeBIPlCU8eUce2bng8mt53WIxHpztazRs6RcBjOIbi5ObGVnNIAwk+A==","shasum":"14d02800245f430ccd09115cc651419acd3cd44d","tarball":"https://registry.npmjs.org/@aethrekh/pisces-echo/-/pisces-echo-0.1.0-beta.0.tgz","fileCount":21,"unpackedSize":36579,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG7dXy+SG+qJb3BEiHQxEoQOtWyGx3REbdsqRu7YuURIAiBsQ3iXKRWHPk8wHUEEDAkgTZRKMoQ0H/wHY79K7a1nGA=="}]},"_npmUser":{"name":"aethrekh","email":"tech@aethrekh.com"},"directories":{},"maintainers":[{"name":"aethrekh","email":"tech@aethrekh.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pisces-echo_0.1.0-beta.0_1787291879727_0.3074512397159783"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-21T05:57:59.540Z","0.1.0-beta.0":"2026-08-21T05:57:59.916Z","modified":"2026-08-21T05:58:00.062Z"},"maintainers":[{"name":"aethrekh","email":"tech@aethrekh.com"}],"description":"Echo — opt-in TTS for Pi sessions. Reads assistant responses aloud using platform system speech (no API key required).","homepage":"https://github.com/AshishBagdane/pisces#readme","keywords":["pi-package","pisces","echo","tts","voice"],"repository":{"type":"git","url":"git+https://github.com/AshishBagdane/pisces.git"},"author":{"name":"Ashish Bagdane","email":"ashishbagdane1@gmail.com"},"bugs":{"url":"https://github.com/AshishBagdane/pisces/issues"},"license":"UNLICENSED","readme":"# Echo\n\nOpt-in TTS layer for Pi sessions. Reads assistant responses aloud using the platform's built-in speech engine — no API key, no cloud service, no extra dependencies.\n\nDisabled by default. Enable with a `.echo.json` config file in your workspace or globally.\n\n## Installation\n\n```bash\npi install npm:@aethrekh/pisces-echo\n```\n\n## Quick start\n\nCreate `.echo.json` in your project root (or run `/echo --setup` for the interactive wizard):\n\n```json\n{ \"mode\": \"assist\", \"voice\": \"Samantha\", \"sounds\": true }\n```\n\nRestart Pi. Echo sets a status line and begins classifying responses.\n\n## Modes\n\n| Mode | What it speaks |\n|---|---|\n| `\"silent\"` | Nothing — no speech, no system prompt injection (default) |\n| `\"verbose\"` | Every assistant response, full text, markdown stripped |\n| `\"assist\"` | Only on: build/test completions, failures, confirmations, destructive operations |\n| `\"companion\"` | Assist + wins, notable observations, interesting patterns |\n\n`assist` and `companion` are LLM-driven: the model appends a hidden `<echo>` JSON block to every response classifying whether to speak and what to say. Echo strips the block before it reaches your terminal and fires TTS only when `speak: true`.\n\n`verbose` bypasses classification entirely — it speaks every response directly without any model involvement.\n\n## Config reference\n\n```jsonc\n{\n  \"mode\": \"assist\",      // \"silent\" | \"verbose\" | \"assist\" | \"companion\"\n  \"voice\": \"Samantha\",   // any voice name from `say -v ?`, or \"auto\" for system default\n  \"sounds\": true         // play a system sound cue before each spoken line\n}\n```\n\nConfig is loaded from the first file found in this order:\n\n1. `.echo.json` in the current workspace root\n2. `~/.pi/echo.json` (global default)\n\nIf neither exists, Echo defaults to `silent` — no audio, no injection.\n\n## Setup wizard\n\nRun `/echo --setup` (or just `/echo`) from any Pi session to launch the interactive wizard:\n\n1. **Voice picker** — scrollable list of installed English voices (`say -v ?`). Navigate with ↑/↓ and hear each voice speak a sample line as you scroll. Press Enter to confirm.\n2. **Mode picker** — four options, each speaks a characteristic sample phrase in your chosen voice.\n3. **Sounds toggle** — plays the actual sound cue so you know what you're opting into.\n4. **Write location** — always writes to `.echo.json` in the current workspace, then optionally to `~/.pi/echo.json` as a global default.\n\n## Platform support\n\n| Platform | TTS engine | Voice selection |\n|---|---|---|\n| macOS | `say` | Any voice from `say -v ?` (e.g. `Samantha`, `Daniel`, `Alex`) |\n| Linux | `espeak` | Voice name per espeak conventions (e.g. `en+f3`) |\n| Windows | PowerShell SAPI | `System.Speech.Synthesis.SpeechSynthesizer` |\n\nSpeech is fire-and-forget — Pi never blocks waiting for audio to finish. Sending a new message stops any in-progress speech.\n\nSystem sound cues:\n\n| Priority | macOS | Linux |\n|---|---|---|\n| `success` | `Glass.aiff` | `complete.oga` (if present) |\n| `error` | `Basso.aiff` | `dialog-error.oga` |\n| `warning` | `Purr.aiff` | `dialog-warning.oga` |\n| `info` | `Pop.aiff` | falls back silently |\n\n## How LLM classification works\n\nIn `assist` and `companion` modes, Echo appends a `[REQUIRED — Echo voice layer]` instruction to the system prompt. The model is told to append a structured JSON block at the end of every response:\n\n```\n<echo>{\"speak\":true,\"summary\":\"Build complete. No warnings.\",\"priority\":\"success\"}</echo>\n```\n\nEcho's `message_end` handler strips the block before it reaches your terminal. If `speak: true`, it fires the sound cue then calls `say` (or equivalent) with the `summary` text. Summaries are capped at 12 words by the model instruction — direct and characterful, not verbose.\n\nIf the model omits the block or produces malformed JSON, Echo silently no-ops. Use `verbose` mode if you need guaranteed audio without relying on model compliance.\n\n## Pi lifecycle hooks used\n\n| Hook | Action |\n|---|---|\n| `resources_discover` | Loads config via `event.cwd` — the workspace path |\n| `session_start` | Sets footer status: `echo: assist · Samantha` |\n| `before_agent_start` | Injects `<echo>` classification instruction (assist/companion only) |\n| `message_end` | Extracts `<echo>` block, strips from display, fires TTS |\n| `turn_start` | Stops any in-progress speech when user sends next message |\n| `session_shutdown` | Stops speech, clears config |\n","readmeFilename":"README.md","_rev":"1-bf68b7af692327cf9eb5b5cdef69594e"}