Skip to content

feat: new context source hooks, streaming chat, and framework parity#337

Merged
vamgan merged 102 commits into
mainfrom
claude/create-agents-md-fqfEf
Jun 13, 2026
Merged

feat: new context source hooks, streaming chat, and framework parity#337
vamgan merged 102 commits into
mainfrom
claude/create-agents-md-fqfEf

Conversation

@vamgan

@vamgan vamgan commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

A large batch of new hooks, examples, and documentation aimed at making askable-ui solve common AI-assistant-in-the-UI problems out of the box.

New context source hooks (core + all frameworks)

Hook What it captures
useAskableFormSource HTML form field values, labels, validation errors; masks passwords by default
useAskableTableSource Table rows, visible page, selection, sort/filter state; auto-notifies on data changes
useAskableErrorSource Validation errors and API failures; compatible with React Hook Form, VeeValidate, Zod
useAskableUserSource Logged-in user profile; works with Clerk, NextAuth, Supabase, Auth0, Pinia auth stores

All four hooks are implemented across React, Vue 3, SolidJS, Svelte 5 (runes), and Angular (service pattern). Core primitives (createAskableFormSource, createAskableErrorSource, createAskableUserSource) are framework-agnostic in @askable-ui/core.

Streaming chat

  • useAskableChat — multi-turn conversation hook with automatic context injection per turn, system prompt factory, clearMessages(), and abort(). Implemented across React, Vue, Solid, Svelte, and React Native.
  • useAskableStream — one-shot streaming primitive with content (accumulated), abort(), onChunk/onSuccess/onError callbacks. All frameworks.

Framework adapters

  • QwikuseAskableAgent with Qwik-serializable $() handlers
  • AngularAskableFormSourceService (ElementRef + autoTrack), AskablePageSourceService, AskableAgentService
  • React NativeuseAskableAgent, useAskableStream, useAskableChat

Examples upgraded

  • examples/nextjs-app-router — replaces Vercel AI SDK useChat with useAskableChat; streaming via /api/askable-chat; full bubble chat UI; .env.example and tsconfig.json added
  • examples/solid-dashboard — adds tabbed AI chat sidebar with useAskableChat + context inspector view
  • packages/create-askable-app/template-svelte — upgraded from context-only to useAskableAgent button pattern (matches Vue template)
  • packages/create-askable-app/template-solid — new SolidJS starter template

Documentation

  • AGENTS.md — new sections for useAskableFormSource, useAskableTableSource, useAskableErrorSource, useAskableUserSource, useAskableStream, useAskableChat, server-side validation with isAskableAgentRequest
  • README.md — updated framework capability tables and feature list

Tests

Total: 686 passing (was 587 before this branch, +99 new tests)

Package Tests
@askable-ui/core 274
@askable-ui/react 143
@askable-ui/vue 81
@askable-ui/solid 48
@askable-ui/svelte 38
@askable-ui/angular 25
@askable-ui/qwik 9
@askable-ui/react-native 24
@askable-ui/mcp 36
@askable-ui/web-component 8

Test plan

  • All 686 tests pass (npx vitest run in each package)
  • Next.js example builds and streaming chat works end-to-end with ANTHROPIC_API_KEY
  • create-askable-app SolidJS and Svelte templates scaffold correctly
  • AskableFormSourceService injects correctly in an Angular component with @ViewChild
  • useAskableTableSource auto-notifies on row array changes in React (state update → AI sees new count)
  • useAskableUserSource with omitFields: ['email'] excludes the email from resolved context

Generated by Claude Code

claude and others added 30 commits June 11, 2026 05:47
…lback safety

- capture.ts: call removeAffordance() before re-rendering the selection
  affordance so repeated captures with once:false don't accumulate DOM nodes
- mcp/index.ts: add requireRedacted option that blocks forwarding packets
  where privacy.redacted===false, preventing unredacted data reaching the
  MCP client; add corresponding tests
- useAskableScrollView.ts: wrap selectVisible/getMeta/getText callbacks in
  try/catch so a consumer-thrown exception cannot halt scroll sync
…n exceptions

- context.ts subscribe(): add try/catch around the sync subscriber callback
  to match the existing protection in subscribeAsync(); prevents a throwing
  subscriber from crashing the observer chain
