[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6G90X96C98C190FTGSGEH6H":3,"skill-same:01M6G90X96C98C190FTGSGEH6H":70},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":34,"linkOnly":35,"markdownContent":36,"markdownBody":37,"frontMatter":38,"refName":40,"commitSha":41,"skillDirectory":42,"forksCount":13,"repositoryHtmlUrl":43,"repositoryHomepageUrl":6,"ownerHtmlUrl":44,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":45,"install":46,"resources":59},"01M6G90X96C98C190FTGSGEH6H","azure-communication-common-java",null,"Azure Communication Services common utilities for Java. Use when working with CommunicationTokenCredential, user identifiers, token refresh, or shared authentication across ACS services.","ricardoaevt\u002Fnexus-roms","ricardoaevt","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F164531880?v=4","01M6DGFGSV6CF9AKPHABBREC79","01M6DGFGYNNPJVDFQA05TDPSBN",0,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-java\u002Fskills\u002Fazure-communication-common-java\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"azure","azure communication common java","communication","java","common","authentication","services","refresh","user","use","across","shared","token","azure communication services","Utilities","with","2026-11-10 10:12:30",false,"---\nname: azure-communication-common-java\ndescription: Azure Communication Services common utilities for Java. Use when working with CommunicationTokenCredential, user identifiers, token refresh, or shared authentication across ACS services.\npackage: com.azure:azure-communication-common\n---\n\n# Azure Communication Common (Java)\n\nShared authentication utilities and data structures for Azure Communication Services.\n\n## Installation\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.azure\u003C\u002FgroupId>\n    \u003CartifactId>azure-communication-common\u003C\u002FartifactId>\n    \u003Cversion>1.4.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n## Key Concepts\n\n| Class | Purpose |\n|-------|---------|\n| `CommunicationTokenCredential` | Authenticate users with ACS services |\n| `CommunicationTokenRefreshOptions` | Configure automatic token refresh |\n| `CommunicationUserIdentifier` | Identify ACS users |\n| `PhoneNumberIdentifier` | Identify PSTN phone numbers |\n| `MicrosoftTeamsUserIdentifier` | Identify Teams users |\n| `UnknownIdentifier` | Generic identifier for unknown types |\n\n## CommunicationTokenCredential\n\n### Static Token (Short-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenCredential;\n\n\u002F\u002F Simple static token - no refresh\nString userToken = \"\u003Cuser-access-token>\";\nCommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);\n\n\u002F\u002F Use with Chat, Calling, etc.\nChatClient chatClient = new ChatClientBuilder()\n    .endpoint(\"https:\u002F\u002F\u003Cresource>.communication.azure.com\")\n    .credential(credential)\n    .buildClient();\n```\n\n### Proactive Token Refresh (Long-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenRefreshOptions;\nimport java.util.concurrent.Callable;\n\n\u002F\u002F Token refresher callback - called when token is about to expire\nCallable\u003CString> tokenRefresher = () -> {\n    \u002F\u002F Call your server to get a fresh token\n    return fetchNewTokenFromServer();\n};\n\n\u002F\u002F With proactive refresh\nCommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)\n    .setRefreshProactively(true)      \u002F\u002F Refresh before expiry\n    .setInitialToken(currentToken);    \u002F\u002F Optional initial token\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);\n```\n\n### Async Token Refresh\n\n```java\nimport java.util.concurrent.CompletableFuture;\n\n\u002F\u002F Async token fetcher\nCallable\u003CString> asyncRefresher = () -> {\n    CompletableFuture\u003CString> future = fetchTokenAsync();\n    return future.get();  \u002F\u002F Block until token is available\n};\n\nCommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)\n    .setRefreshProactively(true);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(options);\n```\n\n## Entra ID (Azure AD) Authentication\n\n```java\nimport com.azure.identity.InteractiveBrowserCredentialBuilder;\nimport com.azure.communication.common.EntraCommunicationTokenCredentialOptions;\nimport java.util.Arrays;\nimport java.util.List;\n\n\u002F\u002F For Teams Phone Extensibility\nInteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()\n    .clientId(\"\u003Cyour-client-id>\")\n    .tenantId(\"\u003Cyour-tenant-id>\")\n    .redirectUrl(\"\u003Cyour-redirect-uri>\")\n    .build();\n\nString resourceEndpoint = \"https:\u002F\u002F\u003Cresource>.communication.azure.com\";\nList\u003CString> scopes = Arrays.asList(\n    \"https:\u002F\u002Fauth.msft.communication.azure.com\u002FTeamsExtension.ManageCalls\"\n);\n\nEntraCommunicationTokenCredentialOptions entraOptions = \n    new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)\n        .setScopes(scopes);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);\n```\n\n## Communication Identifiers\n\n### CommunicationUserIdentifier\n\n```java\nimport com.azure.communication.common.CommunicationUserIdentifier;\n\n\u002F\u002F Create identifier for ACS user\nCommunicationUserIdentifier user = new CommunicationUserIdentifier(\"8:acs:resource-id_user-id\");\n\n\u002F\u002F Get raw ID\nString rawId = user.getId();\n```\n\n### PhoneNumberIdentifier\n\n```java\nimport com.azure.communication.common.PhoneNumberIdentifier;\n\n\u002F\u002F E.164 format phone number\nPhoneNumberIdentifier phone = new PhoneNumberIdentifier(\"+14255551234\");\n\nString phoneNumber = phone.getPhoneNumber();  \u002F\u002F \"+14255551234\"\nString rawId = phone.getRawId();              \u002F\u002F \"4:+14255551234\"\n```\n\n### MicrosoftTeamsUserIdentifier\n\n```java\nimport com.azure.communication.common.MicrosoftTeamsUserIdentifier;\n\n\u002F\u002F Teams user identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);\n\n\u002F\u002F For anonymous Teams users\nMicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setAnonymous(true);\n```\n\n### UnknownIdentifier\n\n```java\nimport com.azure.communication.common.UnknownIdentifier;\n\n\u002F\u002F For identifiers of unknown type\nUnknownIdentifier unknown = new UnknownIdentifier(\"some-raw-id\");\n```\n\n## Identifier Parsing\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\nimport com.azure.communication.common.CommunicationIdentifierModel;\n\n\u002F\u002F Parse raw ID to appropriate type\npublic CommunicationIdentifier parseIdentifier(String rawId) {\n    if (rawId.startsWith(\"8:acs:\")) {\n        return new CommunicationUserIdentifier(rawId);\n    } else if (rawId.startsWith(\"4:\")) {\n        String phone = rawId.substring(2);\n        return new PhoneNumberIdentifier(phone);\n    } else if (rawId.startsWith(\"8:orgid:\")) {\n        String teamsId = rawId.substring(8);\n        return new MicrosoftTeamsUserIdentifier(teamsId);\n    } else {\n        return new UnknownIdentifier(rawId);\n    }\n}\n```\n\n## Type Checking Identifiers\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\n\npublic void processIdentifier(CommunicationIdentifier identifier) {\n    if (identifier instanceof CommunicationUserIdentifier) {\n        CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;\n        System.out.println(\"ACS User: \" + user.getId());\n        \n    } else if (identifier instanceof PhoneNumberIdentifier) {\n        PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;\n        System.out.println(\"Phone: \" + phone.getPhoneNumber());\n        \n    } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {\n        MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;\n        System.out.println(\"Teams User: \" + teams.getUserId());\n        System.out.println(\"Anonymous: \" + teams.isAnonymous());\n        \n    } else if (identifier instanceof UnknownIdentifier) {\n        UnknownIdentifier unknown = (UnknownIdentifier) identifier;\n        System.out.println(\"Unknown: \" + unknown.getId());\n    }\n}\n```\n\n## Token Access\n\n```java\nimport com.azure.core.credential.AccessToken;\n\n\u002F\u002F Get current token (for debugging\u002Flogging - don't expose!)\nCommunicationTokenCredential credential = new CommunicationTokenCredential(token);\n\n\u002F\u002F Sync access\nAccessToken accessToken = credential.getToken();\nSystem.out.println(\"Token expires: \" + accessToken.getExpiresAt());\n\n\u002F\u002F Async access\ncredential.getTokenAsync()\n    .subscribe(token -> {\n        System.out.println(\"Token: \" + token.getToken().substring(0, 20) + \"...\");\n        System.out.println(\"Expires: \" + token.getExpiresAt());\n    });\n```\n\n## Dispose Credential\n\n```java\n\u002F\u002F Clean up when done\ncredential.close();\n\n\u002F\u002F Or use try-with-resources\ntry (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {\n    \u002F\u002F Use credential\n    chatClient.doSomething();\n}\n```\n\n## Cloud Environments\n\n```java\nimport com.azure.communication.common.CommunicationCloudEnvironment;\n\n\u002F\u002F Available environments\nCommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;\nCommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;\nCommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;\n\n\u002F\u002F Set on Teams identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cuser-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);\n```\n\n## Environment Variables\n\n```bash\nAZURE_COMMUNICATION_ENDPOINT=https:\u002F\u002F\u003Cresource>.communication.azure.com\nAZURE_COMMUNICATION_USER_TOKEN=\u003Cuser-access-token>\n```\n\n## Best Practices\n\n1. **Proactive Refresh** - Always use `setRefreshProactively(true)` for long-lived clients\n2. **Token Security** - Never log or expose full tokens\n3. **Close Credentials** - Dispose of credentials when no longer needed\n4. **Error Handling** - Handle token refresh failures gracefully\n5. **Identifier Types** - Use specific identifier types, not raw strings\n\n## Common Usage Patterns\n\n```java\n\u002F\u002F Pattern: Create credential for Chat\u002FCalling client\npublic ChatClient createChatClient(String token, String endpoint) {\n    CommunicationTokenRefreshOptions refreshOptions = \n        new CommunicationTokenRefreshOptions(this::refreshToken)\n            .setRefreshProactively(true)\n            .setInitialToken(token);\n    \n    CommunicationTokenCredential credential = \n        new CommunicationTokenCredential(refreshOptions);\n    \n    return new ChatClientBuilder()\n        .endpoint(endpoint)\n        .credential(credential)\n        .buildClient();\n}\n\nprivate String refreshToken() {\n    \u002F\u002F Call your token endpoint\n    return tokenService.getNewToken();\n}\n```\n\n## Trigger Phrases\n\n- \"ACS authentication\", \"communication token credential\"\n- \"user access token\", \"token refresh\"\n- \"CommunicationUserIdentifier\", \"PhoneNumberIdentifier\"\n- \"Azure Communication Services authentication\"\n","# Azure Communication Common (Java)\n\nShared authentication utilities and data structures for Azure Communication Services.\n\n## Installation\n\n```xml\n\u003Cdependency>\n    \u003CgroupId>com.azure\u003C\u002FgroupId>\n    \u003CartifactId>azure-communication-common\u003C\u002FartifactId>\n    \u003Cversion>1.4.0\u003C\u002Fversion>\n\u003C\u002Fdependency>\n```\n\n## Key Concepts\n\n| Class | Purpose |\n|-------|---------|\n| `CommunicationTokenCredential` | Authenticate users with ACS services |\n| `CommunicationTokenRefreshOptions` | Configure automatic token refresh |\n| `CommunicationUserIdentifier` | Identify ACS users |\n| `PhoneNumberIdentifier` | Identify PSTN phone numbers |\n| `MicrosoftTeamsUserIdentifier` | Identify Teams users |\n| `UnknownIdentifier` | Generic identifier for unknown types |\n\n## CommunicationTokenCredential\n\n### Static Token (Short-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenCredential;\n\n\u002F\u002F Simple static token - no refresh\nString userToken = \"\u003Cuser-access-token>\";\nCommunicationTokenCredential credential = new CommunicationTokenCredential(userToken);\n\n\u002F\u002F Use with Chat, Calling, etc.\nChatClient chatClient = new ChatClientBuilder()\n    .endpoint(\"https:\u002F\u002F\u003Cresource>.communication.azure.com\")\n    .credential(credential)\n    .buildClient();\n```\n\n### Proactive Token Refresh (Long-lived Clients)\n\n```java\nimport com.azure.communication.common.CommunicationTokenRefreshOptions;\nimport java.util.concurrent.Callable;\n\n\u002F\u002F Token refresher callback - called when token is about to expire\nCallable\u003CString> tokenRefresher = () -> {\n    \u002F\u002F Call your server to get a fresh token\n    return fetchNewTokenFromServer();\n};\n\n\u002F\u002F With proactive refresh\nCommunicationTokenRefreshOptions refreshOptions = new CommunicationTokenRefreshOptions(tokenRefresher)\n    .setRefreshProactively(true)      \u002F\u002F Refresh before expiry\n    .setInitialToken(currentToken);    \u002F\u002F Optional initial token\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(refreshOptions);\n```\n\n### Async Token Refresh\n\n```java\nimport java.util.concurrent.CompletableFuture;\n\n\u002F\u002F Async token fetcher\nCallable\u003CString> asyncRefresher = () -> {\n    CompletableFuture\u003CString> future = fetchTokenAsync();\n    return future.get();  \u002F\u002F Block until token is available\n};\n\nCommunicationTokenRefreshOptions options = new CommunicationTokenRefreshOptions(asyncRefresher)\n    .setRefreshProactively(true);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(options);\n```\n\n## Entra ID (Azure AD) Authentication\n\n```java\nimport com.azure.identity.InteractiveBrowserCredentialBuilder;\nimport com.azure.communication.common.EntraCommunicationTokenCredentialOptions;\nimport java.util.Arrays;\nimport java.util.List;\n\n\u002F\u002F For Teams Phone Extensibility\nInteractiveBrowserCredential entraCredential = new InteractiveBrowserCredentialBuilder()\n    .clientId(\"\u003Cyour-client-id>\")\n    .tenantId(\"\u003Cyour-tenant-id>\")\n    .redirectUrl(\"\u003Cyour-redirect-uri>\")\n    .build();\n\nString resourceEndpoint = \"https:\u002F\u002F\u003Cresource>.communication.azure.com\";\nList\u003CString> scopes = Arrays.asList(\n    \"https:\u002F\u002Fauth.msft.communication.azure.com\u002FTeamsExtension.ManageCalls\"\n);\n\nEntraCommunicationTokenCredentialOptions entraOptions = \n    new EntraCommunicationTokenCredentialOptions(entraCredential, resourceEndpoint)\n        .setScopes(scopes);\n\nCommunicationTokenCredential credential = new CommunicationTokenCredential(entraOptions);\n```\n\n## Communication Identifiers\n\n### CommunicationUserIdentifier\n\n```java\nimport com.azure.communication.common.CommunicationUserIdentifier;\n\n\u002F\u002F Create identifier for ACS user\nCommunicationUserIdentifier user = new CommunicationUserIdentifier(\"8:acs:resource-id_user-id\");\n\n\u002F\u002F Get raw ID\nString rawId = user.getId();\n```\n\n### PhoneNumberIdentifier\n\n```java\nimport com.azure.communication.common.PhoneNumberIdentifier;\n\n\u002F\u002F E.164 format phone number\nPhoneNumberIdentifier phone = new PhoneNumberIdentifier(\"+14255551234\");\n\nString phoneNumber = phone.getPhoneNumber();  \u002F\u002F \"+14255551234\"\nString rawId = phone.getRawId();              \u002F\u002F \"4:+14255551234\"\n```\n\n### MicrosoftTeamsUserIdentifier\n\n```java\nimport com.azure.communication.common.MicrosoftTeamsUserIdentifier;\n\n\u002F\u002F Teams user identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.PUBLIC);\n\n\u002F\u002F For anonymous Teams users\nMicrosoftTeamsUserIdentifier anonymousTeamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cteams-user-id>\")\n    .setAnonymous(true);\n```\n\n### UnknownIdentifier\n\n```java\nimport com.azure.communication.common.UnknownIdentifier;\n\n\u002F\u002F For identifiers of unknown type\nUnknownIdentifier unknown = new UnknownIdentifier(\"some-raw-id\");\n```\n\n## Identifier Parsing\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\nimport com.azure.communication.common.CommunicationIdentifierModel;\n\n\u002F\u002F Parse raw ID to appropriate type\npublic CommunicationIdentifier parseIdentifier(String rawId) {\n    if (rawId.startsWith(\"8:acs:\")) {\n        return new CommunicationUserIdentifier(rawId);\n    } else if (rawId.startsWith(\"4:\")) {\n        String phone = rawId.substring(2);\n        return new PhoneNumberIdentifier(phone);\n    } else if (rawId.startsWith(\"8:orgid:\")) {\n        String teamsId = rawId.substring(8);\n        return new MicrosoftTeamsUserIdentifier(teamsId);\n    } else {\n        return new UnknownIdentifier(rawId);\n    }\n}\n```\n\n## Type Checking Identifiers\n\n```java\nimport com.azure.communication.common.CommunicationIdentifier;\n\npublic void processIdentifier(CommunicationIdentifier identifier) {\n    if (identifier instanceof CommunicationUserIdentifier) {\n        CommunicationUserIdentifier user = (CommunicationUserIdentifier) identifier;\n        System.out.println(\"ACS User: \" + user.getId());\n        \n    } else if (identifier instanceof PhoneNumberIdentifier) {\n        PhoneNumberIdentifier phone = (PhoneNumberIdentifier) identifier;\n        System.out.println(\"Phone: \" + phone.getPhoneNumber());\n        \n    } else if (identifier instanceof MicrosoftTeamsUserIdentifier) {\n        MicrosoftTeamsUserIdentifier teams = (MicrosoftTeamsUserIdentifier) identifier;\n        System.out.println(\"Teams User: \" + teams.getUserId());\n        System.out.println(\"Anonymous: \" + teams.isAnonymous());\n        \n    } else if (identifier instanceof UnknownIdentifier) {\n        UnknownIdentifier unknown = (UnknownIdentifier) identifier;\n        System.out.println(\"Unknown: \" + unknown.getId());\n    }\n}\n```\n\n## Token Access\n\n```java\nimport com.azure.core.credential.AccessToken;\n\n\u002F\u002F Get current token (for debugging\u002Flogging - don't expose!)\nCommunicationTokenCredential credential = new CommunicationTokenCredential(token);\n\n\u002F\u002F Sync access\nAccessToken accessToken = credential.getToken();\nSystem.out.println(\"Token expires: \" + accessToken.getExpiresAt());\n\n\u002F\u002F Async access\ncredential.getTokenAsync()\n    .subscribe(token -> {\n        System.out.println(\"Token: \" + token.getToken().substring(0, 20) + \"...\");\n        System.out.println(\"Expires: \" + token.getExpiresAt());\n    });\n```\n\n## Dispose Credential\n\n```java\n\u002F\u002F Clean up when done\ncredential.close();\n\n\u002F\u002F Or use try-with-resources\ntry (CommunicationTokenCredential cred = new CommunicationTokenCredential(options)) {\n    \u002F\u002F Use credential\n    chatClient.doSomething();\n}\n```\n\n## Cloud Environments\n\n```java\nimport com.azure.communication.common.CommunicationCloudEnvironment;\n\n\u002F\u002F Available environments\nCommunicationCloudEnvironment publicCloud = CommunicationCloudEnvironment.PUBLIC;\nCommunicationCloudEnvironment govCloud = CommunicationCloudEnvironment.GCCH;\nCommunicationCloudEnvironment dodCloud = CommunicationCloudEnvironment.DOD;\n\n\u002F\u002F Set on Teams identifier\nMicrosoftTeamsUserIdentifier teamsUser = new MicrosoftTeamsUserIdentifier(\"\u003Cuser-id>\")\n    .setCloudEnvironment(CommunicationCloudEnvironment.GCCH);\n```\n\n## Environment Variables\n\n```bash\nAZURE_COMMUNICATION_ENDPOINT=https:\u002F\u002F\u003Cresource>.communication.azure.com\nAZURE_COMMUNICATION_USER_TOKEN=\u003Cuser-access-token>\n```\n\n## Best Practices\n\n1. **Proactive Refresh** - Always use `setRefreshProactively(true)` for long-lived clients\n2. **Token Security** - Never log or expose full tokens\n3. **Close Credentials** - Dispose of credentials when no longer needed\n4. **Error Handling** - Handle token refresh failures gracefully\n5. **Identifier Types** - Use specific identifier types, not raw strings\n\n## Common Usage Patterns\n\n```java\n\u002F\u002F Pattern: Create credential for Chat\u002FCalling client\npublic ChatClient createChatClient(String token, String endpoint) {\n    CommunicationTokenRefreshOptions refreshOptions = \n        new CommunicationTokenRefreshOptions(this::refreshToken)\n            .setRefreshProactively(true)\n            .setInitialToken(token);\n    \n    CommunicationTokenCredential credential = \n        new CommunicationTokenCredential(refreshOptions);\n    \n    return new ChatClientBuilder()\n        .endpoint(endpoint)\n        .credential(credential)\n        .buildClient();\n}\n\nprivate String refreshToken() {\n    \u002F\u002F Call your token endpoint\n    return tokenService.getNewToken();\n}\n```\n\n## Trigger Phrases\n\n- \"ACS authentication\", \"communication token credential\"\n- \"user access token\", \"token refresh\"\n- \"CommunicationUserIdentifier\", \"PhoneNumberIdentifier\"\n- \"Azure Communication Services authentication\"\n",{"name":5,"package":39,"description":7},"com.azure:azure-communication-common","main","d41309588593cee5c2fb44062474efc3a99fbcb6",".agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-java\u002Fskills\u002Fazure-communication-common-java","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms","https:\u002F\u002Fgithub.com\u002Fricardoaevt","2026-03-23 00:05:03",{"source":8,"skillName":5,"commands":47,"prompt":57,"zipAvailable":58},[48,51,54],{"tool":49,"command":50},"npx","npx skills add ricardoaevt\u002Fnexus-roms --skill azure-communication-common-java",{"tool":52,"command":53},"bunx","bunx skills add ricardoaevt\u002Fnexus-roms --skill azure-communication-common-java",{"tool":55,"command":56},"pnpm","pnpm dlx skills add ricardoaevt\u002Fnexus-roms --skill azure-communication-common-java","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-java\u002Fskills\u002Fazure-communication-common-java\u002FSKILL.md",true,[60,66],{"path":61,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":64,"sourceHtmlUrl":65},"references\u002Facceptance-criteria.md","REFERENCE","参考文档",4620,"https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-java\u002Fskills\u002Fazure-communication-common-java\u002Freferences\u002Facceptance-criteria.md",{"path":67,"resourceType":62,"resourceTypeDesc":63,"sizeBytes":68,"sourceHtmlUrl":69},"references\u002Fexamples.md",14662,"https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fmicrosoft_skills\u002F.github\u002Fplugins\u002Fazure-sdk-java\u002Fskills\u002Fazure-communication-common-java\u002Freferences\u002Fexamples.md",[71,93,109,124,135,144],{"skillNo":72,"name":73,"nameZh":6,"description":74,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":34},"01M6G9HYKQRK6HBKVTZM3258M3","openspec-propose","Propose a new change with all artifacts generated in one step. Use when the user wants to quickly describe what they want to build and get a complete proposal with design, specs, and tasks ready for implementation.","MIT","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-propose\u002FSKILL.md",[],[79,80,81,82,33,83,84,85,86,87,88,27,26,89,90,91,92],"openspec propose","openspec","cli","generated","proposal","complete","get","build","implementation","ready","artifacts","tasks","change","design",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":34},"01M6G9HV9V20WFCHYVSDNQMJVK","openspec-new-change","Start a new OpenSpec change using the experimental artifact workflow. Use when the user wants to create a new feature, fix, or modification with a structured step-by-step approach.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-new-change\u002FSKILL.md",[],[80,100,91,101,81,102,103,104,27,26,105,106,107,108,33],"openspec new change","new feature","structured","artifact","workflow","create","start","fix","feature",{"skillNo":110,"name":111,"nameZh":6,"description":112,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":34},"01M6G9HRF6R89QZXGSFC9DRQW3","openspec-explore","Enter explore mode - a thinking partner for exploring ideas, investigating problems, and clarifying requirements. Use when the user wants to think through something before or during a change.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-explore\u002FSKILL.md",[],[116,117,80,27,118,81,91,26,119,120,121,122,123],"openspec explore","explore","partner","think","thinking partner","thinking","ideas","requirements",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":34},"01M6G9HP3APFCXZG7XRWBMM524","openspec-continue-change","Continue working on an OpenSpec change by creating the next artifact. Use when the user wants to progress their change, create the next artifact, or continue their workflow.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-continue-change\u002FSKILL.md",[],[80,131,132,91,104,81,105,26,27,133,103,134],"continue","openspec continue change","next","progress",{"skillNo":136,"name":137,"nameZh":6,"description":138,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":139,"categories":140,"keywords":141,"publishedAt":34},"01M6G9HKT3WMSDBSKA7YM4MSSQ","openspec-archive-change","Archive a completed change in the experimental workflow. Use when the user wants to finalize and archive a change after implementation is complete.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-archive-change\u002FSKILL.md",[],[142,80,143,91,81,104,26,27,87,84],"openspec archive change","archive",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":75,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":150,"publishedAt":34},"01M6G9HHEG0RJK4E0YTVZZ6A8T","openspec-apply-change","Implement tasks from an OpenSpec change. Use when the user wants to start implementing, continue implementation, or work through tasks.","https:\u002F\u002Fgithub.com\u002Fricardoaevt\u002Fnexus-roms\u002Fblob\u002Fmain\u002F.agent\u002Fskills\u002Fopenspec-apply-change\u002FSKILL.md",[],[80,91,151,152,90,106,131,153,26,27,87,81],"openspec apply change","implement","work"]