@yuktishaalaa/yuktai 5.3.10 → 5.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +7 -7
  2. package/dist/agent-SZENB4QE.mjs +18 -0
  3. package/dist/agentic/a11yCopilot.d.ts +32 -0
  4. package/dist/agentic/contextIndex.d.ts +58 -0
  5. package/dist/agentic/designReview.d.ts +26 -0
  6. package/dist/agentic/dom.d.ts +42 -0
  7. package/dist/agentic/formReview.d.ts +38 -0
  8. package/dist/agentic/gridQuery.d.ts +64 -0
  9. package/dist/agentic/index.d.ts +13 -0
  10. package/dist/agentic/insights.d.ts +62 -0
  11. package/dist/agentic/pageInsights.d.ts +47 -0
  12. package/dist/agentic/qaAudit.d.ts +59 -0
  13. package/dist/agentic/react.d.ts +52 -0
  14. package/dist/agentic/rust/ragCoreWasm.d.ts +3 -0
  15. package/dist/agentic/rust/ragEngine.d.ts +32 -0
  16. package/dist/agentic/taskRunner.d.ts +34 -0
  17. package/dist/agentic/voiceA11yCommands.d.ts +74 -0
  18. package/dist/chunk-K2IBRN5C.mjs +1 -0
  19. package/dist/chunk-M2OKTFX3.mjs +11 -0
  20. package/dist/chunk-N2HHE7YH.mjs +1 -0
  21. package/dist/core/a11yEngine.d.ts +5 -0
  22. package/dist/core/ai/agent.d.ts +21 -0
  23. package/dist/core/ai/labeller.d.ts +12 -0
  24. package/dist/core/ai/promptOptions.d.ts +16 -0
  25. package/dist/core/ai/rag.d.ts +7 -0
  26. package/dist/core/ai/rewriter.d.ts +13 -0
  27. package/dist/core/ai/summarizer.d.ts +8 -0
  28. package/dist/core/ai/transformers-rag.d.ts +9 -0
  29. package/dist/core/ai/translator.d.ts +14 -0
  30. package/dist/core/ai/voice.d.ts +33 -0
  31. package/dist/core/codegen/page-templates.d.ts +32 -0
  32. package/dist/core/codegen/requirement-parser.d.ts +12 -0
  33. package/dist/core/codegen/zip-generator.d.ts +2 -0
  34. package/dist/core/generateUI.d.ts +4 -0
  35. package/dist/core/renderer.d.ts +72 -0
  36. package/dist/grid/YuktaiGrid.d.ts +4 -0
  37. package/dist/grid/YuktaiGridAI.d.ts +46 -0
  38. package/dist/grid/YuktaiGridAgent.d.ts +81 -0
  39. package/dist/grid/YuktaiGridWebMCP.d.ts +54 -0
  40. package/dist/grid/gridTools.d.ts +111 -0
  41. package/dist/grid/rust/engine.d.ts +55 -0
  42. package/dist/grid/rust/gridCoreWasm.d.ts +3 -0
  43. package/dist/grid/rust/useGridCore.d.ts +2 -0
  44. package/dist/grid/types.d.ts +245 -0
  45. package/dist/grid/useGrid.d.ts +57 -0
  46. package/dist/grid/yuktaiGridRows.d.ts +35 -0
  47. package/dist/icons/CheckIcon.d.ts +2 -0
  48. package/dist/icons/ChevronLeftIcon.d.ts +2 -0
  49. package/dist/icons/ChevronRightIcon.d.ts +2 -0
  50. package/dist/icons/CloseIcon.d.ts +2 -0
  51. package/dist/icons/IconBase.d.ts +25 -0
  52. package/dist/icons/SearchIcon.d.ts +2 -0
  53. package/dist/icons/SortDownIcon.d.ts +2 -0
  54. package/dist/icons/SortUpIcon.d.ts +2 -0
  55. package/dist/icons/YuktaiIcon.d.ts +320 -0
  56. package/dist/icons/index.d.ts +16 -0
  57. package/dist/icons/paths.d.ts +167 -0
  58. package/dist/icons/variant.d.ts +42 -0
  59. package/dist/icons.d.mts +1 -568
  60. package/dist/icons.d.ts +1 -568
  61. package/dist/icons.js +1 -1
  62. package/dist/icons.mjs +1 -1
  63. package/dist/index.d.mts +2 -1337
  64. package/dist/index.d.ts +36 -1315
  65. package/dist/index.js +69 -69
  66. package/dist/index.mjs +42 -42
  67. package/dist/next/YuktAIWrapper.d.ts +2 -0
  68. package/dist/plugins/ai.d.ts +4 -0
  69. package/dist/plugins/voice.d.ts +4 -0
  70. package/dist/plugins/wcag.d.ts +98 -0
  71. package/dist/rag-O3FDQPTX.mjs +1 -0
  72. package/dist/react/CodeGenPanel.d.ts +7 -0
  73. package/dist/react/WidgetPanel.d.ts +38 -0
  74. package/dist/react/YuktAIWrapper.d.ts +35 -0
  75. package/dist/renderer.global.js +23 -23
  76. package/dist/runtime/runtime.d.ts +18 -0
  77. package/package.json +5 -3
  78. package/vanilla/index.js +51 -29
  79. package/vanilla/index.min.js +45 -45
  80. package/dist/agent-G67IA7MY.mjs +0 -18
  81. package/dist/chunk-7BGINZ5U.mjs +0 -1
  82. package/dist/chunk-P2PBML6K.mjs +0 -11
  83. package/dist/rag-Q3LUXSSD.mjs +0 -1