- selection.ts: move destroy() before onCapture invocation and wrap the
  callback in try/catch so an exception in user code never leaves selection
  listeners dangling
- capture.ts: remove duplicate removeAffordance() call introduced during
  the previous commit; single call is sufficient and idempotent
…h try/catch

- capture.ts: guard onCapture, onCancel, and onSubmit callbacks so a
  consumer exception cannot propagate into internal pointer/key event
  handlers or leave the DOM in an inconsistent state
- selection.ts: guard onCancel so a throwing consumer cannot leave the
  cancel path half-executed; matches the onCapture fix from the previous commit
…wn exceptions

Wrap the user-supplied affordance render function in try/catch so an
exception does not interrupt the post-capture flow or leave internal
state inconsistent.
README:
- New punchy headline: "Your LLM doesn't know what the user is looking at. Fix that in two lines."
- Lead with "What the AI receives" — shows actual promptContext output upfront
- Before/after comparison showing the problem (stale system prompt) vs the solution
- Prominent MCP section with 3-line setup and Claude Desktop config
- Better organized sections: capture modes, integrations table, framework quick starts
- Links to vanilla-chat example as zero-install demo

examples/vanilla-chat/index.html:
- Zero-install single-file demo that opens directly in any browser
- Full analytics dashboard (3 KPI cards, 4-row deal table) with data-askable
- Real-time "What the AI sees" panel showing live promptContext
- Mock AI chat that generates context-accurate responses from the actual data
- Copy context button, keyboard navigation, beautiful dark-mode design
- Loads @askable-ui/core from CDN — no build step

site/www/index.html:
- Updated page title and OG/Twitter meta tags with sharper copy
- Hero eyebrow: "Claude Desktop · Cursor · CopilotKit · any LLM" (was generic)
- Hero body paragraph: problem-first framing (no screenshots, no guessing)
- Nav: added MCP link, removed redundant Patterns/Integrations links
- Integrations section: added Claude Desktop and Cursor as MCP client cards (5 total)
- New MCP section with code examples, Claude Desktop config, and feature cards
- CTA: "Your AI. Your UI. Finally connected." + Live demo link added
- Footer: MCP guide and Live demo links added
Minimal Vue 3 + Vite demo showing the core askable-ui pattern:
- <Askable :meta="..."> keeps data-askable in sync with reactive props
- useAskable() composable returns promptContext ref that auto-updates
- Live "What the AI sees" panel showing the actual context string
- Mock AI chat demonstrating how specific and accurate responses become
  when the AI has real context (NRR/pipeline/deals with actual values)

Includes README with real-LLM wiring instructions for OpenAI/Anthropic.
… links

- vanilla-chat/README.md: explains zero-install approach, how CDN import
  works, and shows how to connect to a real LLM API (OpenAI/Anthropic)
- README.md: fix @askable/react → @askable-ui/react import typo
- README.md: expand Live links section with Vue, React Native, analytics
  dashboard, and vanilla examples with one-liner descriptions
Exposes all [data-askable] elements currently visible in the viewport
as reactive React state via IntersectionObserver + MutationObserver.

- Standalone hook — no dependency on useAskable
- Optional root, threshold, and scope filter options
- promptContext string ready for direct LLM injection
- Full test suite (6 cases)
Port of the React hook to Vue 3 — reactive ref tracking all visible
[data-askable] elements via IntersectionObserver + MutationObserver.
Supports root, threshold, and scope filter options. Includes 5 tests.
Minimal Next.js 15 app showing the 4-step askable-ui + Vercel AI SDK
integration: annotate → useAskable() → body:{uiContext} → system prompt.
Works with any AI SDK provider. Includes full README with cross-framework
usage notes (LangChain, raw OpenAI SDK).

Also adds useAskableViewport to the Vue and React README examples tables.
Svelte 5: useAskableViewport() runes composable exported via
  @askable-ui/svelte/useAskableViewport.svelte

Svelte 4: createAskableViewportStore() exported from the main
  @askable-ui/svelte entrypoint

