[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-meta-create-webapp":3,"mdc-7vs6h1-key":34,"related-org-meta-create-webapp":2390,"related-repo-meta-create-webapp":2580},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":23,"repoUrl":24,"updatedAt":25,"license":26,"forks":27,"topics":28,"repo":29,"sourceUrl":32,"mdContent":33},"create-webapp","create webapps for smart glasses","Create a new webapp for Meta Display Glasses with D-pad navigation and 600x600 dark-theme display. Use when the user wants to build a new glasses app, start a project, or scaffold a webapp for smart glasses.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"meta","Meta Open Source","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fmeta.png","facebook",[13,17,20],{"name":14,"slug":15,"type":16},"Web Development","web-development","tag",{"name":18,"slug":19,"type":16},"Frontend","frontend",{"name":21,"slug":22,"type":16},"Design","design",189,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-webapp","2026-09-01T08:30:30.160115",null,33,[],{"repoUrl":24,"stars":23,"forks":27,"topics":30,"description":31},[],"AI-assisted development toolkit for building web applications on Meta Ray-Ban Display glasses.","https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-webapp\u002Ftree\u002FHEAD\u002Fplugins\u002Fmeta-wearables-webapp\u002Fskills\u002Fcreate-webapp","---\nname: create-webapp\ndescription: >-\n  Create a new webapp for Meta Display Glasses with D-pad navigation\n  and 600x600 dark-theme display. Use when the user wants to build a\n  new glasses app, start a project, or scaffold a webapp for smart\n  glasses.\nargument-hint: \"[app-type] [app-name]\"\n---\n\n## Required reading\n\nBefore generating or modifying any code, read both:\n\n- `..\u002F..\u002Freferences\u002Fdisplay-guidelines.md`\n- `..\u002F..\u002Freferences\u002Fperformance-guidelines.md`\n\nThese define the non-negotiable display physics, input model, and performance budgets for Meta Display Glasses webapps. Do not skip — generated UI that ignores these will fail on-device.\n\nFor current Web Apps docs, use the shared Wearables MCP endpoint `https:\u002F\u002Fmcp.developer.meta.com\u002Fwearables` and call `search_webapps_docs`. The endpoint does not require auth, OAuth, tokens, or custom authorization headers.\n\nIf these reference files are unavailable in an isolated eval, do not search `\u002F`, home directories, or unrelated workspaces. Apply the requirements already present in this skill and continue.\n\nIf the reference files are unavailable in an isolated eval, still apply these hard performance budgets:\n\n- Initial load under 3 seconds.\n- JavaScript bundle under 500 KB gzipped.\n- 60 fps for focus movement, transitions, and animations.\n- Runtime memory under 128 MB.\n- Fewer than 10 network requests during initial load.\n\n# Create Meta Display Glasses WebApp\n\nCreate complete webapps for Meta Display Glasses with EMG wrist-band input, D-pad navigation — including sensor integration and real API connections.\n\n## Input Model\n\n- **D-pad (Up\u002FDown\u002FLeft\u002FRight)**: Navigate focusable elements (EMG band or captouch)\n- **Pinch = activate**: An EMG pinch fires Enter\u002Fclick on the **focused** element — it is not a positioned click. Build focusable, keyboard-activatable UI.\n- **Continuous drag is opt-in**: There is no free cursor by default. To receive a continuous drag stream (sliders, maps, drawing), set `body { touch-action: none; }` in the initial CSS — see `\u002Fadd-gestures`.\n- **Back**: A thumb + middle-finger back gesture (or Escape) returns to the previous screen — no back button needed\n- **Text entry**: Standard HTML text fields open the on-glasses handwriting + voice composer on focus + tap — no SDK call needed (see `\u002Fadd-text-input`).\n- **Sensors**: Accelerometer, gyroscope, magnetometer, orientation via W3C Generic Sensor API\n\nNo touch input is available. The EMG wrist band translates gestures into D-pad events automatically.\n\n## Related Skills\n\n| Skill | Purpose | When to Use |\n|-------|---------|-------------|\n| `\u002Fadd-ui` | Add screens, buttons, UI components | Expanding the app |\n| `\u002Fadd-text-input` | Text fields, search boxes, forms (on-glasses composer) | Any text entry |\n| `\u002Fadd-gestures` | Pinch-to-activate, opt-in continuous drag | Sliders, maps, drawing, games |\n| `\u002Fadd-offline` | Service Worker + Cache API | Work without Wi-Fi, flaky connections |\n| `\u002Fconnect-api` | Add API connection | Connect to REST\u002FWebSocket APIs |\n| `\u002Fadd-device-sensors` | Add sensor data | Motion\u002Forientation\u002FGPS features |\n| `\u002Fadd-local-storage` | Add data persistence | Save settings, cache, state |\n\n## What Gets Generated\n\n```\n\u003Capp-name>\u002F\n  index.html              # HTML structure with screens\n  styles.css              # Dark theme with focus states, loading states, components\n  app.js                  # Logic, navigation, D-pad, APIs, SDK integration\n  favicon.png             # 128x128 PNG icon themed to the app idea\n  manifest.webmanifest    # Web App Manifest referencing the favicon\n```\n\n## Workflow\n\n### Step 1: Understand the Request\n\nIf the user specified a webapp type, proceed to Step 2.\n\nIf not specified, ask what they want to build. Suggest from categories in [references\u002Fapp-ideas.md](references\u002Fapp-ideas.md).\n\n### Step 2: Determine Output Location\n\nAsk where to create the webapp, or use defaults:\n- `~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\u002F` for new webapps\n- Current directory if already in a webapp workspace\n\n```bash\nmkdir -p ~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\n```\n\n### Step 3: Generate Files\n\nGenerate three files using these templates as the foundation:\n\n1. **index.html** — Read [templates\u002Findex.html](templates\u002Findex.html) for the base HTML structure\n2. **styles.css** — Read [templates\u002Fstyles.css](templates\u002Fstyles.css) for the complete CSS\n3. **app.js** — Read [templates\u002Fapp.js](templates\u002Fapp.js) for the complete JS architecture\n\nKey requirements for the HTML:\n- Viewport: `width=600, height=600`\n- Additive display physics: pure black (`#000000`) renders as transparent on the additive waveguide display. Use black only for the page background\u002Ftransparent areas; visible UI surfaces such as cards, headers, rows, buttons, and panels must use dark gray tones (for example `#121417`, `#1C1E21`, or `#24262B`) with light text.\n- Description: `\u003Cmeta name=\"description\" content=\"...\">` in the `\u003Chead>` with a brief, app-specific summary of what the app does. Replace the template placeholder with real copy.\n- MRBD identification: `\u003Cmeta name=\"mrbd-web-app-capable\" content=\"yes\">` in the `\u003Chead>` to positively identify the page as a Meta Display Glasses (MRBD) compatible webapp. Keep `content=\"yes\"` verbatim.\n- All interactive elements: `class=\"focusable\"` and `tabindex=\"0\"` if not a button\n- Button actions: `data-action=\"action-name\"`\n- Each screen is a `\u003Cdiv class=\"screen\">` with a unique `id`\n\nCustomize these sections in `app.js` for each app:\n- `CONFIG` — API URLs, storage key, SDK options\n- `state.data` — App-specific data shape\n- `handleAppAction()` — App-specific action dispatch\n- `onScreenEnter()` — Screen-specific data loading\u002Frendering\n\nAdd app-specific styles to `styles.css` as needed, building on the template foundations.\n\nFramework guidance:\n- For new Meta Display Glasses webapps, recommend the vanilla HTML\u002FCSS\u002FJS scaffold from this skill as the default path.\n- Advise against heavy frameworks such as React, Angular, Vue, or large UI component libraries for first-pass apps because they make the 500 KB gzipped bundle, 3 second initial load, 128 MB runtime memory, and 60 fps interaction budgets harder to hit.\n- If a framework is truly required, prefer lightweight alternatives such as Preact, keep dependencies minimal, measure the gzipped production bundle early, and preserve the same D-pad focus model and display constraints.\n\n### Step 4: Generate the Favicon\n\nCreate a `favicon.png` themed to the app idea using the bundled pure-Python script (no dependencies — stdlib only).\n\n**Constraints (do not violate):**\n- PNG format. **No SVG** — SVG favicons are not supported.\n- Resolution **larger than 52×52**. Default to **128×128**.\n- Must be referenced from both `index.html` (`\u003Clink rel=\"icon\">`) and the Web App Manifest. The template already wires both.\n\n**How to generate:**\n\n1. Design a small concept that maps to the app idea (e.g. NBA scores → orange basketball with a \"B\" glyph; weather → sun\u002Fcloud; music → note shape). Pick colors that contrast on a dark background.\n2. Build a JSON spec using the primitives the script supports: `background` (solid or vertical gradient), optional rounded `plate`, and `layers` of `circle` \u002F `ring` \u002F `rrect` \u002F `polygon` \u002F `points` \u002F `glyph`. See the script header for the full schema.\n3. Render the PNG into the app directory:\n\n```bash\npython3 \u003Cplugin-path>\u002Fskills\u002Fcreate-webapp\u002Fscripts\u002Ffavicon_generator.py \\\n  --spec - --out \u003Capp-name>\u002Ffavicon.png \u003C\u003C'EOF'\n{\n  \"size\": 128,\n  \"background\": {\"type\": \"gradient\", \"from\": \"#1C1E21\", \"to\": \"#0A0B0C\"},\n  \"plate\": {\"color\": \"#FF6B35\", \"radius\": 28, \"inset\": 8},\n  \"layers\": [\n    {\"type\": \"ring\", \"cx\": 64, \"cy\": 64, \"r\": 38, \"width\": 4, \"color\": \"#1C1E21\"},\n    {\"type\": \"glyph\", \"char\": \"B\", \"cx\": 64, \"cy\": 64, \"scale\": 7, \"color\": \"#1C1E21\"}\n  ]\n}\nEOF\n```\n\n4. Write `manifest.webmanifest` next to `index.html`:\n\n```json\n{\n  \"name\": \"\u003CApp Name>\",\n  \"short_name\": \"\u003CApp Name>\",\n  \"icons\": [\n    { \"src\": \"favicon.png\", \"sizes\": \"128x128\", \"type\": \"image\u002Fpng\" }\n  ],\n  \"background_color\": \"#000000\",\n  \"theme_color\": \"#000000\",\n  \"display\": \"standalone\"\n}\n```\n\nThe `\u003Clink rel=\"icon\">` and `\u003Clink rel=\"manifest\">` references are already present in `templates\u002Findex.html` — no HTML edits needed.\n\n### Step 5: For API-Connected Apps\n\nSee [references\u002Fapi-catalog.md](references\u002Fapi-catalog.md) for free public APIs and integration patterns.\n\n### Step 6: For Sensor Apps\n\nUse `\u002Fadd-device-sensors` to add motion, orientation, or GPS data to the webapp.\n\n### Step 7: For UI Components\n\nSee [references\u002Fui-components.md](references\u002Fui-components.md) for reusable HTML component patterns (cards, lists, tabs, loading states).\n\n### Step 8: Verify\n\n- [ ] All screens have `.screen` class and unique `id`\n- [ ] All interactive elements have `.focusable` class\n- [ ] Buttons have `data-action` attributes\n- [ ] Viewport is `width=600, height=600`\n- [ ] `\u003Chead>` has a `\u003Cmeta name=\"description\">` tag with an app-specific summary (placeholder replaced)\n- [ ] `\u003Chead>` has `\u003Cmeta name=\"mrbd-web-app-capable\" content=\"yes\">`\n- [ ] D-pad navigation works (arrow keys move focus with wrap-around)\n- [ ] Enter key activates focused elements\n- [ ] Escape key navigates back\n- [ ] Focus ring is visible (cyan glow) on selected elements\n- [ ] Loading states shown during API calls\n- [ ] Error states handle API failures gracefully\n- [ ] Demo mode works when sensors are unavailable\n- [ ] Data persists via localStorage\n- [ ] All text is readable on dark background\n- [ ] Content fits within 600x600 viewport\n- [ ] Scrollable lists use `overflow-y: auto` with `max-height`\n- [ ] Focused elements scroll into view automatically\n- [ ] `favicon.png` exists at the app root, is >52×52 PNG (not SVG), and is referenced from both `index.html` and `manifest.webmanifest`\n- [ ] Agent surfaced the hosting\u002Ftest next-step prompt (Step 10)\n\n### Step 9: Guide Next Steps\n\n```\nCreated: ~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\u002F\n  index.html              (screens, structure)\n  styles.css              (dark theme, focus states, loading\u002Ferror states)\n  app.js                  (D-pad nav, API calls, SDK integration)\n  favicon.png             (themed app icon)\n  manifest.webmanifest    (web app manifest)\n\nExpand with:\n  \u002Fadd-ui               Add screens, buttons, UI components\n  \u002Fadd-text-input       Add text fields, search boxes, forms\n  \u002Fadd-gestures         Add sliders, drawing, maps (continuous drag)\n  \u002Fadd-offline          Make the app work without Wi-Fi\n  \u002Fconnect-api          Connect to more APIs\n  \u002Fadd-device-sensors   Add motion\u002Forientation\u002FGPS sensors\n  \u002Fadd-local-storage    Add data persistence\n\nTest locally by opening index.html in a browser and using arrow keys + Enter.\n```\n\n### Step 10: Offer a Hosting Path\n\nAfter expansion options, ask the user how they want to run the app on Meta Display Glasses. The glasses load webapps via HTTPS, so the app needs to be hosted on a public URL.\n\nPrompt the user with:\n\n> Your webapp is ready and works locally. To run it on Meta Display Glasses, it needs to be hosted on a public HTTPS URL. Two options:\n>\n> - **`\u002Ftest-on-device`** — deploy to a public staging URL (e.g. `stage-\u003Capp>.vercel.app`) for iterating\n> - **`\u002Fpublish-to-vercel`** — publish to a stable production URL (e.g. `\u003Capp>.vercel.app`)\n>\n> Both use Vercel (free tier works) and I can set the whole thing up for you. If you'd rather host the app yourself elsewhere, you can skip both — anywhere that serves HTTPS will work.\n\nDo not auto-invoke either skill. Wait for the user's choice.\n\n## Speeding up iteration (optional)\n\nIterating on the glasses (build → install → test on-device) is slow. **When that on-device round-trip is the bottleneck, offer the user a much faster off-device loop:** Claude attaches to a **user-launched** Chromium\u002FEdge serving the app from localhost over the Chrome DevTools Protocol (started with `--remote-debugging-port=9222`), then hot-reload-iterates the app and drives the D-pad user journeys each cycle — no device, no rebuild between edits. The user can also **take control of the same tab** and play with the app directly while iterating. Validate the final result **on-device** before calling it done — the fast loop is for iterating, not for proving on-device parity.\n\nOffer this only when on-device iteration is actually slowing the user down; it's a speed-up, not the default.\n\n## Troubleshooting\n\n| Issue | Solution |\n|-------|----------|\n| Webapp doesn't load on device | Check browser console for JS errors |\n| Focus ring not visible | Verify `.focusable` class on interactive elements |\n| D-pad not navigating | Check `moveFocus()` handles the current screen |\n| Enter not activating | Verify `data-action` attribute on element |\n| Back navigation not working | Check `navigateBack()`, the Escape handler, or the back gesture |\n| API calls failing | Check CORS headers, use proxy if needed |\n| API data not updating | Clear cache: `state.cache = {}` |\n| Sensor data not flowing | Check sensor types are valid, verify device support |\n| Data not persisting | Verify `saveData()` called after state changes |\n| Screen not showing | Check `hidden` class and `navigateTo()` call |\n| Demo mode not working | Verify fallback code in sensor helpers |\n\nUse browser developer tools to view console.log output for debugging.\n",{"data":35,"body":37},{"name":4,"description":6,"argument-hint":36},"[app-type] [app-name]",{"type":38,"children":39},"root",[40,49,55,79,84,105,118,123,151,158,163,169,264,269,275,460,466,478,484,491,496,508,514,519,538,592,598,603,656,661,811,823,870,882,887,905,911,924,932,985,993,1079,1264,1287,1638,1664,1670,1682,1688,1700,1706,1717,1723,2003,2009,2018,2024,2029,2034,2095,2100,2106,2147,2152,2158,2379,2384],{"type":41,"tag":42,"props":43,"children":45},"element","h2",{"id":44},"required-reading",[46],{"type":47,"value":48},"text","Required reading",{"type":41,"tag":50,"props":51,"children":52},"p",{},[53],{"type":47,"value":54},"Before generating or modifying any code, read both:",{"type":41,"tag":56,"props":57,"children":58},"ul",{},[59,70],{"type":41,"tag":60,"props":61,"children":62},"li",{},[63],{"type":41,"tag":64,"props":65,"children":67},"code",{"className":66},[],[68],{"type":47,"value":69},"..\u002F..\u002Freferences\u002Fdisplay-guidelines.md",{"type":41,"tag":60,"props":71,"children":72},{},[73],{"type":41,"tag":64,"props":74,"children":76},{"className":75},[],[77],{"type":47,"value":78},"..\u002F..\u002Freferences\u002Fperformance-guidelines.md",{"type":41,"tag":50,"props":80,"children":81},{},[82],{"type":47,"value":83},"These define the non-negotiable display physics, input model, and performance budgets for Meta Display Glasses webapps. Do not skip — generated UI that ignores these will fail on-device.",{"type":41,"tag":50,"props":85,"children":86},{},[87,89,95,97,103],{"type":47,"value":88},"For current Web Apps docs, use the shared Wearables MCP endpoint ",{"type":41,"tag":64,"props":90,"children":92},{"className":91},[],[93],{"type":47,"value":94},"https:\u002F\u002Fmcp.developer.meta.com\u002Fwearables",{"type":47,"value":96}," and call ",{"type":41,"tag":64,"props":98,"children":100},{"className":99},[],[101],{"type":47,"value":102},"search_webapps_docs",{"type":47,"value":104},". The endpoint does not require auth, OAuth, tokens, or custom authorization headers.",{"type":41,"tag":50,"props":106,"children":107},{},[108,110,116],{"type":47,"value":109},"If these reference files are unavailable in an isolated eval, do not search ",{"type":41,"tag":64,"props":111,"children":113},{"className":112},[],[114],{"type":47,"value":115},"\u002F",{"type":47,"value":117},", home directories, or unrelated workspaces. Apply the requirements already present in this skill and continue.",{"type":41,"tag":50,"props":119,"children":120},{},[121],{"type":47,"value":122},"If the reference files are unavailable in an isolated eval, still apply these hard performance budgets:",{"type":41,"tag":56,"props":124,"children":125},{},[126,131,136,141,146],{"type":41,"tag":60,"props":127,"children":128},{},[129],{"type":47,"value":130},"Initial load under 3 seconds.",{"type":41,"tag":60,"props":132,"children":133},{},[134],{"type":47,"value":135},"JavaScript bundle under 500 KB gzipped.",{"type":41,"tag":60,"props":137,"children":138},{},[139],{"type":47,"value":140},"60 fps for focus movement, transitions, and animations.",{"type":41,"tag":60,"props":142,"children":143},{},[144],{"type":47,"value":145},"Runtime memory under 128 MB.",{"type":41,"tag":60,"props":147,"children":148},{},[149],{"type":47,"value":150},"Fewer than 10 network requests during initial load.",{"type":41,"tag":152,"props":153,"children":155},"h1",{"id":154},"create-meta-display-glasses-webapp",[156],{"type":47,"value":157},"Create Meta Display Glasses WebApp",{"type":41,"tag":50,"props":159,"children":160},{},[161],{"type":47,"value":162},"Create complete webapps for Meta Display Glasses with EMG wrist-band input, D-pad navigation — including sensor integration and real API connections.",{"type":41,"tag":42,"props":164,"children":166},{"id":165},"input-model",[167],{"type":47,"value":168},"Input Model",{"type":41,"tag":56,"props":170,"children":171},{},[172,183,200,226,236,254],{"type":41,"tag":60,"props":173,"children":174},{},[175,181],{"type":41,"tag":176,"props":177,"children":178},"strong",{},[179],{"type":47,"value":180},"D-pad (Up\u002FDown\u002FLeft\u002FRight)",{"type":47,"value":182},": Navigate focusable elements (EMG band or captouch)",{"type":41,"tag":60,"props":184,"children":185},{},[186,191,193,198],{"type":41,"tag":176,"props":187,"children":188},{},[189],{"type":47,"value":190},"Pinch = activate",{"type":47,"value":192},": An EMG pinch fires Enter\u002Fclick on the ",{"type":41,"tag":176,"props":194,"children":195},{},[196],{"type":47,"value":197},"focused",{"type":47,"value":199}," element — it is not a positioned click. Build focusable, keyboard-activatable UI.",{"type":41,"tag":60,"props":201,"children":202},{},[203,208,210,216,218,224],{"type":41,"tag":176,"props":204,"children":205},{},[206],{"type":47,"value":207},"Continuous drag is opt-in",{"type":47,"value":209},": There is no free cursor by default. To receive a continuous drag stream (sliders, maps, drawing), set ",{"type":41,"tag":64,"props":211,"children":213},{"className":212},[],[214],{"type":47,"value":215},"body { touch-action: none; }",{"type":47,"value":217}," in the initial CSS — see ",{"type":41,"tag":64,"props":219,"children":221},{"className":220},[],[222],{"type":47,"value":223},"\u002Fadd-gestures",{"type":47,"value":225},".",{"type":41,"tag":60,"props":227,"children":228},{},[229,234],{"type":41,"tag":176,"props":230,"children":231},{},[232],{"type":47,"value":233},"Back",{"type":47,"value":235},": A thumb + middle-finger back gesture (or Escape) returns to the previous screen — no back button needed",{"type":41,"tag":60,"props":237,"children":238},{},[239,244,246,252],{"type":41,"tag":176,"props":240,"children":241},{},[242],{"type":47,"value":243},"Text entry",{"type":47,"value":245},": Standard HTML text fields open the on-glasses handwriting + voice composer on focus + tap — no SDK call needed (see ",{"type":41,"tag":64,"props":247,"children":249},{"className":248},[],[250],{"type":47,"value":251},"\u002Fadd-text-input",{"type":47,"value":253},").",{"type":41,"tag":60,"props":255,"children":256},{},[257,262],{"type":41,"tag":176,"props":258,"children":259},{},[260],{"type":47,"value":261},"Sensors",{"type":47,"value":263},": Accelerometer, gyroscope, magnetometer, orientation via W3C Generic Sensor API",{"type":41,"tag":50,"props":265,"children":266},{},[267],{"type":47,"value":268},"No touch input is available. The EMG wrist band translates gestures into D-pad events automatically.",{"type":41,"tag":42,"props":270,"children":272},{"id":271},"related-skills",[273],{"type":47,"value":274},"Related Skills",{"type":41,"tag":276,"props":277,"children":278},"table",{},[279,303],{"type":41,"tag":280,"props":281,"children":282},"thead",{},[283],{"type":41,"tag":284,"props":285,"children":286},"tr",{},[287,293,298],{"type":41,"tag":288,"props":289,"children":290},"th",{},[291],{"type":47,"value":292},"Skill",{"type":41,"tag":288,"props":294,"children":295},{},[296],{"type":47,"value":297},"Purpose",{"type":41,"tag":288,"props":299,"children":300},{},[301],{"type":47,"value":302},"When to Use",{"type":41,"tag":304,"props":305,"children":306},"tbody",{},[307,330,351,372,394,416,438],{"type":41,"tag":284,"props":308,"children":309},{},[310,320,325],{"type":41,"tag":311,"props":312,"children":313},"td",{},[314],{"type":41,"tag":64,"props":315,"children":317},{"className":316},[],[318],{"type":47,"value":319},"\u002Fadd-ui",{"type":41,"tag":311,"props":321,"children":322},{},[323],{"type":47,"value":324},"Add screens, buttons, UI components",{"type":41,"tag":311,"props":326,"children":327},{},[328],{"type":47,"value":329},"Expanding the app",{"type":41,"tag":284,"props":331,"children":332},{},[333,341,346],{"type":41,"tag":311,"props":334,"children":335},{},[336],{"type":41,"tag":64,"props":337,"children":339},{"className":338},[],[340],{"type":47,"value":251},{"type":41,"tag":311,"props":342,"children":343},{},[344],{"type":47,"value":345},"Text fields, search boxes, forms (on-glasses composer)",{"type":41,"tag":311,"props":347,"children":348},{},[349],{"type":47,"value":350},"Any text entry",{"type":41,"tag":284,"props":352,"children":353},{},[354,362,367],{"type":41,"tag":311,"props":355,"children":356},{},[357],{"type":41,"tag":64,"props":358,"children":360},{"className":359},[],[361],{"type":47,"value":223},{"type":41,"tag":311,"props":363,"children":364},{},[365],{"type":47,"value":366},"Pinch-to-activate, opt-in continuous drag",{"type":41,"tag":311,"props":368,"children":369},{},[370],{"type":47,"value":371},"Sliders, maps, drawing, games",{"type":41,"tag":284,"props":373,"children":374},{},[375,384,389],{"type":41,"tag":311,"props":376,"children":377},{},[378],{"type":41,"tag":64,"props":379,"children":381},{"className":380},[],[382],{"type":47,"value":383},"\u002Fadd-offline",{"type":41,"tag":311,"props":385,"children":386},{},[387],{"type":47,"value":388},"Service Worker + Cache API",{"type":41,"tag":311,"props":390,"children":391},{},[392],{"type":47,"value":393},"Work without Wi-Fi, flaky connections",{"type":41,"tag":284,"props":395,"children":396},{},[397,406,411],{"type":41,"tag":311,"props":398,"children":399},{},[400],{"type":41,"tag":64,"props":401,"children":403},{"className":402},[],[404],{"type":47,"value":405},"\u002Fconnect-api",{"type":41,"tag":311,"props":407,"children":408},{},[409],{"type":47,"value":410},"Add API connection",{"type":41,"tag":311,"props":412,"children":413},{},[414],{"type":47,"value":415},"Connect to REST\u002FWebSocket APIs",{"type":41,"tag":284,"props":417,"children":418},{},[419,428,433],{"type":41,"tag":311,"props":420,"children":421},{},[422],{"type":41,"tag":64,"props":423,"children":425},{"className":424},[],[426],{"type":47,"value":427},"\u002Fadd-device-sensors",{"type":41,"tag":311,"props":429,"children":430},{},[431],{"type":47,"value":432},"Add sensor data",{"type":41,"tag":311,"props":434,"children":435},{},[436],{"type":47,"value":437},"Motion\u002Forientation\u002FGPS features",{"type":41,"tag":284,"props":439,"children":440},{},[441,450,455],{"type":41,"tag":311,"props":442,"children":443},{},[444],{"type":41,"tag":64,"props":445,"children":447},{"className":446},[],[448],{"type":47,"value":449},"\u002Fadd-local-storage",{"type":41,"tag":311,"props":451,"children":452},{},[453],{"type":47,"value":454},"Add data persistence",{"type":41,"tag":311,"props":456,"children":457},{},[458],{"type":47,"value":459},"Save settings, cache, state",{"type":41,"tag":42,"props":461,"children":463},{"id":462},"what-gets-generated",[464],{"type":47,"value":465},"What Gets Generated",{"type":41,"tag":467,"props":468,"children":472},"pre",{"className":469,"code":471,"language":47},[470],"language-text","\u003Capp-name>\u002F\n  index.html              # HTML structure with screens\n  styles.css              # Dark theme with focus states, loading states, components\n  app.js                  # Logic, navigation, D-pad, APIs, SDK integration\n  favicon.png             # 128x128 PNG icon themed to the app idea\n  manifest.webmanifest    # Web App Manifest referencing the favicon\n",[473],{"type":41,"tag":64,"props":474,"children":476},{"__ignoreMap":475},"",[477],{"type":47,"value":471},{"type":41,"tag":42,"props":479,"children":481},{"id":480},"workflow",[482],{"type":47,"value":483},"Workflow",{"type":41,"tag":485,"props":486,"children":488},"h3",{"id":487},"step-1-understand-the-request",[489],{"type":47,"value":490},"Step 1: Understand the Request",{"type":41,"tag":50,"props":492,"children":493},{},[494],{"type":47,"value":495},"If the user specified a webapp type, proceed to Step 2.",{"type":41,"tag":50,"props":497,"children":498},{},[499,501,507],{"type":47,"value":500},"If not specified, ask what they want to build. Suggest from categories in ",{"type":41,"tag":502,"props":503,"children":505},"a",{"href":504},"references\u002Fapp-ideas.md",[506],{"type":47,"value":504},{"type":47,"value":225},{"type":41,"tag":485,"props":509,"children":511},{"id":510},"step-2-determine-output-location",[512],{"type":47,"value":513},"Step 2: Determine Output Location",{"type":41,"tag":50,"props":515,"children":516},{},[517],{"type":47,"value":518},"Ask where to create the webapp, or use defaults:",{"type":41,"tag":56,"props":520,"children":521},{},[522,533],{"type":41,"tag":60,"props":523,"children":524},{},[525,531],{"type":41,"tag":64,"props":526,"children":528},{"className":527},[],[529],{"type":47,"value":530},"~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\u002F",{"type":47,"value":532}," for new webapps",{"type":41,"tag":60,"props":534,"children":535},{},[536],{"type":47,"value":537},"Current directory if already in a webapp workspace",{"type":41,"tag":467,"props":539,"children":543},{"className":540,"code":541,"language":542,"meta":475,"style":475},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","mkdir -p ~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\n","bash",[544],{"type":41,"tag":64,"props":545,"children":546},{"__ignoreMap":475},[547],{"type":41,"tag":548,"props":549,"children":552},"span",{"class":550,"line":551},"line",1,[553,559,565,570,576,581,587],{"type":41,"tag":548,"props":554,"children":556},{"style":555},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[557],{"type":47,"value":558},"mkdir",{"type":41,"tag":548,"props":560,"children":562},{"style":561},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[563],{"type":47,"value":564}," -p",{"type":41,"tag":548,"props":566,"children":567},{"style":561},[568],{"type":47,"value":569}," ~\u002Fmeta-display-glasses-webapps\u002F",{"type":41,"tag":548,"props":571,"children":573},{"style":572},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[574],{"type":47,"value":575},"\u003C",{"type":41,"tag":548,"props":577,"children":578},{"style":561},[579],{"type":47,"value":580},"app-nam",{"type":41,"tag":548,"props":582,"children":584},{"style":583},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[585],{"type":47,"value":586},"e",{"type":41,"tag":548,"props":588,"children":589},{"style":572},[590],{"type":47,"value":591},">\n",{"type":41,"tag":485,"props":593,"children":595},{"id":594},"step-3-generate-files",[596],{"type":47,"value":597},"Step 3: Generate Files",{"type":41,"tag":50,"props":599,"children":600},{},[601],{"type":47,"value":602},"Generate three files using these templates as the foundation:",{"type":41,"tag":604,"props":605,"children":606},"ol",{},[607,624,640],{"type":41,"tag":60,"props":608,"children":609},{},[610,615,617,622],{"type":41,"tag":176,"props":611,"children":612},{},[613],{"type":47,"value":614},"index.html",{"type":47,"value":616}," — Read ",{"type":41,"tag":502,"props":618,"children":620},{"href":619},"templates\u002Findex.html",[621],{"type":47,"value":619},{"type":47,"value":623}," for the base HTML structure",{"type":41,"tag":60,"props":625,"children":626},{},[627,632,633,638],{"type":41,"tag":176,"props":628,"children":629},{},[630],{"type":47,"value":631},"styles.css",{"type":47,"value":616},{"type":41,"tag":502,"props":634,"children":636},{"href":635},"templates\u002Fstyles.css",[637],{"type":47,"value":635},{"type":47,"value":639}," for the complete CSS",{"type":41,"tag":60,"props":641,"children":642},{},[643,648,649,654],{"type":41,"tag":176,"props":644,"children":645},{},[646],{"type":47,"value":647},"app.js",{"type":47,"value":616},{"type":41,"tag":502,"props":650,"children":652},{"href":651},"templates\u002Fapp.js",[653],{"type":47,"value":651},{"type":47,"value":655}," for the complete JS architecture",{"type":41,"tag":50,"props":657,"children":658},{},[659],{"type":47,"value":660},"Key requirements for the HTML:",{"type":41,"tag":56,"props":662,"children":663},{},[664,675,712,733,760,781,792],{"type":41,"tag":60,"props":665,"children":666},{},[667,669],{"type":47,"value":668},"Viewport: ",{"type":41,"tag":64,"props":670,"children":672},{"className":671},[],[673],{"type":47,"value":674},"width=600, height=600",{"type":41,"tag":60,"props":676,"children":677},{},[678,680,686,688,694,696,702,704,710],{"type":47,"value":679},"Additive display physics: pure black (",{"type":41,"tag":64,"props":681,"children":683},{"className":682},[],[684],{"type":47,"value":685},"#000000",{"type":47,"value":687},") renders as transparent on the additive waveguide display. Use black only for the page background\u002Ftransparent areas; visible UI surfaces such as cards, headers, rows, buttons, and panels must use dark gray tones (for example ",{"type":41,"tag":64,"props":689,"children":691},{"className":690},[],[692],{"type":47,"value":693},"#121417",{"type":47,"value":695},", ",{"type":41,"tag":64,"props":697,"children":699},{"className":698},[],[700],{"type":47,"value":701},"#1C1E21",{"type":47,"value":703},", or ",{"type":41,"tag":64,"props":705,"children":707},{"className":706},[],[708],{"type":47,"value":709},"#24262B",{"type":47,"value":711},") with light text.",{"type":41,"tag":60,"props":713,"children":714},{},[715,717,723,725,731],{"type":47,"value":716},"Description: ",{"type":41,"tag":64,"props":718,"children":720},{"className":719},[],[721],{"type":47,"value":722},"\u003Cmeta name=\"description\" content=\"...\">",{"type":47,"value":724}," in the ",{"type":41,"tag":64,"props":726,"children":728},{"className":727},[],[729],{"type":47,"value":730},"\u003Chead>",{"type":47,"value":732}," with a brief, app-specific summary of what the app does. Replace the template placeholder with real copy.",{"type":41,"tag":60,"props":734,"children":735},{},[736,738,744,745,750,752,758],{"type":47,"value":737},"MRBD identification: ",{"type":41,"tag":64,"props":739,"children":741},{"className":740},[],[742],{"type":47,"value":743},"\u003Cmeta name=\"mrbd-web-app-capable\" content=\"yes\">",{"type":47,"value":724},{"type":41,"tag":64,"props":746,"children":748},{"className":747},[],[749],{"type":47,"value":730},{"type":47,"value":751}," to positively identify the page as a Meta Display Glasses (MRBD) compatible webapp. Keep ",{"type":41,"tag":64,"props":753,"children":755},{"className":754},[],[756],{"type":47,"value":757},"content=\"yes\"",{"type":47,"value":759}," verbatim.",{"type":41,"tag":60,"props":761,"children":762},{},[763,765,771,773,779],{"type":47,"value":764},"All interactive elements: ",{"type":41,"tag":64,"props":766,"children":768},{"className":767},[],[769],{"type":47,"value":770},"class=\"focusable\"",{"type":47,"value":772}," and ",{"type":41,"tag":64,"props":774,"children":776},{"className":775},[],[777],{"type":47,"value":778},"tabindex=\"0\"",{"type":47,"value":780}," if not a button",{"type":41,"tag":60,"props":782,"children":783},{},[784,786],{"type":47,"value":785},"Button actions: ",{"type":41,"tag":64,"props":787,"children":789},{"className":788},[],[790],{"type":47,"value":791},"data-action=\"action-name\"",{"type":41,"tag":60,"props":793,"children":794},{},[795,797,803,805],{"type":47,"value":796},"Each screen is a ",{"type":41,"tag":64,"props":798,"children":800},{"className":799},[],[801],{"type":47,"value":802},"\u003Cdiv class=\"screen\">",{"type":47,"value":804}," with a unique ",{"type":41,"tag":64,"props":806,"children":808},{"className":807},[],[809],{"type":47,"value":810},"id",{"type":41,"tag":50,"props":812,"children":813},{},[814,816,821],{"type":47,"value":815},"Customize these sections in ",{"type":41,"tag":64,"props":817,"children":819},{"className":818},[],[820],{"type":47,"value":647},{"type":47,"value":822}," for each app:",{"type":41,"tag":56,"props":824,"children":825},{},[826,837,848,859],{"type":41,"tag":60,"props":827,"children":828},{},[829,835],{"type":41,"tag":64,"props":830,"children":832},{"className":831},[],[833],{"type":47,"value":834},"CONFIG",{"type":47,"value":836}," — API URLs, storage key, SDK options",{"type":41,"tag":60,"props":838,"children":839},{},[840,846],{"type":41,"tag":64,"props":841,"children":843},{"className":842},[],[844],{"type":47,"value":845},"state.data",{"type":47,"value":847}," — App-specific data shape",{"type":41,"tag":60,"props":849,"children":850},{},[851,857],{"type":41,"tag":64,"props":852,"children":854},{"className":853},[],[855],{"type":47,"value":856},"handleAppAction()",{"type":47,"value":858}," — App-specific action dispatch",{"type":41,"tag":60,"props":860,"children":861},{},[862,868],{"type":41,"tag":64,"props":863,"children":865},{"className":864},[],[866],{"type":47,"value":867},"onScreenEnter()",{"type":47,"value":869}," — Screen-specific data loading\u002Frendering",{"type":41,"tag":50,"props":871,"children":872},{},[873,875,880],{"type":47,"value":874},"Add app-specific styles to ",{"type":41,"tag":64,"props":876,"children":878},{"className":877},[],[879],{"type":47,"value":631},{"type":47,"value":881}," as needed, building on the template foundations.",{"type":41,"tag":50,"props":883,"children":884},{},[885],{"type":47,"value":886},"Framework guidance:",{"type":41,"tag":56,"props":888,"children":889},{},[890,895,900],{"type":41,"tag":60,"props":891,"children":892},{},[893],{"type":47,"value":894},"For new Meta Display Glasses webapps, recommend the vanilla HTML\u002FCSS\u002FJS scaffold from this skill as the default path.",{"type":41,"tag":60,"props":896,"children":897},{},[898],{"type":47,"value":899},"Advise against heavy frameworks such as React, Angular, Vue, or large UI component libraries for first-pass apps because they make the 500 KB gzipped bundle, 3 second initial load, 128 MB runtime memory, and 60 fps interaction budgets harder to hit.",{"type":41,"tag":60,"props":901,"children":902},{},[903],{"type":47,"value":904},"If a framework is truly required, prefer lightweight alternatives such as Preact, keep dependencies minimal, measure the gzipped production bundle early, and preserve the same D-pad focus model and display constraints.",{"type":41,"tag":485,"props":906,"children":908},{"id":907},"step-4-generate-the-favicon",[909],{"type":47,"value":910},"Step 4: Generate the Favicon",{"type":41,"tag":50,"props":912,"children":913},{},[914,916,922],{"type":47,"value":915},"Create a ",{"type":41,"tag":64,"props":917,"children":919},{"className":918},[],[920],{"type":47,"value":921},"favicon.png",{"type":47,"value":923}," themed to the app idea using the bundled pure-Python script (no dependencies — stdlib only).",{"type":41,"tag":50,"props":925,"children":926},{},[927],{"type":41,"tag":176,"props":928,"children":929},{},[930],{"type":47,"value":931},"Constraints (do not violate):",{"type":41,"tag":56,"props":933,"children":934},{},[935,947,965],{"type":41,"tag":60,"props":936,"children":937},{},[938,940,945],{"type":47,"value":939},"PNG format. ",{"type":41,"tag":176,"props":941,"children":942},{},[943],{"type":47,"value":944},"No SVG",{"type":47,"value":946}," — SVG favicons are not supported.",{"type":41,"tag":60,"props":948,"children":949},{},[950,952,957,959,964],{"type":47,"value":951},"Resolution ",{"type":41,"tag":176,"props":953,"children":954},{},[955],{"type":47,"value":956},"larger than 52×52",{"type":47,"value":958},". Default to ",{"type":41,"tag":176,"props":960,"children":961},{},[962],{"type":47,"value":963},"128×128",{"type":47,"value":225},{"type":41,"tag":60,"props":966,"children":967},{},[968,970,975,977,983],{"type":47,"value":969},"Must be referenced from both ",{"type":41,"tag":64,"props":971,"children":973},{"className":972},[],[974],{"type":47,"value":614},{"type":47,"value":976}," (",{"type":41,"tag":64,"props":978,"children":980},{"className":979},[],[981],{"type":47,"value":982},"\u003Clink rel=\"icon\">",{"type":47,"value":984},") and the Web App Manifest. The template already wires both.",{"type":41,"tag":50,"props":986,"children":987},{},[988],{"type":41,"tag":176,"props":989,"children":990},{},[991],{"type":47,"value":992},"How to generate:",{"type":41,"tag":604,"props":994,"children":995},{},[996,1001,1074],{"type":41,"tag":60,"props":997,"children":998},{},[999],{"type":47,"value":1000},"Design a small concept that maps to the app idea (e.g. NBA scores → orange basketball with a \"B\" glyph; weather → sun\u002Fcloud; music → note shape). Pick colors that contrast on a dark background.",{"type":41,"tag":60,"props":1002,"children":1003},{},[1004,1006,1012,1014,1020,1022,1028,1030,1036,1038,1044,1045,1051,1052,1058,1059,1065,1066,1072],{"type":47,"value":1005},"Build a JSON spec using the primitives the script supports: ",{"type":41,"tag":64,"props":1007,"children":1009},{"className":1008},[],[1010],{"type":47,"value":1011},"background",{"type":47,"value":1013}," (solid or vertical gradient), optional rounded ",{"type":41,"tag":64,"props":1015,"children":1017},{"className":1016},[],[1018],{"type":47,"value":1019},"plate",{"type":47,"value":1021},", and ",{"type":41,"tag":64,"props":1023,"children":1025},{"className":1024},[],[1026],{"type":47,"value":1027},"layers",{"type":47,"value":1029}," of ",{"type":41,"tag":64,"props":1031,"children":1033},{"className":1032},[],[1034],{"type":47,"value":1035},"circle",{"type":47,"value":1037}," \u002F ",{"type":41,"tag":64,"props":1039,"children":1041},{"className":1040},[],[1042],{"type":47,"value":1043},"ring",{"type":47,"value":1037},{"type":41,"tag":64,"props":1046,"children":1048},{"className":1047},[],[1049],{"type":47,"value":1050},"rrect",{"type":47,"value":1037},{"type":41,"tag":64,"props":1053,"children":1055},{"className":1054},[],[1056],{"type":47,"value":1057},"polygon",{"type":47,"value":1037},{"type":41,"tag":64,"props":1060,"children":1062},{"className":1061},[],[1063],{"type":47,"value":1064},"points",{"type":47,"value":1037},{"type":41,"tag":64,"props":1067,"children":1069},{"className":1068},[],[1070],{"type":47,"value":1071},"glyph",{"type":47,"value":1073},". See the script header for the full schema.",{"type":41,"tag":60,"props":1075,"children":1076},{},[1077],{"type":47,"value":1078},"Render the PNG into the app directory:",{"type":41,"tag":467,"props":1080,"children":1082},{"className":540,"code":1081,"language":542,"meta":475,"style":475},"python3 \u003Cplugin-path>\u002Fskills\u002Fcreate-webapp\u002Fscripts\u002Ffavicon_generator.py \\\n  --spec - --out \u003Capp-name>\u002Ffavicon.png \u003C\u003C'EOF'\n{\n  \"size\": 128,\n  \"background\": {\"type\": \"gradient\", \"from\": \"#1C1E21\", \"to\": \"#0A0B0C\"},\n  \"plate\": {\"color\": \"#FF6B35\", \"radius\": 28, \"inset\": 8},\n  \"layers\": [\n    {\"type\": \"ring\", \"cx\": 64, \"cy\": 64, \"r\": 38, \"width\": 4, \"color\": \"#1C1E21\"},\n    {\"type\": \"glyph\", \"char\": \"B\", \"cx\": 64, \"cy\": 64, \"scale\": 7, \"color\": \"#1C1E21\"}\n  ]\n}\nEOF\n",[1083],{"type":41,"tag":64,"props":1084,"children":1085},{"__ignoreMap":475},[1086,1124,1174,1183,1192,1201,1210,1219,1228,1237,1246,1255],{"type":41,"tag":548,"props":1087,"children":1088},{"class":550,"line":551},[1089,1094,1099,1104,1109,1114,1119],{"type":41,"tag":548,"props":1090,"children":1091},{"style":555},[1092],{"type":47,"value":1093},"python3",{"type":41,"tag":548,"props":1095,"children":1096},{"style":572},[1097],{"type":47,"value":1098}," \u003C",{"type":41,"tag":548,"props":1100,"children":1101},{"style":561},[1102],{"type":47,"value":1103},"plugin-pat",{"type":41,"tag":548,"props":1105,"children":1106},{"style":583},[1107],{"type":47,"value":1108},"h",{"type":41,"tag":548,"props":1110,"children":1111},{"style":572},[1112],{"type":47,"value":1113},">",{"type":41,"tag":548,"props":1115,"children":1116},{"style":561},[1117],{"type":47,"value":1118},"\u002Fskills\u002Fcreate-webapp\u002Fscripts\u002Ffavicon_generator.py",{"type":41,"tag":548,"props":1120,"children":1121},{"style":583},[1122],{"type":47,"value":1123}," \\\n",{"type":41,"tag":548,"props":1125,"children":1127},{"class":550,"line":1126},2,[1128,1133,1138,1143,1147,1151,1155,1159,1164,1169],{"type":41,"tag":548,"props":1129,"children":1130},{"style":561},[1131],{"type":47,"value":1132},"  --spec",{"type":41,"tag":548,"props":1134,"children":1135},{"style":561},[1136],{"type":47,"value":1137}," -",{"type":41,"tag":548,"props":1139,"children":1140},{"style":561},[1141],{"type":47,"value":1142}," --out",{"type":41,"tag":548,"props":1144,"children":1145},{"style":572},[1146],{"type":47,"value":1098},{"type":41,"tag":548,"props":1148,"children":1149},{"style":561},[1150],{"type":47,"value":580},{"type":41,"tag":548,"props":1152,"children":1153},{"style":583},[1154],{"type":47,"value":586},{"type":41,"tag":548,"props":1156,"children":1157},{"style":572},[1158],{"type":47,"value":1113},{"type":41,"tag":548,"props":1160,"children":1161},{"style":561},[1162],{"type":47,"value":1163},"\u002Ffavicon.png",{"type":41,"tag":548,"props":1165,"children":1166},{"style":572},[1167],{"type":47,"value":1168}," \u003C\u003C",{"type":41,"tag":548,"props":1170,"children":1171},{"style":572},[1172],{"type":47,"value":1173},"'EOF'\n",{"type":41,"tag":548,"props":1175,"children":1177},{"class":550,"line":1176},3,[1178],{"type":41,"tag":548,"props":1179,"children":1180},{"style":561},[1181],{"type":47,"value":1182},"{\n",{"type":41,"tag":548,"props":1184,"children":1186},{"class":550,"line":1185},4,[1187],{"type":41,"tag":548,"props":1188,"children":1189},{"style":561},[1190],{"type":47,"value":1191},"  \"size\": 128,\n",{"type":41,"tag":548,"props":1193,"children":1195},{"class":550,"line":1194},5,[1196],{"type":41,"tag":548,"props":1197,"children":1198},{"style":561},[1199],{"type":47,"value":1200},"  \"background\": {\"type\": \"gradient\", \"from\": \"#1C1E21\", \"to\": \"#0A0B0C\"},\n",{"type":41,"tag":548,"props":1202,"children":1204},{"class":550,"line":1203},6,[1205],{"type":41,"tag":548,"props":1206,"children":1207},{"style":561},[1208],{"type":47,"value":1209},"  \"plate\": {\"color\": \"#FF6B35\", \"radius\": 28, \"inset\": 8},\n",{"type":41,"tag":548,"props":1211,"children":1213},{"class":550,"line":1212},7,[1214],{"type":41,"tag":548,"props":1215,"children":1216},{"style":561},[1217],{"type":47,"value":1218},"  \"layers\": [\n",{"type":41,"tag":548,"props":1220,"children":1222},{"class":550,"line":1221},8,[1223],{"type":41,"tag":548,"props":1224,"children":1225},{"style":561},[1226],{"type":47,"value":1227},"    {\"type\": \"ring\", \"cx\": 64, \"cy\": 64, \"r\": 38, \"width\": 4, \"color\": \"#1C1E21\"},\n",{"type":41,"tag":548,"props":1229,"children":1231},{"class":550,"line":1230},9,[1232],{"type":41,"tag":548,"props":1233,"children":1234},{"style":561},[1235],{"type":47,"value":1236},"    {\"type\": \"glyph\", \"char\": \"B\", \"cx\": 64, \"cy\": 64, \"scale\": 7, \"color\": \"#1C1E21\"}\n",{"type":41,"tag":548,"props":1238,"children":1240},{"class":550,"line":1239},10,[1241],{"type":41,"tag":548,"props":1242,"children":1243},{"style":561},[1244],{"type":47,"value":1245},"  ]\n",{"type":41,"tag":548,"props":1247,"children":1249},{"class":550,"line":1248},11,[1250],{"type":41,"tag":548,"props":1251,"children":1252},{"style":561},[1253],{"type":47,"value":1254},"}\n",{"type":41,"tag":548,"props":1256,"children":1258},{"class":550,"line":1257},12,[1259],{"type":41,"tag":548,"props":1260,"children":1261},{"style":572},[1262],{"type":47,"value":1263},"EOF\n",{"type":41,"tag":604,"props":1265,"children":1266},{"start":1185},[1267],{"type":41,"tag":60,"props":1268,"children":1269},{},[1270,1272,1278,1280,1285],{"type":47,"value":1271},"Write ",{"type":41,"tag":64,"props":1273,"children":1275},{"className":1274},[],[1276],{"type":47,"value":1277},"manifest.webmanifest",{"type":47,"value":1279}," next to ",{"type":41,"tag":64,"props":1281,"children":1283},{"className":1282},[],[1284],{"type":47,"value":614},{"type":47,"value":1286},":",{"type":41,"tag":467,"props":1288,"children":1292},{"className":1289,"code":1290,"language":1291,"meta":475,"style":475},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"name\": \"\u003CApp Name>\",\n  \"short_name\": \"\u003CApp Name>\",\n  \"icons\": [\n    { \"src\": \"favicon.png\", \"sizes\": \"128x128\", \"type\": \"image\u002Fpng\" }\n  ],\n  \"background_color\": \"#000000\",\n  \"theme_color\": \"#000000\",\n  \"display\": \"standalone\"\n}\n","json",[1293],{"type":41,"tag":64,"props":1294,"children":1295},{"__ignoreMap":475},[1296,1303,1345,1381,1406,1517,1525,1561,1597,1631],{"type":41,"tag":548,"props":1297,"children":1298},{"class":550,"line":551},[1299],{"type":41,"tag":548,"props":1300,"children":1301},{"style":572},[1302],{"type":47,"value":1182},{"type":41,"tag":548,"props":1304,"children":1305},{"class":550,"line":1126},[1306,1311,1317,1322,1326,1331,1336,1340],{"type":41,"tag":548,"props":1307,"children":1308},{"style":572},[1309],{"type":47,"value":1310},"  \"",{"type":41,"tag":548,"props":1312,"children":1314},{"style":1313},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[1315],{"type":47,"value":1316},"name",{"type":41,"tag":548,"props":1318,"children":1319},{"style":572},[1320],{"type":47,"value":1321},"\"",{"type":41,"tag":548,"props":1323,"children":1324},{"style":572},[1325],{"type":47,"value":1286},{"type":41,"tag":548,"props":1327,"children":1328},{"style":572},[1329],{"type":47,"value":1330}," \"",{"type":41,"tag":548,"props":1332,"children":1333},{"style":561},[1334],{"type":47,"value":1335},"\u003CApp Name>",{"type":41,"tag":548,"props":1337,"children":1338},{"style":572},[1339],{"type":47,"value":1321},{"type":41,"tag":548,"props":1341,"children":1342},{"style":572},[1343],{"type":47,"value":1344},",\n",{"type":41,"tag":548,"props":1346,"children":1347},{"class":550,"line":1176},[1348,1352,1357,1361,1365,1369,1373,1377],{"type":41,"tag":548,"props":1349,"children":1350},{"style":572},[1351],{"type":47,"value":1310},{"type":41,"tag":548,"props":1353,"children":1354},{"style":1313},[1355],{"type":47,"value":1356},"short_name",{"type":41,"tag":548,"props":1358,"children":1359},{"style":572},[1360],{"type":47,"value":1321},{"type":41,"tag":548,"props":1362,"children":1363},{"style":572},[1364],{"type":47,"value":1286},{"type":41,"tag":548,"props":1366,"children":1367},{"style":572},[1368],{"type":47,"value":1330},{"type":41,"tag":548,"props":1370,"children":1371},{"style":561},[1372],{"type":47,"value":1335},{"type":41,"tag":548,"props":1374,"children":1375},{"style":572},[1376],{"type":47,"value":1321},{"type":41,"tag":548,"props":1378,"children":1379},{"style":572},[1380],{"type":47,"value":1344},{"type":41,"tag":548,"props":1382,"children":1383},{"class":550,"line":1185},[1384,1388,1393,1397,1401],{"type":41,"tag":548,"props":1385,"children":1386},{"style":572},[1387],{"type":47,"value":1310},{"type":41,"tag":548,"props":1389,"children":1390},{"style":1313},[1391],{"type":47,"value":1392},"icons",{"type":41,"tag":548,"props":1394,"children":1395},{"style":572},[1396],{"type":47,"value":1321},{"type":41,"tag":548,"props":1398,"children":1399},{"style":572},[1400],{"type":47,"value":1286},{"type":41,"tag":548,"props":1402,"children":1403},{"style":572},[1404],{"type":47,"value":1405}," [\n",{"type":41,"tag":548,"props":1407,"children":1408},{"class":550,"line":1194},[1409,1414,1418,1423,1427,1431,1435,1439,1443,1448,1452,1457,1461,1465,1469,1474,1478,1482,1486,1491,1495,1499,1503,1508,1512],{"type":41,"tag":548,"props":1410,"children":1411},{"style":572},[1412],{"type":47,"value":1413},"    {",{"type":41,"tag":548,"props":1415,"children":1416},{"style":572},[1417],{"type":47,"value":1330},{"type":41,"tag":548,"props":1419,"children":1420},{"style":555},[1421],{"type":47,"value":1422},"src",{"type":41,"tag":548,"props":1424,"children":1425},{"style":572},[1426],{"type":47,"value":1321},{"type":41,"tag":548,"props":1428,"children":1429},{"style":572},[1430],{"type":47,"value":1286},{"type":41,"tag":548,"props":1432,"children":1433},{"style":572},[1434],{"type":47,"value":1330},{"type":41,"tag":548,"props":1436,"children":1437},{"style":561},[1438],{"type":47,"value":921},{"type":41,"tag":548,"props":1440,"children":1441},{"style":572},[1442],{"type":47,"value":1321},{"type":41,"tag":548,"props":1444,"children":1445},{"style":572},[1446],{"type":47,"value":1447},",",{"type":41,"tag":548,"props":1449,"children":1450},{"style":572},[1451],{"type":47,"value":1330},{"type":41,"tag":548,"props":1453,"children":1454},{"style":555},[1455],{"type":47,"value":1456},"sizes",{"type":41,"tag":548,"props":1458,"children":1459},{"style":572},[1460],{"type":47,"value":1321},{"type":41,"tag":548,"props":1462,"children":1463},{"style":572},[1464],{"type":47,"value":1286},{"type":41,"tag":548,"props":1466,"children":1467},{"style":572},[1468],{"type":47,"value":1330},{"type":41,"tag":548,"props":1470,"children":1471},{"style":561},[1472],{"type":47,"value":1473},"128x128",{"type":41,"tag":548,"props":1475,"children":1476},{"style":572},[1477],{"type":47,"value":1321},{"type":41,"tag":548,"props":1479,"children":1480},{"style":572},[1481],{"type":47,"value":1447},{"type":41,"tag":548,"props":1483,"children":1484},{"style":572},[1485],{"type":47,"value":1330},{"type":41,"tag":548,"props":1487,"children":1488},{"style":555},[1489],{"type":47,"value":1490},"type",{"type":41,"tag":548,"props":1492,"children":1493},{"style":572},[1494],{"type":47,"value":1321},{"type":41,"tag":548,"props":1496,"children":1497},{"style":572},[1498],{"type":47,"value":1286},{"type":41,"tag":548,"props":1500,"children":1501},{"style":572},[1502],{"type":47,"value":1330},{"type":41,"tag":548,"props":1504,"children":1505},{"style":561},[1506],{"type":47,"value":1507},"image\u002Fpng",{"type":41,"tag":548,"props":1509,"children":1510},{"style":572},[1511],{"type":47,"value":1321},{"type":41,"tag":548,"props":1513,"children":1514},{"style":572},[1515],{"type":47,"value":1516}," }\n",{"type":41,"tag":548,"props":1518,"children":1519},{"class":550,"line":1203},[1520],{"type":41,"tag":548,"props":1521,"children":1522},{"style":572},[1523],{"type":47,"value":1524},"  ],\n",{"type":41,"tag":548,"props":1526,"children":1527},{"class":550,"line":1212},[1528,1532,1537,1541,1545,1549,1553,1557],{"type":41,"tag":548,"props":1529,"children":1530},{"style":572},[1531],{"type":47,"value":1310},{"type":41,"tag":548,"props":1533,"children":1534},{"style":1313},[1535],{"type":47,"value":1536},"background_color",{"type":41,"tag":548,"props":1538,"children":1539},{"style":572},[1540],{"type":47,"value":1321},{"type":41,"tag":548,"props":1542,"children":1543},{"style":572},[1544],{"type":47,"value":1286},{"type":41,"tag":548,"props":1546,"children":1547},{"style":572},[1548],{"type":47,"value":1330},{"type":41,"tag":548,"props":1550,"children":1551},{"style":561},[1552],{"type":47,"value":685},{"type":41,"tag":548,"props":1554,"children":1555},{"style":572},[1556],{"type":47,"value":1321},{"type":41,"tag":548,"props":1558,"children":1559},{"style":572},[1560],{"type":47,"value":1344},{"type":41,"tag":548,"props":1562,"children":1563},{"class":550,"line":1221},[1564,1568,1573,1577,1581,1585,1589,1593],{"type":41,"tag":548,"props":1565,"children":1566},{"style":572},[1567],{"type":47,"value":1310},{"type":41,"tag":548,"props":1569,"children":1570},{"style":1313},[1571],{"type":47,"value":1572},"theme_color",{"type":41,"tag":548,"props":1574,"children":1575},{"style":572},[1576],{"type":47,"value":1321},{"type":41,"tag":548,"props":1578,"children":1579},{"style":572},[1580],{"type":47,"value":1286},{"type":41,"tag":548,"props":1582,"children":1583},{"style":572},[1584],{"type":47,"value":1330},{"type":41,"tag":548,"props":1586,"children":1587},{"style":561},[1588],{"type":47,"value":685},{"type":41,"tag":548,"props":1590,"children":1591},{"style":572},[1592],{"type":47,"value":1321},{"type":41,"tag":548,"props":1594,"children":1595},{"style":572},[1596],{"type":47,"value":1344},{"type":41,"tag":548,"props":1598,"children":1599},{"class":550,"line":1230},[1600,1604,1609,1613,1617,1621,1626],{"type":41,"tag":548,"props":1601,"children":1602},{"style":572},[1603],{"type":47,"value":1310},{"type":41,"tag":548,"props":1605,"children":1606},{"style":1313},[1607],{"type":47,"value":1608},"display",{"type":41,"tag":548,"props":1610,"children":1611},{"style":572},[1612],{"type":47,"value":1321},{"type":41,"tag":548,"props":1614,"children":1615},{"style":572},[1616],{"type":47,"value":1286},{"type":41,"tag":548,"props":1618,"children":1619},{"style":572},[1620],{"type":47,"value":1330},{"type":41,"tag":548,"props":1622,"children":1623},{"style":561},[1624],{"type":47,"value":1625},"standalone",{"type":41,"tag":548,"props":1627,"children":1628},{"style":572},[1629],{"type":47,"value":1630},"\"\n",{"type":41,"tag":548,"props":1632,"children":1633},{"class":550,"line":1239},[1634],{"type":41,"tag":548,"props":1635,"children":1636},{"style":572},[1637],{"type":47,"value":1254},{"type":41,"tag":50,"props":1639,"children":1640},{},[1641,1643,1648,1649,1655,1657,1662],{"type":47,"value":1642},"The ",{"type":41,"tag":64,"props":1644,"children":1646},{"className":1645},[],[1647],{"type":47,"value":982},{"type":47,"value":772},{"type":41,"tag":64,"props":1650,"children":1652},{"className":1651},[],[1653],{"type":47,"value":1654},"\u003Clink rel=\"manifest\">",{"type":47,"value":1656}," references are already present in ",{"type":41,"tag":64,"props":1658,"children":1660},{"className":1659},[],[1661],{"type":47,"value":619},{"type":47,"value":1663}," — no HTML edits needed.",{"type":41,"tag":485,"props":1665,"children":1667},{"id":1666},"step-5-for-api-connected-apps",[1668],{"type":47,"value":1669},"Step 5: For API-Connected Apps",{"type":41,"tag":50,"props":1671,"children":1672},{},[1673,1675,1680],{"type":47,"value":1674},"See ",{"type":41,"tag":502,"props":1676,"children":1678},{"href":1677},"references\u002Fapi-catalog.md",[1679],{"type":47,"value":1677},{"type":47,"value":1681}," for free public APIs and integration patterns.",{"type":41,"tag":485,"props":1683,"children":1685},{"id":1684},"step-6-for-sensor-apps",[1686],{"type":47,"value":1687},"Step 6: For Sensor Apps",{"type":41,"tag":50,"props":1689,"children":1690},{},[1691,1693,1698],{"type":47,"value":1692},"Use ",{"type":41,"tag":64,"props":1694,"children":1696},{"className":1695},[],[1697],{"type":47,"value":427},{"type":47,"value":1699}," to add motion, orientation, or GPS data to the webapp.",{"type":41,"tag":485,"props":1701,"children":1703},{"id":1702},"step-7-for-ui-components",[1704],{"type":47,"value":1705},"Step 7: For UI Components",{"type":41,"tag":50,"props":1707,"children":1708},{},[1709,1710,1715],{"type":47,"value":1674},{"type":41,"tag":502,"props":1711,"children":1713},{"href":1712},"references\u002Fui-components.md",[1714],{"type":47,"value":1712},{"type":47,"value":1716}," for reusable HTML component patterns (cards, lists, tabs, loading states).",{"type":41,"tag":485,"props":1718,"children":1720},{"id":1719},"step-8-verify",[1721],{"type":47,"value":1722},"Step 8: Verify",{"type":41,"tag":56,"props":1724,"children":1727},{"className":1725},[1726],"contains-task-list",[1728,1754,1771,1788,1802,1826,1846,1855,1864,1873,1882,1891,1900,1909,1918,1927,1936,1959,1968,1994],{"type":41,"tag":60,"props":1729,"children":1732},{"className":1730},[1731],"task-list-item",[1733,1739,1741,1747,1749],{"type":41,"tag":1734,"props":1735,"children":1738},"input",{"disabled":1736,"type":1737},true,"checkbox",[],{"type":47,"value":1740}," All screens have ",{"type":41,"tag":64,"props":1742,"children":1744},{"className":1743},[],[1745],{"type":47,"value":1746},".screen",{"type":47,"value":1748}," class and unique ",{"type":41,"tag":64,"props":1750,"children":1752},{"className":1751},[],[1753],{"type":47,"value":810},{"type":41,"tag":60,"props":1755,"children":1757},{"className":1756},[1731],[1758,1761,1763,1769],{"type":41,"tag":1734,"props":1759,"children":1760},{"disabled":1736,"type":1737},[],{"type":47,"value":1762}," All interactive elements have ",{"type":41,"tag":64,"props":1764,"children":1766},{"className":1765},[],[1767],{"type":47,"value":1768},".focusable",{"type":47,"value":1770}," class",{"type":41,"tag":60,"props":1772,"children":1774},{"className":1773},[1731],[1775,1778,1780,1786],{"type":41,"tag":1734,"props":1776,"children":1777},{"disabled":1736,"type":1737},[],{"type":47,"value":1779}," Buttons have ",{"type":41,"tag":64,"props":1781,"children":1783},{"className":1782},[],[1784],{"type":47,"value":1785},"data-action",{"type":47,"value":1787}," attributes",{"type":41,"tag":60,"props":1789,"children":1791},{"className":1790},[1731],[1792,1795,1797],{"type":41,"tag":1734,"props":1793,"children":1794},{"disabled":1736,"type":1737},[],{"type":47,"value":1796}," Viewport is ",{"type":41,"tag":64,"props":1798,"children":1800},{"className":1799},[],[1801],{"type":47,"value":674},{"type":41,"tag":60,"props":1803,"children":1805},{"className":1804},[1731],[1806,1809,1811,1816,1818,1824],{"type":41,"tag":1734,"props":1807,"children":1808},{"disabled":1736,"type":1737},[],{"type":47,"value":1810}," ",{"type":41,"tag":64,"props":1812,"children":1814},{"className":1813},[],[1815],{"type":47,"value":730},{"type":47,"value":1817}," has a ",{"type":41,"tag":64,"props":1819,"children":1821},{"className":1820},[],[1822],{"type":47,"value":1823},"\u003Cmeta name=\"description\">",{"type":47,"value":1825}," tag with an app-specific summary (placeholder replaced)",{"type":41,"tag":60,"props":1827,"children":1829},{"className":1828},[1731],[1830,1833,1834,1839,1841],{"type":41,"tag":1734,"props":1831,"children":1832},{"disabled":1736,"type":1737},[],{"type":47,"value":1810},{"type":41,"tag":64,"props":1835,"children":1837},{"className":1836},[],[1838],{"type":47,"value":730},{"type":47,"value":1840}," has ",{"type":41,"tag":64,"props":1842,"children":1844},{"className":1843},[],[1845],{"type":47,"value":743},{"type":41,"tag":60,"props":1847,"children":1849},{"className":1848},[1731],[1850,1853],{"type":41,"tag":1734,"props":1851,"children":1852},{"disabled":1736,"type":1737},[],{"type":47,"value":1854}," D-pad navigation works (arrow keys move focus with wrap-around)",{"type":41,"tag":60,"props":1856,"children":1858},{"className":1857},[1731],[1859,1862],{"type":41,"tag":1734,"props":1860,"children":1861},{"disabled":1736,"type":1737},[],{"type":47,"value":1863}," Enter key activates focused elements",{"type":41,"tag":60,"props":1865,"children":1867},{"className":1866},[1731],[1868,1871],{"type":41,"tag":1734,"props":1869,"children":1870},{"disabled":1736,"type":1737},[],{"type":47,"value":1872}," Escape key navigates back",{"type":41,"tag":60,"props":1874,"children":1876},{"className":1875},[1731],[1877,1880],{"type":41,"tag":1734,"props":1878,"children":1879},{"disabled":1736,"type":1737},[],{"type":47,"value":1881}," Focus ring is visible (cyan glow) on selected elements",{"type":41,"tag":60,"props":1883,"children":1885},{"className":1884},[1731],[1886,1889],{"type":41,"tag":1734,"props":1887,"children":1888},{"disabled":1736,"type":1737},[],{"type":47,"value":1890}," Loading states shown during API calls",{"type":41,"tag":60,"props":1892,"children":1894},{"className":1893},[1731],[1895,1898],{"type":41,"tag":1734,"props":1896,"children":1897},{"disabled":1736,"type":1737},[],{"type":47,"value":1899}," Error states handle API failures gracefully",{"type":41,"tag":60,"props":1901,"children":1903},{"className":1902},[1731],[1904,1907],{"type":41,"tag":1734,"props":1905,"children":1906},{"disabled":1736,"type":1737},[],{"type":47,"value":1908}," Demo mode works when sensors are unavailable",{"type":41,"tag":60,"props":1910,"children":1912},{"className":1911},[1731],[1913,1916],{"type":41,"tag":1734,"props":1914,"children":1915},{"disabled":1736,"type":1737},[],{"type":47,"value":1917}," Data persists via localStorage",{"type":41,"tag":60,"props":1919,"children":1921},{"className":1920},[1731],[1922,1925],{"type":41,"tag":1734,"props":1923,"children":1924},{"disabled":1736,"type":1737},[],{"type":47,"value":1926}," All text is readable on dark background",{"type":41,"tag":60,"props":1928,"children":1930},{"className":1929},[1731],[1931,1934],{"type":41,"tag":1734,"props":1932,"children":1933},{"disabled":1736,"type":1737},[],{"type":47,"value":1935}," Content fits within 600x600 viewport",{"type":41,"tag":60,"props":1937,"children":1939},{"className":1938},[1731],[1940,1943,1945,1951,1953],{"type":41,"tag":1734,"props":1941,"children":1942},{"disabled":1736,"type":1737},[],{"type":47,"value":1944}," Scrollable lists use ",{"type":41,"tag":64,"props":1946,"children":1948},{"className":1947},[],[1949],{"type":47,"value":1950},"overflow-y: auto",{"type":47,"value":1952}," with ",{"type":41,"tag":64,"props":1954,"children":1956},{"className":1955},[],[1957],{"type":47,"value":1958},"max-height",{"type":41,"tag":60,"props":1960,"children":1962},{"className":1961},[1731],[1963,1966],{"type":41,"tag":1734,"props":1964,"children":1965},{"disabled":1736,"type":1737},[],{"type":47,"value":1967}," Focused elements scroll into view automatically",{"type":41,"tag":60,"props":1969,"children":1971},{"className":1970},[1731],[1972,1975,1976,1981,1983,1988,1989],{"type":41,"tag":1734,"props":1973,"children":1974},{"disabled":1736,"type":1737},[],{"type":47,"value":1810},{"type":41,"tag":64,"props":1977,"children":1979},{"className":1978},[],[1980],{"type":47,"value":921},{"type":47,"value":1982}," exists at the app root, is >52×52 PNG (not SVG), and is referenced from both ",{"type":41,"tag":64,"props":1984,"children":1986},{"className":1985},[],[1987],{"type":47,"value":614},{"type":47,"value":772},{"type":41,"tag":64,"props":1990,"children":1992},{"className":1991},[],[1993],{"type":47,"value":1277},{"type":41,"tag":60,"props":1995,"children":1997},{"className":1996},[1731],[1998,2001],{"type":41,"tag":1734,"props":1999,"children":2000},{"disabled":1736,"type":1737},[],{"type":47,"value":2002}," Agent surfaced the hosting\u002Ftest next-step prompt (Step 10)",{"type":41,"tag":485,"props":2004,"children":2006},{"id":2005},"step-9-guide-next-steps",[2007],{"type":47,"value":2008},"Step 9: Guide Next Steps",{"type":41,"tag":467,"props":2010,"children":2013},{"className":2011,"code":2012,"language":47},[470],"Created: ~\u002Fmeta-display-glasses-webapps\u002F\u003Capp-name>\u002F\n  index.html              (screens, structure)\n  styles.css              (dark theme, focus states, loading\u002Ferror states)\n  app.js                  (D-pad nav, API calls, SDK integration)\n  favicon.png             (themed app icon)\n  manifest.webmanifest    (web app manifest)\n\nExpand with:\n  \u002Fadd-ui               Add screens, buttons, UI components\n  \u002Fadd-text-input       Add text fields, search boxes, forms\n  \u002Fadd-gestures         Add sliders, drawing, maps (continuous drag)\n  \u002Fadd-offline          Make the app work without Wi-Fi\n  \u002Fconnect-api          Connect to more APIs\n  \u002Fadd-device-sensors   Add motion\u002Forientation\u002FGPS sensors\n  \u002Fadd-local-storage    Add data persistence\n\nTest locally by opening index.html in a browser and using arrow keys + Enter.\n",[2014],{"type":41,"tag":64,"props":2015,"children":2016},{"__ignoreMap":475},[2017],{"type":47,"value":2012},{"type":41,"tag":485,"props":2019,"children":2021},{"id":2020},"step-10-offer-a-hosting-path",[2022],{"type":47,"value":2023},"Step 10: Offer a Hosting Path",{"type":41,"tag":50,"props":2025,"children":2026},{},[2027],{"type":47,"value":2028},"After expansion options, ask the user how they want to run the app on Meta Display Glasses. The glasses load webapps via HTTPS, so the app needs to be hosted on a public URL.",{"type":41,"tag":50,"props":2030,"children":2031},{},[2032],{"type":47,"value":2033},"Prompt the user with:",{"type":41,"tag":2035,"props":2036,"children":2037},"blockquote",{},[2038,2043,2090],{"type":41,"tag":50,"props":2039,"children":2040},{},[2041],{"type":47,"value":2042},"Your webapp is ready and works locally. To run it on Meta Display Glasses, it needs to be hosted on a public HTTPS URL. Two options:",{"type":41,"tag":56,"props":2044,"children":2045},{},[2046,2068],{"type":41,"tag":60,"props":2047,"children":2048},{},[2049,2058,2060,2066],{"type":41,"tag":176,"props":2050,"children":2051},{},[2052],{"type":41,"tag":64,"props":2053,"children":2055},{"className":2054},[],[2056],{"type":47,"value":2057},"\u002Ftest-on-device",{"type":47,"value":2059}," — deploy to a public staging URL (e.g. ",{"type":41,"tag":64,"props":2061,"children":2063},{"className":2062},[],[2064],{"type":47,"value":2065},"stage-\u003Capp>.vercel.app",{"type":47,"value":2067},") for iterating",{"type":41,"tag":60,"props":2069,"children":2070},{},[2071,2080,2082,2088],{"type":41,"tag":176,"props":2072,"children":2073},{},[2074],{"type":41,"tag":64,"props":2075,"children":2077},{"className":2076},[],[2078],{"type":47,"value":2079},"\u002Fpublish-to-vercel",{"type":47,"value":2081}," — publish to a stable production URL (e.g. ",{"type":41,"tag":64,"props":2083,"children":2085},{"className":2084},[],[2086],{"type":47,"value":2087},"\u003Capp>.vercel.app",{"type":47,"value":2089},")",{"type":41,"tag":50,"props":2091,"children":2092},{},[2093],{"type":47,"value":2094},"Both use Vercel (free tier works) and I can set the whole thing up for you. If you'd rather host the app yourself elsewhere, you can skip both — anywhere that serves HTTPS will work.",{"type":41,"tag":50,"props":2096,"children":2097},{},[2098],{"type":47,"value":2099},"Do not auto-invoke either skill. Wait for the user's choice.",{"type":41,"tag":42,"props":2101,"children":2103},{"id":2102},"speeding-up-iteration-optional",[2104],{"type":47,"value":2105},"Speeding up iteration (optional)",{"type":41,"tag":50,"props":2107,"children":2108},{},[2109,2111,2116,2118,2123,2125,2131,2133,2138,2140,2145],{"type":47,"value":2110},"Iterating on the glasses (build → install → test on-device) is slow. ",{"type":41,"tag":176,"props":2112,"children":2113},{},[2114],{"type":47,"value":2115},"When that on-device round-trip is the bottleneck, offer the user a much faster off-device loop:",{"type":47,"value":2117}," Claude attaches to a ",{"type":41,"tag":176,"props":2119,"children":2120},{},[2121],{"type":47,"value":2122},"user-launched",{"type":47,"value":2124}," Chromium\u002FEdge serving the app from localhost over the Chrome DevTools Protocol (started with ",{"type":41,"tag":64,"props":2126,"children":2128},{"className":2127},[],[2129],{"type":47,"value":2130},"--remote-debugging-port=9222",{"type":47,"value":2132},"), then hot-reload-iterates the app and drives the D-pad user journeys each cycle — no device, no rebuild between edits. The user can also ",{"type":41,"tag":176,"props":2134,"children":2135},{},[2136],{"type":47,"value":2137},"take control of the same tab",{"type":47,"value":2139}," and play with the app directly while iterating. Validate the final result ",{"type":41,"tag":176,"props":2141,"children":2142},{},[2143],{"type":47,"value":2144},"on-device",{"type":47,"value":2146}," before calling it done — the fast loop is for iterating, not for proving on-device parity.",{"type":41,"tag":50,"props":2148,"children":2149},{},[2150],{"type":47,"value":2151},"Offer this only when on-device iteration is actually slowing the user down; it's a speed-up, not the default.",{"type":41,"tag":42,"props":2153,"children":2155},{"id":2154},"troubleshooting",[2156],{"type":47,"value":2157},"Troubleshooting",{"type":41,"tag":276,"props":2159,"children":2160},{},[2161,2177],{"type":41,"tag":280,"props":2162,"children":2163},{},[2164],{"type":41,"tag":284,"props":2165,"children":2166},{},[2167,2172],{"type":41,"tag":288,"props":2168,"children":2169},{},[2170],{"type":47,"value":2171},"Issue",{"type":41,"tag":288,"props":2173,"children":2174},{},[2175],{"type":47,"value":2176},"Solution",{"type":41,"tag":304,"props":2178,"children":2179},{},[2180,2193,2213,2234,2253,2273,2286,2305,2318,2338,2366],{"type":41,"tag":284,"props":2181,"children":2182},{},[2183,2188],{"type":41,"tag":311,"props":2184,"children":2185},{},[2186],{"type":47,"value":2187},"Webapp doesn't load on device",{"type":41,"tag":311,"props":2189,"children":2190},{},[2191],{"type":47,"value":2192},"Check browser console for JS errors",{"type":41,"tag":284,"props":2194,"children":2195},{},[2196,2201],{"type":41,"tag":311,"props":2197,"children":2198},{},[2199],{"type":47,"value":2200},"Focus ring not visible",{"type":41,"tag":311,"props":2202,"children":2203},{},[2204,2206,2211],{"type":47,"value":2205},"Verify ",{"type":41,"tag":64,"props":2207,"children":2209},{"className":2208},[],[2210],{"type":47,"value":1768},{"type":47,"value":2212}," class on interactive elements",{"type":41,"tag":284,"props":2214,"children":2215},{},[2216,2221],{"type":41,"tag":311,"props":2217,"children":2218},{},[2219],{"type":47,"value":2220},"D-pad not navigating",{"type":41,"tag":311,"props":2222,"children":2223},{},[2224,2226,2232],{"type":47,"value":2225},"Check ",{"type":41,"tag":64,"props":2227,"children":2229},{"className":2228},[],[2230],{"type":47,"value":2231},"moveFocus()",{"type":47,"value":2233}," handles the current screen",{"type":41,"tag":284,"props":2235,"children":2236},{},[2237,2242],{"type":41,"tag":311,"props":2238,"children":2239},{},[2240],{"type":47,"value":2241},"Enter not activating",{"type":41,"tag":311,"props":2243,"children":2244},{},[2245,2246,2251],{"type":47,"value":2205},{"type":41,"tag":64,"props":2247,"children":2249},{"className":2248},[],[2250],{"type":47,"value":1785},{"type":47,"value":2252}," attribute on element",{"type":41,"tag":284,"props":2254,"children":2255},{},[2256,2261],{"type":41,"tag":311,"props":2257,"children":2258},{},[2259],{"type":47,"value":2260},"Back navigation not working",{"type":41,"tag":311,"props":2262,"children":2263},{},[2264,2265,2271],{"type":47,"value":2225},{"type":41,"tag":64,"props":2266,"children":2268},{"className":2267},[],[2269],{"type":47,"value":2270},"navigateBack()",{"type":47,"value":2272},", the Escape handler, or the back gesture",{"type":41,"tag":284,"props":2274,"children":2275},{},[2276,2281],{"type":41,"tag":311,"props":2277,"children":2278},{},[2279],{"type":47,"value":2280},"API calls failing",{"type":41,"tag":311,"props":2282,"children":2283},{},[2284],{"type":47,"value":2285},"Check CORS headers, use proxy if needed",{"type":41,"tag":284,"props":2287,"children":2288},{},[2289,2294],{"type":41,"tag":311,"props":2290,"children":2291},{},[2292],{"type":47,"value":2293},"API data not updating",{"type":41,"tag":311,"props":2295,"children":2296},{},[2297,2299],{"type":47,"value":2298},"Clear cache: ",{"type":41,"tag":64,"props":2300,"children":2302},{"className":2301},[],[2303],{"type":47,"value":2304},"state.cache = {}",{"type":41,"tag":284,"props":2306,"children":2307},{},[2308,2313],{"type":41,"tag":311,"props":2309,"children":2310},{},[2311],{"type":47,"value":2312},"Sensor data not flowing",{"type":41,"tag":311,"props":2314,"children":2315},{},[2316],{"type":47,"value":2317},"Check sensor types are valid, verify device support",{"type":41,"tag":284,"props":2319,"children":2320},{},[2321,2326],{"type":41,"tag":311,"props":2322,"children":2323},{},[2324],{"type":47,"value":2325},"Data not persisting",{"type":41,"tag":311,"props":2327,"children":2328},{},[2329,2330,2336],{"type":47,"value":2205},{"type":41,"tag":64,"props":2331,"children":2333},{"className":2332},[],[2334],{"type":47,"value":2335},"saveData()",{"type":47,"value":2337}," called after state changes",{"type":41,"tag":284,"props":2339,"children":2340},{},[2341,2346],{"type":41,"tag":311,"props":2342,"children":2343},{},[2344],{"type":47,"value":2345},"Screen not showing",{"type":41,"tag":311,"props":2347,"children":2348},{},[2349,2350,2356,2358,2364],{"type":47,"value":2225},{"type":41,"tag":64,"props":2351,"children":2353},{"className":2352},[],[2354],{"type":47,"value":2355},"hidden",{"type":47,"value":2357}," class and ",{"type":41,"tag":64,"props":2359,"children":2361},{"className":2360},[],[2362],{"type":47,"value":2363},"navigateTo()",{"type":47,"value":2365}," call",{"type":41,"tag":284,"props":2367,"children":2368},{},[2369,2374],{"type":41,"tag":311,"props":2370,"children":2371},{},[2372],{"type":47,"value":2373},"Demo mode not working",{"type":41,"tag":311,"props":2375,"children":2376},{},[2377],{"type":47,"value":2378},"Verify fallback code in sensor helpers",{"type":41,"tag":50,"props":2380,"children":2381},{},[2382],{"type":47,"value":2383},"Use browser developer tools to view console.log output for debugging.",{"type":41,"tag":2385,"props":2386,"children":2387},"style",{},[2388],{"type":47,"value":2389},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2391,"total":2579},[2392,2414,2428,2449,2470,2487,2498,2516,2529,2542,2557,2569],{"slug":2393,"name":2393,"fn":2394,"description":2395,"org":2396,"tags":2397,"stars":2411,"repoUrl":2412,"updatedAt":2413},"relay-best-practices","write idiomatic Relay code","Best practices for writing idiomatic Relay code. ALWAYS use this skill when writing or modifying React components that use Relay for data fetching. Covers fragments, queries, mutations, pagination, and common anti-patterns. Use when you see `useFragment`, `useLazyLoadQuery`, `usePreloadedQuery`, `useMutation`, `usePaginationFragment`, `graphql` template literals, `react-relay` imports, or `__generated__\u002F*.graphql` files. Also use when asked to explain Relay concepts, debug Relay issues, or review Relay code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2398,2401,2402,2405,2408],{"name":2399,"slug":2400,"type":16},"Engineering","engineering",{"name":18,"slug":19,"type":16},{"name":2403,"slug":2404,"type":16},"GraphQL","graphql",{"name":2406,"slug":2407,"type":16},"React","react",{"name":2409,"slug":2410,"type":16},"Relay","relay",18950,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Frelay","2026-04-22T04:58:15.370563",{"slug":2415,"name":2415,"fn":2416,"description":2417,"org":2418,"tags":2419,"stars":2411,"repoUrl":2412,"updatedAt":2427},"relay-performance","optimize Relay application performance","Performance best practices for Relay applications. Use when optimizing data fetching, reducing re-renders, configuring caching, or improving time to first meaningful paint. Covers query placement, @defer, pagination, fetch policies, garbage collection, fragment granularity, and server-side filtering. Companion to the relay-best-practices skill which covers correctness and architecture.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2420,2421,2422,2425,2426],{"name":18,"slug":19,"type":16},{"name":2403,"slug":2404,"type":16},{"name":2423,"slug":2424,"type":16},"Performance","performance",{"name":2406,"slug":2407,"type":16},{"name":2409,"slug":2410,"type":16},"2026-06-10T07:30:28.726513",{"slug":2429,"name":2429,"fn":2430,"description":2431,"org":2432,"tags":2433,"stars":2446,"repoUrl":2447,"updatedAt":2448},"add-shape-types-to-torch-model","annotate PyTorch models with tensor shapes","Port a PyTorch model to use pyrefly's tensor shape type system (Tensor[[B, C, H, W]], Int[T]). Use this skill whenever the user wants to add shape annotations to a PyTorch model, type a model with tensor dimensions, port a model to use shape tracking, or annotate model forward methods with tensor shapes. Also use when the user mentions tensor shape ports, Int types for PyTorch, or pyrefly shape checking on a model file. Invoke BEFORE starting any model port — the skill's gated workflow prevents common failure modes.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2434,2437,2440,2443],{"name":2435,"slug":2436,"type":16},"Data Modeling","data-modeling",{"name":2438,"slug":2439,"type":16},"Deep Learning","deep-learning",{"name":2441,"slug":2442,"type":16},"Python","python",{"name":2444,"slug":2445,"type":16},"PyTorch","pytorch",6833,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fpyrefly","2026-07-18T05:12:08.515952",{"slug":2450,"name":2450,"fn":2451,"description":2452,"org":2453,"tags":2454,"stars":2467,"repoUrl":2468,"updatedAt":2469},"camera-streaming","configure camera streaming and photo capture","Stream, video frames, photo capture, resolution\u002Fframe rate configuration",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2455,2458,2461,2464],{"name":2456,"slug":2457,"type":16},"Camera","camera",{"name":2459,"slug":2460,"type":16},"Hardware","hardware",{"name":2462,"slug":2463,"type":16},"iOS","ios",{"name":2465,"slug":2466,"type":16},"Video","video",488,"https:\u002F\u002Fgithub.com\u002Ffacebook\u002Fmeta-wearables-dat-ios","2026-08-06T05:38:47.523424",{"slug":2471,"name":2471,"fn":2472,"description":2473,"org":2474,"tags":2475,"stars":2467,"repoUrl":2468,"updatedAt":2486},"dat-conventions","develop iOS applications with DAT SDK","Swift patterns, async\u002Fawait, naming conventions, key types for DAT SDK iOS development",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2476,2477,2480,2483],{"name":2462,"slug":2463,"type":16},{"name":2478,"slug":2479,"type":16},"Mobile","mobile",{"name":2481,"slug":2482,"type":16},"SDK","sdk",{"name":2484,"slug":2485,"type":16},"Swift","swift","2026-08-06T05:38:49.536777",{"slug":2488,"name":2488,"fn":2489,"description":2490,"org":2491,"tags":2492,"stars":2467,"repoUrl":2468,"updatedAt":2497},"debugging","debug wearable device software","Common issues, Developer Mode, version compatibility, state machine diagnosis",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2493,2495,2496],{"name":2494,"slug":2488,"type":16},"Debugging",{"name":2399,"slug":2400,"type":16},{"name":2462,"slug":2463,"type":16},"2026-08-06T05:38:50.51086",{"slug":2499,"name":2499,"fn":2500,"description":2501,"org":2502,"tags":2503,"stars":2467,"repoUrl":2468,"updatedAt":2515},"display-access","manage display capabilities on wearable devices","Display capability setup, display-capable device selection, UI DSL, icons, buttons, images, and video playback",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2504,2505,2508,2511,2514],{"name":21,"slug":22,"type":16},{"name":2506,"slug":2507,"type":16},"Images","images",{"name":2509,"slug":2510,"type":16},"Interaction","interaction",{"name":2512,"slug":2513,"type":16},"UI Components","ui-components",{"name":2465,"slug":2466,"type":16},"2026-08-06T05:38:53.520488",{"slug":2517,"name":2517,"fn":2518,"description":2519,"org":2520,"tags":2521,"stars":2467,"repoUrl":2468,"updatedAt":2528},"getting-started","set up Meta wearable SDK integration","SDK setup, Swift Package Manager integration, Info.plist configuration, and first connection to Meta glasses",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2522,2525,2526,2527],{"name":2523,"slug":2524,"type":16},"Configuration","configuration",{"name":2462,"slug":2463,"type":16},{"name":2481,"slug":2482,"type":16},{"name":2484,"slug":2485,"type":16},"2026-08-06T05:38:48.514522",{"slug":2530,"name":2530,"fn":2531,"description":2532,"org":2533,"tags":2534,"stars":2467,"repoUrl":2468,"updatedAt":2541},"live-debugging-mcp","debug iOS wearable applications","Use this whenever debugging an iOS DAT app with local DAT Inspector MCP tools, live device events, Meta AI app\u002Fdevice boundary issues, permissions, registration, sessions, streaming, callbacks, or user reports that the app cannot communicate with glasses.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2535,2536,2537,2540],{"name":2494,"slug":2488,"type":16},{"name":2462,"slug":2463,"type":16},{"name":2538,"slug":2539,"type":16},"MCP","mcp",{"name":2478,"slug":2479,"type":16},"2026-08-06T06:09:15.013902",{"slug":2543,"name":2543,"fn":2544,"description":2545,"org":2546,"tags":2547,"stars":2467,"repoUrl":2468,"updatedAt":2556},"mockdevice-testing","test wearable apps with mock devices","MockDeviceKit for testing without physical glasses hardware",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2548,2549,2550,2553],{"name":2462,"slug":2463,"type":16},{"name":2478,"slug":2479,"type":16},{"name":2551,"slug":2552,"type":16},"QA","qa",{"name":2554,"slug":2555,"type":16},"Testing","testing","2026-05-15T06:14:37.406692",{"slug":2558,"name":2558,"fn":2559,"description":2560,"org":2561,"tags":2562,"stars":2467,"repoUrl":2468,"updatedAt":2568},"permissions-registration","register apps with Meta AI","App registration with Meta AI, camera permission flows",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2563,2564,2565],{"name":2456,"slug":2457,"type":16},{"name":2462,"slug":2463,"type":16},{"name":2566,"slug":2567,"type":16},"Permissions","permissions","2026-05-15T06:14:46.030253",{"slug":2570,"name":2570,"fn":2571,"description":2572,"org":2573,"tags":2574,"stars":2467,"repoUrl":2468,"updatedAt":2578},"sample-app-guide","build wearable apps with camera streaming","Building a complete DAT app with camera streaming and photo capture",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2575,2576,2577],{"name":2456,"slug":2457,"type":16},{"name":2462,"slug":2463,"type":16},{"name":2478,"slug":2479,"type":16},"2026-08-06T05:38:51.509255",34,{"items":2581,"total":1257},[2582,2594,2604,2618,2630,2642,2655],{"slug":2583,"name":2583,"fn":2584,"description":2585,"org":2586,"tags":2587,"stars":23,"repoUrl":24,"updatedAt":2593},"add-device-sensors","integrate device sensor data","Add device sensor data to a Meta Display Glasses webapp — IMU (accelerometer, gyroscope, orientation) via DeviceMotionEvent\u002FDeviceOrientationEvent, and GPS location via navigator.geolocation. Use when the user wants motion tracking, compass, level tool, step counter, shake detection, head tracking, or location.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2588,2589,2590],{"name":18,"slug":19,"type":16},{"name":2459,"slug":2460,"type":16},{"name":2591,"slug":2592,"type":16},"IoT","iot","2026-09-01T08:30:33.453548",{"slug":2595,"name":2595,"fn":2596,"description":2597,"org":2598,"tags":2599,"stars":23,"repoUrl":24,"updatedAt":2603},"add-gestures","handle gesture interactions in webapps","Handle EMG pinch (tap-to-activate) and opt into continuous pinch-and-drag in a Meta Display Glasses webapp. Use when the user wants sliders, drawing, maps, drag interactions, or game-style continuous input.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2600,2601,2602],{"name":21,"slug":22,"type":16},{"name":18,"slug":19,"type":16},{"name":2509,"slug":2510,"type":16},"2026-09-01T08:30:53.889244",{"slug":2605,"name":2605,"fn":2606,"description":2607,"org":2608,"tags":2609,"stars":23,"repoUrl":24,"updatedAt":2617},"add-local-storage","add client-side data persistence","Add client-side data persistence to a Meta Display Glasses webapp using the W3C Web Storage API (localStorage and sessionStorage). Use when the user wants to save settings, cache data, persist state, or store user preferences.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2610,2611,2614],{"name":18,"slug":19,"type":16},{"name":2612,"slug":2613,"type":16},"Persistence","persistence",{"name":2615,"slug":2616,"type":16},"Storage","storage","2026-09-01T08:30:31.384362",{"slug":2619,"name":2619,"fn":2620,"description":2621,"org":2622,"tags":2623,"stars":23,"repoUrl":24,"updatedAt":2629},"add-offline","enable offline support for webapps","Make a Meta Display Glasses webapp work offline with a Service Worker + Cache API (precache the app shell, cache-first fetch, online\u002Foffline UI). Use when the user wants offline support or resilience to flaky Wi-Fi.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2624,2625,2628],{"name":18,"slug":19,"type":16},{"name":2626,"slug":2627,"type":16},"Offline","offline",{"name":2423,"slug":2424,"type":16},"2026-09-01T08:30:33.83287",{"slug":2631,"name":2631,"fn":2632,"description":2633,"org":2634,"tags":2635,"stars":23,"repoUrl":24,"updatedAt":2641},"add-text-input","add text input to webapps","Add text entry to a Meta Display Glasses webapp. Standard HTML inputs open the on-glasses composer (handwriting + voice) when focused and tapped. Use when the user wants a text field, search box, form input, or notes area.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2636,2639,2640],{"name":2637,"slug":2638,"type":16},"Forms","forms",{"name":18,"slug":19,"type":16},{"name":2512,"slug":2513,"type":16},"2026-09-01T08:30:30.563354",{"slug":2643,"name":2643,"fn":2644,"description":2645,"org":2646,"tags":2647,"stars":23,"repoUrl":24,"updatedAt":2654},"add-ui","add UI components to webapps","Add UI components to a Meta Display Glasses webapp — screens, buttons, lists, cards, forms, toggles, counters, or nav bars. Works with vanilla JS and React apps. Use when the user wants to add any interactive UI element or new screen.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2648,2649,2652,2653],{"name":18,"slug":19,"type":16},{"name":2650,"slug":2651,"type":16},"JavaScript","javascript",{"name":2406,"slug":2407,"type":16},{"name":2512,"slug":2513,"type":16},"2026-09-01T08:30:27.477785",{"slug":2656,"name":2656,"fn":2657,"description":2658,"org":2659,"tags":2660,"stars":23,"repoUrl":24,"updatedAt":2671},"connect-api","connect webapps to REST APIs and WebSockets","Connect a Meta Display Glasses webapp to REST APIs or WebSockets. Use when the user wants to fetch data from an API, add real-time updates, show loading\u002Ferror states, or cache API responses.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[2661,2664,2665,2668],{"name":2662,"slug":2663,"type":16},"API Development","api-development",{"name":18,"slug":19,"type":16},{"name":2666,"slug":2667,"type":16},"REST API","rest-api",{"name":2669,"slug":2670,"type":16},"WebSockets","websockets","2026-09-01T08:30:30.968156"]