diff --git a/.claude/skills/verify/SKILL.md b/.claude/skills/verify/SKILL.md index 89a83b1b..9bb5b621 100644 --- a/.claude/skills/verify/SKILL.md +++ b/.claude/skills/verify/SKILL.md @@ -225,8 +225,8 @@ its profile. It keeps the vault and `.obsidian-e2e-artifacts/`. Delete - `.claude/skills/verify/net.mjs` runs as `watch`, `log` or `unwatch`. It logs every `fetch` and `requestUrl` call PodNotes makes, without query strings, - and answers ElevenLabs, Deepgram and OpenAI with a fixture provider while it - watches. + and answers ElevenLabs, Deepgram, OpenRouter and OpenAI with a fixture + provider while it watches. - `.claude/skills/verify/ui.mjs` sends trusted input through `obsidian dev:cdp`. Its verbs are `click [--text ] [--right]`, diff --git a/.claude/skills/verify/features/transcripts.md b/.claude/skills/verify/features/transcripts.md index 7914999a..3e772f95 100644 --- a/.claude/skills/verify/features/transcripts.md +++ b/.claude/skills/verify/features/transcripts.md @@ -18,6 +18,7 @@ from `Transcript template`, and opens. - `transcript-settings` shows `Transcription provider`, the chosen provider's API key row alone, `Model`, `Speaker labels` and, while those are on, `Speaker label format`. `Speaker labels` is disabled for a model without them. - `transcript-elevenlabs` writes timestamped paragraphs with numbered speakers from one `scribe_v3` request. ElevenLabs gets the address of an episode a saved public feed lists, and the audio itself for a private feed's episode, a local file, and an address that carries a credential or is not public. - `transcript-deepgram` does the same with `nova-3`. +- `transcript-openrouter` offers `Grok STT 2.0` (recommended), `ElevenLabs Scribe v2` and `MAI-Transcribe 2`, filtered by OpenRouter's public model catalog. Grok gets uploads as base64 JSON routed to xAI, Scribe v2 the address of a public episode, and an upload goes in parts of at most 18 MB and 1,800 s. - `transcript-openai` sends OpenAI the audio as `gpt-transcribe` uploads of at most 24 MB and 2,070 s, one at a time, and writes paragraphs without timestamps or speaker labels. - `transcript-existing` refuses a second run while the note exists. @@ -32,13 +33,13 @@ Preconditions: - `FEED=$(node .claude/skills/verify/fixtures.mjs transcripts)` prints `http://podnotes.test:/transcripts.xml`. Add `PodNotes Transcripts` through Settings as [feeds.md](./feeds.md) describes. Its episodes are `VTT Episode` (an HTML link, then a relative VTT link), `SRT Episode`, `JSON Episode`, `Untranscribed Episode` and `Broken Transcript Episode` (its VTT returns 404). - No `transcripts/PodNotes Transcripts/` notes exist yet. -- `NET=node .claude/skills/verify/net.mjs`. Run `$NET watch` before each command, and again after an `app:reload`, which drops it. While it watches, the fixture provider answers ElevenLabs, Deepgram and OpenAI, so nothing is charged even with a key set. -- A fake key is a precondition, not a user path. For ElevenLabs: `CLI eval code='app.secretStorage.setSecret("podnotes-elevenlabs-api-key-424242", "sk-verify-fixture-not-real"), app.plugins.plugins.podnotes.settings.elevenLabsSecretId = "podnotes-elevenlabs-api-key-424242", app.plugins.plugins.podnotes.saveSettings(), "key set"'`. Deepgram and OpenAI take `podnotes-deepgram-api-key-424242` in `deepgramSecretId` and `podnotes-openai-api-key-424242` in `openAISecretId`. +- `NET=node .claude/skills/verify/net.mjs`. Run `$NET watch` before each command, and again after an `app:reload`, which drops it. While it watches, the fixture provider answers ElevenLabs, Deepgram, OpenRouter (its model catalog too) and OpenAI, so nothing is charged even with a key set. +- A fake key is a precondition, not a user path. For ElevenLabs: `CLI eval code='app.secretStorage.setSecret("podnotes-elevenlabs-api-key-424242", "sk-verify-fixture-not-real"), app.plugins.plugins.podnotes.settings.elevenLabsSecretId = "podnotes-elevenlabs-api-key-424242", app.plugins.plugins.podnotes.saveSettings(), "key set"'`. Deepgram, OpenRouter and OpenAI take `podnotes-deepgram-api-key-424242` in `deepgramSecretId`, `podnotes-openrouter-api-key-424242` in `openRouterSecretId` and `podnotes-openai-api-key-424242` in `openAISecretId`. - Choose a provider in Settings by focusing the `Transcription provider` dropdown with `UI click` and stepping with `UI key ArrowDown` or `UI key ArrowUp`, or as a precondition with `CLI eval code='app.plugins.plugins.podnotes.settings.transcript.provider = "openai", app.plugins.plugins.podnotes.settings.transcript.model = "", app.plugins.plugins.podnotes.saveSettings(), "chosen"'`. - **Published.** Play `VTT Episode` ([player.md](./player.md)), then run `UI key Ctrl+p`, `UI type .prompt-input 'Transcribe current episode'` and `UI key Enter`. The exact command is the first suggestion; `--text 'Transcribe current episode'` matches both transcribe commands. The notices read `Queued "VTT Episode" for transcription. It will start automatically.` and, in the progress notice headed `Transcription: VTT Episode (00:00:00):`, `Saved the transcript the feed publishes.` `transcripts/PodNotes Transcripts/VTT Episode.md` opens. Its body starts `[00:00:00](obsidian://podnotes?episodeName=VTT%20Episode&url=...&time=0.48) From Potsdam in Brandenburg, Germany,`. `$NET log` lists `GET .../t/podnews.vtt` and nothing at `api.elevenlabs.io`, `api.deepgram.com` or `api.openai.com`. `node .claude/skills/verify/fixtures.mjs requests` has `/t/podnews.vtt`, not `/t/buzzcast.html`. Repeat with `SRT Episode` and `JSON Episode`. - **Seek.** Switch to Reading view and click a timestamp. `api.currentTime` lands on its time. -- **Settings.** Open Settings > PodNotes. Under `Transcripts` a new vault shows `Transcription provider` on `ElevenLabs`, `ElevenLabs API key`, `Model` on `Recommended (Scribe v3)`, `Speaker labels` on, `Speaker label format`, then the path and template. Choosing `Deepgram` or `OpenAI` swaps the key row for that provider's and the model list for its models. On `OpenAI` the `Speaker labels` row is disabled and reads `GPT Transcribe does not label speakers.` +- **Settings.** Open Settings > PodNotes. Under `Transcripts` a new vault shows `Transcription provider` on `ElevenLabs`, `ElevenLabs API key`, `Model` on `Recommended (Scribe v3)`, `Speaker labels` on, `Speaker label format`, then the path and template. Choosing `Deepgram`, `OpenRouter` or `OpenAI` swaps the key row for that provider's and the model list for its models. On `OpenRouter` the `Model` row offers `Recommended (Grok STT 2.0)`, `Grok STT 2.0`, `ElevenLabs Scribe v2` and `MAI-Transcribe 2`, and `$NET log` shows one `GET https://openrouter.ai/api/v1/models` with no `Authorization`. A model the catalog dates reads `