Skip to content

AIPointer v1.1.0

Choose a tag to compare

@talentsache talentsache released this 17 Aug 16:59
· 3 commits to main since this release

[1.1.0] — 2026-05-16

Major feature release. Audience feedback on v1.0.0 landed at 7/10; v1.1.0
targets 10/10 by hardening the first-run experience, adding a true Child Mode
behavior layer, and polishing the visual + interaction layer. The Pillbox UI
itself is byte-identical to v1.0.0 — Child Mode is a pure behavior layer
(system prompt, tool gating, sanitizer, URL whitelist).

Added

  • Onboarding wizard. Separate framed window on first launch — 5 steps:
    Welcome + privacy, Mode pick (Adult / Child), PIN setup,
    Autostart + updates, Provider + API key. Cancel quits cleanly; complete
    boots the rest of the app. Keychain prompt fires exactly once, at the
    moment the user explicitly clicks Complete.
  • Child Mode. Locale-driven safe-browsing layer that produces kid-friendly
    responses (EN/DE), restricts tools to fetch_url / open_url / launch_app,
    validates every outbound URL against a per-language allowlist, swaps the
    system prompt, and stamps a stricter HTML sanitizer schema. PIN-gated
    Settings, /quit, and mode-switch back to Adult. Voice-first ON by default
    with a slower TTS rate (0.9).
  • launch_app tool. Open whitelisted desktop apps (paint, calculator,
    notes, word, excel, mail, browser) with an approval pill. Cross-platform
    (open -a, start, execFile). Parent-configurable allow-list in Child
    Mode via childModeAllowedApps.
  • Voice command router. Pre-LLM phrase router. Says "open settings" /
    "einstellungen öffnen" / "ayuda" / "aiuto" — fires the matching slash
    command in EN, DE, FR, ES, IT, PT, NL without an LLM round-trip.
    Exact / prefix / Levenshtein-≤-2 matching.
  • Cross-platform autostart. Toggleable "Start AIPointer at login" with a
    "Start in the tray (no window)" sub-toggle. app.setLoginItemSettings on
    macOS / Windows, ~/.config/autostart/aipointer.desktop on Linux.
  • Mouse-wiggle activation. Wiggle the mouse left-right-left within 700ms
    to summon AIPointer. Disable in Settings → Behaviour (on by default).
  • Left-side hotkey listening. New hotkey choices: MetaLeft, CtrlLeft,
    AltLeft, ShiftLeft, plus MetaEither / CtrlEither that listen on
    both sides simultaneously.
  • Dynamic pill. Bottom pill drifts gently toward the cursor with spring
    inertia, never snapping. Pure visual; the pill's hit-test position
    remains centered.
  • Live mode switching. Adult ↔ Child without restart. System prompt,
    tool registry, sanitize schema, voice defaults all rebuild on the fly.
  • PIN module. PBKDF2-SHA256 (200k iterations, 16-byte salt, timing-safe
    compare). Plain electron-store storage on purpose — no safeStorage so
    PIN setup during onboarding doesn't trigger a keychain prompt.
  • Per-language whitelist module. EN + DE kid-safe domain lists with
    optional path-prefix gating (bbc.co.uk → /cbeebies + /bitesize only).
  • Intent router. Pre-LLM keyword/regex matcher for Child Mode — "I want
    to play" → games URL, "show me pictures of …" → image search, etc.
    Short-circuits to a direct action without an LLM round-trip.
  • XSS test suite. 15 attack vectors against the child sanitize schema +
    12 host edge-cases against the URL validator + 6 PIN unit tests +
    10 voice-command tests. npm test runs them all (vitest + jsdom).
  • AUTHORSHIP.md (docs/AUTHORSHIP.md). Canonical provenance / DNA
    record. Referenced by README, CHANGELOG, and the hidden /origin
    slash command. Closes a long-standing dangling reference.
  • Diagnostics. Hidden /diagnostics slash command (Adult mode) prints
    version, provider configuration, permissions state, hotkey, default
    crop, and the last 5 in-memory errors. Useful for support emails.

Changed

  • Default screenshot crop 1024×768 → 512×384. ~75% drop in vision token
    cost with negligible legibility loss for cursor-centered content. Crop
    size now reads from settings (screenshotCropW / screenshotCropH).
    Region selection (drag-rectangle) is unchanged.
  • Glassmorphism restored. Main prompt box, settings, and bottom pill
    now use backdrop-blur-xl backdrop-saturate-150 with reduced bg alpha
    and an inner-ring highlight. New reducedTransparency setting and a
    CSS-var-based escape hatch for older Intel Macs.
  • Voice-first default in Child Mode. Runtime override on audioMode
    forces it ON when in Child Mode, leaving the stored adult preference
    intact for the switch back.
  • Provider key storage is now lazy. SettingsGet IPC no longer
    decrypts API keys; the renderer never sees plaintext keys at load.
    Decryption happens only at query time (router) or on an explicit
    Show key IPC call. First-run keychain prompt is fully deferred to
    the wizard's Complete step.

Fixed

  • TTS continues after mic press. useTTS now tracks a speakId
    version token; when stop() is called mid-fetch, the post-await
    branch checks the token and refuses to start a new audio element.
    Previously a pending synthesizeSpeech IPC could resolve and quietly
    restart playback after the user pressed the mic, producing parallel
    voice + recording.
  • Audio-mode loop: mic press during speaking phase. The loop's
    armNextRef is now reset when the user manually presses the mic, so
    it doesn't auto-restart speaking after the user takes control.
  • Keychain prompt on first run before any disclaimer. SettingsGet IPC
    uses a new lightweight variant (getSettingsLight) that never touches
    safeStorage. The first encryptString call happens at the moment the
    user submits their key in the onboarding wizard — with user-active
    context — not at startup.
  • macOS traffic-lights flicker. Already shipped in v1.0.0 (overlay.ts
    setWindowButtonVisibility + ready-to-show), verified intact.

Security

  • Child Mode URL validation is defense-in-depth. The intent router,
    the LLM tool declaration set, and the open_url execute-time
    validator each independently enforce the whitelist. A jailbroken LLM
    cannot open an off-whitelist URL because open_url.execute rejects it
    with a verbose error that the LLM re-verbalises as a kid-friendly
    redirect.
  • Stricter sanitize schema for Child Mode drops <a>, <details>,
    <summary>, <kbd>, <mark>, <sub>, <sup> entirely and
    restricts class values to a kid-* allow-prefix.
  • PIN hashing uses PBKDF2-SHA256 (200k iterations, 16-byte salt,
    timing-safe compare). Stored plain in electron-store config.json by
    design (no safeStorage trigger). Brute-force is offline-resistant up
    to consumer-grade.
  • Provider keys never leave main process plaintext. The IPC
    surface returns empty strings for apiKey; the renderer must
    explicitly call revealProviderKey to see one, which fires the
    keychain prompt with full user context.
  • Tools blocked in Child Mode: read_clipboard, copy_to_clipboard,
    reveal_in_finder, save_document — both removed from the
    LLM-visible declarations AND refused at execute time as a safety net.

Provenance

  • DNA / authorship file is now real: see docs/AUTHORSHIP.md.
  • v1.1.0 provenance: aipointer/v1.1.0/ms/talentsache/skales/20260516.