[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EXSAAGPQXBTSM3J5C6BB36":3,"skill-same:01M6EXSAAGPQXBTSM3J5C6BB36":71},{"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":18,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":47,"ownerHtmlUrl":48,"ownerBlogUrl":6,"ownerDescription":49,"updatedAt":50,"install":51,"resources":64},"01M6EXSAAGPQXBTSM3J5C6BB36","azure-web-pubsub-ts",null,"Build real-time messaging applications using Azure Web PubSub SDKs for JavaScript (@azure\u002Fweb-pubsub, @azure\u002Fweb-pubsub-client). Use when implementing WebSocket-based real-time features, pub\u002Fsub messaging, group chat, or live notifications.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-web-pubsub-ts\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"web","pubsub","azure web pubsub","azure web pubsub ts","azure","messaging","notifications","websocket","real-time","applications","use","build","chat","time","live","client","javascript","2026-11-10 10:12:30",false,"---\nname: azure-web-pubsub-ts\ndescription: Build real-time messaging applications using Azure Web PubSub SDKs for JavaScript (@azure\u002Fweb-pubsub, @azure\u002Fweb-pubsub-client). Use when implementing WebSocket-based real-time features, pub\u002Fsub messaging, group chat, or live notifications.\npackage: \"@azure\u002Fweb-pubsub, @azure\u002Fweb-pubsub-client\"\n---\n\n# Azure Web PubSub SDKs for TypeScript\n\nReal-time messaging with WebSocket connections and pub\u002Fsub patterns.\n\n## Installation\n\n```bash\n# Server-side management\nnpm install @azure\u002Fweb-pubsub @azure\u002Fidentity\n\n# Client-side real-time messaging\nnpm install @azure\u002Fweb-pubsub-client\n\n# Express middleware for event handlers\nnpm install @azure\u002Fweb-pubsub-express\n```\n\n## Environment Variables\n\n```bash\nWEBPUBSUB_CONNECTION_STRING=Endpoint=https:\u002F\u002F\u003Cresource>.webpubsub.azure.com;AccessKey=\u003Ckey>;Version=1.0;\nWEBPUBSUB_ENDPOINT=https:\u002F\u002F\u003Cresource>.webpubsub.azure.com\n```\n\n## Server-Side: WebPubSubServiceClient\n\n### Authentication\n\n```typescript\nimport { WebPubSubServiceClient, AzureKeyCredential } from \"@azure\u002Fweb-pubsub\";\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\n\n\u002F\u002F Connection string\nconst client = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_CONNECTION_STRING!,\n  \"chat\"  \u002F\u002F hub name\n);\n\n\u002F\u002F DefaultAzureCredential (recommended)\nconst client2 = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_ENDPOINT!,\n  new DefaultAzureCredential(),\n  \"chat\"\n);\n\n\u002F\u002F AzureKeyCredential\nconst client3 = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_ENDPOINT!,\n  new AzureKeyCredential(\"\u003Caccess-key>\"),\n  \"chat\"\n);\n```\n\n### Generate Client Access Token\n\n```typescript\n\u002F\u002F Basic token\nconst token = await client.getClientAccessToken();\nconsole.log(token.url);  \u002F\u002F wss:\u002F\u002F...?access_token=...\n\n\u002F\u002F Token with user ID\nconst userToken = await client.getClientAccessToken({\n  userId: \"user123\",\n});\n\n\u002F\u002F Token with permissions\nconst permToken = await client.getClientAccessToken({\n  userId: \"user123\",\n  roles: [\n    \"webpubsub.joinLeaveGroup\",\n    \"webpubsub.sendToGroup\",\n    \"webpubsub.sendToGroup.chat-room\",  \u002F\u002F specific group\n  ],\n  groups: [\"chat-room\"],  \u002F\u002F auto-join on connect\n  expirationTimeInMinutes: 60,\n});\n```\n\n### Send Messages\n\n```typescript\n\u002F\u002F Broadcast to all connections in hub\nawait client.sendToAll({ message: \"Hello everyone!\" });\nawait client.sendToAll(\"Plain text\", { contentType: \"text\u002Fplain\" });\n\n\u002F\u002F Send to specific user (all their connections)\nawait client.sendToUser(\"user123\", { message: \"Hello!\" });\n\n\u002F\u002F Send to specific connection\nawait client.sendToConnection(\"connectionId\", { data: \"Direct message\" });\n\n\u002F\u002F Send with filter (OData syntax)\nawait client.sendToAll({ message: \"Filtered\" }, {\n  filter: \"userId ne 'admin'\",\n});\n```\n\n### Group Management\n\n```typescript\nconst group = client.group(\"chat-room\");\n\n\u002F\u002F Add user\u002Fconnection to group\nawait group.addUser(\"user123\");\nawait group.addConnection(\"connectionId\");\n\n\u002F\u002F Remove from group\nawait group.removeUser(\"user123\");\n\n\u002F\u002F Send to group\nawait group.sendToAll({ message: \"Group message\" });\n\n\u002F\u002F Close all connections in group\nawait group.closeAllConnections({ reason: \"Maintenance\" });\n```\n\n### Connection Management\n\n```typescript\n\u002F\u002F Check existence\nconst userExists = await client.userExists(\"user123\");\nconst connExists = await client.connectionExists(\"connectionId\");\n\n\u002F\u002F Close connections\nawait client.closeConnection(\"connectionId\", { reason: \"Kicked\" });\nawait client.closeUserConnections(\"user123\");\nawait client.closeAllConnections();\n\n\u002F\u002F Permissions\nawait client.grantPermission(\"connectionId\", \"sendToGroup\", { targetName: \"chat\" });\nawait client.revokePermission(\"connectionId\", \"sendToGroup\", { targetName: \"chat\" });\n```\n\n## Client-Side: WebPubSubClient\n\n### Connect\n\n```typescript\nimport { WebPubSubClient } from \"@azure\u002Fweb-pubsub-client\";\n\n\u002F\u002F Direct URL\nconst client = new WebPubSubClient(\"\u003Cclient-access-url>\");\n\n\u002F\u002F Dynamic URL from negotiate endpoint\nconst client2 = new WebPubSubClient({\n  getClientAccessUrl: async () => {\n    const response = await fetch(\"\u002Fnegotiate\");\n    const { url } = await response.json();\n    return url;\n  },\n});\n\n\u002F\u002F Register handlers BEFORE starting\nclient.on(\"connected\", (e) => {\n  console.log(`Connected: ${e.connectionId}`);\n});\n\nclient.on(\"group-message\", (e) => {\n  console.log(`${e.message.group}: ${e.message.data}`);\n});\n\nawait client.start();\n```\n\n### Send Messages\n\n```typescript\n\u002F\u002F Join group first\nawait client.joinGroup(\"chat-room\");\n\n\u002F\u002F Send to group\nawait client.sendToGroup(\"chat-room\", \"Hello!\", \"text\");\nawait client.sendToGroup(\"chat-room\", { type: \"message\", content: \"Hi\" }, \"json\");\n\n\u002F\u002F Send options\nawait client.sendToGroup(\"chat-room\", \"Hello\", \"text\", {\n  noEcho: true,        \u002F\u002F Don't echo back to sender\n  fireAndForget: true, \u002F\u002F Don't wait for ack\n});\n\n\u002F\u002F Send event to server\nawait client.sendEvent(\"userAction\", { action: \"typing\" }, \"json\");\n```\n\n### Event Handlers\n\n```typescript\n\u002F\u002F Connection lifecycle\nclient.on(\"connected\", (e) => {\n  console.log(`Connected: ${e.connectionId}, User: ${e.userId}`);\n});\n\nclient.on(\"disconnected\", (e) => {\n  console.log(`Disconnected: ${e.message}`);\n});\n\nclient.on(\"stopped\", () => {\n  console.log(\"Client stopped\");\n});\n\n\u002F\u002F Messages\nclient.on(\"group-message\", (e) => {\n  console.log(`[${e.message.group}] ${e.message.fromUserId}: ${e.message.data}`);\n});\n\nclient.on(\"server-message\", (e) => {\n  console.log(`Server: ${e.message.data}`);\n});\n\n\u002F\u002F Rejoin failure\nclient.on(\"rejoin-group-failed\", (e) => {\n  console.log(`Failed to rejoin ${e.group}: ${e.error}`);\n});\n```\n\n## Express Event Handler\n\n```typescript\nimport express from \"express\";\nimport { WebPubSubEventHandler } from \"@azure\u002Fweb-pubsub-express\";\n\nconst app = express();\n\nconst handler = new WebPubSubEventHandler(\"chat\", {\n  path: \"\u002Fapi\u002Fwebpubsub\u002Fhubs\u002Fchat\u002F\",\n  \n  \u002F\u002F Blocking: approve\u002Freject connection\n  handleConnect: (req, res) => {\n    if (!req.claims?.sub) {\n      res.fail(401, \"Authentication required\");\n      return;\n    }\n    res.success({\n      userId: req.claims.sub[0],\n      groups: [\"general\"],\n      roles: [\"webpubsub.sendToGroup\"],\n    });\n  },\n  \n  \u002F\u002F Blocking: handle custom events\n  handleUserEvent: (req, res) => {\n    console.log(`Event from ${req.context.userId}:`, req.data);\n    res.success(`Received: ${req.data}`, \"text\");\n  },\n  \n  \u002F\u002F Non-blocking\n  onConnected: (req) => {\n    console.log(`Client connected: ${req.context.connectionId}`);\n  },\n  \n  onDisconnected: (req) => {\n    console.log(`Client disconnected: ${req.context.connectionId}`);\n  },\n});\n\napp.use(handler.getMiddleware());\n\n\u002F\u002F Negotiate endpoint\napp.get(\"\u002Fnegotiate\", async (req, res) => {\n  const token = await serviceClient.getClientAccessToken({\n    userId: req.user?.id,\n  });\n  res.json({ url: token.url });\n});\n\napp.listen(8080);\n```\n\n## Key Types\n\n```typescript\n\u002F\u002F Server\nimport {\n  WebPubSubServiceClient,\n  WebPubSubGroup,\n  GenerateClientTokenOptions,\n  HubSendToAllOptions,\n} from \"@azure\u002Fweb-pubsub\";\n\n\u002F\u002F Client\nimport {\n  WebPubSubClient,\n  WebPubSubClientOptions,\n  OnConnectedArgs,\n  OnGroupDataMessageArgs,\n} from \"@azure\u002Fweb-pubsub-client\";\n\n\u002F\u002F Express\nimport {\n  WebPubSubEventHandler,\n  ConnectRequest,\n  UserEventRequest,\n  ConnectResponseHandler,\n} from \"@azure\u002Fweb-pubsub-express\";\n```\n\n## Best Practices\n\n1. **Use Entra ID auth** - `DefaultAzureCredential` for production\n2. **Register handlers before start** - Don't miss initial events\n3. **Use groups for channels** - Organize messages by topic\u002Froom\n4. **Handle reconnection** - Client auto-reconnects by default\n5. **Validate in handleConnect** - Reject unauthorized connections early\n6. **Use noEcho** - Prevent message echo back to sender when needed\n","# Azure Web PubSub SDKs for TypeScript\n\nReal-time messaging with WebSocket connections and pub\u002Fsub patterns.\n\n## Installation\n\n```bash\n# Server-side management\nnpm install @azure\u002Fweb-pubsub @azure\u002Fidentity\n\n# Client-side real-time messaging\nnpm install @azure\u002Fweb-pubsub-client\n\n# Express middleware for event handlers\nnpm install @azure\u002Fweb-pubsub-express\n```\n\n## Environment Variables\n\n```bash\nWEBPUBSUB_CONNECTION_STRING=Endpoint=https:\u002F\u002F\u003Cresource>.webpubsub.azure.com;AccessKey=\u003Ckey>;Version=1.0;\nWEBPUBSUB_ENDPOINT=https:\u002F\u002F\u003Cresource>.webpubsub.azure.com\n```\n\n## Server-Side: WebPubSubServiceClient\n\n### Authentication\n\n```typescript\nimport { WebPubSubServiceClient, AzureKeyCredential } from \"@azure\u002Fweb-pubsub\";\nimport { DefaultAzureCredential } from \"@azure\u002Fidentity\";\n\n\u002F\u002F Connection string\nconst client = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_CONNECTION_STRING!,\n  \"chat\"  \u002F\u002F hub name\n);\n\n\u002F\u002F DefaultAzureCredential (recommended)\nconst client2 = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_ENDPOINT!,\n  new DefaultAzureCredential(),\n  \"chat\"\n);\n\n\u002F\u002F AzureKeyCredential\nconst client3 = new WebPubSubServiceClient(\n  process.env.WEBPUBSUB_ENDPOINT!,\n  new AzureKeyCredential(\"\u003Caccess-key>\"),\n  \"chat\"\n);\n```\n\n### Generate Client Access Token\n\n```typescript\n\u002F\u002F Basic token\nconst token = await client.getClientAccessToken();\nconsole.log(token.url);  \u002F\u002F wss:\u002F\u002F...?access_token=...\n\n\u002F\u002F Token with user ID\nconst userToken = await client.getClientAccessToken({\n  userId: \"user123\",\n});\n\n\u002F\u002F Token with permissions\nconst permToken = await client.getClientAccessToken({\n  userId: \"user123\",\n  roles: [\n    \"webpubsub.joinLeaveGroup\",\n    \"webpubsub.sendToGroup\",\n    \"webpubsub.sendToGroup.chat-room\",  \u002F\u002F specific group\n  ],\n  groups: [\"chat-room\"],  \u002F\u002F auto-join on connect\n  expirationTimeInMinutes: 60,\n});\n```\n\n### Send Messages\n\n```typescript\n\u002F\u002F Broadcast to all connections in hub\nawait client.sendToAll({ message: \"Hello everyone!\" });\nawait client.sendToAll(\"Plain text\", { contentType: \"text\u002Fplain\" });\n\n\u002F\u002F Send to specific user (all their connections)\nawait client.sendToUser(\"user123\", { message: \"Hello!\" });\n\n\u002F\u002F Send to specific connection\nawait client.sendToConnection(\"connectionId\", { data: \"Direct message\" });\n\n\u002F\u002F Send with filter (OData syntax)\nawait client.sendToAll({ message: \"Filtered\" }, {\n  filter: \"userId ne 'admin'\",\n});\n```\n\n### Group Management\n\n```typescript\nconst group = client.group(\"chat-room\");\n\n\u002F\u002F Add user\u002Fconnection to group\nawait group.addUser(\"user123\");\nawait group.addConnection(\"connectionId\");\n\n\u002F\u002F Remove from group\nawait group.removeUser(\"user123\");\n\n\u002F\u002F Send to group\nawait group.sendToAll({ message: \"Group message\" });\n\n\u002F\u002F Close all connections in group\nawait group.closeAllConnections({ reason: \"Maintenance\" });\n```\n\n### Connection Management\n\n```typescript\n\u002F\u002F Check existence\nconst userExists = await client.userExists(\"user123\");\nconst connExists = await client.connectionExists(\"connectionId\");\n\n\u002F\u002F Close connections\nawait client.closeConnection(\"connectionId\", { reason: \"Kicked\" });\nawait client.closeUserConnections(\"user123\");\nawait client.closeAllConnections();\n\n\u002F\u002F Permissions\nawait client.grantPermission(\"connectionId\", \"sendToGroup\", { targetName: \"chat\" });\nawait client.revokePermission(\"connectionId\", \"sendToGroup\", { targetName: \"chat\" });\n```\n\n## Client-Side: WebPubSubClient\n\n### Connect\n\n```typescript\nimport { WebPubSubClient } from \"@azure\u002Fweb-pubsub-client\";\n\n\u002F\u002F Direct URL\nconst client = new WebPubSubClient(\"\u003Cclient-access-url>\");\n\n\u002F\u002F Dynamic URL from negotiate endpoint\nconst client2 = new WebPubSubClient({\n  getClientAccessUrl: async () => {\n    const response = await fetch(\"\u002Fnegotiate\");\n    const { url } = await response.json();\n    return url;\n  },\n});\n\n\u002F\u002F Register handlers BEFORE starting\nclient.on(\"connected\", (e) => {\n  console.log(`Connected: ${e.connectionId}`);\n});\n\nclient.on(\"group-message\", (e) => {\n  console.log(`${e.message.group}: ${e.message.data}`);\n});\n\nawait client.start();\n```\n\n### Send Messages\n\n```typescript\n\u002F\u002F Join group first\nawait client.joinGroup(\"chat-room\");\n\n\u002F\u002F Send to group\nawait client.sendToGroup(\"chat-room\", \"Hello!\", \"text\");\nawait client.sendToGroup(\"chat-room\", { type: \"message\", content: \"Hi\" }, \"json\");\n\n\u002F\u002F Send options\nawait client.sendToGroup(\"chat-room\", \"Hello\", \"text\", {\n  noEcho: true,        \u002F\u002F Don't echo back to sender\n  fireAndForget: true, \u002F\u002F Don't wait for ack\n});\n\n\u002F\u002F Send event to server\nawait client.sendEvent(\"userAction\", { action: \"typing\" }, \"json\");\n```\n\n### Event Handlers\n\n```typescript\n\u002F\u002F Connection lifecycle\nclient.on(\"connected\", (e) => {\n  console.log(`Connected: ${e.connectionId}, User: ${e.userId}`);\n});\n\nclient.on(\"disconnected\", (e) => {\n  console.log(`Disconnected: ${e.message}`);\n});\n\nclient.on(\"stopped\", () => {\n  console.log(\"Client stopped\");\n});\n\n\u002F\u002F Messages\nclient.on(\"group-message\", (e) => {\n  console.log(`[${e.message.group}] ${e.message.fromUserId}: ${e.message.data}`);\n});\n\nclient.on(\"server-message\", (e) => {\n  console.log(`Server: ${e.message.data}`);\n});\n\n\u002F\u002F Rejoin failure\nclient.on(\"rejoin-group-failed\", (e) => {\n  console.log(`Failed to rejoin ${e.group}: ${e.error}`);\n});\n```\n\n## Express Event Handler\n\n```typescript\nimport express from \"express\";\nimport { WebPubSubEventHandler } from \"@azure\u002Fweb-pubsub-express\";\n\nconst app = express();\n\nconst handler = new WebPubSubEventHandler(\"chat\", {\n  path: \"\u002Fapi\u002Fwebpubsub\u002Fhubs\u002Fchat\u002F\",\n  \n  \u002F\u002F Blocking: approve\u002Freject connection\n  handleConnect: (req, res) => {\n    if (!req.claims?.sub) {\n      res.fail(401, \"Authentication required\");\n      return;\n    }\n    res.success({\n      userId: req.claims.sub[0],\n      groups: [\"general\"],\n      roles: [\"webpubsub.sendToGroup\"],\n    });\n  },\n  \n  \u002F\u002F Blocking: handle custom events\n  handleUserEvent: (req, res) => {\n    console.log(`Event from ${req.context.userId}:`, req.data);\n    res.success(`Received: ${req.data}`, \"text\");\n  },\n  \n  \u002F\u002F Non-blocking\n  onConnected: (req) => {\n    console.log(`Client connected: ${req.context.connectionId}`);\n  },\n  \n  onDisconnected: (req) => {\n    console.log(`Client disconnected: ${req.context.connectionId}`);\n  },\n});\n\napp.use(handler.getMiddleware());\n\n\u002F\u002F Negotiate endpoint\napp.get(\"\u002Fnegotiate\", async (req, res) => {\n  const token = await serviceClient.getClientAccessToken({\n    userId: req.user?.id,\n  });\n  res.json({ url: token.url });\n});\n\napp.listen(8080);\n```\n\n## Key Types\n\n```typescript\n\u002F\u002F Server\nimport {\n  WebPubSubServiceClient,\n  WebPubSubGroup,\n  GenerateClientTokenOptions,\n  HubSendToAllOptions,\n} from \"@azure\u002Fweb-pubsub\";\n\n\u002F\u002F Client\nimport {\n  WebPubSubClient,\n  WebPubSubClientOptions,\n  OnConnectedArgs,\n  OnGroupDataMessageArgs,\n} from \"@azure\u002Fweb-pubsub-client\";\n\n\u002F\u002F Express\nimport {\n  WebPubSubEventHandler,\n  ConnectRequest,\n  UserEventRequest,\n  ConnectResponseHandler,\n} from \"@azure\u002Fweb-pubsub-express\";\n```\n\n## Best Practices\n\n1. **Use Entra ID auth** - `DefaultAzureCredential` for production\n2. **Register handlers before start** - Don't miss initial events\n3. **Use groups for channels** - Organize messages by topic\u002Froom\n4. **Handle reconnection** - Client auto-reconnects by default\n5. **Validate in handleConnect** - Reject unauthorized connections early\n6. **Use noEcho** - Prevent message echo back to sender when needed\n",{"name":5,"package":41,"description":7},"@azure\u002Fweb-pubsub, @azure\u002Fweb-pubsub-client","main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-web-pubsub-ts",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill azure-web-pubsub-ts",{"tool":57,"command":58},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill azure-web-pubsub-ts",{"tool":60,"command":61},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill azure-web-pubsub-ts","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-web-pubsub-ts\u002FSKILL.md",true,[65],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"skill-report.json","REFERENCE","参考文档",11591,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Fazure-web-pubsub-ts\u002Fskill-report.json",[72,86,96,105,111,118],{"skillNo":73,"name":74,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":75,"categories":76,"keywords":82,"publishedAt":36},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[77],{"categoryNo":78,"categoryName":79,"taxonomyType":80,"taxonomyTypeDesc":81},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[83,84,85],"model","model hierarchy","model hierarchy skill",{"skillNo":87,"name":88,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":92,"publishedAt":36},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[91],{"categoryNo":78,"categoryName":79,"taxonomyType":80,"taxonomyTypeDesc":81},[93,94,95],"MCP","zoom","zoom mcp",{"skillNo":97,"name":98,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":36},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[102,103,104,94],"sdk","zoom apps sdk","apps",{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":36},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[107],{"skillNo":112,"name":113,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":117,"publishedAt":36},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[116],{"categoryNo":78,"categoryName":79,"taxonomyType":80,"taxonomyTypeDesc":81},[113],{"skillNo":119,"name":120,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":36},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[120]]