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,475 @@
1
+ ---
2
+ name: wxc-calling-debug
3
+ description: |
4
+ Debug a failing Webex Calling API call or configuration. Use when an API
5
+ returns an error, a configuration doesn't apply, a resource is missing,
6
+ or a wxcli command fails. Walks through systematic diagnosis.
7
+ NOT for: building/configuring resources (use the appropriate config skill) or
8
+ querying current state without errors (use query-live skill).
9
+ allowed-tools: Read, Grep, Glob, Bash
10
+ argument-hint: [symptom-or-error-message]
11
+ ---
12
+
13
+ <!-- Updated by playbook session 2026-03-18 -->
14
+ <!-- Restructured to canonical 8-step template 2026-03-19 -->
15
+
16
+ # Webex Calling Debug Workflow
17
+
18
+ **Checkpoint — do NOT proceed until you can answer these:**
19
+ 1. What should you check FIRST for any API failure? (Answer: Auth and scope — run `wxcli whoami` and verify token scopes. Auth/scope issues cause 80% of failures.)
20
+ 2. How do you get raw HTTP details for a failing command? (Answer: Add `--debug` flag to the wxcli command — this shows the full request/response including headers, URL, and body.)
21
+
22
+ If you cannot answer both, you skipped reading this skill. Go back and read it.
23
+
24
+ ## Critical Rules
25
+
26
+ 1. **Verify token before any writes** — always run `wxcli whoami` before attempting create/update/delete operations.
27
+ 2. **Never modify without confirmation** — present the diagnostic plan (Step 5) and get user approval before executing fixes.
28
+ 3. **Always check auth/scope first** — auth and scope issues cause 80% of failures. Complete Step 2 before investigating anything else.
29
+ 4. **call-controls requires user-level OAuth** — admin tokens and service-app tokens get 400 "Target user not authorized" on `/telephony/calls/*` endpoints. The user must authenticate with a personal or OAuth token for a specific calling-licensed user.
30
+ 5. **my-settings requires a calling-licensed user** — all `/people/me/*` endpoints return 404 (error 4008) if the authenticated user does not have a Webex Calling license. Test with a calling user's token, not the admin token.
31
+
32
+ ## Step 1: Load references
33
+
34
+ Load the reference docs relevant to the reported symptom. Do NOT load all docs — pick 1-2 based on the API area involved.
35
+
36
+ | Symptom area | Reference docs to load |
37
+ |--------------|----------------------|
38
+ | Auth / token / scope | `docs/reference/authentication.md` |
39
+ | Provisioning (users, locations, licenses) | `docs/reference/provisioning.md` — has a Table of Contents; load only the relevant § ("Gotchas" for cross-cutting bugs, else the matching API section), not the whole doc |
40
+ | Call features (AA, CQ, HG, paging) | `docs/reference/call-features-major.md`, `docs/reference/call-features-additional.md` |
41
+ | Person call settings | `docs/reference/person-call-settings-*.md` (pick the relevant one: handling, media, permissions, behavior) |
42
+ | Location call settings | `docs/reference/location-calling-core.md`, `location-calling-media.md`, `location-recording-advanced.md` |
43
+ | Routing (trunks, dial plans, PSTN) | `docs/reference/call-routing.md` |
44
+ | Devices | `docs/reference/devices-core.md`, `docs/reference/devices-workspaces.md` |
45
+ | Call control (dial, hold, transfer) | `docs/reference/call-control.md` |
46
+ | Reporting / CDR | `docs/reference/reporting-analytics.md` |
47
+ | Webhooks / events | `docs/reference/webhooks-events.md` |
48
+ | Emergency services | `docs/reference/emergency-services.md` |
49
+ | Auth / scopes / raw HTTP | `docs/reference/authentication.md` |
50
+
51
+ Also load `docs/reference/authentication.md` if the user is troubleshooting scope or token issues.
52
+
53
+ **Mandatory --help verification:** Before reproducing or constructing any wxcli command, run `wxcli <group> --help` to verify the subcommand exists, then `wxcli <group> <subcommand> --help` to verify the exact flags (e.g. `wxcli call-queue --help`). A wrong command name or flag (`show` vs `list`, singular vs plural — known issue #5) is itself a common cause of the failure you're debugging, so confirm before assuming the API is at fault. 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.
54
+
55
+ ## Step 2: Verify auth token and scopes
56
+
57
+ Check authentication and scope access BEFORE investigating any other cause. Auth/scope issues account for the vast majority of failures.
58
+
59
+ ### 2a. Is the token valid and not expired?
60
+
61
+ ```bash
62
+ # Quick token check — shows authenticated user, org, and token expiry
63
+ wxcli whoami
64
+ ```
65
+
66
+ If this fails with an auth error, the token is invalid or expired. Ask the user for a new token and configure it:
67
+
68
+ ```bash
69
+ echo "<TOKEN>" | wxcli configure
70
+ ```
71
+
72
+ This pipes the token into `wxcli configure` and saves it to `~/.wxcli/config.json`. Do NOT use `export WEBEX_ACCESS_TOKEN=...` — environment variables do not persist across Bash tool calls in Claude Code.
73
+
74
+ Token lifetimes:
75
+ - **Personal access token**: 12 hours (cannot be refreshed)
76
+ - **OAuth integration**: 14 days access / 90 days refresh
77
+ - **Service app**: access token via refresh (check `tokens.remaining`)
78
+ - **Bot token**: does not expire
79
+
80
+ ### 2b. Does the token have the right scopes?
81
+
82
+ Quick-reference -- common scopes by API area:
83
+
84
+ | API Area | Read Scope | Write Scope |
85
+ |----------|-----------|-------------|
86
+ | Telephony config (locations, numbers, queues, HGs, AAs) | `spark-admin:telephony_config_read` | `spark-admin:telephony_config_write` |
87
+ | People / users | `spark-admin:people_read` | `spark-admin:people_write` |
88
+ | Call control (dial, hold, transfer) | `spark:calls_read` | `spark:calls_write` |
89
+ | Call detail records | `spark-admin:calling_cdr_read` | -- |
90
+ | XSI operations | `spark:xsi` | `spark:xsi` |
91
+ | WebRTC calling | `spark:webrtc_calling` | -- |
92
+
93
+ If you get a **403 Forbidden**, the token almost certainly lacks the required scope. Check what scopes the token carries:
94
+ - For OAuth tokens: check the `scope` field in your cached tokens YML
95
+ - For personal tokens: they carry all scopes your account has -- if you still get 403, you may not be an org admin (required for `spark-admin:` scopes)
96
+
97
+ ### 2c. Scope verification logic
98
+
99
+ When you know the failing API endpoint, use this logic to verify scope access:
100
+
101
+ 1. **Identify the API area from the symptom** — map the failing endpoint to one of the rows in the scope table above.
102
+ 2. **Determine read vs write** — `GET`/`LIST` operations need the read scope; `POST`/`PUT`/`PATCH`/`DELETE` need the write scope.
103
+ 3. **Test scope access** — run a minimal read command for that API area to confirm the scope works:
104
+ ```bash
105
+ # Test telephony_config scope
106
+ wxcli locations list
107
+ # Test people scope
108
+ wxcli users list
109
+ # Test calls scope (requires user-level OAuth — see special cases below)
110
+ wxcli call-controls list
111
+ ```
112
+ 4. **Diagnose 403s** — if the test command returns 403:
113
+ - Personal token: user may not be a full org admin (required for `spark-admin:` scopes)
114
+ - Service app: org admin must authorize the app in Control Hub
115
+ - OAuth integration: the requested scopes were not included in the authorization URL
116
+ - Bot token: bots cannot access admin-scoped endpoints (`spark-admin:*`)
117
+
118
+ **Special cases:**
119
+
120
+ - **call-controls (`/telephony/calls/*`)** — requires **user-level OAuth**, not admin tokens. Admin tokens and service-app tokens get HTTP 400 "Target user not authorized". The authenticated user must be a specific calling-licensed person.
121
+ - **my-settings (`/people/me/*`)** — requires the authenticated user to have a **Webex Calling license**. Returns 404 (error 4008) otherwise. Test with a calling user's token, not an admin-only token.
122
+ - **XSI operations** — require `spark:xsi` scope AND XSI must be provisioned for the org. If scope is present but calls fail, check with Webex TAC.
123
+ - **CDR (`/telephony/callHistory`)** — requires `spark-admin:calling_cdr_read`. This is a separate scope from `telephony_config_read`.
124
+
125
+ ### 2d. Is calling data included?
126
+
127
+ wxcli handles this automatically -- all user-related commands that need calling data (location_id, phone numbers, calling-specific fields) include it in the API request. You do not need to pass a `calling_data` flag.
128
+
129
+ If you are using the Python SDK directly (outside wxcli), you must pass `calling_data=True` to `api.people.list()` and `api.people.details()`. See the Advanced SDK Debugging section in Step 6.
130
+
131
+ ## Step 3: Identify the symptom
132
+
133
+ Ask the user: **What happened?** Map their answer to one of these categories:
134
+
135
+ | Category | User says something like... |
136
+ |----------|-----------------------------|
137
+ | HTTP error from API | "Got a 401/403/404/409", "API returned an error", "RestError" |
138
+ | CLI command failed | "wxcli returned an error", "command exited with non-zero", "got an error message" |
139
+ | Method returns None | "Got None back", "No return value", "Update didn't return anything" |
140
+ | Missing data on object | "location_id is None", "calling_data fields are empty", "no phone number" |
141
+ | Resource not found | "Can't find the queue/user/location", "404 on a resource I just created" |
142
+ | Permission denied | "403 Forbidden", "insufficient scopes", "not authorized" |
143
+ | Rate limited | "429 Too Many Requests", "script is getting throttled" |
144
+ | SDK exception | "RestError", "AsRestError", "ValueError on init" |
145
+ | Configuration didn't apply | "Changed the setting but nothing happened", "Update succeeded but value is the same" |
146
+ | Bulk operation failures | "Some users failed", "partial failures in gather", "exceptions in batch" |
147
+ | Async/timeout issue | "Script hangs", "aiohttp error", "session closed" |
148
+
149
+ ## Step 4: Check prerequisites
150
+
151
+ ### 4a. Reproduce the failure
152
+
153
+ Re-run the failing command with `--debug` to capture the full HTTP request/response:
154
+
155
+ ```bash
156
+ # Add --debug to the exact command that failed
157
+ wxcli <failing-command> --debug
158
+ ```
159
+
160
+ The `--debug` flag shows:
161
+ - Full request URL, method, and headers
162
+ - Request body (for POST/PUT/PATCH)
163
+ - Response status code and body
164
+ - Tracking ID (for Webex TAC escalation)
165
+
166
+ ### 4b. Verify the resource chain
167
+
168
+ Many failures happen because a prerequisite resource is missing or misconfigured. Walk up the dependency chain:
169
+
170
+ ```bash
171
+ # Does the location exist and is it calling-enabled?
172
+ wxcli locations list
173
+
174
+ # Does the user exist and have a calling license?
175
+ wxcli users list --output json | head -20
176
+
177
+ # Does the parent resource exist? (e.g., for a queue agent, does the queue exist?)
178
+ wxcli call-queue show LOCATION_ID QUEUE_ID --output json
179
+ ```
180
+
181
+ ### 4c. Check known gotchas
182
+
183
+ Cross-reference the symptom against these common gotchas:
184
+
185
+ - **Error code 25008**: Missing required field — check which parameters the command requires
186
+ - **HTTP 400 with details**: The error body usually includes a `description` explaining what's wrong
187
+ - **Tracking ID**: Included in error output — save this for TAC escalation
188
+ - **Extension conflict**: Another user/feature already has the extension in that location
189
+ - **Number not in location**: Phone number assignment fails if the number isn't in the location's inventory
190
+ - **Calling license missing**: User shows no calling features if license isn't assigned
191
+ - **Location not calling-enabled**: Features fail if location hasn't been enabled for Webex Calling
192
+
193
+ Also check the loaded reference doc's Gotchas section (if it has one) for API-area-specific issues.
194
+
195
+ ## Step 5: Build and present diagnostic plan -- [SHOW BEFORE EXECUTING]
196
+
197
+ Before running any fix commands, present the user with:
198
+
199
+ 1. **Root cause hypothesis** — what you believe is causing the failure and why
200
+ 2. **Evidence** — the specific error message, HTTP status, or missing data that supports the hypothesis
201
+ 3. **Proposed fix** — the exact commands you plan to run to resolve the issue
202
+ 4. **Verification plan** — how you will confirm the fix worked
203
+ 5. **Risk assessment** — whether the fix modifies any existing resources (creates, updates, or deletes)
204
+
205
+ Format as a brief numbered plan. Wait for user confirmation before proceeding to Step 6.
206
+
207
+ ## Step 6: Execute diagnostic commands and apply fix
208
+
209
+ ### 6a. Match symptom to cause and fix
210
+
211
+ #### HTTP Error Codes
212
+
213
+ | Symptom | Likely Cause | Fix |
214
+ |---------|-------------|-----|
215
+ | **401 Unauthorized** | Token expired or invalid | Run `wxcli configure` to set a new token. For personal tokens: generate new one at developer.webex.com. |
216
+ | **401 immediately after refresh** | Refresh token also expired (>90 days) | Full re-authorization required -- run OAuth flow again or regenerate service app credentials |
217
+ | **403 Forbidden** | Token lacks required scope | Check scope table in Step 2b. For admin endpoints, verify user is a full org admin. For service apps, verify org admin has authorized the app. |
218
+ | **404 Not Found** | Resource ID is wrong, resource doesn't exist, or wrong org | Verify the resource ID. List resources first to confirm it exists. Check you're authenticating against the correct org. |
219
+ | **409 Conflict** | Duplicate resource (name, extension, phone number) | Check for existing resources with the same name/extension/number. Use the corresponding `list` command to find conflicts. |
220
+ | **429 Too Many Requests** | Rate limited | SDK auto-retries when `retry_429=True` (default). For bulk work, lower `concurrent_requests` or use async with semaphore. |
221
+ | **400 Bad Request** | Invalid parameters, wrong data types, missing required fields | Run the command with `--debug` to see the full error body. Error code 25008 means a required field is missing. Check required fields in the API reference. Verify enum values. Check that IDs are the correct type (Webex base64 ID, not UUID). |
222
+ | **400 "Target user not authorized"** | Using admin/service-app token on call-controls endpoint | call-controls requires user-level OAuth. See Critical Rules #4. |
223
+ | **404 error 4008 on /people/me/** | Authenticated user lacks Webex Calling license | my-settings endpoints require a calling-licensed user. See Critical Rules #5. |
224
+ | **502/503 Service Error** | Webex platform issue | Retry after a delay. Check [status.webex.com](https://status.webex.com) for outages. |
225
+
226
+ #### CLI Debugging
227
+
228
+ ```bash
229
+ # Add --debug flag to any wxcli command for verbose HTTP output
230
+ wxcli locations list --debug
231
+
232
+ # Debug a failing write operation — shows full request/response
233
+ wxcli auto-attendant create LOC_ID --name "Test" --extension 9999 --business-schedule "Default" --debug
234
+
235
+ # Check for errors — wxcli shows HTTP status and error message
236
+ wxcli call-queue show LOCATION_ID QUEUE_ID --output json --debug
237
+ ```
238
+
239
+ #### SDK Behavior Issues (for Python SDK / agent fallback)
240
+
241
+ | Symptom | Likely Cause | Fix |
242
+ |---------|-------------|-----|
243
+ | `configure()` / `update()` returns `None` | This is **normal** -- many update/delete methods return `None` on success | Not a bug. Read back the resource with `details()` to verify the change applied. |
244
+ | `calling_data` fields are `None` on Person | Didn't pass `calling_data=True` | Re-fetch: `api.people.list(calling_data=True)` or `api.people.details(id, calling_data=True)` |
245
+ | `list()` result missing agents/details | List endpoints return minimal data | Call `details(location_id=..., queue_id=...)` to get the full object including agents, alternate numbers, etc. |
246
+ | No token found error from wxcli | No token in `WEBEX_ACCESS_TOKEN` env var or config file | Run `wxcli configure` or set `WEBEX_ACCESS_TOKEN` env var |
247
+ | `PagingApi.update()` wrong parameter order | Model comes before ID in signature | Always use keyword args: `api.telephony.paging.update(location_id=loc, update=paging_obj, paging_id=pg_id)` |
248
+ | Generic `.delete()` accepts any ID silently | Used inherited method instead of named delete | Use named methods: `delete_callpark()`, `delete_pickup()`, `delete_paging()`, `delete_huntgroup()`, `delete_queue()`, `delete_auto_attendant()`, `delete_schedule()` |
249
+
250
+ #### Resource/Configuration Issues
251
+
252
+ | Symptom | Likely Cause | Fix |
253
+ |---------|-------------|-----|
254
+ | Location not showing as calling-enabled | Location not enabled for Webex Calling | Enable calling on the location via `wxcli location-settings` or SDK |
255
+ | Phone number assignment fails | Number not in location inventory | Add number to location first. Check available numbers: `wxcli numbers list` |
256
+ | User shows no calling license | License not assigned | Check licenses: `wxcli licenses list`. Assign via SDK or Control Hub. See provisioning.md § "Licenses API". |
257
+ | Feature creation fails with location error | Location doesn't exist or wrong `location_id` | Verify with `wxcli locations list` -- confirm the ID matches |
258
+ | Hunt group / call queue agent not receiving calls | Agent not assigned to the feature, or not joined | Check agent list: `wxcli call-queue show LOCATION_ID QUEUE_ID --output json`. Verify agent `joinEnabled` is `true`. |
259
+ | Async job timeout | Bulk provisioning job still processing | Check job status via SDK `api.telephony.jobs`. Jobs can take minutes for large orgs. |
260
+ | XSI connection fails | XSI not enabled or wrong endpoint | Verify `spark:xsi` scope. Check with Webex TAC if XSI is provisioned for the org. |
261
+ | Setting update succeeded but value unchanged | Some settings require specific preconditions | Check if the feature requires a license, an enabled location, or a specific calling plan. Read back the resource to confirm. |
262
+ | Extension conflict | Another user/feature already has the extension in that location | List all extensions in the location and pick an unused one |
263
+
264
+ #### Async-Specific Issues
265
+
266
+ | Symptom | Likely Cause | Fix |
267
+ |---------|-------------|-----|
268
+ | `RuntimeError: Event loop is closed` | Calling `asyncio.run()` in an already-running loop (Jupyter, etc.) | Use `await main()` directly, or use `nest_asyncio` |
269
+ | `aiohttp.ClientError` / session closed | Session used after `async with` block exited | Keep all API calls inside the `async with aiohttp.ClientSession() as session:` block |
270
+ | Partial failures in `asyncio.gather` | Some calls failed, rest succeeded | Use `return_exceptions=True` and check each result: `isinstance(result, Exception)` |
271
+ | Slow bulk operations | Concurrency too low | Increase semaphore limit in the migration engine pattern |
272
+
273
+ ### 6b. Test with targeted CLI commands
274
+
275
+ Isolate the issue by running minimal commands that test the specific failure:
276
+
277
+ ```bash
278
+ # Test 1: Basic auth — does the token work at all?
279
+ wxcli whoami
280
+
281
+ # Test 2: Can you read telephony config?
282
+ wxcli locations list
283
+
284
+ # Test 3: Can you read calling-specific user data?
285
+ wxcli users list --output json | head -20
286
+
287
+ # Test 4: Test a specific resource directly
288
+ wxcli call-queue show LOCATION_ID QUEUE_ID --output json
289
+ ```
290
+
291
+ If Test 1 fails: token issue (Step 2a).
292
+ If Test 1 passes but Test 2 fails: scope issue (Step 2b/2c).
293
+ If Tests 1-2 pass but Test 3 fails: calling license or org issue.
294
+
295
+ For a specific failing resource, test it directly with `--debug` for full HTTP details:
296
+
297
+ ```bash
298
+ # If a queue/HG/AA operation fails, verify the resource exists
299
+ wxcli call-queue show LOCATION_ID QUEUE_ID --debug
300
+
301
+ # If a create operation fails, check the request body
302
+ wxcli auto-attendant create LOC_ID --name "Test" --extension 9999 --business-schedule "Default" --debug
303
+
304
+ # If a user operation fails, check the user exists and has calling
305
+ wxcli users show USER_ID --output json --debug
306
+ ```
307
+
308
+ #### Fallback: Quick curl test (for Content-Type or header issues)
309
+
310
+ If the CLI sends wrong headers (e.g., wrong Content-Type for JSON Patch endpoints), use curl to test the raw request:
311
+
312
+ ```bash
313
+ TOKEN=$(python3.11 -c "import json; print(json.load(open('$HOME/.wxcli/config.json'))['profiles']['default']['token'])")
314
+ curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
315
+ https://webexapis.com/v1/...
316
+ ```
317
+
318
+ The config file structure is `profiles.<profile_name>.token` (not a top-level `access_token` key). Default profile is `default`.
319
+
320
+ #### Fallback: Advanced SDK Debugging (when CLI doesn't give enough detail)
321
+
322
+ If the `--debug` flag output doesn't reveal the issue, fall back to Python SDK debugging for deeper inspection.
323
+
324
+ ##### Enable debug logging
325
+
326
+ ```python
327
+ import logging
328
+
329
+ logging.basicConfig(level=logging.DEBUG)
330
+ # Reduce noise from urllib3
331
+ logging.getLogger('urllib3').setLevel(logging.INFO)
332
+ ```
333
+
334
+ To log REST traffic to a file only:
335
+
336
+ ```python
337
+ import logging
338
+
339
+ logging.basicConfig(level=logging.INFO)
340
+
341
+ wxcli_logger = logging.getLogger('wxcli')
342
+ wxcli_logger.setLevel(logging.DEBUG)
343
+ handler = logging.FileHandler('rest.log', mode='w')
344
+ handler.setLevel(logging.DEBUG)
345
+ wxcli_logger.addHandler(handler)
346
+ ```
347
+
348
+ Use `wxcli --debug <command>` to enable verbose HTTP logging for any CLI command.
349
+
350
+ ##### Read RestError details
351
+
352
+ When the API returns an error, the SDK raises `RestError` (sync) or `AsRestError` (async). Extract the full details:
353
+
354
+ ```python
355
+ from wxcli.auth import get_api
356
+ from wxcli.errors import WebexError
357
+
358
+ api = get_api()
359
+ try:
360
+ result = api.session.rest_get(
361
+ f"https://webexapis.com/v1/telephony/config/locations/{loc_id}/queues/{queue_id}"
362
+ )
363
+ except RestError as e:
364
+ print(f'HTTP {e.response.status_code}')
365
+ print(f'Error code: {e.code}')
366
+ print(f'Description: {e.description}')
367
+ print(f'Tracking ID: {e.detail.tracking_id}')
368
+ # Full error detail
369
+ for err in e.detail.errors:
370
+ print(f' - {err.description} (code: {err.error_code})')
371
+ ```
372
+
373
+ The **tracking ID** is critical for Webex TAC support escalation.
374
+
375
+ ##### Targeted raw HTTP test
376
+
377
+ If CLI commands don't reveal the issue, use a minimal Python script for deeper inspection:
378
+
379
+ ```python
380
+ from wxcli.auth import get_api
381
+ from wxcli.errors import WebexError
382
+ import json
383
+
384
+ api = get_api()
385
+
386
+ try:
387
+ queue = api.session.rest_get(
388
+ "https://webexapis.com/v1/telephony/config/locations/LOCATION_ID/queues/QUEUE_ID"
389
+ )
390
+ print(f'Queue found: {queue["name"]}')
391
+ except WebexError as e:
392
+ error_data = json.loads(str(e))
393
+ print(f'Error: {error_data}')
394
+ print(f'Check trackingId in the response for TAC escalation')
395
+ ```
396
+
397
+ ## Step 7: Apply fix and verify
398
+
399
+ After identifying and applying the fix:
400
+
401
+ 1. **Re-run the failing command** -- confirm the error is gone
402
+ 2. **Read back the resource** -- use the corresponding `show` command with `--output json` to verify the change actually applied
403
+ 3. **Check for downstream effects** -- if you changed a location, verify users in that location still work. If you changed a queue, verify agents are still assigned.
404
+
405
+ ```bash
406
+ # Example: verify a fix applied
407
+ wxcli call-queue show LOCATION_ID QUEUE_ID --output json
408
+
409
+ # Example: verify users in a location after location change
410
+ wxcli users list --output json | head -40
411
+ ```
412
+
413
+ If the fix didn't work, return to Step 4 and check the next most likely cause.
414
+
415
+ ## Step 8: Report results
416
+
417
+ Summarize the debugging session for the user:
418
+
419
+ 1. **Symptom** — what the user reported
420
+ 2. **Root cause** — what was actually wrong (with evidence)
421
+ 3. **Fix applied** — what commands were run to resolve it
422
+ 4. **Verification** — confirmation that the fix worked (with command output)
423
+ 5. **Prevention** — how to avoid this issue in the future (if applicable)
424
+
425
+ If the issue could not be resolved:
426
+ - Document what was tried and ruled out
427
+ - Provide the **Tracking ID** from the error for Webex TAC escalation
428
+ - Suggest next steps (TAC case, check status.webex.com, etc.)
429
+
430
+ If a reference doc was wrong or incomplete, update it per the Reference Doc Sync Protocol in CLAUDE.md.
431
+
432
+ ---
433
+
434
+ ## Quick Reference: Rate Limit Handling
435
+
436
+ wxcli does NOT auto-retry 429 errors in normal CLI mode — it raises an error. For bulk operations, use the migration engine's async pattern which handles 429 retries with exponential backoff:
437
+
438
+ ```python
439
+ # For bulk async with controlled concurrency, use the migration engine's async pattern:
440
+ # It uses aiohttp with a semaphore for concurrency limiting
441
+ # and automatic 429 retry with Retry-After header parsing.
442
+
443
+ # For shell loops, add sleep between commands:
444
+ # for id in $IDS; do wxcli <command> "$id"; sleep 1; done
445
+ if isinstance(r, Exception)]
446
+ print(f'{len(failures)} failures out of {len(items)}')
447
+ ```
448
+
449
+ The SDK caps retry wait at 60 seconds (`RETRY_429_MAX_WAIT`). If you're still being throttled, reduce `concurrent_requests`.
450
+
451
+ ---
452
+
453
+ ## Quick Reference: Common Scope Requirements
454
+
455
+ | Operation | Required Scope(s) |
456
+ |-----------|--------------------|
457
+ | List/read users | `spark-admin:people_read` |
458
+ | Create/update/delete users | `spark-admin:people_write` |
459
+ | List/read locations, numbers, queues, HGs, AAs, schedules | `spark-admin:telephony_config_read` |
460
+ | Create/update/delete queues, HGs, AAs, schedules, numbers | `spark-admin:telephony_config_write` |
461
+ | Read call history | `spark:calls_read` |
462
+ | Place/control calls | `spark:calls_write` |
463
+ | Read CDR records | `spark-admin:calling_cdr_read` |
464
+ | XSI operations | `spark:xsi` |
465
+ | WebRTC calling | `spark:webrtc_calling` |
466
+ | Read licenses | `spark-admin:people_read` (licenses are part of people API) |
467
+
468
+ ---
469
+
470
+ ## Context Compaction Recovery
471
+
472
+ If context compacts mid-execution, recover by:
473
+ 1. Read the deployment plan from `docs/plans/` to recover what was planned
474
+ 2. Check what's already been created: run the relevant `list` commands
475
+ 3. Resume from the first incomplete step