Same IntersectionObserver + MutationObserver approach as the React
and Vue implementations, completing cross-framework parity.
Tracks the last N focused elements as a navigation trail with:
- history: AskableFocus[] (newest first, capped at maxEntries)
- current: AskableFocus | null
- promptContext: formatted trail string for LLM injection
- Deduplication of consecutive identical entries (opt-out via dedupe:false)
- 8 tests covering trail ordering, dedupe, cap, clear, and prompt format
Vue 3: useAskableHistory() composable (5 tests)
Svelte 5: useAskableHistory() runes composable via useAskableHistory.svelte
Svelte 4: createAskableHistoryStore() exported from main entrypoint

All three match the React implementation: navigation trail, dedupe,
maxEntries cap, promptContext string for LLM injection.
Updates the frameworks table and adds new sections for viewport context
and navigation history hooks in the Capture modes section.
Composes focus, viewport, history, and any other context sources into
one prompt-ready string. Sections with empty values are automatically
skipped. Used in the vercel-ai-sdk example to show all three streams
combined into a single system prompt injection.

5 tests covering section filtering, separator, and fallback.
Surfaces useAskableViewport, useAskableHistory, useAskableCompose in
the landing page package cards and adds a Composing context streams
section to the README.
Cast focus.meta to a typed object without runtime overhead.
Zero-cost cast for TypeScript users who control their data-askable schemas.

  interface KpiMeta { metric: string; value: string; delta: string }
  const typed = asMeta<KpiMeta>(focus);
  typed.meta.value // → string, not unknown
asMeta<T>() and TypedAskableFocus<T> are now importable directly from
@askable-ui/react, @askable-ui/vue, and @askable-ui/svelte.

Adds a 'Typed meta (TypeScript)' section to the README.
New SolidJS adapter with full feature parity:
- useAskable() — reactive focus + promptContext signal
- useAskableViewport() — IntersectionObserver-based viewport tracking
- useAskableHistory() — navigation trail with dedupe + maxEntries cap
- <Askable> — wrapper component using Dynamic for flexible 'as' prop
- asMeta<T>() re-export for typed meta access
- 9 tests (Askable component + useAskable hook)

Adds SolidJS to the README frameworks table, quick starts section,
CONTRIBUTING project structure, and the feature request issue template.
- useAskableCompose() added to @askable-ui/vue (computed-based)
- useAskableCompose() added to @askable-ui/solid (createMemo, accepts
  reactive accessor to correctly track Solid signals)
- examples/solid-dashboard/ — full Vite + SolidJS dashboard showing
  useAskable, useAskableViewport, useAskableHistory, useAskableCompose,
  and asMeta<T> with a live context inspector sidebar
- README examples table updated, landing page adds @askable-ui/solid card
Svelte 5 version accepts a reactive function/accessor so $derived
correctly tracks rune reads. Exported via:
  import { useAskableCompose } from '@askable-ui/svelte/useAskableCompose.svelte'
claude added 2 commits June 12, 2026 13:49
Adds tab visibility context source across all frameworks. AI assistants
can now detect when users switch away from the tab and understand why
real-time features paused, with hide count and hidden duration tracking.

- core: createAskableTabSource factory + 9 tests (all passing)
- React: useAskableTabSource hook with visibilitychange listener
- Vue: useAskableTabSource composable with onMounted/onUnmounted
- Solid: useAskableTabSource primitive with createEffect/onCleanup
- Svelte 5: useAskableTabSource.svelte.ts with $state + onMount/onDestroy
- Angular: AskableTabSourceService with automatic document event cleanup
…DOM sources

Fills in the remaining Angular service gaps. These services mirror the existing
React/Vue/Solid/Svelte hooks and complete full-framework coverage for all sources.

- AskableClipboardSourceService: auto-tracks copy events, addEntry/clear helpers
- AskableStorageSourceService: thin wrapper around createAskableStorageSource
- AskableNotificationSourceService: add/remove/clear/setNotifications management
- AskableDOMSourceService: accepts ElementRef, element, or getter function
Enables AI assistants to proactively diagnose slow page loads and poor
Core Web Vitals ratings across all frameworks.

- core: createAskablePerformanceSource + rateMetric helper + 10 tests
- Navigation timing: loadTime, TTFB, domContentLoaded, dns, connect
- Memory info (Chrome): usedMB, totalMB, limitMB
- Automatic Good/Needs-improvement/Poor ratings per Google thresholds
- addMetric() API integrates with web-vitals library (LCP, FID, CLS, INP, FCP)
- React/Vue/Solid/Svelte hooks + Angular AskablePerformanceSourceService
Enables AI assistants to warn users about low battery before starting
long operations like file exports, data migrations, or video renders.