package/README.md CHANGED
@@ -24,8 +24,8 @@ Built in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03).
24
24
  | 📊 | **YuktaiGrid** | Search, sort, pages, CSV export, 5 WCAG themes, Telugu UI, keyboard navigation |
25
25
  | 🤖 | **Ask your data** | "salary over 1 lakh in Hyderabad", BI answers, unusual rows, multi-step tasks, WebMCP |
26
26
  | 💬 | **Ask page (RAG)** | Answers from your page and data, offline |
27
- | 🛠 | **Page tools** | QA audit (15 WCAG checks), form and design review, voice commands |
28
- | 🦀 | **Rust engine** | Up to 42× faster search on big data (optional) |
27
+ | 🛠 | **Page tools** | QA audit (15 WCAG checks), form and design review, voice commands. In React/Next.js: `showPageTools` |
28
+ | 🦀 | **Rust engine** | Up to 42× faster search on big data. The default since 5.3.11 |
29
29
  | 🎨 | **163 icons** | Any size and colour, outline or filled, safe in Server Components |
30
30
  | ⚡ | **Vibe Coder** | Plain English → a full Next.js project ZIP (developer tool) |
31
31
  | 📱 | **PWA** | Installable, works offline |
@@ -33,7 +33,7 @@ Built in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03).
33
33
  ## Supported languages
34
34
 
35
35
  **Use it with:** HTML · JavaScript · TypeScript · React (JSX) · Next.js (TSX)
36
- **Built with:** TypeScript + Rust (WebAssembly, embedded; no setup needed)
36
+ **Built with:** TypeScript 7 + Rust (WebAssembly, embedded; no setup needed)
37
37
  **Interface:** English and Telugu. All 22 Indian languages for number and date formats, sorting and voice input.
38
38
 
39
39
  ---
@@ -43,7 +43,7 @@ Built in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03).
43
43
  **Plain HTML:** one line, no build step
44
44
 
