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,124 @@
1
+ # Routing Domain
2
+
3
+ **Covers:** Trunks, route groups, route lists, dial plans, translation patterns, PSTN connections.
4
+
5
+ **Important:** All routing commands are under the `call-routing` group. There are NO separate `trunk`, `route-group`, `route-list`, or `dial-plan` command groups.
6
+
7
+ ## Question Patterns
8
+
9
+ | Pattern | Example |
10
+ |---------|---------|
11
+ | Inventory | "What trunks are configured?", "Show me all dial plans" |
12
+ | Detail | "Show me the Main trunk details", "What's in the US dial plan?" |
13
+ | Topology | "Show the full routing path", "Which route group does the Main trunk belong to?" |
14
+ | Translation | "What translation patterns are in place?" |
15
+ | PSTN | "How is PSTN connected at Austin?" |
16
+
17
+ ## Command Recipes
18
+
19
+ ### Trunks
20
+ ```bash
21
+ wxcli call-routing list-trunks -o json
22
+ wxcli call-routing list-trunks --name "Main" -o json
23
+ wxcli call-routing show-trunks TRUNK_ID -o json
24
+ ```
25
+ Show response includes: `name`, `location`, `trunkType` (REGISTERING, CERTIFICATE_BASED), `inboundCalls`, `outboundCalls`, `routeGroup`.
26
+
27
+ ### Route Groups
28
+ ```bash
29
+ wxcli call-routing list-route-groups -o json
30
+ wxcli call-routing show-route-groups ROUTE_GROUP_ID -o json
31
+ ```
32
+ Show response includes: `name`, `localGateways` (list of trunks in the group with priority/weight).
33
+
34
+ ### Route Lists
35
+ ```bash
36
+ wxcli call-routing list-route-lists -o json
37
+ wxcli call-routing show-route-lists ROUTE_LIST_ID -o json
38
+ ```
39
+ Show response includes: `name`, `routeGroup` references, `locationId`.
40
+
41
+ ### Dial Plans
42
+ ```bash
43
+ wxcli call-routing list-dial-plans -o json
44
+ wxcli call-routing list-dial-plans --dial-plan-name "International" -o json
45
+ wxcli call-routing show-dial-plans DIAL_PLAN_ID -o json
46
+ ```
47
+ Show response includes: `name`, `routeType` (ROUTE_LIST or ROUTE_GROUP), `routeId`, `dialPatterns`.
48
+
49
+ ### Translation Patterns
50
+ ```bash
51
+ wxcli call-routing list-translation-patterns -o json
52
+ wxcli call-routing list-translation-patterns --name "Emergency" -o json
53
+ wxcli call-routing list-translation-patterns --matching-pattern "+1911" -o json
54
+ wxcli call-routing show-translation-patterns-call-routing TRANSLATION_ID -o json
55
+ ```
56
+
57
+ ### PSTN Connection
58
+ ```bash
59
+ wxcli pstn list LOCATION_ID -o json
60
+ ```
61
+
62
+ ### Test Call Routing
63
+ ```bash
64
+ wxcli call-routing test-call-routing --originator-id PERSON_ID --originator-type PEOPLE --destination "+15125551234" -o json
65
+ ```
66
+ Tests how a dialed number would be routed. Useful for "what happens if I dial...?" questions. `--originator-type` accepts `PEOPLE` or `TRUNK`. This is a POST but does not modify state — it's a read-only simulation.
67
+
68
+ ## Join Patterns
69
+
70
+ **Topology query** ("Show the full routing path"):
71
+ Build the tree bottom-up:
72
+ 1. `wxcli call-routing list-trunks -o json` → all trunks
73
+ 2. `wxcli call-routing list-route-groups -o json` → all route groups (each references its trunks)
74
+ 3. `wxcli call-routing list-route-lists -o json` → all route lists (each references its route groups)
75
+ 4. `wxcli call-routing list-dial-plans -o json` → all dial plans (each references a route list or route group)
76
+
77
+ Present as a tree:
78
+ ```
79
+ Dial Plan: US Domestic
80
+ └─ Route List: US Routes
81
+ └─ Route Group: Primary RG
82
+ ├─ Trunk: Austin SBC (priority 1)
83
+ └─ Trunk: Denver SBC (priority 2)
84
+
85
+ Dial Plan: International
86
+ └─ Route Group: International RG
87
+ └─ Trunk: Cloud PSTN
88
+ ```
89
+
90
+ **Trunk membership query** ("Which route group does Main trunk belong to?"):
91
+ 1. `wxcli call-routing list-route-groups -o json`
92
+ 2. For each route group, check its `localGateways` list for the trunk name/ID
93
+ 3. Report all route groups that contain the trunk
94
+
95
+ ## Response Guidance
96
+
97
+ **Inventory query** ("What trunks are configured?"):
98
+ ```
99
+ 3 trunks configured:
100
+ - Austin SBC (Registering, Austin location)
101
+ - Denver SBC (Registering, Denver location)
102
+ - Cloud PSTN (Certificate-based, no location)
103
+ ```
104
+
105
+ **Detail query** ("Show me the US dial plan"):
106
+ ```
107
+ US Domestic Dial Plan:
108
+ Route type: Route List
109
+ Route list: US Routes
110
+ Dial patterns:
111
+ - +1[2-9]XXXXXXXXX (US/Canada)
112
+ - 1[2-9]XXXXXXXXX
113
+ - [2-9]XXXXXXXXX (10-digit)
114
+ ```
115
+
116
+ **Topology query** (full tree): See Join Patterns above for the tree format.
117
+
118
+ ## Gotchas
119
+
120
+ 1. **All commands are under `call-routing`.** Do NOT use `wxcli trunk`, `wxcli route-group`, etc. — those groups don't exist. Use `wxcli call-routing list-trunks`, `wxcli call-routing show-trunks`, etc.
121
+ 2. **Dial plan show includes patterns inline.** No separate "list patterns" command needed — they're in the show response.
122
+ 3. **Route groups reference trunks by ID.** To show trunk names in a route group view, you need to cross-reference with the trunk list.
123
+ 4. **Translation patterns support `--name` and `--matching-pattern` server-side filters.** For other criteria, filter client-side. The show command has a generator-artifact suffix: `show-translation-patterns-call-routing` (not `show-translation-patterns`).
124
+ 5. **PSTN list is location-scoped.** Must pass a location ID. For org-wide PSTN view, enumerate all locations.
@@ -0,0 +1,501 @@
1
+ ---
2
+ name: reporting
3
+ description: |
4
+ Query and analyze Webex Calling reporting and analytics: Detailed Call History (CDR),
5
+ Call Queue statistics, Auto Attendant statistics, call quality, report templates,
6
+ converged recording download/export, and call volume trends. 75 CDR recipes + query
7
+ composition guide for answering any natural-language question about a calling environment.
8
+ NOT for: Contact Center analytics (use reporting-cc skill), meetings/workspace analytics
9
+ (use reporting-meetings skill), or per-user recording toggle (use manage-call-settings skill).
10
+ allowed-tools: Read, Grep, Glob, Bash
11
+ argument-hint: [report-type]
12
+ ---
13
+
14
+ # Reporting & Analytics Workflow
15
+
16
+ **Checkpoint — do NOT proceed until you can answer these:**
17
+ 1. What is the maximum date range for a single CDR query? (Answer: 12 hours per request. For longer ranges, issue multiple sequential requests.)
18
+ 2. What base URL does CDR use? (Answer: `https://analytics-calling.webexapis.com` — different from the standard `webexapis.com` base. The CLI handles this automatically.)
19
+ 3. CDR field names use spaces in JSON output — what format? (Answer: `"Start time"`, `"Call outcome reason"`, `"Answer indicator"` — use `r.get('Field Name')` in Python.)
20
+ 4. Does `/tmp/cdr-session.json` exist and what window does it cover? (If yes, check the `_meta` object for `start` and `end` timestamps before re-pulling.)
21
+
22
+ If you cannot answer all four, read `docs/reference/reporting-analytics.md` before proceeding.
23
+
24
+ ## Step 1: Load references
25
+
26
+ 1. Read `docs/reference/reporting-analytics.md` for CDR fields, report templates, API constraints
27
+ 2. The 75 CDR recipes live in `references/cdr-recipes.md` (this skill's `references/` dir) — load on demand when a question maps to a recipe; see the Recipe Catalog index under the CDR Query Composition Guide below
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 (e.g. `wxcli cdr list --help` for call detail records, `wxcli reports --help` for templated reports — date-range and filter flag names are spec-generated). Even read commands differ by name (`show` vs `list`, known issue #5), so confirm before running. 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
32
+
33
+ ```bash
34
+ wxcli whoami
35
+ ```
36
+
37
+ If this fails, stop and resolve authentication first (`wxcli configure`).
38
+
39
+ ### Required scopes by report type
40
+
41
+ | Report Type | Scope | Additional Requirements |
42
+ |-------------|-------|------------------------|
43
+ | CDR (Detailed Call History) | `spark-admin:calling_cdr_read` | Admin must have "Webex Calling Detailed Call History API access" role enabled in Control Hub |
44
+ | Report Templates & Reports | `analytics:read_all` | Read-only or full admin. Org must have **Pro Pack for Cisco Webex** license. |
45
+ | Converged Recordings | `spark-admin:telephony_config_read` | Admin recordings use `/admin/convergedRecordings` endpoint |
46
+ | Recording Reports | `spark-admin:telephony_config_read` | Audit reports for recording access |
47
+ | Partner Reports | `analytics:read_all` | Partner admin scope |
48
+ | **Contact Center stats** | `cjp:config_read` | **Use the `reporting-cc` skill instead** |
49
+ | **Meeting quality/analytics** | `analytics:read_all` | **Use the `reporting-meetings` skill instead** |
50
+
51
+ ### Scope verification gate
52
+
53
+ After identifying the report type (Step 3), verify the token has the required scope:
54
+ - **CDR:** Run `wxcli cdr list --start-time <recent> --end-time <recent> -o json` — if 403, token lacks `spark-admin:calling_cdr_read`
55
+ - **Reports/Templates:** Run `wxcli report-templates list -o json` — if 403, token lacks `analytics:read_all` or org lacks Pro Pack
56
+ - **Recordings:** Run `wxcli converged-recordings list --limit 1 -o json` — if 403, token lacks `spark-admin:telephony_config_read`
57
+ - **Do not proceed to Step 4 until the required scope is confirmed.**
58
+
59
+ ## Step 3: Identify the reporting need
60
+
61
+ Ask the user what they want to analyze. Present this decision matrix if they are unsure:
62
+
63
+ | Need | Report Type | CLI Group |
64
+ |------|-------------|-----------|
65
+ | Recent call logs (who called whom, when, duration, outcome) | **CDR / Detailed Call History** | `wxcli cdr` |
66
+ | Any question about calls (volume, performance, devices, trunks, etc.) | **CDR + Recipe** | `wxcli cdr` + Python analysis |
67
+ | Call queue performance (wait times, abandonment, volume) | **Call Queue Stats report** | `wxcli reports` + `wxcli report-templates` |
68
+ | Per-agent queue performance (handle time, calls handled) | **Call Queue Agent Stats report** | `wxcli reports` + `wxcli report-templates` |
69
+ | Auto attendant call volumes and menu usage | **AA Stats report** | `wxcli reports` + `wxcli report-templates` |
70
+ | Call quality (jitter, latency, packet loss) | **Calling Quality / Media Quality report** | `wxcli reports` + `wxcli report-templates` |
71
+ | Call recordings (list, download, manage) | **Converged Recordings** | `wxcli converged-recordings` |
72
+ | Recording access audit | **Recording Reports** | `wxcli recording-report` |
73
+ | Partner-level report generation | **Partner Reports** | `wxcli partner-reports` |
74
+ | Contact Center queue/agent stats | **→ Use `reporting-cc` skill** | CC-scoped OAuth required |
75
+ | Meeting quality, workspace metrics | **→ Use `reporting-meetings` skill** | Standard admin scopes |
76
+
77
+ ## Step 4: Check prerequisites
78
+
79
+ ### Date range validation
80
+ - CDR Feed/Stream: max 12-hour window per request, data available for last 30 days only
81
+ - Reports API: date range depends on template's `max_days` value, format is `YYYY-MM-DD`
82
+ - Confirm the user's desired date range fits within these constraints; split into multiple requests if needed
83
+
84
+ ### Data availability
85
+ - CDR has a minimum 5-minute delay; recent calls may not appear yet
86
+ - Reports are async (CSV generation takes minutes to hours depending on data volume)
87
+ - Converged recordings require the recording feature to be enabled on the org
88
+
89
+ ## Step 5: Build and present deployment plan — [SHOW BEFORE EXECUTING]
90
+
91
+ Present the following to the user before executing any queries:
92
+
93
+ ```
94
+ REPORTING PLAN
95
+ ==============
96
+ Report type: {CDR / Queue Stats / AA Stats / Call Quality / Recordings}
97
+ Date range: {start} to {end}
98
+ Filters: {location, user, direction, etc.}
99
+ Commands: {list of wxcli commands to run}
100
+ Analysis plan: {which recipe(s) or composition to apply}
101
+ Expected output: {table, JSON, summary stats}
102
+ ```
103
+
104
+ **DO NOT execute until the user approves this plan.**
105
+
106
+ ## Step 6: Execute via wxcli
107
+
108
+ ### 6a. CDR / Detailed Call History
109
+
110
+ #### CDR Feed (batch/historical)
111
+
112
+ ```bash
113
+ wxcli cdr list --start-time "2026-04-10T14:00:00.000Z" --end-time "2026-04-10T16:00:00.000Z" -o json
114
+ ```
115
+
116
+ #### CDR Stream (near-real-time)
117
+
118
+ CDR Stream uses **database write time** (not call start time), has a **2-hour max window** and **12-hour retention**. Use it for near-real-time monitoring or to catch late-arriving records that Feed may miss.
119
+
120
+ ```bash
121
+ wxcli cdr list-cdr_stream --start-time "2026-04-10T14:00:00.000Z" --end-time "2026-04-10T16:00:00.000Z" -o json
122
+ ```
123
+
124
+ #### Filter by location
125
+
126
+ ```bash
127
+ wxcli cdr list --start-time START --end-time END --locations "San Jose,Austin" -o json
128
+ ```
129
+
130
+ #### Multi-pull merge pattern (windows >12 hours)
131
+
132
+ CDR Feed allows a maximum 12-hour window per request. For longer ranges (e.g., "yesterday" = 24h, "this week" = ~4 days), issue sequential 12-hour pulls and merge the results before running any recipe. Rate limit: 1 request/minute — budget ~1 min per pull.
133
+
134
+ **Example: yesterday (24h = 2 pulls)**
135
+ ```bash
136
+ wxcli cdr list --start-time "2026-04-16T00:00:00.000Z" --end-time "2026-04-16T12:00:00.000Z" -o json > /tmp/cdr_p1.json
137
+ wxcli cdr list --start-time "2026-04-16T12:00:00.000Z" --end-time "2026-04-17T00:00:00.000Z" -o json > /tmp/cdr_p2.json
138
+ python3.11 -c "
139
+ import json
140
+ data = json.load(open('/tmp/cdr_p1.json')) + json.load(open('/tmp/cdr_p2.json'))
141
+ json.dump(data, open('/tmp/cdr-session.json','w'))
142
+ print(f'Merged: {len(data)} records')
143
+ "
144
+ # Now pipe /tmp/cdr-session.json to any recipe
145
+ cat /tmp/cdr-session.json | python3.11 -c "import json,sys; data=json.load(sys.stdin); ..."
146
+ ```
147
+
148
+ **Window count by range:**
149
+ | Range | 12h windows | ~Time at 1 req/min |
150
+ |-------|-------------|-------------------|
151
+ | 24h (yesterday) | 2 | ~2 min |
152
+ | 48h (2 days) | 4 | ~4 min |
153
+ | 4 days (this week Mon–Thu) | 8 | ~8 min |
154
+ | 7 days | 14 | ~14 min |
155
+
156
+ Surface the pull count and estimated wait time in your plan before executing.
157
+
158
+ ## CDR Query Composition Guide
159
+
160
+ Use this guide to construct CDR queries for ANY natural-language question. The recipes below cover common patterns — for questions not covered by a recipe, compose a query using the field taxonomy, composition rules, and output patterns.
161
+
162
+ **All recipes follow this execution pattern:**
163
+ 1. Pull CDR data: `wxcli cdr list --start-time START --end-time END -o json`
164
+ 2. Pipe to Python: `| python3.11 -c "import json, sys; data = json.load(sys.stdin); ..."`
165
+ 3. Filter, aggregate, and print results
166
+
167
+ **Time window rules:**
168
+ - Replace START/END with ISO 8601 timestamps: `2026-04-10T14:00:00.000Z`
169
+ - **CDR Feed** (`wxcli cdr list`): 12-hour max window, 30-day retention, timestamps = call start time
170
+ - **CDR Stream** (`wxcli cdr list-cdr_stream`): 2-hour max window, 12-hour retention, timestamps = database write time
171
+ - All recipes use CDR Feed unless noted otherwise
172
+ - Data available for the last 30 days (Feed) or 12 hours (Stream), with a minimum 5-minute delay
173
+ - Add `--locations "Name1,Name2"` to filter by location (up to 10)
174
+ - `--limit` is not supported for CDR: `wxcli cdr list` auto-paginates and always returns all records in the window regardless of `--limit`. To get a small sample, use a short time window (30 minutes) instead of relying on `--limit`.
175
+
176
+ ### CDR Call Leg Model
177
+
178
+ Every call generates one CDR record per **call leg** (one per participant perspective). Understanding leg relationships is essential for correct recipe logic:
179
+
180
+ - **Correlation ID** groups all legs of one call. A simple call has 2 legs (ORIGINATING + TERMINATING) sharing one Correlation ID.
181
+ - **Hunt Group / Call Queue**: All CDRs for the interaction share the **same Correlation ID**. The HG appears in CDRs **twice per ring attempt**: as TERMINATING (HG "receives" the inbound call — one total) and as ORIGINATING (HG "dials" each agent — one per ring attempt), each ORIGINATING paired with an agent TERMINATING. A HG call with 3 ring attempts = 1 inbound ORIGINATING + 1 HG TERMINATING + 3×(HG ORIGINATING + agent TERMINATING) = 8 CDRs. `Answered=Yes` on a HuntGroup CDR means the HG processed the call — **not that a human answered**.
182
+ - **Attended (consultative) transfer**: creates a second call with a new Correlation ID. `Transfer related call ID` on the bridging CDRs contains a **`Local call ID`** from the other call group — NOT the other call's Correlation ID. Linking rule: if `CDR1.'Transfer related call ID'` = `CDR2.'Local call ID'`, their Correlation IDs are linked.
183
+ - **Blind transfer**: creates a new call with a new Correlation ID. `Transfer related call ID` is **NOT populated** — blind transfers cannot be linked to the original call via this field.
184
+ - **Related Call ID**: deflection chaining key. Each HG ring attempt's ORIGINATING CDR has `Related call ID` = the HG's TERMINATING CDR's `Local call ID`. This chains each agent delivery back to the HG that distributed it. Also used when service activation (recording, exec-assistant) spawns a new separate call.
185
+ - **Direction**: ORIGINATING = the party who placed/initiated the leg. TERMINATING = the party who received it. The HG itself generates BOTH directions (see HG pattern above).
186
+ - **Answer indicator**: `Yes` on answered legs, `No` on unanswered. In a HG with 5 ring attempts: HG TERMINATING = `Yes` (HG processed it), only the answering agent's HG ORIGINATING + agent TERMINATING pair = `Yes`; all other agent attempts = `No`.
187
+
188
+ See `docs/reference/reporting-analytics.md` § CDR Data Model for the full reference including diagrams and all enum values.
189
+
190
+ ### Field Taxonomy
191
+
192
+ CDR returns 55+ fields with space-separated JSON keys. Use this taxonomy to find the right fields:
193
+
194
+ | Category | Fields (JSON keys) | Answers |
195
+ |----------|-------------------|---------|
196
+ | **Timing** | `Start time`, `Answer time`, `Duration`, `Ring duration`, `Hold duration`, `Release time` | "how long", "when", "average duration" |
197
+ | **Outcome** | `Answer indicator` (Yes/No/Yes-PostRedirection), `Call outcome` (Success/Failure/Refusal), `Call outcome reason`, `Releasing party` (Local/Remote/Unknown), `Answered elsewhere` | "what happened", "who hung up" |
198
+ | **Party** | `Calling number`, `Called number`, `User`, `User number`, `User type`, `Caller ID number`, `Dialed digits`, `Department ID` | "who called", "which user" |
199
+ | **Routing** | `Direction` (ORIGINATING/TERMINATING), `Call type` (SIP_ENTERPRISE/SIP_NATIONAL/SIP_INTERNATIONAL/SIP_TOLLFREE/SIP_PREMIUM/SIP_MOBILE/SIP_EMERGENCY), `Original reason`, `Redirect reason`, `Related reason`, `Route group` | "inbound or outbound", "was it forwarded" |
200
+ | **Infrastructure** | `Inbound trunk`, `Outbound trunk`, `Client type` (SIP/WXC_CLIENT/WXC_DEVICE/WXC_THIRD_PARTY/TEAMS_WXC_CLIENT/WXC_SIP_GW), `Client version`, `Model`, `Device MAC`, `OS type`, `Sub client type` | "which trunk", "what device" |
201
+ | **Location** | `Location`, `Site main number`, `Site timezone`, `Site UUID` | "which office" |
202
+ | **PSTN** | `PSTN vendor name`, `PSTN legal entity`, `PSTN provider ID`, `International country`, `Authorization code` | "which carrier", "cost" |
203
+ | **Recording** | `Call Recording Platform Name`, `Call Recording Result` (successful/failed/successful but not kept), `Call Recording Trigger` (always/always-pause-resume/on-demand/on-demand-user-start) | "was it recorded" |
204
+ | **Reputation** | `Caller Reputation Score` (0.0-5.0), `Caller Reputation Service Result` (allow/block/captcha-allow/captcha-block), `Caller Reputation Score Reason` | "spam calls" |
205
+ | **Queue/AA** | `Queue type` (Customer Assist/Call Queue), `Auto Attendant Key Pressed` | "queue CDR data", "AA menu" |
206
+ | **Correlation** | `Correlation ID`, `Call ID`, `Interaction ID`, `Local call ID` (this CDR's identity), `Remote call ID` (paired CDR's local ID), `Network call ID` (secondary leg-pairing key), `Related call ID` (deflection chain: ORIGINATING.relatedCallId = source TERMINATING.localCallId), `Transfer related call ID` (contains a localCallId from the other transfer call group — NOT a Correlation ID) | "trace this call", "link legs", "follow transfer" |
207
+
208
+ ### Composition Rules
209
+
210
+ | User Says | Python Translation |
211
+ |-----------|-------------------|
212
+ | "How many [calls that X]" | `filtered = [r for r in data if COND]; len(filtered)` |
213
+ | "Average / mean [metric]" | `vals = [int(r.get(F,0)) for r in data if COND]; sum(vals)/len(vals) if vals else 0` |
214
+ | "Longest / max / worst" | `max(vals) if vals else 0` |
215
+ | "By [field]" / "per [field]" | `Counter(r.get(F) for r in data)` |
216
+ | "[X] that then [Y]" | Chain: `[r for r in data if COND_A and COND_B]` |
217
+ | "Over the last N hours" | Compute start/end from `datetime.now(timezone.utc) - timedelta(hours=N)` |
218
+ | "Top N" / "worst N" | `Counter(...).most_common(N)` |
219
+ | "Percentage" / "rate" | `len(subset) / len(total) * 100` |
220
+ | "Per hour" / "hourly" | `Counter(r.get('Start time','')[:13] for r in data)` |
221
+ | "Per day" / "daily" | `Counter(r.get('Start time','')[:10] for r in data)` |
222
+ | "Trend" / "compare" | Two CDR pulls, compare counts |
223
+ | "Which [X] has worst/best" | Group-by + aggregate + sort |
224
+
225
+ ### Output Patterns
226
+
227
+ **A — Count:** `len([r for r in data if COND])`
228
+
229
+ **B — Top-N:** `Counter(r.get(F) for r in data).most_common(N)`
230
+
231
+ **C — Time-series:** `Counter(r.get('Start time','')[:13] for r in data)` then `sorted()`
232
+
233
+ **D — Cross-tab:** `Counter((r.get(F1), r.get(F2)) for r in data)`
234
+
235
+ **E — Percentage:** `len(subset) / len(total) * 100`
236
+
237
+ **F — Threshold:** `[r for r in data if int(r.get(F, 0)) > T]`
238
+
239
+ **G — Chained filter:** `[r for r in data if COND_A and COND_B and COND_C]`
240
+
241
+ **H — Aggregation:** `sum(vals)/len(vals) if vals else 0` / `max(vals) if vals else 0` / `min(vals) if vals else 0`
242
+
243
+ ### Recipe Catalog — 75 recipes across 11 categories
244
+
245
+ The full recipe catalog lives in `references/cdr-recipes.md` (relative to this skill). **Do not inline it here — read it on demand** when you need a specific recipe, then adapt the snippet using the Field Taxonomy and Composition Rules above. For questions no recipe covers, compose a query from the Output Patterns above.
246
+
247
+ | # | Category | Recipes | Covers |
248
+ |---|----------|---------|--------|
249
+ | 1 | Call Volume & Traffic | 1–8 | total count, by location/hour/day/type, inbound vs outbound, peak hour, trend |
250
+ | 2 | Call Outcomes & Quality | 9–16 | missed/failed/abandoned, answer rate, outcome reason, short calls, long-ring no-answer |
251
+ | 3 | Hold & Wait Time | 17–24 | avg hold, excessive hold (>30s/>60s), hold-then-abandon, ring duration, hold by user |
252
+ | 4 | User & Agent Performance | 25–32 | top talkers, calls/duration per user, missed per user, answer rate, international, after-hours |
253
+ | 5 | Trunk & Routing | 33–39 | calls per trunk, utilization by hour, route groups, redirect/original reason, forwarding loops |
254
+ | 6 | PSTN & Billing | 40–46 | by vendor, duration by vendor, international by country, call-type mix, auth codes, vendor comparison |
255
+ | 7 | Device & Client | 47–52 | client type, device model inventory, OS type, softphone vs desk, Webex Go mobile, client version |
256
+ | 8 | Spam & Reputation | 53–57 | reputation score distribution, blocked vs allowed, top blocked numbers, spam by location, captcha |
257
+ | 9 | Recording Compliance | 58–63 | success rate, by platform, by trigger, failed recordings, unrecorded analysis, compliance by location |
258
+ | 10 | Call Tracing & Diagnostics | 64–69 | trace by correlation ID, transfer chains, park/retrieve, forwarding path, quality proxy, repeat callers |
259
+ | 11 | Cross-Category Compound | 70–75 | multi-filter queries combining dimensions from other categories: spam→queue→abandon, international calls on a trunk during business hours, forwarded-twice→voicemail, missed calls from repeat callers, long-hold calls that were transferred, after-hours emergency (look here when a question crosses trunk + call-type + time, etc., not just one category) |
260
+
261
+ **To find a recipe:** `grep -nE '^### Category|^\*\*Recipe' .claude/skills/reporting/references/cdr-recipes.md` for the full list, or grep by keyword (e.g. `grep -ni "emergency" .claude/skills/reporting/references/cdr-recipes.md`).
262
+
263
+ ### 6b. Reports API (async CSV reports)
264
+
265
+ Use the Reports API for queue stats, AA stats, call quality, and engagement reports. These are generated asynchronously as CSV files.
266
+
267
+ #### Discover templates
268
+
269
+ ```bash
270
+ wxcli report-templates list -o json
271
+ ```
272
+
273
+ Look for templates by name: "Call Queue Stats", "Call Queue Agent Stats", "Auto-attendant Stats Summary", "Calling Media Quality", "Calling Quality", "Calling Engagement".
274
+
275
+ #### Create a report
276
+
277
+ ```bash
278
+ wxcli reports create --template-id TEMPLATE_ID --start-date "2026-04-01" --end-date "2026-04-10"
279
+ ```
280
+
281
+ Template IDs are org-specific — always discover them at runtime. Date format is `YYYY-MM-DD`.
282
+
283
+ #### Poll status
284
+
285
+ ```bash
286
+ wxcli reports show REPORT_ID -o json
287
+ ```
288
+
289
+ Poll until `status` is `"done"`. The response will include `downloadURL` for the CSV ZIP file.
290
+
291
+ #### Download the CSV
292
+
293
+ ```bash
294
+ curl -H "Authorization: Bearer $WEBEX_ACCESS_TOKEN" -o report.zip "DOWNLOAD_URL"
295
+ unzip report.zip
296
+ ```
297
+
298
+ #### Delete the report (free quota — max 50 reports)
299
+
300
+ ```bash
301
+ wxcli reports delete REPORT_ID --force
302
+ ```
303
+
304
+ #### Standard report templates
305
+
306
+ | Template Name | Description |
307
+ |---------------|-------------|
308
+ | Detailed Call History | Comprehensive call log (all CDR fields) |
309
+ | Calling Media Quality | Per-call-leg quality (latency, jitter, packet loss) |
310
+ | Calling Engagement | Usage and adoption tracking |
311
+ | Calling Quality | Client-side quality from Webex Calling app |
312
+ | Call Queue Stats | Queue-level KPIs (volume, wait, abandonment) |
313
+ | Call Queue Agent Stats | Per-agent queue performance |
314
+ | Auto-attendant Stats Summary | AA call volume and handling |
315
+ | Auto-attendant Business & After-Hours Key Details | AA key-press patterns |
316
+
317
+ ### 6c. Converged recordings
318
+
319
+ #### List recordings
320
+
321
+ ```bash
322
+ wxcli converged-recordings list --from "2026-04-01T00:00:00Z" --to "2026-04-10T00:00:00Z" -o json
323
+ wxcli converged-recordings list-converged-recordings --owner-email user@company.com -o json
324
+ ```
325
+
326
+ #### Download artifacts
327
+
328
+ ```bash
329
+ wxcli converged-recordings download RECORDING_ID
330
+ wxcli converged-recordings download RECORDING_ID --include-audio
331
+ ```
332
+
333
+ #### Bulk export for BI
334
+
335
+ ```bash
336
+ wxcli converged-recordings export --from "2026-04-01T00:00:00Z" --to "2026-04-10T00:00:00Z"
337
+ wxcli converged-recordings export --from START --to END --owner-email user@company.com --include-audio
338
+ ```
339
+
340
+ #### Recording audit
341
+
342
+ ```bash
343
+ wxcli recording-report list -o json
344
+ wxcli recording-report list-access-detail --recording-id RECORDING_ID -o json
345
+ ```
346
+
347
+ ## Step 7: Session Pattern — Pull Once, Query Many
348
+
349
+ CDR pulls are slow due to the CDR API rate limit (1 request/minute) and the 12-hour max window per request. A 7-day pull requires 14 sequential requests = ~14 minutes. This section prevents redundant pulls and sets correct user expectations.
350
+
351
+ ### Rate limit reality
352
+
353
+ The CDR Feed API (`analytics-calling.webexapis.com`) enforces **1 request per minute** per user token. wxcli's `wxcli cdr list` respects this limit with built-in sleep between requests, so each pull takes ~60 seconds regardless of data volume. Calculate expected pull time before starting:
354
+
355
+ | Window | Pulls | Expected Time |
356
+ |--------|-------|---------------|
357
+ | ≤12h | 1 | ~1 min |
358
+ | 12–24h | 2 | ~2 min |
359
+ | 1–3 days | 2–6 | ~2–6 min |
360
+ | 7 days | 14 | ~14 min |
361
+ | 30 days | 60 | ~60 min — use Reports API instead |
362
+
363
+ **For windows >24 hours:** Tell the user the expected pull time before starting. Example: "A 7-day CDR pull requires 14 API requests at ~1/minute = approximately 14 minutes. Proceed?"
364
+
365
+ **For windows >7 days:** Recommend the Reports API (Detailed Call History template) instead — it's async but handles up to 30 days in a single request with no per-minute rate limit. Requires `analytics:read_all` scope and Pro Pack. If the org lacks Pro Pack, CDR Feed is the only option — warn about the wait time.
366
+
367
+ ### Two-phase split
368
+
369
+ 1. **Pull phase** — requires `wxc-calling-builder` agent (wxcli hook blocks direct CLI calls). The caller (Claude's main context) spawns the builder agent with instructions to pull CDR data and save to `/tmp/cdr-session.json`. The builder agent handles multi-pull merge for windows >12h automatically. Once the file is written, the builder agent's job is done — do not keep it running.
370
+ 2. **Recipe phase** — runs directly via Bash, no agent spawn needed. `cat /tmp/cdr-session.json | python3.11 -c "..."` executes in ~2 seconds. The skill guides recipe selection; Claude executes inline.
371
+
372
+ ### Pull phase instructions for builder agent
373
+
374
+ When spawning the builder agent for CDR pulls, include these instructions in the prompt:
375
+
376
+ 1. **Progress output:** After each window, print: `echo "✓ Window N/TOTAL: START → END (X records)" >&2`
377
+ 2. **Error handling:** Use this pattern for each pull to prevent 0-byte files on API errors:
378
+ ```bash
379
+ wxcli cdr list --start-time START --end-time END -o json > /tmp/cdr_wNN.json 2>/tmp/cdr_err.log
380
+ if [ ! -s /tmp/cdr_wNN.json ]; then echo "[]" > /tmp/cdr_wNN.json; fi
381
+ ```
382
+ 3. **Merge:** After all pulls complete, merge with Python and write `/tmp/cdr-session.json`.
383
+ 4. **Run foreground, not background:** CDR pulls take minutes. Run the builder agent in the foreground so its progress output streams to the user. Do NOT use `run_in_background`.
384
+
385
+ ### Cache file format
386
+
387
+ The pull phase writes `/tmp/cdr-session.json` as a JSON object:
388
+ ```json
389
+ {"_meta": {"start": "2026-04-10T00:00:00.000Z", "end": "2026-04-13T00:00:00.000Z", "pulled": "2026-04-13T12:34:56Z", "records": 1847}, "data": [ ...CDR records... ]}
390
+ ```
391
+
392
+ Recipes read from the `data` array: `data = json.load(sys.stdin)['data']`
393
+
394
+ ### Cache decision logic
395
+
396
+ On every CDR question:
397
+
398
+ 1. **Check** — does `/tmp/cdr-session.json` exist? Read `_meta.start`, `_meta.end`.
399
+ 2. **Cache hit** — requested window is within `_meta` boundaries → run recipe directly via Bash. No agent spawn.
400
+ 3. **Cache miss** — requested window extends beyond `_meta` boundaries, or file doesn't exist, or user says "refresh" → spawn `wxc-calling-builder` to re-pull (foreground). Builder overwrites the cache file with the new window.
401
+ 4. **Explicit refresh** — if the user says "refresh", "re-pull", or "new data", always re-pull regardless of cache state.
402
+
403
+ ### Presentation Rules
404
+
405
+ **Rule 1 — Format what the recipe prints.**
406
+ Present all columns the recipe outputs. The `# Output:` comment above each recipe's bash block tells you exactly what columns to expect. Never collapse to 2 columns if the recipe produces more.
407
+
408
+ **Rule 2 — Collapse to prose when ≤ 2 rows.**
409
+ A table with 1–2 rows is worse than a sentence.
410
+ - ✅ "All 10 calls came from HQ (10/10)."
411
+ - ❌ | Location | Total | ... | / | HQ | 10 | ...
412
+
413
+ **Rule 3 — Adapt to the user's question framing.**
414
+
415
+ | User says | Format |
416
+ |---|---|
417
+ | "how many", "what's the count" | Lead with the number inline; table is secondary or omitted |
418
+ | "show me", "list", "breakdown", "by X" | Table is primary |
419
+ | "analyze", "what do you see", "explain" | Narrative with numbers embedded inline |
420
+ | "compare" | Two-row side-by-side if two windows; sorted table otherwise |
421
+
422
+ **Rule 4 — One summary line above every table.**
423
+ e.g., "5 missed calls out of 247 total (2.0%)" — always present, even for large tables.
424
+
425
+ **Rule 5 — Timestamps trimmed to YYYY-MM-DD HH:MM.** Drop seconds and timezone.
426
+
427
+ **Rule 6 — No unsolicited commentary.**
428
+ No analysis, recommendations, or data quality notes below the table unless the user asks "why", "what do you see", or "analyze this".
429
+
430
+ ### Recipe adaptation for cached data
431
+
432
+ When running recipes against the cache file, adapt the standard recipe pattern:
433
+ ```bash
434
+ # Standard (from pull): wxcli cdr list ... -o json | python3.11 -c "..."
435
+ # Cached: read from file, access the 'data' array
436
+ cat /tmp/cdr-session.json | python3.11 -c "import json,sys; raw=json.load(sys.stdin); data=raw['data']; ..."
437
+ ```
438
+
439
+ All 75 recipes work unchanged except: replace `data = json.load(sys.stdin)` with `data = json.load(sys.stdin)['data']`.
440
+
441
+ ## Step 8: Verify
442
+
443
+ After retrieving data, verify the results make sense and present key findings.
444
+
445
+ ```bash
446
+ # Quick CDR sanity check
447
+ wxcli cdr list --start-time START --end-time END -o json | python3.11 -c "import json,sys; data=json.load(sys.stdin); print(f'Records: {len(data)}')"
448
+
449
+ # Quick report templates check
450
+ wxcli report-templates list -o json | python3.11 -c "import json,sys; data=json.load(sys.stdin); print(f'Templates: {len(data)}')"
451
+ ```
452
+
453
+ ## Step 9: Report results
454
+
455
+ Present findings using the Step 7 presentation format: one-line summary + markdown table. No unsolicited recommendations or data quality commentary unless the user asks.
456
+
457
+ For non-CDR results (Reports API, recordings), use:
458
+ - **Data retrieved:** Report type, date range, record count
459
+ - **Key findings:** Top metrics, trends, anomalies discovered
460
+ - **Cleanup reminders:** Delete reports to free quota if applicable
461
+
462
+ ---
463
+
464
+ ## Critical Rules
465
+
466
+ 1. **CDR is NOT real-time.** Minimum 5-minute delay. Data may take up to 24 hours to fully populate.
467
+ 2. **12-hour maximum query window.** For longer ranges, issue multiple sequential requests.
468
+ 3. **30-day data retention.** Older data must come from Reports API (CSV).
469
+ 4. **Date format:** CDR uses ISO 8601 with milliseconds: `2026-04-10T14:00:00.000Z`. Reports API uses `YYYY-MM-DD`.
470
+ 5. **Regional endpoints.** CDR HTTP 451 means wrong region — response body has the correct URL.
471
+ 6. **Rate limits:** CDR Feed enforces 1 request/minute per user token (+ 10 pagination/minute). A 7-day pull = 14 requests = ~14 minutes. Always tell the user the expected wait time before starting. For windows >7 days, recommend the Reports API instead.
472
+ 7. **Report quota: max 50.** Always delete reports after downloading.
473
+ 8. **Pro Pack required for Reports API.** CDR Feed does NOT require Pro Pack.
474
+ 9. **Template IDs are org-specific.** Never hardcode — discover at runtime.
475
+ 10. **Reports are async CSV/ZIP.** Poll `wxcli reports show REPORT_ID` until `status` is `"done"`.
476
+ 11. **CDR field names use spaces.** `"Start time"`, `"Call outcome reason"` — use exact names in Python.
477
+ 12. **Location filter uses names, not IDs.** Up to 10, comma-separated.
478
+ 13. **Recording management is destructive.** `create-purge` is permanent. Always confirm.
479
+ 14. **Converged recordings scope split.** User-level: `wxcli converged-recordings list`. Admin: `wxcli converged-recordings list-converged-recordings`.
480
+
481
+ ---
482
+
483
+ ## Scope Quick Reference
484
+
485
+ | Scope | Grants Access To |
486
+ |-------|-----------------|
487
+ | `spark-admin:calling_cdr_read` | CDR Feed and Stream |
488
+ | `analytics:read_all` | Report Templates, Reports, Partner Reports |
489
+ | `spark-admin:locations_read` | Location name filtering on CDR |
490
+ | `spark-admin:telephony_config_read` | Converged recordings read |
491
+ | `spark-admin:telephony_config_write` | Recording management (reassign, delete, purge) |
492
+ | `spark-compliance:recordings_read` | Compliance officer recording access |
493
+
494
+ ---
495
+
496
+ ## Context Compaction Recovery
497
+
498
+ If context compacts mid-execution:
499
+ 1. Read `docs/reference/reporting-analytics.md` to recover field references
500
+ 2. Check what data has already been retrieved by reviewing recent command output
501
+ 3. Review Steps 1-8 and resume from the first incomplete step