diff --git a/docs/superpowers/plans/2026-03-17-v070-website-release.md b/docs/superpowers/plans/2026-03-17-v070-website-release.md new file mode 100644 index 0000000..4cc7e9d --- /dev/null +++ b/docs/superpowers/plans/2026-03-17-v070-website-release.md @@ -0,0 +1,927 @@ +# Mingly v0.7.0 Website + Release — Implementation Plan + +> **STATUS: UMGESETZT (2026-03-17).** Release v0.7.0 "Swiss AI Privacy" publiziert (GitHub Release 2026-03-17), Website-Content live auf mingly.ch (mingly-website Commit 02e6d22), Preprocessor-Fixes in v0.7.0 enthalten. Verifiziert gegen Live-Site, App und GitHub-Release am 2026-07-02; Checkboxen nachtraeglich abgehakt. Bekannte Restluecke (statische SEO-/og-Tags in index.html) wird separat im mingly-website-Repo gefixt. + +> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Update mingly.ch website content to reflect v0.7.0 "Swiss AI Privacy" release, bump app version, add MEDIUM backlog preprocessor fixes, build & publish release. + +**Architecture:** i18n-driven website (DE+EN translation files), Vite+React+Tailwind on Vercel. App uses electron-builder for distribution via GitHub Releases. + +**Tech Stack:** TypeScript, React, Tailwind, Vite, Electron, electron-builder, Vitest + +--- + +## Chunk 1: Website Content Updates + +### Task 1: Update Hero Section (DE) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:3-27` + +- [x] **Step 1: Update meta title + description** + +Change meta.title from "Dein KI-Chat. Deine Regeln." to Swiss AI Privacy focus: +```typescript +meta: { + title: "Mingly – Swiss AI Privacy | KI nutzen, Daten behalten", + description: + "Mingly ist der Desktop AI Client mit automatischer On-Device PII-Protection. Multi-LLM, Dokumentenkontext, Wissensdatenbank, intelligentes Routing. Open Source, Swiss Made, nDSG/DSGVO-konform.", + keywords: + "Swiss AI Privacy, KI Chat, AI Desktop, Open Source, PII Detection, lokale KI, Datenschutz, Wissensdatenbank, RAG, LLM Router, Ollama, Claude, GPT, Gemini, Schweiz, nDSG, DSGVO", +}, +``` + +- [x] **Step 2: Update hero badge, title, subtitle, tags** + +```typescript +hero: { + badge: "Swiss AI Privacy · On-Device · nDSG/DSGVO 🇨🇭", + title1: "Swiss AI Privacy.", + title2: "KI nutzen, Daten behalten.", + subtitle: + "Multi-LLM Desktop Client mit automatischer On-Device PII-Protection. Sensible Daten werden erkannt und bleiben lokal — bevor sie an eine KI gesendet werden.", + downloadBtn: "Download", + sourceBtn: "Quellcode auf GitHub", + tags: ["🔒 OS-Keychain", "🇨🇭 nDSG / DSGVO", "⚡ Offline-fähig", "🧠 On-Device NER"], +}, +``` + +- [x] **Step 3: Verify file saves without syntax errors** + +Run: `cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20` +Expected: No errors related to de.ts + +- [x] **Step 4: Commit** + +```bash +cd ~/projects/mingly-website +git add src/i18n/de.ts +git commit -m "feat(i18n): update DE hero + meta for Swiss AI Privacy v0.7.0" +``` + +--- + +### Task 2: Update Hero Section (EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/en.ts:3-27` + +- [x] **Step 1: Update meta title + description (EN mirror)** + +```typescript +meta: { + title: "Mingly – Swiss AI Privacy | Use AI, Keep Your Data", + description: + "Mingly is the desktop AI client with automatic on-device PII protection. Multi-LLM, document context, knowledge base, intelligent routing. Open Source, Swiss Made, GDPR/nDSG compliant.", + keywords: + "Swiss AI Privacy, AI Chat, AI Desktop, Open Source, PII Detection, local AI, privacy, knowledge base, RAG, LLM Router, Ollama, Claude, GPT, Gemini, Switzerland, GDPR, nDSG", +}, +``` + +- [x] **Step 2: Update hero badge, title, subtitle, tags (EN mirror)** + +```typescript +hero: { + badge: "Swiss AI Privacy · On-Device · GDPR/nDSG 🇨🇭", + title1: "Swiss AI Privacy.", + title2: "Use AI, Keep Your Data.", + subtitle: + "Multi-LLM desktop client with automatic on-device PII protection. Sensitive data is detected and stays local — before it reaches any AI.", + downloadBtn: "Download", + sourceBtn: "Source code on GitHub", + tags: ["🔒 OS Keychain", "🇨🇭 GDPR / nDSG", "⚡ Offline-capable", "🧠 On-Device NER"], +}, +``` + +- [x] **Step 3: Verify + Commit** + +```bash +cd ~/projects/mingly-website +npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/en.ts +git commit -m "feat(i18n): update EN hero + meta for Swiss AI Privacy v0.7.0" +``` + +--- + +### Task 3: Reorder Features + Update Tags (DE) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:53-129` + +- [x] **Step 1: Reorder features array — Swiss AI Privacy first, On-Device NER second** + +New order (10 items): +1. Swiss AI Privacy — tag: "Core", tagColor: C.rose +2. On-Device NER (NEW) — tag: "Core", tagColor: C.rose +3. Smart LLM Routing — tag: "Smart", tagColor: C.emerald +4. Dokumentenkontext — tag: "Free", tagColor: C.emerald +5. Wissensdatenbank (RAG) — tag: "Pro", tagColor: C.indigoLight +6. Tool-Anbindung (MCP) — tag: "Extensible", tagColor: C.indigoLight +7. Context Engineering — tag: "Smart", tagColor: C.indigo (remove "v0.5" tag) +8. Alle KI-Modelle, ein Chat — tag: "Chat", tagColor: C.indigo +9. Multi-Backend Routing — tag: "Network", tagColor: C.emerald +10. Kosten & Nutzung im Blick — tag: "Smart", tagColor: C.amber +11. Maximaler Datenschutz — tag: "Security", tagColor: C.rose + +```typescript +items: [ + { + icon: "🇨🇭", + title: "Swiss AI Privacy", + desc: "On-Device PII-Erkennung (Gesundheit, AHV, IBAN, Namen, Adressen) mit 4 Privacy-Modi: Shield, Vault, Transparent, Local Only. Sensible Daten bleiben lokal. nDSG-konform.", + tag: "Core", + tagColor: C.rose, + }, + { + icon: "🧠", + title: "On-Device NER", + desc: "piiranha-v1 (400M Parameter) erkennt 17 PII-Kategorien direkt auf deinem Gerät — unter 50ms, ohne Cloud. 3-Layer Pipeline: Regex + Swiss Patterns + Neural Network.", + tag: "Core", + tagColor: C.rose, + }, + { + icon: "🔀", + title: "Smart LLM Routing", + desc: "Mingly wählt automatisch das beste Modell — lokal, im Netzwerk oder aus der Cloud. Basierend auf Thema, Kosten und Sensibilität deiner Daten.", + tag: "Smart", + tagColor: C.emerald, + }, + { + icon: "📄", + title: "Dokumentenkontext", + desc: "Lade Dokumente im Chat hoch oder gib Ordner frei — die KI bezieht deine Dateien in die Antworten ein. Kostenlos für alle.", + tag: "Free", + tagColor: C.emerald, + }, + { + icon: "📚", + title: "Wissensdatenbank (RAG)", + desc: "Indexiere tausende Dokumente mit Vektordatenbanken. Semantische Suche, automatische Kontext-Injektion und Quellenangaben.", + tag: "Pro", + tagColor: C.indigoLight, + }, + { + icon: "🔌", + title: "Tool-Anbindung (MCP)", + desc: "Verbinde Mingly mit deinen Tools: Dateisystem, Datenbanken, Web-Suche und eigene Workflows — alles erweiterbar.", + tag: "Extensible", + tagColor: C.indigoLight, + }, + { + icon: "🧠", + title: "Context Engineering", + desc: "Fortschritts-Tracking, Fehler-Erhaltung und KV-Cache-Optimierung halten Agenten bei langen Aufgaben auf Kurs — inspiriert von Manus AI.", + tag: "Smart", + tagColor: C.indigo, + }, + { + icon: "🤖", + title: "Alle KI-Modelle, ein Chat", + desc: "Claude, GPT, Gemini, Llama und mehr — nahtlos wechseln, Antworten vergleichen, Gespräche fortführen.", + tag: "Chat", + tagColor: C.indigo, + }, + { + icon: "🌐", + title: "Multi-Backend Routing", + desc: "Verbinde mehrere Ollama-Instanzen im lokalen Netzwerk. Mingly verteilt Anfragen automatisch auf die schnellsten und am wenigsten ausgelasteten Server.", + tag: "Network", + tagColor: C.emerald, + }, + { + icon: "📊", + title: "Kosten & Nutzung im Blick", + desc: "Sieh genau, was jede Anfrage kostet. Setze monatliche Budgets, und Mingly warnt dich, bevor das Limit erreicht wird.", + tag: "Smart", + tagColor: C.amber, + }, + { + icon: "🔐", + title: "Maximaler Datenschutz", + desc: "Schlüssel im OS-Keychain, keine Telemetrie, DSGVO/DSG-konform. Circuit Breaker schützt vor Kostenexplosion, Canary Tokens erkennen System-Prompt-Leaks.", + tag: "Security", + tagColor: C.rose, + }, +], +``` + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/de.ts +git commit -m "feat(i18n): reorder DE features — Swiss AI Privacy + NER first" +``` + +--- + +### Task 4: Reorder Features + Update Tags (EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/en.ts:53-128` + +- [x] **Step 1: Mirror DE feature reorder to EN** + +Same structure as Task 3 but in English: +1. Swiss AI Privacy: "On-device PII detection (health data, AHV, IBAN, names, addresses) with 4 privacy modes: Shield, Vault, Transparent, Local Only. Sensitive data stays local. nDSG compliant." +2. On-Device NER: "piiranha-v1 (400M parameters) detects 17 PII categories directly on your device — under 50ms, no cloud. 3-layer pipeline: Regex + Swiss Patterns + Neural Network." +3-11: Same reorder as DE, English text stays same, tags updated (remove "v0.7", "v0.5"). + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/en.ts +git commit -m "feat(i18n): reorder EN features — Swiss AI Privacy + NER first" +``` + +--- + +### Task 5: Update Pricing Privacy Messaging (DE + EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:384-480` +- Modify: `~/projects/mingly-website/src/i18n/en.ts:379-474` + +- [x] **Step 1: Update DE pricing tiers with privacy messaging** + +Free tier features — replace list: +```typescript +features: [ + "Lokale Modelle (Ollama)", + "Dokumentenkontext (Uploads & Ordner)", + "3 Gespräche pro Tag (Cloud)", + "Swiss AI Privacy (volle PII-Protection)", + "On-Device NER (piiranha-v1)", + "Circuit Breaker & Guardrails", + "Community-Support", +], +``` + +Pro tier — add after "Alles in Free, plus:": +```typescript +features: [ + "Alles in Free, plus:", + "Cloud-APIs (Claude, GPT, Gemini)", + "Unbegrenzte Gespräche", + "4 Privacy-Modi (Shield/Vault/Transparent/Local Only)", + "Wissensdatenbank (RAG)", + "Datenklassifikation & Smart Routing", + "Prompt-Vorlagen & -Verwaltung", + "Multimodal (Bilder & Vision)", + "Agentic Mode (ReAct + Tools)", + "Modellvergleich mit Agenten", + "Parallele Subagenten", + "Context Engineering", + "Multi-Backend Load Balancing", + "Export (Markdown, PDF, JSON)", + "Auto-Updates", +], +``` + +Team tier — add privacy audit: +```typescript +features: [ + "Alles in Pro, plus:", + "Team-Arbeitsräume", + "Geteilte Wissensbasen", + "Privacy-Audit-Log", + "Rollenverwaltung (RBAC)", + "Nutzungs-Tracking pro User", + "Audit-Logs & Canary Tokens", + "SSO (OAuth / SAML)", + "Priority-Support", +], +``` + +Enterprise tier — add compliance: +```typescript +features: [ + "Alles in Team, plus:", + "On-Premise / Air-Gap", + "nDSG/DSGVO Compliance-Dashboard", + "Custom PII-Regeln", + "LDAP / Active Directory", + "Dedizierter Support & SLA", + "Custom-Integrationen", + "White-Label-Option", +], +``` + +- [x] **Step 2: Mirror to EN pricing** + +Same changes in English translations. + +- [x] **Step 3: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/de.ts src/i18n/en.ts +git commit -m "feat(i18n): update pricing tiers with privacy messaging (DE+EN)" +``` + +--- + +### Task 6: Reorder Use Cases + Add Lawyer (DE) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:130-235` + +- [x] **Step 1: Reorder use cases — Privacy-first order** + +New order: +1. Hausarztpraxis (was #4) — already privacy-focused, stays same +2. Steuerberatung (was #1) — stays same +3. Anwaltskanzlei (NEW) — replaces Elektro Brunner +4. Marketing-Agentur (was #3) — add privacy angle + +Replace Elektro Brunner (item[1]) with Anwaltskanzlei: +```typescript +{ + icon: "⚖️", + color: C.indigoLight, + badge: "KMU · Recht", + meta: "6 Mitarbeitende · Hybrid-Modus", + title: "Anwaltskanzlei Winterthur: Vertragsentwürfe und Recherche mit KI", + desc: "Eine Wirtschaftskanzlei nutzt KI für Vertragsanalyse, Recherche und Mandantenkorrespondenz — ohne Daten in die Cloud zu senden.", + toggleOpen: "Wie nutzen sie Mingly?", + toggleClose: "Weniger anzeigen", + details: [ + { + label: "🔒 SWISS AI PRIVACY", + text: "Mingly erkennt Mandantennamen, AHV-Nummern und Adressen automatisch und anonymisiert sie vor Cloud-Anfragen. Anwaltsgeheimnis gewahrt.", + }, + { + label: "📚 WISSENSDATENBANK", + text: "OR, ZGB, Bundesgerichtsentscheide und interne Muster als RAG-Wissensbasis. Mingly zitiert mit Fundstelle.", + }, + { + label: "📝 VERTRÄGE", + text: "Entwurf-Prompts mit Vertragsvorlagen kombiniert. Mingly generiert Erstversionen, die der Anwalt prüft und anpasst.", + }, + ], + metrics: ["⏱ Recherche: 60 Min. → 15 Min.", "🔒 Anwaltsgeheimnis gewahrt", "📄 500+ Dokumente indexiert"], +}, +``` + +Reorder: [Arztpraxis, Steuerberatung, Anwaltskanzlei, Marketing-Agentur] + +Update Marketing-Agentur details to add privacy angle — change first detail label: +```typescript +{ + label: "🔒 MULTI-CLIENT PRIVACY", + text: "Jeder Kunde hat eine isolierte Wissensdatenbank. Swiss AI Privacy stellt sicher, dass Kundendaten nie an den falschen Provider gelangen.", +}, +``` + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/de.ts +git commit -m "feat(i18n): reorder DE use cases + add lawyer, privacy-first" +``` + +--- + +### Task 7: Reorder Use Cases + Add Lawyer (EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/en.ts:130-235` + +- [x] **Step 1: Mirror DE use case changes to EN** + +New order: [Family Practice, Tax Advisory, Law Firm (NEW), Marketing Agency] + +Law Firm: +```typescript +{ + icon: "⚖️", + color: C.indigoLight, + badge: "SME · Legal", + meta: "6 employees · Hybrid mode", + title: "Law Firm Winterthur: Contract drafts and research with AI", + desc: "A commercial law firm uses AI for contract analysis, research, and client correspondence — without sending data to the cloud.", + toggleOpen: "How do they use Mingly?", + toggleClose: "Show less", + details: [ + { + label: "🔒 SWISS AI PRIVACY", + text: "Mingly automatically detects client names, AHV numbers, and addresses and anonymizes them before cloud requests. Attorney-client privilege maintained.", + }, + { + label: "📚 KNOWLEDGE BASE", + text: "Swiss Code of Obligations, Civil Code, Federal Court decisions, and internal templates as RAG knowledge base. Mingly cites with reference.", + }, + { + label: "📝 CONTRACTS", + text: "Draft prompts combined with contract templates. Mingly generates first versions that the lawyer reviews and refines.", + }, + ], + metrics: ["⏱ Research: 60 min → 15 min", "🔒 Attorney-client privilege", "📄 500+ docs indexed"], +}, +``` + +Marketing Agency — update first detail: +```typescript +{ + label: "🔒 MULTI-CLIENT PRIVACY", + text: "Each client gets an isolated knowledge base. Swiss AI Privacy ensures client data never reaches the wrong provider.", +}, +``` + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/en.ts +git commit -m "feat(i18n): reorder EN use cases + add lawyer, privacy-first" +``` + +--- + +### Task 8: Update FAQ Swiss AI Privacy Answer (DE + EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:522-524` +- Modify: `~/projects/mingly-website/src/i18n/en.ts:517-519` + +- [x] **Step 1: Expand FAQ answer with 3-Layer detail** + +DE: +```typescript +{ + q: "Was ist Swiss AI Privacy?", + a: "Mingly erkennt sensible Daten automatisch auf deinem Gerät — bevor sie an eine KI gesendet werden. Die 3-Layer-Pipeline (Regex + Swiss Patterns + piiranha-v1 NER) erkennt 17 PII-Kategorien: Namen, Adressen, AHV-Nummern, IBAN, Gesundheitsdaten und mehr. 4 Privacy-Modi (Shield, Vault, Transparent, Local Only) bestimmen, wie mit erkannten Daten umgegangen wird. Alles lokal, nDSG-konform.", +}, +``` + +EN: +```typescript +{ + q: "What is Swiss AI Privacy?", + a: "Mingly detects sensitive data automatically on your device — before it reaches any AI. The 3-layer pipeline (Regex + Swiss Patterns + piiranha-v1 NER) detects 17 PII categories: names, addresses, AHV numbers, IBAN, health data, and more. 4 privacy modes (Shield, Vault, Transparent, Local Only) determine how detected data is handled. Everything local, nDSG compliant.", +}, +``` + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/de.ts src/i18n/en.ts +git commit -m "feat(i18n): expand Swiss AI Privacy FAQ with 3-Layer detail (DE+EN)" +``` + +--- + +### Task 9: Update CTA + Footer (DE + EN) + +**Files:** +- Modify: `~/projects/mingly-website/src/i18n/de.ts:531-537` +- Modify: `~/projects/mingly-website/src/i18n/en.ts:526-532` + +- [x] **Step 1: Update CTA section** + +DE: +```typescript +cta: { + title1: "KI nutzen.", + title2: "Daten behalten.", + sub: "Swiss AI Privacy. Open Source. On-Device. Jetzt herunterladen oder den Quellcode forken.", + downloadBtn: "Jetzt herunterladen", + sourceBtn: "Quellcode auf GitHub →", +}, +``` + +EN: +```typescript +cta: { + title1: "Use AI.", + title2: "Keep Your Data.", + sub: "Swiss AI Privacy. Open source. On-device. Download now or fork the source code.", + downloadBtn: "Download now", + sourceBtn: "Source code on GitHub →", +}, +``` + +- [x] **Step 2: Verify + Commit** + +```bash +cd ~/projects/mingly-website && npx tsc --noEmit 2>&1 | head -20 +git add src/i18n/de.ts src/i18n/en.ts +git commit -m "feat(i18n): update CTA for Swiss AI Privacy messaging (DE+EN)" +``` + +--- + +### Task 10: Update Version in downloads.ts + +**Files:** +- Modify: `~/projects/mingly-website/src/lib/downloads.ts:1` + +- [x] **Step 1: Bump version** + +```typescript +export const MINGLY_VERSION = "0.7.0"; +``` + +- [x] **Step 2: Verify URLs are correct** + +Run: `cd ~/projects/mingly-website && grep -n "0.5.1" src/ -r` +Expected: No results (all references updated) + +- [x] **Step 3: Commit** + +```bash +cd ~/projects/mingly-website +git add src/lib/downloads.ts +git commit -m "chore: bump download version to 0.7.0" +``` + +--- + +## Chunk 2: Mingly App Updates + +### Task 11: Version Bump (package.json) + +**Files:** +- Modify: `~/mingly/package.json:3` + +- [x] **Step 1: Bump version** + +Change `"version": "0.5.1"` to `"version": "0.7.0"` + +- [x] **Step 2: Commit** + +```bash +cd ~/mingly +git add package.json +git commit -m "chore: bump version to 0.7.0" +``` + +--- + +### Task 12: CHANGELOG v0.7.0 Entry + +**Files:** +- Modify: `~/mingly/CHANGELOG.md:1-5` + +- [x] **Step 1: Add v0.7.0 entry at top** + +Insert after `# Changelog` line: + +```markdown +## [0.7.0] - 2026-03-17 + +### Added — Swiss AI Privacy (Phase 7b) +- **3-Layer PII Detection Pipeline** — Regex → Swiss Patterns → piiranha-v1 NER (400M ONNX, fp32). 17 PII-Kategorien: PERSON, EMAIL, PHONE, IBAN, AHV, CREDIT_CARD, ADDRESS, LOCATION, DATE_OF_BIRTH, PASSPORT, IP_ADDRESS, URL, ORGANIZATION, CUSTOM +- **On-Device NER** — piiranha-v1 (onnx-community/piiranha-v1-detect-personal-information-ONNX) läuft im Worker Thread, <50ms Inferenz, kein Cloud-Call +- **NER Model Manager** — Download, Status-Tracking, Cache-Management für ONNX-Modell (~1.15GB fp32) +- **4 Privacy-Modi** — Shield (anonymize before cloud), Vault (local-only for sensitive), Transparent (detect + warn), Local Only (never cloud) +- **Text Preprocessor** — Defeats evasion: Zero-Width Character Stripping, URL-Decoding, Unicode NFC, HTML-Entity Decoding, Fullwidth Normalization +- **Entity Dedup with Co-existence** — NER + Regex entities with different categories on overlapping spans are both kept (e.g., PERSON + EMAIL) +- **Privacy UI** — Settings page with model download, privacy mode selection, PII category toggles +- **Privacy IPC** — Full Electron IPC layer for privacy settings, detection, and NER model management + +### Security +- **Red-Team Suite** — 143 test cases across 10 categories (encoding tricks, format embedding, language mixing, etc.) +- **3-Layer Results** — 84.9% detection rate (113/133), 0 CRITICAL failures +- **REGEX_STRUCTURAL_CATEGORIES** — EMAIL, PHONE, CREDIT_CARD, IP_ADDRESS, URL, IBAN, AHV, DATE_OF_BIRTH protected from NER override + +### Technical +- 1254+ Tests, 143 Red-Team Tests +- Neue Dateien: 15+ (privacy modules, preprocessor, red-team infrastructure) +- TypeScript strict mode clean +``` + +- [x] **Step 2: Commit** + +```bash +cd ~/mingly +git add CHANGELOG.md +git commit -m "docs: add v0.7.0 CHANGELOG entry — Swiss AI Privacy" +``` + +--- + +### Task 13: MEDIUM Backlog — HTML Entity Decoding + +**Files:** +- Modify: `~/mingly/src/main/privacy/text-preprocessor.ts` +- Modify/Create: `~/mingly/tests/unit/text-preprocessor.test.ts` + +- [x] **Step 1: Write failing test for HTML entity decoding** + +```typescript +it('decodes HTML entities in PII-relevant characters', () => { + const result = preprocessText('hans@test.ch') + expect(result.normalized).toBe('hans@test.ch') + expect(result.wasModified).toBe(true) +}) + +it('decodes named HTML entities', () => { + const result = preprocessText('hans@test.ch') + expect(result.normalized).toBe('hans@test.ch') + expect(result.wasModified).toBe(true) +}) + +it('preserves offset mapping through HTML entity decoding', () => { + const result = preprocessText('a@b') + expect(result.normalized).toBe('a@b') + // 'a' at 0 maps to original 0 + // '@' at 1 maps to original 1 (start of @) + // 'b' at 2 maps to original 6 + expect(result.toOriginalOffset(0)).toBe(0) + expect(result.toOriginalOffset(2)).toBe(6) +}) +``` + +- [x] **Step 2: Run test to verify it fails** + +Run: `cd ~/mingly && npx vitest run tests/unit/text-preprocessor.test.ts --reporter verbose 2>&1 | tail -20` +Expected: FAIL + +- [x] **Step 3: Implement HTML entity decoding** + +Add after URL-decode step (Step 2) and before NFC (Step 3) in `preprocessText()`: + +```typescript +// Step 2b: Decode HTML entities commonly used in PII evasion +const preHtmlText = normalized +const preHtmlMap = [...offsetMap] + +const htmlDecoded = decodeHtmlEntities(preHtmlText) +if (htmlDecoded.text !== preHtmlText) { + wasModified = true + normalized = htmlDecoded.text + const newOffsetMap: number[] = [] + for (let ni = 0; ni < htmlDecoded.text.length; ni++) { + const preHtmlIndex = htmlDecoded.toPreIndex(ni) + newOffsetMap.push(preHtmlMap[preHtmlIndex] ?? preHtmlIndex) + } + offsetMap.length = 0 + offsetMap.push(...newOffsetMap) +} +``` + +Add new function: +```typescript +/** PII-relevant HTML entities */ +const HTML_ENTITY_MAP: Record = { + '&': '&', '<': '<', '>': '>', + '@': '@', '.': '.', '+': '+', + '‐': '-', '‐': '-', '#': '#', + '(': '(', ')': ')', +} + +function decodeHtmlEntities(text: string): { + text: string + toPreIndex(decodedIndex: number): number +} { + const offsetMap: number[] = [] + let decoded = '' + let i = 0 + + while (i < text.length) { + if (text[i] === '&') { + // Try numeric entity: &#DD; or &#xHH; + const numMatch = text.substring(i).match(/^&#(\d{1,4});/) + const hexMatch = text.substring(i).match(/^&#x([0-9A-Fa-f]{1,4});/) + // Try named entity + let namedMatch: string | null = null + for (const [entity, replacement] of Object.entries(HTML_ENTITY_MAP)) { + if (text.substring(i, i + entity.length) === entity) { + namedMatch = entity + break + } + } + + if (numMatch) { + const charCode = parseInt(numMatch[1], 10) + if (charCode > 0 && charCode < 0x10000) { + offsetMap.push(i) + decoded += String.fromCharCode(charCode) + i += numMatch[0].length + continue + } + } else if (hexMatch) { + const charCode = parseInt(hexMatch[1], 16) + if (charCode > 0 && charCode < 0x10000) { + offsetMap.push(i) + decoded += String.fromCharCode(charCode) + i += hexMatch[0].length + continue + } + } else if (namedMatch) { + offsetMap.push(i) + decoded += HTML_ENTITY_MAP[namedMatch] + i += namedMatch.length + continue + } + } + offsetMap.push(i) + decoded += text[i] + i++ + } + + return { + text: decoded, + toPreIndex(decodedIndex: number): number { + return offsetMap[decodedIndex] ?? decodedIndex + } + } +} +``` + +- [x] **Step 4: Run test to verify it passes** + +Run: `cd ~/mingly && npx vitest run tests/unit/text-preprocessor.test.ts --reporter verbose 2>&1 | tail -30` +Expected: PASS + +- [x] **Step 5: Commit** + +```bash +cd ~/mingly +git add src/main/privacy/text-preprocessor.ts tests/unit/text-preprocessor.test.ts +git commit -m "feat(privacy): add HTML entity decoding to text preprocessor" +``` + +--- + +### Task 14: MEDIUM Backlog — Fullwidth Normalization + +**Files:** +- Modify: `~/mingly/src/main/privacy/text-preprocessor.ts` +- Modify: `~/mingly/tests/unit/text-preprocessor.test.ts` + +- [x] **Step 1: Write failing test for fullwidth normalization** + +```typescript +it('normalizes fullwidth ASCII characters', () => { + // Fullwidth @ = U+FF20, fullwidth . = U+FF0E + const result = preprocessText('hans\uFF20test\uFF0Ech') + expect(result.normalized).toBe('hans@test.ch') + expect(result.wasModified).toBe(true) +}) + +it('normalizes fullwidth digits', () => { + // Fullwidth 0-9 = U+FF10-FF19 + const result = preprocessText('\uFF10\uFF17\uFF18 123 45 67') + expect(result.normalized).toBe('078 123 45 67') + expect(result.wasModified).toBe(true) +}) +``` + +- [x] **Step 2: Run test to verify it fails** + +Run: `cd ~/mingly && npx vitest run tests/unit/text-preprocessor.test.ts --reporter verbose 2>&1 | tail -20` +Expected: FAIL + +- [x] **Step 3: Implement fullwidth normalization** + +Add after HTML entity step and before NFC: + +```typescript +// Step 2c: Normalize fullwidth ASCII characters (U+FF01-FF5E → U+0021-007E) +const preFullwidthText = normalized +let fullwidthModified = false +let fullwidthResult = '' +for (let fi = 0; fi < preFullwidthText.length; fi++) { + const code = preFullwidthText.charCodeAt(fi) + if (code >= 0xFF01 && code <= 0xFF5E) { + fullwidthResult += String.fromCharCode(code - 0xFEE0) + fullwidthModified = true + } else { + fullwidthResult += preFullwidthText[fi] + } +} +if (fullwidthModified) { + wasModified = true + normalized = fullwidthResult + // Offset map stays same (1:1 character replacement) +} +``` + +- [x] **Step 4: Run test to verify it passes** + +Run: `cd ~/mingly && npx vitest run tests/unit/text-preprocessor.test.ts --reporter verbose 2>&1 | tail -30` +Expected: PASS + +- [x] **Step 5: Run full test suite** + +Run: `cd ~/mingly && npx vitest run 2>&1 | tail -20` +Expected: All tests pass + +- [x] **Step 6: Commit** + +```bash +cd ~/mingly +git add src/main/privacy/text-preprocessor.ts tests/unit/text-preprocessor.test.ts +git commit -m "feat(privacy): add fullwidth ASCII normalization to text preprocessor" +``` + +--- + +## Chunk 3: Build, Release, Deploy + +### Task 15: Build Mingly Release + +- [x] **Step 1: Run full test suite** + +```bash +cd ~/mingly && npx vitest run 2>&1 | tail -30 +``` +Expected: All tests pass + +- [x] **Step 2: Build macOS release** + +```bash +cd ~/mingly && npm run dist:mac +``` +Expected: DMG + ZIP in `dist/` directory + +- [x] **Step 3: Verify build artifacts** + +```bash +ls -la ~/mingly/dist/*.dmg ~/mingly/dist/*.zip 2>/dev/null +``` + +- [x] **Step 4: Commit any build-related changes if needed** + +--- + +### Task 16: Create GitHub Release v0.7.0 + +- [x] **Step 1: Push all mingly commits** + +```bash +cd ~/mingly && git push origin main +``` + +- [x] **Step 2: Create GitHub Release** + +```bash +cd ~/mingly && gh release create v0.7.0 \ + --title "v0.7.0 — Swiss AI Privacy" \ + --notes "$(cat <<'EOF' +## Swiss AI Privacy + +Mingly v0.7.0 introduces **Swiss AI Privacy** — automatic on-device PII protection. + +### Highlights +- **3-Layer PII Detection**: Regex → Swiss Patterns → piiranha-v1 NER (400M ONNX) +- **17 PII Categories**: Names, addresses, AHV numbers, IBAN, health data, and more +- **4 Privacy Modes**: Shield, Vault, Transparent, Local Only +- **On-Device NER**: <50ms inference, no cloud required +- **Red-Team Tested**: 143 test cases, 84.9% detection rate, 0 critical failures + +### Downloads +- **macOS**: DMG (Apple Silicon) or ZIP +- **Windows**: Installer or Portable +- **Linux**: AppImage or .deb + +Full changelog: CHANGELOG.md +EOF +)" \ + dist/Mingly-0.7.0-arm64.dmg \ + dist/Mingly-0.7.0-arm64-mac.zip +``` + +--- + +### Task 17: Deploy Website + +- [x] **Step 1: Push website changes** + +```bash +cd ~/projects/mingly-website && git push origin main +``` +Expected: Vercel auto-deploys on push + +- [x] **Step 2: Verify deployment** + +Check Vercel dashboard or `vercel ls` for successful deployment. + +- [x] **Step 3: Verify live site** + +Open mingly.ch, check: +- Hero shows "Swiss AI Privacy" +- Features show Swiss AI Privacy + NER first +- Pricing shows privacy messaging +- Use Cases show Arztpraxis first + Anwaltskanzlei +- Download links point to v0.7.0 +- FAQ has expanded Swiss AI Privacy answer + +--- + +### Task 18: Post-Release Verification + +- [x] **Step 1: Test download links** + +Verify that `https://github.com/Baldri/mingly/releases/download/v0.7.0/Mingly-0.7.0-arm64.dmg` returns 200. + +- [x] **Step 2: Update memory** + +Update `~/.claude/projects/-Users-holgervonellerts-projects/memory/MEMORY.md` with v0.7.0 release status. diff --git a/package-lock.json b/package-lock.json index 169c5b0..fc234fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "dependencies": { "@anthropic-ai/sdk": "^0.71.2", "@google/generative-ai": "^0.24.1", + "@huggingface/transformers": "^4.2.0", "@qdrant/js-client-rest": "^1.16.2", - "@xenova/transformers": "^2.17.2", "electron-updater": "^6.7.3", "lucide-react": "^0.563.0", "nanoid": "^5.1.6", @@ -2577,7 +2577,6 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3125,30 +3124,17 @@ "hono": "^4" } }, - "node_modules/@huggingface/jinja": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.2.2.tgz", - "integrity": "sha512-/KPde26khDUIPkTGU82jdtTW9UAuvUTumCAbFs/7giR0SxsvZC4hru51PBvpijH6BVkHcROcvZM/lpy5h1jRRA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, "node_modules/@huggingface/tokenizers": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@huggingface/tokenizers/-/tokenizers-0.1.3.tgz", "integrity": "sha512-8rF/RRT10u+kn7YuUbUg0OF30K8rjTc78aHpxT+qJ1uWSqxT1MHi8+9ltwYfkFYJzT/oS+qw3JVfHtNMGAdqyA==", - "dev": true, - "license": "Apache-2.0", - "optional": true + "license": "Apache-2.0" }, "node_modules/@huggingface/transformers": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-4.2.0.tgz", "integrity": "sha512-8BRCoBMH0XsWaEIamuR0LrJGAfftgHAfb2Vrffy0VKlSAE/MnUJ5/h/zTfEP3fDIft+nk7TqB8xXEyABGitBjQ==", - "dev": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "@huggingface/jinja": "^0.5.6", "@huggingface/tokenizers": "^0.1.3", @@ -3161,9 +3147,7 @@ "version": "0.5.9", "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.9.tgz", "integrity": "sha512-uWTG+l3VJRsl7EXxYizuL3P+cCPoc3cRqbWWRcQN0FhejRfbdq0RNhCmbY/YDtnTcz9icdLYuLDjsnz4d8JMuw==", - "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=18" } @@ -3172,34 +3156,26 @@ "version": "25.9.23", "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz", "integrity": "sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==", - "dev": true, - "license": "Apache-2.0", - "optional": true + "license": "Apache-2.0" }, "node_modules/@huggingface/transformers/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==", - "dev": true, - "license": "Apache-2.0", - "optional": true + "license": "Apache-2.0" }, "node_modules/@huggingface/transformers/node_modules/onnxruntime-common": { "version": "1.24.3", "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.3.tgz", "integrity": "sha512-GeuPZO6U/LBJXvwdaqHbuUmoXiEdeCjWi/EG7Y1HNnDwJYuk6WUbNXpF6luSUY8yASul3cmUlLGrCCL1ZgVXqA==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/@huggingface/transformers/node_modules/onnxruntime-node": { "version": "1.24.3", "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.24.3.tgz", "integrity": "sha512-JH7+czbc8ALA819vlTgcV+Q214/+VjGeBHDjX81+ZCD0PCVCIFGFNtT0V4sXG/1JXypKPgScQcB3ij/hk3YnTg==", - "dev": true, "hasInstallScript": true, "license": "MIT", - "optional": true, "os": [ "win32", "darwin", @@ -3215,9 +3191,7 @@ "version": "1.26.0-dev.20260416-b7804b056c", "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.26.0-dev.20260416-b7804b056c.tgz", "integrity": "sha512-MD6Ss4GSpQBo6zqoJzyT9LRbKYs7x/JVN23FT24EcEvlqF4VuzPOeH6X38orZPKHQDbprn7K+SBpu0/mj2CQiw==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "flatbuffers": "^25.1.24", "guid-typescript": "^1.0.9", @@ -3231,18 +3205,14 @@ "version": "1.24.0-dev.20251116-b39e144322", "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.24.0-dev.20251116-b39e144322.tgz", "integrity": "sha512-BOoomdHYmNRL5r4iQ4bMvsl2t0/hzVQ3OM3PHD0gxeXu1PmggqBv3puZicEUVOA3AtHHYmqZtjMj9FOfGrATTw==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/@huggingface/transformers/node_modules/protobufjs": { "version": "7.6.4", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz", "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==", - "dev": true, "hasInstallScript": true, "license": "BSD-3-Clause", - "optional": true, "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -3264,9 +3234,7 @@ "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -3278,10 +3246,8 @@ "version": "0.34.5", "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", @@ -3363,9 +3329,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=18" } @@ -3377,7 +3341,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3400,7 +3363,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3423,7 +3385,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3440,7 +3401,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3457,7 +3417,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3474,7 +3433,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3491,7 +3449,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3508,7 +3465,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3525,7 +3481,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3542,7 +3497,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3559,7 +3513,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3576,7 +3529,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -3593,7 +3545,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3616,7 +3567,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3639,7 +3589,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3662,7 +3611,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3685,7 +3633,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3708,7 +3655,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3731,7 +3677,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3754,7 +3699,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -3777,7 +3721,6 @@ "cpu": [ "wasm32" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -3797,7 +3740,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3817,7 +3759,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -3837,7 +3778,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -5600,12 +5540,6 @@ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", @@ -7798,12 +7732,6 @@ "@types/node": "*" } }, - "node_modules/@types/long": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", - "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==", - "license": "MIT" - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -8188,20 +8116,6 @@ "url": "https://opencollective.com/vitest" } }, - "node_modules/@xenova/transformers": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/@xenova/transformers/-/transformers-2.17.2.tgz", - "integrity": "sha512-lZmHqzrVIkSvZdKZEx7IYY51TK0WDrC8eR0c5IMnBsO8di8are1zzw8BlLhyO2TklZKLN5UffNGs1IJwT6oOqQ==", - "license": "Apache-2.0", - "dependencies": { - "@huggingface/jinja": "^0.2.2", - "onnxruntime-web": "1.14.0", - "sharp": "^0.32.0" - }, - "optionalDependencies": { - "onnxruntime-node": "1.14.0" - } - }, "node_modules/@xmldom/xmldom": { "version": "0.8.13", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.13.tgz", @@ -8281,9 +8195,7 @@ "version": "0.5.18", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.18.tgz", "integrity": "sha512-ufJnssQGbxzLNS1Ho9bCtX4rQKCCvoVuDLHoJyc3F9dOGDB4BkWs2Ci0kv53lqocAEQ/Cbi+I2XCsNYGqVYqng==", - "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=12.0" } @@ -8863,101 +8775,11 @@ "dev": true, "license": "MIT" }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } - }, - "node_modules/bare-fs": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.3.tgz", - "integrity": "sha512-9+kwVx8QYvt3hPWnmb19tPnh38c6Nihz8Lx3t0g9+4GoIf3/fTgYwM4Z6NxgI+B9elLQA7mLE9PpqcWtOMRDiQ==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", - "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", - "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.21.0" - }, - "peerDependencies": { - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/bare-url": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", - "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-path": "^3.0.0" - } - }, "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==", + "dev": true, "funding": [ { "type": "github", @@ -9068,7 +8890,9 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", @@ -9153,9 +8977,7 @@ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/bowser": { "version": "2.14.1", @@ -9236,6 +9058,7 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, "funding": [ { "type": "github", @@ -9828,23 +9651,11 @@ "node": ">=0.10.0" } }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, - "engines": { - "node": ">=12.5.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -9857,18 +9668,9 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -10406,6 +10208,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -10421,6 +10224,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -10444,15 +10248,6 @@ } } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/default-browser": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", @@ -10499,9 +10294,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -10532,9 +10325,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -10607,9 +10398,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", @@ -11167,6 +10956,7 @@ "version": "1.4.5", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -11276,7 +11066,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11286,7 +11075,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11332,9 +11120,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/es6-promisify": { "version": "7.0.0", @@ -11417,9 +11203,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">=10" }, @@ -11532,15 +11316,6 @@ "node": ">=0.8.x" } }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.7.0" - } - }, "node_modules/eventsource": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", @@ -11634,15 +11409,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/expect-type": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", @@ -11796,12 +11562,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT" - }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -12109,12 +11869,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/flatbuffers": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", - "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==", - "license": "SEE LICENSE IN LICENSE.txt" - }, "node_modules/fn.name": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", @@ -12236,7 +11990,9 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" + "dev": true, + "license": "MIT", + "peer": true }, "node_modules/fs-extra": { "version": "8.1.0", @@ -12517,12 +12273,6 @@ "node": ">= 20" } }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -12586,9 +12336,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "dev": true, "license": "BSD-3-Clause", - "optional": true, "dependencies": { "boolean": "^3.0.1", "es6-error": "^4.1.1", @@ -12605,9 +12353,7 @@ "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, @@ -12619,9 +12365,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "define-properties": "^1.2.1", "gopd": "^1.0.1" @@ -12684,7 +12428,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12745,9 +12488,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "es-define-property": "^1.0.0" }, @@ -13227,6 +12968,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, "funding": [ { "type": "github", @@ -13259,12 +13001,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, "license": "ISC" }, "node_modules/inline-style-parser": { @@ -13317,12 +13054,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-arrayish": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", - "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", - "license": "MIT" - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -13974,9 +13705,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC", - "optional": true + "license": "ISC" }, "node_modules/json5": { "version": "2.2.3", @@ -14691,12 +14420,6 @@ "node": ">=0.1.90" } }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "license": "Apache-2.0" - }, "node_modules/longest-streak": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", @@ -14817,9 +14540,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "escape-string-regexp": "^4.0.0" }, @@ -15618,6 +15339,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15680,12 +15402,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, "node_modules/mongodb-connection-string-url": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-7.0.1.tgz", @@ -15891,12 +15607,6 @@ "node": "^18 || >=20" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, "node_modules/natural": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/natural/-/natural-8.1.1.tgz", @@ -15973,30 +15683,6 @@ "node": ">= 0.4.0" } }, - "node_modules/node-abi": { - "version": "3.87.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", - "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-abi/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-addon-api": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", @@ -16244,9 +15930,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, "license": "MIT", - "optional": true, "engines": { "node": ">= 0.4" } @@ -16298,6 +15982,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -16329,50 +16014,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/onnx-proto": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/onnx-proto/-/onnx-proto-4.0.4.tgz", - "integrity": "sha512-aldMOB3HRoo6q/phyB6QRQxSt895HNNw82BNyZ2CMh4bjeKv7g/c+VpAFtJuEMVfYLMbRx61hbuqnKceLeDcDA==", - "license": "MIT", - "dependencies": { - "protobufjs": "^6.8.8" - } - }, - "node_modules/onnxruntime-common": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.14.0.tgz", - "integrity": "sha512-3LJpegM2iMNRX2wUmtYfeX/ytfOzNwAWKSq1HbRrKc9+uqG/FsEA0bbKZl1btQeZaXhC26l44NWpNUeXPII7Ew==", - "license": "MIT" - }, - "node_modules/onnxruntime-node": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.14.0.tgz", - "integrity": "sha512-5ba7TWomIV/9b6NH/1x/8QEeowsb+jBEvFzU6z0T4mNsFwdPqXeFUM7uxC6QeSRkEbWu3qEB0VMjrvzN/0S9+w==", - "license": "MIT", - "optional": true, - "os": [ - "win32", - "darwin", - "linux" - ], - "dependencies": { - "onnxruntime-common": "~1.14.0" - } - }, - "node_modules/onnxruntime-web": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.14.0.tgz", - "integrity": "sha512-Kcqf43UMfW8mCydVGcX9OMXI2VN17c0p6XvR7IPSZzBf/6lteBzXHvcEVWDPmCKuGombl997HgLqj91F11DzXw==", - "license": "MIT", - "dependencies": { - "flatbuffers": "^1.12.0", - "guid-typescript": "^1.0.9", - "long": "^4.0.0", - "onnx-proto": "^4.0.4", - "onnxruntime-common": "~1.14.0", - "platform": "^1.3.6" - } - }, "node_modules/open": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", @@ -17441,32 +17082,6 @@ "node": "^20.20.0 || >=22.22.0" } }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/pretty-ms": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", @@ -18154,32 +17769,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/protobufjs": { - "version": "6.11.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.6.tgz", - "integrity": "sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.1", - "@types/node": ">=13.7.0", - "long": "^4.0.0" - }, - "bin": { - "pbjs": "bin/pbjs", - "pbts": "bin/pbts" - } - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -18310,6 +17899,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -18449,21 +18039,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -18615,6 +18190,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -18858,9 +18434,7 @@ "version": "2.15.4", "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, "license": "BSD-3-Clause", - "optional": true, "dependencies": { "boolean": "^3.0.1", "detect-node": "^2.0.4", @@ -19036,6 +18610,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -19131,9 +18706,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/send": { "version": "1.2.1", @@ -19193,9 +18766,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, "license": "MIT", - "optional": true, "dependencies": { "type-fest": "^0.13.1" }, @@ -19210,9 +18781,7 @@ "version": "0.13.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, "license": "(MIT OR CC0-1.0)", - "optional": true, "engines": { "node": ">=10" }, @@ -19247,86 +18816,6 @@ "dev": true, "license": "ISC" }, - "node_modules/sharp": { - "version": "0.32.6", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", - "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.2", - "node-addon-api": "^6.1.0", - "prebuild-install": "^7.1.1", - "semver": "^7.5.4", - "simple-get": "^4.0.1", - "tar-fs": "^3.0.4", - "tunnel-agent": "^0.6.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/sharp/node_modules/b4a": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, - "node_modules/sharp/node_modules/node-addon-api": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", - "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", - "license": "MIT" - }, - "node_modules/sharp/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp/node_modules/tar-fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", - "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/sharp/node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -19467,51 +18956,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "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" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "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", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/simple-git": { "version": "3.36.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.36.0.tgz", @@ -19530,15 +18974,6 @@ "url": "https://github.com/steveukx/git-js?sponsor=1" } }, - "node_modules/simple-swizzle": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", - "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, "node_modules/simple-update-notifier": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", @@ -19789,9 +19224,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true + "license": "BSD-3-Clause" }, "node_modules/sql.js": { "version": "1.13.0", @@ -19878,21 +19311,11 @@ "node": ">=0.10.0" } }, - "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", - "license": "MIT", - "dependencies": { - "events-universal": "^1.0.0", - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -19983,15 +19406,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/strnum": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", @@ -20203,29 +19617,13 @@ "node": ">=10" } }, - "node_modules/tar-fs": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-fs/node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, "license": "MIT", + "peer": true, "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", @@ -20293,29 +19691,6 @@ "node": ">= 10.0.0" } }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, - "node_modules/text-decoder/node_modules/b4a": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, "node_modules/text-extensions": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-3.1.0.tgz", @@ -20662,18 +20037,6 @@ "fsevents": "~2.3.3" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-is": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", @@ -21001,6 +20364,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, "license": "MIT" }, "node_modules/vary": { @@ -21985,6 +21349,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/ws": { diff --git a/package.json b/package.json index faba8dd..a77f6fd 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,9 @@ "dev": "concurrently \"npm run dev:vite\" \"npm run dev:electron\"", "dev:vite": "vite", "dev:electron": "npm run build:preload && wait-on http://localhost:5173 && electron .", - "build": "npm run build:main && npm run build:preload && npm run build:renderer", - "build:main": "esbuild src/main/index.ts --bundle --platform=node --outfile=dist/main/index.js --external:electron --external:electron-updater --external:sql.js --external:@xenova/transformers --format=cjs --target=node18 --sourcemap", + "build": "npm run build:main && npm run build:ner-worker && npm run build:preload && npm run build:renderer", + "build:main": "esbuild src/main/index.ts --bundle --platform=node --outfile=dist/main/index.js --external:electron --external:electron-updater --external:sql.js --external:@huggingface/transformers --format=cjs --target=node18 --sourcemap", + "build:ner-worker": "esbuild src/main/privacy/ner-worker.ts --bundle --platform=node --outfile=dist/main/ner-worker.js --external:@huggingface/transformers --format=cjs --target=node18 --sourcemap", "build:preload": "esbuild src/preload/index.ts --bundle --platform=node --outfile=dist/preload/index.js --external:electron --format=iife --target=node18", "build:renderer": "vite build", "start": "electron .", @@ -37,8 +38,8 @@ "dependencies": { "@anthropic-ai/sdk": "^0.71.2", "@google/generative-ai": "^0.24.1", + "@huggingface/transformers": "^4.2.0", "@qdrant/js-client-rest": "^1.16.2", - "@xenova/transformers": "^2.17.2", "electron-updater": "^6.7.3", "lucide-react": "^0.563.0", "nanoid": "^5.1.6", diff --git a/src/main/privacy/model-manager.ts b/src/main/privacy/model-manager.ts index 21064be..74a3bbf 100644 --- a/src/main/privacy/model-manager.ts +++ b/src/main/privacy/model-manager.ts @@ -15,7 +15,7 @@ export class NERModelManager { constructor(baseDir?: string) { this.baseDir = baseDir ?? DEFAULT_BASE_DIR - // @xenova/transformers caches in {cacheDir}/{org}/{model-name}/ + // @huggingface/transformers caches in {cacheDir}/{org}/{model-name}/ (same layout as @xenova v2) this.modelDir = path.join(this.baseDir, ...MODEL_ID.split('/')) this.status = this.checkLocalStatus() } @@ -49,14 +49,14 @@ export class NERModelManager { try { fs.mkdirSync(this.baseDir, { recursive: true }) - const { pipeline, env } = await import('@xenova/transformers') + const { pipeline, env } = await import('@huggingface/transformers') env.cacheDir = this.baseDir env.allowRemoteModels = true - // Use non-quantized (fp32) model for full GIVENNAME/SURNAME detection quality. + // fp32 (non-quantized) model for full GIVENNAME/SURNAME detection quality. // Quantized model loses name recognition. fp32 is ~1.15GB but inference is still <50ms. const pipe = await pipeline('token-classification', MODEL_ID, { - quantized: false, + dtype: 'fp32', progress_callback: (progress: { status: string; loaded?: number; total?: number }) => { if (progress.status === 'progress' && progress.total) { this.downloadProgress = Math.round(((progress.loaded ?? 0) / progress.total) * 100) diff --git a/src/main/privacy/ner-worker.ts b/src/main/privacy/ner-worker.ts index 18d1030..eb6a5a8 100644 --- a/src/main/privacy/ner-worker.ts +++ b/src/main/privacy/ner-worker.ts @@ -13,11 +13,11 @@ type WorkerMessage = let pipe: any = null async function initPipeline(modelId: string, cacheDir: string): Promise { - const { pipeline, env } = await import('@xenova/transformers') + const { pipeline, env } = await import('@huggingface/transformers') env.cacheDir = cacheDir env.allowRemoteModels = false // model must be pre-downloaded via model-manager - // Use non-quantized (fp32) for full PII detection quality - pipe = await pipeline('token-classification', modelId, { quantized: false }) + // fp32 (non-quantized) for full PII detection quality + pipe = await pipeline('token-classification', modelId, { dtype: 'fp32' }) parentPort?.postMessage({ type: 'ready' }) } diff --git a/src/main/tracking/llm-cost-table.json b/src/main/tracking/llm-cost-table.json index 31bbeff..87f7b08 100644 --- a/src/main/tracking/llm-cost-table.json +++ b/src/main/tracking/llm-cost-table.json @@ -1,6 +1,6 @@ { "$schema": "https://json-schema.org/draft/2020-12/schema", - "_version": "2026-03-10", + "_version": "2026-07-02", "_description": "LLM provider pricing in USD per 1M tokens. Shared across Mingly and Claude Remote.", "anthropic": { "claude-opus-4-6": { "input": 5, "output": 25 }, diff --git a/tests/integration/privacy-ner-integration.test.ts b/tests/integration/privacy-ner-integration.test.ts index 78321bb..e14aa88 100644 --- a/tests/integration/privacy-ner-integration.test.ts +++ b/tests/integration/privacy-ner-integration.test.ts @@ -146,7 +146,7 @@ describe.skipIf(SKIP)('piiranha-v1 NER Integration', () => { console.log('[NER Integration] Model already cached.') } - const transformers = await import('@xenova/transformers') + const transformers = await import('@huggingface/transformers') transformers.env.cacheDir = INTEGRATION_MODEL_DIR transformers.env.allowRemoteModels = true // allow download of non-quantized variant @@ -154,7 +154,7 @@ describe.skipIf(SKIP)('piiranha-v1 NER Integration', () => { pipeline = await transformers.pipeline( 'token-classification', 'onnx-community/piiranha-v1-detect-personal-information-ONNX', - { quantized: false } + { dtype: 'fp32' } ) console.log('[NER Integration] Pipeline ready.') }, 300_000) diff --git a/tests/red-team/helpers/direct-ner-detector.ts b/tests/red-team/helpers/direct-ner-detector.ts index b5df88c..d9be4c3 100644 --- a/tests/red-team/helpers/direct-ner-detector.ts +++ b/tests/red-team/helpers/direct-ner-detector.ts @@ -188,13 +188,13 @@ export async function createDirectNERDetector(): Promise<{ shutdown: () => Promise getModelManager: () => { getStatus: () => string } }> { - const { pipeline, env } = await import('@xenova/transformers') + const { pipeline, env } = await import('@huggingface/transformers') env.cacheDir = CACHE_DIR env.allowRemoteModels = false console.log('[DirectNER] Loading piiranha-v1 fp32 model...') const startLoad = performance.now() - const pipe = await pipeline('token-classification', MODEL_ID, { quantized: false }) + const pipe = await pipeline('token-classification', MODEL_ID, { dtype: 'fp32' }) console.log(`[DirectNER] Model loaded in ${Math.round(performance.now() - startLoad)}ms`) let available = true