45
45
  ```html
46
- <script src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai@5.3.9/vanilla/index.min.js"></script>
46
+ <script src="https://cdn.jsdelivr.net/npm/@yuktishaalaa/yuktai@5.3.12/vanilla/index.min.js"></script>
47
47
  <script>
48
48
  yuktai.renderGrid("#staff", { data: rows, columns, engine: "auto", showSearchTime: true })
49
49
  </script>
@@ -63,7 +63,7 @@ import type { ReactNode } from "react"
63
63
 
64
64
  export default function YuktaiClient({ children }: { children: ReactNode }) {
65
65
  return (
66
- <YuktAIWrapper position="left" launcher showAccessibility showRag engine="rust">
66
+ <YuktAIWrapper position="left" launcher showAccessibility showRag showPageTools engine="rust">
67
67
  {children}
68
68
  </YuktAIWrapper>
69
69
  )
@@ -100,9 +100,9 @@ More examples for every feature: **https://yuktaidocs.netlify.app/**
100
100
 
101
101
  ---
102
102
 
103
- ## Rust engine (optional)
103
+ ## Rust engine (default)
104
104
 
105
- Set `engine="rust"` or `"auto"`. Results are identical to TypeScript, proven by tests, only faster. If WebAssembly is unavailable, it falls back to TypeScript.
105
+ Since 5.3.11 the grid and page search use Rust by default. Results are identical to TypeScript, proven by tests, only faster. If WebAssembly is unavailable or blocked by a Content Security Policy, they fall back to TypeScript. Set `engine="ts"` to keep TypeScript only, or `"auto"` for Rust from 10,000 rows. The 💬 button uses Rust page search when you set `engine`.
106
106
 
107
107
  | Task | TypeScript | Rust | Speed-up |
108
108
  |---|---|---|---|
@@ -0,0 +1,18 @@
1
+ import{a as T}from"./chunk-N2HHE7YH.mjs";function f(n){try{let a=window.getComputedStyle(n);if(a.display==="none"||a.visibility==="hidden"||a.opacity==="0"||n.hidden)return!1;let t=n.getBoundingClientRect();return!(t.width===0&&t.height===0)}catch{return!0}}function E(){let n=[],a=new Set,t=e=>{let r=e.trim();r&&r.length>10&&!a.has(r)&&(a.add(r),n.push(r))};document.title&&t(document.title);let o=['meta[name="description"]','meta[name="keywords"]','meta[property="og:title"]','meta[property="og:description"]','meta[name="twitter:title"]','meta[name="twitter:description"]'];for(let e of o){let r=document.querySelector(e)?.getAttribute("content");r&&t(r)}let l=["h1","h2","h3","h4","h5","h6","p","blockquote","q","pre","code","li","dt","dd","th","td","caption","a","b","strong","em","i","u","s","abbr","acronym","cite","dfn","mark","small","sub","sup","ins","del","bdi","bdo","article","section","aside","nav","header","footer","main","summary","details","figcaption","figure","address","time","output","label","legend","option","button","font","center","span","div","[role='heading']","[role='main']","[role='article']","[role='region']","[role='complementary']","[role='contentinfo']","[role='navigation']","[role='banner']","[role='listitem']","[role='cell']","[role='columnheader']","[role='rowheader']"],c=document.querySelectorAll(l.join(","));for(let e of c){if(e.closest("[data-yuktai-panel]")||!f(e)||e.querySelector("p, h1, h2, h3, h4, h5, h6, li, td, th, div, article, section, blockquote, pre"))continue;let i=e.innerText?.trim();if(i&&i.length>10&&t(i),!i){let d=e.textContent?.trim();d&&d.length>10&&t(d)}let s=e.getAttribute("aria-label")?.trim();s&&s.length>5&&t(s);let u=e.getAttribute("aria-description")?.trim();u&&u.length>5&&t(u);let m=e.getAttribute("aria-valuetext")?.trim();m&&t(m);let p=e.getAttribute("title")?.trim();p&&p.length>5&&t(p);let b=e.getAttribute("data-label")?.trim();b&&t(b);let y=e.getAttribute("data-title")?.trim();y&&t(y),e.querySelectorAll("img").forEach(d=>{let g=d.getAttribute("alt")?.trim();g&&g.length>5&&t(g);let h=d.getAttribute("title")?.trim();h&&h.length>5&&t(h)})}document.querySelectorAll("img").forEach(e=>{if(e.closest("[data-yuktai-panel]")||!f(e))return;let r=e.getAttribute("alt")?.trim(),i=e.getAttribute("title")?.trim();r&&r.length>5&&t(r),i&&i.length>5&&t(i)}),document.querySelectorAll("input:not([type=hidden]), textarea").forEach(e=>{if(e.closest("[data-yuktai-panel]")||!f(e))return;e.placeholder&&t(e.placeholder),e.value&&e.value.length>3&&t(e.value);let r=e.getAttribute("aria-label")?.trim();r&&t(r)}),document.querySelectorAll("select").forEach(e=>{e.closest("[data-yuktai-panel]")||f(e)&&Array.from(e.options).forEach(r=>{r.text?.trim().length>3&&t(r.text.trim())})}),document.querySelectorAll("td, th").forEach(e=>{if(e.closest("[data-yuktai-panel]")||!f(e))return;let r=e.innerText?.trim();r&&r.length>3&&t(r)});try{document.querySelectorAll("iframe").forEach(e=>{try{let r=e.contentDocument;if(!r)return;let i=r.body?.innerText?.trim();i&&i.length>20&&t(i.slice(0,500))}catch{}})}catch{}return document.querySelectorAll("a").forEach(e=>{if(e.closest("[data-yuktai-panel]")||!f(e))return;let r=e.innerText?.trim();r&&r.length>3&&r.length<100&&t(r)}),n.join(" ").slice(0,5e3)}function x(n){let a=n.getAttribute("aria-label")?.trim();if(a)return a;let t=n.getAttribute("aria-labelledby");if(t){let i=document.getElementById(t);if(i)return i.innerText?.trim()||""}if(n.id){let i=document.querySelector(`label[for="${n.id}"]`);if(i)return i.innerText?.trim()||""}let o=n.closest("label");if(o){let i=o.cloneNode(!0);return i.querySelectorAll("input, select, textarea").forEach(s=>s.remove()),i.innerText?.trim()||""}if((n instanceof HTMLInputElement||n instanceof HTMLTextAreaElement)&&n.placeholder)return n.placeholder;if(n.name)return n.name.replace(/[_-]/g," ");let l=n.previousSibling;if(l?.nodeType===Node.TEXT_NODE){let i=l.textContent?.trim();if(i&&i.length>1)return i}let c=n.previousElementSibling;if(c){let i=c.innerText?.trim();if(i&&i.length>1&&i.length<60)return i}let e=n.closest("td, th");if(e){let i=e.previousElementSibling;if(i){let s=i.innerText?.trim();if(s&&s.length>1)return s}}let r=n.getAttribute("title")?.trim();return r||(n instanceof HTMLInputElement?n.type:"field")}function L(){let n=[],a=document.querySelectorAll(["input:not([type=hidden])","input:not([type=submit])","input:not([type=button])","input:not([type=reset])","input:not([type=image])","select","textarea","[contenteditable='true']","[role='textbox']","[role='combobox']","[role='spinbutton']","[role='searchbox']","[role='listbox']"].join(", "));for(let t of a){if(t.closest("[data-yuktai-panel]")||!f(t))continue;if(t instanceof HTMLInputElement){let l=t.type.toLowerCase();if(["submit","button","reset","image"].includes(l))continue}let o=x(t);n.push({label:o,type:t instanceof HTMLInputElement?t.type:t.tagName.toLowerCase(),placeholder:(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)&&t.placeholder||"",required:t.required||t.getAttribute("aria-required")==="true"||t.getAttribute("data-required")==="true",element:t})}return n}function A(n,a=3e3){n.scrollIntoView({behavior:"smooth",block:"center"}),n.style.outline="3px solid #0d9488",n.style.outlineOffset="3px";try{n.focus()}catch{}setTimeout(()=>{n.style.outline="",n.style.outlineOffset=""},a)}function M(n){let a=n.toLowerCase(),t=document.querySelectorAll("h1, h2, h3, h4, h5, h6, section, article, [id], [aria-label], [role='heading'], [role='region']");for(let o of t){if(o.closest("[data-yuktai-panel]")||!f(o))continue;if((o.innerText||o.getAttribute("id")||o.getAttribute("aria-label")||o.getAttribute("name")||"").toLowerCase().includes(a))return o.scrollIntoView({behavior:"smooth",block:"center"}),o.style.outline="2px solid #0d9488",o.style.outlineOffset="4px",setTimeout(()=>{o.style.outline="",o.style.outlineOffset=""},2500),!0}return!1}async function H(n,a,t){let o=window,l=o.LanguageModel||o.ai?.languageModel;if(!l)throw new Error("Gemini Nano not available");let c=await l.create({...T,systemPrompt:`You are a helpful web accessibility agent.
2
+ Create a simple action plan to help a user complete a task on a webpage.
3
+ Rules:
4
+ - Maximum 5 steps
5
+ - Short and clear \u2014 no jargon
6
+ - If filling a form \u2014 list each field and what to enter
7
+ - No markdown \u2014 no asterisks, no bold, no headers
8
+ - Number each step: 1. 2. 3.`}),r=`Page content: ${n}${t?`
9
+ The page has form fields the user may need to fill.`:""}
10
+
11
+ User task: ${a}
12
+
13
+ Action plan:`,i=await c.prompt(r);return c.destroy(),i?.trim()||""}async function w(n,a){let{askPageWithTransformers:t}=await import("./transformers-rag-MQZRMFTG.mjs");return(await t(`How do I: ${a}`)).answer||"I could not create a plan for this task."}async function q(n,a,t){if(!n.trim())return{success:!1,steps:[],error:"Please tell me what you want to do."};if(!a)return{success:!1,steps:[],error:"No AI engine available on this device."};let o=[],l=(c,e="info")=>{let r={text:c,type:e};o.push(r),t(r)};try{l("\u{1F4D6} Reading page content...","info");let c=E(),e=L(),r=e.length>0;c.length<50&&l("\u26A0\uFE0F Page content is very limited. This may be a static image page.","error"),l(r?`\u{1F4CB} Found ${e.length} form field${e.length!==1?"s":""} on this page`:"\u{1F4C4} No form fields found \u2014 this appears to be a content page","info"),l("\u{1F916} Creating action plan...","info");let i="";try{a==="gemini"?i=await H(c,n,r):i=await w(c,n)}catch{i=r?`1. Locate the form on this page
14
+ 2. Fill each required field
15
+ 3. Review your answers
16
+ 4. Submit the form`:`1. Read the page carefully
17
+ 2. Find the section relevant to your task
18
+ 3. Follow the on-page instructions`}if(i&&(l("\u2705 Your action plan:","success"),i.split(/\n/).map(s=>s.replace(/\*\*/g,"").replace(/\*/g,"").trim()).filter(s=>s.length>5).slice(0,6).forEach(s=>l(` ${s}`,"action"))),r){let s=e[0];l(`\u{1F3AF} First field: "${s.label}"${s.required?" \u2605 required":""}`,"field"),A(s.element),e.length>1&&l(`\u{1F4DD} All ${e.length} fields: ${e.map(u=>u.label).join(" \u2192 ")}`,"info")}else{let s=n.toLowerCase().split(/\s+/).filter(m=>m.length>3),u=!1;for(let m of s)if(M(m)){l(`\u{1F3AF} Scrolled to relevant section: "${m}"`,"action"),u=!0;break}u||l("\u{1F4A1} Scroll through the page to find what you need.","info")}return l("\u2705 Ready. Follow the steps above. Ask me again if you need more help.","success"),{success:!0,steps:o}}catch(c){let e=c instanceof Error?c.message:"Agent error.";return l(`\u26A0\uFE0F ${e}`,"error"),{success:!1,steps:o,error:e}}}export{E as getPageText,A as highlightField,q as runAgent,L as scanFormFields,M as scrollToSection};
@@ -0,0 +1,32 @@
1
+ import { type AuditOptions, type AuditReport } from "./qaAudit";
2
+ export interface CopilotFixResult {
3
+ issueId: string;
4
+ applied: boolean;
5
+ message: string;
6
+ }
7
+ export interface CopilotState {
8
+ report: AuditReport | null;
9
+ watching: boolean;
10
+ appliedFixes: number;
11
+ }
12
+ export interface A11yCopilotOptions extends AuditOptions {
13
+ /** Called after every scan (initial, manual or caused by DOM changes). */
14
+ onUpdate?: (state: CopilotState) => void;
15
+ /** Wait this long after DOM changes before rescanning (default 600ms). */
16
+ debounceMs?: number;
17
+ /** Apply every safe fix automatically after each scan (default false). */
18
+ autoApply?: boolean;
19
+ /** Language used when the page has no lang attribute (default: browser language). */
20
+ defaultLang?: string;
21
+ }
22
+ export interface A11yCopilot {
23
+ start(): void;
24
+ stop(): void;
25
+ scan(): AuditReport;
26
+ explain(issueId: string): string;
27
+ applyFix(issueId: string): CopilotFixResult;
28
+ applyAllFixes(): CopilotFixResult[];
29
+ undoAll(): number;
30
+ getState(): CopilotState;
31
+ }
32
+ export declare function createA11yCopilot(options?: A11yCopilotOptions): A11yCopilot;
@@ -0,0 +1,58 @@
1
+ import type { GridToolColumn } from "../grid/gridTools";
2
+ import { type AuditRoot } from "./dom";
3
+ import type { GridEngine } from "../grid/rust/engine";
4
+ export interface ContextPassage {
5
+ id: string;
6
+ source: "page" | "grid" | "custom";
7
+ text: string;
8
+ /** Grid row id or page section heading. */
9
+ ref?: string;
10
+ }
11
+ export interface ContextHit extends ContextPassage {
12
+ score: number;
13
+ }
14
+ export interface ContextAnswer {
15
+ answer: string;
16
+ hits: ContextHit[];
17
+ /** True when `generate` produced the answer; false for extractive answers. */
18
+ generated: boolean;
19
+ }
20
+ /** Unicode-aware tokens: keeps Telugu/Devanagari combining marks together. */
21
+ export declare function tokenize(text: string): string[];
22
+ export declare function pagePassages(root?: AuditRoot, maxChars?: number): ContextPassage[];
23
+ export declare function gridPassages<T>(data: T[], columns: GridToolColumn[], rowKey?: string): ContextPassage[];
24
+ export interface ContextIndexOptions<T = Record<string, unknown>> {
25
+ /** Index the visible page text (default true). */
26
+ includePage?: boolean;
27
+ root?: AuditRoot;
28
+ rows?: T[];
29
+ columns?: GridToolColumn[];
30
+ rowKey?: string;
31
+ /** Extra documents, e.g. FAQ text or help articles. */
32
+ documents?: Array<{
33
+ id: string;
34
+ text: string;
35
+ }>;
36
+ /**
37
+ * Search engine: "rust" (default since v5.3.11), "auto" (Rust from 1,000
38
+ * passages) or "ts". Same passages, same scores, same order; Rust is faster
39
+ * on long pages and big grids. Works offline (the engine is embedded) and
40
+ * falls back to TypeScript when WebAssembly is missing or blocked.
41
+ */
42
+ engine?: GridEngine;
43
+ }
44
+ export declare function createContextIndex<T>(input?: ContextIndexOptions<T>): {
45
+ search: (question: string, k?: number) => ContextHit[];
46
+ ask: (question: string, opts?: {
47
+ k?: number;
48
+ generate?: (question: string, context: string) => Promise<string>;
49
+ }) => Promise<ContextAnswer>;
50
+ /** Call after the page or data changes. */
51
+ rebuild: () => void;
52
+ update(next: Partial<ContextIndexOptions<T>>): void;
53
+ size: () => number;
54
+ /** "rust" when the Rust engine answers searches for this index, else "ts". */
55
+ readonly engine: "rust" | "ts";
56
+ /** Resolves "rust" or "ts" once the engine is loaded (or not wanted). */
57
+ whenEngineReady: () => Promise<"rust" | "ts">;
58
+ };
@@ -0,0 +1,26 @@
1
+ import { type AuditRoot } from "./dom";
2
+ export type DesignCategory = "hierarchy" | "readability" | "interaction" | "clutter" | "consistency";
3
+ export interface DesignFinding {
4
+ category: DesignCategory;
5
+ severity: "high" | "medium" | "low";
6
+ message: string;
7
+ suggestion: string;
8
+ selector?: string;
9
+ }
10
+ export interface DesignReview {
11
+ score: number;
12
+ categories: Record<DesignCategory, {
13
+ score: number;
14
+ findings: number;
15
+ }>;
16
+ findings: DesignFinding[];
17
+ summary: string;
18
+ }
19
+ export interface DesignReviewOptions {
20
+ root?: AuditRoot;
21
+ /** Minimum body text size in px (default 14; 16 recommended for seniors). */
22
+ minFontSize?: number;
23
+ /** Maximum comfortable line length in characters (default 90). */
24
+ maxLineLength?: number;
25
+ }
26
+ export declare function reviewDesign(options?: DesignReviewOptions): DesignReview;
@@ -0,0 +1,42 @@
1
+ /** Elements inside yuktai's own panels are never audited or read. */
2
+ /** YuktAI's own UI: panels, floating buttons (React data-yuktai-ui, vanilla data-yuktai-fabs). Audits skip it. */
3
+ export declare const YUKTAI_IGNORE = "[data-yuktai-panel],[data-yuktai-ui],[data-yuktai-fabs]";
4
+ export type AuditRoot = Document | Element;
5
+ export declare function isBrowser(): boolean;
6
+ /** Works across frames/realms, unlike `instanceof Document`. */
7
+ export declare function isDocument(node: unknown): node is Document;
8
+ export declare function resolveRoot(root?: AuditRoot | null): AuditRoot | null;
9
+ /** querySelectorAll that skips yuktai's own UI and hidden elements. */
10
+ export declare function queryAll<T extends Element = Element>(root: AuditRoot, selector: string, options?: {
11
+ includeHidden?: boolean;
12
+ }): T[];
13
+ export declare function isVisible(el: Element): boolean;
14
+ /** Collapse whitespace and trim. */
15
+ export declare function cleanText(text: string | null | undefined): string;
16
+ export declare function shorten(text: string, max?: number): string;
17
+ /** A short, readable CSS path such as `main > form:nth-of-type(2) > input`. */
18
+ export declare function selectorFor(el: Element): string;
19
+ /** The label a screen reader would most likely announce for this element. */
20
+ export declare function accessibleName(el: Element): string;
21
+ export type RGBA = {
22
+ r: number;
23
+ g: number;
24
+ b: number;
25
+ a: number;
26
+ };
27
+ export declare function parseColor(value: string | null | undefined): RGBA | null;
28
+ /** Paint `top` over `bottom` (simple alpha compositing). */
29
+ export declare function blend(top: RGBA, bottom: RGBA): RGBA;
30
+ export declare function relativeLuminance(c: RGBA): number;
31
+ export declare function contrastRatio(fg: RGBA, bg: RGBA): number;
32
+ /**
33
+ * Background actually behind an element: walks up the tree and composites
34
+ * semi-transparent layers over white. Returns null when a background image
35
+ * makes the answer unknowable.
36
+ */
37
+ export declare function effectiveBackground(el: Element): RGBA | null;
38
+ export declare function isLargeText(el: Element): boolean;
39
+ /** True when the element has its own visible text (not only inside children). */
40
+ export declare function hasDirectText(el: Element): boolean;
41
+ export declare const FOCUSABLE = "a[href],button,input:not([type='hidden']),select,textarea,summary,[tabindex]:not([tabindex='-1']),[contenteditable='true']";
42
+ export declare const INTERACTIVE = "a[href],button,input:not([type='hidden']),select,textarea,summary,[role='button'],[role='link'],[role='checkbox'],[role='tab'],[role='menuitem']";
@@ -0,0 +1,38 @@
1
+ import { type AuditRoot } from "./dom";
2
+ export type FormFindingLevel = "problem" | "improvement";
3
+ export interface FormField {
4
+ label: string;
5
+ type: string;
6
+ name: string;
7
+ required: boolean;
8
+ hasVisibleLabel: boolean;
9
+ selector: string;
10
+ element: Element;
11
+ }
12
+ export interface FormFinding {
13
+ level: FormFindingLevel;
14
+ message: string;
15
+ suggestion: string;
16
+ field?: string;
17
+ selector?: string;
18
+ }
19
+ export interface FormReview {
20
+ name: string;
21
+ selector: string;
22
+ fields: FormField[];
23
+ findings: FormFinding[];
24
+ /** 0–100, higher is easier to complete. */
25
+ score: number;
26
+ summary: string;
27
+ }
28
+ export interface FormReviewOptions {
29
+ root?: AuditRoot;
30
+ /** Extra checks for older users: font size, field count, vague buttons (default true). */
31
+ seniorFriendly?: boolean;
32
+ /** Forms with more fields than this get a "split into steps" suggestion (default 8). */
33
+ maxFieldsPerStep?: number;
34
+ }
35
+ export declare function readFormFields(form: Element): FormField[];
36
+ export declare function reviewForm(form: Element, options?: FormReviewOptions): FormReview;
37
+ /** Reviews every <form> (and every role="form") on the page. */
38
+ export declare function reviewForms(options?: FormReviewOptions): FormReview[];
@@ -0,0 +1,64 @@
1
+ import { type GridToolColumn, type GridToolContext, type GridToolFilter, type GridToolSort } from "../grid/gridTools";
2
+ export interface ParsedGridQuery {
3
+ filters: GridToolFilter[];
4
+ /** Free-text terms that didn't map to a column; matched across all columns. */
5
+ search: string[];
6
+ sort: GridToolSort | null;
7
+ limit: number | null;
8
+ /** Assumptions the parser made (shown to the user so they can correct it). */
9
+ notes: string[];
10
+ /** Plain-English reading of the query. */
11
+ explanation: string;
12
+ }
13
+ export interface GridQueryResult<T> {
14
+ rows: T[];
15
+ ids: string[];
16
+ parsed: ParsedGridQuery;
17
+ message: string;
18
+ }
19
+ type Row = Record<string, unknown>;
20
+ /** "₹10,000" → 10000, "1.5 lakh" → 150000, "2cr" → 20000000, "10k" → 10000. */
21
+ export declare function parseAmount(text: string): number | null;
22
+ /** The column mentioned in `text` (longest name wins), or undefined. */
23
+ export declare function findMentionedColumn(text: string, columns: GridToolColumn[], kind?: GridToolColumn["type"]): GridToolColumn | undefined;
24
+ export interface ParseOptions<T = Row> {
25
+ /** Rows let the parser recognise values like "overdue" in a Status column. */
26
+ data?: T[];
27
+ }
28
+ export declare function parseGridQuery<T = Row>(query: string, columns: GridToolColumn[], options?: ParseOptions<T>): ParsedGridQuery;
29
+ /** Runs a parsed query over rows without touching any UI. */
30
+ export declare function executeGridQuery<T>(data: T[], columns: GridToolColumn[], parsed: ParsedGridQuery): T[];
31
+ /**
32
+ * Parses and runs a natural-language query, then pushes the result into the
33
+ * grid through the context callbacks (filters, sort, highlight).
34
+ */
35
+ export declare function runGridQuery<T>(query: string, context: GridToolContext<T>, options?: {
36
+ apply?: boolean;
37
+ }): GridQueryResult<T>;
38
+ export interface GridAnomaly {
39
+ rowId: string;
40
+ column: string;
41
+ label: string;
42
+ value: unknown;
43
+ kind: "high" | "low" | "duplicate";
44
+ reason: string;
45
+ }
46
+ /**
47
+ * Finds unusual rows: numeric values far outside the typical range
48
+ * (interquartile-range rule) and rows that duplicate another row.
49
+ */
50
+ export declare function detectAnomalies<T>(data: T[], columns: GridToolColumn[], options?: {
51
+ rowKey?: string;
52
+ factor?: number;
53
+ columns?: string[];
54
+ }): GridAnomaly[];
55
+ export declare function summarizeRows<T>(rows: T[], columns: GridToolColumn[]): string;
56
+ export interface GridAnswer<T> {
57
+ kind: "query" | "anomalies" | "summary";
58
+ message: string;
59
+ ids: string[];
60
+ rows: T[];
61
+ anomalies?: GridAnomaly[];
62
+ }
63
+ export declare function answerGridQuestion<T>(question: string, context: GridToolContext<T>): GridAnswer<T>;
64
+ export {};
@@ -0,0 +1,13 @@
1
+ export * from "./a11yCopilot";
2
+ export * from "./pageInsights";
3
+ export * from "./gridQuery";
4
+ export * from "./voiceA11yCommands";
5
+ export * from "./qaAudit";
6
+ export * from "./formReview";
7
+ export * from "./contextIndex";
8
+ export * from "./taskRunner";
9
+ export * from "./insights";
10
+ export * from "./designReview";
11
+ export * from "./react";
12
+ export { contrastRatio, parseColor, relativeLuminance, accessibleName } from "./dom";
13
+ export type { RGBA, AuditRoot } from "./dom";
@@ -0,0 +1,62 @@
1
+ import type { GridToolColumn } from "../grid/gridTools";
2
+ export type Aggregation = "sum" | "avg" | "count" | "min" | "max";
3
+ export type Period = "day" | "week" | "month" | "quarter" | "year";
4
+ export interface GroupResult {
5
+ group: string;
6
+ value: number;
7
+ count: number;
8
+ }
9
+ export interface PeriodChange {
10
+ group: string;
11
+ current: number;
12
+ previous: number;
13
+ change: number;
14
+ /** null when the previous value was 0 */
15
+ changePct: number | null;
16
+ }
17
+ export interface PeriodComparison {
18
+ period: Period;
19
+ current: {
20
+ from: Date;
21
+ to: Date;
22
+ };
23
+ previous: {
24
+ from: Date;
25
+ to: Date;
26
+ };
27
+ rows: PeriodChange[];
28
+ }
29
+ export declare function aggregate(values: number[], agg: Aggregation): number;
30
+ /** Groups rows by a column and aggregates a metric (or counts rows). Sorted high → low. */
31
+ export declare function groupBy<T>(data: T[], groupKey: string, metricKey: string | null, agg?: Aggregation): GroupResult[];
32
+ export declare function startOfPeriod(date: Date, period: Period, weekStartsOn?: number): Date;
33
+ export declare function addPeriods(date: Date, period: Period, n: number): Date;
34
+ export interface ComparePeriodsOptions {
35
+ dateKey: string;
36
+ metricKey: string;
37
+ groupKey?: string;
38
+ agg?: Aggregation;
39
+ period: Period;
40
+ /** "Now" for the comparison (default: today). */
41
+ referenceDate?: Date | string;
42
+ /**
43
+ * true (default): compare the same elapsed time — e.g. Mon–Wed this week
44
+ * vs Mon–Wed last week — so a half-finished week doesn't look like a drop.
45
+ */
46
+ toDate?: boolean;
47
+ weekStartsOn?: number;
48
+ }
49
+ export declare function comparePeriods<T>(data: T[], o: ComparePeriodsOptions): PeriodComparison;
50
+ /** Time series: one aggregated value per period, oldest first. */
51
+ export declare function trend<T>(data: T[], dateKey: string, metricKey: string, period: Period, agg?: Aggregation): Array<{
52
+ start: Date;
53
+ value: number;
54
+ }>;
55
+ export interface InsightAnswer {
56
+ kind: "period-change" | "group" | "trend" | "total" | "unknown";
57
+ answer: string;
58
+ table: Array<Record<string, string | number>>;
59
+ }
60
+ export declare function askInsight<T>(question: string, data: T[], columns: GridToolColumn[], options?: {
61
+ referenceDate?: Date | string;
62
+ }): InsightAnswer;
@@ -0,0 +1,47 @@
1
+ import { type AuditRoot } from "./dom";
2
+ export interface PageOutline {
3
+ title: string;
4
+ description: string;
5
+ language: string;
6
+ headings: Array<{
7
+ level: number;
8
+ text: string;
9
+ }>;
10
+ landmarks: Record<string, number>;
11
+ counts: {
12
+ links: number;
13
+ buttons: number;
14
+ images: number;
15
+ forms: number;
16
+ tables: number;
17
+ fields: number;
18
+ };
19
+ unlabeledFields: Array<{
20
+ type: string;
21
+ hint: string;
22
+ selector: string;
23
+ }>;
24
+ imagesWithoutAlt: Array<{
25
+ src: string;
26
+ selector: string;
27
+ }>;
28
+ purpose: string;
29
+ }
30
+ export interface PageAnswer {
31
+ intent: PageIntent;
32
+ answer: string;
33
+ /** Elements the answer refers to, so the UI can highlight them. */
34
+ targets: string[];
35
+ suggestions: string[];
36
+ }
37
+ export type PageIntent = "purpose" | "missing-labels" | "images" | "structure" | "forms" | "links" | "counts" | "unknown";
38
+ export declare function analyzePage(root?: AuditRoot): PageOutline;
39
+ export declare function detectPageIntent(question: string): PageIntent;
40
+ /**
41
+ * Answers a question about the current page.
42
+ * @param summarize Optional hook (e.g. Gemini Nano or your own model) used for "purpose" questions.
43
+ */
44
+ export declare function askAboutPage(question: string, options?: {
45
+ root?: AuditRoot;
46
+ summarize?: (pageText: string) => Promise<string>;
47
+ }): Promise<PageAnswer>;
@@ -0,0 +1,59 @@
1
+ import { type AuditRoot } from "./dom";
2
+ export type AuditSeverity = "critical" | "serious" | "moderate" | "minor";
3
+ export type AuditRuleId = "html-lang" | "page-title" | "image-alt" | "heading-order" | "single-h1" | "landmark-main" | "form-label" | "button-name" | "link-name" | "color-contrast" | "positive-tabindex" | "keyboard-access" | "duplicate-id" | "form-error" | "target-size";
4
+ export interface AuditIssue {
5
+ /** Stable within one report, e.g. "image-alt-3". */
6
+ id: string;
7
+ rule: AuditRuleId;
8
+ severity: AuditSeverity;
9
+ /** WCAG success criterion, e.g. "1.1.1", or "best practice". */
10
+ wcag: string;
11
+ message: string;
12
+ /** Why it matters, in plain English. */
13
+ why: string;
14
+ /** What to change. */
15
+ fix: string;
16
+ selector: string;
17
+ snippet: string;
18
+ /** True when the copilot can apply a safe fix in the browser. */
19
+ autoFixable: boolean;
20
+ element?: Element;
21
+ }
22
+ export interface AuditCheck {
23
+ rule: AuditRuleId;
24
+ title: string;
25
+ passed: boolean;
26
+ issueCount: number;
27
+ }
28
+ export interface AuditReport {
29
+ url: string;
30
+ title: string;
31
+ generatedAt: string;
32
+ score: number;
33
+ passed: boolean;
34
+ checks: AuditCheck[];
35
+ issues: AuditIssue[];
36
+ summary: string;
37
+ }
38
+ export interface AuditOptions {
39
+ root?: AuditRoot;
40
+ /** Skip rules you don't need. */
41
+ skip?: AuditRuleId[];
42
+ /** Cap contrast checks on very large pages (default 600 elements). */
43
+ maxContrastChecks?: number;
44
+ /** Minimum interactive target size in CSS px (WCAG 2.5.8 uses 24). */
45
+ minTargetSize?: number;
46
+ }
47
+ interface RuleInfo {
48
+ title: string;
49
+ wcag: string;
50
+ severity: AuditSeverity;
51
+ why: string;
52
+ }
53
+ export declare const AUDIT_RULES: Record<AuditRuleId, RuleInfo>;
54
+ export declare function runQaAudit(options?: AuditOptions): AuditReport;
55
+ /** Markdown report you can download, paste into a ticket or attach to a PR. */
56
+ export declare function auditToMarkdown(report: AuditReport): string;
57
+ /** JSON without DOM references, safe to store or send to a server. */
58
+ export declare function auditToJSON(report: AuditReport): string;
59
+ export {};
@@ -0,0 +1,52 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type GridToolFilter, type GridToolSort } from "../grid/gridTools";
3
+ import type { GridEngine } from "../grid/rust/engine";
4
+ import { type StepResult } from "./taskRunner";
5
+ export interface UseAgenticGridOptions<T> {
6
+ data: T[];
7
+ columns: Array<{
8
+ key: string;
9
+ label: string;
10
+ type?: string;
11
+ }>;
12
+ rowKey?: string;
13
+ /** "Now" for questions like "this week" (default: today). */
14
+ referenceDate?: Date | string;
15
+ onOpenRow?: (id: string) => void;
16
+ }
17
+ export type AgenticAnswerKind = "query" | "anomalies" | "summary" | "insight" | "tasks";
18
+ export declare function useAgenticGrid<T extends Record<string, unknown>>(options: UseAgenticGridOptions<T>): {
19
+ /** Pass to <YuktaiGrid data={…}> */
20
+ gridData: T[];
21
+ /** Pass to <YuktaiGrid highlightIds={…}> */
22
+ highlightIds: string[];
23
+ filters: GridToolFilter[];
24
+ sort: GridToolSort | null;
25
+ ask: (question: string) => Promise<void>;
26
+ reset: () => void;
27
+ answer: string;
28
+ kind: AgenticAnswerKind | null;
29
+ table: Record<string, string | number>[];
30
+ steps: StepResult[];
31
+ busy: boolean;
32
+ visibleIds: string[];
33
+ };
34
+ export declare function AgenticGridBar({ grid, placeholder, examples, style, }: {
35
+ grid: ReturnType<typeof useAgenticGrid<any>>;
36
+ placeholder?: string;
37
+ examples?: string[];
38
+ style?: CSSProperties;
39
+ }): import("react").JSX.Element;
40
+ type Tab = "copilot" | "qa" | "forms" | "design" | "ask" | "voice";
41
+ export interface AgenticPanelProps {
42
+ defaultTab?: Tab;
43
+ /** Speech recognition language for the Voice tab (default "en-IN"). */
44
+ voiceLang?: string;
45
+ /** Optional model hook for Ask page, e.g. Gemini Nano or your own API. */
46
+ generate?: (question: string, context: string) => Promise<string>;
47
+ /** Ask page search engine: "rust" (default since v5.3.11), "auto" or "ts". Same answers; Rust is faster on long pages. */
48
+ engine?: GridEngine;
49
+ style?: CSSProperties;
50
+ }
51
+ export declare function AgenticPanel({ defaultTab, voiceLang, generate, engine, style }: AgenticPanelProps): import("react").JSX.Element;
52
+ export {};
@@ -0,0 +1,3 @@
1
+ /** yuktai rag-core WebAssembly (32925 bytes), base64. */
2
+ export declare const RAG_CORE_WASM_BASE64: string;
3
+ export declare const RAG_CORE_WASM_SIZE = 32925;
@@ -0,0 +1,32 @@
1
+ import { type GridEngine } from "../../grid/rust/engine";
2
+ /** `engine: "auto"` switches the RAG search to Rust from this many passages. */
3
+ export declare const RAG_AUTO_MIN_PASSAGES = 1000;
4
+ export declare function wantsRustRag(engine: GridEngine | undefined, passages: number): boolean;
5
+ /** Compiles the RAG engine once per page; resolves null without WebAssembly. */
6
+ export declare function loadRagCore(): Promise<WebAssembly.Module | null>;
7
+ export declare function getLoadedRagCore(): WebAssembly.Module | null;
8
+ export interface RagHit {
9
+ /** Passage position, as given to build() */
10
+ doc: number;
11
+ score: number;
12
+ }
13
+ /** One index per RagCore (each has its own WebAssembly memory). */
14
+ export declare class RagCore {
15
+ private readonly x;
16
+ private readonly encoder;
17
+ private docs;
18
+ private ready;
19
+ private constructor();
20
+ static create(mod?: WebAssembly.Module | null): RagCore | null;
21
+ /**
22
+ * Indexes the passages: one array of tokenize() words per passage.
23
+ * Returns false if Rust could not take it (TypeScript is then used).
24
+ */
25
+ build(docs: string[][]): boolean;
26
+ /**
27
+ * Best passages for the question words `terms` (tokenize() output), with
28
+ * `idf[i]` per word and `avgDiv` = average passage length (or 1).
29
+ * Null means "use TypeScript".
30
+ */
31
+ search(terms: string[], idf: number[], avgDiv: number, k: number): RagHit[] | null;
32
+ }