@yuktishaalaa/yuktai 5.0.0 → 5.1.0

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.
package/README.md CHANGED
@@ -1,121 +1,93 @@
1
1
  # @yuktishaalaa/yuktai
2
2
 
3
- > Universal Next.js plugin for accessibility, AI, and data. One install brings WCAG 2.2 auto-fix, in-browser RAG, an AI agent, code generation, and an accessible data grid with Agentic AI + WebMCP — zero API keys, zero cost, works offline.
3
+ > Universal Next.js plugin for accessibility, AI, and data. One install brings WCAG 2.2 auto-fix, in-browser RAG, an AI agent, code generation, and an accessible data grid with Agentic AI + WebMCP. Zero API keys, zero cost, works offline.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
6
-
7
6
  [![downloads](https://img.shields.io/npm/dm/@yuktishaalaa/yuktai)](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
8
-
9
7
  [![license](https://img.shields.io/badge/license-ISC-brightgreen)](./LICENSE)
10
-
11
8
  [![node](https://img.shields.io/badge/node-%3E%3D18-blue)](https://nodejs.org)
9
+ [![Next.js](https://img.shields.io/badge/Next.js-13%2B-black)](https://nextjs.org)
12
10
 
13
- [![Next.js](https://img.shields.io/badge/Next.js-16%2B-black)](https://nextjs.org)
11
+ **7,000+ developers** have already installed yuktai. Built entirely in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03).
14
12
 
15
- **7,000+ developers** already installed yuktai. Built entirely in free time by [Sandeep Miriyala](https://github.com/sandeepmiriyala03) with help from Claude, GPT, and Gemini.
16
-
17
- Live demo → [https://aksharatantra.miriyala.in/staffdirectory](https://aksharatantra.miriyala.in/staffdirectory)
13
+ **Live demos:**
14
+ - Staff directory: https://aksharatantra.miriyala.in/staffdirectory
15
+ - Ratnalabala, a Telugu poetry app built on YuktAI Grid: https://ratnalabala.vercel.app/poems?view=grid
18
16
 
19
17
  ---
20
18
 
21
19
  ## The story
22
20
 
23
- I have been building web apps since 2013. In all those years the same things kept breaking on almost every website I touched. Missing ARIA labels. No keyboard navigation. Forms that senior citizens couldn't figure out. Data grids that broke on mobile. Accessibility tools that cost money. AI tools that needed API keys.
24
-
25
- I wanted something without any of those barriers.
21
+ I have been building web apps since 2013. In all those years, the same things kept breaking on almost every website I touched: missing ARIA labels, no keyboard navigation, forms that senior citizens couldn't figure out, data grids that broke on mobile, accessibility tools that cost money, and AI tools that needed API keys.
26
22
 
27
- Free. Open source. One install. Works on every device. No account. No key. No server.
23
+ I wanted something without any of those barriers. Free. Open source. One install. Works on every device. No account. No key. No server.
28
24
 
29
- So I built yuktai — one weekend and one late-night at a time. This README is the map of everything that shipped.
25
+ So I built yuktai, one weekend and one late night at a time.
30
26
 
31
27
  ---
32
28
 
33
29
  ## What's inside
34
30
 
35
- Five modules ship in the single npm package:
31
+ Five modules ship in a single npm package:
36
32
 
37
33
  | Module | Features | What it does |
38
-
39
34
  |---|---|---|
40
-
41
35
  | **1. Accessibility Engine** | 16 | WCAG 2.2 auto-fix, speak on focus, colour-blind modes, dyslexia font, skip links |
42
-
43
- | **2. YuktaiGrid** ⭐ NEW | 12 | Accessible data grid with 5 WCAG themes, search, sort, pagination, mobile card view |
44
-
45
- | **3. In-Tab RAG** | 11 | Ask questions about any page — offline, no API |
46
-
47
- | **4. Autonomous AI Agent** | 13 | Natural-language browser automation |
48
-
36
+ | **2. YuktaiGrid** ⭐ | 19 | Accessible data grid with Agentic AI, WebMCP, 5 WCAG themes, English/Telugu UI |
37
+ | **3. In-Tab RAG** | 11 | Ask questions about any page, offline, no API |
38
+ | **4. Autonomous AI Agent** | 13 | Natural-language browser guidance |
49
39
  | **5. Vibe Coder** | 19 | Generate full Next.js projects from plain English |
50
40
 
51
- Plus Grid Assistant capabilities, Grid Agent tools, WebMCP integration, 7 custom SVG icons, and a voice + chat assistant.
52
-
53
41
  ---
54
42
 
55
- ## What's new
56
-
57
- ### v4.6.4 — YuktaiGrid Agentic AI + WebMCP
58
-
59
- YuktaiGrid now brings Grid UI, Grid AI Assistant, reusable Grid Tools, Agent execution, and WebMCP registration together.
60
-
61
- - Shared Grid Tools for Agent and WebMCP execution
62
-
63
- - Search grid rows
64
-
65
- - Count grid rows
66
-
67
- - Get grid columns
68
-
69
- - Get a row by ID
70
-
71
- - Highlight rows
72
-
73
- - Select a row
74
-
75
- - Open a row
76
-
77
- - WebMCP registration through document.modelContext
78
-
79
- - useYuktaiGridAgent for programmatic Grid tool execution
43
+ ## What's new in v4.6.4: YuktaiGrid Agentic AI + WebMCP
80
44
 
45
+ - Shared Grid Tools used by both the Agent and WebMCP
46
+ - Tools: search, count, columns, get row, highlight, select, open
47
+ - WebMCP registration through `document.modelContext`
48
+ - `useYuktaiGridAgent` hook for programmatic tool execution
81
49
  - Embedded Grid AI Assistant inside YuktaiGrid
50
+ - English and Telugu AI UI, with English or Telugu voice input
51
+ - Working page-size switching (10 → 20 → 50 → 100)
52
+ - Seven inline SVG icons, no external icon dependency
82
53
 
83
- - English and Telugu AI UI
84
-
85
- - English voice input by default with Telugu voice-input support
86
-
87
- - language, inputLanguage, and embedded AI options
54
+ **Architecture:** User → Agent / WebMCP → Grid Tools → YuktaiGrid → Data
88
55
 
89
- - Functional page-size switching such as 10 → 20 → 50 → 100
90
-
91
- - Inline SVG Grid icons with no external icon dependency
92
-
93
- - Public seven-icon package API
56
+ ---
94
57
 
95
- Architecture: User → Agent → WebMCP → YuktaiGrid → Data
58
+ ## Works on every device
96
59
 
97
- ### v4.6.3
60
+ | Device | Browser | Core features | AI engine |
61
+ |---|---|---|---|
62
+ | 🖥 Desktop | Chrome 147+ | ✅ All | Gemini Nano |
63
+ | 🖥 Desktop | Firefox / Edge / Safari | ✅ All | Transformers.js |
64
+ | 📱 Android | Chrome Mobile | ✅ All | Transformers.js |
65
+ | 📱 iOS | Safari Mobile | ✅ All | Transformers.js |
66
+ | 📲 PWA offline | All browsers | ✅ All | Offline after first load |
98
67
 
99
- Previous published release before the v4.6.4 Grid fixes and polish.
68
+ yuktai picks the best AI engine automatically. Users never need to know which one is running.
100
69
 
101
70
  ---
102
71
 
103
72
  ## Install
104
73
 
105
- ### Next.js 16 + React 19 (recommended)
74
+ **Next.js 16 + React 19 (recommended)**
106
75
 
107
76
  ```bash
108
-
109
77
  npm install @yuktishaalaa/yuktai --legacy-peer-deps
110
-
111
78
  ```
112
79
 
113
- ### Older Next.js (13, 14, 15)
80
+ **Next.js 13, 14, 15**
114
81
 
115
82
  ```bash
116
-
117
83
  npm install @yuktishaalaa/yuktai
84
+ ```
85
+
86
+ **Yarn / pnpm**
118
87
 
88
+ ```bash
89
+ yarn add @yuktishaalaa/yuktai
90
+ pnpm add @yuktishaalaa/yuktai
119
91
  ```
120
92
 
121
93
  Requirements: Node.js 18+, npm 8+, Next.js 13+.
@@ -124,771 +96,511 @@ Requirements: Node.js 18+, npm 8+, Next.js 13+.
124
96
 
125
97
  ## Quick start
126
98
 
127
- ### Step 1 — `next.config.js`
99
+ ### Step 1: `next.config.js`
128
100
 
129
101
  ```js
130
-
131
102
  const nextConfig = {
132
-
133
-   transpilePackages: ["@yuktishaalaa/yuktai"],
134
-
103
+ transpilePackages: ["@yuktishaalaa/yuktai"],
104
+ async headers() {
105
+ return [
106
+ {
107
+ source: "/(.*)",
108
+ headers: [
109
+ // Needed for voice control and voice input
110
+ { key: "Permissions-Policy", value: "microphone=*, speaker=*" },
111
+ ],
112
+ },
113
+ ];
114
+ },
135
115
  };
136
116
 
137
117
  module.exports = nextConfig;
138
-
139
118
  ```
140
119
 
141
- ### Step 2 — Client wrapper
120
+ ### Step 2: Client wrapper
142
121
 
143
122
  ```tsx
144
-
145
123
  // components/YuktaiClient.tsx
146
-
147
124
  "use client";
148
125
 
149
126
  import { useState, useEffect, type ReactNode } from "react";
150
-
151
127
  import { YuktAIWrapper } from "@yuktishaalaa/yuktai";
152
128
 
153
129
  export default function YuktaiClient({ children }: { children: ReactNode }) {
130
+ const [mounted, setMounted] = useState(false);
131
+ useEffect(() => setMounted(true), []);
154
132
 
155
-   const [mounted, setMounted] = useState(false);
156
-
157
-   useEffect(() => setMounted(true), []);
158
-
159
-   if (!mounted) return <>{children}</>;
160
-
161
-   return (
162
-
163
-     <YuktAIWrapper position="left">
164
-
165
-       {children}
166
-
167
-     </YuktAIWrapper>
168
-
169
-   );
133
+ if (!mounted) return <>{children}</>;
170
134
 
135
+ return (
136
+ <YuktAIWrapper position="left" showRag showAgent>
137
+ {children}
138
+ </YuktAIWrapper>
139
+ );
171
140
  }
172
-
173
141
  ```
174
142
 
175
- ### Step 3 — `app/layout.tsx`
143
+ ### Step 3: `app/layout.tsx`
176
144
 
177
145
  ```tsx
178
-
179
146
  import YuktaiClient from "@/components/YuktaiClient";
180
147
 
181
148
  export default function RootLayout({ children }: { children: React.ReactNode }) {
182
-
183
-   return (
184
-
185
-     <html lang="en">
186
-
187
-       <body>
188
-
189
-         <YuktaiClient>
190
-
191
-           <main>{children}</main>
192
-
193
-         </YuktaiClient>
194
-
195
-       </body>
196
-
197
-     </html>
198
-
199
-   );
200
-
149
+ return (
150
+ <html lang="en">
151
+ <body>
152
+ <YuktaiClient>
153
+ <main>{children}</main>
154
+ </YuktaiClient>
155
+ </body>
156
+ </html>
157
+ );
201
158
  }
202
-
203
159
  ```
204
160
 
205
- That's it. Three AI-powered buttons appear on every page. Click the ♿ button bottom-right to open the accessibility panel.
206
-
207
- ---
208
-
209
- ## Module 1 — Accessibility Engine
210
-
211
- Scans every element and injects missing accessibility attributes automatically.
212
-
213
- Covers: headings, images, forms, tables, lists, landmarks, ARIA widgets. Watches for new DOM elements via `MutationObserver`.
161
+ That's it. Floating buttons appear on every page: ♿ opens the accessibility panel, 💬 opens "Ask this page", and the agent button opens the AI agent.
214
162
 
215
- ### Features (16)
163
+ ### Wrapper props
216
164
 
217
- - WCAG 2.2 auto-fix — ARIA, roles, tabindex, scope, autocomplete
165
+ | Prop | Type | Default | Description |
166
+ |---|---|---|---|
167
+ | `position` | `"left" \| "right"` | `"left"` | Which side the buttons appear on |
168
+ | `showRag` | `boolean` | `false` | Show the 💬 Ask-this-page button |
169
+ | `showAgent` | `boolean` | `false` | Show the AI agent button |
170
+ | `config` | `Partial<A11yConfig>` | `undefined` | Accessibility config overrides |
171
+ | `children` | `ReactNode` | required | Your app content |
218
172
 
219
- - Speak on focus — browser speech synthesis
220
-
221
- - Voice control — say commands to navigate
222
-
223
- - High contrast · Dark mode · Reduce motion · Large targets (44×44)
224
-
225
- - Colour-blind modes — Deuteranopia, Protanopia, Tritanopia, Greyscale
173
+ ---
226
174
 
227
- - Dyslexia font — Atkinson Hyperlegible (research-backed)
175
+ ## Module 1: Accessibility Engine
228
176
 
229
- - Local font picker, font scaling 80–130%
177
+ Scans every element and injects missing accessibility attributes automatically. Covers headings, images, forms, tables, lists, landmarks, and ARIA widgets. Watches for new DOM elements with `MutationObserver`.
230
178
 
231
- - Audit badge — WCAG score 0–100 (localhost only)
179
+ **Features**
232
180
 
233
- - Skip links, focus trap, preference persistence, reset
181
+ - WCAG 2.2 auto-fix: ARIA, roles, tabindex, scope, autocomplete, alt text
182
+ - Speak on focus using browser SpeechSynthesis
183
+ - Voice control using the SpeechRecognition API
184
+ - Visual alerts for deaf and hard-of-hearing users
185
+ - High contrast, dark mode, reduce motion, large targets (44×44)
186
+ - Colour-blind modes: Deuteranopia, Protanopia, Tritanopia, Greyscale
187
+ - Dyslexia font: Atkinson Hyperlegible
188
+ - Local font picker and font scaling from 80% to 130%
189
+ - Audit badge with a WCAG score from 0 to 100 (localhost only)
190
+ - Skip links, focus trap, saved preferences, reset
234
191
 
235
- ### Direct API
192
+ **Direct API**
236
193
 
237
194
  ```ts
195
+ import { wcagPlugin, type A11yConfig } from "@yuktishaalaa/yuktai";
238
196
 
239
- import { wcagPlugin } from "@yuktishaalaa/yuktai";
240
-
241
- // Apply fixes
242
-
243
- const report = wcagPlugin.applyFixes({
244
-
245
-   enabled:       true,
246
-
247
-   highContrast:  false,
248
-
249
-   darkMode:      false,
250
-
251
-   reduceMotion:  false,
252
-
253
-   largeTargets:  false,
254
-
255
-   speechEnabled: false,
256
-
257
-   colorBlindMode:"none",
258
-
259
-   autoFix:       true,
260
-
261
- });
197
+ const config: A11yConfig = {
198
+ enabled: true,
199
+ highContrast: false,
200
+ darkMode: false,
201
+ reduceMotion: false,
202
+ largeTargets: false,
203
+ speechEnabled: false,
204
+ colorBlindMode: "none", // none | deuteranopia | protanopia | tritanopia | achromatopsia
205
+ autoFix: true,
206
+ showPreferencePanel: true,
207
+ showSkipLinks: true,
208
+ showAuditBadge: false, // dev only (localhost)
209
+ fontSizeMultiplier: 1,
210
+ timeoutWarning: 0, // seconds, 0 = off
211
+ };
262
212
 
263
- console.log(report.fixed);   // number of fixes applied
213
+ const report = wcagPlugin.applyFixes(config);
214
+ console.log(report.fixed); // number of fixes applied
215
+ console.log(report.score); // 0–100
216
+ ```
264
217
 
265
- console.log(report.score);   // 0–100
218
+ ### WCAG coverage
266
219
 
267
- ```
220
+ | Standard | Criteria | Examples |
221
+ |---|---|---|
222
+ | WCAG 2.0 | 19 | Alt text, roles, labels, tables, landmarks, focus |
223
+ | WCAG 2.1 | 7 | Touch targets, reflow, motion, orientation |
224
+ | WCAG 2.2 | 3 | Focus appearance, target size, timeout warning |
225
+ | Beyond WCAG | Extras | Speech, visual alerts, colour-blind modes, dyslexia font, audit score |
268
226
 
269
227
  ---
270
228
 
271
- ## Module 2 — YuktaiGrid ⭐
229
+ ## Module 2: YuktaiGrid ⭐
272
230
 
273
- An accessible data grid built for Next.js. Handles small tables and large datasets. Works with any API. Ships with the 5 accessibility themes.
231
+ An accessible data grid for Next.js, with an embedded AI assistant, agent tools, and WebMCP support.
274
232
 
275
- ### Usage
233
+ ### Basic usage
276
234
 
277
235
  ```tsx
278
-
279
236
  "use client";
280
237
 
281
238
  import { YuktaiGrid } from "@yuktishaalaa/yuktai";
282
239
 
283
240
  const data = [
284
-
285
- { id: 1, name: "Sandeep", role: "Developer", salary: 85000 },
286
-
287
- { id: 2, name: "Priya", role: "Designer", salary: 90000 },
288
-
241
+ { id: 1, name: "Sandeep", role: "Developer", salary: 85000 },
242
+ { id: 2, name: "Priya", role: "Designer", salary: 90000 },
289
243
  ];
290
244
 
291
245
  export default function EmployeesPage() {
246
+ return (
247
+ <YuktaiGrid
248
+ data={data}
249
+ rowKey="id"
250
+ columns={[
251
+ { key: "name", label: "Name", sortable: true },
252
+ { key: "role", label: "Role" },
253
+ { key: "salary", label: "Salary", type: "number", align: "right" },
254
+ ]}
255
+ theme="default" // default | high-contrast | dark | color-blind | dyslexia
256
+ locale="en-US" // en-US | te-IN
257
+ view="auto" // auto | table | card
258
+ search
259
+ ai
260
+ pagination={{
261
+ pageSize: 20,
262
+ showSizeChanger: true,
263
+ sizeOptions: [10, 20, 50, 100],
264
+ }}
265
+ />
266
+ );
267
+ }
268
+ ```
292
269
 
293
- return (
294
-
295
- \<YuktaiGrid
296
-
297
- data={data}
298
-
299
- columns={[
300
-
301
- { key: "name", label: "Name", sortable: true },
302
-
303
- { key: "role", label: "Role" },
304
-
305
- { key: "salary", label: "Salary", type: "number", align: "right" },
306
-
307
- ]}
308
-
309
- theme="default" // default | high-contrast | dark | color-blind | dyslexia
310
-
311
- locale="en-US" // en-US | te-IN
312
-
313
- search={true} // real-time filtering
270
+ ### Grid features
314
271
 
315
- ai={true} // embedded Grid AI Assistant
272
+ - Real-time search, column sorting, client-side pagination with page-size switching
273
+ - Mobile card view below a configurable breakpoint
274
+ - Loading and empty states
275
+ - 5 WCAG themes
276
+ - Row selection, custom cell render, `rowKey`
277
+ - Row highlighting with optional auto-scroll
278
+ - Keyboard navigation, ARIA grid semantics, 44×44 targets
279
+ - English and Telugu UI
280
+ - Embedded Grid AI Assistant with voice and chat
316
281
 
317
- view="auto" // auto | table | card
282
+ ### Grid AI Assistant
318
283
 
319
- pagination={{
320
- pageSize: 20,
321
- showSizeChanger: true,
322
- sizeOptions: [10, 20, 50, 100],
323
- }}
284
+ Runs embedded in the grid or as a standalone component. Intent parsing runs locally and supports search, sort, count, highest, lowest, average, total, and row lookup.
324
285
 
286
+ ```tsx
287
+ <YuktaiGridAI
288
+ data={data}
289
+ columns={columns}
290
+ onSearch={handleSearch}
291
+ onSort={handleSort}
292
+ language="te-IN" // AI UI and responses: en-US | te-IN
293
+ inputLanguage="te-IN" // voice input: en-US | te-IN
294
+ embedded
325
295
  />
326
-
327
- );
328
-
329
- }
330
-
331
296
  ```
332
297
 
333
- ### Grid features
298
+ Voice recognition depends on browser Web Speech API support.
334
299
 
335
- - Search bar with inline SVG icon
300
+ ### Agent tools
336
301
 
337
- - Sort — click a column header to toggle ascending / descending
302
+ Generic, reusable grid operations shared by the Agent and WebMCP:
338
303
 
339
- - Functional client-side pagination
304
+ ```ts
305
+ import {
306
+ searchGrid,
307
+ countGrid,
308
+ getColumns,
309
+ getRow,
310
+ highlightRows,
311
+ selectRow,
312
+ openRow,
313
+ } from "@yuktishaalaa/yuktai";
314
+ ```
340
315
 
341
- - Configurable page-size switching such as 10, 20, 50, 100
316
+ Run tools programmatically:
342
317
 
343
- - Mobile card view below the configured breakpoint
318
+ ```tsx
319
+ import { useYuktaiGridAgent, type GridAgentTool } from "@yuktishaalaa/yuktai";
344
320
 
345
- - Loading and empty states
321
+ const tools: GridAgentTool[] = [
322
+ {
323
+ name: "search",
324
+ description: "Search grid rows by a text query",
325
+ execute: async ({ query }) => searchGrid(data, query),
326
+ },
327
+ ];
346
328
 
347
- - 5 WCAG themes
329
+ const { executeTool, loading } = useYuktaiGridAgent({ tools });
330
+ ```
348
331
 
349
- - Row selection, custom render, and rowKey
332
+ **Design principle:** keep generic tools in the package and put app-specific rules in your app.
350
333
 
351
- - Row highlighting and optional auto-scroll to highlighted rows
334
+ ```text
335
+ Generic YuktAI tools + Your domain rules = Your application agent
336
+ ```
352
337
 
353
- - Embedded Grid AI Assistant
338
+ ### WebMCP
354
339
 
355
- - English and Telugu Grid UI
340
+ Exposes grid tools to browser AI agents through `document.modelContext`, so agents call real operations instead of guessing from the DOM. Registration is invisible in the UI.
341
+
342
+ ```tsx
343
+ <YuktaiGrid
344
+ data={rows}
345
+ columns={columns}
346
+ ai
347
+ webmcp
348
+ toolName="my_grid"
349
+ toolDescriptions={TOOL_DESCRIPTIONS}
350
+ onWebMCPStatusChange={setStatus} // unsupported | registering | ready | partial | error
351
+ />
352
+ ```
356
353
 
357
- - Inline SVG search, sort, selection, and pagination icons
354
+ Or standalone:
358
355
 
359
- - No external icon dependency
356
+ ```tsx
357
+ <YuktaiGridWebMCP data={data} columns={columns} />
358
+ ```
360
359
 
361
- ### Handling large datasets (100K, 200K, 300K rows)
360
+ WebMCP is not available in every browser, so always handle the `unsupported` status gracefully.
362
361
 
363
- **Client-side pagination handles a few thousand rows well.** For anything larger, use **server-side pagination** — fetch only the page you need.
362
+ ### Large datasets (100K+ rows)
364
363
 
365
- Here's the pattern with a Next.js API proxy that also solves CORS.
364
+ Client-side pagination handles a few thousand rows well. For anything larger, use server-side pagination and disable the grid's built-in search and pagination.
366
365
 
367
- **`src/app/api/employees/route.ts`** — the proxy:
366
+ `src/app/api/employees/route.ts`:
368
367
 
369
368
  ```ts
370
-
371
369
  import { NextRequest, NextResponse } from "next/server";
372
370
 
373
371
  let cachedData: any[] | null = null;
374
-
375
372
  let cacheTime = 0;
376
-
377
373
  const TTL_MS = 60_000;
378
374
 
379
375
  async function fetchAll(): Promise<any[]> {
380
-
381
-   const now = Date.now();
382
-
383
-   if (cachedData && now - cacheTime < TTL_MS) return cachedData;
384
-
385
-   const res  = await fetch("https://your-api.com/employees", { cache: "no-store" });
386
-
387
-   const json = await res.json();
388
-
389
-   cachedData = Array.isArray(json) ? json : (json.employees ?? json.data ?? []);
390
-
391
-   cacheTime  = now;
392
-
393
-   return cachedData;
394
-
376
+ const now = Date.now();
377
+ if (cachedData && now - cacheTime < TTL_MS) return cachedData;
378
+ const res = await fetch("https://your-api.com/employees", { cache: "no-store" });
379
+ const json = await res.json();
380
+ cachedData = Array.isArray(json) ? json : json.employees ?? json.data ?? [];
381
+ cacheTime = now;
382
+ return cachedData;
395
383
  }
396
384
 
397
385
  export async function GET(req: NextRequest) {
398
-
399
-   const p = req.nextUrl.searchParams;
400
-
401
-   const page     = Math.max(1, parseInt(p.get("page")     || "1"));
402
-
403
-   const pageSize = Math.max(1, parseInt(p.get("pageSize") || "5000"));
404
-
405
-   const search   = (p.get("search") || "").toLowerCase().trim();
406
-
407
-   const all      = await fetchAll();
408
-
409
-   const filtered = search
410
-
411
-     ? all.filter(r => Object.values(r).some(v => String(v).toLowerCase().includes(search)))
412
-
413
-     : all;
414
-
415
-   const total = filtered.length;
416
-
417
-   const rows  = filtered.slice((page - 1) * pageSize, page * pageSize);
418
-
419
-   return NextResponse.json({
420
-
421
-     rows,
422
-
423
-     pagination: { page, pageSize, totalRows: total, totalPages: Math.ceil(total / pageSize) },
424
-
425
-   });
426
-
386
+ const p = req.nextUrl.searchParams;
387
+ const page = Math.max(1, parseInt(p.get("page") || "1"));
388
+ const pageSize = Math.max(1, parseInt(p.get("pageSize") || "5000"));
389
+ const search = (p.get("search") || "").toLowerCase().trim();
390
+
391
+ const all = await fetchAll();
392
+ const filtered = search
393
+ ? all.filter((r) => Object.values(r).some((v) => String(v).toLowerCase().includes(search)))
394
+ : all;
395
+
396
+ const total = filtered.length;
397
+ const rows = filtered.slice((page - 1) * pageSize, page * pageSize);
398
+
399
+ return NextResponse.json({
400
+ rows,
401
+ pagination: { page, pageSize, totalRows: total, totalPages: Math.ceil(total / pageSize) },
402
+ });
427
403
  }
428
-
429
404
  ```
430
405
 
431
- **Page — call the paginated API and disable the grid's built-in pagination:**
406
+ Page:
432
407
 
433
408
  ```tsx
434
-
435
- const [apiResp, setApiResp]     = useState<any>(null);
436
-
437
- const [currentPage, setPage]    = useState(1);
409
+ const [apiResp, setApiResp] = useState<any>(null);
410
+ const [currentPage, setPage] = useState(1);
438
411
 
439
412
  useEffect(() => {
440
-
441
-   fetch(`/api/employees?page=${currentPage}&pageSize=5000`)
442
-
443
-     .then(r => r.json())
444
-
445
-     .then(setApiResp);
446
-
413
+ fetch(`/api/employees?page=${currentPage}&pageSize=5000`)
414
+ .then((r) => r.json())
415
+ .then(setApiResp);
447
416
  }, [currentPage]);
448
417
 
449
418
  <YuktaiGrid
450
-
451
-   data={apiResp?.rows ?? []}
452
-
453
-   columns={columns}
454
-
455
-   search={false}         // disable — we handle search server-side
456
-
457
-   pagination={false}     // disable — we handle pagination server-side
458
-
459
-   loading={!apiResp}
460
-
461
- />
462
-
419
+ data={apiResp?.rows ?? []}
420
+ columns={columns}
421
+ search={false} // handled server-side
422
+ pagination={false} // handled server-side
423
+ loading={!apiResp}
424
+ />;
463
425
  ```
464
426
 
465
- Then render your own pagination bar backed by `apiResp.pagination`. This pattern works for 100K, 200K, 300K rows — the browser only ever holds 5,000 rows in memory.
427
+ Render your own pagination bar from `apiResp.pagination`. The browser only ever holds one page in memory.
466
428
 
467
429
  ---
468
430
 
469
- ---
431
+ ## Showcase: Ratnalabala (Telugu poetry)
470
432
 
471
- ## Grid Agentic AI + WebMCP
472
-
473
- YuktaiGrid exposes reusable Grid operations so an Agent can work with grid data through a shared tool layer and WebMCP.
474
-
475
- ### Grid tools
476
-
477
- ```ts
478
-
479
- import {
480
- searchGrid,
481
- countGrid,
482
- getColumns,
483
- getRow,
484
- highlightRows,
485
- selectRow,
486
- openRow,
487
- } from "@yuktishaalaa/yuktai";
488
-
489
- ```
490
-
491
- These operations form the common execution layer for programmatic Agent tools and WebMCP.
492
-
493
- ### Agent execution
494
-
495
- ```tsx
496
-
497
- import {
498
- useYuktaiGridAgent,
499
- type GridAgentTool,
500
- } from "@yuktishaalaa/yuktai";
501
-
502
- const tools: GridAgentTool[] = [
503
- {
504
- name: "search",
505
- description: "Search grid rows",
506
- execute: async ({ query }) => {
507
- return { query };
508
- },
509
- },
510
- ];
511
-
512
- const { executeTool, loading } =
513
- useYuktaiGridAgent({ tools });
514
-
515
- ```
516
-
517
- ### WebMCP
518
-
519
- ```tsx
520
-
521
- import {
522
- YuktaiGridWebMCP,
523
- } from "@yuktishaalaa/yuktai";
524
-
525
- <YuktaiGridWebMCP
526
- data={data}
527
- columns={columns}
528
- />
433
+ [Ratnalabala](https://ratnalabala.vercel.app/poems?view=grid) shows that an agentic grid is more than a chatbot next to a table. Users type or speak in Telugu, and the grid acts.
529
434
 
435
+ | User says | Agent action |
436
+ |---|---|
437
+ | `ఎన్ని పద్యాలు` (how many poems) | `count` → "మొత్తం 36 పద్యాలు ఉన్నాయి." |
438
+ | `గర్వం తెరువు` (open "Garvam") | `open` |
439
+ | `"బుద్ధి" ఉన్న పద్యాలు` (poems with "buddhi") | `search` + highlight |
440
+ | `అక్షర క్రమంలో` (alphabetical) | `sort(title, asc)` |
441
+ | `ఈరోజు పద్యం` (poem of the day) | custom rule + highlight |
442
+
443
+ **Stack:** Next.js · React + TypeScript · MUI · YuktAI Grid · FastAPI (Python) · PostgreSQL on Neon · Vercel · Web Speech API · WebMCP
444
+
445
+ ```text
446
+ PostgreSQL → FastAPI → Next.js API proxy → Ratnalabala UI → YuktAI Grid
447
+ ├── Agent
448
+ └── WebMCP
530
449
  ```
531
450
 
532
- WebMCP registration is invisible in the UI and uses document.modelContext when available.
533
-
534
- ### Embedded Grid AI Assistant
535
-
536
451
  ```tsx
537
-
538
- <YuktaiGrid
539
- data={data}
540
- columns={columns}
541
- locale="te-IN"
542
- ai={true}
543
- pagination={{
544
- pageSize: 20,
545
- showSizeChanger: true,
546
- sizeOptions: [10, 20, 50, 100],
547
- }}
452
+ <YuktaiGrid<PoemRow>
453
+ data={rows}
454
+ columns={COLUMNS}
455
+ rowKey="id"
456
+ locale="te-IN"
457
+ inputLanguage="te-IN"
458
+ customRules={POEM_RULES}
459
+ search
460
+ highlightIds={highlightIds}
461
+ autoScrollToHighlight
462
+ onRowClick={(row) => onOpenPoem(row.title)}
463
+ ai
464
+ webmcp
465
+ toolName="ratnalabala_poems"
466
+ toolDescriptions={TOOL_DESCRIPTIONS}
467
+ onWebMCPStatusChange={setWebmcp}
548
468
  />
549
-
550
469
  ```
551
470
 
552
- Grid AI supports:
553
-
554
- - language="en-US" or language="te-IN" for AI UI and responses
555
-
556
- - inputLanguage="en-US" or inputLanguage="te-IN" for voice input
557
-
558
- - embedded mode for rendering AI inside the Grid
559
-
560
- - Local intent parsing for search, sort, count, highest, lowest, average, total, and lookup
561
-
562
471
  ---
563
472
 
564
- ## Module 3 — In-Tab RAG (Ask This Page)
565
-
566
- Retrieval-Augmented Generation running entirely in the browser. Extracts semantic chunks from the current DOM, embeds them, finds the best match for the user's question, and answers — offline, no API key.
567
-
568
- ### Features (11)
473
+ ## Module 3: In-Tab RAG (Ask This Page)
569
474
 
570
- - Ask any question about any page
475
+ Retrieval-Augmented Generation running entirely in the browser. It extracts text chunks from the current page, embeds them, finds the best match for the question, and answers. Offline, no API key.
571
476
 
572
- - Gemini Nano on desktop Chrome — zero download, zero API
573
-
574
- - Transformers.js on mobile — 30 MB one-time model load
575
-
576
- - Auto engine detection and switching
577
-
578
- - Works offline after first load
579
-
580
- - q4 quantization on mobile (32-bit → 4-bit weights)
581
-
582
- - `flan-t5-small` for full-sentence answers
583
-
584
- - Cosine similarity semantic search
585
-
586
- - Deduped DOM text extraction
477
+ | Device | Engine | How it works |
478
+ |---|---|---|
479
+ | Desktop Chrome with Gemini Nano | `window.LanguageModel` | Page text sent as context, instant answer |
480
+ | Mobile and all other browsers | Transformers.js | Embeddings + `flan-t5-small`, q4 quantized |
587
481
 
588
- ### What I learned
482
+ - About 30 MB one-time model download on mobile, cached in IndexedDB
483
+ - Works fully offline after first load
484
+ - All processing on device, no data sent anywhere
589
485
 
590
- The hardest part was mobile. Transformers.js kept crashing on iOS Safari with out-of-memory errors. Learning about quantization — same model, 75% smaller — fixed it. DistilBERT gives short useless spans; flan-t5-small gives real sentences. None of that was in any tutorial. Found on a Saturday by breaking things until something worked.
486
+ **What I learned:** Transformers.js kept crashing on iOS Safari with out-of-memory errors. Quantization (same model, 75% smaller) fixed it. DistilBERT gave short, useless spans; `flan-t5-small` gives real sentences.
591
487
 
592
488
  ---
593
489
 
594
- ## Module 4 — Autonomous AI Agent
595
-
596
- User types a goal in plain English. Yuktai reads the DOM, finds the right elements, plans steps, and highlights what to do.
597
-
598
- ### Features (13)
599
-
600
- - Plain-English goal input
490
+ ## Module 4: Autonomous AI Agent
601
491
 
602
- - Reads full page DOM — 9 traversal strategies
603
-
604
- - Scans all form fields — 11 label strategies
492
+ Type a goal in plain English. yuktai reads the page, finds the right elements, plans the steps, and highlights what to do.
605
493
 
494
+ - 9 DOM traversal strategies and 11 form-label strategies
606
495
  - Works on static HTML, React, WordPress, and old government portals
496
+ - Gemini Nano planning on desktop, Transformers.js on mobile, rule-based fallback
497
+ - Highlights target fields, scrolls to sections, shows a numbered plan, handles iframes
607
498
 
608
- - Gemini Nano planning on desktop, Transformers.js on mobile
609
-
610
- - Rule-based fallback if AI fails
611
-
612
- - Highlights target field with teal outline
613
-
614
- - Scrolls to relevant section by keyword
615
-
616
- - Numbered step-by-step plan
617
-
618
- - Handles iframes
619
-
620
- The 11 label strategies came from real websites — old government portals put labels in the previous table cell, modern apps use `aria-label`, static pages use `placeholder`. Every strategy solved a problem I had actually hit.
499
+ Every label strategy came from a real website: old portals put labels in the previous table cell, modern apps use `aria-label`, static pages use `placeholder`.
621
500
 
622
501
  ---
623
502
 
624
- ## Module 5 — Vibe Coder
625
-
626
- Type a business requirement. Yuktai generates a full Next.js 16 project as a downloadable ZIP.
627
-
628
- ### Features (19)
503
+ ## Module 5: Vibe Coder
629
504
 
630
- - Detects website type (12 types), pages needed (21 types), features (14 types)
631
-
632
- - Detects theme colour (8), extracts site name
505
+ Type a business requirement and download a full Next.js 16 project as a ZIP.
633
506
 
507
+ - Detects website type (12), pages (21), features (14), theme colour (8), and site name
634
508
  - Preview before generating
509
+ - TypeScript, Tailwind + CSS Modules, mobile responsive
510
+ - Navbar, Footer, Home, About, Contact, Services, Pricing, Auth, Dashboard
511
+ - `npm run dev` works immediately
635
512
 
636
- - Full Next.js 16 project — Tailwind + CSS Modules, TypeScript, mobile responsive
637
-
638
- - Navbar, Footer, Home, About, Contact, Services, Pricing, Auth, Dashboard pages
639
-
640
- - Downloads as ZIP · `npm run dev` works immediately
641
-
642
- - Pure templates — no AI writes the code
643
-
644
- No AI writes a single line. Pure template engineering. Same reusable-utility thinking from 2013 jQuery — now generating entire Next.js projects.
513
+ No AI writes the code. It's pure template engineering.
645
514
 
646
515
  ---
647
516
 
648
- ## Grid AI Assistant — Voice + Chat
649
-
650
- The Grid AI Assistant can run embedded inside YuktaiGrid or as a standalone component.
651
-
652
- Voice input uses the browser Web Speech API. AI responses can be spoken with SpeechSynthesis. Intent parsing runs locally for the supported Grid operations.
653
-
654
- Supports:
655
-
656
- - Search
657
-
658
- - Sort
659
-
660
- - Count
661
-
662
- - Highest / maximum
663
-
664
- - Lowest / minimum
517
+ ## Gemini Nano setup (desktop Chrome, one time)
665
518
 
666
- - Average
519
+ Needed only for Gemini Nano features on desktop Chrome. Mobile and other browsers use Transformers.js automatically.
667
520
 
668
- - Total
521
+ 1. Open `chrome://flags` and enable: Prompt API for Gemini Nano, Summarization API, Writer API, Rewriter API, Translation API.
522
+ 2. Click **Relaunch**.
523
+ 3. Open `chrome://components`, find **Optimization Guide On Device Model**, and click **Check for update**.
524
+ 4. Refresh your page. AI features unlock automatically.
669
525
 
670
- - Row lookup
671
-
672
- - English and Telugu AI UI
673
-
674
- - English voice input by default
675
-
676
- - Telugu voice input with inputLanguage="te-IN"
677
-
678
- Example:
679
-
680
- ```tsx
681
-
682
- <YuktaiGridAI
683
- data={data}
684
- columns={columns}
685
- onSearch={handleSearch}
686
- onSort={handleSort}
687
- language="te-IN"
688
- inputLanguage="en-US"
689
- embedded
690
- />
691
-
692
- ```
526
+ **Gemini Nano features:** plain-English rewriting, 3-sentence page summary, AI-generated ARIA labels, page translation in 18 languages.
693
527
 
694
- Voice recognition depends on browser Web Speech API support.
528
+ > Chrome 147 moved the APIs from `window.ai` to standalone globals such as `window.LanguageModel`. yuktai supports both.
695
529
 
696
530
  ---
697
531
 
698
- ## Icon library
532
+ ## Icons
699
533
 
700
- 7 custom SVG icons. Zero external dependency. All seven remain part of the public package API.
534
+ Seven custom SVG icons with no external dependency.
701
535
 
702
536
  ```tsx
703
-
704
537
  import {
705
-
706
-   SearchIcon,
707
-
708
-   SortUpIcon,
709
-
710
-   SortDownIcon,
711
-
712
-   ChevronLeftIcon,
713
-
714
-   ChevronRightIcon,
715
-
716
-   CheckIcon,
717
-
718
-   CloseIcon,
719
-
538
+ SearchIcon,
539
+ SortUpIcon,
540
+ SortDownIcon,
541
+ ChevronLeftIcon,
542
+ ChevronRightIcon,
543
+ CheckIcon,
544
+ CloseIcon,
720
545
  } from "@yuktishaalaa/yuktai";
721
546
 
722
- <SearchIcon        size={20} />
723
-
724
- <SortUpIcon        size={20} color="#0D9488" />
725
-
726
- <CheckIcon         size={20} color="#10b981" label="Task complete" />
727
-
728
- <CloseIcon         size={20} color="#dc2626" />
729
-
730
- <ChevronLeftIcon   size={24} label="Previous" />
731
-
732
- <ChevronRightIcon  size={24} label="Next" />
733
-
734
- ```
735
-
736
- Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (default 2.5), `label` (adds ARIA — decorative if omitted).
737
-
738
- ---
739
-
740
- ## Gemini Nano (Chrome 147+)
741
-
742
- - Plain-English mode — rewrites complex text
743
-
744
- - Summarise page — 3-sentence summary
745
-
746
- - Smart ARIA labels — AI generates labels
747
-
748
- - Translate page — 18 languages
749
-
750
- - Chrome 147+ standalone globals (`window.LanguageModel`)
751
-
752
- - Fallback to old `window.ai` namespace
753
-
754
- Chrome 147 silently removed `window.ai` and moved everything to standalone globals. Debugged for an evening before finding it in the release notes.
755
-
756
- ---
757
-
758
- ## Technical (17 features)
759
-
760
- Zero API keys · Zero cost · Zero telemetry · Works on all browsers · Works on mobile (Android + iOS) · Works offline after first load · PWA compatible · Next.js 16 compatible · React 19 compatible · TypeScript throughout · SSR safe (no window errors) · Escape closes all panels · Each panel closes others · `data-yuktai-panel` — never reads own UI · Three stacked FAB buttons · Mobile full-screen panels · Tablet responsive · `showRag`, `showAgent`, `position` props.
761
-
762
- ---
763
-
764
- ## Configuration
765
-
766
- ```ts
767
-
768
- import { wcagPlugin, A11yConfig } from "@yuktishaalaa/yuktai";
769
-
770
- const config: A11yConfig = {
771
-
772
-   enabled:             true,   // required
773
-
774
-   highContrast:        false,
775
-
776
-   darkMode:            false,
777
-
778
-   reduceMotion:        false,
779
-
780
-   largeTargets:        false,
781
-
782
-   speechEnabled:       false,
783
-
784
-   colorBlindMode:      "none", // none | deuteranopia | protanopia | tritanopia | achromatopsia
785
-
786
-   autoFix:             true,
787
-
788
-   showPreferencePanel: true,
789
-
790
-   showSkipLinks:       true,
791
-
792
-   showAuditBadge:      false,  // dev only (localhost)
793
-
794
-   fontSizeMultiplier:  1,
795
-
796
-   timeoutWarning:      0,      // seconds (0 = off)
797
-
798
- };
799
-
800
- await wcagPlugin.execute(config);
801
-
547
+ <SearchIcon size={20} />
548
+ <CheckIcon size={20} color="#10b981" label="Task complete" />
802
549
  ```
803
550
 
804
- ---
805
-
806
- ## WCAG coverage
807
-
808
- | Standard | Criteria covered |
809
-
810
- |---|---|
811
-
812
- | WCAG 2.0 | 19 criteria |
813
-
814
- | WCAG 2.1 | 7 criteria |
815
-
816
- | WCAG 2.2 | 3 criteria (focus appearance, target size, timeout) |
817
-
818
- | Beyond WCAG | SpeechSynthesis, visual alerts, keyboard cheatsheet, audit score, colour-blind modes, dyslexia font |
551
+ Props: `size` (default 20), `color` (default `currentColor`), `strokeWidth` (default 2.5), `label` (adds ARIA; decorative if omitted).
819
552
 
820
553
  ---
821
554
 
822
555
  ## Design principles
823
556
 
824
- - **Zero id attributes** — no injected node ever gets an `id`. Tracked via module-level JavaScript references. Never collides with host app ids.
825
-
826
- - **Zero API keys** — runs entirely in the browser. No external calls, no telemetry, no cost.
827
-
828
- - **Zero framework lock-in** — `core/renderer.ts` has no framework imports. Works in Node.js, browsers, and test environments.
829
-
830
- - **Honest limits** — client-side grid pagination works for a few thousand rows. Beyond that, use server-side pagination (pattern shown above).
557
+ - **Zero API keys, zero cost, zero telemetry.** Everything runs in the browser.
558
+ - **Zero injected ids.** Injected nodes are tracked by JavaScript references, so they never collide with your app's ids.
559
+ - **Zero framework lock-in.** `core/renderer.ts` has no framework imports.
560
+ - **Never reads its own UI.** Panels are marked with `data-yuktai-panel`.
561
+ - **SSR safe.** No `window` errors on the server.
562
+ - **Honest limits.** Client-side pagination is for a few thousand rows; use server-side beyond that.
831
563
 
832
564
  ---
833
565
 
834
566
  ## Compatibility
835
567
 
836
- ### Next.js versions
837
-
838
- | Version | Supported |
839
-
568
+ | | Supported |
840
569
  |---|---|
841
-
842
- | Next.js 16 | ✅ |
843
-
844
- | Next.js 15 | ✅ |
845
-
846
- | Next.js 14 | ✅ |
847
-
848
- | Next.js 13 | ✅ |
849
-
850
- ### React versions
851
-
852
- | Version | Supported | Install flag |
853
-
854
- |---|---|---|
855
-
856
- | React 19 | ✅ | `--legacy-peer-deps` |
857
-
858
- | React 18 | ✅ | none |
859
-
860
- | React 17 | ✅ | none |
861
-
862
- ### Browsers
863
-
864
- Chrome 90+ · Firefox 90+ · Safari 15+ · Edge 90+ · Samsung Internet 14+
570
+ | Next.js | 13, 14, 15, 16 |
571
+ | React | 17, 18, 19 (19 needs `--legacy-peer-deps`) |
572
+ | Node.js | 18+ |
573
+ | Browsers | Chrome 90+, Firefox 90+, Safari 15+, Edge 90+, Samsung Internet 14+ |
865
574
 
866
575
  ---
867
576
 
868
577
  ## Roadmap
869
578
 
870
- Shipped: v4.6.4 — YuktaiGrid Agentic AI + WebMCP integration, embedded Grid AI Assistant, English/Telugu Grid UI, functional page-size switching, and Grid icon polish.
579
+ - **Shipped (v4.6.4):** YuktaiGrid Agentic AI + WebMCP, embedded Grid AI Assistant, English/Telugu UI, page-size switching, icon polish
580
+ - **Next:** more Grid Agent tools and WebMCP capabilities, multilingual RAG (Telugu, Hindi, Tamil, Bengali)
581
+ - **Later:** RTL support, richer browser-native AI, multimodal grid experiences
582
+
583
+ ---
871
584
 
872
- Next: expand Grid Agent tools and WebMCP capabilities.
585
+ ## Contributing
873
586
 
874
- Long term: richer browser-native AI and multimodal Grid experiences.
587
+ Issues and pull requests are welcome at [github.com/sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai). For security issues, see [SECURITY.md](./SECURITY.md).
875
588
 
876
589
  ---
877
590
 
878
591
  ## Links
879
592
 
880
- - npm — [@yuktishaalaa/yuktai](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
881
-
882
- - GitHub — [sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai)
883
-
884
- - Live demo — [aksharatantra.vercel.app](https://aksharatantra.vercel.app)
593
+ - npm: [@yuktishaalaa/yuktai](https://www.npmjs.com/package/@yuktishaalaa/yuktai)
594
+ - GitHub: [sandeepmiriyala03/yuktai](https://github.com/sandeepmiriyala03/yuktai)
595
+ - Demo: [aksharatantra.miriyala.in/staffdirectory](https://aksharatantra.miriyala.in/staffdirectory)
596
+ - Showcase: [ratnalabala.vercel.app](https://ratnalabala.vercel.app/poems?view=grid)
885
597
 
886
598
  ---
887
599
 
888
600
  ## License
889
601
 
890
- ISC © Sandeep Miriyala — [Yuktishaalaa AI Lab](https://github.com/sandeepmiriyala03)
602
+ ISC © Sandeep Miriyala, [Yuktishaalaa AI Lab](https://github.com/sandeepmiriyala03)
891
603
 
892
- Built in free time. With help from Claude, GPT, and Gemini for learning — but every line written, every bug fixed, every decision made by me.
604
+ Built in free time, with help from Claude, GPT, and Gemini for learning. Every line written, every bug fixed, and every decision made by me.
893
605
 
894
- Free forever. Open source.
606
+ **Free forever. Open source. Built for every user.** 🏺