- core: createAskableBatterySource + getBatteryStatus + formatDuration helpers + 9 tests
- status: critical (<15%), low (<30%), medium (<60%), high (<100%), full
- auto-subscribes to levelchange, chargingchange, chargingtimechange events
- React/Vue/Solid/Svelte hooks + Angular AskableBatterySourceService
Enables AI assistants to provide location-aware assistance — nearest stores,
delivery estimates, timezone-aware scheduling, and geofence-based features.

- core: createAskableGeolocationSource + 9 tests
- Tracks coords, accuracy, heading, speed, permissionState, and error
- autoRequest and watch modes for one-shot or continuous tracking
- requestPosition() for manual on-demand location requests
- React/Vue/Solid/Svelte hooks + Angular AskableGeolocationSourceService
…acking

Enables AI assistants to give time-aware assistance — knowing the user's
local time, timezone, whether they're within business hours, and how long
they've been in the current session.

- core: createAskableTimeSource + buildTimeSnapshot helper + 9 tests
- Tracks: local time, IANA timezone, UTC offset, dayOfWeek, isWeekend
- isBusinessHours: configurable start/end hours and working days
- sessionSeconds: time elapsed since page load
- intervalMs option: auto-refresh interval (default 60s)
- React/Vue/Solid/Svelte hooks + Angular AskableTimeSourceService
Enables AI assistants to know which element the user is working on,
providing targeted help for form fields, buttons, and interactive elements.

- core: createAskableFocusSource + elementToFocusSnapshot helper + 9 tests
- Captures: tag, id, label, role, name, type, value, classes, isFormField
- focusChangeCount and lastChangedAt for focus history context
- focusout uses setTimeout to avoid false "no focus" during tab navigation
- React/Vue/Solid/Svelte hooks + Angular AskableFocusSourceService
Tracks multi-step wizard, stepper, and checkout flow state across all
frameworks so AI assistants can guide users through complex processes.
Exports next/prev/goTo/complete/setError/reset across React, Vue, Solid,
Svelte, and Angular. Core buildMultistepSnapshot computes progress,
completion, and step metadata from a shared snapshot pattern.
Tracks ecommerce cart state (items, quantities, subtotal, discount, tax,
shipping, total) so AI assistants can answer questions about cart contents.
Provides addItem/removeItem/updateQuantity/setItems/setTotals/clearCart
across React, Vue, Solid, Svelte, and Angular. 528 tests passing.
claude added 2 commits June 13, 2026 16:03
Resolves conflicts in README.md and site/www/index.html by keeping the
more complete feature-branch versions.
The MCP docs live at /docs/api/mcp, not /docs/guide/mcp. Updates the
broken links in README.md, AGENTS.md, and the landing page.
- locale-source: cast resolvedOptions to access hourCycle (not in CI's TS lib)
- useAskablePageSource: Omit context-level textExtractor so the page-source
  extractor signature (Document | HTMLElement) wins across React/Vue/Solid/Svelte
- vue chat/stream: type isStreaming as ComputedRef<boolean> instead of the
  writable computed overload
@pkg-pr-new

pkg-pr-new Bot commented Jun 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

@askable-ui/context

npm i https://pkg.pr.new/@askable-ui/context@337

@askable-ui/core

npm i https://pkg.pr.new/@askable-ui/core@337

@askable-ui/create-app

npm i https://pkg.pr.new/@askable-ui/create-app@337

@askable-ui/mcp

npm i https://pkg.pr.new/@askable-ui/mcp@337

@askable-ui/react

npm i https://pkg.pr.new/@askable-ui/react@337

@askable-ui/react-native

npm i https://pkg.pr.new/@askable-ui/react-native@337

@askable-ui/svelte

npm i https://pkg.pr.new/@askable-ui/svelte@337

@askable-ui/vue

npm i https://pkg.pr.new/@askable-ui/vue@337

commit: 18ba8d8

…md-fqfEf

# Conflicts:
#	README.md
#	site/www/index.html
@vamgan vamgan force-pushed the claude/create-agents-md-fqfEf branch from 974428e to 18ba8d8 Compare June 13, 2026 16:30
@vamgan vamgan merged commit 18ba8d8 into main Jun 13, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants