wxcli 1.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (413) hide show
  1. wxcli/__init__.py +4 -0
  2. wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
  3. wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
  4. wxcli/_playbook/.claude/rules/cleanup.md +29 -0
  5. wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
  6. wxcli/_playbook/.claude/rules/org-health.md +14 -0
  7. wxcli/_playbook/.claude/settings.json +8 -0
  8. wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
  9. wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
  10. wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
  11. wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
  12. wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
  13. wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
  14. wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
  15. wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
  16. wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
  17. wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
  18. wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
  19. wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
  20. wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
  21. wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
  22. wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
  23. wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
  24. wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
  25. wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
  26. wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
  27. wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
  28. wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
  29. wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
  30. wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
  31. wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
  32. wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
  33. wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
  34. wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
  35. wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
  36. wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
  37. wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
  38. wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
  39. wxcli/_playbook/CLAUDE.md +373 -0
  40. wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
  41. wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
  42. wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
  43. wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
  44. wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
  45. wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
  46. wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
  47. wxcli/_playbook/docs/reference/admin-partner.md +357 -0
  48. wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
  49. wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
  50. wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
  51. wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
  52. wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
  53. wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
  54. wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
  55. wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
  56. wxcli/_playbook/docs/reference/authentication.md +965 -0
  57. wxcli/_playbook/docs/reference/call-control.md +1205 -0
  58. wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
  59. wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
  60. wxcli/_playbook/docs/reference/call-routing.md +2304 -0
  61. wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
  62. wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
  63. wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
  64. wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
  65. wxcli/_playbook/docs/reference/devices-core.md +1869 -0
  66. wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
  67. wxcli/_playbook/docs/reference/devices-platform.md +467 -0
  68. wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
  69. wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
  70. wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
  71. wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
  72. wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
  73. wxcli/_playbook/docs/reference/meetings-content.md +473 -0
  74. wxcli/_playbook/docs/reference/meetings-core.md +903 -0
  75. wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
  76. wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
  77. wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
  78. wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
  79. wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
  80. wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
  81. wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
  82. wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
  83. wxcli/_playbook/docs/reference/provisioning.md +1366 -0
  84. wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
  85. wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
  86. wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
  87. wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
  88. wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
  89. wxcli/_version.py +24 -0
  90. wxcli/auth.py +137 -0
  91. wxcli/commands/__init__.py +0 -0
  92. wxcli/commands/_registry.py +181 -0
  93. wxcli/commands/activation_email.py +103 -0
  94. wxcli/commands/admin_recordings.py +585 -0
  95. wxcli/commands/analytics.py +105 -0
  96. wxcli/commands/announcement_playlists.py +219 -0
  97. wxcli/commands/announcements.py +519 -0
  98. wxcli/commands/archive_users.py +36 -0
  99. wxcli/commands/attachment_actions.py +60 -0
  100. wxcli/commands/audit_events.py +83 -0
  101. wxcli/commands/authorizations.py +113 -0
  102. wxcli/commands/auto_attendant.py +642 -0
  103. wxcli/commands/broadworks_billing_reports.py +126 -0
  104. wxcli/commands/broadworks_enterprises.py +160 -0
  105. wxcli/commands/broadworks_subscribers.py +319 -0
  106. wxcli/commands/broadworks_workspaces.py +108 -0
  107. wxcli/commands/call_controls.py +1304 -0
  108. wxcli/commands/call_park.py +494 -0
  109. wxcli/commands/call_pickup.py +229 -0
  110. wxcli/commands/call_queue.py +1878 -0
  111. wxcli/commands/call_recording.py +707 -0
  112. wxcli/commands/call_routing.py +1610 -0
  113. wxcli/commands/call_settings_for_me_phase_5.py +212 -0
  114. wxcli/commands/caller_reputation.py +169 -0
  115. wxcli/commands/calling_service.py +305 -0
  116. wxcli/commands/cc_address_book.py +770 -0
  117. wxcli/commands/cc_agent_greetings.py +242 -0
  118. wxcli/commands/cc_agent_summaries.py +39 -0
  119. wxcli/commands/cc_agent_wellbeing.py +216 -0
  120. wxcli/commands/cc_agents.py +425 -0
  121. wxcli/commands/cc_ai_assistant.py +55 -0
  122. wxcli/commands/cc_ai_feature.py +294 -0
  123. wxcli/commands/cc_audio_files.py +149 -0
  124. wxcli/commands/cc_auto_csat.py +311 -0
  125. wxcli/commands/cc_aux_code.py +458 -0
  126. wxcli/commands/cc_business_hour.py +353 -0
  127. wxcli/commands/cc_call_monitoring.py +228 -0
  128. wxcli/commands/cc_callbacks.py +194 -0
  129. wxcli/commands/cc_campaign.py +212 -0
  130. wxcli/commands/cc_captures.py +39 -0
  131. wxcli/commands/cc_contact_list.py +169 -0
  132. wxcli/commands/cc_contact_number.py +295 -0
  133. wxcli/commands/cc_data_sources.py +235 -0
  134. wxcli/commands/cc_desktop_layout.py +380 -0
  135. wxcli/commands/cc_desktop_profile.py +322 -0
  136. wxcli/commands/cc_dial_number.py +511 -0
  137. wxcli/commands/cc_dial_plan.py +347 -0
  138. wxcli/commands/cc_dnc.py +101 -0
  139. wxcli/commands/cc_entry_point.py +545 -0
  140. wxcli/commands/cc_ewt.py +51 -0
  141. wxcli/commands/cc_flow.py +477 -0
  142. wxcli/commands/cc_global_vars.py +430 -0
  143. wxcli/commands/cc_holiday_list.py +335 -0
  144. wxcli/commands/cc_journey.py +1261 -0
  145. wxcli/commands/cc_legacy_flows.py +49 -0
  146. wxcli/commands/cc_multimedia_profile.py +436 -0
  147. wxcli/commands/cc_notification.py +51 -0
  148. wxcli/commands/cc_outdial_ani.py +604 -0
  149. wxcli/commands/cc_overrides.py +341 -0
  150. wxcli/commands/cc_queue.py +1083 -0
  151. wxcli/commands/cc_queue_stats.py +55 -0
  152. wxcli/commands/cc_realtime.py +51 -0
  153. wxcli/commands/cc_resource_collection.py +312 -0
  154. wxcli/commands/cc_search.py +46 -0
  155. wxcli/commands/cc_site.py +400 -0
  156. wxcli/commands/cc_skill.py +350 -0
  157. wxcli/commands/cc_skill_profile.py +289 -0
  158. wxcli/commands/cc_subscriptions.py +426 -0
  159. wxcli/commands/cc_summaries.py +130 -0
  160. wxcli/commands/cc_tasks.py +844 -0
  161. wxcli/commands/cc_team.py +325 -0
  162. wxcli/commands/cc_user_profiles.py +349 -0
  163. wxcli/commands/cc_users.py +701 -0
  164. wxcli/commands/cc_work_types.py +363 -0
  165. wxcli/commands/cdr.py +89 -0
  166. wxcli/commands/classifications.py +38 -0
  167. wxcli/commands/cleanup.py +1427 -0
  168. wxcli/commands/client_settings.py +72 -0
  169. wxcli/commands/conference.py +328 -0
  170. wxcli/commands/configure.py +72 -0
  171. wxcli/commands/converged_recordings.py +347 -0
  172. wxcli/commands/converged_recordings_export.py +310 -0
  173. wxcli/commands/cq_playlists.py +42 -0
  174. wxcli/commands/cucm.py +2794 -0
  175. wxcli/commands/cucm_config.py +129 -0
  176. wxcli/commands/customer_assist.py +373 -0
  177. wxcli/commands/data_sources.py +227 -0
  178. wxcli/commands/dect_devices.py +787 -0
  179. wxcli/commands/device_configurations.py +77 -0
  180. wxcli/commands/device_dynamic_settings.py +320 -0
  181. wxcli/commands/device_settings.py +1489 -0
  182. wxcli/commands/devices.py +280 -0
  183. wxcli/commands/domains.py +142 -0
  184. wxcli/commands/ecm.py +178 -0
  185. wxcli/commands/emergency_services.py +827 -0
  186. wxcli/commands/events.py +83 -0
  187. wxcli/commands/external_voicemail.py +52 -0
  188. wxcli/commands/groups.py +206 -0
  189. wxcli/commands/guest_management.py +76 -0
  190. wxcli/commands/hds.py +340 -0
  191. wxcli/commands/hot_desk.py +67 -0
  192. wxcli/commands/hot_desking_members.py +118 -0
  193. wxcli/commands/hot_desking_portal.py +124 -0
  194. wxcli/commands/hunt_group.py +577 -0
  195. wxcli/commands/hybrid_clusters.py +71 -0
  196. wxcli/commands/hybrid_connectors.py +67 -0
  197. wxcli/commands/identity_org.py +159 -0
  198. wxcli/commands/init_playbook.py +155 -0
  199. wxcli/commands/licenses.py +106 -0
  200. wxcli/commands/live_monitoring.py +40 -0
  201. wxcli/commands/location_call_handling.py +577 -0
  202. wxcli/commands/location_schedules.py +341 -0
  203. wxcli/commands/location_settings.py +1297 -0
  204. wxcli/commands/location_voicemail.py +494 -0
  205. wxcli/commands/locations.py +336 -0
  206. wxcli/commands/meeting_captions.py +110 -0
  207. wxcli/commands/meeting_chats.py +63 -0
  208. wxcli/commands/meeting_invitees.py +234 -0
  209. wxcli/commands/meeting_messages.py +28 -0
  210. wxcli/commands/meeting_participants.py +278 -0
  211. wxcli/commands/meeting_polls.py +111 -0
  212. wxcli/commands/meeting_preferences.py +515 -0
  213. wxcli/commands/meeting_qa.py +78 -0
  214. wxcli/commands/meeting_qualities.py +43 -0
  215. wxcli/commands/meeting_reports.py +101 -0
  216. wxcli/commands/meeting_session_types.py +105 -0
  217. wxcli/commands/meeting_site.py +57 -0
  218. wxcli/commands/meeting_slido.py +44 -0
  219. wxcli/commands/meeting_summaries.py +92 -0
  220. wxcli/commands/meeting_tracking_codes.py +233 -0
  221. wxcli/commands/meeting_transcripts.py +230 -0
  222. wxcli/commands/meetings.py +1997 -0
  223. wxcli/commands/memberships.py +164 -0
  224. wxcli/commands/messages.py +213 -0
  225. wxcli/commands/mode_management.py +244 -0
  226. wxcli/commands/my_call_settings.py +3577 -0
  227. wxcli/commands/numbers.py +405 -0
  228. wxcli/commands/operating_modes.py +410 -0
  229. wxcli/commands/org_contacts.py +284 -0
  230. wxcli/commands/org_health_cli.py +55 -0
  231. wxcli/commands/org_settings.py +71 -0
  232. wxcli/commands/organizations.py +83 -0
  233. wxcli/commands/paging_group.py +257 -0
  234. wxcli/commands/partner_admins.py +141 -0
  235. wxcli/commands/partner_reports.py +188 -0
  236. wxcli/commands/partner_tags.py +216 -0
  237. wxcli/commands/people.py +279 -0
  238. wxcli/commands/person_call_settings.py +71 -0
  239. wxcli/commands/pstn.py +280 -0
  240. wxcli/commands/recording_report.py +154 -0
  241. wxcli/commands/report_templates.py +38 -0
  242. wxcli/commands/reports.py +144 -0
  243. wxcli/commands/resource_group_memberships.py +160 -0
  244. wxcli/commands/resource_groups.py +67 -0
  245. wxcli/commands/roles.py +63 -0
  246. wxcli/commands/room_tabs.py +160 -0
  247. wxcli/commands/rooms.py +225 -0
  248. wxcli/commands/scim_bulk.py +46 -0
  249. wxcli/commands/scim_groups.py +246 -0
  250. wxcli/commands/scim_schemas.py +82 -0
  251. wxcli/commands/scim_users.py +283 -0
  252. wxcli/commands/security_audit.py +54 -0
  253. wxcli/commands/service_apps.py +51 -0
  254. wxcli/commands/single_number_reach.py +209 -0
  255. wxcli/commands/team_memberships.py +155 -0
  256. wxcli/commands/teams.py +153 -0
  257. wxcli/commands/ucm_profile.py +42 -0
  258. wxcli/commands/update.py +219 -0
  259. wxcli/commands/user_settings.py +5116 -0
  260. wxcli/commands/video_mesh.py +1090 -0
  261. wxcli/commands/virtual_extensions.py +502 -0
  262. wxcli/commands/virtual_line_settings.py +2072 -0
  263. wxcli/commands/webhooks.py +176 -0
  264. wxcli/commands/wholesale_billing_reports.py +147 -0
  265. wxcli/commands/wholesale_provisioning.py +523 -0
  266. wxcli/commands/workspace_locations.py +339 -0
  267. wxcli/commands/workspace_metrics.py +103 -0
  268. wxcli/commands/workspace_personalization.py +70 -0
  269. wxcli/commands/workspace_settings.py +3347 -0
  270. wxcli/commands/workspaces.py +279 -0
  271. wxcli/commands/xapi.py +114 -0
  272. wxcli/config.py +139 -0
  273. wxcli/errors.py +77 -0
  274. wxcli/main.py +210 -0
  275. wxcli/migration/CLAUDE.md +106 -0
  276. wxcli/migration/__init__.py +1 -0
  277. wxcli/migration/advisory/CLAUDE.md +196 -0
  278. wxcli/migration/advisory/__init__.py +46 -0
  279. wxcli/migration/advisory/advisor.py +107 -0
  280. wxcli/migration/advisory/advisory_patterns.py +2552 -0
  281. wxcli/migration/advisory/recommendation_rules.py +835 -0
  282. wxcli/migration/cucm/CLAUDE.md +74 -0
  283. wxcli/migration/cucm/__init__.py +5 -0
  284. wxcli/migration/cucm/connection.py +265 -0
  285. wxcli/migration/cucm/discovery.py +225 -0
  286. wxcli/migration/cucm/extractors/__init__.py +1 -0
  287. wxcli/migration/cucm/extractors/announcements.py +92 -0
  288. wxcli/migration/cucm/extractors/base.py +90 -0
  289. wxcli/migration/cucm/extractors/device_profiles.py +98 -0
  290. wxcli/migration/cucm/extractors/devices.py +193 -0
  291. wxcli/migration/cucm/extractors/e911.py +103 -0
  292. wxcli/migration/cucm/extractors/features.py +309 -0
  293. wxcli/migration/cucm/extractors/helpers.py +73 -0
  294. wxcli/migration/cucm/extractors/informational.py +295 -0
  295. wxcli/migration/cucm/extractors/locations.py +221 -0
  296. wxcli/migration/cucm/extractors/moh.py +100 -0
  297. wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
  298. wxcli/migration/cucm/extractors/routing.py +493 -0
  299. wxcli/migration/cucm/extractors/shared_lines.py +146 -0
  300. wxcli/migration/cucm/extractors/templates.py +229 -0
  301. wxcli/migration/cucm/extractors/tier4.py +173 -0
  302. wxcli/migration/cucm/extractors/users.py +240 -0
  303. wxcli/migration/cucm/extractors/voicemail.py +243 -0
  304. wxcli/migration/cucm/extractors/workspaces.py +88 -0
  305. wxcli/migration/cucm/unity_connection.py +304 -0
  306. wxcli/migration/execute/CLAUDE.md +372 -0
  307. wxcli/migration/execute/__init__.py +303 -0
  308. wxcli/migration/execute/batch.py +277 -0
  309. wxcli/migration/execute/dependency.py +483 -0
  310. wxcli/migration/execute/engine.py +964 -0
  311. wxcli/migration/execute/handlers.py +2232 -0
  312. wxcli/migration/execute/planner.py +1939 -0
  313. wxcli/migration/execute/runtime.py +571 -0
  314. wxcli/migration/export/CLAUDE.md +49 -0
  315. wxcli/migration/export/__init__.py +8 -0
  316. wxcli/migration/export/csv_export.py +126 -0
  317. wxcli/migration/export/deployment_plan.py +479 -0
  318. wxcli/migration/export/json_export.py +60 -0
  319. wxcli/migration/models.py +941 -0
  320. wxcli/migration/phone_models.py +50 -0
  321. wxcli/migration/preflight/CLAUDE.md +52 -0
  322. wxcli/migration/preflight/__init__.py +89 -0
  323. wxcli/migration/preflight/checks.py +911 -0
  324. wxcli/migration/preflight/runner.py +293 -0
  325. wxcli/migration/rate_limiter.py +144 -0
  326. wxcli/migration/report/CLAUDE.md +245 -0
  327. wxcli/migration/report/__init__.py +7 -0
  328. wxcli/migration/report/appendix.py +2437 -0
  329. wxcli/migration/report/assembler.py +183 -0
  330. wxcli/migration/report/charts.py +263 -0
  331. wxcli/migration/report/executive.py +776 -0
  332. wxcli/migration/report/explainer.py +704 -0
  333. wxcli/migration/report/helpers.py +74 -0
  334. wxcli/migration/report/ingest.py +152 -0
  335. wxcli/migration/report/notice_templates.py +192 -0
  336. wxcli/migration/report/score.py +375 -0
  337. wxcli/migration/report/styles.py +1052 -0
  338. wxcli/migration/report/user_diff.py +1052 -0
  339. wxcli/migration/report/user_notice.py +425 -0
  340. wxcli/migration/state.py +139 -0
  341. wxcli/migration/store.py +860 -0
  342. wxcli/migration/transform/CLAUDE.md +107 -0
  343. wxcli/migration/transform/__init__.py +12 -0
  344. wxcli/migration/transform/analysis_pipeline.py +453 -0
  345. wxcli/migration/transform/analyzers/__init__.py +142 -0
  346. wxcli/migration/transform/analyzers/css_permission.py +189 -0
  347. wxcli/migration/transform/analyzers/css_routing.py +335 -0
  348. wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
  349. wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
  350. wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
  351. wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
  352. wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
  353. wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
  354. wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
  355. wxcli/migration/transform/analyzers/missing_data.py +300 -0
  356. wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
  357. wxcli/migration/transform/analyzers/shared_line.py +170 -0
  358. wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
  359. wxcli/migration/transform/analyzers/workspace_license.py +212 -0
  360. wxcli/migration/transform/cross_reference.py +1136 -0
  361. wxcli/migration/transform/cucm_pattern.py +246 -0
  362. wxcli/migration/transform/decisions.py +301 -0
  363. wxcli/migration/transform/e164.py +145 -0
  364. wxcli/migration/transform/engine.py +256 -0
  365. wxcli/migration/transform/mappers/CLAUDE.md +123 -0
  366. wxcli/migration/transform/mappers/__init__.py +76 -0
  367. wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
  368. wxcli/migration/transform/mappers/base.py +190 -0
  369. wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
  370. wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
  371. wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
  372. wxcli/migration/transform/mappers/css_mapper.py +868 -0
  373. wxcli/migration/transform/mappers/dect_mapper.py +367 -0
  374. wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
  375. wxcli/migration/transform/mappers/device_mapper.py +227 -0
  376. wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
  377. wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
  378. wxcli/migration/transform/mappers/e911_mapper.py +129 -0
  379. wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
  380. wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
  381. wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
  382. wxcli/migration/transform/mappers/line_mapper.py +310 -0
  383. wxcli/migration/transform/mappers/location_mapper.py +235 -0
  384. wxcli/migration/transform/mappers/moh_mapper.py +114 -0
  385. wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
  386. wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
  387. wxcli/migration/transform/mappers/routing_mapper.py +821 -0
  388. wxcli/migration/transform/mappers/snr_mapper.py +201 -0
  389. wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
  390. wxcli/migration/transform/mappers/user_mapper.py +264 -0
  391. wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
  392. wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
  393. wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
  394. wxcli/migration/transform/normalizers.py +2008 -0
  395. wxcli/migration/transform/pattern_converter.py +106 -0
  396. wxcli/migration/transform/pipeline.py +271 -0
  397. wxcli/migration/transform/rules.py +255 -0
  398. wxcli/org_health/CLAUDE.md +63 -0
  399. wxcli/org_health/__init__.py +7 -0
  400. wxcli/org_health/analyze.py +93 -0
  401. wxcli/org_health/checks.py +458 -0
  402. wxcli/org_health/collector.py +62 -0
  403. wxcli/org_health/models.py +78 -0
  404. wxcli/org_health/report.py +300 -0
  405. wxcli/output.py +101 -0
  406. wxcli-1.2.0.dist-info/METADATA +505 -0
  407. wxcli-1.2.0.dist-info/RECORD +413 -0
  408. wxcli-1.2.0.dist-info/WHEEL +5 -0
  409. wxcli-1.2.0.dist-info/entry_points.txt +2 -0
  410. wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
  411. wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
  412. wxcli-1.2.0.dist-info/scm_version.json +8 -0
  413. wxcli-1.2.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,638 @@
1
+ ---
2
+ name: manage-identity
3
+ description: |
4
+ Manage Webex identity and directory: SCIM user/group sync, SCIM bulk operations,
5
+ domain verification (DNS TXT records), org contact import, directory entries,
6
+ group membership, and directory cleanup.
7
+ Guides from prerequisites through execution and verification.
8
+ NOT for: Webex Calling user provisioning (use provision-calling skill) or
9
+ license assignment (use manage-licensing skill).
10
+ allowed-tools: Read, Grep, Glob, Bash
11
+ argument-hint: [operation — e.g. "sync users", "verify domain", "bulk import", "cleanup directory"]
12
+ ---
13
+
14
+ <!-- Updated by playbook session 2026-03-19 -->
15
+
16
+ # Manage Identity Workflow
17
+
18
+ **Checkpoint — do NOT proceed until you can answer these:**
19
+ 1. What is the critical difference between SCIM PUT and PATCH for user updates? (Answer: PUT replaces the entire user resource — any field omitted is deleted. PATCH modifies only specified fields. Always use PATCH for partial updates.)
20
+ 2. What must be completed before SCIM sync can work for a domain? (Answer: Domain verification — the domain must be verified and claimed in Control Hub before SCIM can provision users with that email domain.)
21
+
22
+ If you cannot answer both, you skipped reading this skill. Go back and read it.
23
+
24
+ ## Step 1: Load references
25
+
26
+ 1. Read `docs/reference/admin-identity-scim.md` for SCIM users, groups, bulk, schemas, identity org, and People/Groups API patterns
27
+ 2. Read `docs/reference/admin-org-management.md` for domains, org contacts, roles, and org settings
28
+
29
+ **Mandatory --help verification:** Before constructing any wxcli command, run `wxcli <group> --help` to verify the subcommand exists, then `wxcli <group> <subcommand> --help` to verify the exact flags. Do NOT rely on examples in this skill or reference docs — the CLI is auto-generated and flag names may differ from what documentation suggests.
30
+
31
+ ## Step 2: Verify auth token is working
32
+
33
+ Before any identity operation, confirm the token is valid and has appropriate scopes.
34
+
35
+ ```bash
36
+ wxcli whoami
37
+ ```
38
+
39
+ If this fails with 401/403, stop and troubleshoot auth before proceeding. Common causes:
40
+ - Token expired (personal access tokens last 12 hours)
41
+ - Token not configured -- run `wxcli configure` or check `~/.wxcli/config.json`
42
+ - Token lacks identity scopes -- SCIM endpoints require `identity:people_rw` or `identity:people_read`, NOT the `spark-admin:people_*` scopes used by Calling APIs
43
+
44
+ Check the org ID (needed for all SCIM and domain commands):
45
+
46
+ ```bash
47
+ wxcli organizations list
48
+ ```
49
+
50
+ ## Step 3: Determine the operation
51
+
52
+ Ask the user which identity operation they need. The eight supported operations are:
53
+
54
+ | Need | Operation | CLI Group | Prerequisites |
55
+ |------|-----------|-----------|---------------|
56
+ | Sync users from IdP (Azure AD, Okta) | SCIM bulk import | `scim-bulk`, `scim-users` | Domain verified and claimed; `identity:people_rw` scope |
57
+ | Search/find users in directory | SCIM user search | `scim-users` | `identity:people_read` scope; org ID |
58
+ | Create/update/delete individual users | SCIM user CRUD | `scim-users` | `identity:people_rw` scope; org ID |
59
+ | Manage groups and membership | Group CRUD | `scim-groups` or `groups` | `identity:people_rw` (SCIM) or admin token (Webex Groups) |
60
+ | Import org contacts (directory listing) | Bulk contact import | `org-contacts` | `identity:contacts_rw` scope; org ID |
61
+ | Verify/claim a domain before sync | Domain verification | `domains` | `identity:organizations_rw` scope; DNS access |
62
+ | Clean up stale/inactive users | Directory cleanup | `scim-users`, `scim-bulk` | `identity:people_rw` scope; org ID |
63
+ | Check SCIM schema for field mapping | Schema introspection | `scim-schemas` | `identity:people_read` scope |
64
+
65
+ Confirm with the user before proceeding:
66
+ - **Which operation** from the table above
67
+ - **Target details** (user emails, group names, domain name, contact list, etc.)
68
+ - **For bulk**: CSV or list of users/contacts to provision
69
+
70
+ ## Step 4: Check prerequisites
71
+
72
+ Run these checks based on the operation. **Stop and report** if any prerequisite fails.
73
+
74
+ ### For all SCIM operations (scim-users, scim-groups, scim-bulk):
75
+ ```bash
76
+ # Get the org ID (required as positional argument for all SCIM commands)
77
+ wxcli organizations list
78
+ # Note the org ID from the output -- you will pass it as the first argument
79
+ ```
80
+
81
+ ### For domain verification:
82
+ ```bash
83
+ # Check current domain status (if available)
84
+ wxcli domains get-domain-verification $ORG_ID --domain "example.com"
85
+ # This returns the DNS TXT token. The user must add this to their DNS before verify-domain will succeed.
86
+ ```
87
+
88
+ **DNS is outside the CLI's control.** If the user has not added the TXT record, provide the token value and instruct them to:
89
+ 1. Add a TXT record at their domain root with the returned token value
90
+ 2. Wait for DNS propagation (typically 15-60 minutes, up to 48 hours)
91
+ 3. Return when ready to proceed with verification
92
+
93
+ ### For SCIM sync (bulk import):
94
+ ```bash
95
+ # Verify domain is claimed before syncing users at that domain
96
+ # The domain must be verified AND claimed, or SCIM user creation for that domain will fail
97
+ wxcli domains verify-domain $ORG_ID --domain "example.com"
98
+ ```
99
+
100
+ ### For user search/lookup:
101
+ ```bash
102
+ # SCIM search -- use filter syntax
103
+ wxcli scim-users list $ORG_ID --filter 'userName eq "target@example.com"'
104
+
105
+ # Or use People API (no org ID needed)
106
+ wxcli people list --email "target@example.com"
107
+ ```
108
+
109
+ ### For org contacts:
110
+ ```bash
111
+ # Check existing contacts before importing
112
+ wxcli org-contacts list $ORG_ID
113
+ ```
114
+
115
+ ## Step 5: Build plan -- [SHOW BEFORE EXECUTING]
116
+
117
+ **Present the plan to the user and wait for approval.** Never execute write operations without confirmation.
118
+
119
+ Format the plan as:
120
+
121
+ ```
122
+ === Identity Management Plan ===
123
+
124
+ Operation: [SCIM Bulk Import / Domain Verification / Directory Cleanup / etc.]
125
+
126
+ Target:
127
+ - [specific details -- domain, user list, group name, etc.]
128
+
129
+ Steps:
130
+ 1. [First CLI command -- what it does]
131
+ 2. [Second CLI command -- what it does]
132
+ 3. Verify: [what we'll check after]
133
+
134
+ Prerequisites verified:
135
+ - Auth token valid (authenticated as [name])
136
+ - Org ID: [org_id]
137
+ - Domain verified: [domain] (if applicable)
138
+ - Scope confirmed: [identity:people_rw / identity:contacts_rw / etc.]
139
+
140
+ Proceed? [wait for user confirmation]
141
+ ```
142
+
143
+ ## Step 6: Execute the identity operation
144
+
145
+ ### Operation A: Domain Verification
146
+
147
+ Complete end-to-end flow for adding a domain to the Webex org.
148
+
149
+ ```bash
150
+ # Step 1: Get the verification token
151
+ wxcli domains get-domain-verification $ORG_ID --domain "newdomain.com"
152
+ # Response includes a token like: "webex-verification=abc123def456"
153
+
154
+ # Step 2: DNS TXT record must be added by the user (outside CLI)
155
+ # Record type: TXT, Name: @ (or newdomain.com), Value: the returned token
156
+
157
+ # Step 3: Verify the domain
158
+ wxcli domains verify-domain $ORG_ID --domain "newdomain.com"
159
+
160
+ # Step 4: Claim the domain for user provisioning
161
+ wxcli domains claim-domain $ORG_ID
162
+
163
+ # Or combine verify + claim in one step:
164
+ wxcli domains verify-domain $ORG_ID --domain "newdomain.com" --claim-domain true
165
+ ```
166
+
167
+ ### Operation B: SCIM User Search
168
+
169
+ ```bash
170
+ # Search by exact email
171
+ wxcli scim-users list $ORG_ID --filter 'userName eq "jsmith@example.com"'
172
+
173
+ # Search by display name (contains)
174
+ wxcli scim-users list $ORG_ID --filter 'displayName co "Smith"'
175
+
176
+ # Search by email domain
177
+ wxcli scim-users list $ORG_ID --filter 'userName co "@acme.com"'
178
+
179
+ # Get specific attributes only
180
+ wxcli scim-users list $ORG_ID --filter 'userName sw "j"' --attributes "userName,displayName,emails"
181
+
182
+ # Get a specific user by ID
183
+ wxcli scim-users show $ORG_ID $USER_ID -o json
184
+ ```
185
+
186
+ ### Operation C: SCIM User Create/Update/Delete
187
+
188
+ **Create:**
189
+
190
+ ```bash
191
+ # Create a single user
192
+ wxcli scim-users create $ORG_ID --user-name "newuser@example.com" --display-name "New User" --active
193
+
194
+ # Create with full JSON body (for nested fields: name, emails, addresses)
195
+ wxcli scim-users create $ORG_ID --json-body '{
196
+ "userName": "jdoe@example.com",
197
+ "displayName": "Jane Doe",
198
+ "name": {"givenName": "Jane", "familyName": "Doe"},
199
+ "emails": [{"value": "jdoe@example.com", "type": "work", "primary": true}],
200
+ "active": true
201
+ }'
202
+ ```
203
+
204
+ **Update (PATCH — always use this for modifications):**
205
+
206
+ ```bash
207
+ # Change display name (only this field changes, everything else preserved)
208
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
209
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
210
+ "Operations": [
211
+ {"op": "replace", "path": "displayName", "value": "Jane M. Doe"}
212
+ ]
213
+ }'
214
+
215
+ # Change multiple fields at once
216
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
217
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
218
+ "Operations": [
219
+ {"op": "replace", "path": "displayName", "value": "Jane M. Doe"},
220
+ {"op": "replace", "path": "title", "value": "Senior Engineer"}
221
+ ]
222
+ }'
223
+
224
+ # Deactivate a user
225
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
226
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
227
+ "Operations": [{"op": "replace", "path": "active", "value": false}]
228
+ }'
229
+
230
+ # Add a value to a multi-valued attribute
231
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
232
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
233
+ "Operations": [
234
+ {"op": "add", "path": "phoneNumbers", "value": [{"value": "+15551234567", "type": "work"}]}
235
+ ]
236
+ }'
237
+ ```
238
+
239
+ PATCH operations: `add` (append value), `replace` (change value), `remove` (delete value). The `schemas` field with `PatchOp` URN is required in every PATCH body.
240
+
241
+ **Full replace (PUT — DANGEROUS, rarely needed):**
242
+
243
+ > **WARNING: `scim-users update` uses HTTP PUT, which REPLACES the entire user resource. Any attribute not included in the body is DELETED.** This means emails, phone numbers, addresses, group memberships, and active status are all removed if not explicitly included. Use PATCH (`update-users`) instead unless you have a specific reason to replace the full resource.
244
+
245
+ ```bash
246
+ # ONLY use PUT when you need to replace the entire resource
247
+ # Step 1: GET the current full resource
248
+ wxcli scim-users show $ORG_ID $USER_ID -o json > user.json
249
+
250
+ # Step 2: Edit user.json (make your changes to the full object)
251
+
252
+ # Step 3: PUT the modified full resource back
253
+ wxcli scim-users update $ORG_ID $USER_ID --json-body "$(cat user.json)"
254
+ ```
255
+
256
+ **When to use PUT vs PATCH:**
257
+ - **PATCH (99% of cases):** Changing display name, title, active status, adding/removing phone numbers, updating addresses — any targeted field change
258
+ - **PUT (rare):** Replacing a user's entire profile from an external IdP sync, or resetting a corrupted user record to a known-good state
259
+
260
+ **Delete:**
261
+
262
+ ```bash
263
+ wxcli scim-users delete $ORG_ID $USER_ID --force
264
+ ```
265
+
266
+ The same PUT/PATCH distinction applies to groups: use `scim-groups update-groups` (PATCH) instead of `scim-groups update` (PUT).
267
+
268
+ ### Operation D: SCIM Bulk Import
269
+
270
+ ```bash
271
+ # Bulk create multiple users in a single API call
272
+ wxcli scim-bulk create $ORG_ID --fail-on-errors 5 --json-body '{
273
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
274
+ "failOnErrors": 5,
275
+ "Operations": [
276
+ {
277
+ "method": "POST",
278
+ "path": "/Users",
279
+ "data": {
280
+ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
281
+ "userName": "alice@example.com",
282
+ "displayName": "Alice Smith",
283
+ "name": {"givenName": "Alice", "familyName": "Smith"},
284
+ "emails": [{"value": "alice@example.com", "type": "work", "primary": true}],
285
+ "active": true
286
+ }
287
+ },
288
+ {
289
+ "method": "POST",
290
+ "path": "/Users",
291
+ "data": {
292
+ "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
293
+ "userName": "bob@example.com",
294
+ "displayName": "Bob Jones",
295
+ "name": {"givenName": "Bob", "familyName": "Jones"},
296
+ "emails": [{"value": "bob@example.com", "type": "work", "primary": true}],
297
+ "active": true
298
+ }
299
+ }
300
+ ]
301
+ }'
302
+ ```
303
+
304
+ Check the response for per-operation status. Each operation returns its own status code (e.g., `201` for created, `409` for conflict/duplicate).
305
+
306
+ **Bulk operation safety:**
307
+ - Bulk requests can mix operations (POST create, PUT replace, PATCH update, DELETE remove)
308
+ - **Never use PUT operations in bulk unless you have the full resource for every user**
309
+ - Prefer PATCH operations in bulk for updates — same safety as individual PATCH
310
+ - The `--fail-on-errors` parameter controls how many individual failures abort the entire batch
311
+ - **Always check per-operation status in the response** — a 200 response on the bulk endpoint does NOT mean all operations succeeded. Each operation has its own `status` field (201 = created, 200 = updated, 409 = duplicate, 400 = validation error)
312
+
313
+ ### Operation E: Group Management
314
+
315
+ **SCIM Groups (for IdP sync):**
316
+
317
+ ```bash
318
+ # List all SCIM groups
319
+ wxcli scim-groups list $ORG_ID
320
+
321
+ # Create a SCIM group with members
322
+ wxcli scim-groups create $ORG_ID --json-body '{
323
+ "displayName": "DevOps Team",
324
+ "members": [
325
+ {"value": "USER_ID_1", "type": "user"},
326
+ {"value": "USER_ID_2", "type": "user"}
327
+ ]
328
+ }'
329
+
330
+ # Add a member via PATCH
331
+ wxcli scim-groups update-groups $ORG_ID $GROUP_ID --json-body '{
332
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
333
+ "Operations": [
334
+ {"op": "add", "path": "members", "value": [{"value": "USER_ID", "type": "user"}]}
335
+ ]
336
+ }'
337
+
338
+ # Remove a member via PATCH
339
+ wxcli scim-groups update-groups $ORG_ID $GROUP_ID --json-body '{
340
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
341
+ "Operations": [
342
+ {"op": "remove", "path": "members[value eq \"USER_ID\"]"}
343
+ ]
344
+ }'
345
+ ```
346
+
347
+ **Webex Groups (native, no org ID needed):**
348
+
349
+ ```bash
350
+ # List all groups
351
+ wxcli groups list
352
+
353
+ # Create a group with members
354
+ wxcli groups create --json-body '{
355
+ "displayName": "Support Team",
356
+ "members": [
357
+ {"id": "PERSON_ID_1", "type": "user"},
358
+ {"id": "PERSON_ID_2", "type": "user"}
359
+ ]
360
+ }'
361
+
362
+ # Add/remove members
363
+ wxcli groups update $GROUP_ID --json-body '{
364
+ "members": [
365
+ {"id": "PERSON_ID", "type": "user", "operation": "add"}
366
+ ]
367
+ }'
368
+
369
+ # List group members (paginated)
370
+ wxcli groups list-members $GROUP_ID --count 100
371
+ ```
372
+
373
+ ### Operation F: Org Contacts Import
374
+
375
+ ```bash
376
+ # Create a single contact
377
+ wxcli org-contacts create $ORG_ID \
378
+ --schemas "urn:cisco:codev:identity:contact:core:1.0" \
379
+ --source CH \
380
+ --display-name "Jane Smith" \
381
+ --first-name "Jane" \
382
+ --last-name "Smith" \
383
+ --company-name "Acme Corp" \
384
+ --primary-contact-method EMAIL
385
+
386
+ # Bulk create/update contacts
387
+ wxcli org-contacts create-bulk $ORG_ID \
388
+ --schemas "urn:cisco:codev:identity:contact:core:1.0" \
389
+ --json-body '{
390
+ "schemas": "urn:cisco:codev:identity:contact:core:1.0",
391
+ "contacts": [
392
+ {
393
+ "displayName": "Alice Johnson",
394
+ "firstName": "Alice",
395
+ "lastName": "Johnson",
396
+ "source": "CH",
397
+ "primaryContactMethod": "EMAIL",
398
+ "emails": [{"value": "alice@example.com", "type": "work"}]
399
+ },
400
+ {
401
+ "displayName": "Bob Williams",
402
+ "firstName": "Bob",
403
+ "lastName": "Williams",
404
+ "source": "CH",
405
+ "primaryContactMethod": "PHONE",
406
+ "phoneNumbers": [{"value": "+14155551234", "type": "work"}]
407
+ }
408
+ ]
409
+ }'
410
+
411
+ # Bulk delete contacts
412
+ wxcli org-contacts create-delete $ORG_ID \
413
+ --schemas "urn:cisco:codev:identity:contact:core:1.0" \
414
+ --json-body '{
415
+ "schemas": "urn:cisco:codev:identity:contact:core:1.0",
416
+ "contactIds": ["contact-id-1", "contact-id-2"]
417
+ }'
418
+ ```
419
+
420
+ ### Operation G: Directory Cleanup (Deactivate Stale Users)
421
+
422
+ ```bash
423
+ # Step 1: List active users
424
+ wxcli scim-users list $ORG_ID --filter 'active eq true' -o json
425
+
426
+ # Step 2: Deactivate individual users via PATCH
427
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
428
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
429
+ "Operations": [{"op": "replace", "path": "active", "value": false}]
430
+ }'
431
+
432
+ # Or bulk deactivate many users at once
433
+ wxcli scim-bulk create $ORG_ID --fail-on-errors 10 --json-body '{
434
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:BulkRequest"],
435
+ "failOnErrors": 10,
436
+ "Operations": [
437
+ {"method": "PATCH", "path": "/Users/USER_ID_1", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}},
438
+ {"method": "PATCH", "path": "/Users/USER_ID_2", "data": {"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"], "Operations": [{"op": "replace", "path": "active", "value": false}]}}
439
+ ]
440
+ }'
441
+
442
+ # Step 3: For permanent removal, delete after deactivation
443
+ wxcli scim-users delete $ORG_ID $USER_ID --force
444
+ ```
445
+
446
+ ### Operation H: Schema Introspection
447
+
448
+ ```bash
449
+ # Get the SCIM User schema (discover all available user attributes)
450
+ wxcli scim-schemas show-user -o json
451
+
452
+ # Get the SCIM Group schema
453
+ wxcli scim-schemas show -o json
454
+
455
+ # Get a specific schema by URN (e.g., the Cisco extension schema)
456
+ wxcli scim-schemas show-scim2 "urn:scim:schemas:extension:cisco:webexidentity:2.0:User" -o json
457
+ ```
458
+
459
+ ## Step 7: Verify results
460
+
461
+ Always read back the created/updated resources to confirm.
462
+
463
+ ### Verify SCIM users:
464
+ ```bash
465
+ # Verify a specific user was created/updated
466
+ wxcli scim-users show $ORG_ID $USER_ID -o json
467
+ # Confirm: userName, displayName, active status, group memberships
468
+
469
+ # Verify bulk import -- search for imported users
470
+ wxcli scim-users list $ORG_ID --filter 'userName co "@example.com"'
471
+ # Count results to confirm expected number of users imported
472
+ ```
473
+
474
+ ### Verify groups:
475
+ ```bash
476
+ # SCIM group
477
+ wxcli scim-groups list $ORG_ID --filter 'displayName eq "DevOps Team"' --include-members true
478
+
479
+ # Webex group
480
+ wxcli groups show $GROUP_ID --include-members true -o json
481
+ ```
482
+
483
+ ### Verify domain:
484
+ ```bash
485
+ # Re-run verify to confirm domain status
486
+ wxcli domains verify-domain $ORG_ID --domain "example.com"
487
+ ```
488
+
489
+ ### Verify org contacts:
490
+ ```bash
491
+ # Search for imported contacts
492
+ wxcli org-contacts list $ORG_ID --keyword "Smith"
493
+ ```
494
+
495
+ ## Step 8: Report results
496
+
497
+ Summarize what was done:
498
+
499
+ ```
500
+ === Identity Management Complete ===
501
+
502
+ Operation: [what was done]
503
+ Results:
504
+ - [resource]: [status] ([id])
505
+ - [resource]: [status] ([id])
506
+
507
+ Verification:
508
+ - [what was confirmed]
509
+
510
+ Next steps:
511
+ - [any follow-up actions needed]
512
+ ```
513
+
514
+ ---
515
+
516
+ ## Critical Rules
517
+
518
+ 1. **ALWAYS test auth first** -- Run `wxcli whoami` before any identity call. Do not proceed on auth failure.
519
+
520
+ 2. **ALWAYS show plan before executing** -- Present the plan and wait for user confirmation. Never modify users, groups, or contacts without approval.
521
+
522
+ 3. **NEVER use `scim-users update` (PUT) for partial changes** — PUT replaces the entire resource, deleting any attributes not included. Always use `scim-users update-users` (PATCH) for targeted changes. See Operation C for the full pattern and examples. Same applies to `scim-groups update` vs `scim-groups update-groups`.
523
+
524
+ 4. **SCIM PATCH is partial update -- safer for targeted changes** -- Use `scim-users update-users` or `scim-groups update-groups` with SCIM patch operations (`add`, `replace`, `remove`) to change specific fields without risk of data loss.
525
+
526
+ 5. **Bulk operations can partially fail** -- A `scim-bulk create` request can succeed for some operations and fail for others. The `--fail-on-errors` parameter controls the abort threshold. Always check the response body for per-operation `status` codes (e.g., `201` for created, `409` for duplicate).
527
+
528
+ 6. **`/me` endpoint requires user-level token, not admin** -- `scim-users show-me` and `people list-me` return the identity of the authenticated user. These fail with admin service-app tokens because service apps do not represent a person. Use a user-level OAuth token.
529
+
530
+ 7. **Domain verification requires DNS TXT record -- this skill cannot verify DNS** -- After providing the verification token, instruct the user to add the TXT record and wait for propagation (typically 15-60 minutes, up to 48 hours). Do not call `verify-domain` until the user confirms the TXT record is in place.
531
+
532
+ 8. **Org contacts bulk import/delete are async jobs -- poll for completion** -- The `create-bulk` and `create-delete` commands may return before all items are processed. Verify results after completion.
533
+
534
+ 9. **ALWAYS show plan before executing write operations** -- Never create, update, or delete users, groups, contacts, or domains without presenting the plan and getting user confirmation.
535
+
536
+ 10. **SCIM commands require org ID as positional argument** -- All `scim-users`, `scim-groups`, and `scim-bulk` commands require `ORG_ID` as the first positional argument. Webex REST API commands (`people`, `groups`) do not -- they use the org implied by the token.
537
+
538
+ 11. **Identity scopes are separate from Calling scopes** -- SCIM endpoints require `identity:people_rw` / `identity:people_read`. Webex REST endpoints (`people`, `groups`) require `spark-admin:people_write` / `spark-admin:people_read`. Mixing them up produces 403 errors.
539
+
540
+ 12. **People API `emails` must use `--json-body`** -- The `people create` command does not have a `--emails` CLI option. Pass emails via `--json-body '{"emails": ["user@example.com"], ...}'`.
541
+
542
+ 13. **If users need Webex Calling after identity provisioning**, switch to the `provision-calling` skill to assign calling licenses and configure locations. SCIM user creation does not assign calling licenses — that's a separate workflow.
543
+
544
+ 14. **If bulk-creating 20+ users with calling licenses**, consider using `provision-calling` skill directly instead of SCIM → license assignment as two separate steps. The provisioning skill can handle the full user+license workflow.
545
+
546
+ ---
547
+
548
+ ## Error Handling
549
+
550
+ When a wxcli command fails:
551
+
552
+ **A. Fix and retry** -- Missing required field, wrong ID, format issue:
553
+ 1. Read the full error message
554
+ 2. Run `wxcli <group> <command> --help` to check required flags
555
+ 3. Fix the command and retry
556
+
557
+ **B. Skip and continue** -- Resource already exists or already configured:
558
+ 1. Verify current state: `wxcli scim-users show $ORG_ID $USER_ID` or `wxcli people show $PERSON_ID`
559
+ 2. If state is correct, skip to next operation
560
+
561
+ **C. Escalate** -- Unclear or persistent error:
562
+ 1. Run with `--debug` for raw HTTP details
563
+ 2. Invoke `/wxc-calling-debug` for systematic diagnosis
564
+
565
+ Identity-specific errors:
566
+
567
+ - **403 on SCIM endpoints**: Token lacks `identity:people_rw` or `identity:people_read` scope. These are separate from `spark-admin:people_*` scopes. Verify your integration/service-app has identity scopes granted.
568
+ - **403 on domain commands**: Token lacks `identity:organizations_rw` scope. Domain management uses org-level identity scopes.
569
+ - **403 on org-contacts**: Token lacks `identity:contacts_rw` scope.
570
+ - **404 on `show-me` / `list-me`**: Using an admin/service-app token. Switch to a user-level OAuth token.
571
+ - **409 on SCIM create**: User or group already exists. GET the existing resource and decide whether to update or skip.
572
+ - **400 on SCIM filter**: Invalid SCIM filter syntax. Valid operators: `eq`, `ne`, `co` (contains), `sw` (starts with), `pr` (present), `gt`, `ge`, `lt`, `le`. Attribute names are case-sensitive.
573
+ - **400 on bulk operations**: Check per-operation status in the response. Individual operations may fail while others succeed.
574
+ - **Domain verification failure**: DNS TXT record not yet propagated. Wait and retry after confirming TXT record is in place.
575
+ - **400 on `org-contacts create`**: Missing `--schemas` or `--source`. Both are required. Schema value is always `"urn:cisco:codev:identity:contact:core:1.0"`. Source must be `CH` or `Webex4Broadworks`.
576
+
577
+ **SCIM update errors:**
578
+ - **Accidental PUT data loss:** If `scim-users update` (PUT) was run with incomplete data and attributes were deleted, recover immediately:
579
+ 1. Check if the user still exists: `wxcli scim-users show $ORG_ID $USER_ID -o json`
580
+ 2. If the user exists but is missing attributes, use PATCH to restore them:
581
+ ```bash
582
+ wxcli scim-users update-users $ORG_ID $USER_ID --json-body '{
583
+ "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
584
+ "Operations": [
585
+ {"op": "add", "path": "emails", "value": [{"value": "user@example.com", "type": "work", "primary": true}]},
586
+ {"op": "replace", "path": "active", "value": true}
587
+ ]
588
+ }'
589
+ ```
590
+ 3. If group memberships were lost, re-add via `scim-groups update-groups`
591
+ - **400 on PATCH (invalid operation):** Check the `Operations` array format. Each operation needs `op` (add/replace/remove), `path` (attribute name), and `value` (for add/replace). The `schemas` array with the PatchOp URN is required.
592
+ - **409 on create (user exists):** The user already exists in this org. Use `scim-users list` with a filter to find the existing record: `wxcli scim-users list $ORG_ID --filter 'userName eq "user@example.com"' -o json`
593
+
594
+ ---
595
+
596
+ ## Required Scopes Reference
597
+
598
+ | Operation | Scope(s) |
599
+ |-----------|----------|
600
+ | List/search SCIM users | `identity:people_read` |
601
+ | Create/update/delete SCIM users | `identity:people_rw` |
602
+ | List/search SCIM groups | `identity:people_read` |
603
+ | Create/update/delete SCIM groups | `identity:people_rw` |
604
+ | SCIM bulk operations | `identity:people_rw` |
605
+ | SCIM schema introspection | `identity:people_read` |
606
+ | Identity org settings (read) | `identity:organizations_read` |
607
+ | Identity org settings (write) | `identity:organizations_rw` |
608
+ | Generate OTP for a user | `Identity:one_time_password` |
609
+ | List/view people (Webex API) | `spark-admin:people_read` |
610
+ | Create/update/delete people (Webex API) | `spark-admin:people_write` + `spark-admin:people_read` |
611
+ | Domain verification/claiming | `identity:organizations_rw` |
612
+ | Org contacts (read) | `identity:contacts_read` |
613
+ | Org contacts (write) | `identity:contacts_rw` |
614
+ | List roles | Admin token (no additional scope documented) |
615
+
616
+ ---
617
+
618
+ ## SCIM vs Webex API Quick Reference
619
+
620
+ Use this to decide which CLI group to use:
621
+
622
+ | Use Case | SCIM (`scim-users`, `scim-groups`) | Webex REST (`people`, `groups`) |
623
+ |----------|------------------------------------|---------------------------------|
624
+ | IdP integration (Okta, Azure AD) | Yes | No |
625
+ | Automated bulk provisioning | Yes (via `scim-bulk`) | Loop with `people create` |
626
+ | Need calling-specific data | No | Yes (`--calling-data true`) |
627
+ | Partial update (PATCH) | Yes (`update-users`) | No (PUT only on `people update`) |
628
+ | Requires org ID argument | Yes | No (uses token's org) |
629
+ | Scopes needed | `identity:people_rw` | `spark-admin:people_write` |
630
+
631
+ ---
632
+
633
+ ## Context Compaction Recovery
634
+
635
+ If context compacts mid-execution, recover by:
636
+ 1. Read the deployment plan from `docs/plans/` to recover what was planned
637
+ 2. Check what's already been done: run the relevant `list` commands
638
+ 3. Resume from the first incomplete step