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,405 @@
1
+ import json
2
+ import typer
3
+ from wxcli.auth import get_api
4
+ from wxcli.errors import WebexError, handle_rest_error
5
+ from wxcli.output import print_table, print_json
6
+ from wxcli.config import get_org_id
7
+
8
+
9
+ app = typer.Typer(help="Manage Webex Calling numbers.")
10
+
11
+
12
+ @app.command("create")
13
+ def create(
14
+ location_id: str = typer.Argument(help="locationId"),
15
+ number_type: str = typer.Option(None, "--number-type", help="Choices: TOLLFREE, DID, MOBILE"),
16
+ number_usage_type: str = typer.Option(None, "--number-usage-type", help="Choices: NONE, SERVICE"),
17
+ state: str = typer.Option(None, "--state", help="Choices: ACTIVE, INACTIVE"),
18
+ subscription_id: str = typer.Option(None, "--subscription-id", help="The `subscriptionId` to be used for the mobile number order."),
19
+ carrier_id: str = typer.Option(None, "--carrier-id", help="The `carrierId` to be used for the mobile number order."),
20
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
21
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
22
+ debug: bool = typer.Option(False, "--debug"),
23
+ ):
24
+ """Add Phone Numbers to a Location\n\nExample --json-body:\n '{"phoneNumbers":["..."],"numberType":"TOLLFREE","numberUsageType":"NONE","state":"ACTIVE","subscriptionId":"...","carrierId":"..."}'."""
25
+ api = get_api(debug=debug)
26
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/numbers"
27
+ params = {}
28
+ org_id = get_org_id()
29
+ if org_id is not None:
30
+ params["orgId"] = org_id
31
+ if json_body:
32
+ body = json.loads(json_body)
33
+ else:
34
+ body = {}
35
+ if number_type is not None:
36
+ body["numberType"] = number_type
37
+ if number_usage_type is not None:
38
+ body["numberUsageType"] = number_usage_type
39
+ if state is not None:
40
+ body["state"] = state
41
+ if subscription_id is not None:
42
+ body["subscriptionId"] = subscription_id
43
+ if carrier_id is not None:
44
+ body["carrierId"] = carrier_id
45
+ try:
46
+ result = api.session.rest_post(url, json=body, params=params)
47
+ except WebexError as e:
48
+ handle_rest_error(e)
49
+ if output == "json":
50
+ print_json(result)
51
+ elif isinstance(result, dict) and "id" in result:
52
+ typer.echo(f"Created: {result['id']}")
53
+ elif not result or result == {}:
54
+ typer.echo("Created.")
55
+ else:
56
+ print_json(result)
57
+
58
+
59
+
60
+ @app.command("update")
61
+ def update(
62
+ location_id: str = typer.Argument(help="locationId"),
63
+ action: str = typer.Option(None, "--action", help="Choices: ACTIVATE, DEACTIVATE"),
64
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
65
+ debug: bool = typer.Option(False, "--debug"),
66
+ ):
67
+ """Manage Number State in a Location\n\nExample --json-body:\n '{"phoneNumbers":["..."],"action":"ACTIVATE"}'."""
68
+ api = get_api(debug=debug)
69
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/numbers"
70
+ params = {}
71
+ org_id = get_org_id()
72
+ if org_id is not None:
73
+ params["orgId"] = org_id
74
+ if json_body:
75
+ body = json.loads(json_body)
76
+ else:
77
+ body = {}
78
+ if action is not None:
79
+ body["action"] = action
80
+ try:
81
+ result = api.session.rest_put(url, json=body, params=params)
82
+ except WebexError as e:
83
+ handle_rest_error(e)
84
+ typer.echo(f"Updated.")
85
+
86
+
87
+
88
+ @app.command("delete")
89
+ def delete(
90
+ location_id: str = typer.Argument(help="locationId"),
91
+ force: bool = typer.Option(False, "--force", help="Skip confirmation"),
92
+ debug: bool = typer.Option(False, "--debug"),
93
+ ):
94
+ """Remove Phone Numbers from a Location."""
95
+ if not force:
96
+ typer.confirm(f"Delete {location_id}?", abort=True)
97
+ api = get_api(debug=debug)
98
+ url = f"https://webexapis.com/v1/telephony/config/locations/{location_id}/numbers"
99
+ params = {}
100
+ org_id = get_org_id()
101
+ if org_id is not None:
102
+ params["orgId"] = org_id
103
+ try:
104
+ api.session.rest_delete(url, params=params)
105
+ except WebexError as e:
106
+ handle_rest_error(e)
107
+ typer.echo(f"Deleted: {location_id}")
108
+
109
+
110
+
111
+ @app.command("validate-phone-numbers")
112
+ def validate_phone_numbers(
113
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
114
+ debug: bool = typer.Option(False, "--debug"),
115
+ ):
116
+ """Validate Phone Numbers\n\nExample --json-body:\n '{"phoneNumbers":["..."]}'."""
117
+ api = get_api(debug=debug)
118
+ url = f"https://webexapis.com/v1/telephony/config/actions/validateNumbers/invoke"
119
+ params = {}
120
+ org_id = get_org_id()
121
+ if org_id is not None:
122
+ params["orgId"] = org_id
123
+ if json_body:
124
+ body = json.loads(json_body)
125
+ else:
126
+ body = {}
127
+ try:
128
+ result = api.session.rest_post(url, json=body, params=params)
129
+ except WebexError as e:
130
+ handle_rest_error(e)
131
+ print_json(result)
132
+
133
+
134
+
135
+ @app.command("list")
136
+ def cmd_list(
137
+ location_id: str = typer.Option(None, "--location-id", help="Return the list of phone numbers for this location within th"),
138
+ phone_number: str = typer.Option(None, "--phone-number", help="Search for this `phoneNumber`."),
139
+ available: str = typer.Option(None, "--available", help="Search among the available phone numbers. This parameter can"),
140
+ order: str = typer.Option(None, "--order", help="Sort the list of phone numbers based on the following:`lastN"),
141
+ owner_name: str = typer.Option(None, "--owner-name", help="Return the list of phone numbers that are owned by the given"),
142
+ owner_id: str = typer.Option(None, "--owner-id", help="Returns only the matched number/extension entries assigned t"),
143
+ owner_type: str = typer.Option(None, "--owner-type", help="Choices: PEOPLE, PLACE, AUTO_ATTENDANT, CALL_QUEUE, PAGING_GROUP, HUNT_GROUP, VOICE_MESSAGING, BROADWORKS_ANYWHERE, CONTACT_CENTER_LINK, ROUTE_LIST, VOICEMAIL_GROUP, VIRTUAL_LINE"),
144
+ extension: str = typer.Option(None, "--extension", help="Returns the list of phone numbers with the given extension."),
145
+ number_type: str = typer.Option(None, "--number-type", help="Choices: NUMBER, EXTENSION"),
146
+ phone_number_type: str = typer.Option(None, "--phone-number-type", help="Choices: PRIMARY, ALTERNATE, FAX, DNIS, Default"),
147
+ state: str = typer.Option(None, "--state", help="Choices: ACTIVE, INACTIVE, Default"),
148
+ details: str = typer.Option(None, "--details", help="Returns the overall count of the phone numbers along with ot"),
149
+ toll_free_numbers: str = typer.Option(None, "--toll-free-numbers", help="Returns the list of toll-free phone numbers."),
150
+ restricted_non_geo_numbers: str = typer.Option(None, "--restricted-non-geo-numbers", help="Returns the list of restricted non-geographical numbers."),
151
+ included_telephony_types: str = typer.Option(None, "--included-telephony-types", help="Returns the list of phone numbers that are of given `include"),
152
+ service_number: str = typer.Option(None, "--service-number", help="Returns the list of service phone numbers."),
153
+ reserved_number: str = typer.Option(None, "--reserved-number", help="Filters reserved phone numbers. When set to `true`, returns"),
154
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
155
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
156
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
157
+ debug: bool = typer.Option(False, "--debug"),
158
+ ):
159
+ """Get Phone Numbers for an Organization with Given Criteria."""
160
+ api = get_api(debug=debug)
161
+ url = f"https://webexapis.com/v1/telephony/config/numbers"
162
+ params = {}
163
+ if location_id is not None:
164
+ params["locationId"] = location_id
165
+ if phone_number is not None:
166
+ params["phoneNumber"] = phone_number
167
+ if available is not None:
168
+ params["available"] = available
169
+ if order is not None:
170
+ params["order"] = order
171
+ if owner_name is not None:
172
+ params["ownerName"] = owner_name
173
+ if owner_id is not None:
174
+ params["ownerId"] = owner_id
175
+ if owner_type is not None:
176
+ params["ownerType"] = owner_type
177
+ if extension is not None:
178
+ params["extension"] = extension
179
+ if number_type is not None:
180
+ params["numberType"] = number_type
181
+ if phone_number_type is not None:
182
+ params["phoneNumberType"] = phone_number_type
183
+ if state is not None:
184
+ params["state"] = state
185
+ if details is not None:
186
+ params["details"] = details
187
+ if toll_free_numbers is not None:
188
+ params["tollFreeNumbers"] = toll_free_numbers
189
+ if restricted_non_geo_numbers is not None:
190
+ params["restrictedNonGeoNumbers"] = restricted_non_geo_numbers
191
+ if included_telephony_types is not None:
192
+ params["includedTelephonyTypes"] = included_telephony_types
193
+ if service_number is not None:
194
+ params["serviceNumber"] = service_number
195
+ if reserved_number is not None:
196
+ params["reservedNumber"] = reserved_number
197
+ if limit > 0:
198
+ params["max"] = limit
199
+ if offset > 0:
200
+ params["start"] = offset
201
+ org_id = get_org_id()
202
+ if org_id is not None:
203
+ params["orgId"] = org_id
204
+ result = None
205
+ try:
206
+ result = api.session.rest_get(url, params=params)
207
+ except WebexError as e:
208
+ handle_rest_error(e)
209
+ result = result or []
210
+ items = result.get("phoneNumbers", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
211
+ if output == "json":
212
+ print_json(items)
213
+ else:
214
+ print_table(items, columns=[('Phone Number', 'phoneNumber'), ('Extension', 'extension'), ('State', 'state'), ('Owner Type', 'owner.type'), ('Owner Name', 'owner.firstName')], limit=limit)
215
+
216
+
217
+
218
+ @app.command("list-manage-numbers")
219
+ def list_manage_numbers(
220
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
221
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
222
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
223
+ debug: bool = typer.Option(False, "--debug"),
224
+ ):
225
+ """List Manage Numbers Jobs."""
226
+ api = get_api(debug=debug)
227
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers"
228
+ params = {}
229
+ if limit > 0:
230
+ params["max"] = limit
231
+ if offset > 0:
232
+ params["start"] = offset
233
+ org_id = get_org_id()
234
+ if org_id is not None:
235
+ params["orgId"] = org_id
236
+ result = None
237
+ try:
238
+ result = api.session.rest_get(url, params=params)
239
+ except WebexError as e:
240
+ handle_rest_error(e)
241
+ result = result or []
242
+ items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
243
+ if output == "json":
244
+ print_json(items)
245
+ else:
246
+ print_table(items, columns=[('ID', 'id'), ('Operation', 'operationType'), ('Status', 'latestExecutionStatus')], limit=limit)
247
+
248
+
249
+
250
+ @app.command("create-manage-numbers")
251
+ def create_manage_numbers(
252
+ operation: str = typer.Option(None, "--operation", help="(required) The kind of operation to be carried out."),
253
+ target_location_id: str = typer.Option(None, "--target-location-id", help="Mandatory for a `MOVE` operation. The target location within"),
254
+ number_usage_type: str = typer.Option(None, "--number-usage-type", help="The number usage type. Mandatory for `NUMBER_USAGE_CHANGE` o"),
255
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body (overrides other options)"),
256
+ output: str = typer.Option("id", "--output", "-o", help="Output format: id|json"),
257
+ debug: bool = typer.Option(False, "--debug"),
258
+ ):
259
+ """Initiate Number Jobs\n\nExample --json-body:\n '{"operation":"...","numberList":[{"locationId":"...","numbers":"..."}],"targetLocationId":"...","numberUsageType":"..."}'."""
260
+ api = get_api(debug=debug)
261
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers"
262
+ params = {}
263
+ org_id = get_org_id()
264
+ if org_id is not None:
265
+ params["orgId"] = org_id
266
+ if json_body:
267
+ body = json.loads(json_body)
268
+ else:
269
+ body = {}
270
+ if operation is not None:
271
+ body["operation"] = operation
272
+ if target_location_id is not None:
273
+ body["targetLocationId"] = target_location_id
274
+ if number_usage_type is not None:
275
+ body["numberUsageType"] = number_usage_type
276
+ _missing = [f for f in ['operation'] if f not in body or body[f] is None]
277
+ if _missing:
278
+ typer.echo("Error: Missing required fields: " + ", ".join(_missing), err=True)
279
+ raise typer.Exit(1)
280
+ try:
281
+ result = api.session.rest_post(url, json=body, params=params)
282
+ except WebexError as e:
283
+ handle_rest_error(e)
284
+ if output == "json":
285
+ print_json(result)
286
+ elif isinstance(result, dict) and "id" in result:
287
+ typer.echo(f"Created: {result['id']}")
288
+ elif not result or result == {}:
289
+ typer.echo("Created.")
290
+ else:
291
+ print_json(result)
292
+
293
+
294
+
295
+ @app.command("show")
296
+ def show(
297
+ job_id: str = typer.Argument(help="jobId"),
298
+ output: str = typer.Option("json", "--output", "-o", help="Output format: table|json"),
299
+ debug: bool = typer.Option(False, "--debug"),
300
+ ):
301
+ """Get Manage Numbers Job Status."""
302
+ api = get_api(debug=debug)
303
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers/{job_id}"
304
+ params = {}
305
+ org_id = get_org_id()
306
+ if org_id is not None:
307
+ params["orgId"] = org_id
308
+ try:
309
+ result = api.session.rest_get(url, params=params)
310
+ except WebexError as e:
311
+ handle_rest_error(e)
312
+ if output == "json":
313
+ print_json(result)
314
+ else:
315
+ if isinstance(result, dict):
316
+ print_table([result], columns=[("Key", ""), ("Value", "")], limit=0)
317
+ elif isinstance(result, list):
318
+ print_table(result, columns=[("ID", "id"), ("Name", "name")], limit=0)
319
+ else:
320
+ print_json(result)
321
+
322
+
323
+
324
+ @app.command("pause-the-manage")
325
+ def pause_the_manage(
326
+ job_id: str = typer.Argument(help="jobId"),
327
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
328
+ debug: bool = typer.Option(False, "--debug"),
329
+ ):
330
+ """Pause the Manage Numbers Job."""
331
+ api = get_api(debug=debug)
332
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers/{job_id}/actions/pause/invoke"
333
+ params = {}
334
+ org_id = get_org_id()
335
+ if org_id is not None:
336
+ params["orgId"] = org_id
337
+ if json_body:
338
+ body = json.loads(json_body)
339
+ else:
340
+ body = {}
341
+ try:
342
+ result = api.session.rest_post(url, json=body, params=params)
343
+ except WebexError as e:
344
+ handle_rest_error(e)
345
+ print_json(result)
346
+
347
+
348
+
349
+ @app.command("resume-the-manage")
350
+ def resume_the_manage(
351
+ job_id: str = typer.Argument(help="jobId"),
352
+ json_body: str = typer.Option(None, "--json-body", help="Full JSON body"),
353
+ debug: bool = typer.Option(False, "--debug"),
354
+ ):
355
+ """Resume the Manage Numbers Job."""
356
+ api = get_api(debug=debug)
357
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers/{job_id}/actions/resume/invoke"
358
+ params = {}
359
+ org_id = get_org_id()
360
+ if org_id is not None:
361
+ params["orgId"] = org_id
362
+ if json_body:
363
+ body = json.loads(json_body)
364
+ else:
365
+ body = {}
366
+ try:
367
+ result = api.session.rest_post(url, json=body, params=params)
368
+ except WebexError as e:
369
+ handle_rest_error(e)
370
+ print_json(result)
371
+
372
+
373
+
374
+ @app.command("list-errors")
375
+ def list_errors(
376
+ job_id: str = typer.Argument(help="jobId"),
377
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table|json"),
378
+ limit: int = typer.Option(0, "--limit", help="Max results (0=all for paginated endpoints, API default for non-paginated)"),
379
+ offset: int = typer.Option(0, "--offset", help="Start offset"),
380
+ debug: bool = typer.Option(False, "--debug"),
381
+ ):
382
+ """List Manage Numbers Job Errors."""
383
+ api = get_api(debug=debug)
384
+ url = f"https://webexapis.com/v1/telephony/config/jobs/numbers/manageNumbers/{job_id}/errors"
385
+ params = {}
386
+ if limit > 0:
387
+ params["max"] = limit
388
+ if offset > 0:
389
+ params["start"] = offset
390
+ org_id = get_org_id()
391
+ if org_id is not None:
392
+ params["orgId"] = org_id
393
+ result = None
394
+ try:
395
+ result = api.session.rest_get(url, params=params)
396
+ except WebexError as e:
397
+ handle_rest_error(e)
398
+ result = result or []
399
+ items = result.get("items", result.get("data", result if isinstance(result, list) else [])) if isinstance(result, dict) else (result if isinstance(result, list) else [])
400
+ if output == "json":
401
+ print_json(items)
402
+ else:
403
+ print_table(items, columns=[("ID", "id"), ("Name", "name")], limit=limit)
404
+
405
+