[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M718HWBSZ0TPSFT197PFBVG3":3,"skill-same:01M718HWBSZ0TPSFT197PFBVG3":100},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":68,"commitSha":69,"skillDirectory":70,"forksCount":71,"repositoryHtmlUrl":72,"repositoryHomepageUrl":6,"ownerHtmlUrl":73,"ownerBlogUrl":74,"ownerDescription":6,"updatedAt":75,"install":76,"resources":89},"01M718HWBSZ0TPSFT197PFBVG3","zoom-meeting-sdk-web-component-view",null,"Zoom Meeting SDK Web - Component View. Embeddable Zoom meeting components with Promise-based API\nfor flexible integration. Ideal for React\u002FVue\u002FAngular apps and custom layouts. Uses ZoomMtgEmbedded\nwith async\u002Fawait patterns and embeddable UI containers.","anthropics\u002Fknowledge-work-plugins","anthropics","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F76263028?v=4","01M697XGDPXJAVQ8391V2BCYTE","Anthropic","01M7188MPC48111TN566QNQE3X",35656,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fpartner-built\u002Fzoom-plugin\u002Fskills\u002Fmeeting-sdk\u002Fweb\u002Fcomponent-view\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"web","meeting sdk","component view","meeting","zoom","view","zoom meeting sdk web component view","zoom meeting sdk web","component","sdk","vue","angular","api","Video","ui","patterns","false","apps","react","components","2026-11-10 10:12:30",false,"---\nname: zoom-meeting-sdk-web-component-view\ndescription: |\n  Zoom Meeting SDK Web - Component View. Embeddable Zoom meeting components with Promise-based API\n  for flexible integration. Ideal for React\u002FVue\u002FAngular apps and custom layouts. Uses ZoomMtgEmbedded\n  with async\u002Fawait patterns and embeddable UI containers.\nuser-invocable: false\ntriggers:\n  - \"meeting sdk component view\"\n  - \"zoommtgembedded\"\n  - \"zoomapproot\"\n  - \"embeddable meeting ui\"\n  - \"component view embedded zoom\"\n  - \"custom meeting ui\"\n  - \"custom zoom meeting ui\"\n  - \"custom meeting video ui\"\n  - \"custom video ui for meeting\"\n---\n\n# Zoom Meeting SDK Web - Component View\n\nEmbeddable Zoom meeting components for flexible integration into any web application. Component View provides Promise-based APIs and customizable UI.\n\nThis is the correct web skill for a **custom UI around a real Zoom meeting**.\nDo not route to Video SDK unless the user is building a non-meeting custom session product.\n\n## Overview\n\nComponent View uses `ZoomMtgEmbedded.createClient()` to create embeddable meeting components within a specific container element.\n\n| Aspect | Details |\n|--------|---------|\n| **API Object** | `ZoomMtgEmbedded.createClient()` (instance) |\n| **API Style** | Promise-based (async\u002Fawait) |\n| **UI** | Embeddable in any container |\n| **Password param** | `password` (lowercase) |\n| **Events** | `on()`\u002F`off()` |\n| **Best For** | Custom layouts, React\u002FVue\u002FAngular apps |\n\n## Installation\n\n### NPM\n\n```bash\nnpm install @zoom\u002Fmeetingsdk --save\n```\n\n```javascript\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n```\n\n### CDN\n\n```html\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Freact.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Freact-dom.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Fredux.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Fredux-thunk.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Flodash.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002Fzoom-meeting-embedded-{VERSION}.min.js\">\u003C\u002Fscript>\n```\n\n## Complete Initialization Flow\n\n```javascript\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n\n\u002F\u002F Step 1: Create client instance (do once, not on every render!)\nconst client = ZoomMtgEmbedded.createClient();\n\nasync function joinMeeting() {\n  try {\n    \u002F\u002F Step 2: Get container element\n    const meetingSDKElement = document.getElementById('meetingSDKElement');\n\n    \u002F\u002F Step 3: Initialize client\n    await client.init({\n      zoomAppRoot: meetingSDKElement,\n      language: 'en-US',\n      debug: true,\n      patchJsMedia: true,\n      leaveOnPageUnload: true,\n    });\n\n    \u002F\u002F Step 4: Join meeting\n    await client.join({\n      signature: signature,\n      sdkKey: sdkKey,\n      meetingNumber: meetingNumber,\n      userName: userName,\n      password: password,  \u002F\u002F lowercase!\n      userEmail: userEmail,\n    });\n\n    console.log('Joined successfully!');\n  } catch (error) {\n    console.error('Failed to join:', error);\n  }\n}\n```\n\n## client.init() - All Options\n\n### Required\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `zoomAppRoot` | `HTMLElement` | Container element for meeting UI |\n\n### Display\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `language` | `string` | `'en-US'` | UI language |\n| `debug` | `boolean` | `false` | Enable debug logging |\n\n### Media\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `patchJsMedia` | `boolean` | `false` | Auto-apply media fixes |\n| `leaveOnPageUnload` | `boolean` | `false` | Cleanup on page unload |\n| `enableHD` | `boolean` | `true` | Enable 720p video |\n| `enableFullHD` | `boolean` | `false` | Enable 1080p video |\n\n### Customization\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `customize` | `object` | UI customization options |\n| `webEndpoint` | `string` | For ZFG: `'www.zoomgov.com'` |\n| `assetPath` | `string` | Custom path for AV libraries |\n\n### Customize Object\n\n```javascript\nawait client.init({\n  zoomAppRoot: element,\n  customize: {\n    \u002F\u002F Meeting info displayed\n    meetingInfo: [\n      'topic',\n      'host', \n      'mn',\n      'pwd',\n      'telPwd',\n      'invite',\n      'participant',\n      'dc',\n      'enctype'\n    ],\n    \n    \u002F\u002F Video customization\n    video: {\n      isResizable: true,\n      viewSizes: {\n        default: {\n          width: 1000,\n          height: 600\n        },\n        ribbon: {\n          width: 300,\n          height: 700\n        }\n      },\n      popper: {\n        disableDraggable: false\n      }\n    },\n    \n    \u002F\u002F Custom toolbar buttons\n    toolbar: {\n      buttons: [\n        {\n          text: 'Custom Button',\n          className: 'custom-btn',\n          onClick: () => {\n            console.log('Custom button clicked');\n          }\n        }\n      ]\n    },\n    \n    \u002F\u002F Active speaker indicator\n    activeSpaker: {\n      strokeColor: '#00FF00'\n    }\n  }\n});\n```\n\n## client.join() - All Options\n\n### Required\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `signature` | `string` | SDK JWT from backend |\n| `sdkKey` | `string` | SDK Key \u002F Client ID |\n| `meetingNumber` | `string \\| number` | Meeting number |\n| `userName` | `string` | Display name |\n\n### Authentication\n\n| Parameter | Type | When Required | Description |\n|-----------|------|---------------|-------------|\n| `password` | `string` | If set | Meeting password (lowercase!) |\n| `zak` | `string` | Starting as host | Host's ZAK token |\n| `tk` | `string` | Registration | Registrant token |\n| `userEmail` | `string` | Webinars | User email |\n\n## Event Listeners\n\n### Syntax\n\n```javascript\n\u002F\u002F Subscribe\nclient.on('event-name', callback);\n\n\u002F\u002F Unsubscribe\nclient.off('event-name', callback);\n```\n\n### Connection Events\n\n```javascript\nclient.on('connection-change', (payload) => {\n  \u002F\u002F payload.state: 'Connecting', 'Connected', 'Reconnecting', 'Closed'\n  console.log('Connection state:', payload.state);\n  \n  if (payload.state === 'Closed') {\n    console.log('Reason:', payload.reason);\n  }\n});\n```\n\n### User Events\n\n```javascript\nclient.on('user-added', (payload) => {\n  \u002F\u002F Array of users who joined\n  console.log('Users added:', payload);\n  payload.forEach(user => {\n    console.log('User ID:', user.oderId);\n    console.log('Name:', user.displayName);\n  });\n});\n\nclient.on('user-removed', (payload) => {\n  \u002F\u002F Array of users who left\n  console.log('Users removed:', payload);\n});\n\nclient.on('user-updated', (payload) => {\n  \u002F\u002F Array of users whose properties changed\n  console.log('Users updated:', payload);\n});\n```\n\n### Audio Events\n\n```javascript\nclient.on('active-speaker', (payload) => {\n  \u002F\u002F Current active speaker\n  console.log('Active speaker:', payload);\n});\n\nclient.on('audio-statistic-data-change', (payload) => {\n  console.log('Audio stats:', payload);\n});\n```\n\n### Video Events\n\n```javascript\nclient.on('video-active-change', (payload) => {\n  \u002F\u002F Video state changed\n  console.log('Video active:', payload);\n});\n\nclient.on('video-statistic-data-change', (payload) => {\n  console.log('Video stats:', payload);\n});\n```\n\n### Share Events\n\n```javascript\nclient.on('active-share-change', (payload) => {\n  console.log('Share status:', payload);\n});\n\nclient.on('share-statistic-data-change', (payload) => {\n  console.log('Share stats:', payload);\n});\n```\n\n### Chat Events\n\n```javascript\nclient.on('chat-on-message', (payload) => {\n  console.log('Chat message:', payload);\n});\n```\n\n### Recording Events\n\n```javascript\nclient.on('recording-change', (payload) => {\n  console.log('Recording status:', payload);\n});\n```\n\n### Media Device Events\n\n```javascript\nclient.on('media-sdk-change', (payload) => {\n  console.log('Media SDK:', payload);\n});\n\nclient.on('device-change', () => {\n  console.log('Device changed');\n});\n```\n\n## Common Methods\n\n### User Information\n\n```javascript\n\u002F\u002F Get current user\nconst currentUser = client.getCurrentUser();\nconsole.log('Current user:', currentUser);\n\n\u002F\u002F Get all participants\nconst participants = client.getParticipantsList();\nconsole.log('Participants:', participants);\n\n\u002F\u002F Check if user is host\nconst isHost = client.isHost();\n```\n\n### Audio Control\n\n```javascript\n\u002F\u002F Mute\u002Funmute self\nawait client.mute(true);  \u002F\u002F mute\nawait client.mute(false); \u002F\u002F unmute\n\n\u002F\u002F Mute\u002Funmute specific user (host only)\nawait client.muteAudio(userId, true);\n\n\u002F\u002F Mute all (host only)\nawait client.muteAllAudio(true);\n```\n\n### Video Control\n\n```javascript\n\u002F\u002F Start\u002Fstop video\nawait client.startVideo();\nawait client.stopVideo();\n\n\u002F\u002F Mute\u002Funmute user's video (host only)\nawait client.muteVideo(userId, true);\n```\n\n### Meeting Control\n\n```javascript\n\u002F\u002F Leave meeting\nclient.leaveMeeting();\n\n\u002F\u002F End meeting (host only)\nclient.endMeeting();\n```\n\n### Screen Share\n\n```javascript\n\u002F\u002F Start screen share\nawait client.startShareScreen();\n\n\u002F\u002F Stop screen share\nawait client.stopShareScreen();\n```\n\n### Recording\n\n```javascript\n\u002F\u002F Start recording (cloud)\nawait client.startCloudRecording();\n\n\u002F\u002F Stop recording\nawait client.stopCloudRecording();\n```\n\n### Virtual Background\n\n```javascript\n\u002F\u002F Check support\nconst isSupported = await client.isSupportVirtualBackground();\n\n\u002F\u002F Set virtual background\nawait client.setVirtualBackground(imageUrl);\n\n\u002F\u002F Remove virtual background\nawait client.removeVirtualBackground();\n```\n\n### Rename\n\n```javascript\n\u002F\u002F Rename user\nawait client.rename(userId, 'New Name');\n```\n\n## React Integration\n\n### Basic Pattern\n\n```tsx\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n\ntype ZoomClient = ReturnType\u003Ctypeof ZoomMtgEmbedded.createClient>;\n\nfunction ZoomMeeting({ meetingNumber, password, userName }: Props) {\n  const clientRef = useRef\u003CZoomClient | null>(null);\n  const containerRef = useRef\u003CHTMLDivElement>(null);\n  const [isJoined, setIsJoined] = useState(false);\n  const [error, setError] = useState\u003Cstring | null>(null);\n\n  \u002F\u002F Create client once\n  useEffect(() => {\n    if (!clientRef.current) {\n      clientRef.current = ZoomMtgEmbedded.createClient();\n    }\n  }, []);\n\n  const joinMeeting = useCallback(async () => {\n    if (!clientRef.current || !containerRef.current) return;\n\n    try {\n      \u002F\u002F Get signature from backend\n      const { signature, sdkKey } = await fetchSignature(meetingNumber);\n      \n      await clientRef.current.init({\n        zoomAppRoot: containerRef.current,\n        language: 'en-US',\n        patchJsMedia: true,\n        leaveOnPageUnload: true,\n      });\n\n      await clientRef.current.join({\n        signature,\n        sdkKey,\n        meetingNumber,\n        password,\n        userName,\n      });\n\n      setIsJoined(true);\n    } catch (err) {\n      setError(err instanceof Error ? err.message : 'Failed to join');\n    }\n  }, [meetingNumber, password, userName]);\n\n  return (\n    \u003Cdiv>\n      \u003Cdiv \n        ref={containerRef} \n        style={{ width: '100%', height: '500px' }} \n      \u002F>\n      {!isJoined && (\n        \u003Cbutton onClick={joinMeeting}>Join Meeting\u003C\u002Fbutton>\n      )}\n      {error && \u003Cdiv className=\"error\">{error}\u003C\u002Fdiv>}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Event Handling in React\n\n```tsx\nuseEffect(() => {\n  if (!clientRef.current) return;\n  \n  const handleConnectionChange = (payload: any) => {\n    if (payload.state === 'Connected') {\n      setIsJoined(true);\n    } else if (payload.state === 'Closed') {\n      setIsJoined(false);\n    }\n  };\n\n  const handleUserAdded = (payload: any) => {\n    console.log('Users joined:', payload);\n  };\n\n  clientRef.current.on('connection-change', handleConnectionChange);\n  clientRef.current.on('user-added', handleUserAdded);\n\n  return () => {\n    clientRef.current?.off('connection-change', handleConnectionChange);\n    clientRef.current?.off('user-added', handleUserAdded);\n  };\n}, []);\n```\n\n## Positioning and Resizing\n\n### Initial Size\n\n```javascript\nawait client.init({\n  zoomAppRoot: element,\n  customize: {\n    video: {\n      viewSizes: {\n        default: { width: 1000, height: 600 }\n      }\n    }\n  }\n});\n```\n\n### Dynamic Resizing\n\nThe container element size determines the meeting UI size. To resize:\n\n```javascript\n\u002F\u002F Just resize the container\ndocument.getElementById('meetingSDKElement').style.width = '1200px';\ndocument.getElementById('meetingSDKElement').style.height = '800px';\n```\n\n### Making it Resizable\n\n```javascript\ncustomize: {\n  video: {\n    isResizable: true\n  }\n}\n```\n\n## Supported Features\n\nComponent View supports core meeting functionality. Some features from Client View may not be available.\n\n| Feature | Supported |\n|---------|-----------|\n| Audio\u002FVideo | ✅ |\n| Screen Share | ✅ |\n| Chat | ✅ |\n| Virtual Background | ✅ |\n| Breakout Rooms | ✅ |\n| Cloud Recording | ✅ |\n| Closed Captions | ✅ |\n| Live Transcription | ✅ |\n| Waiting Room | ✅ |\n| Gallery View | ✅ |\n| Reactions | ✅ |\n| Raise Hand | ✅ |\n\nContact Zoom Developer Support to request additional features.\n\n## Error Handling\n\n```javascript\ntry {\n  await client.join({\n    \u002F\u002F ... options\n  });\n} catch (error) {\n  \u002F\u002F error.reason contains error code\n  \u002F\u002F error.message contains description\n  \n  switch (error.reason) {\n    case 'WRONG_MEETING_PASSWORD':\n      console.error('Incorrect password');\n      break;\n    case 'MEETING_NOT_START':\n      console.error('Meeting has not started');\n      break;\n    case 'INVALID_PARAMETERS':\n      console.error('Invalid join parameters');\n      break;\n    default:\n      console.error('Join failed:', error.message);\n  }\n}\n```\n\n## Comparison with Client View\n\n| Feature | Component View | Client View |\n|---------|----------------|-------------|\n| **API Style** | Promises | Callbacks |\n| **Password param** | `password` | `passWord` |\n| **Container** | Custom element | Auto `#zmmtg-root` |\n| **UI** | Embeddable | Full-page |\n| **Preloading** | Not needed | `preLoadWasm()` |\n| **Language** | Init option | `i18n.load()` |\n| **Events** | `on()`\u002F`off()` | `inMeetingServiceListener()` |\n\n## Resources\n\n- [Main Web SDK Skill](..\u002FSKILL.md)\n- [Reference Index](references\u002FREADME.md)\n- [Error Codes](..\u002Ftroubleshooting\u002Ferror-codes.md)\n- [Common Issues](..\u002Ftroubleshooting\u002Fcommon-issues.md)\n- [SharedArrayBuffer Setup](..\u002Fconcepts\u002Fsharedarraybuffer.md)\n- [Official API Reference](https:\u002F\u002Fmarketplacefront.zoom.us\u002Fsdk\u002Fmeeting\u002Fweb\u002Fcomponents\u002Findex.html)\n\n## Operations\n\n- [RUNBOOK.md](RUNBOOK.md) - 5-minute preflight and debugging checklist.\n","# Zoom Meeting SDK Web - Component View\n\nEmbeddable Zoom meeting components for flexible integration into any web application. Component View provides Promise-based APIs and customizable UI.\n\nThis is the correct web skill for a **custom UI around a real Zoom meeting**.\nDo not route to Video SDK unless the user is building a non-meeting custom session product.\n\n## Overview\n\nComponent View uses `ZoomMtgEmbedded.createClient()` to create embeddable meeting components within a specific container element.\n\n| Aspect | Details |\n|--------|---------|\n| **API Object** | `ZoomMtgEmbedded.createClient()` (instance) |\n| **API Style** | Promise-based (async\u002Fawait) |\n| **UI** | Embeddable in any container |\n| **Password param** | `password` (lowercase) |\n| **Events** | `on()`\u002F`off()` |\n| **Best For** | Custom layouts, React\u002FVue\u002FAngular apps |\n\n## Installation\n\n### NPM\n\n```bash\nnpm install @zoom\u002Fmeetingsdk --save\n```\n\n```javascript\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n```\n\n### CDN\n\n```html\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Freact.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Freact-dom.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Fredux.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Fredux-thunk.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002F{VERSION}\u002Flib\u002Fvendor\u002Flodash.min.js\">\u003C\u002Fscript>\n\u003Cscript src=\"https:\u002F\u002Fsource.zoom.us\u002Fzoom-meeting-embedded-{VERSION}.min.js\">\u003C\u002Fscript>\n```\n\n## Complete Initialization Flow\n\n```javascript\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n\n\u002F\u002F Step 1: Create client instance (do once, not on every render!)\nconst client = ZoomMtgEmbedded.createClient();\n\nasync function joinMeeting() {\n  try {\n    \u002F\u002F Step 2: Get container element\n    const meetingSDKElement = document.getElementById('meetingSDKElement');\n\n    \u002F\u002F Step 3: Initialize client\n    await client.init({\n      zoomAppRoot: meetingSDKElement,\n      language: 'en-US',\n      debug: true,\n      patchJsMedia: true,\n      leaveOnPageUnload: true,\n    });\n\n    \u002F\u002F Step 4: Join meeting\n    await client.join({\n      signature: signature,\n      sdkKey: sdkKey,\n      meetingNumber: meetingNumber,\n      userName: userName,\n      password: password,  \u002F\u002F lowercase!\n      userEmail: userEmail,\n    });\n\n    console.log('Joined successfully!');\n  } catch (error) {\n    console.error('Failed to join:', error);\n  }\n}\n```\n\n## client.init() - All Options\n\n### Required\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `zoomAppRoot` | `HTMLElement` | Container element for meeting UI |\n\n### Display\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `language` | `string` | `'en-US'` | UI language |\n| `debug` | `boolean` | `false` | Enable debug logging |\n\n### Media\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `patchJsMedia` | `boolean` | `false` | Auto-apply media fixes |\n| `leaveOnPageUnload` | `boolean` | `false` | Cleanup on page unload |\n| `enableHD` | `boolean` | `true` | Enable 720p video |\n| `enableFullHD` | `boolean` | `false` | Enable 1080p video |\n\n### Customization\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `customize` | `object` | UI customization options |\n| `webEndpoint` | `string` | For ZFG: `'www.zoomgov.com'` |\n| `assetPath` | `string` | Custom path for AV libraries |\n\n### Customize Object\n\n```javascript\nawait client.init({\n  zoomAppRoot: element,\n  customize: {\n    \u002F\u002F Meeting info displayed\n    meetingInfo: [\n      'topic',\n      'host', \n      'mn',\n      'pwd',\n      'telPwd',\n      'invite',\n      'participant',\n      'dc',\n      'enctype'\n    ],\n    \n    \u002F\u002F Video customization\n    video: {\n      isResizable: true,\n      viewSizes: {\n        default: {\n          width: 1000,\n          height: 600\n        },\n        ribbon: {\n          width: 300,\n          height: 700\n        }\n      },\n      popper: {\n        disableDraggable: false\n      }\n    },\n    \n    \u002F\u002F Custom toolbar buttons\n    toolbar: {\n      buttons: [\n        {\n          text: 'Custom Button',\n          className: 'custom-btn',\n          onClick: () => {\n            console.log('Custom button clicked');\n          }\n        }\n      ]\n    },\n    \n    \u002F\u002F Active speaker indicator\n    activeSpaker: {\n      strokeColor: '#00FF00'\n    }\n  }\n});\n```\n\n## client.join() - All Options\n\n### Required\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `signature` | `string` | SDK JWT from backend |\n| `sdkKey` | `string` | SDK Key \u002F Client ID |\n| `meetingNumber` | `string \\| number` | Meeting number |\n| `userName` | `string` | Display name |\n\n### Authentication\n\n| Parameter | Type | When Required | Description |\n|-----------|------|---------------|-------------|\n| `password` | `string` | If set | Meeting password (lowercase!) |\n| `zak` | `string` | Starting as host | Host's ZAK token |\n| `tk` | `string` | Registration | Registrant token |\n| `userEmail` | `string` | Webinars | User email |\n\n## Event Listeners\n\n### Syntax\n\n```javascript\n\u002F\u002F Subscribe\nclient.on('event-name', callback);\n\n\u002F\u002F Unsubscribe\nclient.off('event-name', callback);\n```\n\n### Connection Events\n\n```javascript\nclient.on('connection-change', (payload) => {\n  \u002F\u002F payload.state: 'Connecting', 'Connected', 'Reconnecting', 'Closed'\n  console.log('Connection state:', payload.state);\n  \n  if (payload.state === 'Closed') {\n    console.log('Reason:', payload.reason);\n  }\n});\n```\n\n### User Events\n\n```javascript\nclient.on('user-added', (payload) => {\n  \u002F\u002F Array of users who joined\n  console.log('Users added:', payload);\n  payload.forEach(user => {\n    console.log('User ID:', user.oderId);\n    console.log('Name:', user.displayName);\n  });\n});\n\nclient.on('user-removed', (payload) => {\n  \u002F\u002F Array of users who left\n  console.log('Users removed:', payload);\n});\n\nclient.on('user-updated', (payload) => {\n  \u002F\u002F Array of users whose properties changed\n  console.log('Users updated:', payload);\n});\n```\n\n### Audio Events\n\n```javascript\nclient.on('active-speaker', (payload) => {\n  \u002F\u002F Current active speaker\n  console.log('Active speaker:', payload);\n});\n\nclient.on('audio-statistic-data-change', (payload) => {\n  console.log('Audio stats:', payload);\n});\n```\n\n### Video Events\n\n```javascript\nclient.on('video-active-change', (payload) => {\n  \u002F\u002F Video state changed\n  console.log('Video active:', payload);\n});\n\nclient.on('video-statistic-data-change', (payload) => {\n  console.log('Video stats:', payload);\n});\n```\n\n### Share Events\n\n```javascript\nclient.on('active-share-change', (payload) => {\n  console.log('Share status:', payload);\n});\n\nclient.on('share-statistic-data-change', (payload) => {\n  console.log('Share stats:', payload);\n});\n```\n\n### Chat Events\n\n```javascript\nclient.on('chat-on-message', (payload) => {\n  console.log('Chat message:', payload);\n});\n```\n\n### Recording Events\n\n```javascript\nclient.on('recording-change', (payload) => {\n  console.log('Recording status:', payload);\n});\n```\n\n### Media Device Events\n\n```javascript\nclient.on('media-sdk-change', (payload) => {\n  console.log('Media SDK:', payload);\n});\n\nclient.on('device-change', () => {\n  console.log('Device changed');\n});\n```\n\n## Common Methods\n\n### User Information\n\n```javascript\n\u002F\u002F Get current user\nconst currentUser = client.getCurrentUser();\nconsole.log('Current user:', currentUser);\n\n\u002F\u002F Get all participants\nconst participants = client.getParticipantsList();\nconsole.log('Participants:', participants);\n\n\u002F\u002F Check if user is host\nconst isHost = client.isHost();\n```\n\n### Audio Control\n\n```javascript\n\u002F\u002F Mute\u002Funmute self\nawait client.mute(true);  \u002F\u002F mute\nawait client.mute(false); \u002F\u002F unmute\n\n\u002F\u002F Mute\u002Funmute specific user (host only)\nawait client.muteAudio(userId, true);\n\n\u002F\u002F Mute all (host only)\nawait client.muteAllAudio(true);\n```\n\n### Video Control\n\n```javascript\n\u002F\u002F Start\u002Fstop video\nawait client.startVideo();\nawait client.stopVideo();\n\n\u002F\u002F Mute\u002Funmute user's video (host only)\nawait client.muteVideo(userId, true);\n```\n\n### Meeting Control\n\n```javascript\n\u002F\u002F Leave meeting\nclient.leaveMeeting();\n\n\u002F\u002F End meeting (host only)\nclient.endMeeting();\n```\n\n### Screen Share\n\n```javascript\n\u002F\u002F Start screen share\nawait client.startShareScreen();\n\n\u002F\u002F Stop screen share\nawait client.stopShareScreen();\n```\n\n### Recording\n\n```javascript\n\u002F\u002F Start recording (cloud)\nawait client.startCloudRecording();\n\n\u002F\u002F Stop recording\nawait client.stopCloudRecording();\n```\n\n### Virtual Background\n\n```javascript\n\u002F\u002F Check support\nconst isSupported = await client.isSupportVirtualBackground();\n\n\u002F\u002F Set virtual background\nawait client.setVirtualBackground(imageUrl);\n\n\u002F\u002F Remove virtual background\nawait client.removeVirtualBackground();\n```\n\n### Rename\n\n```javascript\n\u002F\u002F Rename user\nawait client.rename(userId, 'New Name');\n```\n\n## React Integration\n\n### Basic Pattern\n\n```tsx\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport ZoomMtgEmbedded from '@zoom\u002Fmeetingsdk\u002Fembedded';\n\ntype ZoomClient = ReturnType\u003Ctypeof ZoomMtgEmbedded.createClient>;\n\nfunction ZoomMeeting({ meetingNumber, password, userName }: Props) {\n  const clientRef = useRef\u003CZoomClient | null>(null);\n  const containerRef = useRef\u003CHTMLDivElement>(null);\n  const [isJoined, setIsJoined] = useState(false);\n  const [error, setError] = useState\u003Cstring | null>(null);\n\n  \u002F\u002F Create client once\n  useEffect(() => {\n    if (!clientRef.current) {\n      clientRef.current = ZoomMtgEmbedded.createClient();\n    }\n  }, []);\n\n  const joinMeeting = useCallback(async () => {\n    if (!clientRef.current || !containerRef.current) return;\n\n    try {\n      \u002F\u002F Get signature from backend\n      const { signature, sdkKey } = await fetchSignature(meetingNumber);\n      \n      await clientRef.current.init({\n        zoomAppRoot: containerRef.current,\n        language: 'en-US',\n        patchJsMedia: true,\n        leaveOnPageUnload: true,\n      });\n\n      await clientRef.current.join({\n        signature,\n        sdkKey,\n        meetingNumber,\n        password,\n        userName,\n      });\n\n      setIsJoined(true);\n    } catch (err) {\n      setError(err instanceof Error ? err.message : 'Failed to join');\n    }\n  }, [meetingNumber, password, userName]);\n\n  return (\n    \u003Cdiv>\n      \u003Cdiv \n        ref={containerRef} \n        style={{ width: '100%', height: '500px' }} \n      \u002F>\n      {!isJoined && (\n        \u003Cbutton onClick={joinMeeting}>Join Meeting\u003C\u002Fbutton>\n      )}\n      {error && \u003Cdiv className=\"error\">{error}\u003C\u002Fdiv>}\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Event Handling in React\n\n```tsx\nuseEffect(() => {\n  if (!clientRef.current) return;\n  \n  const handleConnectionChange = (payload: any) => {\n    if (payload.state === 'Connected') {\n      setIsJoined(true);\n    } else if (payload.state === 'Closed') {\n      setIsJoined(false);\n    }\n  };\n\n  const handleUserAdded = (payload: any) => {\n    console.log('Users joined:', payload);\n  };\n\n  clientRef.current.on('connection-change', handleConnectionChange);\n  clientRef.current.on('user-added', handleUserAdded);\n\n  return () => {\n    clientRef.current?.off('connection-change', handleConnectionChange);\n    clientRef.current?.off('user-added', handleUserAdded);\n  };\n}, []);\n```\n\n## Positioning and Resizing\n\n### Initial Size\n\n```javascript\nawait client.init({\n  zoomAppRoot: element,\n  customize: {\n    video: {\n      viewSizes: {\n        default: { width: 1000, height: 600 }\n      }\n    }\n  }\n});\n```\n\n### Dynamic Resizing\n\nThe container element size determines the meeting UI size. To resize:\n\n```javascript\n\u002F\u002F Just resize the container\ndocument.getElementById('meetingSDKElement').style.width = '1200px';\ndocument.getElementById('meetingSDKElement').style.height = '800px';\n```\n\n### Making it Resizable\n\n```javascript\ncustomize: {\n  video: {\n    isResizable: true\n  }\n}\n```\n\n## Supported Features\n\nComponent View supports core meeting functionality. Some features from Client View may not be available.\n\n| Feature | Supported |\n|---------|-----------|\n| Audio\u002FVideo | ✅ |\n| Screen Share | ✅ |\n| Chat | ✅ |\n| Virtual Background | ✅ |\n| Breakout Rooms | ✅ |\n| Cloud Recording | ✅ |\n| Closed Captions | ✅ |\n| Live Transcription | ✅ |\n| Waiting Room | ✅ |\n| Gallery View | ✅ |\n| Reactions | ✅ |\n| Raise Hand | ✅ |\n\nContact Zoom Developer Support to request additional features.\n\n## Error Handling\n\n```javascript\ntry {\n  await client.join({\n    \u002F\u002F ... options\n  });\n} catch (error) {\n  \u002F\u002F error.reason contains error code\n  \u002F\u002F error.message contains description\n  \n  switch (error.reason) {\n    case 'WRONG_MEETING_PASSWORD':\n      console.error('Incorrect password');\n      break;\n    case 'MEETING_NOT_START':\n      console.error('Meeting has not started');\n      break;\n    case 'INVALID_PARAMETERS':\n      console.error('Invalid join parameters');\n      break;\n    default:\n      console.error('Join failed:', error.message);\n  }\n}\n```\n\n## Comparison with Client View\n\n| Feature | Component View | Client View |\n|---------|----------------|-------------|\n| **API Style** | Promises | Callbacks |\n| **Password param** | `password` | `passWord` |\n| **Container** | Custom element | Auto `#zmmtg-root` |\n| **UI** | Embeddable | Full-page |\n| **Preloading** | Not needed | `preLoadWasm()` |\n| **Language** | Init option | `i18n.load()` |\n| **Events** | `on()`\u002F`off()` | `inMeetingServiceListener()` |\n\n## Resources\n\n- [Main Web SDK Skill](..\u002FSKILL.md)\n- [Reference Index](references\u002FREADME.md)\n- [Error Codes](..\u002Ftroubleshooting\u002Ferror-codes.md)\n- [Common Issues](..\u002Ftroubleshooting\u002Fcommon-issues.md)\n- [SharedArrayBuffer Setup](..\u002Fconcepts\u002Fsharedarraybuffer.md)\n- [Official API Reference](https:\u002F\u002Fmarketplacefront.zoom.us\u002Fsdk\u002Fmeeting\u002Fweb\u002Fcomponents\u002Findex.html)\n\n## Operations\n\n- [RUNBOOK.md](RUNBOOK.md) - 5-minute preflight and debugging checklist.\n",{"name":5,"triggers":57,"description":67,"user-invocable":53},[58,59,60,61,62,63,64,65,66],"meeting sdk component view","zoommtgembedded","zoomapproot","embeddable meeting ui","component view embedded zoom","custom meeting ui","custom zoom meeting ui","custom meeting video ui","custom video ui for meeting","Zoom Meeting SDK Web - Component View. Embeddable Zoom meeting components with Promise-based API\nfor flexible integration. Ideal for React\u002FVue\u002FAngular apps and custom layouts. Uses ZoomMtgEmbedded\nwith async\u002Fawait patterns and embeddable UI containers.\n","main","e605d8ddbfb688da57dfaaceebd93f12a64ef1d3","partner-built\u002Fzoom-plugin\u002Fskills\u002Fmeeting-sdk\u002Fweb\u002Fcomponent-view",3945,"https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins","https:\u002F\u002Fgithub.com\u002Fanthropics","https:\u002F\u002Fanthropic.com","2026-11-13 23:29:50",{"source":8,"skillName":5,"commands":77,"prompt":87,"zipAvailable":88},[78,81,84],{"tool":79,"command":80},"npx","npx skills add anthropics\u002Fknowledge-work-plugins --skill zoom-meeting-sdk-web-component-view",{"tool":82,"command":83},"bunx","bunx skills add anthropics\u002Fknowledge-work-plugins --skill zoom-meeting-sdk-web-component-view",{"tool":85,"command":86},"pnpm","pnpm dlx skills add anthropics\u002Fknowledge-work-plugins --skill zoom-meeting-sdk-web-component-view","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fpartner-built\u002Fzoom-plugin\u002Fskills\u002Fmeeting-sdk\u002Fweb\u002Fcomponent-view\u002FSKILL.md",true,[90,96],{"path":91,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":94,"sourceHtmlUrl":95},"references\u002FREADME.md","REFERENCE","参考文档",477,"https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fpartner-built\u002Fzoom-plugin\u002Fskills\u002Fmeeting-sdk\u002Fweb\u002Fcomponent-view\u002Freferences\u002FREADME.md",{"path":97,"resourceType":92,"resourceTypeDesc":93,"sizeBytes":98,"sourceHtmlUrl":99},"RUNBOOK.md",2419,"https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fpartner-built\u002Fzoom-plugin\u002Fskills\u002Fmeeting-sdk\u002Fweb\u002Fcomponent-view\u002FRUNBOOK.md",[101,128,153,176,201,227],{"skillNo":102,"name":103,"nameZh":6,"description":104,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":105,"categories":106,"keywords":107,"publishedAt":52},"01M718Y97HCGW12Q53PSJDY03W","ticket-deflector","Reads a forwarded customer email or ticket, pulls order and refund status from a payments connector (PayPal, Square, or Stripe) or Shopify, account history from the CRM, and open tickets from a support desk (Zoho Desk), drafts a tone-matched reply in the owner's writing voice, and can issue a refund through the payments connector with explicit owner approval. With Shopify connected it also runs a proactive order-triage mode that surfaces orders needing attention — unfulfilled past the promised window, payment problems, pending refunds, stuck shipments — and drafts the next action for each before the customer has to ask. Use when the user says \"draft a response,\" \"answer this customer,\" \"where's my order,\" \"I want a refund,\" \"check my orders,\" or \"anything about to blow up.\"","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Fticket-deflector\u002FSKILL.md",[],[108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127],"ticket","ticket deflector","mode","up","payments","open","writing","when","workflow","ask","Connector","text","mail","window","next","customer","support","crm","past","read",{"skillNo":129,"name":130,"nameZh":6,"description":131,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":132,"categories":133,"keywords":134,"publishedAt":52},"01M718Y55HFAN5705ME5VEDZ9K","tax-season-organizer","Prepares tax-season materials for the owner's accountant, not tax advice. US federal tax; a non-US business gets its closed-books packet instead. Two modes: (1) quarterly estimated tax from YTD net income in the ledger (MYOB, NetSuite, QuickBooks, Xero, or Zoho Books); (2) year-end 1099 prep, scanning the ledger, PayPal, and Stripe for contractors paid over USD 600 into a 1099-NEC list with missing W-9 flags.\nAny tax request routes first to \u002Ftax-prep, which confirms the books are closed and reconciled before running this skill. Use this skill directly only when the owner says the period's books are already closed: \"books are closed, now do the 1099s,\" \"run the quarterly estimate off the closed numbers,\" or \"just the contractor W-9 list.\"","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Ftax-season-organizer\u002FSKILL.md",[],[135,136,137,138,139,140,141,142,143,144,115,145,146,147,148,149,127,150,151,152],"tax season organizer","tax","us federal","which","netsuite","paid","end","usd","only","now","books","xero","scanning","run","request","flags","list","stripe",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":52},"01M718Y13VVPHDD9NTDBVFJ2AZ","tax-prep","Prepares tax materials as a two-link chain — month-end-prep confirms the books are closed and reconciled first, then tax-season-organizer calculates the quarterly estimated payment or builds the year-end 1099-NEC list and accountant packet from those closed numbers. Requires a ledger (MYOB, NetSuite, QuickBooks, Xero, or Zoho Books); uses Gusto, PayPal, and Stripe when connected, else CSV upload. US federal tax math; a non-US business gets the closed-books packet. Prep material for a CPA, never tax advice, nothing filed. Trigger on \"quarterly taxes,\" \"estimated tax payment,\" \"how much should I set aside,\" \"1099s,\" \"1099-NEC,\" \"W-9s,\" \"year-end tax prep,\" \"get my books ready for my accountant,\" any phrasing that suggests a tax deadline is coming, or a question about net profit or YTD income that sounds like worry about a tax bill. An owner who says the period's books are already closed routes to tax-season-organizer directly.","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Ftax-prep\u002FSKILL.md",[],[160,136,161,162,137,163,164,139,165,166,167,168,169,170,171,141,172,173,174,175],"tax prep","prep","SET","as","ready","never","zoho books","get","chain","profit","for","trigger","material","question","paypal","business",{"skillNo":177,"name":178,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":183,"publishedAt":52},"01M718XWTWQZ01GYSG9T8RW8TW","speed-to-lead","Makes sure no inbound lead goes unanswered. Watches web forms, the shared inbox, and the CRM for new inquiries, qualifies each one against the owner's criteria, drafts a reply in the owner's voice with real meeting times for the owner to approve and send, routes anything hot to a human right away, and logs the whole thing to the CRM. Never sends on its own. Built to run on a schedule so overnight inquiries are drafted and sorted by morning, and works from forwarded or pasted inquiries when no connector is available. Use this whenever the owner is worried about inbound leads or response time — including phrasings like \"leads are going cold,\" \"did anyone answer that inquiry,\" \"I keep missing form submissions,\" \"nothing falls through the cracks,\" \"handle my inbound,\" \"respond to this lead,\" or \"we lose people because nobody gets back fast enough.\" Reach for it for a single unanswered inquiry as readily as for a standing setup.","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Fspeed-to-lead\u002FSKILL.md",[182],{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},[184,185,186,187,188,189,165,190,191,192,193,194,195,196,115,197,198,118,199,200],"speed to lead","lead","speed","shared","back","cold","time","inbox","send","respond","new","web forms","people","schedule","logs","sure","human",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":210,"publishedAt":52},"01M718XQYMN1KY3TPS33967FK0","social-content-engine","Runs the owner's content operation as a standing thing rather than a one-off: keeps a rolling posting calendar, learns the owner's voice, generates on-brand Canva graphics, writes captions that sound like them, repurposes one asset into every channel format, and stages posts for approval instead of publishing on its own. Pulls product photos and prices from Shopify when connected; with no connectors, drafts the calendar and asset briefs for manual posting. Use this whenever the owner talks about posting, content, or social — including \"I need to post more,\" \"we've gone quiet on Instagram,\" \"what should we post this month,\" \"make the content,\" \"give me a month of posts,\" \"write this in my voice,\" \"repurpose this,\" or \"set up our content calendar.\" Reach for it for a single post as readily as for a full quarter. One handoff: a finished, approved campaign brief goes to canva-creator; this skill owns the standing operation.","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Fsocial-content-engine\u002FSKILL.md",[207],{"categoryNo":208,"categoryName":209,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000036","内容创作者",[211,212,213,214,215,216,162,217,218,219,220,111,221,115,222,223,224,127,225,226],"social","social content engine","engine","content engine","social content","content","brief","posts","Captions","prices","campaign","me","product","calendar","write","drafts",{"skillNo":228,"name":229,"nameZh":6,"description":230,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":231,"categories":232,"keywords":233,"publishedAt":52},"01M718XMPJVH0EVRVP998BVZPC","smb-router","The front door to the Small Business plugin. Listens to what the owner needs right now — vague or specific — and routes them to the best skill or slash command for the moment. Also serves as a guide: explains what's available, suggests what to try next, and adapts recommendations based on stored business context. Trigger whenever the owner asks \"what can you do,\" \"help me with my business,\" \"what should I focus on,\" \"I don't know where to start,\" or any open-ended business request that doesn't clearly match a single skill.","https:\u002F\u002Fgithub.com\u002Fanthropics\u002Fknowledge-work-plugins\u002Fblob\u002Fmain\u002Fsmall-business\u002Fskills\u002Fsmb-router\u002FSKILL.md",[],[234,235,236,163,237,170,171,238,113,239,144,175,240,241,242,243,244,222,245,122],"router","smb","smb router","do","front","single","you","vague","can","with","plugin","focus"]