diff --git a/.claude/settings.local.json b/.claude/settings.local.json
new file mode 100644
index 0000000..74dfd0a
--- /dev/null
+++ b/.claude/settings.local.json
@@ -0,0 +1,6 @@
+{
+ "enabledMcpjsonServers": [
+ "obsidian"
+ ],
+ "enableAllProjectMcpServers": true
+}
diff --git a/.gitignore b/.gitignore
index 3dddcdf..3cd4dc3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,6 +21,7 @@ src-tauri/gen/
.env.*
!.env.example
*.local
+.mcp.json
# OS/editor
.DS_Store
@@ -32,3 +33,4 @@ Thumbs.db
# Superpowers local worktrees
.worktrees/
worktrees/
+.opencode
diff --git a/.impeccable.md b/.impeccable.md
new file mode 100644
index 0000000..6c079ff
--- /dev/null
+++ b/.impeccable.md
@@ -0,0 +1,17 @@
+## Design Context
+
+### Users
+Pessoas que escrevem no computador e precisam transformar fala em texto rápido: criadores, profissionais, estudantes e usuários que alternam entre apps de edição, chat, navegador e documentos. O contexto principal é desktop, com foco em velocidade, ditado por atalho global e baixa fricção.
+
+### Brand Personality
+Premium, silencioso e preciso. A interface deve parecer uma ferramenta de produtividade de alto nível: discreta enquanto ouve, confiável quando insere texto, clara quando precisa de revisão.
+
+### Aesthetic Direction
+Dark-first, overlay-first, inspirado em produtividade premium tipo Superhuman: superfícies profundas, tipografia compacta, brilho violeta controlado, creme quente como acento, nada genérico ou “AI dashboard”. O app deve parecer um instrumento de escrita, não um painel técnico.
+
+### Design Principles
+1. Overlay é o produto: a experiência principal é compacta, flutuante e focada em ação imediata.
+2. Configurações devem ser explícitas: Whisper integrado vs Docker/API precisa ser impossível de confundir.
+3. Visual premium sem peso: preferir CSS, SVG e microinterações nativas a bibliotecas pesadas.
+4. Hierarquia acima de decoração: cada cor, borda e animação deve comunicar estado ou foco.
+5. Segurança do texto: se inserção automática não for confiável, preservar e revelar revisão editável.
diff --git a/.impeccable/critique/2026-07-11T18-50-55Z__src-app-ts.md b/.impeccable/critique/2026-07-11T18-50-55Z__src-app-ts.md
new file mode 100644
index 0000000..b049902
--- /dev/null
+++ b/.impeccable/critique/2026-07-11T18-50-55Z__src-app-ts.md
@@ -0,0 +1,83 @@
+---
+target: src/app.ts + src/styles.css
+total_score: 23
+p0_count: 0
+p1_count: 4
+timestamp: 2026-07-11T18-50-55Z
+slug: src-app-ts
+---
+Method: degraded single-context (no sub-agent tool exposed; browser automation unavailable)
+
+# Design critique — src/app.ts + src/styles.css
+
+## Design Health Score
+
+| # | Heuristic | Score | Key issue |
+|---|-----------|-------|-----------|
+| 1 | Visibility of System Status | 3 | Status exists, but visual priority competes with actions. |
+| 2 | Match System / Real World | 2 | Settings copy mixes user language with API/model jargon. |
+| 3 | User Control and Freedom | 2 | Modal has close/cancel, but no Escape handling found. |
+| 4 | Consistency and Standards | 2 | Many button/control styles and decorative effects for one small tool. |
+| 5 | Error Prevention | 2 | Validation exists; settings still exposes too many easy-to-misconfigure fields. |
+| 6 | Recognition Rather Than Recall | 2 | Icon compact buttons are accessible, but visually require recognition/hover/title memory. |
+| 7 | Flexibility and Efficiency | 3 | Hotkey and compact dictation flow are strong. |
+| 8 | Aesthetic and Minimalist Design | 1 | Heavy gradients, glow, blur, shadows, and ambient decoration fight the minimal goal. |
+| 9 | Error Recovery | 3 | Inline modal errors and focus recovery are good. |
+| 10 | Help and Documentation | 1 | Little contextual help for Docker/API, insertion mode, or failures. |
+| Total | | 23/40 | Acceptable, but visually overworked. |
+
+## Anti-patterns verdict
+
+LLM assessment: the interface has a recognizable AI-era dark glass look: violet ambient orbs, radial gradients, glow pills, blurred panels, rounded cards, and many icon buttons. The core product is a transcription utility; it should feel calm, direct, and task-first.
+
+Deterministic scan: `detect.mjs --json src` returned `[]`. No bundled Impeccable detector issues.
+
+Browser evidence: skipped; no browser automation package/MCP available in this session.
+
+## What works
+
+- Core workflow is small: record, edit, copy/insert/save/clear.
+- Recent accessibility work helped: modal focus trap, inert, visible labels, reduced motion, inline errors.
+- Dictation overlay/review is a good product idea and should stay, but quieter.
+
+## Priority issues
+
+### P1 — CSS height syntax is broken
+`src/styles.css:52-53` has `height: 100dvh` without a semicolon before `min-height`. This can invalidate sizing and risks reviving the window-collapse bug.
+
+Fix: make it two clean declarations.
+
+### P1 — The visual system is too decorative for a utility
+Metrics: `src/styles.css` has 1373 lines, 174 selectors, 18 gradients, 8 backdrop-filter references, 15 box-shadows, and ambient animated decoration. For a small desktop transcription tool, this is visual noise.
+
+Fix: remove ambient orbs/grid, most radial gradients, most shadows, and glass blur. Use flat surfaces, one border, one accent.
+
+### P1 — Primary screen hierarchy is crowded
+The main screen has status, record, four compact action buttons, message, secondary actions, editor, diagnostics. Many elements have similar weight, so the primary job—record and review text—does not dominate.
+
+Fix: keep one primary action, move rare actions into a small overflow/menu or footer row, make the editor the main object.
+
+### P1 — Settings modal exposes implementation detail too early
+Mode, endpoint, model, API key, hotkey, insertion, privacy are all in one modal. This feels like a developer config panel, not a minimal product UI.
+
+Fix: split into three plain groups: Recording, Output, Advanced. Hide endpoint/model under Advanced unless Docker/API is chosen.
+
+### P2 — Frontend is hard to reshape safely
+`src/app.ts` is 1367 lines and `src/styles.css` is 1373 lines. Design changes require editing a large procedural DOM file and a large global stylesheet.
+
+Fix: minimal split only: `Topbar`, `EditorPane`, `SettingsDialog`, `DictationOverlay`, plus `tokens.css`.
+
+### P2 — Product copy should be calmer and less technical
+Examples: `Docker / API`, `Endpoint`, `Modelo no servidor`, `api_key`, `Whisper integrado`. Good for developers, rough for normal users.
+
+Fix: use user-facing labels first, technical details second: “Transcrição local”, “Servidor local”, “Chave da API”, “Modelo”.
+
+## Persona red flags
+
+- Alex, power user: wants speed; compact hotkey helps, but action clutter slows scanning.
+- Jordan, first-timer: sees Docker/API/model/endpoint and may not know what is safe to touch.
+- Sam, keyboard/screen-reader user: core fixes are good, but modal should support Escape and visible grouping should be simpler.
+
+## Recommended direction
+
+Make the app quiet: dark flat shell, one accent, editor-first layout, fewer controls visible, settings simplified. Do not add a design system framework or dependency.
diff --git a/.openclaude/settings.local.json b/.openclaude/settings.local.json
new file mode 100644
index 0000000..a2b8ac1
--- /dev/null
+++ b/.openclaude/settings.local.json
@@ -0,0 +1,8 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(rtk git:*)",
+ "mcp__plugin_context-mode_context-mode__ctx_search"
+ ]
+ }
+}
diff --git a/.pi/settings.json b/.pi/settings.json
new file mode 100644
index 0000000..b7f82c6
--- /dev/null
+++ b/.pi/settings.json
@@ -0,0 +1,27 @@
+{
+ "hud": {
+ "mode": "footer",
+ "position": "top-right",
+ "shortcut": "ctrl+shift+h",
+ "switchShortcut": "ctrl+.",
+ "minimizeShortcut": "ctrl+h",
+ "autoCompactWhileStreaming": true,
+ "startupNotification": true,
+ "usageDisplay": "metered",
+ "contextIndicator": "icon",
+ "expandedWidth": 42,
+ "compactWidth": 26,
+ "minTerminalWidth": 90,
+ "margin": {
+ "top": 1,
+ "right": 1,
+ "bottom": 1
+ },
+ "visibility": {
+ "context": true,
+ "project": true,
+ "worktrees": true,
+ "mcps": true
+ }
+ }
+}
diff --git a/README.md b/README.md
index aa84172..2d37563 100644
--- a/README.md
+++ b/README.md
@@ -1,96 +1,230 @@
-# Transcript Desktop
+
+
+
-Aplicativo desktop de transcrição para Windows e Linux, construído com Tauri + Rust + TypeScript. O objetivo é oferecer ditado/transcrição offline-first com revisão obrigatória em modal antes de inserir texto em outro aplicativo.
+
Transcript
-## Estado atual
+
+ Um app desktop rápido para ditado local, transcrição e inserção automática de texto em qualquer lugar.
+
-Este repositório contém um MVP nativo funcional:
+
+
+
+
+
+
+
-- app Tauri 2 funcional;
-- modal editável em TypeScript sem framework pesado;
-- backend Rust modular;
-- catálogo e download do modelo `cstr/parakeet-tdt-0.6b-v3-GGUF` em Q8;
-- captura real de microfone em WAV via CPAL;
-- execução do sidecar CrispASR/Parakeet;
-- hotkey global `Ctrl+Shift+Space`;
-- inserção híbrida por clipboard + paste automático no Windows/X11 quando disponível;
-- fallback manual no Wayland;
-- tray/system tray básico;
-- CI, build e release via GitHub Actions.
+---
+
+## Por que este projeto existe?
+
+Digitar tudo manualmente é lento. A ideia do **Transcript** nasceu de uma frustração bem prática: muitos fluxos de trabalho exigem escrever o tempo todo — mensagens, prompts, documentos, tickets, código, respostas — mas os recursos nativos de ditado nem sempre entregam velocidade, precisão ou flexibilidade suficientes.
+
+A transcrição nativa do Windows, por exemplo, pode ser útil, mas ainda deixa a desejar quando você quer um fluxo realmente ágil: apertar um atalho global, falar naturalmente e ver o texto aparecer no campo em que você já estava digitando.
+
+O **Transcript** resolve esse problema com um fluxo direto:
+
+```text
+atalho global → fala → transcrição rápida → texto inserido no app em foco
+```
+
+Ele foi desenhado para quem quer escrever com a voz sem depender de interfaces pesadas, janelas grandes ou cópia manual constante.
+
+---
+
+## O que o Transcript faz
+
+O Transcript é um aplicativo desktop para Windows e Linux construído com **Tauri 2**, **Rust** e **TypeScript**. Ele grava sua voz, transcreve localmente com **whisper.cpp base multilingual** por padrão e insere o texto diretamente onde o cursor estava. APIs compatíveis com OpenAI continuam disponíveis como opção.
+
+### Principais recursos
+
+- **Hotkey global** — por padrão `Ctrl+Shift+Space`.
+- **Ditado em qualquer aplicativo** — navegador, editor, chat, terminal, IDE ou campo de texto.
+- **Overlay flutuante compacto** — uma barra inferior com waveform enquanto você fala.
+- **Transcrição local embutida** — inclui `whisper.cpp` + `ggml-base.bin` multilingual, com suporte a PT-BR sem Docker/API.
+- **API key opcional** — endpoints locais não precisam de chave; provedores externos podem usar chave salva com segurança.
+- **Credential Manager** — a chave nunca é salva em texto claro.
+- **Normalização com IA** — corrige erros comuns de transcrição sem mudar o significado.
+- **Engenharia de prompt** — normaliza a entrada e gera um prompt estruturado, adaptado ao domínio e à jurisdição explicitamente informada.
+- **Provedores de texto** — presets para OpenAI e Anthropic, além de endpoint customizado nos dois formatos.
+- **Inserção automática** — copia para o clipboard e tenta acionar `Ctrl+V` no app em foco.
+- **Fallback seguro** — se não conseguir inserir automaticamente, mantém o texto no clipboard.
+- **UI dark glass/acrylic** — interface compacta, frameless, sempre no topo e focada em velocidade.
+- **Health check antes de transcrever** — detecta API offline ou modelo inexistente antes de deixar o usuário esperando.
+
+---
+
+## Fluxo de uso
+
+1. Posicione o cursor em qualquer campo de texto.
+2. Pressione `Ctrl+Shift+Space`.
+3. Fale naturalmente.
+4. Pressione `Ctrl+Shift+Space` novamente.
+5. O Transcript transcreve e tenta inserir o texto automaticamente.
+
+Se a inserção automática não for possível, o texto fica no clipboard para você colar manualmente.
+
+---
+
+## Configuração recomendada
+
+Por padrão, o app funciona localmente com Whisper Base multilingual embutido. Para usar Docker, Parakeet/Speaches ou um provedor remoto, configure uma API compatível com OpenAI:
+
+```text
+POST /v1/audio/transcriptions
+```
+
+Configuração local recomendada:
+
+```text
+Endpoint: http://localhost:8022/v1/audio/transcriptions
+Modelo: alefiury/parakeet-tdt-0.6b-v3-ptBR-TAGARELA-onnx
+Idioma: pt
+api_key: deixe em branco se o servidor local não exigir autenticação
+```
+
+Também funciona com provedores remotos compatíveis com OpenAI, incluindo o endpoint oficial:
+
+```text
+https://api.openai.com/v1/audio/transcriptions
+```
+
+### Assistente de texto
+
+Em **Configurações → Assistente de texto**, escolha OpenAI, Anthropic ou um endpoint customizado, informe o modelo e salve a chave. No editor, alterne entre **Normalizar** e **Criar prompt** e clique no botão de IA. O resultado substitui o texto do editor para poder ser revisado, copiado, salvo ou inserido.
+
+Endpoints customizados aceitam os formatos OpenAI Chat Completions e Anthropic Messages. A chave é opcional para endpoints customizados locais sem autenticação.
+
+---
+
+## Privacidade e segurança
+
+- Áudios são enviados apenas para o endpoint que você configurar.
+- Servidores locais permitem manter o fluxo dentro da sua máquina/rede.
+- `api_key` é armazenada no Credential Manager do sistema operacional.
+- O app não grava chaves em arquivos `.env`, JSON ou texto claro.
+- Textos só são enviados ao provedor quando o usuário aciona **Normalizar texto** ou **Criar prompt**.
+- Cada chave do assistente fica no Credential Manager e só é devolvida à interface após o usuário clicar em **Mostrar**.
+- A inserção de texto usa clipboard + paste automático; se falhar, o texto permanece no clipboard.
+
+---
## Arquitetura
```text
-src/ Frontend TypeScript/CSS
+src/
+ app.ts Interface TypeScript sem framework pesado
+ styles.css UI dark glass/acrylic + overlay de ditado
+
src-tauri/src/
- audio/ Captura de microfone e gravação WAV
- transcription/ Contratos, CrispASR sidecar e API compatível com OpenAI
- injection/ Clipboard, paste automático e fallback manual
- models/ Catálogo do modelo offline
- settings/ Configuração padrão
- tray.rs Menu da bandeja do sistema
- ui_commands.rs Comandos Tauri expostos ao frontend
- app_state.rs Estado compartilhado mínimo
+ audio/ Captura de microfone e escrita WAV via CPAL + hound
+ transcription/ Cliente OpenAI-compatible multipart/form-data
+ text_processing.rs Normalização e engenharia de prompt via OpenAI/Anthropic
+ injection/ Clipboard, Ctrl+V automático e fallback manual
+ secrets.rs Integração com Credential Manager via keyring
+ shortcuts.rs Hotkey global
+ ui_commands.rs Comandos Tauri e fluxo nativo de ditado
+ app_state.rs Estado compartilhado da aplicação
+ tray.rs System tray
+
+assets/brand/
+ logo.png Logo oficial do projeto
+ logo-*.png Derivações em PNG
+
+src-tauri/icons/
+ icon.ico Ícone oficial do app/instalador Windows
```
-A regra de design é manter arquivos pequenos, responsabilidades claras e zero overengineering. O app começa com contratos e stubs explícitos para as partes nativas mais arriscadas.
+---
-## Modelo offline principal
+## Desenvolvimento local
-- Repositório: `cstr/parakeet-tdt-0.6b-v3-GGUF`
-- Arquivo: `parakeet-tdt-0.6b-v3-q8_0.gguf`
-- Quantização: `Q8_0`
-- Tamanho registrado no catálogo: `745121600` bytes
-- Modelo base: NVIDIA Parakeet TDT 0.6B v3
-- Idioma: detecção automática; português incluído no conjunto suportado pelo modelo base.
+Pré-requisitos:
-O modelo não deve ser embutido no instalador principal. A estratégia recomendada é instalar o app leve e baixar o GGUF pelo gerenciador de modelos.
+- Node.js
+- npm
+- Rust stable
+- Dependências do Tauri 2 para o seu sistema operacional
-## Sidecar CrispASR
-
-O app chama por padrão o binário `parakeet-main` com:
-
-```bash
-parakeet-main -m -f -t
-```
-
-Para o modelo v3, o projeto CrispASR recomenda compilar o target `parakeet-main` no branch `parakeet`. O app limita automaticamente o número de threads a no máximo 4 para manter compatibilidade com PCs simples.
-
-Enquanto o binário não estiver no `PATH` ou empacotado como sidecar, a transcrição local retorna erro claro após a gravação.
-
-## Compatibilidade Windows/Linux
-
-- Windows: clipboard + tentativa de `Ctrl+V` via `SendKeys`.
-- Linux X11: clipboard + tentativa de `Ctrl+V` via `xdotool` quando instalado.
-- Linux Wayland: suporte parcial por limitação de segurança dos compositors. O fallback seguro é copiar o texto e orientar o usuário a colar manualmente.
-
-## Comandos locais
+Instalação:
```bash
npm install
+```
+
+Rodar em modo desenvolvimento:
+
+```bash
+npm run tauri:dev
+```
+
+Validação:
+
+```bash
npm run typecheck
npm run test -- --run
-npm run build
cargo test --manifest-path src-tauri/Cargo.toml
+```
+
+Build frontend:
+
+```bash
+npm run build
+```
+
+---
+
+## Gerar instalador Windows
+
+```bash
npm run tauri:build
```
-## CI/CD
+Artefatos gerados:
-Workflows:
+```text
+src-tauri/target/release/bundle/nsis/Transcript_0.1.0_x64-setup.exe
+src-tauri/target/release/bundle/msi/Transcript_0.1.0_x64_en-US.msi
+```
-- `.github/workflows/ci.yml`: valida PRs e pushes em `main`.
-- `.github/workflows/build.yml`: gera bundles Windows/Linux em push para `main` e manualmente.
-- `.github/workflows/release.yml`: publica GitHub Releases em tags `v*.*.*`.
+Use o instalador NSIS para uso diário enquanto novas versões são desenvolvidas.
-A lógica fica em comandos npm/cargo para facilitar migração futura para GitLab CI.
+---
-## Fontes técnicas usadas
+## Estado atual
-- Tauri 2 commands: https://v2.tauri.app/develop/calling-rust
-- Tauri 2 system tray: https://v2.tauri.app/learn/system-tray
-- Tauri 2 sidecars: https://v2.tauri.app/develop/sidecar
-- Tauri GitHub pipelines: https://v2.tauri.app/distribute/pipelines/github
-- Tauri Linux prerequisites: https://v2.tauri.app/start/prerequisites
-- NVIDIA Parakeet v3 model card: https://huggingface.co/nvidia/parakeet-tdt-0.6b-v3/blob/main/README.md
-- cstr Parakeet GGUF: https://huggingface.co/cstr/parakeet-tdt-0.6b-v3-GGUF
+O projeto já possui:
+
+- gravação real de microfone;
+- transcrição local embutida com whisper.cpp base multilingual;
+- transcrição opcional via API compatível com OpenAI;
+- hotkey global;
+- overlay compacto de ditado;
+- health check de endpoint/modelo;
+- normalização e engenharia de prompt com OpenAI, Anthropic ou endpoint customizado;
+- inserção automática por clipboard + paste;
+- fallback manual;
+- app Windows sem terminal visível no build release;
+- ícone oficial no instalador e no app.
+
+---
+
+## Roadmap
+
+Ideias futuras:
+
+- rename completo para uma marca final, como **TypeVoz**;
+- seletor de modelos no app;
+- presets para provedores locais/remotos;
+- histórico de transcrições;
+- restauração segura do clipboard anterior;
+- waveform reativo ao volume real do microfone;
+- empacotamento e release automatizado.
+
+---
+
+## Licença
+
+Projeto em desenvolvimento. Defina a licença antes de publicar o repositório publicamente.
diff --git a/assets/brand/logo-128.png b/assets/brand/logo-128.png
new file mode 100644
index 0000000..f20e425
Binary files /dev/null and b/assets/brand/logo-128.png differ
diff --git a/assets/brand/logo-256.png b/assets/brand/logo-256.png
new file mode 100644
index 0000000..c7c118d
Binary files /dev/null and b/assets/brand/logo-256.png differ
diff --git a/assets/brand/logo-512.png b/assets/brand/logo-512.png
new file mode 100644
index 0000000..9ceafc7
Binary files /dev/null and b/assets/brand/logo-512.png differ
diff --git a/assets/brand/logo-64.png b/assets/brand/logo-64.png
new file mode 100644
index 0000000..956af8c
Binary files /dev/null and b/assets/brand/logo-64.png differ
diff --git a/assets/brand/logo.png b/assets/brand/logo.png
new file mode 100644
index 0000000..f81fbc3
Binary files /dev/null and b/assets/brand/logo.png differ
diff --git a/assets/brand/mark-128.png b/assets/brand/mark-128.png
new file mode 100644
index 0000000..1ae60fc
Binary files /dev/null and b/assets/brand/mark-128.png differ
diff --git a/assets/brand/mark-256.png b/assets/brand/mark-256.png
new file mode 100644
index 0000000..a6c8caf
Binary files /dev/null and b/assets/brand/mark-256.png differ
diff --git a/assets/brand/mark-512.png b/assets/brand/mark-512.png
new file mode 100644
index 0000000..d5f110f
Binary files /dev/null and b/assets/brand/mark-512.png differ
diff --git a/assets/brand/mark-64.png b/assets/brand/mark-64.png
new file mode 100644
index 0000000..77184f6
Binary files /dev/null and b/assets/brand/mark-64.png differ
diff --git a/assets/brand/mark.png b/assets/brand/mark.png
new file mode 100644
index 0000000..4a00575
Binary files /dev/null and b/assets/brand/mark.png differ
diff --git a/design/transcript-design-exploration-v2.html b/design/transcript-design-exploration-v2.html
new file mode 100644
index 0000000..7106c12
--- /dev/null
+++ b/design/transcript-design-exploration-v2.html
@@ -0,0 +1,1878 @@
+
+
+
+
+
+ Transcript — Redesign v2
+
+
+
+
+
+
+
+
+
Redesign v2 · Impeccable pass
+
+ Agora são direções diferentes, não seis skins do mesmo layout.
+
+
+ O clone fiel continua como baseline. As outras seis propostas foram
+ reconstruídas em torno de modelos mentais diferentes: comando
+ nativo, ilha de ditado, mesa editorial, motor local, HUD radial e
+ pilha física de estados.
+
+ Clone atual + 6 direções para decidir sem retrabalho.
+
+
+ O primeiro painel é uma reprodução fiel do design atual do
+ aplicativo. Os outros seis são propostas de evolução, mantendo o
+ produto compacto, escuro, rápido e coerente com o logo/mark atual.
+
+
+
+
+
+
+
+
+
+
00 · Clone atual, sem reinterpretar.
+
+ Reprodução do app atual: janela 380×460, topbar frameless, marca
+ circular, painel principal translúcido, botão de gravação âmbar,
+ ações em grid, editor expansível e overlay de ditado. Esta versão
+ serve como baseline visual para comparação.
+
+
+
+ FidelidadeCores, raios, pesos, espaçamentos e hierarquia copiados do CSS
+ atual.
+
+
+ EstadosUse os botões de estado para conferir texto, overlay e
+ configurações.
+
+
+ MarcaUsa o mesmo mark transparente que está na UI atual.
+
+
+ DecisãoEscolha esta opção se quisermos apenas ajustes cirúrgicos sem
+ redesign.
+
+
+
+
+
+
+
+
+
01 · Satin refinement.
+
+ Mesma estrutura do app atual, mas com refinamento de densidade,
+ melhor contraste de cards e uma área de texto mais “produto
+ premium”. É a evolução mais segura: quase sem risco de quebrar fluxo
+ mental do usuário.
+
+
+
+ Melhor escolhaRecomendado se queremos subir qualidade sem mudar o
+ comportamento.
+
+
+ UXMenos ruído, hierarquia de status mais clara e botões mais
+ previsíveis.
+
+
+ ImplementaçãoBaixo esforço: reaproveita a estrutura atual com tokens
+ melhores.
+
+
+ RiscoMuito baixo; mantém o app compacto e familiar.
+
+
+
+
+
+
+
+
+
02 · Command deck.
+
+ Direção mais “power user”: parece uma ferramenta nativa para quem
+ usa atalho o tempo todo. Traz status técnico local/API de forma
+ discreta e deixa o botão de ditado como comando principal.
+
+
+
+ TomTerminal premium, técnico, rápido, ideal para app de
+ produtividade.
+
+
+ ClarezaÓtimo para mostrar local/offline, latência e modelo ativo sem
+ poluir.
+
+
+ UXFavorece usuários avançados e atalhos globais.
+
+
+ RiscoVisual menos “macio”; pode parecer mais developer tool.
+
+
+
+
+
+
+
+
+
03 · Aurora dictation.
+
+ Mais emocional e memorável: transforma o ato de gravar em foco
+ central, com orb grande, marca forte e sensação de áudio vivo. Bom
+ se quisermos que o app pareça mais “AI assistant” e menos
+ utilitário.
+
+
+
+ ImpactoVisual mais marcante para screenshots, README e
+ marketing.
+
+
+ InteraçãoO estado de gravação fica impossível de não perceber.
+
+
+ MarcaA marca vira elemento central sem virar “cartão branco”.
+
+
+ RiscoMais mudança de layout, exige cuidado para não parecer
+ decorativo demais.
+
+
+
+
+
+
+
+
+
04 · Studio paper.
+
+ Uma direção clara e editorial: menos glass, mais leitura, mais
+ “documento”. É a melhor se o foco principal for revisar e editar o
+ texto transcrito com conforto, mantendo um contraste elegante.
+
+
+
+ LeituraExcelente para textos longos e revisão pós-transcrição.
+
+
+ ContrasteModo claro controlado, útil para acessibilidade e uso
+ diurno.
+
+
+ PersonalidadeMenos comum no ecossistema de apps de AI, mais editorial.
+
+
+ RiscoAfasta do dark glass atual; pode parecer outro produto.
+
+
+
+
+
+
+
+
+
05 · Local core.
+
+ Design orientado ao novo diferencial do app: transcrição local
+ embutida. Mostra claramente que há um modelo offline, latência
+ esperada e fallback de API, sem transformar isso em painel técnico
+ demais.
+
+
+
+ ProdutoComunica “sem Docker/API” como valor principal do app.
+
+
+ ConfiançaAjuda o usuário a saber se está usando local, API ou
+ fallback.
+
+
+ UXBom para onboarding e redução de suporte.
+
+
+ RiscoMais informação na tela; precisa manter modo compacto.
+
+
+
+
+
+
+
+
+
06 · Overlay first.
+
+ Direção baseada no caso de uso principal: apertar atalho em qualquer
+ app, ditar e inserir. Em vez de pensar primeiro na janela principal,
+ esta versão prioriza a barra flutuante como “produto principal”.
+
+
+
+ HotkeyO fluxo global fica mais claro, elegante e menos
+ intrusivo.
+
+
+ FocoIdeal para usuários que quase nunca abrem a janela
+ completa.
+
+
+ PolimentoOverlay vira assinatura visual do app.
+
+
+ RiscoNão resolve sozinho a tela de configurações/editor; precisa
+ combinar com outra direção.
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/development-pipeline.md b/docs/development-pipeline.md
new file mode 100644
index 0000000..cbd54c0
--- /dev/null
+++ b/docs/development-pipeline.md
@@ -0,0 +1,35 @@
+# Multi-agent development pipeline
+
+Goal: ship UI changes with high design quality, code quality, and the least code that works.
+
+## Phases
+
+1. **Scope framer — `product-framer`**
+ - Convert the request into a short fix ledger: issue, acceptance criteria, files, out-of-scope.
+ - Output: checklist only; no code.
+
+2. **Design quality — `ui-art-director` + `ux-critic`**
+ - Validate hierarchy, density, typography, motion, and user flow.
+ - Cut changes that do not improve the user's experience.
+
+3. **Minimal code preflight — `code-reviewer`**
+ - Find existing patterns and the shortest safe implementation path.
+ - Reject new dependencies and speculative abstractions.
+
+4. **Implementation — `frontend-craftsperson`**
+ - Implement one focused batch at a time.
+ - Add the smallest tests that prove behavior.
+ - Reuse tokens and existing DOM helpers.
+
+5. **Final 3-agent review**
+ - `visual-qa`: visual regressions and missed UX criteria.
+ - `accessibility-reviewer`: keyboard, focus, labels, motion, semantics.
+ - `code-reviewer`: correctness, maintainability, unnecessary code.
+
+6. **Fix loop**
+ - Send only blocking review findings back to `frontend-craftsperson`.
+ - Rerun the same 3-agent final review once.
+
+## Default rule
+
+If two solutions work, choose the one with fewer files, fewer branches, and no dependency changes.
diff --git a/docs/obsidian-mcp.md b/docs/obsidian-mcp.md
new file mode 100644
index 0000000..df2dfc5
--- /dev/null
+++ b/docs/obsidian-mcp.md
@@ -0,0 +1,11 @@
+# MCP Obsidian
+
+O projeto usa o servidor MCP HTTP `obsidian` no endpoint local:
+
+```text
+https://127.0.0.1:27124/mcp/
+```
+
+A configuração local fica em `.mcp.json`, que é ignorado pelo Git. Antes de iniciar o OpenClaude neste projeto, defina a variável de ambiente `OBSIDIAN_MCP_TOKEN` com o token do Obsidian.
+
+Nunca commite o token nem o arquivo `.mcp.json`.
diff --git a/docs/superpowers/plans/2026-07-11-minimalist-front.md b/docs/superpowers/plans/2026-07-11-minimalist-front.md
new file mode 100644
index 0000000..c1a8aae
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-11-minimalist-front.md
@@ -0,0 +1,46 @@
+# Minimalist Front Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Make the Transcript desktop UI quieter, more minimal, and better organized without adding dependencies.
+
+**Architecture:** Keep the current vanilla TypeScript DOM structure. Use the shortest safe path: CSS cleanup/overrides, small copy changes, and one keyboard behavior fix. No component split in this pass.
+
+**Tech Stack:** Tauri, TypeScript, Vite, Vitest, CSS.
+
+---
+
+### Task 1: Regression tests
+
+**Files:**
+- Modify: `src/app.test.ts`
+
+- [ ] Add tests for Escape closing settings and minimalist CSS baseline.
+- [ ] Run `npm test -- --run src/app.test.ts --reporter=verbose`; expect new tests to fail before implementation.
+
+### Task 2: Behavior and copy polish
+
+**Files:**
+- Modify: `src/app.ts`
+
+- [ ] Add Escape handling to close the settings modal.
+- [ ] Rename technical settings labels to calmer user-facing labels.
+
+### Task 3: Minimal visual pass
+
+**Files:**
+- Modify: `src/styles.css`
+
+- [ ] Fix the invalid `height: 100dvh` declaration.
+- [ ] Hide ambient decoration.
+- [ ] Flatten shell, topbar, buttons, editor, settings, and dictation overlay.
+- [ ] Keep reduced motion and existing accessibility styles.
+
+### Task 4: Verification
+
+**Files:**
+- Read-only verification.
+
+- [ ] Run `npm test -- --run`.
+- [ ] Run `npm run build`.
+- [ ] Run `cargo check --manifest-path src-tauri/Cargo.toml` through VS Build Tools environment.
diff --git a/docs/superpowers/plans/2026-07-13-audio-history-streaming-fallback.md b/docs/superpowers/plans/2026-07-13-audio-history-streaming-fallback.md
new file mode 100644
index 0000000..0ad6032
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-13-audio-history-streaming-fallback.md
@@ -0,0 +1,209 @@
+# Audio History, API Fallback, and Streaming Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Retain the last 10 recordings, export them through a native save dialog, fall back from API to local Whisper PT-BR, and insert streaming API text progressively.
+
+**Architecture:** Add a small `audio_history` module that owns safe filename validation, metadata, retention, and export source resolution. Extend the existing OpenAI-compatible client to detect SSE/NDJSON by response `Content-Type`; the existing UI command pipeline owns partial rendering and global-hotkey insertion so the client remains transport-focused.
+
+**Tech Stack:** Rust, Tauri 2, `tauri-plugin-dialog`, reqwest blocking client, TypeScript, Vitest, Cargo tests.
+
+---
+
+### Task 1: Persist a bounded, safe audio history
+
+**Files:**
+- Create: `src-tauri/src/audio_history.rs`
+- Modify: `src-tauri/src/lib.rs`
+- Modify: `src-tauri/src/app_state.rs`
+- Modify: `src-tauri/src/ui_commands.rs`
+- Test: `src-tauri/src/audio_history.rs`
+
+- [ ] **Step 1: Write failing history tests**
+
+```rust
+#[test]
+fn retain_keeps_the_ten_newest_wavs() { /* create 11 timestamped WAV files; assert 10 remain */ }
+
+#[test]
+fn audio_id_cannot_escape_recordings_dir() {
+ assert!(resolve_audio_path(Path::new("recordings"), "../secret.wav").is_err());
+}
+```
+
+- [ ] **Step 2: Run the focused test**
+
+Run: `cargo test --manifest-path src-tauri/Cargo.toml audio_history::tests --lib`
+Expected: compilation failure because `audio_history` does not exist.
+
+- [ ] **Step 3: Implement a minimal history module**
+
+```rust
+pub const AUDIO_HISTORY_LIMIT: usize = 10;
+
+#[derive(Debug, Clone, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct AudioHistoryItem { pub id: String, pub size_bytes: u64, pub modified_at_ms: u64 }
+
+pub fn retain_audio_history(dir: &Path) -> AppResult> { /* list WAVs, sort newest-first, remove beyond 10 */ }
+pub fn resolve_audio_path(dir: &Path, id: &str) -> AppResult { /* filename-only + canonicalized containment */ }
+```
+
+- [ ] **Step 4: Call retention after both normal and hotkey transcription flows**
+
+Replace `cleanup_audio_if_needed` calls with `retain_audio_history(&state.recordings_dir)` so captured WAVs are never deleted simply because `keep_audio` is false. Add `audio_history` to `AppSnapshot` from `ManagedAppState::snapshot`.
+
+- [ ] **Step 5: Run the focused test**
+
+Run: `cargo test --manifest-path src-tauri/Cargo.toml audio_history::tests --lib`
+Expected: PASS.
+
+### Task 2: Export recordings safely through a native dialog
+
+**Files:**
+- Modify: `src-tauri/Cargo.toml`
+- Modify: `src-tauri/src/lib.rs`
+- Modify: `src-tauri/src/ui_commands.rs`
+- Test: `src-tauri/src/audio_history.rs`
+
+- [ ] **Step 1: Add a failing source-resolution test**
+
+```rust
+#[test]
+fn resolve_audio_path_accepts_a_listed_wav() { /* assert a known WAV resolves inside recordings */ }
+```
+
+- [ ] **Step 2: Add the documented Tauri dialog plugin**
+
+```toml
+tauri-plugin-dialog = "2"
+```
+
+```rust
+.plugin(tauri_plugin_dialog::init())
+```
+
+Use `DialogExt::dialog().file().add_filter("Áudio WAV", &["wav"]).blocking_save_file()` and `std::fs::copy`; return `false` when the user cancels.
+
+- [ ] **Step 3: Register an explicit command**
+
+```rust
+#[tauri::command]
+pub(crate) fn download_audio(id: String, app: tauri::AppHandle, state: State<'_, ManagedAppState>) -> Result
+```
+
+Resolve `id` through `audio_history::resolve_audio_path`; never accept a caller-provided file path.
+
+- [ ] **Step 4: Run Rust tests**
+
+Run: `cargo test --manifest-path src-tauri/Cargo.toml --lib`
+Expected: PASS.
+
+### Task 3: API-to-Whisper PT-BR fallback
+
+**Files:**
+- Modify: `src-tauri/src/ui_commands.rs`
+- Test: `src-tauri/src/ui_commands.rs`
+
+- [ ] **Step 1: Write a failing pure routing test**
+
+```rust
+#[test]
+fn api_failure_without_partial_uses_local_fallback() {
+ assert!(should_fallback_to_whisper(TranscriptionMode::ApiOnly, false));
+}
+
+#[test]
+fn partial_stream_does_not_fallback_and_duplicate_text() {
+ assert!(!should_fallback_to_whisper(TranscriptionMode::ApiOnly, true));
+}
+```
+
+- [ ] **Step 2: Implement the smallest routing rule**
+
+```rust
+fn should_fallback_to_whisper(mode: TranscriptionMode, partial_received: bool) -> bool {
+ matches!(mode, TranscriptionMode::ApiOnly) && !partial_received
+}
+```
+
+In `run_configured_transcription`, use a cloned settings value with `transcription.language = Some("pt".into())` to invoke existing Whisper after API failure. Preserve local-first’s current local-then-API behavior.
+
+- [ ] **Step 3: Run focused tests**
+
+Run: `cargo test --manifest-path src-tauri/Cargo.toml ui_commands::tests --lib`
+Expected: PASS.
+
+### Task 4: Stream response handling and immediate insertion
+
+**Files:**
+- Modify: `src-tauri/src/transcription/openai.rs`
+- Modify: `src-tauri/src/ui_commands.rs`
+- Test: `src-tauri/src/transcription/openai.rs`
+
+- [ ] **Step 1: Write failing parser tests**
+
+```rust
+#[test]
+fn streaming_content_type_is_detected() { /* text/event-stream and x-ndjson true */ }
+
+#[test]
+fn cumulative_stream_text_becomes_only_the_new_suffix() {
+ assert_eq!(stream_delta("olá", "olá mundo"), " mundo");
+}
+```
+
+- [ ] **Step 2: Implement response-stream transport**
+
+Set `Accept: text/event-stream, application/x-ndjson, application/json`. For SSE/NDJSON headers, read lines from the blocking response, ignore `[DONE]`, extract `delta`, `text`, `transcript`, `result`, `output`, `data`, and OpenAI `choices[0].delta.content`, then invoke an optional partial callback. Keep JSON/plain-text behavior unchanged.
+
+- [ ] **Step 3: Wire partial callbacks into UI commands**
+
+- Main-window transcriptions append partials to `TranscriptDraft.text` and emit snapshots.
+- Global-hotkey transcriptions hide the non-focusable island on first partial and use existing `FallbackInjector` with `ClipboardPaste` for each new suffix.
+- Only perform the final full-text insertion when no partial was inserted.
+- Suppress API-to-Whisper fallback after a partial to prevent duplicate external text.
+
+- [ ] **Step 4: Run focused tests**
+
+Run: `cargo test --manifest-path src-tauri/Cargo.toml transcription::openai::tests ui_commands::tests --lib`
+Expected: PASS.
+
+### Task 5: Minimal audio history UI
+
+**Files:**
+- Modify: `src/app.ts`
+- Modify: `src/app.test.ts`
+- Modify: `src/styles.css`
+
+- [ ] **Step 1: Write failing frontend tests**
+
+```ts
+it("shows the latest audio and requests its download", async () => {
+ // Fake snapshot has audioHistory[0]; click the button; expect download_audio with its id.
+});
+```
+
+- [ ] **Step 2: Implement a compact details list**
+
+Add `audioHistory` to frontend `AppSnapshot`. Render one collapsed `` section below diagnostics: “Áudios recentes”, a primary “Baixar último áudio” action, and up to 10 safe metadata rows. Show a useful empty state. Call native `download_audio` by item ID.
+
+- [ ] **Step 3: Add restrained CSS**
+
+Use existing tokens and compact buttons. Do not introduce a new modal, gradients, or a card grid. Preserve visible focus styles and reduced-motion behavior.
+
+- [ ] **Step 4: Run focused tests**
+
+Run: `npm test -- --run src/app.test.ts --reporter=verbose`
+Expected: PASS.
+
+### Task 6: Full verification and release artifact
+
+**Files:**
+- Modify only release metadata if a new artifact version is required.
+
+- [ ] Run `cargo fmt --manifest-path src-tauri/Cargo.toml -- --check`.
+- [ ] Run `cargo test --manifest-path src-tauri/Cargo.toml --lib`.
+- [ ] Run `npm test -- --run && npm run build`.
+- [ ] Run `cargo check --manifest-path src-tauri/Cargo.toml` inside the VS Build Tools environment.
+- [ ] Run `npm run tauri:build` inside the VS Build Tools environment and verify installer timestamps.
diff --git a/docs/superpowers/specs/2026-07-13-audio-history-streaming-fallback-design.md b/docs/superpowers/specs/2026-07-13-audio-history-streaming-fallback-design.md
new file mode 100644
index 0000000..b5985ac
--- /dev/null
+++ b/docs/superpowers/specs/2026-07-13-audio-history-streaming-fallback-design.md
@@ -0,0 +1,44 @@
+# Áudio persistente, fallback local e streaming — Design
+
+## Objetivo
+
+Guardar os 10 áudios mais recentes enviados à transcrição, permitir salvar qualquer um deles em um local escolhido pelo usuário, usar Whisper local em PT-BR quando a API falhar e inserir texto progressivamente quando a API responder em streaming.
+
+## Escopo e decisões
+
+### Histórico de áudio
+
+- Cada gravação finalizada permanece no diretório de dados do aplicativo como WAV.
+- O histórico é limitado a 10 arquivos, ordenados por data de modificação decrescente. Ao finalizar uma gravação, arquivos mais antigos são removidos.
+- Cada item expõe somente `id` (nome de arquivo validado), nome, tamanho e data. Caminhos absolutos nunca são enviados ao frontend.
+- O frontend mostra um `` compacto de “Áudios recentes”, com “Baixar último áudio” e ações de salvar por item.
+- O salvamento usa o diálogo nativo de arquivo e copia o WAV para a localização escolhida. Cancelar o diálogo não é erro.
+
+### Fallback API → Whisper
+
+- O modo de servidor tenta a API configurada primeiro.
+- Qualquer falha antes de texto parcial aciona Whisper embarcado com idioma fixo `pt`.
+- Se uma resposta streaming já tiver emitido texto parcial, não há fallback automático: repetir o texto poderia duplicar o que já foi inserido no campo ativo. O erro é mostrado para revisão.
+- O modo local continua usando Whisper primeiro e API como fallback, preservando o comportamento existente.
+
+### Streaming de resposta
+
+- O cliente envia `Accept: text/event-stream, application/x-ndjson, application/json`.
+- A API é detectada como streaming exclusivamente pelo `Content-Type` da resposta: `text/event-stream` ou `application/x-ndjson`.
+- Eventos SSE/NDJSON aceitam `delta`, `text`, `transcript`, `result`, `output`, `data` e `choices[0].delta.content`; payloads cumulativos são convertidos em somente o sufixo novo.
+- Na janela principal, cada fragmento atualiza o editor de transcrição.
+- No atalho global, o primeiro fragmento esconde a barra não focável e tenta colar imediatamente no campo externo ativo; a transcrição final não é colada uma segunda vez.
+- Respostas JSON normais mantêm o fluxo atual: texto completo somente após concluir.
+
+## Segurança e limites
+
+- IDs de áudio são nomes simples de WAV; separadores de diretório, extensões diferentes e caminhos fora do diretório de gravações são rejeitados.
+- O backend nunca recebe um destino de arquivo escolhido pelo frontend; o diálogo nativo escolhe o destino e o backend executa a cópia local.
+- Áudio é dado potencialmente sensível. A retenção fixa em 10 arquivos é deliberada e visível na UI; não há telemetria nem upload adicional.
+
+## Testes
+
+- Histórico: limita a 10, remove o mais antigo, rejeita IDs inseguros.
+- Fallback: API-only usa Whisper PT-BR quando não houve parcial; streaming parcial não dispara fallback.
+- Streaming: detecta Content-Type, extrai deltas/cumulativos e evita duplicação.
+- Frontend: renderiza histórico e pede download do item selecionado.
diff --git a/findings.md b/findings.md
new file mode 100644
index 0000000..e3377f6
--- /dev/null
+++ b/findings.md
@@ -0,0 +1,7 @@
+# Findings
+
+- Available agents differ from memory: accessibility-reviewer, code-reviewer, design-squad-lead, design-system-architect, frontend-craftsperson, product-framer, test-automator, ui-art-director, ux-critic, visual-qa.
+- Design-squad-lead recommended six-phase pipeline with final visual/a11y/code review.
+- Accessibility-reviewer flagged modal focus/inert, dictation textarea label, compact button names, field-level errors, reduced motion, select focus.
+- Test-automator proposed Vitest DOM tests for modal focus/inert, dictation textarea label, compact button aria labels, API defaults.
+- Current speech container endpoint is `http://127.0.0.1:8000/v1/stt/transcribe`, model `nvidia/parakeet-tdt-0.6b-v3`.
diff --git a/index.html b/index.html
index 23aad0e..5728805 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,11 @@
Transcript
+
+
diff --git a/package-lock.json b/package-lock.json
index fec932e..ca14dec 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,14 +1,16 @@
{
"name": "transcript-desktop",
- "version": "0.1.0",
+ "version": "0.3.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "transcript-desktop",
- "version": "0.1.0",
+ "version": "0.3.1",
"dependencies": {
- "@tauri-apps/api": "^2.9.0"
+ "@hypabolic/pi-hypa": "^0.1.6",
+ "@tauri-apps/api": "^2.9.0",
+ "lucide-static": "^1.18.0"
},
"devDependencies": {
"@tauri-apps/cli": "^2.9.0",
@@ -222,6 +224,1964 @@
"node": ">=20.19.0"
}
},
+ "node_modules/@earendil-works/pi-coding-agent": {
+ "version": "0.80.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-coding-agent/-/pi-coding-agent-0.80.2.tgz",
+ "integrity": "sha512-m9v7OUit0s9LklWfh61ca/XY5INjUzjtYtNZwy3cNvyjOLk3IpBgghP8aAp0iH35rLaiRwuuWiJ8t88ODMWY+A==",
+ "hasShrinkwrap": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@earendil-works/pi-agent-core": "^0.80.2",
+ "@earendil-works/pi-ai": "^0.80.2",
+ "@earendil-works/pi-tui": "^0.80.2",
+ "@silvia-odwyer/photon-node": "0.3.4",
+ "chalk": "5.6.2",
+ "cross-spawn": "7.0.6",
+ "diff": "8.0.4",
+ "glob": "13.0.6",
+ "highlight.js": "10.7.3",
+ "hosted-git-info": "9.0.3",
+ "ignore": "7.0.5",
+ "jiti": "2.7.0",
+ "minimatch": "10.2.5",
+ "proper-lockfile": "4.1.2",
+ "semver": "7.8.0",
+ "typebox": "1.1.38",
+ "undici": "8.5.0",
+ "yaml": "2.9.0"
+ },
+ "bin": {
+ "pi": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ },
+ "optionalDependencies": {
+ "@mariozechner/clipboard": "0.3.9"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@anthropic-ai/sdk": {
+ "version": "0.91.1",
+ "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.91.1.tgz",
+ "integrity": "sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "json-schema-to-ts": "^3.1.1"
+ },
+ "bin": {
+ "anthropic-ai-sdk": "bin/cli"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/crc32": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
+ "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-browser": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
+ "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/sha256-js": "^5.2.0",
+ "@aws-crypto/supports-web-crypto": "^5.2.0",
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "@aws-sdk/util-locate-window": "^3.0.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/sha256-js": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
+ "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/util": "^5.2.0",
+ "@aws-sdk/types": "^3.222.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/supports-web-crypto": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
+ "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-crypto/util": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
+ "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/types": "^3.222.0",
+ "@smithy/util-utf8": "^2.0.0",
+ "tslib": "^2.6.2"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/client-bedrock-runtime": {
+ "version": "3.1048.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1048.0.tgz",
+ "integrity": "sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/credential-provider-node": "^3.972.42",
+ "@aws-sdk/eventstream-handler-node": "^3.972.16",
+ "@aws-sdk/middleware-eventstream": "^3.972.12",
+ "@aws-sdk/middleware-websocket": "^3.972.19",
+ "@aws-sdk/token-providers": "3.1048.0",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/fetch-http-handler": "^5.4.2",
+ "@smithy/node-http-handler": "^4.7.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/core": {
+ "version": "3.974.11",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.11.tgz",
+ "integrity": "sha512-QpnINq5FZH6EOaDEkmHdT7eUunbvD27pDNQypaWjFyYz7Zl1q3UCMQErBZxpmfGfI7MvI2TlK8KTkgNpv8b1ug==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.8",
+ "@aws-sdk/xml-builder": "^3.972.24",
+ "@aws/lambda-invoke-store": "^0.2.2",
+ "@smithy/core": "^3.24.2",
+ "@smithy/signature-v4": "^5.4.2",
+ "@smithy/types": "^4.14.1",
+ "bowser": "^2.11.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-env": {
+ "version": "3.972.37",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.37.tgz",
+ "integrity": "sha512-/jpPvEh6f7ntmIzf7dNxoNX6Q8vt8UpesCjbW6mFfk4V1NW6bIy9qxcQ6WbA8As5yQhsZOe+xeNd4xHX8kdY2Q==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-http": {
+ "version": "3.972.39",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.39.tgz",
+ "integrity": "sha512-pIgTpisWyWg7X1bUbzSjuUYosYTD0Ghz2M0hkSTmb3a6i3qV3uU+NYJPI/E2XSC0HcsZh5rsLPzeXrkb2DS0Cg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/fetch-http-handler": "^5.4.2",
+ "@smithy/node-http-handler": "^4.7.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-ini": {
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.41.tgz",
+ "integrity": "sha512-u2tyjaxJJzW8UtW4SM1ZcPMDwO6y+kV+llvou+Adts0FAKyzes5jG4izQN+KX3yE8ZROpS5y1LJ//xL2iSf76w==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/credential-provider-env": "^3.972.37",
+ "@aws-sdk/credential-provider-http": "^3.972.39",
+ "@aws-sdk/credential-provider-login": "^3.972.41",
+ "@aws-sdk/credential-provider-process": "^3.972.37",
+ "@aws-sdk/credential-provider-sso": "^3.972.41",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.41",
+ "@aws-sdk/nested-clients": "^3.997.9",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/credential-provider-imds": "^4.3.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-login": {
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.41.tgz",
+ "integrity": "sha512-0LBitxXiAiaE5nlFPfpNIww/8FRY/I7WIndWsc9GmNFOM7cE1wNpVNQEGEk9Outg5l8xl+3vybxFyUy4l9q/LQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/nested-clients": "^3.997.9",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-node": {
+ "version": "3.972.42",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.42.tgz",
+ "integrity": "sha512-D4oon2zbqqsWOJUM99Gm3/ZyJ0IJvTXVN3PyloGb3kQEyI36fjCZheZj422lAgTWWd6TSHgiImLt3RIaLdv3dQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/credential-provider-env": "^3.972.37",
+ "@aws-sdk/credential-provider-http": "^3.972.39",
+ "@aws-sdk/credential-provider-ini": "^3.972.41",
+ "@aws-sdk/credential-provider-process": "^3.972.37",
+ "@aws-sdk/credential-provider-sso": "^3.972.41",
+ "@aws-sdk/credential-provider-web-identity": "^3.972.41",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/credential-provider-imds": "^4.3.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-process": {
+ "version": "3.972.37",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.37.tgz",
+ "integrity": "sha512-7nVaHBUaWIddASYfVaA9O4D5ZVjewU3sCol9WqZPGfW0nR+0WqE0xHZnD/U2L33PlOB8KNXGKZ6wOES/QijKzg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-sso": {
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.41.tgz",
+ "integrity": "sha512-IOWAWEHe5LkjSKkkUUX9ciV6Y1scHTsnfEkdt5yyC4Slrc7AGbkLPrpntjqh18ksJAMOaVhoBsO8p2WyTcY2wQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/nested-clients": "^3.997.9",
+ "@aws-sdk/token-providers": "3.1048.0",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/credential-provider-web-identity": {
+ "version": "3.972.41",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.41.tgz",
+ "integrity": "sha512-mbACk9Yypa8nm4iGZLs0PofOXEcTDOUw6wDnsPXNDNSd2WNXs1tSo+6nc/fh0jLYdfVZThhBL98PHW4aXFsG5A==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/nested-clients": "^3.997.9",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/eventstream-handler-node": {
+ "version": "3.972.16",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.16.tgz",
+ "integrity": "sha512-yedpPgKftqjU5SlPFHfqWpOw6xSCRieWRG1euWOlXn4WJxt2VX92VprCa2PpSOXjVCAeK6dTjW9eJRXVig9yGA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-eventstream": {
+ "version": "3.972.12",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.12.tgz",
+ "integrity": "sha512-tHTHHCHNrq6XklQvlzHBDJG4Iuhh7NVPRdtmvP+nHFA+5sxPlIDzlAHHgfoYHGvT3NXP1yVP/L5c3opUn6T3Qg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/middleware-websocket": {
+ "version": "3.972.19",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.19.tgz",
+ "integrity": "sha512-mkEhOGYozqKQkbFaVrjwr0faiwwZza1v5/jSY6Tucm3bD+uKTazIUH/4Yo6aMnQD2ua2W9cMP6s8mvwTcjtqHw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/fetch-http-handler": "^5.4.2",
+ "@smithy/signature-v4": "^5.4.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/nested-clients": {
+ "version": "3.997.9",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.9.tgz",
+ "integrity": "sha512-jPR3rnmRI4hWYyzfmTGBr7NblMp8QYYeflHXba1H6+7CGrWVqWKQzaXFQ4qbExqPRsXN3T3L3JxFhr6aouXUGQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/sha256-browser": "5.2.0",
+ "@aws-crypto/sha256-js": "5.2.0",
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/signature-v4-multi-region": "^3.996.27",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/fetch-http-handler": "^5.4.2",
+ "@smithy/node-http-handler": "^4.7.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/signature-v4-multi-region": {
+ "version": "3.996.27",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.27.tgz",
+ "integrity": "sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/signature-v4": "^5.4.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/token-providers": {
+ "version": "3.1048.0",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1048.0.tgz",
+ "integrity": "sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-sdk/core": "^3.974.11",
+ "@aws-sdk/nested-clients": "^3.997.9",
+ "@aws-sdk/types": "^3.973.8",
+ "@smithy/core": "^3.24.2",
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/types": {
+ "version": "3.973.8",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz",
+ "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/types": "^4.14.1",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/util-locate-window": {
+ "version": "3.965.5",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz",
+ "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws-sdk/xml-builder": {
+ "version": "3.972.24",
+ "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.24.tgz",
+ "integrity": "sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@nodable/entities": "2.1.0",
+ "@smithy/types": "^4.14.1",
+ "fast-xml-parser": "5.7.3",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@aws/lambda-invoke-store": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz",
+ "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@babel/runtime": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
+ "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-agent-core": {
+ "version": "0.80.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-agent-core/-/pi-agent-core-0.80.2.tgz",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@earendil-works/pi-ai": "^0.80.2",
+ "ignore": "7.0.5",
+ "typebox": "1.1.38",
+ "yaml": "2.9.0"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-ai": {
+ "version": "0.80.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-ai/-/pi-ai-0.80.2.tgz",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@anthropic-ai/sdk": "0.91.1",
+ "@aws-sdk/client-bedrock-runtime": "3.1048.0",
+ "@google/genai": "1.52.0",
+ "@mistralai/mistralai": "2.2.6",
+ "@opentelemetry/api": "1.9.0",
+ "@smithy/node-http-handler": "4.7.3",
+ "http-proxy-agent": "7.0.2",
+ "https-proxy-agent": "7.0.6",
+ "openai": "6.26.0",
+ "partial-json": "0.1.7",
+ "typebox": "1.1.38"
+ },
+ "bin": {
+ "pi-ai": "dist/cli.js"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui": {
+ "version": "0.80.2",
+ "resolved": "https://registry.npmjs.org/@earendil-works/pi-tui/-/pi-tui-0.80.2.tgz",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "get-east-asian-width": "1.6.0",
+ "marked": "18.0.5"
+ },
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@google/genai": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.52.0.tgz",
+ "integrity": "sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==",
+ "hasInstallScript": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "google-auth-library": "^10.3.0",
+ "p-retry": "^4.6.2",
+ "protobufjs": "^7.5.4",
+ "ws": "^8.18.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "@modelcontextprotocol/sdk": "^1.25.2"
+ },
+ "peerDependenciesMeta": {
+ "@modelcontextprotocol/sdk": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard/-/clipboard-0.3.9.tgz",
+ "integrity": "sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ },
+ "optionalDependencies": {
+ "@mariozechner/clipboard-darwin-arm64": "0.3.9",
+ "@mariozechner/clipboard-darwin-universal": "0.3.9",
+ "@mariozechner/clipboard-darwin-x64": "0.3.9",
+ "@mariozechner/clipboard-linux-arm64-gnu": "0.3.9",
+ "@mariozechner/clipboard-linux-arm64-musl": "0.3.9",
+ "@mariozechner/clipboard-linux-riscv64-gnu": "0.3.9",
+ "@mariozechner/clipboard-linux-x64-gnu": "0.3.9",
+ "@mariozechner/clipboard-linux-x64-musl": "0.3.9",
+ "@mariozechner/clipboard-win32-arm64-msvc": "0.3.9",
+ "@mariozechner/clipboard-win32-x64-msvc": "0.3.9"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-arm64": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-arm64/-/clipboard-darwin-arm64-0.3.9.tgz",
+ "integrity": "sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-universal": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-universal/-/clipboard-darwin-universal-0.3.9.tgz",
+ "integrity": "sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-darwin-x64": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-darwin-x64/-/clipboard-darwin-x64-0.3.9.tgz",
+ "integrity": "sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-gnu": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-gnu/-/clipboard-linux-arm64-gnu-0.3.9.tgz",
+ "integrity": "sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-arm64-musl": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-arm64-musl/-/clipboard-linux-arm64-musl-0.3.9.tgz",
+ "integrity": "sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-riscv64-gnu": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-riscv64-gnu/-/clipboard-linux-riscv64-gnu-0.3.9.tgz",
+ "integrity": "sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-gnu": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-gnu/-/clipboard-linux-x64-gnu-0.3.9.tgz",
+ "integrity": "sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-linux-x64-musl": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-linux-x64-musl/-/clipboard-linux-x64-musl-0.3.9.tgz",
+ "integrity": "sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-arm64-msvc": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-arm64-msvc/-/clipboard-win32-arm64-msvc-0.3.9.tgz",
+ "integrity": "sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mariozechner/clipboard-win32-x64-msvc": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@mariozechner/clipboard-win32-x64-msvc/-/clipboard-win32-x64-msvc-0.3.9.tgz",
+ "integrity": "sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "peer": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@mistralai/mistralai": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-2.2.6.tgz",
+ "integrity": "sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "^1.40.0",
+ "ws": "^8.18.0",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-to-json-schema": "^3.25.0"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.9.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@nodable/entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/nodable"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.41.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz",
+ "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/codegen": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
+ "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
+ "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/fetch": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
+ "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@protobufjs/utf8": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
+ "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@silvia-odwyer/photon-node": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@silvia-odwyer/photon-node/-/photon-node-0.3.4.tgz",
+ "integrity": "sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/core": {
+ "version": "3.24.3",
+ "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.24.3.tgz",
+ "integrity": "sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@aws-crypto/crc32": "5.2.0",
+ "@smithy/types": "^4.14.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/credential-provider-imds": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.3.3.tgz",
+ "integrity": "sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/core": "^3.24.3",
+ "@smithy/types": "^4.14.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/fetch-http-handler": {
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.4.3.tgz",
+ "integrity": "sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/core": "^3.24.3",
+ "@smithy/types": "^4.14.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/is-array-buffer": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
+ "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/node-http-handler": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.7.3.tgz",
+ "integrity": "sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/core": "^3.24.3",
+ "@smithy/types": "^4.14.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/signature-v4": {
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.4.3.tgz",
+ "integrity": "sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/core": "^3.24.3",
+ "@smithy/types": "^4.14.2",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/types": {
+ "version": "4.14.2",
+ "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.2.tgz",
+ "integrity": "sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-buffer-from": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
+ "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/is-array-buffer": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@smithy/util-utf8": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
+ "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@smithy/util-buffer-from": "^2.2.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/@types/node": {
+ "version": "22.19.19",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz",
+ "integrity": "sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/bignumber.js": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
+ "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/bowser": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz",
+ "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/brace-expansion": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/diff": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz",
+ "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-builder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz",
+ "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-expression-matcher": "^1.5.0",
+ "xml-naming": "^0.1.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/fast-xml-parser": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.3.tgz",
+ "integrity": "sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@nodable/entities": "^2.1.0",
+ "fast-xml-builder": "^1.1.7",
+ "path-expression-matcher": "^1.5.0",
+ "strnum": "^2.2.3"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/gaxios": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz",
+ "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^7.0.1",
+ "node-fetch": "^3.3.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/gcp-metadata": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
+ "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "google-logging-utils": "^1.0.0",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/get-east-asian-width": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz",
+ "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/glob": {
+ "version": "13.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
+ "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
+ "license": "BlueOak-1.0.0",
+ "peer": true,
+ "dependencies": {
+ "minimatch": "^10.2.2",
+ "minipass": "^7.1.3",
+ "path-scurry": "^2.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/google-auth-library": {
+ "version": "10.6.2",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz",
+ "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "gaxios": "^7.1.4",
+ "gcp-metadata": "8.1.2",
+ "google-logging-utils": "1.1.3",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/google-logging-utils": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
+ "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/hosted-git-info": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz",
+ "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "lru-cache": "^11.1.0"
+ },
+ "engines": {
+ "node": "^20.17.0 || >=22.9.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/jiti": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
+ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/json-schema-to-ts": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
+ "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "ts-algebra": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
+ "license": "Apache-2.0",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/lru-cache": {
+ "version": "11.4.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.4.0.tgz",
+ "integrity": "sha512-W+R+kFL4HgVxONq2bhXPi3bGpzGe/yEhVOp233qw9wCRtgncJ15P3bC+e4zZMu4Cq7d+WAJjXGW0uUkifhcatA==",
+ "license": "BlueOak-1.0.0",
+ "peer": true,
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/marked": {
+ "version": "18.0.5",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.5.tgz",
+ "integrity": "sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==",
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 20"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "license": "BlueOak-1.0.0",
+ "peer": true,
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "license": "BlueOak-1.0.0",
+ "peer": true,
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/node-fetch": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/openai": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz",
+ "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "bin": {
+ "openai": "bin/cli"
+ },
+ "peerDependencies": {
+ "ws": "^8.18.0",
+ "zod": "^3.25 || ^4.0"
+ },
+ "peerDependenciesMeta": {
+ "ws": {
+ "optional": true
+ },
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
+ "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@types/retry": "0.12.0",
+ "retry": "^0.13.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/p-retry/node_modules/@types/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/partial-json": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz",
+ "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/path-expression-matcher": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz",
+ "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/path-scurry": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
+ "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
+ "license": "BlueOak-1.0.0",
+ "peer": true,
+ "dependencies": {
+ "lru-cache": "^11.0.0",
+ "minipass": "^7.1.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz",
+ "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.4",
+ "retry": "^0.12.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/proper-lockfile/node_modules/retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/protobufjs": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz",
+ "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==",
+ "hasInstallScript": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.5",
+ "@protobufjs/eventemitter": "^1.1.1",
+ "@protobufjs/fetch": "^1.1.1",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.1",
+ "@types/node": ">=13.7.0",
+ "long": "^5.3.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/retry": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
+ "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/semver": {
+ "version": "7.8.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.0.tgz",
+ "integrity": "sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==",
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/strnum": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz",
+ "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/ts-algebra": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
+ "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/typebox": {
+ "version": "1.1.38",
+ "resolved": "https://registry.npmjs.org/typebox/-/typebox-1.1.38.tgz",
+ "integrity": "sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/undici": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-8.5.0.tgz",
+ "integrity": "sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=22.19.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/ws": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
+ "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/xml-naming": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz",
+ "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/yaml": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz",
+ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==",
+ "license": "ISC",
+ "peer": true,
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@earendil-works/pi-coding-agent/node_modules/zod-to-json-schema": {
+ "version": "3.25.2",
+ "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
+ "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
+ "license": "ISC",
+ "peer": true,
+ "peerDependencies": {
+ "zod": "^3.25.28 || ^4"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.7",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
@@ -682,6 +2642,141 @@
}
}
},
+ "node_modules/@hypabolic/hypa": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa/-/hypa-0.1.6.tgz",
+ "integrity": "sha512-WV8zcqJdUwIUydaVYQUL6z96ja2XkbcKi/E7V8a4h+7PG5rUxdbpr6GiFE5pI8dCJxWbQuYFEW3qbuxRk46+ZA==",
+ "license": "FSL-1.1-ALv2",
+ "bin": {
+ "hypa": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@hypabolic/hypa-darwin-arm64": "0.1.6",
+ "@hypabolic/hypa-darwin-x64": "0.1.6",
+ "@hypabolic/hypa-linux-arm64": "0.1.6",
+ "@hypabolic/hypa-linux-x64": "0.1.6",
+ "@hypabolic/hypa-win32-arm64": "0.1.6",
+ "@hypabolic/hypa-win32-x64": "0.1.6"
+ }
+ },
+ "node_modules/@hypabolic/hypa-darwin-arm64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-darwin-arm64/-/hypa-darwin-arm64-0.1.6.tgz",
+ "integrity": "sha512-7KnpV71Pr7vNANNjCuwW/DRKoUJ1Zv1byDqJ4tp50mtocTfkclAakemY4pA7ZBt259K/mwiDfVowf4b5g3ij5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/hypa-darwin-x64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-darwin-x64/-/hypa-darwin-x64-0.1.6.tgz",
+ "integrity": "sha512-zcWJalubvOmJQa+jwhPc1Ml8O+7SwJtF7sHmm8HQJA3ohA3jpybp96RQQJ+Upkub+igprGD9iqEApDmhSjOoag==",
+ "cpu": [
+ "x64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/hypa-linux-arm64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-linux-arm64/-/hypa-linux-arm64-0.1.6.tgz",
+ "integrity": "sha512-rGFApROl1BMc3wxARPzwzZ32Oh2WNaGlPmbyzznorcgAy8SoiBG5zG+ekOW6l7Rx5uW5tsHCBneaXN8AJ+fPSA==",
+ "cpu": [
+ "arm64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/hypa-linux-x64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-linux-x64/-/hypa-linux-x64-0.1.6.tgz",
+ "integrity": "sha512-2nApNAghtrUjU0+o3XiLISIqALIiB8yHBzg4nZhlGK1Vr7vTYAg9gxM6UDE0bEkHBgG6FPaI4L+BzPF8/kKF2g==",
+ "cpu": [
+ "x64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/hypa-win32-arm64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-win32-arm64/-/hypa-win32-arm64-0.1.6.tgz",
+ "integrity": "sha512-VkjNVWG8O3KyFx/VX2DOGMwg0f3q21jVJsvjByQccaKmxTZhptMHpnSRvpjnSfIZsWTcd2RwIjRoOiKXU5kBTg==",
+ "cpu": [
+ "arm64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/hypa-win32-x64": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/hypa-win32-x64/-/hypa-win32-x64-0.1.6.tgz",
+ "integrity": "sha512-M/p7eMs5dURE8EoNfzdob39UFRIFwCwaPUadZsv9iFK0eMUFVoBIkEKWyeymEZS/ngyd7RaqWbOwArhtnavwFw==",
+ "cpu": [
+ "x64"
+ ],
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@hypabolic/pi-hypa": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@hypabolic/pi-hypa/-/pi-hypa-0.1.6.tgz",
+ "integrity": "sha512-NKdZWP84grPYU16oAFTKHB8ZiE2HEjGGpwXGvrPrz4QLUbO8A80N01EnVflCNqYOOrXOrOheC1AdnDF4FLcJmw==",
+ "hasInstallScript": true,
+ "license": "FSL-1.1-ALv2",
+ "dependencies": {
+ "@hypabolic/hypa": "0.1.6"
+ },
+ "peerDependencies": {
+ "@earendil-works/pi-coding-agent": "*"
+ }
+ },
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
@@ -1669,6 +3764,12 @@
"node": "20 || >=22"
}
},
+ "node_modules/lucide-static": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/lucide-static/-/lucide-static-1.18.0.tgz",
+ "integrity": "sha512-0WRXLQnjbte5SXuzom6yfeGlVSFsEsC9rzxn66DZN0pXows3+N34CQHy3BHI1qA3uH7u/SUzx8LQhjeAnxd8JQ==",
+ "license": "ISC"
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -2012,7 +4113,6 @@
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz",
"integrity": "sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=20.18.1"
diff --git a/package.json b/package.json
index 1d2dedf..da68751 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "transcript-desktop",
- "version": "0.1.0",
+ "version": "0.3.1",
"private": true,
"type": "module",
"scripts": {
@@ -12,7 +12,9 @@
"tauri:build": "tauri build"
},
"dependencies": {
- "@tauri-apps/api": "^2.9.0"
+ "@hypabolic/pi-hypa": "^0.1.6",
+ "@tauri-apps/api": "^2.9.0",
+ "lucide-static": "^1.18.0"
},
"devDependencies": {
"@tauri-apps/cli": "^2.9.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..7e7f130
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,2736 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+overrides:
+ esbuild@>=0.27.3 <0.28.1: '>=0.28.1'
+
+importers:
+
+ .:
+ dependencies:
+ '@hypabolic/pi-hypa':
+ specifier: ^0.1.6
+ version: 0.1.6(@earendil-works/pi-coding-agent@0.80.2(ws@8.21.0)(zod@4.4.3))
+ '@tauri-apps/api':
+ specifier: ^2.9.0
+ version: 2.11.1
+ lucide-static:
+ specifier: ^1.18.0
+ version: 1.21.0
+ devDependencies:
+ '@tauri-apps/cli':
+ specifier: ^2.9.0
+ version: 2.11.3
+ jsdom:
+ specifier: ^29.1.1
+ version: 29.1.1
+ typescript:
+ specifier: ^5.9.3
+ version: 5.9.3
+ vite:
+ specifier: ^7.2.6
+ version: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0)
+ vitest:
+ specifier: ^4.0.15
+ version: 4.1.9(@opentelemetry/api@1.9.0)(@types/node@26.0.1)(jsdom@29.1.1)(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0))
+
+packages:
+
+ '@anthropic-ai/sdk@0.91.1':
+ resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==}
+ hasBin: true
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+ peerDependenciesMeta:
+ zod:
+ optional: true
+
+ '@asamuzakjp/css-color@5.1.11':
+ resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ '@asamuzakjp/dom-selector@7.1.1':
+ resolution: {integrity: sha512-67RZDnYRc8H/8MLDgQCDE//zoqVFwajkepHZgmXrbwybzXOEwOWGPYGmALYl9J2DOLfFPPs6kKCqmbzV895hTQ==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ '@asamuzakjp/generational-cache@1.0.1':
+ resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ '@asamuzakjp/nwsapi@2.3.9':
+ resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==}
+
+ '@aws-crypto/crc32@5.2.0':
+ resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==}
+ engines: {node: '>=16.0.0'}
+
+ '@aws-crypto/sha256-browser@5.2.0':
+ resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==}
+
+ '@aws-crypto/sha256-js@5.2.0':
+ resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==}
+ engines: {node: '>=16.0.0'}
+
+ '@aws-crypto/supports-web-crypto@5.2.0':
+ resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==}
+
+ '@aws-crypto/util@5.2.0':
+ resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==}
+
+ '@aws-sdk/client-bedrock-runtime@3.1048.0':
+ resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/core@3.974.23':
+ resolution: {integrity: sha512-MiWR/uWjxjFXGzrE0Ghc5lWxUxzHsUWFhV+OX7M4cR9SrmrnZs6TXavnCWnzzdwJeFri34xQo81rvGNzK3c4BQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-env@3.972.49':
+ resolution: {integrity: sha512-liB3yQNHCM9k/gu/w36XHMKPluT7HTlnGUhRbBGSISDQkcr/Sy1zsZabiuvQj8WG5yW573u9RehrBvvnIQ9OEQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-http@3.972.51':
+ resolution: {integrity: sha512-XET0H2oofciJ5lMRWNIvRjAP7Q3wv2XT+JtJJEdhPWUMwe3TvQ9qcxonpu7vXmNngncvFpi4E2It+Tamas/naA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-ini@3.972.56':
+ resolution: {integrity: sha512-IAmc61hbgQiHht9U3x0tnRwz0lzdwOwD/i9voRgdJrKamF+JtmrBOsW9GwB7mfFonNWOWL4qARWYrF8veEMe3w==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-login@3.972.55':
+ resolution: {integrity: sha512-hBBkANo3cDn+h2qxxzER4a+J8JCO9o9Z/YYmU7iky6AcaarX5RRdRcHNC6SLdwY0vAXQygn6soUbDqPn3GghaA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-node@3.972.58':
+ resolution: {integrity: sha512-OyCLVmSI7pZO8hxwNVX6pXhTVlJqRBTp+ijdEfJSUj0RyjHnF602OfAarOzGq6wkGodeFkYBt8MmJ6A6ycRgWw==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-process@3.972.49':
+ resolution: {integrity: sha512-C8h36lBuC/RnBSsjlO+dn6xZm3KbAl5vpJaVPAfQnMmz2/OISmKOc8XZcqMQgO2ADwBYNRMM6Kf3vz9G/TulMQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-sso@3.972.55':
+ resolution: {integrity: sha512-1FkOz74Ea5QGS9jtIoXp55T/IkSS3spv+nLTT07fRY/+T5xmEOqaYBVIaEmX4zTNvbV6g2lrtlaVKWEoNyJt3w==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/credential-provider-web-identity@3.972.55':
+ resolution: {integrity: sha512-g2BoECD1q01kTPByi56+VLVvdWDzMkKIcr77qixpqH0okw2t0U5CoPv+6S8v/D1Y2Wa6QKKtn6XAtDzP+Kfpvg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/eventstream-handler-node@3.972.22':
+ resolution: {integrity: sha512-tqPJv0dz4+O0hWGm1a6YekcMZyPhDFs/zH73Von7icaVT5n0Jqvm86typ3jRrG+qoUdPhALOnboRLTmnWQTlYQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/middleware-eventstream@3.972.18':
+ resolution: {integrity: sha512-OHpk8YoZi3yexPq8aFt1vN1IxA2zLKvsIR5GpWYylX/ve6kQmY7wxHNSFy/D3t2apMZ16rs76Co4dJWcDyIk3A==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/middleware-websocket@3.972.31':
+ resolution: {integrity: sha512-ps1rumU1LybSFHaW9dTDgkhCMJLVaedEY78kKSzUDDY+b9974/g6aiaYYA0U9WV0oL4CJCJrVWG+EZ/qr4or7g==}
+ engines: {node: '>= 14.0.0'}
+
+ '@aws-sdk/nested-clients@3.997.23':
+ resolution: {integrity: sha512-gO93ZPsI2bxeFZD42f1/qjDw6FAZkNZcKRO94LIiT03fzOmcJ9e/tunxjVjA1Rl69ClmVJzz8H3G9CdKef10PA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/signature-v4-multi-region@3.996.35':
+ resolution: {integrity: sha512-6L/VWs+Wch2stHemCGTmUNqKLMzURxQDK5boNG3Jn3kAOp71meDUuS5sbObpEvFxHDq0uWeSLFDNSYsjNt+Dlg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/token-providers@3.1048.0':
+ resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/token-providers@3.1074.0':
+ resolution: {integrity: sha512-pv80IzgGW4RnXWtft692chZOM9i6PhebVsLCcnaM4dBEPZva2fE6FXAHs76G7Rc7s3yGyX/68G0nZMrUy+Vmpg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/types@3.973.13':
+ resolution: {integrity: sha512-pEHZqRkAlHfnfAU9tK+WpKv/gBNjGJrHMgA3A0iYRGyswBS2t0pfez+lWlwktb3Bqa0ovh7w/QJTFwp3fDxLNg==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/util-locate-window@3.965.8':
+ resolution: {integrity: sha512-uUbMs1cBZPafD0ohUj6EwNf0fPZ534NvBxHox4hjX+0Rxq5paSYUem7+hi833pYrzrcnBATKIYpR02MDXT5M9g==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws-sdk/xml-builder@3.972.31':
+ resolution: {integrity: sha512-SzE4Pgyl+hDF+BuyuzxUSpwnuUu9lJuO1YGgteG89/4Qv0+2IQiVQqdbPV32IozLvXWQChPQcdkk/sKvb1QHiQ==}
+ engines: {node: '>=20.0.0'}
+
+ '@aws/lambda-invoke-store@0.2.4':
+ resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==}
+ engines: {node: '>=18.0.0'}
+
+ '@babel/runtime@7.29.7':
+ resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==}
+ engines: {node: '>=6.9.0'}
+
+ '@bramus/specificity@2.4.2':
+ resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==}
+ hasBin: true
+
+ '@csstools/color-helpers@6.0.2':
+ resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==}
+ engines: {node: '>=20.19.0'}
+
+ '@csstools/css-calc@3.2.1':
+ resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^4.0.0
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-color-parser@4.1.8':
+ resolution: {integrity: sha512-3chWb7PRLijpJpPIKkDxdu6IBeO5MrFACND57On0j8OPpc0wZibcGc3xAHrSEbOx/KDRyMHoIxGn0w1PhXMYHw==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-parser-algorithms': ^4.0.0
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-parser-algorithms@4.0.0':
+ resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==}
+ engines: {node: '>=20.19.0'}
+ peerDependencies:
+ '@csstools/css-tokenizer': ^4.0.0
+
+ '@csstools/css-syntax-patches-for-csstree@1.1.5':
+ resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==}
+ peerDependencies:
+ css-tree: ^3.2.1
+ peerDependenciesMeta:
+ css-tree:
+ optional: true
+
+ '@csstools/css-tokenizer@4.0.0':
+ resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==}
+ engines: {node: '>=20.19.0'}
+
+ '@earendil-works/pi-agent-core@0.80.2':
+ resolution: {integrity: sha512-BF9WPhixIFjT6Kp3Iz3H6ugkU+4AWotM8py96XE5pIK0arJbQKMWbR+dXSWWDEmR5yc/aFQODnuyowOEzMGO7Q==}
+ engines: {node: '>=22.19.0'}
+
+ '@earendil-works/pi-ai@0.80.2':
+ resolution: {integrity: sha512-5GNKfdrRJ4uZ5Zd9iudoXggi/BbUcKnD/xfRHtdR+7q4vWqPvfx8auFuaT+ewGBVI8K4wj87eigFQ/iCSuy9RQ==}
+ engines: {node: '>=22.19.0'}
+ hasBin: true
+
+ '@earendil-works/pi-coding-agent@0.80.2':
+ resolution: {integrity: sha512-m9v7OUit0s9LklWfh61ca/XY5INjUzjtYtNZwy3cNvyjOLk3IpBgghP8aAp0iH35rLaiRwuuWiJ8t88ODMWY+A==}
+ engines: {node: '>=22.19.0'}
+ hasBin: true
+
+ '@earendil-works/pi-tui@0.80.2':
+ resolution: {integrity: sha512-OvOAMIbXiC9OSse17YMiXIsI9AS5XM/ZV8N/k+UzdlRpPILDQYmLElevgGW92kkXR8qHBClIdzhCjuzlBGvphA==}
+ engines: {node: '>=22.19.0'}
+
+ '@esbuild/aix-ppc64@0.28.1':
+ resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.28.1':
+ resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.28.1':
+ resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.28.1':
+ resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.28.1':
+ resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.28.1':
+ resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.28.1':
+ resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.28.1':
+ resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.28.1':
+ resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.28.1':
+ resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.28.1':
+ resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.28.1':
+ resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.28.1':
+ resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.28.1':
+ resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.28.1':
+ resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.28.1':
+ resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.28.1':
+ resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.28.1':
+ resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.28.1':
+ resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.28.1':
+ resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.28.1':
+ resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.28.1':
+ resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.28.1':
+ resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.28.1':
+ resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.28.1':
+ resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.28.1':
+ resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@exodus/bytes@1.15.1':
+ resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+ peerDependencies:
+ '@noble/hashes': ^1.8.0 || ^2.0.0
+ peerDependenciesMeta:
+ '@noble/hashes':
+ optional: true
+
+ '@google/genai@1.52.0':
+ resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==}
+ engines: {node: '>=20.0.0'}
+ peerDependencies:
+ '@modelcontextprotocol/sdk': ^1.25.2
+ peerDependenciesMeta:
+ '@modelcontextprotocol/sdk':
+ optional: true
+
+ '@hypabolic/hypa-darwin-arm64@0.1.6':
+ resolution: {integrity: sha512-7KnpV71Pr7vNANNjCuwW/DRKoUJ1Zv1byDqJ4tp50mtocTfkclAakemY4pA7ZBt259K/mwiDfVowf4b5g3ij5A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@hypabolic/hypa-darwin-x64@0.1.6':
+ resolution: {integrity: sha512-zcWJalubvOmJQa+jwhPc1Ml8O+7SwJtF7sHmm8HQJA3ohA3jpybp96RQQJ+Upkub+igprGD9iqEApDmhSjOoag==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@hypabolic/hypa-linux-arm64@0.1.6':
+ resolution: {integrity: sha512-rGFApROl1BMc3wxARPzwzZ32Oh2WNaGlPmbyzznorcgAy8SoiBG5zG+ekOW6l7Rx5uW5tsHCBneaXN8AJ+fPSA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@hypabolic/hypa-linux-x64@0.1.6':
+ resolution: {integrity: sha512-2nApNAghtrUjU0+o3XiLISIqALIiB8yHBzg4nZhlGK1Vr7vTYAg9gxM6UDE0bEkHBgG6FPaI4L+BzPF8/kKF2g==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@hypabolic/hypa-win32-arm64@0.1.6':
+ resolution: {integrity: sha512-VkjNVWG8O3KyFx/VX2DOGMwg0f3q21jVJsvjByQccaKmxTZhptMHpnSRvpjnSfIZsWTcd2RwIjRoOiKXU5kBTg==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@hypabolic/hypa-win32-x64@0.1.6':
+ resolution: {integrity: sha512-M/p7eMs5dURE8EoNfzdob39UFRIFwCwaPUadZsv9iFK0eMUFVoBIkEKWyeymEZS/ngyd7RaqWbOwArhtnavwFw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@hypabolic/hypa@0.1.6':
+ resolution: {integrity: sha512-WV8zcqJdUwIUydaVYQUL6z96ja2XkbcKi/E7V8a4h+7PG5rUxdbpr6GiFE5pI8dCJxWbQuYFEW3qbuxRk46+ZA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ '@hypabolic/pi-hypa@0.1.6':
+ resolution: {integrity: sha512-NKdZWP84grPYU16oAFTKHB8ZiE2HEjGGpwXGvrPrz4QLUbO8A80N01EnVflCNqYOOrXOrOheC1AdnDF4FLcJmw==}
+ peerDependencies:
+ '@earendil-works/pi-coding-agent': '*'
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@mariozechner/clipboard-darwin-arm64@0.3.9':
+ resolution: {integrity: sha512-BfgV7vCEWZwJwZJw03r6bP5+tf0iI/ANuQYCxi9RNn7FrWB3yzGuMKCrNLRl6V761vXRdL8+OqZ0wd4TqlsNOQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@mariozechner/clipboard-darwin-universal@0.3.9':
+ resolution: {integrity: sha512-BGGR4iA9Z2shAjI65eI5xtyb3LYNlDW9X3gxKxDbqtbnREohsrqznov6zpKoIrsRWpzlYVEdKphS7ksJ0/ndSQ==}
+ engines: {node: '>= 10'}
+ os: [darwin]
+
+ '@mariozechner/clipboard-darwin-x64@0.3.9':
+ resolution: {integrity: sha512-4kURmCbS6nt8uYhtmWpUcJWyPHfmAr5dTpXD1nO3pIfa+TSQ9DbrGOYCKH+aEFW47XhQ4Vp8ZTszie+wfFvDKg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@mariozechner/clipboard-linux-arm64-gnu@0.3.9':
+ resolution: {integrity: sha512-g59OkUGP2DDfCOIKypHeYgv2M55u/cKvXa5dSxFbEJ34XvIQMdcVmpKCkGUro3ZgefXiGVdwguvTMQGpHWzIXw==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@mariozechner/clipboard-linux-arm64-musl@0.3.9':
+ resolution: {integrity: sha512-AGuJdgKsmJdm4Pych7kv3sqe591ERRaAHW3xjLooiFzn8J+PxUyof++7YZrB5Y5tpnTO+K18Og3taj2NpluCRQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@mariozechner/clipboard-linux-riscv64-gnu@0.3.9':
+ resolution: {integrity: sha512-DXBEAiuMpk7dhS1a9NzNxVAFi1vaKoPu7rQNgY8LIDLGrK3lnIp3nT10DUum+PKVJoJppIP+NAA8IZe4DMNDPw==}
+ engines: {node: '>= 10'}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@mariozechner/clipboard-linux-x64-gnu@0.3.9':
+ resolution: {integrity: sha512-WORrMLd6EpElEME7JRKfSaY34nW1P5LbdgK5YNCS1ncG2LqmITsSMEJ8nh2mpvxb3TxqbOOKgY7k9eMJYlW9Mw==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@mariozechner/clipboard-linux-x64-musl@0.3.9':
+ resolution: {integrity: sha512-/DHn+1DrfL6oRaPPWXaOKvonFFrni666fxd+zFqiQEfvBH0tsHVWjq9iqBk0oDp0qaPA72lIMy5BptxISBEhZQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@mariozechner/clipboard-win32-arm64-msvc@0.3.9':
+ resolution: {integrity: sha512-O5FHD3ErkMwMhNzAfu3ggy0ug4z7btZuoQgwwxlzPrwV2bxlD6WDpqBY4NCgICAgZdDKdp+loUEKVAVt8aYnhQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@mariozechner/clipboard-win32-x64-msvc@0.3.9':
+ resolution: {integrity: sha512-ihQC3EufqEY81vhXBgVBtK4prL+wc62zJsSvxrgz7K1hsdt6OObz6v9p3Rn1OG3GJksTTKMJF0u/guMISHPhSA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@mariozechner/clipboard@0.3.9':
+ resolution: {integrity: sha512-ABnA53mdfkGZwOFUdZNv2S0CWGO/EIuPj8Vv9xmBFmSYg/qFc7ihO6q5FcQjvoE67kZpWkEc4AhD6B/os04yuA==}
+ engines: {node: '>= 10'}
+
+ '@mistralai/mistralai@2.2.6':
+ resolution: {integrity: sha512-W8pX7zHxjJvMIpw8JMxeJEleapXX0Q9NPszdNzqkM3MIEoIGPObdodujj+WHteXEvGfaP/AMwlNyRfEzSY6dQQ==}
+ peerDependencies:
+ '@opentelemetry/api': ^1.9.0
+ peerDependenciesMeta:
+ '@opentelemetry/api':
+ optional: true
+
+ '@opentelemetry/api@1.9.0':
+ resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==}
+ engines: {node: '>=8.0.0'}
+
+ '@opentelemetry/semantic-conventions@1.41.1':
+ resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==}
+ engines: {node: '>=14'}
+
+ '@protobufjs/aspromise@1.1.2':
+ resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
+
+ '@protobufjs/base64@1.1.2':
+ resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
+
+ '@protobufjs/codegen@2.0.5':
+ resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==}
+
+ '@protobufjs/eventemitter@1.1.1':
+ resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==}
+
+ '@protobufjs/fetch@1.1.1':
+ resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==}
+
+ '@protobufjs/float@1.0.2':
+ resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
+
+ '@protobufjs/path@1.1.2':
+ resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
+
+ '@protobufjs/pool@1.1.0':
+ resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
+
+ '@protobufjs/utf8@1.1.1':
+ resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==}
+
+ '@rollup/rollup-android-arm-eabi@4.62.2':
+ resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.62.2':
+ resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.62.2':
+ resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.62.2':
+ resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.62.2':
+ resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.62.2':
+ resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.2':
+ resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==}
+ cpu: [arm]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.2':
+ resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==}
+ cpu: [arm]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.2':
+ resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-arm64-musl@4.62.2':
+ resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.2':
+ resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-loong64-musl@4.62.2':
+ resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==}
+ cpu: [loong64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.2':
+ resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.2':
+ resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==}
+ cpu: [ppc64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.2':
+ resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.2':
+ resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.2':
+ resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==}
+ cpu: [s390x]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-gnu@4.62.2':
+ resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@rollup/rollup-linux-x64-musl@4.62.2':
+ resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@rollup/rollup-openbsd-x64@4.62.2':
+ resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.62.2':
+ resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.2':
+ resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.2':
+ resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.62.2':
+ resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.62.2':
+ resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@silvia-odwyer/photon-node@0.3.4':
+ resolution: {integrity: sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==}
+
+ '@smithy/core@3.26.0':
+ resolution: {integrity: sha512-mLUktFAn+Pa2agl1J7VgtYNFWCX8/b4GMJSK1hCu4YCvtBfM6F8Os3EP4ry+DFFlXOf3wyvlgXhuUdFoy52D3g==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/credential-provider-imds@4.4.2':
+ resolution: {integrity: sha512-18UMDMyrAbDcpmL1gLUA7ww0fRTcdCrSjSJOi2Sbld+tVjwD/pW+OAwjlScFLR7vvBnhZrIPQ7kVuTf1mnJLug==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/fetch-http-handler@5.5.2':
+ resolution: {integrity: sha512-Ei/UK/QMhq0rKaMqGPlOAkE2yS9DZeYmZdk1RAKc3vp3zxgleZHZyBLlZv8yLsxljX4svCRuMTD6u3LLIcU4Bg==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/is-array-buffer@2.2.0':
+ resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==}
+ engines: {node: '>=14.0.0'}
+
+ '@smithy/node-http-handler@4.7.3':
+ resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/node-http-handler@4.8.2':
+ resolution: {integrity: sha512-wfl1uwrAqMH9/pi4kqBo5LBcFwrJLxuDLqL7p7qNcJIFcyZDUc6pzhYk4CYv+DP7fIUpQCZumwNnkhPKS52osQ==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/signature-v4@5.5.2':
+ resolution: {integrity: sha512-7xHpmPY4rt0IOmeAA8EfjgEH8isT+587TCdy9H6a7d4OMi5CQ0oEHhWllunvPu4j4Cq0vTFwdxXN/kABWPjdyA==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/types@4.15.0':
+ resolution: {integrity: sha512-Z5TAOxygoFvybJV3igo5SloFflSokHx2hu1eFA+DxDTcn+FtKxUSui+rbTRG1pAafMA888Z3MVvCWUuvCrTXjg==}
+ engines: {node: '>=18.0.0'}
+
+ '@smithy/util-buffer-from@2.2.0':
+ resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==}
+ engines: {node: '>=14.0.0'}
+
+ '@smithy/util-utf8@2.3.0':
+ resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==}
+ engines: {node: '>=14.0.0'}
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@tauri-apps/api@2.11.1':
+ resolution: {integrity: sha512-M2FPuYND2m+wh5hfW9ZpSdxMPdEJovPBWwoHJmwUpysTYNHaOkVFN419m/K0LIgjb/7KU2vBgsUepJWugQCvAA==}
+
+ '@tauri-apps/cli-darwin-arm64@2.11.3':
+ resolution: {integrity: sha512-BxpaM8bsCoXs3wd4WKYhas/G1gs7+r7B+e4WnyRk2GEoVOouJB1hoL6E6YLXZDXbYci6VFdrNnobQwd2uVL4ew==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tauri-apps/cli-darwin-x64@2.11.3':
+ resolution: {integrity: sha512-DbZYuPB1ZEzcAHYeyCvo3ltzM27+aXwPloCrtexPnmgPgulYJm3TOq6aC4S+wPhSXteddg8zImtNkvx/gQzmwg==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tauri-apps/cli-linux-arm-gnueabihf@2.11.3':
+ resolution: {integrity: sha512-741NduqBmz1XkdU8yz3OI/kBZtqHbvxo9F9ytIeWYU69/Ba9dcZEbqOU++Dp0G/XU8vAI0TfTywEl+p+BbLvaA==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tauri-apps/cli-linux-arm64-gnu@2.11.3':
+ resolution: {integrity: sha512-RWAXT8pTqIczXcoic+LXlo6uEbAXGB0cgh6Pg7Y9xVnEbzryQ1JHtRGj9SxzrKSemBIDBH6Qc24kK2G69i8ofA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tauri-apps/cli-linux-arm64-musl@2.11.3':
+ resolution: {integrity: sha512-qomqYS+yAkd0gXMRmhguWXc7RfVN+XKKXaEwbf5QmKURwydLFOTldd6F8/WoZDSsBMrV8dpNxz0YneGLmobiSA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+ libc: [musl]
+
+ '@tauri-apps/cli-linux-riscv64-gnu@2.11.3':
+ resolution: {integrity: sha512-jOCXbDqeDj5XcclsOBAaXjtTgwZCVg8zEZ+dbPUCoADOgljFgL0rOkYTc96vUYgOrYEfuHYihWMxIDGaD6GwJw==}
+ engines: {node: '>= 10'}
+ cpu: [riscv64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tauri-apps/cli-linux-x64-gnu@2.11.3':
+ resolution: {integrity: sha512-+u3HO/F3gHwL48t9gWN/urqZvpaEJzBFmTaq5eSIhvy8TOvnhb+LgJr3Q3BG+5JxuBrCUjqtOEz6gMttdJFSBA==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [glibc]
+
+ '@tauri-apps/cli-linux-x64-musl@2.11.3':
+ resolution: {integrity: sha512-spr5Jpr6KF/vehkLwJ0YmdGv8QwpWU+uw7J8bgijO0sox6ZCYsSNMbcsQjTqPi4xl+p0woIYpWXgChgHYpAc8g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+ libc: [musl]
+
+ '@tauri-apps/cli-win32-arm64-msvc@2.11.3':
+ resolution: {integrity: sha512-abkoRQih5xBa3vz2spWaex0kP/MzVzVPQHom2f8jnCq46R/luOD6Uy85EMU9/bfzf6ZzdorWJsgO+OMX90Fx2w==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tauri-apps/cli-win32-ia32-msvc@2.11.3':
+ resolution: {integrity: sha512-Vy6AvzFm1G40hg3r+OYDB3jkuu7R4wnMzbQBKuun9v6Cgg8IierpLL7toMzrZKs/8NlG8Sg4x1iLFR52oknyHg==}
+ engines: {node: '>= 10'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@tauri-apps/cli-win32-x64-msvc@2.11.3':
+ resolution: {integrity: sha512-GlciF75GdbseajOyib2aCHwE3BXIqZ1liGKWLFRvCdN5wm8h8hFssEVKQ/6E+2jsMLg9v7LCTb983YFnn0QSww==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tauri-apps/cli@2.11.3':
+ resolution: {integrity: sha512-EElQe8z8uD7Pi5++tJ/UfEwWuK08rd3oCDYdeIbJAb6pZRrxlqmoF5gh5H5YvzmUPhS4IRCaLSsQhvWkrfK+GQ==}
+ engines: {node: '>= 10'}
+ hasBin: true
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/node@26.0.1':
+ resolution: {integrity: sha512-fc3KiUoBt6kie0N9bIW3E47vZsuaMf0PM2AaUpLCLT0s/LvX1nxAim6Fc049cNxODPpGm6qRAuUOB86SkRuPQw==}
+
+ '@types/retry@0.12.0':
+ resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==}
+
+ '@vitest/expect@4.1.9':
+ resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==}
+
+ '@vitest/mocker@4.1.9':
+ resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@4.1.9':
+ resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==}
+
+ '@vitest/runner@4.1.9':
+ resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==}
+
+ '@vitest/snapshot@4.1.9':
+ resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==}
+
+ '@vitest/spy@4.1.9':
+ resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==}
+
+ '@vitest/utils@4.1.9':
+ resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==}
+
+ agent-base@7.1.4:
+ resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
+ engines: {node: '>= 14'}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ balanced-match@4.0.4:
+ resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
+ engines: {node: 18 || 20 || >=22}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ bidi-js@1.0.3:
+ resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==}
+
+ bignumber.js@9.3.1:
+ resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==}
+
+ bowser@2.14.1:
+ resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==}
+
+ brace-expansion@5.0.6:
+ resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==}
+ engines: {node: 18 || 20 || >=22}
+
+ buffer-equal-constant-time@1.0.1:
+ resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
+
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
+
+ chalk@5.6.2:
+ resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
+ css-tree@3.2.1:
+ resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==}
+ engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
+
+ data-uri-to-buffer@4.0.1:
+ resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
+ engines: {node: '>= 12'}
+
+ data-urls@7.0.0:
+ resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decimal.js@10.6.0:
+ resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==}
+
+ diff@8.0.4:
+ resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==}
+ engines: {node: '>=0.3.1'}
+
+ ecdsa-sig-formatter@1.0.11:
+ resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
+
+ entities@8.0.0:
+ resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==}
+ engines: {node: '>=20.19.0'}
+
+ es-module-lexer@2.1.0:
+ resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==}
+
+ esbuild@0.28.1:
+ resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ expect-type@1.3.0:
+ resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
+ engines: {node: '>=12.0.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ fetch-blob@3.2.0:
+ resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
+ engines: {node: ^12.20 || >= 14.13}
+
+ formdata-polyfill@4.0.10:
+ resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
+ engines: {node: '>=12.20.0'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ gaxios@7.1.5:
+ resolution: {integrity: sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==}
+ engines: {node: '>=18'}
+
+ gcp-metadata@8.1.2:
+ resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==}
+ engines: {node: '>=18'}
+
+ get-east-asian-width@1.6.0:
+ resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==}
+ engines: {node: '>=18'}
+
+ glob@13.0.6:
+ resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
+ engines: {node: 18 || 20 || >=22}
+
+ google-auth-library@10.7.0:
+ resolution: {integrity: sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==}
+ engines: {node: '>=18'}
+
+ google-logging-utils@1.1.3:
+ resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==}
+ engines: {node: '>=14'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ highlight.js@10.7.3:
+ resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==}
+
+ hosted-git-info@9.0.3:
+ resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==}
+ engines: {node: ^20.17.0 || >=22.9.0}
+
+ html-encoding-sniffer@6.0.0:
+ resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ http-proxy-agent@7.0.2:
+ resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==}
+ engines: {node: '>= 14'}
+
+ https-proxy-agent@7.0.6:
+ resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
+ engines: {node: '>= 14'}
+
+ ignore@7.0.5:
+ resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
+ engines: {node: '>= 4'}
+
+ is-potential-custom-element-name@1.0.1:
+ resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jiti@2.7.0:
+ resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
+ hasBin: true
+
+ jsdom@29.1.1:
+ resolution: {integrity: sha512-ECi4Fi2f7BdJtUKTflYRTiaMxIB0O6zfR1fX0GXpUrf6flp8QIYn1UT20YQqdSOfk2dfkCwS8LAFoJDEppNK5Q==}
+ engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0}
+ peerDependencies:
+ canvas: ^3.0.0
+ peerDependenciesMeta:
+ canvas:
+ optional: true
+
+ json-bigint@1.0.0:
+ resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
+
+ json-schema-to-ts@3.1.1:
+ resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
+ engines: {node: '>=16'}
+
+ jwa@2.0.1:
+ resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
+
+ jws@4.0.1:
+ resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
+
+ long@5.3.2:
+ resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
+
+ lru-cache@11.5.1:
+ resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==}
+ engines: {node: 20 || >=22}
+
+ lucide-static@1.21.0:
+ resolution: {integrity: sha512-6248z2/4sEyKkYAPPUYxOPiB2RCfMmLdMHuoOhsTFnoD40ixAoHmTVhOPux8ADa1NTBmzpEKF7WNePm+Ms503Q==}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ marked@18.0.5:
+ resolution: {integrity: sha512-S6GcvALHg6K4ohtu4E7x0a1AqhAjp6cV8KhLSyN9qVapnzJkusVBxZRcIU9AeYsbe6P1hKDusSbEOzGyyuce6w==}
+ engines: {node: '>= 20'}
+ hasBin: true
+
+ mdn-data@2.27.1:
+ resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==}
+
+ minimatch@10.2.5:
+ resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
+ engines: {node: 18 || 20 || >=22}
+
+ minipass@7.1.3:
+ resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ nanoid@3.3.15:
+ resolution: {integrity: sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node-domexception@1.0.0:
+ resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+ engines: {node: '>=10.5.0'}
+ deprecated: Use your platform's native DOMException instead
+
+ node-fetch@3.3.2:
+ resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ obug@2.1.3:
+ resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==}
+ engines: {node: '>=12.20.0'}
+
+ openai@6.26.0:
+ resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==}
+ hasBin: true
+ peerDependencies:
+ ws: ^8.18.0
+ zod: ^3.25 || ^4.0
+ peerDependenciesMeta:
+ ws:
+ optional: true
+ zod:
+ optional: true
+
+ p-retry@4.6.2:
+ resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==}
+ engines: {node: '>=8'}
+
+ parse5@8.0.1:
+ resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==}
+
+ partial-json@0.1.7:
+ resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-scurry@2.0.2:
+ resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
+ engines: {node: 18 || 20 || >=22}
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.4:
+ resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
+ engines: {node: '>=12'}
+
+ postcss@8.5.15:
+ resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ proper-lockfile@4.1.2:
+ resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==}
+
+ protobufjs@7.6.4:
+ resolution: {integrity: sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==}
+ engines: {node: '>=12.0.0'}
+
+ punycode@2.3.1:
+ resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
+ engines: {node: '>=6'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ retry@0.12.0:
+ resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
+ engines: {node: '>= 4'}
+
+ retry@0.13.1:
+ resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
+ engines: {node: '>= 4'}
+
+ rollup@4.62.2:
+ resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ saxes@6.0.0:
+ resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
+ engines: {node: '>=v12.22.7'}
+
+ semver@7.8.0:
+ resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ signal-exit@3.0.7:
+ resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.1.0:
+ resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==}
+
+ symbol-tree@3.2.4:
+ resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@1.2.4:
+ resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinyrainbow@3.1.0:
+ resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==}
+ engines: {node: '>=14.0.0'}
+
+ tldts-core@7.4.4:
+ resolution: {integrity: sha512-vwVLJVvvpslm7vqAH7+XNj/neA/Ynq7DT2EEcMuwc5YzN5XaMyRAqxwU+uX3azZ1FQtB2gvrvnLnAEkvYlVdfg==}
+
+ tldts@7.4.4:
+ resolution: {integrity: sha512-kFXFK7O4WPextIUAOk8qtnw9dxR9UIXP9CjuH1cTBVBZMDeQcUPgr/IazGiw1B0Yiw5L75gHLWeW4iD793r90g==}
+ hasBin: true
+
+ tough-cookie@6.0.1:
+ resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==}
+ engines: {node: '>=16'}
+
+ tr46@6.0.0:
+ resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==}
+ engines: {node: '>=20'}
+
+ ts-algebra@2.0.0:
+ resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
+
+ tslib@2.8.1:
+ resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
+
+ typebox@1.1.38:
+ resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==}
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ undici-types@8.3.0:
+ resolution: {integrity: sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==}
+
+ undici@7.28.0:
+ resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==}
+ engines: {node: '>=20.18.1'}
+
+ undici@8.5.0:
+ resolution: {integrity: sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==}
+ engines: {node: '>=22.19.0'}
+
+ vite@7.3.5:
+ resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ lightningcss: ^1.21.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@4.1.9:
+ resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.1.9
+ '@vitest/browser-preview': 4.1.9
+ '@vitest/browser-webdriverio': 4.1.9
+ '@vitest/coverage-istanbul': 4.1.9
+ '@vitest/coverage-v8': 4.1.9
+ '@vitest/ui': 4.1.9
+ happy-dom: '*'
+ jsdom: '*'
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ w3c-xmlserializer@5.0.0:
+ resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
+ engines: {node: '>=18'}
+
+ web-streams-polyfill@3.3.3:
+ resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
+ engines: {node: '>= 8'}
+
+ webidl-conversions@8.0.1:
+ resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==}
+ engines: {node: '>=20'}
+
+ whatwg-mimetype@5.0.0:
+ resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==}
+ engines: {node: '>=20'}
+
+ whatwg-url@16.0.1:
+ resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==}
+ engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ ws@8.21.0:
+ resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==}
+ engines: {node: '>=10.0.0'}
+ peerDependencies:
+ bufferutil: ^4.0.1
+ utf-8-validate: '>=5.0.2'
+ peerDependenciesMeta:
+ bufferutil:
+ optional: true
+ utf-8-validate:
+ optional: true
+
+ xml-name-validator@5.0.0:
+ resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
+ engines: {node: '>=18'}
+
+ xmlchars@2.2.0:
+ resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
+
+ yaml@2.9.0:
+ resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
+ engines: {node: '>= 14.6'}
+ hasBin: true
+
+ zod-to-json-schema@3.25.2:
+ resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
+ peerDependencies:
+ zod: ^3.25.28 || ^4
+
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+
+snapshots:
+
+ '@anthropic-ai/sdk@0.91.1(zod@4.4.3)':
+ dependencies:
+ json-schema-to-ts: 3.1.1
+ optionalDependencies:
+ zod: 4.4.3
+
+ '@asamuzakjp/css-color@5.1.11':
+ dependencies:
+ '@asamuzakjp/generational-cache': 1.0.1
+ '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-color-parser': 4.1.8(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@asamuzakjp/dom-selector@7.1.1':
+ dependencies:
+ '@asamuzakjp/generational-cache': 1.0.1
+ '@asamuzakjp/nwsapi': 2.3.9
+ bidi-js: 1.0.3
+ css-tree: 3.2.1
+ is-potential-custom-element-name: 1.0.1
+
+ '@asamuzakjp/generational-cache@1.0.1': {}
+
+ '@asamuzakjp/nwsapi@2.3.9': {}
+
+ '@aws-crypto/crc32@5.2.0':
+ dependencies:
+ '@aws-crypto/util': 5.2.0
+ '@aws-sdk/types': 3.973.13
+ tslib: 2.8.1
+
+ '@aws-crypto/sha256-browser@5.2.0':
+ dependencies:
+ '@aws-crypto/sha256-js': 5.2.0
+ '@aws-crypto/supports-web-crypto': 5.2.0
+ '@aws-crypto/util': 5.2.0
+ '@aws-sdk/types': 3.973.13
+ '@aws-sdk/util-locate-window': 3.965.8
+ '@smithy/util-utf8': 2.3.0
+ tslib: 2.8.1
+
+ '@aws-crypto/sha256-js@5.2.0':
+ dependencies:
+ '@aws-crypto/util': 5.2.0
+ '@aws-sdk/types': 3.973.13
+ tslib: 2.8.1
+
+ '@aws-crypto/supports-web-crypto@5.2.0':
+ dependencies:
+ tslib: 2.8.1
+
+ '@aws-crypto/util@5.2.0':
+ dependencies:
+ '@aws-sdk/types': 3.973.13
+ '@smithy/util-utf8': 2.3.0
+ tslib: 2.8.1
+
+ '@aws-sdk/client-bedrock-runtime@3.1048.0':
+ dependencies:
+ '@aws-crypto/sha256-browser': 5.2.0
+ '@aws-crypto/sha256-js': 5.2.0
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/credential-provider-node': 3.972.58
+ '@aws-sdk/eventstream-handler-node': 3.972.22
+ '@aws-sdk/middleware-eventstream': 3.972.18
+ '@aws-sdk/middleware-websocket': 3.972.31
+ '@aws-sdk/token-providers': 3.1048.0
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/fetch-http-handler': 5.5.2
+ '@smithy/node-http-handler': 4.8.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/core@3.974.23':
+ dependencies:
+ '@aws-sdk/types': 3.973.13
+ '@aws-sdk/xml-builder': 3.972.31
+ '@aws/lambda-invoke-store': 0.2.4
+ '@smithy/core': 3.26.0
+ '@smithy/signature-v4': 5.5.2
+ '@smithy/types': 4.15.0
+ bowser: 2.14.1
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-env@3.972.49':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-http@3.972.51':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/fetch-http-handler': 5.5.2
+ '@smithy/node-http-handler': 4.8.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-ini@3.972.56':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/credential-provider-env': 3.972.49
+ '@aws-sdk/credential-provider-http': 3.972.51
+ '@aws-sdk/credential-provider-login': 3.972.55
+ '@aws-sdk/credential-provider-process': 3.972.49
+ '@aws-sdk/credential-provider-sso': 3.972.55
+ '@aws-sdk/credential-provider-web-identity': 3.972.55
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/credential-provider-imds': 4.4.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-login@3.972.55':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-node@3.972.58':
+ dependencies:
+ '@aws-sdk/credential-provider-env': 3.972.49
+ '@aws-sdk/credential-provider-http': 3.972.51
+ '@aws-sdk/credential-provider-ini': 3.972.56
+ '@aws-sdk/credential-provider-process': 3.972.49
+ '@aws-sdk/credential-provider-sso': 3.972.55
+ '@aws-sdk/credential-provider-web-identity': 3.972.55
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/credential-provider-imds': 4.4.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-process@3.972.49':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-sso@3.972.55':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/token-providers': 3.1074.0
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/credential-provider-web-identity@3.972.55':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/eventstream-handler-node@3.972.22':
+ dependencies:
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/middleware-eventstream@3.972.18':
+ dependencies:
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/middleware-websocket@3.972.31':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/fetch-http-handler': 5.5.2
+ '@smithy/signature-v4': 5.5.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/nested-clients@3.997.23':
+ dependencies:
+ '@aws-crypto/sha256-browser': 5.2.0
+ '@aws-crypto/sha256-js': 5.2.0
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/signature-v4-multi-region': 3.996.35
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/fetch-http-handler': 5.5.2
+ '@smithy/node-http-handler': 4.8.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/signature-v4-multi-region@3.996.35':
+ dependencies:
+ '@aws-sdk/types': 3.973.13
+ '@smithy/signature-v4': 5.5.2
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/token-providers@3.1048.0':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/token-providers@3.1074.0':
+ dependencies:
+ '@aws-sdk/core': 3.974.23
+ '@aws-sdk/nested-clients': 3.997.23
+ '@aws-sdk/types': 3.973.13
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/types@3.973.13':
+ dependencies:
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws-sdk/util-locate-window@3.965.8':
+ dependencies:
+ tslib: 2.8.1
+
+ '@aws-sdk/xml-builder@3.972.31':
+ dependencies:
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@aws/lambda-invoke-store@0.2.4': {}
+
+ '@babel/runtime@7.29.7': {}
+
+ '@bramus/specificity@2.4.2':
+ dependencies:
+ css-tree: 3.2.1
+
+ '@csstools/color-helpers@6.0.2': {}
+
+ '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-color-parser@4.1.8(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/color-helpers': 6.0.2
+ '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0)
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)':
+ dependencies:
+ '@csstools/css-tokenizer': 4.0.0
+
+ '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)':
+ optionalDependencies:
+ css-tree: 3.2.1
+
+ '@csstools/css-tokenizer@4.0.0': {}
+
+ '@earendil-works/pi-agent-core@0.80.2(ws@8.21.0)(zod@4.4.3)':
+ dependencies:
+ '@earendil-works/pi-ai': 0.80.2(ws@8.21.0)(zod@4.4.3)
+ ignore: 7.0.5
+ typebox: 1.1.38
+ yaml: 2.9.0
+ transitivePeerDependencies:
+ - '@modelcontextprotocol/sdk'
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ - ws
+ - zod
+
+ '@earendil-works/pi-ai@0.80.2(ws@8.21.0)(zod@4.4.3)':
+ dependencies:
+ '@anthropic-ai/sdk': 0.91.1(zod@4.4.3)
+ '@aws-sdk/client-bedrock-runtime': 3.1048.0
+ '@google/genai': 1.52.0
+ '@mistralai/mistralai': 2.2.6(@opentelemetry/api@1.9.0)
+ '@opentelemetry/api': 1.9.0
+ '@smithy/node-http-handler': 4.7.3
+ http-proxy-agent: 7.0.2
+ https-proxy-agent: 7.0.6
+ openai: 6.26.0(ws@8.21.0)(zod@4.4.3)
+ partial-json: 0.1.7
+ typebox: 1.1.38
+ transitivePeerDependencies:
+ - '@modelcontextprotocol/sdk'
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ - ws
+ - zod
+
+ '@earendil-works/pi-coding-agent@0.80.2(ws@8.21.0)(zod@4.4.3)':
+ dependencies:
+ '@earendil-works/pi-agent-core': 0.80.2(ws@8.21.0)(zod@4.4.3)
+ '@earendil-works/pi-ai': 0.80.2(ws@8.21.0)(zod@4.4.3)
+ '@earendil-works/pi-tui': 0.80.2
+ '@silvia-odwyer/photon-node': 0.3.4
+ chalk: 5.6.2
+ cross-spawn: 7.0.6
+ diff: 8.0.4
+ glob: 13.0.6
+ highlight.js: 10.7.3
+ hosted-git-info: 9.0.3
+ ignore: 7.0.5
+ jiti: 2.7.0
+ minimatch: 10.2.5
+ proper-lockfile: 4.1.2
+ semver: 7.8.0
+ typebox: 1.1.38
+ undici: 8.5.0
+ yaml: 2.9.0
+ optionalDependencies:
+ '@mariozechner/clipboard': 0.3.9
+ transitivePeerDependencies:
+ - '@modelcontextprotocol/sdk'
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+ - ws
+ - zod
+
+ '@earendil-works/pi-tui@0.80.2':
+ dependencies:
+ get-east-asian-width: 1.6.0
+ marked: 18.0.5
+
+ '@esbuild/aix-ppc64@0.28.1':
+ optional: true
+
+ '@esbuild/android-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/android-arm@0.28.1':
+ optional: true
+
+ '@esbuild/android-x64@0.28.1':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/darwin-x64@0.28.1':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-arm@0.28.1':
+ optional: true
+
+ '@esbuild/linux-ia32@0.28.1':
+ optional: true
+
+ '@esbuild/linux-loong64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.28.1':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.28.1':
+ optional: true
+
+ '@esbuild/linux-s390x@0.28.1':
+ optional: true
+
+ '@esbuild/linux-x64@0.28.1':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.28.1':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/sunos-x64@0.28.1':
+ optional: true
+
+ '@esbuild/win32-arm64@0.28.1':
+ optional: true
+
+ '@esbuild/win32-ia32@0.28.1':
+ optional: true
+
+ '@esbuild/win32-x64@0.28.1':
+ optional: true
+
+ '@exodus/bytes@1.15.1': {}
+
+ '@google/genai@1.52.0':
+ dependencies:
+ google-auth-library: 10.7.0
+ p-retry: 4.6.2
+ protobufjs: 7.6.4
+ ws: 8.21.0
+ transitivePeerDependencies:
+ - bufferutil
+ - supports-color
+ - utf-8-validate
+
+ '@hypabolic/hypa-darwin-arm64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa-darwin-x64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa-linux-arm64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa-linux-x64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa-win32-arm64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa-win32-x64@0.1.6':
+ optional: true
+
+ '@hypabolic/hypa@0.1.6':
+ optionalDependencies:
+ '@hypabolic/hypa-darwin-arm64': 0.1.6
+ '@hypabolic/hypa-darwin-x64': 0.1.6
+ '@hypabolic/hypa-linux-arm64': 0.1.6
+ '@hypabolic/hypa-linux-x64': 0.1.6
+ '@hypabolic/hypa-win32-arm64': 0.1.6
+ '@hypabolic/hypa-win32-x64': 0.1.6
+
+ '@hypabolic/pi-hypa@0.1.6(@earendil-works/pi-coding-agent@0.80.2(ws@8.21.0)(zod@4.4.3))':
+ dependencies:
+ '@earendil-works/pi-coding-agent': 0.80.2(ws@8.21.0)(zod@4.4.3)
+ '@hypabolic/hypa': 0.1.6
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@mariozechner/clipboard-darwin-arm64@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-darwin-universal@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-darwin-x64@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-linux-arm64-gnu@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-linux-arm64-musl@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-linux-riscv64-gnu@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-linux-x64-gnu@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-linux-x64-musl@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-win32-arm64-msvc@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard-win32-x64-msvc@0.3.9':
+ optional: true
+
+ '@mariozechner/clipboard@0.3.9':
+ optionalDependencies:
+ '@mariozechner/clipboard-darwin-arm64': 0.3.9
+ '@mariozechner/clipboard-darwin-universal': 0.3.9
+ '@mariozechner/clipboard-darwin-x64': 0.3.9
+ '@mariozechner/clipboard-linux-arm64-gnu': 0.3.9
+ '@mariozechner/clipboard-linux-arm64-musl': 0.3.9
+ '@mariozechner/clipboard-linux-riscv64-gnu': 0.3.9
+ '@mariozechner/clipboard-linux-x64-gnu': 0.3.9
+ '@mariozechner/clipboard-linux-x64-musl': 0.3.9
+ '@mariozechner/clipboard-win32-arm64-msvc': 0.3.9
+ '@mariozechner/clipboard-win32-x64-msvc': 0.3.9
+ optional: true
+
+ '@mistralai/mistralai@2.2.6(@opentelemetry/api@1.9.0)':
+ dependencies:
+ '@opentelemetry/semantic-conventions': 1.41.1
+ ws: 8.21.0
+ zod: 4.4.3
+ zod-to-json-schema: 3.25.2(zod@4.4.3)
+ optionalDependencies:
+ '@opentelemetry/api': 1.9.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+
+ '@opentelemetry/api@1.9.0': {}
+
+ '@opentelemetry/semantic-conventions@1.41.1': {}
+
+ '@protobufjs/aspromise@1.1.2': {}
+
+ '@protobufjs/base64@1.1.2': {}
+
+ '@protobufjs/codegen@2.0.5': {}
+
+ '@protobufjs/eventemitter@1.1.1': {}
+
+ '@protobufjs/fetch@1.1.1':
+ dependencies:
+ '@protobufjs/aspromise': 1.1.2
+
+ '@protobufjs/float@1.0.2': {}
+
+ '@protobufjs/path@1.1.2': {}
+
+ '@protobufjs/pool@1.1.0': {}
+
+ '@protobufjs/utf8@1.1.1': {}
+
+ '@rollup/rollup-android-arm-eabi@4.62.2':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.62.2':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.62.2':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.2':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.62.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.62.2':
+ optional: true
+
+ '@silvia-odwyer/photon-node@0.3.4': {}
+
+ '@smithy/core@3.26.0':
+ dependencies:
+ '@aws-crypto/crc32': 5.2.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/credential-provider-imds@4.4.2':
+ dependencies:
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/fetch-http-handler@5.5.2':
+ dependencies:
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/is-array-buffer@2.2.0':
+ dependencies:
+ tslib: 2.8.1
+
+ '@smithy/node-http-handler@4.7.3':
+ dependencies:
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/node-http-handler@4.8.2':
+ dependencies:
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/signature-v4@5.5.2':
+ dependencies:
+ '@smithy/core': 3.26.0
+ '@smithy/types': 4.15.0
+ tslib: 2.8.1
+
+ '@smithy/types@4.15.0':
+ dependencies:
+ tslib: 2.8.1
+
+ '@smithy/util-buffer-from@2.2.0':
+ dependencies:
+ '@smithy/is-array-buffer': 2.2.0
+ tslib: 2.8.1
+
+ '@smithy/util-utf8@2.3.0':
+ dependencies:
+ '@smithy/util-buffer-from': 2.2.0
+ tslib: 2.8.1
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@tauri-apps/api@2.11.1': {}
+
+ '@tauri-apps/cli-darwin-arm64@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-darwin-x64@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-arm-gnueabihf@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-arm64-gnu@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-arm64-musl@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-riscv64-gnu@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-x64-gnu@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-linux-x64-musl@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-win32-arm64-msvc@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-win32-ia32-msvc@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli-win32-x64-msvc@2.11.3':
+ optional: true
+
+ '@tauri-apps/cli@2.11.3':
+ optionalDependencies:
+ '@tauri-apps/cli-darwin-arm64': 2.11.3
+ '@tauri-apps/cli-darwin-x64': 2.11.3
+ '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.3
+ '@tauri-apps/cli-linux-arm64-gnu': 2.11.3
+ '@tauri-apps/cli-linux-arm64-musl': 2.11.3
+ '@tauri-apps/cli-linux-riscv64-gnu': 2.11.3
+ '@tauri-apps/cli-linux-x64-gnu': 2.11.3
+ '@tauri-apps/cli-linux-x64-musl': 2.11.3
+ '@tauri-apps/cli-win32-arm64-msvc': 2.11.3
+ '@tauri-apps/cli-win32-ia32-msvc': 2.11.3
+ '@tauri-apps/cli-win32-x64-msvc': 2.11.3
+
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/estree@1.0.9': {}
+
+ '@types/node@26.0.1':
+ dependencies:
+ undici-types: 8.3.0
+
+ '@types/retry@0.12.0': {}
+
+ '@vitest/expect@4.1.9':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.1.9
+ '@vitest/utils': 4.1.9
+ chai: 6.2.2
+ tinyrainbow: 3.1.0
+
+ '@vitest/mocker@4.1.9(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0))':
+ dependencies:
+ '@vitest/spy': 4.1.9
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0)
+
+ '@vitest/pretty-format@4.1.9':
+ dependencies:
+ tinyrainbow: 3.1.0
+
+ '@vitest/runner@4.1.9':
+ dependencies:
+ '@vitest/utils': 4.1.9
+ pathe: 2.0.3
+
+ '@vitest/snapshot@4.1.9':
+ dependencies:
+ '@vitest/pretty-format': 4.1.9
+ '@vitest/utils': 4.1.9
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@4.1.9': {}
+
+ '@vitest/utils@4.1.9':
+ dependencies:
+ '@vitest/pretty-format': 4.1.9
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.0
+
+ agent-base@7.1.4: {}
+
+ assertion-error@2.0.1: {}
+
+ balanced-match@4.0.4: {}
+
+ base64-js@1.5.1: {}
+
+ bidi-js@1.0.3:
+ dependencies:
+ require-from-string: 2.0.2
+
+ bignumber.js@9.3.1: {}
+
+ bowser@2.14.1: {}
+
+ brace-expansion@5.0.6:
+ dependencies:
+ balanced-match: 4.0.4
+
+ buffer-equal-constant-time@1.0.1: {}
+
+ chai@6.2.2: {}
+
+ chalk@5.6.2: {}
+
+ convert-source-map@2.0.0: {}
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ css-tree@3.2.1:
+ dependencies:
+ mdn-data: 2.27.1
+ source-map-js: 1.2.1
+
+ data-uri-to-buffer@4.0.1: {}
+
+ data-urls@7.0.0:
+ dependencies:
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ decimal.js@10.6.0: {}
+
+ diff@8.0.4: {}
+
+ ecdsa-sig-formatter@1.0.11:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ entities@8.0.0: {}
+
+ es-module-lexer@2.1.0: {}
+
+ esbuild@0.28.1:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.28.1
+ '@esbuild/android-arm': 0.28.1
+ '@esbuild/android-arm64': 0.28.1
+ '@esbuild/android-x64': 0.28.1
+ '@esbuild/darwin-arm64': 0.28.1
+ '@esbuild/darwin-x64': 0.28.1
+ '@esbuild/freebsd-arm64': 0.28.1
+ '@esbuild/freebsd-x64': 0.28.1
+ '@esbuild/linux-arm': 0.28.1
+ '@esbuild/linux-arm64': 0.28.1
+ '@esbuild/linux-ia32': 0.28.1
+ '@esbuild/linux-loong64': 0.28.1
+ '@esbuild/linux-mips64el': 0.28.1
+ '@esbuild/linux-ppc64': 0.28.1
+ '@esbuild/linux-riscv64': 0.28.1
+ '@esbuild/linux-s390x': 0.28.1
+ '@esbuild/linux-x64': 0.28.1
+ '@esbuild/netbsd-arm64': 0.28.1
+ '@esbuild/netbsd-x64': 0.28.1
+ '@esbuild/openbsd-arm64': 0.28.1
+ '@esbuild/openbsd-x64': 0.28.1
+ '@esbuild/openharmony-arm64': 0.28.1
+ '@esbuild/sunos-x64': 0.28.1
+ '@esbuild/win32-arm64': 0.28.1
+ '@esbuild/win32-ia32': 0.28.1
+ '@esbuild/win32-x64': 0.28.1
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ expect-type@1.3.0: {}
+
+ extend@3.0.2: {}
+
+ fdir@6.5.0(picomatch@4.0.4):
+ optionalDependencies:
+ picomatch: 4.0.4
+
+ fetch-blob@3.2.0:
+ dependencies:
+ node-domexception: 1.0.0
+ web-streams-polyfill: 3.3.3
+
+ formdata-polyfill@4.0.10:
+ dependencies:
+ fetch-blob: 3.2.0
+
+ fsevents@2.3.3:
+ optional: true
+
+ gaxios@7.1.5:
+ dependencies:
+ extend: 3.0.2
+ https-proxy-agent: 7.0.6
+ node-fetch: 3.3.2
+ transitivePeerDependencies:
+ - supports-color
+
+ gcp-metadata@8.1.2:
+ dependencies:
+ gaxios: 7.1.5
+ google-logging-utils: 1.1.3
+ json-bigint: 1.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ get-east-asian-width@1.6.0: {}
+
+ glob@13.0.6:
+ dependencies:
+ minimatch: 10.2.5
+ minipass: 7.1.3
+ path-scurry: 2.0.2
+
+ google-auth-library@10.7.0:
+ dependencies:
+ base64-js: 1.5.1
+ ecdsa-sig-formatter: 1.0.11
+ gaxios: 7.1.5
+ gcp-metadata: 8.1.2
+ google-logging-utils: 1.1.3
+ jws: 4.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ google-logging-utils@1.1.3: {}
+
+ graceful-fs@4.2.11: {}
+
+ highlight.js@10.7.3: {}
+
+ hosted-git-info@9.0.3:
+ dependencies:
+ lru-cache: 11.5.1
+
+ html-encoding-sniffer@6.0.0:
+ dependencies:
+ '@exodus/bytes': 1.15.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ http-proxy-agent@7.0.2:
+ dependencies:
+ agent-base: 7.1.4
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ https-proxy-agent@7.0.6:
+ dependencies:
+ agent-base: 7.1.4
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ ignore@7.0.5: {}
+
+ is-potential-custom-element-name@1.0.1: {}
+
+ isexe@2.0.0: {}
+
+ jiti@2.7.0: {}
+
+ jsdom@29.1.1:
+ dependencies:
+ '@asamuzakjp/css-color': 5.1.11
+ '@asamuzakjp/dom-selector': 7.1.1
+ '@bramus/specificity': 2.4.2
+ '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1)
+ '@exodus/bytes': 1.15.1
+ css-tree: 3.2.1
+ data-urls: 7.0.0
+ decimal.js: 10.6.0
+ html-encoding-sniffer: 6.0.0
+ is-potential-custom-element-name: 1.0.1
+ lru-cache: 11.5.1
+ parse5: 8.0.1
+ saxes: 6.0.0
+ symbol-tree: 3.2.4
+ tough-cookie: 6.0.1
+ undici: 7.28.0
+ w3c-xmlserializer: 5.0.0
+ webidl-conversions: 8.0.1
+ whatwg-mimetype: 5.0.0
+ whatwg-url: 16.0.1
+ xml-name-validator: 5.0.0
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ json-bigint@1.0.0:
+ dependencies:
+ bignumber.js: 9.3.1
+
+ json-schema-to-ts@3.1.1:
+ dependencies:
+ '@babel/runtime': 7.29.7
+ ts-algebra: 2.0.0
+
+ jwa@2.0.1:
+ dependencies:
+ buffer-equal-constant-time: 1.0.1
+ ecdsa-sig-formatter: 1.0.11
+ safe-buffer: 5.2.1
+
+ jws@4.0.1:
+ dependencies:
+ jwa: 2.0.1
+ safe-buffer: 5.2.1
+
+ long@5.3.2: {}
+
+ lru-cache@11.5.1: {}
+
+ lucide-static@1.21.0: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ marked@18.0.5: {}
+
+ mdn-data@2.27.1: {}
+
+ minimatch@10.2.5:
+ dependencies:
+ brace-expansion: 5.0.6
+
+ minipass@7.1.3: {}
+
+ ms@2.1.3: {}
+
+ nanoid@3.3.15: {}
+
+ node-domexception@1.0.0: {}
+
+ node-fetch@3.3.2:
+ dependencies:
+ data-uri-to-buffer: 4.0.1
+ fetch-blob: 3.2.0
+ formdata-polyfill: 4.0.10
+
+ obug@2.1.3: {}
+
+ openai@6.26.0(ws@8.21.0)(zod@4.4.3):
+ optionalDependencies:
+ ws: 8.21.0
+ zod: 4.4.3
+
+ p-retry@4.6.2:
+ dependencies:
+ '@types/retry': 0.12.0
+ retry: 0.13.1
+
+ parse5@8.0.1:
+ dependencies:
+ entities: 8.0.0
+
+ partial-json@0.1.7: {}
+
+ path-key@3.1.1: {}
+
+ path-scurry@2.0.2:
+ dependencies:
+ lru-cache: 11.5.1
+ minipass: 7.1.3
+
+ pathe@2.0.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.4: {}
+
+ postcss@8.5.15:
+ dependencies:
+ nanoid: 3.3.15
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ proper-lockfile@4.1.2:
+ dependencies:
+ graceful-fs: 4.2.11
+ retry: 0.12.0
+ signal-exit: 3.0.7
+
+ protobufjs@7.6.4:
+ dependencies:
+ '@protobufjs/aspromise': 1.1.2
+ '@protobufjs/base64': 1.1.2
+ '@protobufjs/codegen': 2.0.5
+ '@protobufjs/eventemitter': 1.1.1
+ '@protobufjs/fetch': 1.1.1
+ '@protobufjs/float': 1.0.2
+ '@protobufjs/path': 1.1.2
+ '@protobufjs/pool': 1.1.0
+ '@protobufjs/utf8': 1.1.1
+ '@types/node': 26.0.1
+ long: 5.3.2
+
+ punycode@2.3.1: {}
+
+ require-from-string@2.0.2: {}
+
+ retry@0.12.0: {}
+
+ retry@0.13.1: {}
+
+ rollup@4.62.2:
+ dependencies:
+ '@types/estree': 1.0.9
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.62.2
+ '@rollup/rollup-android-arm64': 4.62.2
+ '@rollup/rollup-darwin-arm64': 4.62.2
+ '@rollup/rollup-darwin-x64': 4.62.2
+ '@rollup/rollup-freebsd-arm64': 4.62.2
+ '@rollup/rollup-freebsd-x64': 4.62.2
+ '@rollup/rollup-linux-arm-gnueabihf': 4.62.2
+ '@rollup/rollup-linux-arm-musleabihf': 4.62.2
+ '@rollup/rollup-linux-arm64-gnu': 4.62.2
+ '@rollup/rollup-linux-arm64-musl': 4.62.2
+ '@rollup/rollup-linux-loong64-gnu': 4.62.2
+ '@rollup/rollup-linux-loong64-musl': 4.62.2
+ '@rollup/rollup-linux-ppc64-gnu': 4.62.2
+ '@rollup/rollup-linux-ppc64-musl': 4.62.2
+ '@rollup/rollup-linux-riscv64-gnu': 4.62.2
+ '@rollup/rollup-linux-riscv64-musl': 4.62.2
+ '@rollup/rollup-linux-s390x-gnu': 4.62.2
+ '@rollup/rollup-linux-x64-gnu': 4.62.2
+ '@rollup/rollup-linux-x64-musl': 4.62.2
+ '@rollup/rollup-openbsd-x64': 4.62.2
+ '@rollup/rollup-openharmony-arm64': 4.62.2
+ '@rollup/rollup-win32-arm64-msvc': 4.62.2
+ '@rollup/rollup-win32-ia32-msvc': 4.62.2
+ '@rollup/rollup-win32-x64-gnu': 4.62.2
+ '@rollup/rollup-win32-x64-msvc': 4.62.2
+ fsevents: 2.3.3
+
+ safe-buffer@5.2.1: {}
+
+ saxes@6.0.0:
+ dependencies:
+ xmlchars: 2.2.0
+
+ semver@7.8.0: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ siginfo@2.0.0: {}
+
+ signal-exit@3.0.7: {}
+
+ source-map-js@1.2.1: {}
+
+ stackback@0.0.2: {}
+
+ std-env@4.1.0: {}
+
+ symbol-tree@3.2.4: {}
+
+ tinybench@2.9.0: {}
+
+ tinyexec@1.2.4: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+
+ tinyrainbow@3.1.0: {}
+
+ tldts-core@7.4.4: {}
+
+ tldts@7.4.4:
+ dependencies:
+ tldts-core: 7.4.4
+
+ tough-cookie@6.0.1:
+ dependencies:
+ tldts: 7.4.4
+
+ tr46@6.0.0:
+ dependencies:
+ punycode: 2.3.1
+
+ ts-algebra@2.0.0: {}
+
+ tslib@2.8.1: {}
+
+ typebox@1.1.38: {}
+
+ typescript@5.9.3: {}
+
+ undici-types@8.3.0: {}
+
+ undici@7.28.0: {}
+
+ undici@8.5.0: {}
+
+ vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0):
+ dependencies:
+ esbuild: 0.28.1
+ fdir: 6.5.0(picomatch@4.0.4)
+ picomatch: 4.0.4
+ postcss: 8.5.15
+ rollup: 4.62.2
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 26.0.1
+ fsevents: 2.3.3
+ jiti: 2.7.0
+ yaml: 2.9.0
+
+ vitest@4.1.9(@opentelemetry/api@1.9.0)(@types/node@26.0.1)(jsdom@29.1.1)(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0)):
+ dependencies:
+ '@vitest/expect': 4.1.9
+ '@vitest/mocker': 4.1.9(vite@7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0))
+ '@vitest/pretty-format': 4.1.9
+ '@vitest/runner': 4.1.9
+ '@vitest/snapshot': 4.1.9
+ '@vitest/spy': 4.1.9
+ '@vitest/utils': 4.1.9
+ es-module-lexer: 2.1.0
+ expect-type: 1.3.0
+ magic-string: 0.30.21
+ obug: 2.1.3
+ pathe: 2.0.3
+ picomatch: 4.0.4
+ std-env: 4.1.0
+ tinybench: 2.9.0
+ tinyexec: 1.2.4
+ tinyglobby: 0.2.17
+ tinyrainbow: 3.1.0
+ vite: 7.3.5(@types/node@26.0.1)(jiti@2.7.0)(yaml@2.9.0)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@opentelemetry/api': 1.9.0
+ '@types/node': 26.0.1
+ jsdom: 29.1.1
+ transitivePeerDependencies:
+ - msw
+
+ w3c-xmlserializer@5.0.0:
+ dependencies:
+ xml-name-validator: 5.0.0
+
+ web-streams-polyfill@3.3.3: {}
+
+ webidl-conversions@8.0.1: {}
+
+ whatwg-mimetype@5.0.0: {}
+
+ whatwg-url@16.0.1:
+ dependencies:
+ '@exodus/bytes': 1.15.1
+ tr46: 6.0.0
+ webidl-conversions: 8.0.1
+ transitivePeerDependencies:
+ - '@noble/hashes'
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
+ ws@8.21.0: {}
+
+ xml-name-validator@5.0.0: {}
+
+ xmlchars@2.2.0: {}
+
+ yaml@2.9.0: {}
+
+ zod-to-json-schema@3.25.2(zod@4.4.3):
+ dependencies:
+ zod: 4.4.3
+
+ zod@4.4.3: {}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
new file mode 100644
index 0000000..41b1043
--- /dev/null
+++ b/pnpm-workspace.yaml
@@ -0,0 +1,8 @@
+allowBuilds:
+ '@google/genai': true
+ '@hypabolic/hypa-win32-x64': true
+ '@hypabolic/pi-hypa': true
+ esbuild: true
+ protobufjs: true
+overrides:
+ esbuild@>=0.27.3 <0.28.1: '>=0.28.1'
diff --git a/progress.md b/progress.md
new file mode 100644
index 0000000..7b710c8
--- /dev/null
+++ b/progress.md
@@ -0,0 +1,20 @@
+# Progress
+
+- Loaded relevant skills.
+- Created `docs/development-pipeline.md`.
+- Dispatched design/test/accessibility subagents; incorporated their recommendations.
+- Added failing tests first for endpoint defaults, modal focus trap, inert, labels, aria labels, inline errors, reduced motion, and api_key empty-state handling.
+- Implemented UI/accessibility fixes in `src/app.ts` and `src/styles.css`.
+- Updated Rust-side default API endpoint/model in settings and transcription client.
+- Final review loop passed: visual QA, accessibility review, and implementation code review found no blockers introduced by this work.
+- Verified `npm test -- --run` and `npm run build` pass.
+- Earlier `cargo check` was blocked by missing Cargo; Rust/Cargo + Visual Studio Build Tools are now installed.
+- Installed Rust/Cargo + Visual Studio Build Tools; `cargo check --manifest-path src-tauri/Cargo.toml` now passes.
+- Built Transcript 0.3.0 artifacts: EXE, NSIS installer, MSI.
+- Ran Impeccable critique for the front; score was 23/40 and snapshot saved under `.impeccable/critique/`.
+- Implemented the approved minimalist front pass: fixed CSS height syntax, hid ambient decoration, flattened visual treatment, calmed settings copy, and added regression tests.
+- Final verification after minimalist pass: `npm test -- --run` passed 13 tests, `npm run build` passed, `cargo check --manifest-path src-tauri/Cargo.toml` passed, and `npm run tauri:build` rebuilt 0.3.0 artifacts.
+- Added speech-api compatibility in `src-tauri/src/transcription/openai.rs`: known `/v1/stt/transcribe` endpoints health-check `/readyz`, FastAPI nested errors render as `CODE: message`, and generic APIs without `/models` retain the existing 404-is-reachable behavior.
+- TDD verification: new speech-api tests went RED then GREEN; Rust library suite passed 35 tests, frontend suite passed 13 tests, frontend build and Cargo check passed.
+- Verified the live local API using `GET /readyz` and multipart `POST /v1/stt/transcribe` with the app's `file`, `model`, and `language` fields; it returned a transcript successfully.
+- Bumped patch version to 0.3.1 and built updated EXE/NSIS/MSI artifacts.
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..7dde9c0
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index 48d4707..150c4cd 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -85,7 +85,7 @@ dependencies = [
"objc2-foundation",
"parking_lot",
"percent-encoding",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
"x11rb",
]
@@ -819,6 +819,16 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "dbus-secret-service"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "708b509edf7889e53d7efb0ffadd994cc6c2345ccb62f55cfd6b0682165e4fa6"
+dependencies = [
+ "dbus",
+ "zeroize",
+]
+
[[package]]
name = "deranged"
version = "0.5.8"
@@ -2137,6 +2147,20 @@ dependencies = [
"unicode-segmentation",
]
+[[package]]
+name = "keyring"
+version = "3.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c"
+dependencies = [
+ "byteorder",
+ "dbus-secret-service",
+ "linux-keyutils",
+ "log",
+ "windows-sys 0.60.2",
+ "zeroize",
+]
+
[[package]]
name = "leb128fmt"
version = "0.1.0"
@@ -2211,6 +2235,16 @@ dependencies = [
"libc",
]
+[[package]]
+name = "linux-keyutils"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83270a18e9f90d0707c41e9f35efada77b64c0e6f3f1810e71c8368a864d5590"
+dependencies = [
+ "bitflags 2.13.0",
+ "libc",
+]
+
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
@@ -2285,6 +2319,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+[[package]]
+name = "mime_guess"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
[[package]]
name = "minimal-lexical"
version = "0.2.1"
@@ -2584,6 +2628,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [
"bitflags 2.13.0",
"block2",
+ "libc",
"objc2",
"objc2-core-foundation",
]
@@ -3083,7 +3128,7 @@ dependencies = [
"once_cell",
"socket2",
"tracing",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -3230,6 +3275,7 @@ dependencies = [
"hyper-util",
"js-sys",
"log",
+ "mime_guess",
"percent-encoding",
"pin-project-lite",
"quinn",
@@ -3285,6 +3331,30 @@ dependencies = [
"web-sys",
]
+[[package]]
+name = "rfd"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672"
+dependencies = [
+ "block2",
+ "dispatch2",
+ "glib-sys",
+ "gobject-sys",
+ "gtk-sys",
+ "js-sys",
+ "log",
+ "objc2",
+ "objc2-app-kit",
+ "objc2-core-foundation",
+ "objc2-foundation",
+ "raw-window-handle",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "windows-sys 0.60.2",
+]
+
[[package]]
name = "ring"
version = "0.17.14"
@@ -4048,6 +4118,48 @@ dependencies = [
"walkdir",
]
+[[package]]
+name = "tauri-plugin-dialog"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65981abb771e74e571a38196c3baa11c459379164791eba0e67abc1a5fac9884"
+dependencies = [
+ "log",
+ "raw-window-handle",
+ "rfd",
+ "serde",
+ "serde_json",
+ "tauri",
+ "tauri-plugin",
+ "tauri-plugin-fs",
+ "thiserror 2.0.18",
+ "url",
+]
+
+[[package]]
+name = "tauri-plugin-fs"
+version = "2.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7ecc274121aca0c036a2b42d1cbe83d368d348f54e0bb8a735c2b1548e8f371"
+dependencies = [
+ "anyhow",
+ "dunce",
+ "glob",
+ "log",
+ "objc2-foundation",
+ "percent-encoding",
+ "schemars 0.8.22",
+ "serde",
+ "serde_json",
+ "serde_repr",
+ "tauri",
+ "tauri-plugin",
+ "tauri-utils",
+ "thiserror 2.0.18",
+ "toml 1.1.2+spec-1.1.0",
+ "url",
+]
+
[[package]]
name = "tauri-plugin-global-shortcut"
version = "2.3.2"
@@ -4553,16 +4665,18 @@ dependencies = [
[[package]]
name = "transcript-desktop"
-version = "0.1.0"
+version = "0.3.1"
dependencies = [
"arboard",
"cpal",
"hound",
+ "keyring",
"reqwest 0.12.28",
"serde",
"serde_json",
"tauri",
"tauri-build",
+ "tauri-plugin-dialog",
"tauri-plugin-global-shortcut",
"tauri-plugin-opener",
"thiserror 2.0.18",
@@ -4660,6 +4774,12 @@ dependencies = [
"unic-common",
]
+[[package]]
+name = "unicase"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+
[[package]]
name = "unicode-ident"
version = "1.0.24"
@@ -5278,6 +5398,15 @@ dependencies = [
"windows-targets 0.52.6",
]
+[[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.5",
+]
+
[[package]]
name = "windows-sys"
version = "0.61.2"
@@ -5311,13 +5440,30 @@ dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
- "windows_i686_gnullvm",
+ "windows_i686_gnullvm 0.52.6",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
]
+[[package]]
+name = "windows-targets"
+version = "0.53.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
+dependencies = [
+ "windows-link 0.2.1",
+ "windows_aarch64_gnullvm 0.53.1",
+ "windows_aarch64_msvc 0.53.1",
+ "windows_i686_gnu 0.53.1",
+ "windows_i686_gnullvm 0.53.1",
+ "windows_i686_msvc 0.53.1",
+ "windows_x86_64_gnu 0.53.1",
+ "windows_x86_64_gnullvm 0.53.1",
+ "windows_x86_64_msvc 0.53.1",
+]
+
[[package]]
name = "windows-threading"
version = "0.1.0"
@@ -5348,6 +5494,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
@@ -5360,6 +5512,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
+
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
@@ -5372,12 +5530,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+[[package]]
+name = "windows_i686_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
+
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
+
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
@@ -5390,6 +5560,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+[[package]]
+name = "windows_i686_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
+
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
@@ -5402,6 +5578,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
+
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
@@ -5414,6 +5596,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
@@ -5426,6 +5614,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.53.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
+
[[package]]
name = "winnow"
version = "0.5.40"
@@ -5778,6 +5972,20 @@ name = "zeroize"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
+dependencies = [
+ "zeroize_derive",
+]
+
+[[package]]
+name = "zeroize_derive"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
[[package]]
name = "zerotrie"
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 29fcf63..d3c9227 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "transcript-desktop"
-version = "0.1.0"
+version = "0.3.1"
description = "Offline-first desktop transcription app for Windows and Linux"
authors = ["Transcript contributors"]
edition = "2021"
@@ -18,11 +18,17 @@ serde_json = "1"
tauri = { version = "2", features = ["tray-icon", "image-png"] }
tauri-plugin-opener = "2"
tauri-plugin-global-shortcut = "2"
+keyring = { version = "3", default-features = false, features = [
+ "windows-native",
+ "linux-native-sync-persistent",
+] }
reqwest = { version = "0.12", default-features = false, features = [
"blocking",
"rustls-tls",
+ "multipart",
] }
cpal = "0.15.3"
hound = "3.5"
arboard = "3.6"
thiserror = "2"
+tauri-plugin-dialog = "2"
diff --git a/src-tauri/binaries/ggml-base.dll b/src-tauri/binaries/ggml-base.dll
new file mode 100644
index 0000000..83a04aa
Binary files /dev/null and b/src-tauri/binaries/ggml-base.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-alderlake.dll b/src-tauri/binaries/ggml-cpu-alderlake.dll
new file mode 100644
index 0000000..3a980df
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-alderlake.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-cannonlake.dll b/src-tauri/binaries/ggml-cpu-cannonlake.dll
new file mode 100644
index 0000000..68d8811
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-cannonlake.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-cascadelake.dll b/src-tauri/binaries/ggml-cpu-cascadelake.dll
new file mode 100644
index 0000000..bd1bb02
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-cascadelake.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-haswell.dll b/src-tauri/binaries/ggml-cpu-haswell.dll
new file mode 100644
index 0000000..9c1751c
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-haswell.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-icelake.dll b/src-tauri/binaries/ggml-cpu-icelake.dll
new file mode 100644
index 0000000..e7c208e
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-icelake.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-sandybridge.dll b/src-tauri/binaries/ggml-cpu-sandybridge.dll
new file mode 100644
index 0000000..05d2a03
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-sandybridge.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-skylakex.dll b/src-tauri/binaries/ggml-cpu-skylakex.dll
new file mode 100644
index 0000000..6650dc2
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-skylakex.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-sse42.dll b/src-tauri/binaries/ggml-cpu-sse42.dll
new file mode 100644
index 0000000..7c2f32b
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-sse42.dll differ
diff --git a/src-tauri/binaries/ggml-cpu-x64.dll b/src-tauri/binaries/ggml-cpu-x64.dll
new file mode 100644
index 0000000..f20e3b1
Binary files /dev/null and b/src-tauri/binaries/ggml-cpu-x64.dll differ
diff --git a/src-tauri/binaries/ggml.dll b/src-tauri/binaries/ggml.dll
new file mode 100644
index 0000000..6ee0e61
Binary files /dev/null and b/src-tauri/binaries/ggml.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared.tar.bz2 b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared.tar.bz2
new file mode 100644
index 0000000..31c2c0b
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared.tar.bz2 differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime.dll
new file mode 100644
index 0000000..ea37949
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime_providers_shared.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime_providers_shared.dll
new file mode 100644
index 0000000..cc1e520
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/onnxruntime_providers_shared.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-keyword-spotter.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-keyword-spotter.exe
new file mode 100644
index 0000000..5604409
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-keyword-spotter.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-audio-tagging.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-audio-tagging.exe
new file mode 100644
index 0000000..2089976
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-audio-tagging.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-denoiser.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-denoiser.exe
new file mode 100644
index 0000000..8d32fa8
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-denoiser.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-language-identification.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-language-identification.exe
new file mode 100644
index 0000000..a872ea1
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-language-identification.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-parallel.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-parallel.exe
new file mode 100644
index 0000000..73b37b3
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-parallel.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-punctuation.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-punctuation.exe
new file mode 100644
index 0000000..ecad4a3
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-punctuation.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-source-separation.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-source-separation.exe
new file mode 100644
index 0000000..b9bd3f7
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-source-separation.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-speaker-diarization.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-speaker-diarization.exe
new file mode 100644
index 0000000..e7e6166
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-speaker-diarization.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-tts.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-tts.exe
new file mode 100644
index 0000000..b406643
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-tts.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-websocket-server.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-websocket-server.exe
new file mode 100644
index 0000000..90dae7e
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-websocket-server.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-zeroshot-tts.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-zeroshot-tts.exe
new file mode 100644
index 0000000..3a76fb3
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-offline-zeroshot-tts.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-punctuation.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-punctuation.exe
new file mode 100644
index 0000000..f1ee2ad
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-punctuation.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-client.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-client.exe
new file mode 100644
index 0000000..65135e8
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-client.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-server.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-server.exe
new file mode 100644
index 0000000..4e6b570
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-online-websocket-server.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-vad.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-vad.exe
new file mode 100644
index 0000000..3c9c0ef
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-vad.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-version.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-version.exe
new file mode 100644
index 0000000..cdfb320
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx-version.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx.exe b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx.exe
new file mode 100644
index 0000000..82cd48e
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/bin/sherpa-onnx.exe differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/cargs.h b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/cargs.h
new file mode 100644
index 0000000..3bcf17f
--- /dev/null
+++ b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/cargs.h
@@ -0,0 +1,162 @@
+#pragma once
+
+/**
+ * This is a simple alternative cross-platform implementation of getopt, which
+ * is used to parse argument strings submitted to the executable (argc and argv
+ * which are received in the main function).
+ */
+
+#ifndef CAG_LIBRARY_H
+#define CAG_LIBRARY_H
+
+#include
+#include
+#include
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define CAG_EXPORT __declspec(dllexport)
+#define CAG_IMPORT __declspec(dllimport)
+#elif __GNUC__ >= 4
+#define CAG_EXPORT __attribute__((visibility("default")))
+#define CAG_IMPORT __attribute__((visibility("default")))
+#else
+#define CAG_EXPORT
+#define CAG_IMPORT
+#endif
+
+#if defined(CAG_SHARED)
+#if defined(CAG_EXPORTS)
+#define CAG_PUBLIC CAG_EXPORT
+#else
+#define CAG_PUBLIC CAG_IMPORT
+#endif
+#else
+#define CAG_PUBLIC
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An option is used to describe a flag/argument option submitted when the
+ * program is run.
+ */
+typedef struct cag_option
+{
+ const char identifier;
+ const char *access_letters;
+ const char *access_name;
+ const char *value_name;
+ const char *description;
+} cag_option;
+
+/**
+ * A context is used to iterate over all options provided. It stores the parsing
+ * state.
+ */
+typedef struct cag_option_context
+{
+ const struct cag_option *options;
+ size_t option_count;
+ int argc;
+ char **argv;
+ int index;
+ int inner_index;
+ bool forced_end;
+ char identifier;
+ char *value;
+} cag_option_context;
+
+/**
+ * This is just a small macro which calculates the size of an array.
+ */
+#define CAG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/**
+ * @brief Prints all options to the terminal.
+ *
+ * This function prints all options to the terminal. This can be used to
+ * generate the output for a "--help" option.
+ *
+ * @param options The options which will be printed.
+ * @param option_count The option count which will be printed.
+ * @param destination The destination where the output will be printed.
+ */
+CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
+ FILE *destination);
+
+/**
+ * @brief Prepare argument options context for parsing.
+ *
+ * This function prepares the context for iteration and initializes the context
+ * with the supplied options and arguments. After the context has been prepared,
+ * it can be used to fetch arguments from it.
+ *
+ * @param context The context which will be initialized.
+ * @param options The registered options which are available for the program.
+ * @param option_count The amount of options which are available for the
+ * program.
+ * @param argc The amount of arguments the user supplied in the main function.
+ * @param argv A pointer to the arguments of the main function.
+ */
+CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
+ const cag_option *options, size_t option_count, int argc, char **argv);
+
+/**
+ * @brief Fetches an option from the argument list.
+ *
+ * This function fetches a single option from the argument list. The context
+ * will be moved to that item. Information can be extracted from the context
+ * after the item has been fetched.
+ * The arguments will be re-ordered, which means that non-option arguments will
+ * be moved to the end of the argument list. After all options have been
+ * fetched, all non-option arguments will be positioned after the index of
+ * the context.
+ *
+ * @param context The context from which we will fetch the option.
+ * @return Returns true if there was another option or false if the end is
+ * reached.
+ */
+CAG_PUBLIC bool cag_option_fetch(cag_option_context *context);
+
+/**
+ * @brief Gets the identifier of the option.
+ *
+ * This function gets the identifier of the option, which should be unique to
+ * this option and can be used to determine what kind of option this is.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns the identifier of the option.
+ */
+CAG_PUBLIC char cag_option_get(const cag_option_context *context);
+
+/**
+ * @brief Gets the value from the option.
+ *
+ * This function gets the value from the option, if any. If the option does not
+ * contain a value, this function will return NULL.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns a pointer to the value or NULL if there is no value.
+ */
+CAG_PUBLIC const char *cag_option_get_value(const cag_option_context *context);
+
+/**
+ * @brief Gets the current index of the context.
+ *
+ * This function gets the index within the argv arguments of the context. The
+ * context always points to the next item which it will inspect. This is
+ * particularly useful to inspect the original argument array, or to get
+ * non-option arguments after option fetching has finished.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns the current index of the context.
+ */
+CAG_PUBLIC int cag_option_get_index(const cag_option_context *context);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/c-api.h b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/c-api.h
new file mode 100644
index 0000000..18c6d79
--- /dev/null
+++ b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/c-api.h
@@ -0,0 +1,1918 @@
+// sherpa-onnx/c-api/c-api.h
+//
+// Copyright (c) 2023 Xiaomi Corporation
+
+// C API for sherpa-onnx
+//
+// Please refer to
+// https://github.com/k2-fsa/sherpa-onnx/blob/master/c-api-examples/decode-file-c-api.c
+// for usages.
+//
+
+#ifndef SHERPA_ONNX_C_API_C_API_H_
+#define SHERPA_ONNX_C_API_C_API_H_
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// See https://github.com/pytorch/pytorch/blob/main/c10/macros/Export.h
+// We will set SHERPA_ONNX_BUILD_SHARED_LIBS and SHERPA_ONNX_BUILD_MAIN_LIB in
+// CMakeLists.txt
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wattributes"
+#endif
+
+#if defined(_WIN32)
+#if defined(SHERPA_ONNX_BUILD_SHARED_LIBS)
+#define SHERPA_ONNX_EXPORT __declspec(dllexport)
+#define SHERPA_ONNX_IMPORT __declspec(dllimport)
+#else
+#define SHERPA_ONNX_EXPORT
+#define SHERPA_ONNX_IMPORT
+#endif
+#else // WIN32
+#define SHERPA_ONNX_EXPORT __attribute__((visibility("default")))
+
+#define SHERPA_ONNX_IMPORT SHERPA_ONNX_EXPORT
+#endif // WIN32
+
+#if defined(SHERPA_ONNX_BUILD_MAIN_LIB)
+#define SHERPA_ONNX_API SHERPA_ONNX_EXPORT
+#else
+#define SHERPA_ONNX_API SHERPA_ONNX_IMPORT
+#endif
+
+// Please don't free the returned pointer.
+// Please don't modify the memory pointed by the returned pointer.
+//
+// The memory pointed by the returned pointer is statically allocated.
+//
+// Example return value: "1.12.1"
+SHERPA_ONNX_API const char *SherpaOnnxGetVersionStr();
+
+// Please don't free the returned pointer.
+// Please don't modify the memory pointed by the returned pointer.
+//
+// The memory pointed by the returned pointer is statically allocated.
+//
+// Example return value: "6982b86c"
+SHERPA_ONNX_API const char *SherpaOnnxGetGitSha1();
+
+// Please don't free the returned pointer.
+// Please don't modify the memory pointed by the returned pointer.
+//
+// The memory pointed by the returned pointer is statically allocated.
+//
+// Example return value: "Fri Jun 20 11:22:52 2025"
+SHERPA_ONNX_API const char *SherpaOnnxGetGitDate();
+
+// return 1 if the given file exists; return 0 otherwise
+SHERPA_ONNX_API int32_t SherpaOnnxFileExists(const char *filename);
+
+/// Please refer to
+/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
+/// to download pre-trained models. That is, you can find encoder-xxx.onnx
+/// decoder-xxx.onnx, joiner-xxx.onnx, and tokens.txt for this struct
+/// from there.
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineTransducerModelConfig {
+ const char *encoder;
+ const char *decoder;
+ const char *joiner;
+} SherpaOnnxOnlineTransducerModelConfig;
+
+// please visit
+// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-paraformer/index.html
+// to download pre-trained streaming paraformer models
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineParaformerModelConfig {
+ const char *encoder;
+ const char *decoder;
+} SherpaOnnxOnlineParaformerModelConfig;
+
+// Please visit
+// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-ctc/zipformer-ctc-models.html#
+// to download pre-trained streaming zipformer2 ctc models
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineZipformer2CtcModelConfig {
+ const char *model;
+} SherpaOnnxOnlineZipformer2CtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineNemoCtcModelConfig {
+ const char *model;
+} SherpaOnnxOnlineNemoCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineToneCtcModelConfig {
+ const char *model;
+} SherpaOnnxOnlineToneCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineModelConfig {
+ SherpaOnnxOnlineTransducerModelConfig transducer;
+ SherpaOnnxOnlineParaformerModelConfig paraformer;
+ SherpaOnnxOnlineZipformer2CtcModelConfig zipformer2_ctc;
+ const char *tokens;
+ int32_t num_threads;
+ const char *provider;
+ int32_t debug; // true to print debug information of the model
+ const char *model_type;
+ // Valid values:
+ // - cjkchar
+ // - bpe
+ // - cjkchar+bpe
+ const char *modeling_unit;
+ const char *bpe_vocab;
+ /// if non-null, loading the tokens from the buffer instead of from the
+ /// "tokens" file
+ const char *tokens_buf;
+ /// byte size excluding the trailing '\0'
+ int32_t tokens_buf_size;
+ SherpaOnnxOnlineNemoCtcModelConfig nemo_ctc;
+ SherpaOnnxOnlineToneCtcModelConfig t_one_ctc;
+} SherpaOnnxOnlineModelConfig;
+
+/// It expects 16 kHz 16-bit single channel wave format.
+SHERPA_ONNX_API typedef struct SherpaOnnxFeatureConfig {
+ /// Sample rate of the input data. MUST match the one expected
+ /// by the model. For instance, it should be 16000 for models provided
+ /// by us.
+ int32_t sample_rate;
+
+ /// Feature dimension of the model.
+ /// For instance, it should be 80 for models provided by us.
+ int32_t feature_dim;
+} SherpaOnnxFeatureConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineCtcFstDecoderConfig {
+ const char *graph;
+ int32_t max_active;
+} SherpaOnnxOnlineCtcFstDecoderConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxHomophoneReplacerConfig {
+ const char *dict_dir; // unused
+ const char *lexicon;
+ const char *rule_fsts;
+} SherpaOnnxHomophoneReplacerConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerConfig {
+ SherpaOnnxFeatureConfig feat_config;
+ SherpaOnnxOnlineModelConfig model_config;
+
+ /// Possible values are: greedy_search, modified_beam_search
+ const char *decoding_method;
+
+ /// Used only when decoding_method is modified_beam_search
+ /// Example value: 4
+ int32_t max_active_paths;
+
+ /// 0 to disable endpoint detection.
+ /// A non-zero value to enable endpoint detection.
+ int32_t enable_endpoint;
+
+ /// An endpoint is detected if trailing silence in seconds is larger than
+ /// this value even if nothing has been decoded.
+ /// Used only when enable_endpoint is not 0.
+ float rule1_min_trailing_silence;
+
+ /// An endpoint is detected if trailing silence in seconds is larger than
+ /// this value after something that is not blank has been decoded.
+ /// Used only when enable_endpoint is not 0.
+ float rule2_min_trailing_silence;
+
+ /// An endpoint is detected if the utterance in seconds is larger than
+ /// this value.
+ /// Used only when enable_endpoint is not 0.
+ float rule3_min_utterance_length;
+
+ /// Path to the hotwords.
+ const char *hotwords_file;
+
+ /// Bonus score for each token in hotwords.
+ float hotwords_score;
+
+ SherpaOnnxOnlineCtcFstDecoderConfig ctc_fst_decoder_config;
+ const char *rule_fsts;
+ const char *rule_fars;
+ float blank_penalty;
+
+ /// if non-nullptr, loading the hotwords from the buffered string directly in
+ const char *hotwords_buf;
+ /// byte size excluding the tailing '\0'
+ int32_t hotwords_buf_size;
+ SherpaOnnxHomophoneReplacerConfig hr;
+} SherpaOnnxOnlineRecognizerConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerResult {
+ // Recognized text
+ const char *text;
+
+ // Pointer to continuous memory which holds string based tokens
+ // which are separated by \0
+ const char *tokens;
+
+ // a pointer array containing the address of the first item in tokens
+ const char *const *tokens_arr;
+
+ // Pointer to continuous memory which holds timestamps
+ //
+ // Caution: If timestamp information is not available, this pointer is NULL.
+ // Please check whether it is NULL before you access it; otherwise, you would
+ // get segmentation fault.
+ float *timestamps;
+
+ // The number of tokens/timestamps in above pointer
+ int32_t count;
+
+ /** Return a json string.
+ *
+ * The returned string contains:
+ * {
+ * "text": "The recognition result",
+ * "tokens": [x, x, x],
+ * "timestamps": [x, x, x],
+ * "segment": x,
+ * "start_time": x,
+ * "is_final": true|false
+ * }
+ */
+ const char *json;
+} SherpaOnnxOnlineRecognizerResult;
+
+/// Note: OnlineRecognizer here means StreamingRecognizer.
+/// It does not need to access the Internet during recognition.
+/// Everything is run locally.
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizer
+ SherpaOnnxOnlineRecognizer;
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlineStream SherpaOnnxOnlineStream;
+
+/// @param config Config for the recognizer.
+/// @return Return a pointer to the recognizer. The user has to invoke
+// SherpaOnnxDestroyOnlineRecognizer() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineRecognizer *
+SherpaOnnxCreateOnlineRecognizer(
+ const SherpaOnnxOnlineRecognizerConfig *config);
+
+/// Free a pointer returned by SherpaOnnxCreateOnlineRecognizer()
+///
+/// @param p A pointer returned by SherpaOnnxCreateOnlineRecognizer()
+SHERPA_ONNX_API void SherpaOnnxDestroyOnlineRecognizer(
+ const SherpaOnnxOnlineRecognizer *recognizer);
+
+/// Create an online stream for accepting wave samples.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer()
+/// @return Return a pointer to an OnlineStream. The user has to invoke
+/// SherpaOnnxDestroyOnlineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineStream *SherpaOnnxCreateOnlineStream(
+ const SherpaOnnxOnlineRecognizer *recognizer);
+
+/// Create an online stream for accepting wave samples with the specified hot
+/// words.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer()
+/// @return Return a pointer to an OnlineStream. The user has to invoke
+/// SherpaOnnxDestroyOnlineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineStream *
+SherpaOnnxCreateOnlineStreamWithHotwords(
+ const SherpaOnnxOnlineRecognizer *recognizer, const char *hotwords);
+
+/// Destroy an online stream.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream()
+SHERPA_ONNX_API void SherpaOnnxDestroyOnlineStream(
+ const SherpaOnnxOnlineStream *stream);
+
+/// Accept input audio samples and compute the features.
+/// The user has to invoke SherpaOnnxDecodeOnlineStream() to run the neural
+/// network and decoding.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream().
+/// @param sample_rate Sample rate of the input samples. If it is different
+/// from config.feat_config.sample_rate, we will do
+/// resampling inside sherpa-onnx.
+/// @param samples A pointer to a 1-D array containing audio samples.
+/// The range of samples has to be normalized to [-1, 1].
+/// @param n Number of elements in the samples array.
+SHERPA_ONNX_API void SherpaOnnxOnlineStreamAcceptWaveform(
+ const SherpaOnnxOnlineStream *stream, int32_t sample_rate,
+ const float *samples, int32_t n);
+
+/// Return 1 if there are enough number of feature frames for decoding.
+/// Return 0 otherwise.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream
+SHERPA_ONNX_API int32_t
+SherpaOnnxIsOnlineStreamReady(const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Call this function to run the neural network model and decoding.
+//
+/// Precondition for this function: SherpaOnnxIsOnlineStreamReady() MUST
+/// return 1.
+///
+/// Usage example:
+///
+/// while (SherpaOnnxIsOnlineStreamReady(recognizer, stream)) {
+/// SherpaOnnxDecodeOnlineStream(recognizer, stream);
+/// }
+///
+SHERPA_ONNX_API void SherpaOnnxDecodeOnlineStream(
+ const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+/// This function is similar to SherpaOnnxDecodeOnlineStream(). It decodes
+/// multiple OnlineStream in parallel.
+///
+/// Caution: The caller has to ensure each OnlineStream is ready, i.e.,
+/// SherpaOnnxIsOnlineStreamReady() for that stream should return 1.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer()
+/// @param streams A pointer array containing pointers returned by
+/// SherpaOnnxCreateOnlineRecognizer()
+/// @param n Number of elements in the given streams array.
+SHERPA_ONNX_API void SherpaOnnxDecodeMultipleOnlineStreams(
+ const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream **streams, int32_t n);
+
+/// Get the decoding results so far for an OnlineStream.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer().
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream().
+/// @return A pointer containing the result. The user has to invoke
+/// SherpaOnnxDestroyOnlineRecognizerResult() to free the returned
+/// pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineRecognizerResult *
+SherpaOnnxGetOnlineStreamResult(const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Destroy the pointer returned by SherpaOnnxGetOnlineStreamResult().
+///
+/// @param r A pointer returned by SherpaOnnxGetOnlineStreamResult()
+SHERPA_ONNX_API void SherpaOnnxDestroyOnlineRecognizerResult(
+ const SherpaOnnxOnlineRecognizerResult *r);
+
+/// Return the result as a json string.
+/// The user has to invoke
+/// SherpaOnnxDestroyOnlineStreamResultJson()
+/// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const char *SherpaOnnxGetOnlineStreamResultAsJson(
+ const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyOnlineStreamResultJson(const char *s);
+
+/// SherpaOnnxOnlineStreamReset an OnlineStream , which clears the neural
+/// network model state and the state for decoding.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer().
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream
+SHERPA_ONNX_API void SherpaOnnxOnlineStreamReset(
+ const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Signal that no more audio samples would be available.
+/// After this call, you cannot call SherpaOnnxOnlineStreamAcceptWaveform() any
+/// more.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream()
+SHERPA_ONNX_API void SherpaOnnxOnlineStreamInputFinished(
+ const SherpaOnnxOnlineStream *stream);
+
+/// Return 1 if an endpoint has been detected.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOnlineRecognizer()
+/// @param stream A pointer returned by SherpaOnnxCreateOnlineStream()
+/// @return Return 1 if an endpoint is detected. Return 0 otherwise.
+SHERPA_ONNX_API int32_t
+SherpaOnnxOnlineStreamIsEndpoint(const SherpaOnnxOnlineRecognizer *recognizer,
+ const SherpaOnnxOnlineStream *stream);
+
+// for displaying results on Linux/macOS.
+SHERPA_ONNX_API typedef struct SherpaOnnxDisplay SherpaOnnxDisplay;
+
+/// Create a display object. Must be freed using SherpaOnnxDestroyDisplay to
+/// avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxDisplay *SherpaOnnxCreateDisplay(
+ int32_t max_word_per_line);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyDisplay(const SherpaOnnxDisplay *display);
+
+/// Print the result.
+SHERPA_ONNX_API void SherpaOnnxPrint(const SherpaOnnxDisplay *display,
+ int32_t idx, const char *s);
+// ============================================================
+// For offline ASR (i.e., non-streaming ASR)
+// ============================================================
+
+/// Please refer to
+/// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
+/// to download pre-trained models. That is, you can find encoder-xxx.onnx
+/// decoder-xxx.onnx, and joiner-xxx.onnx for this struct
+/// from there.
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTransducerModelConfig {
+ const char *encoder;
+ const char *decoder;
+ const char *joiner;
+} SherpaOnnxOfflineTransducerModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineParaformerModelConfig {
+ const char *model;
+} SherpaOnnxOfflineParaformerModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineNemoEncDecCtcModelConfig {
+ const char *model;
+} SherpaOnnxOfflineNemoEncDecCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineWhisperModelConfig {
+ const char *encoder;
+ const char *decoder;
+ const char *language;
+ const char *task;
+ int32_t tail_paddings;
+} SherpaOnnxOfflineWhisperModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineCanaryModelConfig {
+ const char *encoder;
+ const char *decoder;
+ const char *src_lang;
+ const char *tgt_lang;
+ int32_t use_pnc;
+} SherpaOnnxOfflineCanaryModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineFireRedAsrModelConfig {
+ const char *encoder;
+ const char *decoder;
+} SherpaOnnxOfflineFireRedAsrModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineMoonshineModelConfig {
+ const char *preprocessor;
+ const char *encoder;
+ const char *uncached_decoder;
+ const char *cached_decoder;
+} SherpaOnnxOfflineMoonshineModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTdnnModelConfig {
+ const char *model;
+} SherpaOnnxOfflineTdnnModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineLMConfig {
+ const char *model;
+ float scale;
+} SherpaOnnxOfflineLMConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSenseVoiceModelConfig {
+ const char *model;
+ const char *language;
+ int32_t use_itn;
+} SherpaOnnxOfflineSenseVoiceModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineDolphinModelConfig {
+ const char *model;
+} SherpaOnnxOfflineDolphinModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineZipformerCtcModelConfig {
+ const char *model;
+} SherpaOnnxOfflineZipformerCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineWenetCtcModelConfig {
+ const char *model;
+} SherpaOnnxOfflineWenetCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineOmnilingualAsrCtcModelConfig {
+ const char *model;
+} SherpaOnnxOfflineOmnilingualAsrCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineFunASRNanoModelConfig {
+ const char *encoder_adaptor;
+ const char *llm;
+ const char *embedding;
+ const char *tokenizer;
+ const char *system_prompt;
+ const char *user_prompt;
+ int32_t max_new_tokens;
+ float temperature;
+ float top_p;
+ int32_t seed;
+} SherpaOnnxOfflineFunASRNanoModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineMedAsrCtcModelConfig {
+ const char *model;
+} SherpaOnnxOfflineMedAsrCtcModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineModelConfig {
+ SherpaOnnxOfflineTransducerModelConfig transducer;
+ SherpaOnnxOfflineParaformerModelConfig paraformer;
+ SherpaOnnxOfflineNemoEncDecCtcModelConfig nemo_ctc;
+ SherpaOnnxOfflineWhisperModelConfig whisper;
+ SherpaOnnxOfflineTdnnModelConfig tdnn;
+
+ const char *tokens;
+ int32_t num_threads;
+ int32_t debug;
+ const char *provider;
+ const char *model_type;
+ // Valid values:
+ // - cjkchar
+ // - bpe
+ // - cjkchar+bpe
+ const char *modeling_unit;
+ const char *bpe_vocab;
+ const char *telespeech_ctc;
+ SherpaOnnxOfflineSenseVoiceModelConfig sense_voice;
+ SherpaOnnxOfflineMoonshineModelConfig moonshine;
+ SherpaOnnxOfflineFireRedAsrModelConfig fire_red_asr;
+ SherpaOnnxOfflineDolphinModelConfig dolphin;
+ SherpaOnnxOfflineZipformerCtcModelConfig zipformer_ctc;
+ SherpaOnnxOfflineCanaryModelConfig canary;
+ SherpaOnnxOfflineWenetCtcModelConfig wenet_ctc;
+ SherpaOnnxOfflineOmnilingualAsrCtcModelConfig omnilingual;
+ SherpaOnnxOfflineMedAsrCtcModelConfig medasr;
+ SherpaOnnxOfflineFunASRNanoModelConfig funasr_nano;
+} SherpaOnnxOfflineModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineRecognizerConfig {
+ SherpaOnnxFeatureConfig feat_config;
+ SherpaOnnxOfflineModelConfig model_config;
+ SherpaOnnxOfflineLMConfig lm_config;
+
+ const char *decoding_method;
+ int32_t max_active_paths;
+
+ /// Path to the hotwords.
+ const char *hotwords_file;
+
+ /// Bonus score for each token in hotwords.
+ float hotwords_score;
+ const char *rule_fsts;
+ const char *rule_fars;
+ float blank_penalty;
+
+ SherpaOnnxHomophoneReplacerConfig hr;
+} SherpaOnnxOfflineRecognizerConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineRecognizer
+ SherpaOnnxOfflineRecognizer;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineStream SherpaOnnxOfflineStream;
+
+/// @param config Config for the recognizer.
+/// @return Return a pointer to the recognizer. The user has to invoke
+// SherpaOnnxDestroyOfflineRecognizer() to free it to avoid memory
+// leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineRecognizer *
+SherpaOnnxCreateOfflineRecognizer(
+ const SherpaOnnxOfflineRecognizerConfig *config);
+
+/// @param config Config for the recognizer.
+SHERPA_ONNX_API void SherpaOnnxOfflineRecognizerSetConfig(
+ const SherpaOnnxOfflineRecognizer *recognizer,
+ const SherpaOnnxOfflineRecognizerConfig *config);
+
+/// Free a pointer returned by SherpaOnnxCreateOfflineRecognizer()
+///
+/// @param p A pointer returned by SherpaOnnxCreateOfflineRecognizer()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineRecognizer(
+ const SherpaOnnxOfflineRecognizer *recognizer);
+
+/// Create an offline stream for accepting wave samples.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOfflineRecognizer()
+/// @return Return a pointer to an OfflineStream. The user has to invoke
+/// SherpaOnnxDestroyOfflineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineStream *SherpaOnnxCreateOfflineStream(
+ const SherpaOnnxOfflineRecognizer *recognizer);
+
+/// Create an offline stream for accepting wave samples with the specified hot
+/// words.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOfflineRecognizer()
+/// @return Return a pointer to an OfflineStream. The user has to invoke
+/// SherpaOnnxDestroyOfflineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineStream *
+SherpaOnnxCreateOfflineStreamWithHotwords(
+ const SherpaOnnxOfflineRecognizer *recognizer, const char *hotwords);
+
+/// Destroy an offline stream.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOfflineStream()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineStream(
+ const SherpaOnnxOfflineStream *stream);
+
+/// Accept input audio samples and compute the features.
+/// The user has to invoke SherpaOnnxDecodeOfflineStream() to run the neural
+/// network and decoding.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOfflineStream().
+/// @param sample_rate Sample rate of the input samples. If it is different
+/// from config.feat_config.sample_rate, we will do
+/// resampling inside sherpa-onnx.
+/// @param samples A pointer to a 1-D array containing audio samples.
+/// The range of samples has to be normalized to [-1, 1].
+/// @param n Number of elements in the samples array.
+///
+/// @caution: For each offline stream, please invoke this function only once!
+SHERPA_ONNX_API void SherpaOnnxAcceptWaveformOffline(
+ const SherpaOnnxOfflineStream *stream, int32_t sample_rate,
+ const float *samples, int32_t n);
+/// Decode an offline stream.
+///
+/// We assume you have invoked SherpaOnnxAcceptWaveformOffline() for the given
+/// stream before calling this function.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOfflineRecognizer().
+/// @param stream A pointer returned by SherpaOnnxCreateOfflineStream()
+SHERPA_ONNX_API void SherpaOnnxDecodeOfflineStream(
+ const SherpaOnnxOfflineRecognizer *recognizer,
+ const SherpaOnnxOfflineStream *stream);
+
+/// Decode a list offline streams in parallel.
+///
+/// We assume you have invoked SherpaOnnxAcceptWaveformOffline() for each stream
+/// before calling this function.
+///
+/// @param recognizer A pointer returned by SherpaOnnxCreateOfflineRecognizer().
+/// @param streams A pointer pointer array containing pointers returned
+/// by SherpaOnnxCreateOfflineStream().
+/// @param n Number of entries in the given streams.
+SHERPA_ONNX_API void SherpaOnnxDecodeMultipleOfflineStreams(
+ const SherpaOnnxOfflineRecognizer *recognizer,
+ const SherpaOnnxOfflineStream **streams, int32_t n);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineRecognizerResult {
+ const char *text;
+
+ // Pointer to continuous memory which holds timestamps
+ //
+ // It is NULL if the model does not support timestamps
+ float *timestamps;
+
+ // number of entries in timestamps
+ int32_t count;
+
+ // Pointer to continuous memory which holds string based tokens
+ // which are separated by \0
+ const char *tokens;
+
+ // a pointer array containing the address of the first item in tokens
+ const char *const *tokens_arr;
+
+ /** Return a json string.
+ *
+ * The returned string contains:
+ * {
+ * "text": "The recognition result",
+ * "tokens": [x, x, x],
+ * "timestamps": [x, x, x],
+ * "durations": [x, x, x],
+ * "segment": x,
+ * "start_time": x,
+ * "is_final": true|false
+ * }
+ */
+ const char *json;
+
+ // return recognized language
+ const char *lang;
+
+ // return emotion.
+ const char *emotion;
+
+ // return event.
+ const char *event;
+
+ // Pointer to continuous memory which holds durations (in seconds) for each
+ // token It is NULL if the model does not support durations
+ float *durations;
+
+ // Pointer to continuous memory which holds log probabilities (confidence)
+ // for each token. It is NULL if the model does not support probabilities.
+ // ys_log_probs[i] is the log probability for token i.
+ float *ys_log_probs;
+} SherpaOnnxOfflineRecognizerResult;
+
+/// Get the result of the offline stream.
+///
+/// We assume you have called SherpaOnnxDecodeOfflineStream() or
+/// SherpaOnnxDecodeMultipleOfflineStreams() with the given stream before
+/// calling this function.
+///
+/// @param stream A pointer returned by SherpaOnnxCreateOfflineStream().
+/// @return Return a pointer to the result. The user has to invoke
+/// SherpaOnnxDestroyOnlineRecognizerResult() to free the returned
+/// pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineRecognizerResult *
+SherpaOnnxGetOfflineStreamResult(const SherpaOnnxOfflineStream *stream);
+
+/// Destroy the pointer returned by SherpaOnnxGetOfflineStreamResult().
+///
+/// @param r A pointer returned by SherpaOnnxGetOfflineStreamResult()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineRecognizerResult(
+ const SherpaOnnxOfflineRecognizerResult *r);
+
+/// Return the result as a json string.
+/// The user has to use SherpaOnnxDestroyOfflineStreamResultJson()
+/// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const char *SherpaOnnxGetOfflineStreamResultAsJson(
+ const SherpaOnnxOfflineStream *stream);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineStreamResultJson(const char *s);
+
+// ============================================================
+// For Keyword Spotter
+// ============================================================
+SHERPA_ONNX_API typedef struct SherpaOnnxKeywordResult {
+ /// The triggered keyword.
+ /// For English, it consists of space separated words.
+ /// For Chinese, it consists of Chinese words without spaces.
+ /// Example 1: "hello world"
+ /// Example 2: "你好世界"
+ const char *keyword;
+
+ /// Decoded results at the token level.
+ /// For instance, for BPE-based models it consists of a list of BPE tokens.
+ const char *tokens;
+
+ const char *const *tokens_arr;
+
+ int32_t count;
+
+ /// timestamps.size() == tokens.size()
+ /// timestamps[i] records the time in seconds when tokens[i] is decoded.
+ float *timestamps;
+
+ /// Starting time of this segment.
+ /// When an endpoint is detected, it will change
+ float start_time;
+
+ /** Return a json string.
+ *
+ * The returned string contains:
+ * {
+ * "keyword": "The triggered keyword",
+ * "tokens": [x, x, x],
+ * "timestamps": [x, x, x],
+ * "start_time": x,
+ * }
+ */
+ const char *json;
+} SherpaOnnxKeywordResult;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxKeywordSpotterConfig {
+ SherpaOnnxFeatureConfig feat_config;
+ SherpaOnnxOnlineModelConfig model_config;
+ int32_t max_active_paths;
+ int32_t num_trailing_blanks;
+ float keywords_score;
+ float keywords_threshold;
+ const char *keywords_file;
+ /// if non-null, loading the keywords from the buffer instead of from the
+ /// keywords_file
+ const char *keywords_buf;
+ /// byte size excluding the trailing '\0'
+ int32_t keywords_buf_size;
+} SherpaOnnxKeywordSpotterConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxKeywordSpotter
+ SherpaOnnxKeywordSpotter;
+
+/// @param config Config for the keyword spotter.
+/// @return Return a pointer to the spotter. The user has to invoke
+/// SherpaOnnxDestroyKeywordSpotter() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotter(
+ const SherpaOnnxKeywordSpotterConfig *config);
+
+/// Free a pointer returned by SherpaOnnxCreateKeywordSpotter()
+///
+/// @param p A pointer returned by SherpaOnnxCreateKeywordSpotter()
+SHERPA_ONNX_API void SherpaOnnxDestroyKeywordSpotter(
+ const SherpaOnnxKeywordSpotter *spotter);
+
+/// Create an online stream for accepting wave samples.
+///
+/// @param spotter A pointer returned by SherpaOnnxCreateKeywordSpotter()
+/// @return Return a pointer to an OnlineStream. The user has to invoke
+/// SherpaOnnxDestroyOnlineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineStream *SherpaOnnxCreateKeywordStream(
+ const SherpaOnnxKeywordSpotter *spotter);
+
+/// Create an online stream for accepting wave samples with the specified hot
+/// words.
+///
+/// @param spotter A pointer returned by SherpaOnnxCreateKeywordSpotter()
+/// @param keywords A pointer points to the keywords that you set
+/// @return Return a pointer to an OnlineStream. The user has to invoke
+/// SherpaOnnxDestroyOnlineStream() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineStream *
+SherpaOnnxCreateKeywordStreamWithKeywords(
+ const SherpaOnnxKeywordSpotter *spotter, const char *keywords);
+
+/// Return 1 if there are enough number of feature frames for decoding.
+/// Return 0 otherwise.
+///
+/// @param spotter A pointer returned by SherpaOnnxCreateKeywordSpotter
+/// @param stream A pointer returned by SherpaOnnxCreateKeywordStream
+SHERPA_ONNX_API int32_t
+SherpaOnnxIsKeywordStreamReady(const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Call this function to run the neural network model and decoding.
+//
+/// Precondition for this function: SherpaOnnxIsKeywordStreamReady() MUST
+/// return 1.
+SHERPA_ONNX_API void SherpaOnnxDecodeKeywordStream(
+ const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Please call it right after a keyword is detected
+SHERPA_ONNX_API void SherpaOnnxResetKeywordStream(
+ const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream *stream);
+
+/// This function is similar to SherpaOnnxDecodeKeywordStream(). It decodes
+/// multiple OnlineStream in parallel.
+///
+/// Caution: The caller has to ensure each OnlineStream is ready, i.e.,
+/// SherpaOnnxIsKeywordStreamReady() for that stream should return 1.
+///
+/// @param spotter A pointer returned by SherpaOnnxCreateKeywordSpotter()
+/// @param streams A pointer array containing pointers returned by
+/// SherpaOnnxCreateKeywordStream()
+/// @param n Number of elements in the given streams array.
+SHERPA_ONNX_API void SherpaOnnxDecodeMultipleKeywordStreams(
+ const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream **streams, int32_t n);
+
+/// Get the decoding results so far for an OnlineStream.
+///
+/// @param spotter A pointer returned by SherpaOnnxCreateKeywordSpotter().
+/// @param stream A pointer returned by SherpaOnnxCreateKeywordStream().
+/// @return A pointer containing the result. The user has to invoke
+/// SherpaOnnxDestroyKeywordResult() to free the returned pointer to
+/// avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxKeywordResult *SherpaOnnxGetKeywordResult(
+ const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream *stream);
+
+/// Destroy the pointer returned by SherpaOnnxGetKeywordResult().
+///
+/// @param r A pointer returned by SherpaOnnxGetKeywordResult()
+SHERPA_ONNX_API void SherpaOnnxDestroyKeywordResult(
+ const SherpaOnnxKeywordResult *r);
+
+// the user has to call SherpaOnnxFreeKeywordResultJson() to free the returned
+// pointer to avoid memory leak
+SHERPA_ONNX_API const char *SherpaOnnxGetKeywordResultAsJson(
+ const SherpaOnnxKeywordSpotter *spotter,
+ const SherpaOnnxOnlineStream *stream);
+
+SHERPA_ONNX_API void SherpaOnnxFreeKeywordResultJson(const char *s);
+
+// ============================================================
+// For VAD
+// ============================================================
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSileroVadModelConfig {
+ // Path to the silero VAD model
+ const char *model;
+
+ // threshold to classify a segment as speech
+ //
+ // If the predicted probability of a segment is larger than this
+ // value, then it is classified as speech.
+ float threshold;
+
+ // in seconds
+ float min_silence_duration;
+
+ // in seconds
+ float min_speech_duration;
+
+ int32_t window_size;
+
+ // If a speech segment is longer than this value, then we increase
+ // the threshold to 0.9. After finishing detecting the segment,
+ // the threshold value is reset to its original value.
+ float max_speech_duration;
+} SherpaOnnxSileroVadModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxTenVadModelConfig {
+ // Path to the ten-vad model
+ const char *model;
+
+ // threshold to classify a segment as speech
+ //
+ // If the predicted probability of a segment is larger than this
+ // value, then it is classified as speech.
+ float threshold;
+
+ // in seconds
+ float min_silence_duration;
+
+ // in seconds
+ float min_speech_duration;
+
+ int32_t window_size;
+
+ // If a speech segment is longer than this value, then we increase
+ // the threshold to 0.9. After finishing detecting the segment,
+ // the threshold value is reset to its original value.
+ float max_speech_duration;
+} SherpaOnnxTenVadModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxVadModelConfig {
+ SherpaOnnxSileroVadModelConfig silero_vad;
+
+ int32_t sample_rate;
+ int32_t num_threads;
+ const char *provider;
+ int32_t debug;
+ SherpaOnnxTenVadModelConfig ten_vad;
+} SherpaOnnxVadModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxCircularBuffer
+ SherpaOnnxCircularBuffer;
+
+// Return an instance of circular buffer. The user has to use
+// SherpaOnnxDestroyCircularBuffer() to free the returned pointer to avoid
+// memory leak.
+SHERPA_ONNX_API const SherpaOnnxCircularBuffer *SherpaOnnxCreateCircularBuffer(
+ int32_t capacity);
+
+// Free the pointer returned by SherpaOnnxCreateCircularBuffer()
+SHERPA_ONNX_API void SherpaOnnxDestroyCircularBuffer(
+ const SherpaOnnxCircularBuffer *buffer);
+
+SHERPA_ONNX_API void SherpaOnnxCircularBufferPush(
+ const SherpaOnnxCircularBuffer *buffer, const float *p, int32_t n);
+
+// Return n samples starting at the given index.
+//
+// Return a pointer to an array containing n samples starting at start_index.
+// The user has to use SherpaOnnxCircularBufferFree() to free the returned
+// pointer to avoid memory leak.
+SHERPA_ONNX_API const float *SherpaOnnxCircularBufferGet(
+ const SherpaOnnxCircularBuffer *buffer, int32_t start_index, int32_t n);
+
+// Free the pointer returned by SherpaOnnxCircularBufferGet().
+SHERPA_ONNX_API void SherpaOnnxCircularBufferFree(const float *p);
+
+// Remove n elements from the buffer
+SHERPA_ONNX_API void SherpaOnnxCircularBufferPop(
+ const SherpaOnnxCircularBuffer *buffer, int32_t n);
+
+// Return number of elements in the buffer.
+SHERPA_ONNX_API int32_t
+SherpaOnnxCircularBufferSize(const SherpaOnnxCircularBuffer *buffer);
+
+// Return the head of the buffer. It's always non-decreasing until you
+// invoke SherpaOnnxCircularBufferReset() which resets head to 0.
+SHERPA_ONNX_API int32_t
+SherpaOnnxCircularBufferHead(const SherpaOnnxCircularBuffer *buffer);
+
+// Clear all elements in the buffer
+SHERPA_ONNX_API void SherpaOnnxCircularBufferReset(
+ const SherpaOnnxCircularBuffer *buffer);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpeechSegment {
+ // The start index in samples of this segment
+ int32_t start;
+
+ // pointer to the array containing the samples
+ float *samples;
+
+ // number of samples in this segment
+ int32_t n;
+} SherpaOnnxSpeechSegment;
+
+typedef struct SherpaOnnxVoiceActivityDetector SherpaOnnxVoiceActivityDetector;
+
+// Return an instance of VoiceActivityDetector.
+// The user has to use SherpaOnnxDestroyVoiceActivityDetector() to free
+// the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxVoiceActivityDetector *
+SherpaOnnxCreateVoiceActivityDetector(const SherpaOnnxVadModelConfig *config,
+ float buffer_size_in_seconds);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyVoiceActivityDetector(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+SHERPA_ONNX_API void SherpaOnnxVoiceActivityDetectorAcceptWaveform(
+ const SherpaOnnxVoiceActivityDetector *p, const float *samples, int32_t n);
+
+// Return 1 if there are no speech segments available.
+// Return 0 if there are speech segments.
+SHERPA_ONNX_API int32_t
+SherpaOnnxVoiceActivityDetectorEmpty(const SherpaOnnxVoiceActivityDetector *p);
+
+// Return 1 if there is voice detected.
+// Return 0 if voice is silent.
+SHERPA_ONNX_API int32_t SherpaOnnxVoiceActivityDetectorDetected(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+// Return the first speech segment.
+// It throws if SherpaOnnxVoiceActivityDetectorEmpty() returns 1.
+SHERPA_ONNX_API void SherpaOnnxVoiceActivityDetectorPop(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+// Clear current speech segments.
+SHERPA_ONNX_API void SherpaOnnxVoiceActivityDetectorClear(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+// Return the first speech segment.
+// The user has to use SherpaOnnxDestroySpeechSegment() to free the returned
+// pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxSpeechSegment *
+SherpaOnnxVoiceActivityDetectorFront(const SherpaOnnxVoiceActivityDetector *p);
+
+// Free the pointer returned SherpaOnnxVoiceActivityDetectorFront().
+SHERPA_ONNX_API void SherpaOnnxDestroySpeechSegment(
+ const SherpaOnnxSpeechSegment *p);
+
+// Re-initialize the voice activity detector.
+SHERPA_ONNX_API void SherpaOnnxVoiceActivityDetectorReset(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+SHERPA_ONNX_API void SherpaOnnxVoiceActivityDetectorFlush(
+ const SherpaOnnxVoiceActivityDetector *p);
+
+// ============================================================
+// For offline Text-to-Speech (i.e., non-streaming TTS)
+// ============================================================
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsVitsModelConfig {
+ const char *model;
+ const char *lexicon;
+ const char *tokens;
+ const char *data_dir;
+
+ float noise_scale;
+ float noise_scale_w;
+ float length_scale; // < 1, faster in speech speed; > 1, slower in speed
+ const char *dict_dir; // unused
+} SherpaOnnxOfflineTtsVitsModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsMatchaModelConfig {
+ const char *acoustic_model;
+ const char *vocoder;
+ const char *lexicon;
+ const char *tokens;
+ const char *data_dir;
+
+ float noise_scale;
+ float length_scale; // < 1, faster in speech speed; > 1, slower in speed
+ const char *dict_dir; // unused
+} SherpaOnnxOfflineTtsMatchaModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsKokoroModelConfig {
+ const char *model;
+ const char *voices;
+ const char *tokens;
+ const char *data_dir;
+
+ float length_scale; // < 1, faster in speech speed; > 1, slower in speed
+ const char *dict_dir; // unused
+ const char *lexicon;
+ const char *lang;
+} SherpaOnnxOfflineTtsKokoroModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsKittenModelConfig {
+ const char *model;
+ const char *voices;
+ const char *tokens;
+ const char *data_dir;
+
+ float length_scale; // < 1, faster in speech speed; > 1, slower in speed
+} SherpaOnnxOfflineTtsKittenModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsZipvoiceModelConfig {
+ const char *tokens;
+ const char *encoder;
+ const char *decoder;
+ const char *vocoder;
+ const char *data_dir;
+ const char *lexicon;
+ float feat_scale;
+ float t_shift;
+ float target_rms;
+ float guidance_scale;
+} SherpaOnnxOfflineTtsZipvoiceModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsModelConfig {
+ SherpaOnnxOfflineTtsVitsModelConfig vits;
+ int32_t num_threads;
+ int32_t debug;
+ const char *provider;
+ SherpaOnnxOfflineTtsMatchaModelConfig matcha;
+ SherpaOnnxOfflineTtsKokoroModelConfig kokoro;
+ SherpaOnnxOfflineTtsKittenModelConfig kitten;
+ SherpaOnnxOfflineTtsZipvoiceModelConfig zipvoice;
+} SherpaOnnxOfflineTtsModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTtsConfig {
+ SherpaOnnxOfflineTtsModelConfig model;
+ const char *rule_fsts;
+ int32_t max_num_sentences;
+ const char *rule_fars;
+ float silence_scale;
+} SherpaOnnxOfflineTtsConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxGeneratedAudio {
+ const float *samples; // in the range [-1, 1]
+ int32_t n; // number of samples
+ int32_t sample_rate;
+} SherpaOnnxGeneratedAudio;
+
+// If the callback returns 0, then it stops generating
+// If the callback returns 1, then it keeps generating
+typedef int32_t (*SherpaOnnxGeneratedAudioCallback)(const float *samples,
+ int32_t n);
+
+typedef int32_t (*SherpaOnnxGeneratedAudioCallbackWithArg)(const float *samples,
+ int32_t n,
+ void *arg);
+
+typedef int32_t (*SherpaOnnxGeneratedAudioProgressCallback)(
+ const float *samples, int32_t n, float p);
+
+typedef int32_t (*SherpaOnnxGeneratedAudioProgressCallbackWithArg)(
+ const float *samples, int32_t n, float p, void *arg);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineTts SherpaOnnxOfflineTts;
+
+// Create an instance of offline TTS. The user has to use DestroyOfflineTts()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts(
+ const SherpaOnnxOfflineTtsConfig *config);
+
+// Free the pointer returned by SherpaOnnxCreateOfflineTts()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineTts(
+ const SherpaOnnxOfflineTts *tts);
+
+// Return the sample rate of the current TTS object
+SHERPA_ONNX_API int32_t
+SherpaOnnxOfflineTtsSampleRate(const SherpaOnnxOfflineTts *tts);
+
+// Return the number of speakers of the current TTS object
+SHERPA_ONNX_API int32_t
+SherpaOnnxOfflineTtsNumSpeakers(const SherpaOnnxOfflineTts *tts);
+
+// Generate audio from the given text and speaker id (sid).
+// The user has to use SherpaOnnxDestroyOfflineTtsGeneratedAudio() to free the
+// returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxGeneratedAudio *SherpaOnnxOfflineTtsGenerate(
+ const SherpaOnnxOfflineTts *tts, const char *text, int32_t sid,
+ float speed);
+
+// callback is called whenever SherpaOnnxOfflineTtsConfig.max_num_sentences
+// sentences have been processed. The pointer passed to the callback
+// is freed once the callback is returned. So the caller should not keep
+// a reference to it.
+SHERPA_ONNX_API const SherpaOnnxGeneratedAudio *
+SherpaOnnxOfflineTtsGenerateWithCallback(
+ const SherpaOnnxOfflineTts *tts, const char *text, int32_t sid, float speed,
+ SherpaOnnxGeneratedAudioCallback callback);
+
+SHERPA_ONNX_API
+const SherpaOnnxGeneratedAudio *
+SherpaOnnxOfflineTtsGenerateWithProgressCallback(
+ const SherpaOnnxOfflineTts *tts, const char *text, int32_t sid, float speed,
+ SherpaOnnxGeneratedAudioProgressCallback callback);
+
+SHERPA_ONNX_API
+const SherpaOnnxGeneratedAudio *
+SherpaOnnxOfflineTtsGenerateWithProgressCallbackWithArg(
+ const SherpaOnnxOfflineTts *tts, const char *text, int32_t sid, float speed,
+ SherpaOnnxGeneratedAudioProgressCallbackWithArg callback, void *arg);
+
+// Same as SherpaOnnxGeneratedAudioCallback but you can pass an additional
+// `void* arg` to the callback.
+SHERPA_ONNX_API const SherpaOnnxGeneratedAudio *
+SherpaOnnxOfflineTtsGenerateWithCallbackWithArg(
+ const SherpaOnnxOfflineTts *tts, const char *text, int32_t sid, float speed,
+ SherpaOnnxGeneratedAudioCallbackWithArg callback, void *arg);
+
+SHERPA_ONNX_API const SherpaOnnxGeneratedAudio *
+SherpaOnnxOfflineTtsGenerateWithZipvoice(const SherpaOnnxOfflineTts *tts,
+ const char *text,
+ const char *prompt_text,
+ const float *prompt_samples,
+ int32_t n_prompt, int32_t prompt_sr,
+ float speed, int32_t num_steps);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineTtsGeneratedAudio(
+ const SherpaOnnxGeneratedAudio *p);
+
+// Write the generated audio to a wave file.
+// The saved wave file contains a single channel and has 16-bit samples.
+//
+// Return 1 if the write succeeded; return 0 on failure.
+SHERPA_ONNX_API int32_t SherpaOnnxWriteWave(const float *samples, int32_t n,
+ int32_t sample_rate,
+ const char *filename);
+
+// the amount of bytes needed to store a wave file which contains a
+// single channel and has 16-bit samples.
+SHERPA_ONNX_API int64_t SherpaOnnxWaveFileSize(int32_t n_samples);
+
+// Similar to SherpaOnnxWriteWave , it writes wave to allocated buffer;
+//
+// in some case (http tts api return wave binary file, server do not need to
+// write wave to fs)
+SHERPA_ONNX_API void SherpaOnnxWriteWaveToBuffer(const float *samples,
+ int32_t n, int32_t sample_rate,
+ char *buffer);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxWave {
+ // samples normalized to the range [-1, 1]
+ const float *samples;
+ int32_t sample_rate;
+ int32_t num_samples;
+} SherpaOnnxWave;
+
+// Return a NULL pointer on error. It supports only standard WAVE file.
+// Each sample should be 16-bit. It supports only single channel..
+//
+// If the returned pointer is not NULL, the user has to invoke
+// SherpaOnnxFreeWave() to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxWave *SherpaOnnxReadWave(const char *filename);
+
+// Similar to SherpaOnnxReadWave(), it has read the content of `filename`
+// into the array `data`.
+//
+// If the returned pointer is not NULL, the user has to invoke
+// SherpaOnnxFreeWave() to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxWave *SherpaOnnxReadWaveFromBinaryData(
+ const char *data, int32_t n);
+
+SHERPA_ONNX_API void SherpaOnnxFreeWave(const SherpaOnnxWave *wave);
+
+// ============================================================
+// For spoken language identification
+// ============================================================
+
+SHERPA_ONNX_API typedef struct
+ SherpaOnnxSpokenLanguageIdentificationWhisperConfig {
+ const char *encoder;
+ const char *decoder;
+ int32_t tail_paddings;
+} SherpaOnnxSpokenLanguageIdentificationWhisperConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpokenLanguageIdentificationConfig {
+ SherpaOnnxSpokenLanguageIdentificationWhisperConfig whisper;
+ int32_t num_threads;
+ int32_t debug;
+ const char *provider;
+} SherpaOnnxSpokenLanguageIdentificationConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpokenLanguageIdentification
+ SherpaOnnxSpokenLanguageIdentification;
+
+// Create an instance of SpokenLanguageIdentification.
+// The user has to invoke SherpaOnnxDestroySpokenLanguageIdentification()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxSpokenLanguageIdentification *
+SherpaOnnxCreateSpokenLanguageIdentification(
+ const SherpaOnnxSpokenLanguageIdentificationConfig *config);
+
+SHERPA_ONNX_API void SherpaOnnxDestroySpokenLanguageIdentification(
+ const SherpaOnnxSpokenLanguageIdentification *slid);
+
+// The user has to invoke SherpaOnnxDestroyOfflineStream()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API SherpaOnnxOfflineStream *
+SherpaOnnxSpokenLanguageIdentificationCreateOfflineStream(
+ const SherpaOnnxSpokenLanguageIdentification *slid);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpokenLanguageIdentificationResult {
+ // en for English
+ // de for German
+ // zh for Chinese
+ // es for Spanish
+ // ...
+ const char *lang;
+} SherpaOnnxSpokenLanguageIdentificationResult;
+
+// The user has to invoke SherpaOnnxDestroySpokenLanguageIdentificationResult()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxSpokenLanguageIdentificationResult *
+SherpaOnnxSpokenLanguageIdentificationCompute(
+ const SherpaOnnxSpokenLanguageIdentification *slid,
+ const SherpaOnnxOfflineStream *s);
+
+SHERPA_ONNX_API void SherpaOnnxDestroySpokenLanguageIdentificationResult(
+ const SherpaOnnxSpokenLanguageIdentificationResult *r);
+
+// ============================================================
+// For speaker embedding extraction
+// ============================================================
+SHERPA_ONNX_API typedef struct SherpaOnnxSpeakerEmbeddingExtractorConfig {
+ const char *model;
+ int32_t num_threads;
+ int32_t debug;
+ const char *provider;
+} SherpaOnnxSpeakerEmbeddingExtractorConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpeakerEmbeddingExtractor
+ SherpaOnnxSpeakerEmbeddingExtractor;
+
+// The user has to invoke SherpaOnnxDestroySpeakerEmbeddingExtractor()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxSpeakerEmbeddingExtractor *
+SherpaOnnxCreateSpeakerEmbeddingExtractor(
+ const SherpaOnnxSpeakerEmbeddingExtractorConfig *config);
+
+SHERPA_ONNX_API void SherpaOnnxDestroySpeakerEmbeddingExtractor(
+ const SherpaOnnxSpeakerEmbeddingExtractor *p);
+
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingExtractorDim(
+ const SherpaOnnxSpeakerEmbeddingExtractor *p);
+
+// The user has to invoke SherpaOnnxDestroyOnlineStream() to free the returned
+// pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOnlineStream *
+SherpaOnnxSpeakerEmbeddingExtractorCreateStream(
+ const SherpaOnnxSpeakerEmbeddingExtractor *p);
+
+// Return 1 if the stream has enough feature frames for computing embeddings.
+// Return 0 otherwise.
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingExtractorIsReady(
+ const SherpaOnnxSpeakerEmbeddingExtractor *p,
+ const SherpaOnnxOnlineStream *s);
+
+// Compute the embedding of the stream.
+//
+// @return Return a pointer pointing to an array containing the embedding.
+// The length of the array is `dim` as returned by
+// SherpaOnnxSpeakerEmbeddingExtractorDim(p)
+//
+// The user has to invoke SherpaOnnxSpeakerEmbeddingExtractorDestroyEmbedding()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const float *
+SherpaOnnxSpeakerEmbeddingExtractorComputeEmbedding(
+ const SherpaOnnxSpeakerEmbeddingExtractor *p,
+ const SherpaOnnxOnlineStream *s);
+
+SHERPA_ONNX_API void SherpaOnnxSpeakerEmbeddingExtractorDestroyEmbedding(
+ const float *v);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpeakerEmbeddingManager
+ SherpaOnnxSpeakerEmbeddingManager;
+
+// The user has to invoke SherpaOnnxDestroySpeakerEmbeddingManager()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxSpeakerEmbeddingManager *
+SherpaOnnxCreateSpeakerEmbeddingManager(int32_t dim);
+
+SHERPA_ONNX_API void SherpaOnnxDestroySpeakerEmbeddingManager(
+ const SherpaOnnxSpeakerEmbeddingManager *p);
+
+// Register the embedding of a user
+//
+// @param name The name of the user
+// @param p Pointer to an array containing the embeddings. The length of the
+// array must be equal to `dim` used to construct the manager `p`.
+//
+// @return Return 1 if added successfully. Return 0 on error
+SHERPA_ONNX_API int32_t
+SherpaOnnxSpeakerEmbeddingManagerAdd(const SherpaOnnxSpeakerEmbeddingManager *p,
+ const char *name, const float *v);
+
+// @param v Pointer to an array of embeddings. If there are n embeddings, then
+// v[0] is the pointer to the 0-th array containing the embeddings
+// v[1] is the pointer to the 1-st array containing the embeddings
+// v[n-1] is the pointer to the last array containing the embeddings
+// v[n] is a NULL pointer
+// @return Return 1 if added successfully. Return 0 on error
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerAddList(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const char *name,
+ const float **v);
+
+// Similar to SherpaOnnxSpeakerEmbeddingManagerAddList() but the memory
+// is flattened.
+//
+// The length of the input array should be `n * dim`.
+//
+// @return Return 1 if added successfully. Return 0 on error
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerAddListFlattened(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const char *name,
+ const float *v, int32_t n);
+
+// Remove a user.
+// @param naem The name of the user to remove.
+// @return Return 1 if removed successfully; return 0 on error.
+//
+// Note if the user does not exist, it also returns 0.
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerRemove(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const char *name);
+
+// Search if an existing users' embedding matches the given one.
+//
+// @param p Pointer to an array containing the embedding. The dim
+// of the array must equal to `dim` used to construct the manager `p`.
+// @param threshold A value between 0 and 1. If the similarity score exceeds
+// this threshold, we say a match is found.
+// @return Returns the name of the user if found. Return NULL if not found.
+// If not NULL, the caller has to invoke
+// SherpaOnnxSpeakerEmbeddingManagerFreeSearch() to free the returned
+// pointer to avoid memory leak.
+SHERPA_ONNX_API const char *SherpaOnnxSpeakerEmbeddingManagerSearch(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const float *v,
+ float threshold);
+
+SHERPA_ONNX_API void SherpaOnnxSpeakerEmbeddingManagerFreeSearch(
+ const char *name);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxSpeakerEmbeddingManagerSpeakerMatch {
+ float score;
+ const char *name;
+} SherpaOnnxSpeakerEmbeddingManagerSpeakerMatch;
+
+SHERPA_ONNX_API typedef struct
+ SherpaOnnxSpeakerEmbeddingManagerBestMatchesResult {
+ const SherpaOnnxSpeakerEmbeddingManagerSpeakerMatch *matches;
+ int32_t count;
+} SherpaOnnxSpeakerEmbeddingManagerBestMatchesResult;
+
+// Get the best matching speakers whose embeddings match the given
+// embedding.
+//
+// @param p Pointer to the SherpaOnnxSpeakerEmbeddingManager instance.
+// @param v Pointer to an array containing the embedding vector.
+// @param threshold Minimum similarity score required for a match (between 0 and
+// 1).
+// @param n Number of best matches to retrieve.
+// @return Returns a pointer to
+// SherpaOnnxSpeakerEmbeddingManagerBestMatchesResult
+// containing the best matches found. Returns NULL if no matches are
+// found. The caller is responsible for freeing the returned pointer
+// using SherpaOnnxSpeakerEmbeddingManagerFreeBestMatches() to
+// avoid memory leaks.
+SHERPA_ONNX_API const SherpaOnnxSpeakerEmbeddingManagerBestMatchesResult *
+SherpaOnnxSpeakerEmbeddingManagerGetBestMatches(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const float *v, float threshold,
+ int32_t n);
+
+SHERPA_ONNX_API void SherpaOnnxSpeakerEmbeddingManagerFreeBestMatches(
+ const SherpaOnnxSpeakerEmbeddingManagerBestMatchesResult *r);
+
+// Check whether the input embedding matches the embedding of the input
+// speaker.
+//
+// It is for speaker verification.
+//
+// @param name The target speaker name.
+// @param p The input embedding to check.
+// @param threshold A value between 0 and 1.
+// @return Return 1 if it matches. Otherwise, it returns 0.
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerVerify(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const char *name,
+ const float *v, float threshold);
+
+// Return 1 if the user with the name is in the manager.
+// Return 0 if the user does not exist.
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerContains(
+ const SherpaOnnxSpeakerEmbeddingManager *p, const char *name);
+
+// Return number of speakers in the manager.
+SHERPA_ONNX_API int32_t SherpaOnnxSpeakerEmbeddingManagerNumSpeakers(
+ const SherpaOnnxSpeakerEmbeddingManager *p);
+
+// Return the name of all speakers in the manager.
+//
+// @return Return an array of pointers `ans`. If there are n speakers, then
+// - ans[0] contains the name of the 0-th speaker
+// - ans[1] contains the name of the 1-st speaker
+// - ans[n-1] contains the name of the last speaker
+// - ans[n] is NULL
+// If there are no users at all, then ans[0] is NULL. In any case,
+// `ans` is not NULL.
+//
+// Each name is NULL-terminated
+//
+// The caller has to invoke SherpaOnnxSpeakerEmbeddingManagerFreeAllSpeakers()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const char *const *
+SherpaOnnxSpeakerEmbeddingManagerGetAllSpeakers(
+ const SherpaOnnxSpeakerEmbeddingManager *p);
+
+SHERPA_ONNX_API void SherpaOnnxSpeakerEmbeddingManagerFreeAllSpeakers(
+ const char *const *names);
+
+// ============================================================
+// For audio tagging
+// ============================================================
+SHERPA_ONNX_API typedef struct
+ SherpaOnnxOfflineZipformerAudioTaggingModelConfig {
+ const char *model;
+} SherpaOnnxOfflineZipformerAudioTaggingModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxAudioTaggingModelConfig {
+ SherpaOnnxOfflineZipformerAudioTaggingModelConfig zipformer;
+ const char *ced;
+ int32_t num_threads;
+ int32_t debug; // true to print debug information of the model
+ const char *provider;
+} SherpaOnnxAudioTaggingModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxAudioTaggingConfig {
+ SherpaOnnxAudioTaggingModelConfig model;
+ const char *labels;
+ int32_t top_k;
+} SherpaOnnxAudioTaggingConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxAudioEvent {
+ const char *name;
+ int32_t index;
+ float prob;
+} SherpaOnnxAudioEvent;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxAudioTagging SherpaOnnxAudioTagging;
+
+// The user has to invoke
+// SherpaOnnxDestroyAudioTagging()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxAudioTagging *SherpaOnnxCreateAudioTagging(
+ const SherpaOnnxAudioTaggingConfig *config);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyAudioTagging(
+ const SherpaOnnxAudioTagging *tagger);
+
+// The user has to invoke SherpaOnnxDestroyOfflineStream()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOfflineStream *
+SherpaOnnxAudioTaggingCreateOfflineStream(const SherpaOnnxAudioTagging *tagger);
+
+// Return an array of pointers. The length of the array is top_k + 1.
+// If top_k is -1, then config.top_k is used, where config is the config
+// used to create the input tagger.
+//
+// The ans[0]->prob has the largest probability among the array elements
+// The last element of the array is a null pointer
+//
+// The user has to use SherpaOnnxAudioTaggingFreeResults()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxAudioEvent *const *
+SherpaOnnxAudioTaggingCompute(const SherpaOnnxAudioTagging *tagger,
+ const SherpaOnnxOfflineStream *s, int32_t top_k);
+
+SHERPA_ONNX_API void SherpaOnnxAudioTaggingFreeResults(
+ const SherpaOnnxAudioEvent *const *p);
+
+// ============================================================
+// For punctuation
+// ============================================================
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflinePunctuationModelConfig {
+ const char *ct_transformer;
+ int32_t num_threads;
+ int32_t debug; // true to print debug information of the model
+ const char *provider;
+} SherpaOnnxOfflinePunctuationModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflinePunctuationConfig {
+ SherpaOnnxOfflinePunctuationModelConfig model;
+} SherpaOnnxOfflinePunctuationConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflinePunctuation
+ SherpaOnnxOfflinePunctuation;
+
+// The user has to invoke SherpaOnnxDestroyOfflinePunctuation()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOfflinePunctuation *
+SherpaOnnxCreateOfflinePunctuation(
+ const SherpaOnnxOfflinePunctuationConfig *config);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflinePunctuation(
+ const SherpaOnnxOfflinePunctuation *punct);
+
+// Add punctuations to the input text.
+// The user has to invoke SherpaOfflinePunctuationFreeText()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const char *SherpaOfflinePunctuationAddPunct(
+ const SherpaOnnxOfflinePunctuation *punct, const char *text);
+
+SHERPA_ONNX_API void SherpaOfflinePunctuationFreeText(const char *text);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlinePunctuationModelConfig {
+ const char *cnn_bilstm;
+ const char *bpe_vocab;
+ int32_t num_threads;
+ int32_t debug;
+ const char *provider;
+} SherpaOnnxOnlinePunctuationModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlinePunctuationConfig {
+ SherpaOnnxOnlinePunctuationModelConfig model;
+} SherpaOnnxOnlinePunctuationConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOnlinePunctuation
+ SherpaOnnxOnlinePunctuation;
+
+// Create an online punctuation processor. The user has to invoke
+// SherpaOnnxDestroyOnlinePunctuation() to free the returned pointer
+// to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOnlinePunctuation *
+SherpaOnnxCreateOnlinePunctuation(
+ const SherpaOnnxOnlinePunctuationConfig *config);
+
+// Free a pointer returned by SherpaOnnxCreateOnlinePunctuation()
+SHERPA_ONNX_API void SherpaOnnxDestroyOnlinePunctuation(
+ const SherpaOnnxOnlinePunctuation *punctuation);
+
+// Add punctuations to the input text. The user has to invoke
+// SherpaOnnxOnlinePunctuationFreeText() to free the returned pointer
+// to avoid memory leak
+SHERPA_ONNX_API const char *SherpaOnnxOnlinePunctuationAddPunct(
+ const SherpaOnnxOnlinePunctuation *punctuation, const char *text);
+
+// Free a pointer returned by SherpaOnnxOnlinePunctuationAddPunct()
+SHERPA_ONNX_API void SherpaOnnxOnlinePunctuationFreeText(const char *text);
+
+// for resampling
+SHERPA_ONNX_API typedef struct SherpaOnnxLinearResampler
+ SherpaOnnxLinearResampler;
+
+/*
+ float min_freq = min(sampling_rate_in_hz, samp_rate_out_hz);
+ float lowpass_cutoff = 0.99 * 0.5 * min_freq;
+ int32_t lowpass_filter_width = 6;
+
+ You can set filter_cutoff_hz to lowpass_cutoff
+ sand set num_zeros to lowpass_filter_width
+*/
+// The user has to invoke SherpaOnnxDestroyLinearResampler()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxLinearResampler *
+SherpaOnnxCreateLinearResampler(int32_t samp_rate_in_hz,
+ int32_t samp_rate_out_hz,
+ float filter_cutoff_hz, int32_t num_zeros);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyLinearResampler(
+ const SherpaOnnxLinearResampler *p);
+
+SHERPA_ONNX_API void SherpaOnnxLinearResamplerReset(
+ const SherpaOnnxLinearResampler *p);
+
+typedef struct SherpaOnnxResampleOut {
+ const float *samples;
+ int32_t n;
+} SherpaOnnxResampleOut;
+// The user has to invoke SherpaOnnxLinearResamplerResampleFree()
+// to free the returned pointer to avoid memory leak.
+//
+// If this is the last segment, you can set flush to 1; otherwise, please
+// set flush to 0
+SHERPA_ONNX_API const SherpaOnnxResampleOut *SherpaOnnxLinearResamplerResample(
+ const SherpaOnnxLinearResampler *p, const float *input, int32_t input_dim,
+ int32_t flush);
+
+SHERPA_ONNX_API void SherpaOnnxLinearResamplerResampleFree(
+ const SherpaOnnxResampleOut *p);
+
+SHERPA_ONNX_API int32_t SherpaOnnxLinearResamplerResampleGetInputSampleRate(
+ const SherpaOnnxLinearResampler *p);
+
+SHERPA_ONNX_API int32_t SherpaOnnxLinearResamplerResampleGetOutputSampleRate(
+ const SherpaOnnxLinearResampler *p);
+
+// =========================================================================
+// For offline speaker diarization (i.e., non-streaming speaker diarization)
+// =========================================================================
+SHERPA_ONNX_API typedef struct
+ SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig {
+ const char *model;
+} SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeakerSegmentationModelConfig {
+ SherpaOnnxOfflineSpeakerSegmentationPyannoteModelConfig pyannote;
+ int32_t num_threads; // 1
+ int32_t debug; // false
+ const char *provider; // "cpu"
+} SherpaOnnxOfflineSpeakerSegmentationModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxFastClusteringConfig {
+ // If greater than 0, then threshold is ignored.
+ //
+ // We strongly recommend that you set it if you know the number of clusters
+ // in advance
+ int32_t num_clusters;
+
+ // distance threshold.
+ //
+ // The smaller, the more clusters it will generate.
+ // The larger, the fewer clusters it will generate.
+ float threshold;
+} SherpaOnnxFastClusteringConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeakerDiarizationConfig {
+ SherpaOnnxOfflineSpeakerSegmentationModelConfig segmentation;
+ SherpaOnnxSpeakerEmbeddingExtractorConfig embedding;
+ SherpaOnnxFastClusteringConfig clustering;
+
+ // if a segment is less than this value, then it is discarded
+ float min_duration_on; // in seconds
+
+ // if the gap between to segments of the same speaker is less than this value,
+ // then these two segments are merged into a single segment.
+ // We do this recursively.
+ float min_duration_off; // in seconds
+} SherpaOnnxOfflineSpeakerDiarizationConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeakerDiarization
+ SherpaOnnxOfflineSpeakerDiarization;
+
+// The users has to invoke SherpaOnnxDestroyOfflineSpeakerDiarization()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarization *
+SherpaOnnxCreateOfflineSpeakerDiarization(
+ const SherpaOnnxOfflineSpeakerDiarizationConfig *config);
+
+// Free the pointer returned by SherpaOnnxCreateOfflineSpeakerDiarization()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineSpeakerDiarization(
+ const SherpaOnnxOfflineSpeakerDiarization *sd);
+
+// Expected sample rate of the input audio samples
+SHERPA_ONNX_API int32_t SherpaOnnxOfflineSpeakerDiarizationGetSampleRate(
+ const SherpaOnnxOfflineSpeakerDiarization *sd);
+
+// Only config->clustering is used. All other fields are ignored
+SHERPA_ONNX_API void SherpaOnnxOfflineSpeakerDiarizationSetConfig(
+ const SherpaOnnxOfflineSpeakerDiarization *sd,
+ const SherpaOnnxOfflineSpeakerDiarizationConfig *config);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeakerDiarizationResult
+ SherpaOnnxOfflineSpeakerDiarizationResult;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeakerDiarizationSegment {
+ float start;
+ float end;
+ int32_t speaker;
+} SherpaOnnxOfflineSpeakerDiarizationSegment;
+
+SHERPA_ONNX_API int32_t SherpaOnnxOfflineSpeakerDiarizationResultGetNumSpeakers(
+ const SherpaOnnxOfflineSpeakerDiarizationResult *r);
+
+SHERPA_ONNX_API int32_t SherpaOnnxOfflineSpeakerDiarizationResultGetNumSegments(
+ const SherpaOnnxOfflineSpeakerDiarizationResult *r);
+
+// The user has to invoke SherpaOnnxOfflineSpeakerDiarizationDestroySegment()
+// to free the returned pointer to avoid memory leak.
+//
+// The returned pointer is the start address of an array.
+// Number of entries in the array equals to the value
+// returned by SherpaOnnxOfflineSpeakerDiarizationResultGetNumSegments()
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarizationSegment *
+SherpaOnnxOfflineSpeakerDiarizationResultSortByStartTime(
+ const SherpaOnnxOfflineSpeakerDiarizationResult *r);
+
+SHERPA_ONNX_API void SherpaOnnxOfflineSpeakerDiarizationDestroySegment(
+ const SherpaOnnxOfflineSpeakerDiarizationSegment *s);
+
+typedef int32_t (*SherpaOnnxOfflineSpeakerDiarizationProgressCallback)(
+ int32_t num_processed_chunks, int32_t num_total_chunks, void *arg);
+
+typedef int32_t (*SherpaOnnxOfflineSpeakerDiarizationProgressCallbackNoArg)(
+ int32_t num_processed_chunks, int32_t num_total_chunks);
+
+// The user has to invoke SherpaOnnxOfflineSpeakerDiarizationDestroyResult()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarizationResult *
+SherpaOnnxOfflineSpeakerDiarizationProcess(
+ const SherpaOnnxOfflineSpeakerDiarization *sd, const float *samples,
+ int32_t n);
+
+// The user has to invoke SherpaOnnxOfflineSpeakerDiarizationDestroyResult()
+// to free the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarizationResult *
+SherpaOnnxOfflineSpeakerDiarizationProcessWithCallback(
+ const SherpaOnnxOfflineSpeakerDiarization *sd, const float *samples,
+ int32_t n, SherpaOnnxOfflineSpeakerDiarizationProgressCallback callback,
+ void *arg);
+
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarizationResult *
+SherpaOnnxOfflineSpeakerDiarizationProcessWithCallbackNoArg(
+ const SherpaOnnxOfflineSpeakerDiarization *sd, const float *samples,
+ int32_t n,
+ SherpaOnnxOfflineSpeakerDiarizationProgressCallbackNoArg callback);
+
+SHERPA_ONNX_API void SherpaOnnxOfflineSpeakerDiarizationDestroyResult(
+ const SherpaOnnxOfflineSpeakerDiarizationResult *r);
+
+// =========================================================================
+// For offline speech enhancement
+// =========================================================================
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig {
+ const char *model;
+} SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeechDenoiserModelConfig {
+ SherpaOnnxOfflineSpeechDenoiserGtcrnModelConfig gtcrn;
+ int32_t num_threads;
+ int32_t debug; // true to print debug information of the model
+ const char *provider;
+} SherpaOnnxOfflineSpeechDenoiserModelConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeechDenoiserConfig {
+ SherpaOnnxOfflineSpeechDenoiserModelConfig model;
+} SherpaOnnxOfflineSpeechDenoiserConfig;
+
+SHERPA_ONNX_API typedef struct SherpaOnnxOfflineSpeechDenoiser
+ SherpaOnnxOfflineSpeechDenoiser;
+
+// The users has to invoke SherpaOnnxDestroyOfflineSpeechDenoiser()
+// to free the returned pointer to avoid memory leak
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeechDenoiser *
+SherpaOnnxCreateOfflineSpeechDenoiser(
+ const SherpaOnnxOfflineSpeechDenoiserConfig *config);
+
+// Free the pointer returned by SherpaOnnxCreateOfflineSpeechDenoiser()
+SHERPA_ONNX_API void SherpaOnnxDestroyOfflineSpeechDenoiser(
+ const SherpaOnnxOfflineSpeechDenoiser *sd);
+
+SHERPA_ONNX_API int32_t SherpaOnnxOfflineSpeechDenoiserGetSampleRate(
+ const SherpaOnnxOfflineSpeechDenoiser *sd);
+
+SHERPA_ONNX_API typedef struct SherpaOnnxDenoisedAudio {
+ const float *samples; // in the range [-1, 1]
+ int32_t n; // number of samples
+ int32_t sample_rate;
+} SherpaOnnxDenoisedAudio;
+
+// Run speech denosing on input samples
+// @param samples A 1-D array containing the input audio samples. Each sample
+// should be in the range [-1, 1].
+// @param n Number of samples
+// @param sample_rate Sample rate of the input samples
+//
+// The user MUST use SherpaOnnxDestroyDenoisedAudio() to free the returned
+// pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxDenoisedAudio *
+SherpaOnnxOfflineSpeechDenoiserRun(const SherpaOnnxOfflineSpeechDenoiser *sd,
+ const float *samples, int32_t n,
+ int32_t sample_rate);
+
+SHERPA_ONNX_API void SherpaOnnxDestroyDenoisedAudio(
+ const SherpaOnnxDenoisedAudio *p);
+
+#ifdef __OHOS__
+
+// It is for HarmonyOS
+typedef struct NativeResourceManager NativeResourceManager;
+
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeechDenoiser *
+SherpaOnnxCreateOfflineSpeechDenoiserOHOS(
+ const SherpaOnnxOfflineSpeechDenoiserConfig *config,
+ NativeResourceManager *mgr);
+
+/// @param config Config for the recognizer.
+/// @return Return a pointer to the recognizer. The user has to invoke
+// SherpaOnnxDestroyOnlineRecognizer() to free it to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxOnlineRecognizer *
+SherpaOnnxCreateOnlineRecognizerOHOS(
+ const SherpaOnnxOnlineRecognizerConfig *config, NativeResourceManager *mgr);
+
+/// @param config Config for the recognizer.
+/// @return Return a pointer to the recognizer. The user has to invoke
+// SherpaOnnxDestroyOfflineRecognizer() to free it to avoid memory
+// leak.
+SHERPA_ONNX_API const SherpaOnnxOfflineRecognizer *
+SherpaOnnxCreateOfflineRecognizerOHOS(
+ const SherpaOnnxOfflineRecognizerConfig *config,
+ NativeResourceManager *mgr);
+
+// Return an instance of VoiceActivityDetector.
+// The user has to use SherpaOnnxDestroyVoiceActivityDetector() to free
+// the returned pointer to avoid memory leak.
+SHERPA_ONNX_API const SherpaOnnxVoiceActivityDetector *
+SherpaOnnxCreateVoiceActivityDetectorOHOS(
+ const SherpaOnnxVadModelConfig *config, float buffer_size_in_seconds,
+ NativeResourceManager *mgr);
+
+SHERPA_ONNX_API const SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTtsOHOS(
+ const SherpaOnnxOfflineTtsConfig *config, NativeResourceManager *mgr);
+
+SHERPA_ONNX_API const SherpaOnnxSpeakerEmbeddingExtractor *
+SherpaOnnxCreateSpeakerEmbeddingExtractorOHOS(
+ const SherpaOnnxSpeakerEmbeddingExtractorConfig *config,
+ NativeResourceManager *mgr);
+
+SHERPA_ONNX_API const SherpaOnnxKeywordSpotter *
+SherpaOnnxCreateKeywordSpotterOHOS(const SherpaOnnxKeywordSpotterConfig *config,
+ NativeResourceManager *mgr);
+
+SHERPA_ONNX_API const SherpaOnnxOfflineSpeakerDiarization *
+SherpaOnnxCreateOfflineSpeakerDiarizationOHOS(
+ const SherpaOnnxOfflineSpeakerDiarizationConfig *config,
+ NativeResourceManager *mgr);
+#endif
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif // SHERPA_ONNX_C_API_C_API_H_
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/cxx-api.h b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/cxx-api.h
new file mode 100644
index 0000000..e1981f0
--- /dev/null
+++ b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/include/sherpa-onnx/c-api/cxx-api.h
@@ -0,0 +1,841 @@
+// sherpa-onnx/c-api/cxx-api.h
+//
+// Copyright (c) 2024 Xiaomi Corporation
+
+// C++ Wrapper of the C API for sherpa-onnx
+#ifndef SHERPA_ONNX_C_API_CXX_API_H_
+#define SHERPA_ONNX_C_API_CXX_API_H_
+
+#include
+#include
+#include
+
+#include "sherpa-onnx/c-api/c-api.h"
+
+namespace sherpa_onnx::cxx {
+
+// ============================================================================
+// Streaming ASR
+// ============================================================================
+struct OnlineTransducerModelConfig {
+ std::string encoder;
+ std::string decoder;
+ std::string joiner;
+};
+
+struct OnlineParaformerModelConfig {
+ std::string encoder;
+ std::string decoder;
+};
+
+struct OnlineZipformer2CtcModelConfig {
+ std::string model;
+};
+
+struct OnlineNemoCtcModelConfig {
+ std::string model;
+};
+
+struct OnlineToneCtcModelConfig {
+ std::string model;
+};
+
+struct OnlineModelConfig {
+ OnlineTransducerModelConfig transducer;
+ OnlineParaformerModelConfig paraformer;
+ OnlineZipformer2CtcModelConfig zipformer2_ctc;
+ OnlineNemoCtcModelConfig nemo_ctc;
+ OnlineToneCtcModelConfig t_one_ctc;
+ std::string tokens;
+ int32_t num_threads = 1;
+ std::string provider = "cpu";
+ bool debug = false;
+ std::string model_type;
+ std::string modeling_unit = "cjkchar";
+ std::string bpe_vocab;
+ std::string tokens_buf;
+};
+
+struct FeatureConfig {
+ int32_t sample_rate = 16000;
+ int32_t feature_dim = 80;
+};
+
+struct OnlineCtcFstDecoderConfig {
+ std::string graph;
+ int32_t max_active = 3000;
+};
+
+struct HomophoneReplacerConfig {
+ std::string dict_dir; // unused
+ std::string lexicon;
+ std::string rule_fsts;
+};
+
+struct OnlineRecognizerConfig {
+ FeatureConfig feat_config;
+ OnlineModelConfig model_config;
+
+ std::string decoding_method = "greedy_search";
+
+ int32_t max_active_paths = 4;
+
+ bool enable_endpoint = false;
+
+ float rule1_min_trailing_silence = 2.4;
+
+ float rule2_min_trailing_silence = 1.2;
+
+ float rule3_min_utterance_length = 20;
+
+ std::string hotwords_file;
+
+ float hotwords_score = 1.5;
+
+ OnlineCtcFstDecoderConfig ctc_fst_decoder_config;
+ std::string rule_fsts;
+ std::string rule_fars;
+ float blank_penalty = 0;
+
+ std::string hotwords_buf;
+ HomophoneReplacerConfig hr;
+};
+
+struct OnlineRecognizerResult {
+ std::string text;
+ std::vector tokens;
+ std::vector timestamps;
+ std::string json;
+};
+
+struct Wave {
+ std::vector samples;
+ int32_t sample_rate;
+};
+
+SHERPA_ONNX_API Wave ReadWave(const std::string &filename);
+
+// Return true on success;
+// Return false on failure
+SHERPA_ONNX_API bool WriteWave(const std::string &filename, const Wave &wave);
+
+template
+class SHERPA_ONNX_API MoveOnly {
+ public:
+ MoveOnly() = default;
+ explicit MoveOnly(const T *p) : p_(p) {}
+
+ ~MoveOnly() { Destroy(); }
+
+ MoveOnly(const MoveOnly &) = delete;
+
+ MoveOnly &operator=(const MoveOnly &) = delete;
+
+ MoveOnly(MoveOnly &&other) : p_(other.Release()) {}
+
+ MoveOnly &operator=(MoveOnly &&other) {
+ if (&other == this) {
+ return *this;
+ }
+
+ Destroy();
+
+ p_ = other.Release();
+
+ return *this;
+ }
+
+ const T *Get() const { return p_; }
+
+ const T *Release() {
+ const T *p = p_;
+ p_ = nullptr;
+ return p;
+ }
+
+ private:
+ void Destroy() {
+ if (p_ == nullptr) {
+ return;
+ }
+
+ static_cast(this)->Destroy(p_);
+
+ p_ = nullptr;
+ }
+
+ protected:
+ const T *p_ = nullptr;
+};
+
+class SHERPA_ONNX_API OnlineStream
+ : public MoveOnly {
+ public:
+ explicit OnlineStream(const SherpaOnnxOnlineStream *p);
+
+ void AcceptWaveform(int32_t sample_rate, const float *samples,
+ int32_t n) const;
+
+ void InputFinished() const;
+
+ void Destroy(const SherpaOnnxOnlineStream *p) const;
+};
+
+class SHERPA_ONNX_API OnlineRecognizer
+ : public MoveOnly {
+ public:
+ static OnlineRecognizer Create(const OnlineRecognizerConfig &config);
+
+ void Destroy(const SherpaOnnxOnlineRecognizer *p) const;
+
+ OnlineStream CreateStream() const;
+
+ OnlineStream CreateStream(const std::string &hotwords) const;
+
+ bool IsReady(const OnlineStream *s) const;
+
+ void Decode(const OnlineStream *s) const;
+
+ void Decode(const OnlineStream *ss, int32_t n) const;
+
+ OnlineRecognizerResult GetResult(const OnlineStream *s) const;
+
+ void Reset(const OnlineStream *s) const;
+
+ bool IsEndpoint(const OnlineStream *s) const;
+
+ private:
+ explicit OnlineRecognizer(const SherpaOnnxOnlineRecognizer *p);
+};
+
+// ============================================================================
+// Non-streaming ASR
+// ============================================================================
+struct SHERPA_ONNX_API OfflineTransducerModelConfig {
+ std::string encoder;
+ std::string decoder;
+ std::string joiner;
+};
+
+struct SHERPA_ONNX_API OfflineParaformerModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineNemoEncDecCtcModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineWhisperModelConfig {
+ std::string encoder;
+ std::string decoder;
+ std::string language;
+ std::string task = "transcribe";
+ int32_t tail_paddings = -1;
+};
+
+struct SHERPA_ONNX_API OfflineCanaryModelConfig {
+ std::string encoder;
+ std::string decoder;
+ std::string src_lang;
+ std::string tgt_lang;
+ bool use_pnc = true;
+};
+
+struct SHERPA_ONNX_API OfflineFireRedAsrModelConfig {
+ std::string encoder;
+ std::string decoder;
+};
+
+struct SHERPA_ONNX_API OfflineTdnnModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineSenseVoiceModelConfig {
+ std::string model;
+ std::string language;
+ bool use_itn = false;
+};
+
+struct SHERPA_ONNX_API OfflineDolphinModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineZipformerCtcModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineWenetCtcModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineOmnilingualAsrCtcModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineMedAsrCtcModelConfig {
+ std::string model;
+};
+
+struct SHERPA_ONNX_API OfflineMoonshineModelConfig {
+ std::string preprocessor;
+ std::string encoder;
+ std::string uncached_decoder;
+ std::string cached_decoder;
+};
+
+struct SHERPA_ONNX_API OfflineFunASRNanoModelConfig {
+ std::string encoder_adaptor;
+ std::string llm;
+ std::string embedding;
+ std::string tokenizer;
+ std::string system_prompt = "You are a helpful assistant.";
+ std::string user_prompt = "语音转写:";
+ int32_t max_new_tokens = 512;
+ float temperature = 1e-6f;
+ float top_p = 0.8f;
+ int32_t seed = 42;
+};
+
+struct SHERPA_ONNX_API OfflineModelConfig {
+ OfflineTransducerModelConfig transducer;
+ OfflineParaformerModelConfig paraformer;
+ OfflineNemoEncDecCtcModelConfig nemo_ctc;
+ OfflineWhisperModelConfig whisper;
+ OfflineTdnnModelConfig tdnn;
+
+ std::string tokens;
+ int32_t num_threads = 1;
+ bool debug = false;
+ std::string provider = "cpu";
+ std::string model_type;
+ std::string modeling_unit = "cjkchar";
+ std::string bpe_vocab;
+ std::string telespeech_ctc;
+ OfflineSenseVoiceModelConfig sense_voice;
+ OfflineMoonshineModelConfig moonshine;
+ OfflineFireRedAsrModelConfig fire_red_asr;
+ OfflineDolphinModelConfig dolphin;
+ OfflineZipformerCtcModelConfig zipformer_ctc;
+ OfflineCanaryModelConfig canary;
+ OfflineWenetCtcModelConfig wenet_ctc;
+ OfflineOmnilingualAsrCtcModelConfig omnilingual;
+ OfflineMedAsrCtcModelConfig medasr;
+ OfflineFunASRNanoModelConfig funasr_nano;
+};
+
+struct SHERPA_ONNX_API OfflineLMConfig {
+ std::string model;
+ float scale = 1.0;
+};
+
+struct SHERPA_ONNX_API OfflineRecognizerConfig {
+ FeatureConfig feat_config;
+ OfflineModelConfig model_config;
+ OfflineLMConfig lm_config;
+
+ std::string decoding_method = "greedy_search";
+ int32_t max_active_paths = 4;
+
+ std::string hotwords_file;
+
+ float hotwords_score = 1.5;
+ std::string rule_fsts;
+ std::string rule_fars;
+ float blank_penalty = 0;
+ HomophoneReplacerConfig hr;
+};
+
+struct SHERPA_ONNX_API OfflineRecognizerResult {
+ std::string text;
+ std::vector timestamps;
+ std::vector tokens;
+ std::string json;
+ std::string lang;
+ std::string emotion;
+ std::string event;
+
+ // non-empty only for TDT models
+ std::vector durations;
+};
+
+class SHERPA_ONNX_API OfflineStream
+ : public MoveOnly {
+ public:
+ explicit OfflineStream(const SherpaOnnxOfflineStream *p);
+
+ void AcceptWaveform(int32_t sample_rate, const float *samples,
+ int32_t n) const;
+
+ void Destroy(const SherpaOnnxOfflineStream *p) const;
+};
+
+class SHERPA_ONNX_API OfflineRecognizer
+ : public MoveOnly {
+ public:
+ static OfflineRecognizer Create(const OfflineRecognizerConfig &config);
+
+ void Destroy(const SherpaOnnxOfflineRecognizer *p) const;
+
+ OfflineStream CreateStream() const;
+
+ OfflineStream CreateStream(const std::string &hotwords) const;
+
+ void Decode(const OfflineStream *s) const;
+
+ void Decode(const OfflineStream *ss, int32_t n) const;
+
+ OfflineRecognizerResult GetResult(const OfflineStream *s) const;
+
+ // For unreal engine, please use this function
+ // See also https://github.com/k2-fsa/sherpa-onnx/discussions/1960
+ std::shared_ptr GetResultPtr(
+ const OfflineStream *s) const;
+
+ void SetConfig(const OfflineRecognizerConfig &config) const;
+
+ private:
+ explicit OfflineRecognizer(const SherpaOnnxOfflineRecognizer *p);
+};
+
+// ============================================================================
+// Non-streaming TTS
+// ============================================================================
+struct OfflineTtsVitsModelConfig {
+ std::string model;
+ std::string lexicon;
+ std::string tokens;
+ std::string data_dir;
+ std::string dict_dir; // unused
+
+ float noise_scale = 0.667;
+ float noise_scale_w = 0.8;
+ float length_scale = 1.0; // < 1, faster in speed; > 1, slower in speed
+};
+
+struct OfflineTtsMatchaModelConfig {
+ std::string acoustic_model;
+ std::string vocoder;
+ std::string lexicon;
+ std::string tokens;
+ std::string data_dir;
+ std::string dict_dir; // unused
+
+ float noise_scale = 0.667;
+ float length_scale = 1.0; // < 1, faster in speed; > 1, slower in speed
+};
+
+struct OfflineTtsKokoroModelConfig {
+ std::string model;
+ std::string voices;
+ std::string tokens;
+ std::string data_dir;
+ std::string dict_dir; // unused
+ std::string lexicon;
+ std::string lang;
+
+ float length_scale = 1.0; // < 1, faster in speed; > 1, slower in speed
+};
+
+struct OfflineTtsKittenModelConfig {
+ std::string model;
+ std::string voices;
+ std::string tokens;
+ std::string data_dir;
+
+ float length_scale = 1.0; // < 1, faster in speed; > 1, slower in speed
+};
+
+struct OfflineTtsZipvoiceModelConfig {
+ std::string tokens;
+ std::string encoder;
+ std::string decoder;
+ std::string vocoder;
+ std::string data_dir;
+ std::string lexicon;
+
+ float feat_scale = 0.1;
+ float t_shift = 0.5;
+ float target_rms = 0.1;
+ float guidance_scale = 1.0;
+};
+
+struct OfflineTtsModelConfig {
+ OfflineTtsVitsModelConfig vits;
+ OfflineTtsMatchaModelConfig matcha;
+ OfflineTtsKokoroModelConfig kokoro;
+ OfflineTtsKittenModelConfig kitten;
+ OfflineTtsZipvoiceModelConfig zipvoice;
+
+ int32_t num_threads = 1;
+ bool debug = false;
+ std::string provider = "cpu";
+};
+
+struct OfflineTtsConfig {
+ OfflineTtsModelConfig model;
+ std::string rule_fsts;
+ std::string rule_fars;
+ int32_t max_num_sentences = 1;
+ float silence_scale = 0.2;
+};
+
+struct GeneratedAudio {
+ std::vector samples; // in the range [-1, 1]
+ int32_t sample_rate;
+};
+
+// Return 1 to continue generating
+// Return 0 to stop generating
+using OfflineTtsCallback = int32_t (*)(const float *samples,
+ int32_t num_samples, float progress,
+ void *arg);
+
+class SHERPA_ONNX_API OfflineTts
+ : public MoveOnly {
+ public:
+ static OfflineTts Create(const OfflineTtsConfig &config);
+
+ void Destroy(const SherpaOnnxOfflineTts *p) const;
+
+ // Return the sample rate of the generated audio
+ int32_t SampleRate() const;
+
+ // Number of supported speakers.
+ // If it supports only a single speaker, then it return 0 or 1.
+ int32_t NumSpeakers() const;
+
+ // @param text A string containing words separated by spaces
+ // @param sid Speaker ID. Used only for multi-speaker models, e.g., models
+ // trained using the VCTK dataset. It is not used for
+ // single-speaker models, e.g., models trained using the ljspeech
+ // dataset.
+ // @param speed The speed for the generated speech. E.g., 2 means 2x faster.
+ // @param callback If not NULL, it is called whenever config.max_num_sentences
+ // sentences have been processed. The callback is called in
+ // the current thread.
+ GeneratedAudio Generate(const std::string &text, int32_t sid = 0,
+ float speed = 1.0,
+ OfflineTtsCallback callback = nullptr,
+ void *arg = nullptr) const;
+
+ // Like Generate, but return a smart pointer.
+ //
+ // See also https://github.com/k2-fsa/sherpa-onnx/issues/2347
+ std::shared_ptr Generate2(
+ const std::string &text, int32_t sid = 0, float speed = 1.0,
+ OfflineTtsCallback callback = nullptr, void *arg = nullptr) const;
+
+ private:
+ explicit OfflineTts(const SherpaOnnxOfflineTts *p);
+};
+
+// ============================================================
+// For Keyword Spotter
+// ============================================================
+
+struct KeywordResult {
+ std::string keyword;
+ std::vector tokens;
+ std::vector timestamps;
+ float start_time;
+ std::string json;
+};
+
+struct KeywordSpotterConfig {
+ FeatureConfig feat_config;
+ OnlineModelConfig model_config;
+ int32_t max_active_paths = 4;
+ int32_t num_trailing_blanks = 1;
+ float keywords_score = 1.0f;
+ float keywords_threshold = 0.25f;
+ std::string keywords_file;
+};
+
+class SHERPA_ONNX_API KeywordSpotter
+ : public MoveOnly {
+ public:
+ static KeywordSpotter Create(const KeywordSpotterConfig &config);
+
+ void Destroy(const SherpaOnnxKeywordSpotter *p) const;
+
+ OnlineStream CreateStream() const;
+
+ OnlineStream CreateStream(const std::string &keywords) const;
+
+ bool IsReady(const OnlineStream *s) const;
+
+ void Decode(const OnlineStream *s) const;
+
+ void Decode(const OnlineStream *ss, int32_t n) const;
+
+ void Reset(const OnlineStream *s) const;
+
+ KeywordResult GetResult(const OnlineStream *s) const;
+
+ private:
+ explicit KeywordSpotter(const SherpaOnnxKeywordSpotter *p);
+};
+
+struct OfflineSpeechDenoiserGtcrnModelConfig {
+ std::string model;
+};
+
+struct OfflineSpeechDenoiserModelConfig {
+ OfflineSpeechDenoiserGtcrnModelConfig gtcrn;
+ int32_t num_threads = 1;
+ int32_t debug = false;
+ std::string provider = "cpu";
+};
+
+struct OfflineSpeechDenoiserConfig {
+ OfflineSpeechDenoiserModelConfig model;
+};
+
+struct DenoisedAudio {
+ std::vector samples; // in the range [-1, 1]
+ int32_t sample_rate;
+};
+
+class SHERPA_ONNX_API OfflineSpeechDenoiser
+ : public MoveOnly {
+ public:
+ static OfflineSpeechDenoiser Create(
+ const OfflineSpeechDenoiserConfig &config);
+
+ void Destroy(const SherpaOnnxOfflineSpeechDenoiser *p) const;
+
+ DenoisedAudio Run(const float *samples, int32_t n, int32_t sample_rate) const;
+
+ int32_t GetSampleRate() const;
+
+ private:
+ explicit OfflineSpeechDenoiser(const SherpaOnnxOfflineSpeechDenoiser *p);
+};
+
+// ==============================
+// VAD
+// ==============================
+
+struct SileroVadModelConfig {
+ std::string model;
+ float threshold = 0.5;
+ float min_silence_duration = 0.5;
+ float min_speech_duration = 0.25;
+ int32_t window_size = 512;
+ float max_speech_duration = 20;
+};
+
+struct TenVadModelConfig {
+ std::string model;
+ float threshold = 0.5;
+ float min_silence_duration = 0.5;
+ float min_speech_duration = 0.25;
+ int32_t window_size = 256;
+ float max_speech_duration = 20;
+};
+
+struct VadModelConfig {
+ SileroVadModelConfig silero_vad;
+ TenVadModelConfig ten_vad;
+
+ int32_t sample_rate = 16000;
+ int32_t num_threads = 1;
+ std::string provider = "cpu";
+ bool debug = false;
+};
+
+struct SpeechSegment {
+ int32_t start;
+ std::vector samples;
+};
+
+class SHERPA_ONNX_API CircularBuffer
+ : public MoveOnly {
+ public:
+ static CircularBuffer Create(int32_t capacity);
+
+ void Destroy(const SherpaOnnxCircularBuffer *p) const;
+
+ void Push(const float *p, int32_t n) const;
+
+ std::vector Get(int32_t start_index, int32_t n) const;
+
+ void Pop(int32_t n) const;
+
+ int32_t Size() const;
+
+ int32_t Head() const;
+
+ void Reset() const;
+
+ private:
+ explicit CircularBuffer(const SherpaOnnxCircularBuffer *p);
+};
+
+class SHERPA_ONNX_API VoiceActivityDetector
+ : public MoveOnly {
+ public:
+ static VoiceActivityDetector Create(const VadModelConfig &config,
+ float buffer_size_in_seconds);
+
+ void Destroy(const SherpaOnnxVoiceActivityDetector *p) const;
+
+ void AcceptWaveform(const float *samples, int32_t n) const;
+
+ bool IsEmpty() const;
+
+ bool IsDetected() const;
+
+ void Pop() const;
+
+ void Clear() const;
+
+ SpeechSegment Front() const;
+
+ // For unreal engine, please use this function
+ // See also https://github.com/k2-fsa/sherpa-onnx/discussions/1960
+ std::shared_ptr FrontPtr() const;
+
+ void Reset() const;
+
+ void Flush() const;
+
+ private:
+ explicit VoiceActivityDetector(const SherpaOnnxVoiceActivityDetector *p);
+};
+
+class SHERPA_ONNX_API LinearResampler
+ : public MoveOnly {
+ public:
+ LinearResampler() = default;
+ static LinearResampler Create(int32_t samp_rate_in_hz,
+ int32_t samp_rate_out_hz,
+ float filter_cutoff_hz, int32_t num_zeros);
+
+ void Destroy(const SherpaOnnxLinearResampler *p) const;
+
+ void Reset() const;
+
+ std::vector Resample(const float *input, int32_t input_dim,
+ bool flush) const;
+
+ int32_t GetInputSamplingRate() const;
+ int32_t GetOutputSamplingRate() const;
+
+ private:
+ explicit LinearResampler(const SherpaOnnxLinearResampler *p);
+};
+
+SHERPA_ONNX_API std::string GetVersionStr();
+SHERPA_ONNX_API std::string GetGitSha1();
+SHERPA_ONNX_API std::string GetGitDate();
+SHERPA_ONNX_API bool FileExists(const std::string &filename);
+
+// ============================================================================
+// Offline Punctuation
+// ============================================================================
+struct OfflinePunctuationModelConfig {
+ std::string ct_transformer;
+ int32_t num_threads = 1;
+ bool debug = false;
+ std::string provider = "cpu";
+};
+
+struct OfflinePunctuationConfig {
+ OfflinePunctuationModelConfig model;
+};
+
+class SHERPA_ONNX_API OfflinePunctuation
+ : public MoveOnly {
+ public:
+ static OfflinePunctuation Create(const OfflinePunctuationConfig &config);
+
+ void Destroy(const SherpaOnnxOfflinePunctuation *p) const;
+
+ // Add punctuations to the input text and return it.
+ std::string AddPunctuation(const std::string &text) const;
+
+ private:
+ explicit OfflinePunctuation(const SherpaOnnxOfflinePunctuation *p);
+};
+
+// ============================================================================
+// Online Punctuation
+// ============================================================================
+struct OnlinePunctuationModelConfig {
+ std::string cnn_bilstm;
+ std::string bpe_vocab;
+ int32_t num_threads = 1;
+ bool debug = false;
+ std::string provider = "cpu";
+};
+
+struct OnlinePunctuationConfig {
+ OnlinePunctuationModelConfig model;
+};
+
+class SHERPA_ONNX_API OnlinePunctuation
+ : public MoveOnly {
+ public:
+ static OnlinePunctuation Create(const OnlinePunctuationConfig &config);
+
+ void Destroy(const SherpaOnnxOnlinePunctuation *p) const;
+
+ // Add punctuations to the input text and return it.
+ std::string AddPunctuation(const std::string &text) const;
+
+ private:
+ explicit OnlinePunctuation(const SherpaOnnxOnlinePunctuation *p);
+};
+
+// ============================================================================
+// Audio tagging
+// ============================================================================
+struct OfflineZipformerAudioTaggingModelConfig {
+ std::string model;
+};
+
+struct AudioTaggingModelConfig {
+ OfflineZipformerAudioTaggingModelConfig zipformer;
+ std::string ced;
+ int32_t num_threads = 1;
+ bool debug = false; // true to print debug information of the model
+ std::string provider = "cpu";
+};
+
+struct AudioTaggingConfig {
+ AudioTaggingModelConfig model;
+ std::string labels;
+ int32_t top_k = 5;
+};
+
+struct AudioEvent {
+ std::string name;
+ int32_t index;
+ float prob;
+};
+
+class SHERPA_ONNX_API AudioTagging
+ : public MoveOnly {
+ public:
+ static AudioTagging Create(const AudioTaggingConfig &config);
+
+ void Destroy(const SherpaOnnxAudioTagging *p) const;
+
+ OfflineStream CreateStream() const;
+ // when top_k is -1, it uses the top_k from config.top_k
+ // when top_k is > 0, config.top_k is ignored
+ std::vector Compute(const OfflineStream *s, int32_t top_k = -1);
+
+ // For unreal engine, please use this function
+ // See also https://github.com/k2-fsa/sherpa-onnx/discussions/1960
+ std::shared_ptr> ComputePtr(const OfflineStream *s,
+ int32_t top_k = -1);
+
+ private:
+ explicit AudioTagging(const SherpaOnnxAudioTagging *p);
+};
+
+} // namespace sherpa_onnx::cxx
+
+#endif // SHERPA_ONNX_C_API_CXX_API_H_
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.dll
new file mode 100644
index 0000000..10ace0c
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.h b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.h
new file mode 100644
index 0000000..3bcf17f
--- /dev/null
+++ b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.h
@@ -0,0 +1,162 @@
+#pragma once
+
+/**
+ * This is a simple alternative cross-platform implementation of getopt, which
+ * is used to parse argument strings submitted to the executable (argc and argv
+ * which are received in the main function).
+ */
+
+#ifndef CAG_LIBRARY_H
+#define CAG_LIBRARY_H
+
+#include
+#include
+#include
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define CAG_EXPORT __declspec(dllexport)
+#define CAG_IMPORT __declspec(dllimport)
+#elif __GNUC__ >= 4
+#define CAG_EXPORT __attribute__((visibility("default")))
+#define CAG_IMPORT __attribute__((visibility("default")))
+#else
+#define CAG_EXPORT
+#define CAG_IMPORT
+#endif
+
+#if defined(CAG_SHARED)
+#if defined(CAG_EXPORTS)
+#define CAG_PUBLIC CAG_EXPORT
+#else
+#define CAG_PUBLIC CAG_IMPORT
+#endif
+#else
+#define CAG_PUBLIC
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * An option is used to describe a flag/argument option submitted when the
+ * program is run.
+ */
+typedef struct cag_option
+{
+ const char identifier;
+ const char *access_letters;
+ const char *access_name;
+ const char *value_name;
+ const char *description;
+} cag_option;
+
+/**
+ * A context is used to iterate over all options provided. It stores the parsing
+ * state.
+ */
+typedef struct cag_option_context
+{
+ const struct cag_option *options;
+ size_t option_count;
+ int argc;
+ char **argv;
+ int index;
+ int inner_index;
+ bool forced_end;
+ char identifier;
+ char *value;
+} cag_option_context;
+
+/**
+ * This is just a small macro which calculates the size of an array.
+ */
+#define CAG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/**
+ * @brief Prints all options to the terminal.
+ *
+ * This function prints all options to the terminal. This can be used to
+ * generate the output for a "--help" option.
+ *
+ * @param options The options which will be printed.
+ * @param option_count The option count which will be printed.
+ * @param destination The destination where the output will be printed.
+ */
+CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
+ FILE *destination);
+
+/**
+ * @brief Prepare argument options context for parsing.
+ *
+ * This function prepares the context for iteration and initializes the context
+ * with the supplied options and arguments. After the context has been prepared,
+ * it can be used to fetch arguments from it.
+ *
+ * @param context The context which will be initialized.
+ * @param options The registered options which are available for the program.
+ * @param option_count The amount of options which are available for the
+ * program.
+ * @param argc The amount of arguments the user supplied in the main function.
+ * @param argv A pointer to the arguments of the main function.
+ */
+CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
+ const cag_option *options, size_t option_count, int argc, char **argv);
+
+/**
+ * @brief Fetches an option from the argument list.
+ *
+ * This function fetches a single option from the argument list. The context
+ * will be moved to that item. Information can be extracted from the context
+ * after the item has been fetched.
+ * The arguments will be re-ordered, which means that non-option arguments will
+ * be moved to the end of the argument list. After all options have been
+ * fetched, all non-option arguments will be positioned after the index of
+ * the context.
+ *
+ * @param context The context from which we will fetch the option.
+ * @return Returns true if there was another option or false if the end is
+ * reached.
+ */
+CAG_PUBLIC bool cag_option_fetch(cag_option_context *context);
+
+/**
+ * @brief Gets the identifier of the option.
+ *
+ * This function gets the identifier of the option, which should be unique to
+ * this option and can be used to determine what kind of option this is.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns the identifier of the option.
+ */
+CAG_PUBLIC char cag_option_get(const cag_option_context *context);
+
+/**
+ * @brief Gets the value from the option.
+ *
+ * This function gets the value from the option, if any. If the option does not
+ * contain a value, this function will return NULL.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns a pointer to the value or NULL if there is no value.
+ */
+CAG_PUBLIC const char *cag_option_get_value(const cag_option_context *context);
+
+/**
+ * @brief Gets the current index of the context.
+ *
+ * This function gets the index within the argv arguments of the context. The
+ * context always points to the next item which it will inspect. This is
+ * particularly useful to inspect the original argument array, or to get
+ * non-option arguments after option fetching has finished.
+ *
+ * @param context The context from which the option was fetched.
+ * @return Returns the current index of the context.
+ */
+CAG_PUBLIC int cag_option_get_index(const cag_option_context *context);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.lib b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.lib
new file mode 100644
index 0000000..f9abebf
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/cargs.lib differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime.dll
new file mode 100644
index 0000000..ea37949
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime_providers_shared.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime_providers_shared.dll
new file mode 100644
index 0000000..cc1e520
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/onnxruntime_providers_shared.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/pkgconfig/espeak-ng.pc b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/pkgconfig/espeak-ng.pc
new file mode 100644
index 0000000..073f139
--- /dev/null
+++ b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/pkgconfig/espeak-ng.pc
@@ -0,0 +1,11 @@
+prefix=D:/a/sherpa-onnx/sherpa-onnx/build/install
+exec_prefix=D:/a/sherpa-onnx/sherpa-onnx/build/install
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: espeak-ng
+Description: espeak-ng is a multi-lingual software speech synthesizer
+Version: 1.52.0.1
+Requires:
+Libs: -L${libdir} -lespeak-ng
+Cflags: -I${includedir}
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.dll
new file mode 100644
index 0000000..518a60b
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.lib b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.lib
new file mode 100644
index 0000000..d0ff35f
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-c-api.lib differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.dll b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.dll
new file mode 100644
index 0000000..fb98710
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.dll differ
diff --git a/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.lib b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.lib
new file mode 100644
index 0000000..fd66a05
Binary files /dev/null and b/src-tauri/binaries/sherpa-onnx-v1.12.23-win-x64-shared/lib/sherpa-onnx-cxx-api.lib differ
diff --git a/src-tauri/binaries/whisper-bin-x64-v1.9.1.zip b/src-tauri/binaries/whisper-bin-x64-v1.9.1.zip
new file mode 100644
index 0000000..ebf7f5a
Binary files /dev/null and b/src-tauri/binaries/whisper-bin-x64-v1.9.1.zip differ
diff --git a/src-tauri/binaries/whisper-cli.exe b/src-tauri/binaries/whisper-cli.exe
new file mode 100644
index 0000000..3d573d4
Binary files /dev/null and b/src-tauri/binaries/whisper-cli.exe differ
diff --git a/src-tauri/binaries/whisper.dll b/src-tauri/binaries/whisper.dll
new file mode 100644
index 0000000..a826fe8
Binary files /dev/null and b/src-tauri/binaries/whisper.dll differ
diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png
new file mode 100644
index 0000000..f20e425
Binary files /dev/null and b/src-tauri/icons/128x128.png differ
diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png
new file mode 100644
index 0000000..c7c118d
Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ
diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png
new file mode 100644
index 0000000..3516480
Binary files /dev/null and b/src-tauri/icons/32x32.png differ
diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico
index a34a461..be8ba8a 100644
Binary files a/src-tauri/icons/icon.ico and b/src-tauri/icons/icon.ico differ
diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png
new file mode 100644
index 0000000..9ceafc7
Binary files /dev/null and b/src-tauri/icons/icon.png differ
diff --git a/src-tauri/resources/whisper/ggml-base.dll b/src-tauri/resources/whisper/ggml-base.dll
new file mode 100644
index 0000000..83a04aa
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-base.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-alderlake.dll b/src-tauri/resources/whisper/ggml-cpu-alderlake.dll
new file mode 100644
index 0000000..3a980df
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-alderlake.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-cannonlake.dll b/src-tauri/resources/whisper/ggml-cpu-cannonlake.dll
new file mode 100644
index 0000000..68d8811
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-cannonlake.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-cascadelake.dll b/src-tauri/resources/whisper/ggml-cpu-cascadelake.dll
new file mode 100644
index 0000000..bd1bb02
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-cascadelake.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-haswell.dll b/src-tauri/resources/whisper/ggml-cpu-haswell.dll
new file mode 100644
index 0000000..9c1751c
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-haswell.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-icelake.dll b/src-tauri/resources/whisper/ggml-cpu-icelake.dll
new file mode 100644
index 0000000..e7c208e
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-icelake.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-sandybridge.dll b/src-tauri/resources/whisper/ggml-cpu-sandybridge.dll
new file mode 100644
index 0000000..05d2a03
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-sandybridge.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-skylakex.dll b/src-tauri/resources/whisper/ggml-cpu-skylakex.dll
new file mode 100644
index 0000000..6650dc2
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-skylakex.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-sse42.dll b/src-tauri/resources/whisper/ggml-cpu-sse42.dll
new file mode 100644
index 0000000..7c2f32b
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-sse42.dll differ
diff --git a/src-tauri/resources/whisper/ggml-cpu-x64.dll b/src-tauri/resources/whisper/ggml-cpu-x64.dll
new file mode 100644
index 0000000..f20e3b1
Binary files /dev/null and b/src-tauri/resources/whisper/ggml-cpu-x64.dll differ
diff --git a/src-tauri/resources/whisper/ggml.dll b/src-tauri/resources/whisper/ggml.dll
new file mode 100644
index 0000000..6ee0e61
Binary files /dev/null and b/src-tauri/resources/whisper/ggml.dll differ
diff --git a/src-tauri/resources/whisper/whisper-cli.exe b/src-tauri/resources/whisper/whisper-cli.exe
new file mode 100644
index 0000000..3d573d4
Binary files /dev/null and b/src-tauri/resources/whisper/whisper-cli.exe differ
diff --git a/src-tauri/resources/whisper/whisper.dll b/src-tauri/resources/whisper/whisper.dll
new file mode 100644
index 0000000..a826fe8
Binary files /dev/null and b/src-tauri/resources/whisper/whisper.dll differ
diff --git a/src-tauri/src/app_state.rs b/src-tauri/src/app_state.rs
index 74d08cc..bd46015 100644
--- a/src-tauri/src/app_state.rs
+++ b/src-tauri/src/app_state.rs
@@ -1,37 +1,52 @@
-use std::path::PathBuf;
-use std::sync::Mutex;
+use std::fs;
+use std::path::{Path, PathBuf};
+use std::sync::{Arc, Mutex};
use serde::{Deserialize, Serialize};
use crate::audio::{RecordingSession, RecordingStatus};
-use crate::diagnostics::TranscriptionAttempt;
+use crate::audio_history::{list_audio_history, AudioHistoryItem};
use crate::models::{model_statuses, ModelWithStatus};
+use crate::secrets::SecretStore;
use crate::settings::AppSettings;
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+pub struct TranscriptDraft {
+ pub text: String,
+ pub last_message: Option,
+ pub last_attempt: Option,
+}
+
+impl Default for TranscriptDraft {
+ fn default() -> Self {
+ Self {
+ text: String::new(),
+ last_message: Some("Revise o texto antes de inserir.".to_string()),
+ last_attempt: None,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+#[serde(rename_all = "camelCase")]
+pub struct AppSnapshot {
+ pub settings: AppSettings,
+ pub recording_status: RecordingStatus,
+ pub transcript: TranscriptDraft,
+ pub models: Vec,
+ pub app_version: String,
+ pub audio_history: Vec,
+}
+
pub struct ManagedAppState {
pub recording: Mutex,
pub transcript: Mutex,
pub settings: Mutex,
pub model_dir: PathBuf,
pub recordings_dir: PathBuf,
-}
-
-#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
-#[serde(rename_all = "camelCase")]
-pub struct TranscriptDraft {
- pub text: String,
- pub last_message: Option,
- #[serde(default, skip_serializing_if = "Option::is_none")]
- pub last_attempt: Option,
-}
-
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
-#[serde(rename_all = "camelCase")]
-pub struct AppSnapshot {
- pub recording_status: RecordingStatus,
- pub transcript: TranscriptDraft,
- pub settings: AppSettings,
- pub models: Vec,
+ settings_path: PathBuf,
+ pub secrets: Mutex