AIPointer v1.1.0
[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 viachildModeAllowedApps. - 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.setLoginItemSettingson
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, plusMetaEither/CtrlEitherthat 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 testruns 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
/diagnosticsslash 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 usebackdrop-blur-xl backdrop-saturate-150with reduced bg alpha
and an inner-ring highlight. NewreducedTransparencysetting 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 keyIPC call. First-run keychain prompt is fully deferred to
the wizard's Complete step.
Fixed
- TTS continues after mic press.
useTTSnow tracks aspeakId
version token; whenstop()is called mid-fetch, the post-await
branch checks the token and refuses to start a new audio element.
Previously a pendingsynthesizeSpeechIPC 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
armNextRefis 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 theopen_urlexecute-time
validator each independently enforce the whitelist. A jailbroken LLM
cannot open an off-whitelist URL becauseopen_url.executerejects 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 akid-*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 forapiKey; the renderer must
explicitly callrevealProviderKeyto 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.