{"id":47710884,"url":"https://github.com/askable-ui/askable","last_synced_at":"2026-05-31T02:03:01.069Z","repository":{"id":347476255,"uuid":"1194180957","full_name":"askable-ui/askable","owner":"askable-ui","description":"Two lines of code to give your LLM eyes. One attribute.","archived":false,"fork":false,"pushed_at":"2026-05-31T00:44:55.000Z","size":12930,"stargazers_count":8,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-05-31T01:14:10.165Z","etag":null,"topics":["ai","ai-agents","copilot","developer-tools","django","frontend","llm","prompt-engineering","python","react","streamlit","svelte","ui","vue"],"latest_commit_sha":null,"homepage":"https://askable-ui.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/askable-ui.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-28T02:38:08.000Z","updated_at":"2026-05-31T00:41:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/askable-ui/askable","commit_stats":null,"previous_names":["vamgan/askable","askable-ui/askable"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/askable-ui/askable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askable-ui%2Faskable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askable-ui%2Faskable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askable-ui%2Faskable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askable-ui%2Faskable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/askable-ui","download_url":"https://codeload.github.com/askable-ui/askable/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/askable-ui%2Faskable/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33716339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","ai-agents","copilot","developer-tools","django","frontend","llm","prompt-engineering","python","react","streamlit","svelte","ui","vue"],"created_at":"2026-04-02T18:31:49.150Z","updated_at":"2026-05-31T02:03:01.063Z","avatar_url":"https://github.com/askable-ui.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"site/www/avatar.png\" alt=\"askable-ui\" width=\"96\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003easkable-ui\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eTwo lines of code to give your LLM eyes.\u003c/strong\u003e\u003cbr /\u003e\n  One attribute. Zero prompt engineering. It knows exactly what the user sees.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@askable-ui/core\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@askable-ui/core?color=4f46e5\u0026label=npm\" alt=\"npm version\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@askable-ui/core\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dw/@askable-ui/core?color=4f46e5\u0026label=downloads\" alt=\"npm downloads\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"./LICENSE\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/l/@askable-ui/core?color=4f46e5\" alt=\"MIT license\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/askable-ui/askable/actions\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/askable-ui/askable/static_quality.yml?branch=main\u0026color=4f46e5\u0026label=CI\" alt=\"CI\" /\u003e\n  \u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/PRs-welcome-4f46e5\" alt=\"PRs welcome\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cvideo src=\"https://github.com/user-attachments/assets/dfc6a889-e093-452d-8259-e7123b446d24\" autoplay loop muted playsinline width=\"720\"\u003e\u003c/video\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"#quick-start\"\u003eQuick Start\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"#why\"\u003eWhy\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"#how-it-works\"\u003eHow it works\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"#works-with\"\u003eWorks with\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"#features\"\u003eFeatures\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"#packages\"\u003ePackages\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://askable-ui.com/docs/\"\u003eDocs\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://askable-ui.com/docs/guide/agents\"\u003eAgent Templates\u003c/a\u003e \u0026nbsp;·\u0026nbsp;\n  \u003ca href=\"https://askable-mu.vercel.app/\"\u003eLive Demo\u003c/a\u003e\n\u003c/p\u003e\n\n---\n\n## Quick start\n\n```bash\nnpm install @askable-ui/react\n```\n\n```tsx\nimport { Askable, useAskable } from '@askable-ui/react';\n\nfunction Dashboard({ kpi }) {\n  const { promptContext } = useAskable();\n  // promptContext: \"User is focused on: metric=revenue, value=$2.3M, delta=+12%\"\n\n  return (\n    \u003cAskable meta={{ metric: kpi.name, value: kpi.value, delta: kpi.delta }}\u003e\n      \u003cKPICard data={kpi} /\u003e\n    \u003c/Askable\u003e\n  );\n}\n```\n\nThat's it. `promptContext` updates automatically as the user interacts. Pass it to any LLM.\n\nNeed a runnable starter app with Askable and CopilotKit?\n\n```bash\nnpm create @askable-ui/app my-app\ncd my-app\nnpm install\nnpm run dev\n```\n\n\n---\n\n## Why\n\nAI copilots ask users to _describe_ what they're looking at.\nThat's friction — and it's imprecise.\n\naskable-ui solves this with one HTML attribute. Mark any element with `data-askable`, and the library tracks user focus and serializes it into a prompt-ready string. The model gets the user's exact visual context — not a guess, the real thing.\n\nNo page scraping. No DOM serialization. No prompt bloat. **Lightweight and zero-dependency.**\n\n---\n\n## How it works\n\n**1. Annotate** — same data that renders your chart feeds the AI\n\n```tsx\n\u003cAskable meta={{ metric: 'revenue', value: '$2.3M', delta: '+12%', period: 'Q3' }}\u003e\n  \u003cRevenueChart data={data} /\u003e\n\u003c/Askable\u003e\n```\n\n**2. Observe** — automatic, zero config\n\n```tsx\nconst { ctx, promptContext } = useAskable();\n// promptContext updates whenever the user clicks, hovers, or focuses\n\nconst { ctx: tableCtx } = useAskable({ name: 'table' });\nconst { ctx: chartCtx } = useAskable({ name: 'chart' });\n// named contexts stay isolated for multi-region pages\n\nconst { ctx: screenCtx } = useAskable({ viewport: true });\n// screenCtx.toViewportContext() serializes currently visible annotated elements\n```\n\n**3. Inject** — at the AI boundary, one line\n\n```ts\nconst result = await streamText({\n  model: openai('gpt-4o'),\n  system: `You are a helpful analytics assistant.\\n\\n${promptContext}`,\n  messages,\n});\n```\n\n---\n\n## Works with\n\n**LLM SDKs** — OpenAI · Anthropic · Vercel AI SDK · CopilotKit · LangChain · any SDK\n\n**Frameworks** — React · Vue 3 · Svelte · Vanilla JS · Next.js · Nuxt · SvelteKit\n\naskable-ui is the context layer. It doesn't replace your LLM SDK — it gives it eyes.\n\n---\n\n## Features\n\n- **Zero config** — one attribute, works with any DOM structure, styling system, or component library\n- **React, Vue, Svelte** — idiomatic hooks and components; core is framework-agnostic\n- **SSR safe** — defers to client lifecycle, no `window is not defined`\n- **\"Ask AI\" button** — `ctx.select(element)` pins focus to any element programmatically\n- **Conversation history** — `ctx.toHistoryContext(n)` for multi-turn context\n- **Viewport awareness** — `ctx.getVisibleElements()` / `ctx.toViewportContext()` for on-screen context\n- **Redaction hooks** — strip sensitive fields before data reaches serialization\n- **Inspector panel** — `\u003cAskableInspector /\u003e` or `useAskable({ inspector: true })` for a live dev overlay\n- **Agent templates** — reusable `AGENTS.md` guidance and copy-paste prompts for coding-agent-driven adoption\n- **Lightweight core** — zero runtime dependencies\n\n---\n\n## Packages\n\n| Package | Version | Use when |\n|---|---|---|\n| [`@askable-ui/core`](https://www.npmjs.com/package/@askable-ui/core) | [![npm](https://img.shields.io/npm/v/@askable-ui/core?color=4f46e5)](https://www.npmjs.com/package/@askable-ui/core) | Vanilla JS, custom framework, or as a peer dep |\n| [`@askable-ui/react`](https://www.npmjs.com/package/@askable-ui/react) | [![npm](https://img.shields.io/npm/v/@askable-ui/react?color=4f46e5)](https://www.npmjs.com/package/@askable-ui/react) | React 18+ |\n| [`@askable-ui/react-native`](https://www.npmjs.com/package/@askable-ui/react-native) | [![npm](https://img.shields.io/npm/v/@askable-ui/react-native?color=4f46e5)](https://www.npmjs.com/package/@askable-ui/react-native) | React Native (initial press-driven adapter) |\n| [`@askable-ui/vue`](https://www.npmjs.com/package/@askable-ui/vue) | [![npm](https://img.shields.io/npm/v/@askable-ui/vue?color=4f46e5)](https://www.npmjs.com/package/@askable-ui/vue) | Vue 3 |\n| [`@askable-ui/svelte`](https://www.npmjs.com/package/@askable-ui/svelte) | [![npm](https://img.shields.io/npm/v/@askable-ui/svelte?color=4f46e5)](https://www.npmjs.com/package/@askable-ui/svelte) | Svelte 4 \u0026 5 |\n| [`@askable-ui/create-app`](https://www.npmjs.com/package/@askable-ui/create-app) | npm package | React + Vite + CopilotKit starter scaffold |\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFramework quick starts\u003c/strong\u003e\u003c/summary\u003e\n\n### React Native\n\n```bash\nnpm install @askable-ui/react-native\n```\n\n```tsx\nimport { Pressable, Text } from 'react-native';\nimport { Askable, useAskable } from '@askable-ui/react-native';\n\nfunction RevenueCard() {\n  const { ctx, promptContext } = useAskable();\n\n  return (\n    \u003cAskable ctx={ctx} meta={{ widget: 'revenue' }} text=\"Revenue card\"\u003e\n      \u003cPressable\u003e\n        \u003cText\u003eRevenue\u003c/Text\u003e\n      \u003c/Pressable\u003e\n    \u003c/Askable\u003e\n  );\n}\n```\n\nFor a runnable mobile demo, see [`examples/react-native-expo`](./examples/react-native-expo).\n\n### Vue 3\n\n```bash\nnpm install @askable-ui/vue\n```\n\n```vue\n\u003cscript setup\u003e\nimport { Askable, useAskable } from '@askable-ui/vue';\nconst { promptContext } = useAskable();\nconst props = defineProps(['kpi']);\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cAskable :meta=\"{ metric: kpi.name, value: kpi.value }\"\u003e\n    \u003cKPICard :data=\"kpi\" /\u003e\n  \u003c/Askable\u003e\n\u003c/template\u003e\n```\n\n### Svelte\n\n```bash\nnpm install @askable-ui/svelte\n```\n\n```svelte\n\u003cscript\u003e\n  import { Askable, useAskable } from '@askable-ui/svelte';\n  const { promptContext } = useAskable();\n  export let kpi;\n\u003c/script\u003e\n\n\u003cAskable meta={{ metric: kpi.name, value: kpi.value }}\u003e\n  \u003cKPICard data={kpi} /\u003e\n\u003c/Askable\u003e\n```\n\n### Vanilla JS\n\n```bash\nnpm install @askable-ui/core\n```\n\n```ts\nimport { createAskableContext } from '@askable-ui/core';\n\nconst ctx = createAskableContext();\nctx.observe(document.body);\n\nctx.on('focus', () =\u003e {\n  console.log(ctx.toPromptContext());\n  // \"User is focused on: — metric: revenue, value: $2.3M\"\n});\n```\n\n\u003c/details\u003e\n\n---\n\n## Live links\n\n- **Docs:** [askable-ui.com/docs](https://askable-ui.com/docs/)\n- **Analytics dashboard demo:** [askable-mu.vercel.app](https://askable-mu.vercel.app/)\n\n---\n\n## Documentation\n\n**[askable-ui.com/docs](https://askable-ui.com/docs/)**\n\n| Guide | |\n|---|---|\n| [Getting started](https://askable-ui.com/docs/guide/getting-started) | Install, observe, inject |\n| [Annotating elements](https://askable-ui.com/docs/guide/annotating) | `data-askable`, nesting, priority |\n| [React](https://askable-ui.com/docs/guide/react) · [Vue](https://askable-ui.com/docs/guide/vue) · [Svelte](https://askable-ui.com/docs/guide/svelte) | Framework guides |\n| [CopilotKit integration](https://askable-ui.com/docs/guide/copilotkit) | Context-in-input pattern |\n| [API reference](https://askable-ui.com/docs/api/core) | Full type docs |\n\n---\n\n## Using with coding agents\n\n[`AGENTS.md`](./AGENTS.md) contains copy-pasteable instructions for Claude, Cursor, Codex, and similar tools. Drop it into your project root and your coding agent will know how to integrate `askable-ui` correctly — annotation patterns, passive vs explicit flows, sanitization, and common mistakes.\n\n---\n\n## Contributing\n\nPRs welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions.\n\n## License\n\nMIT — see [LICENSE](./LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskable-ui%2Faskable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faskable-ui%2Faskable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faskable-ui%2Faskable/lists"}