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.
- wxcli/__init__.py +4 -0
- wxcli/_playbook/.claude/agents/migration-advisor.md +239 -0
- wxcli/_playbook/.claude/agents/wxc-calling-builder.md +946 -0
- wxcli/_playbook/.claude/rules/cleanup.md +29 -0
- wxcli/_playbook/.claude/rules/cucm-migration.md +58 -0
- wxcli/_playbook/.claude/rules/org-health.md +14 -0
- wxcli/_playbook/.claude/settings.json +8 -0
- wxcli/_playbook/.claude/skills/audit-compliance/SKILL.md +515 -0
- wxcli/_playbook/.claude/skills/call-control/SKILL.md +747 -0
- wxcli/_playbook/.claude/skills/configure-features/SKILL.md +623 -0
- wxcli/_playbook/.claude/skills/configure-routing/SKILL.md +627 -0
- wxcli/_playbook/.claude/skills/contact-center/SKILL.md +1181 -0
- wxcli/_playbook/.claude/skills/cucm-migrate/SKILL.md +820 -0
- wxcli/_playbook/.claude/skills/customer-assist/SKILL.md +443 -0
- wxcli/_playbook/.claude/skills/device-platform/SKILL.md +407 -0
- wxcli/_playbook/.claude/skills/manage-call-settings/SKILL.md +757 -0
- wxcli/_playbook/.claude/skills/manage-devices/SKILL.md +790 -0
- wxcli/_playbook/.claude/skills/manage-identity/SKILL.md +638 -0
- wxcli/_playbook/.claude/skills/manage-licensing/SKILL.md +528 -0
- wxcli/_playbook/.claude/skills/manage-meetings/SKILL.md +708 -0
- wxcli/_playbook/.claude/skills/messaging-bots/SKILL.md +365 -0
- wxcli/_playbook/.claude/skills/messaging-spaces/SKILL.md +520 -0
- wxcli/_playbook/.claude/skills/org-health/SKILL.md +159 -0
- wxcli/_playbook/.claude/skills/provision-calling/SKILL.md +421 -0
- wxcli/_playbook/.claude/skills/query-live/SKILL.md +183 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-flow-trace.md +223 -0
- wxcli/_playbook/.claude/skills/query-live/domains/call-history.md +44 -0
- wxcli/_playbook/.claude/skills/query-live/domains/features.md +169 -0
- wxcli/_playbook/.claude/skills/query-live/domains/numbers.md +93 -0
- wxcli/_playbook/.claude/skills/query-live/domains/people-and-settings.md +146 -0
- wxcli/_playbook/.claude/skills/query-live/domains/routing.md +124 -0
- wxcli/_playbook/.claude/skills/reporting/SKILL.md +501 -0
- wxcli/_playbook/.claude/skills/reporting/references/cdr-recipes.md +1628 -0
- wxcli/_playbook/.claude/skills/reporting-cc/SKILL.md +251 -0
- wxcli/_playbook/.claude/skills/reporting-meetings/SKILL.md +290 -0
- wxcli/_playbook/.claude/skills/teardown/SKILL.md +214 -0
- wxcli/_playbook/.claude/skills/video-mesh/SKILL.md +379 -0
- wxcli/_playbook/.claude/skills/wxc-calling-debug/SKILL.md +475 -0
- wxcli/_playbook/CLAUDE.md +373 -0
- wxcli/_playbook/docs/reference/CLAUDE.md +25 -0
- wxcli/_playbook/docs/reference/admin-apps-data.md +643 -0
- wxcli/_playbook/docs/reference/admin-audit-security.md +322 -0
- wxcli/_playbook/docs/reference/admin-hybrid.md +383 -0
- wxcli/_playbook/docs/reference/admin-identity-scim.md +1007 -0
- wxcli/_playbook/docs/reference/admin-licensing.md +414 -0
- wxcli/_playbook/docs/reference/admin-org-management.md +586 -0
- wxcli/_playbook/docs/reference/admin-partner.md +357 -0
- wxcli/_playbook/docs/reference/archive/wxc-sdk-patterns.md +1229 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-advanced.md +835 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-core.md +743 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-devices-workspaces.md +1305 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-features.md +849 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-locations.md +938 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-person.md +1255 -0
- wxcli/_playbook/docs/reference/archive/wxcadm-routing.md +1262 -0
- wxcli/_playbook/docs/reference/authentication.md +965 -0
- wxcli/_playbook/docs/reference/call-control.md +1205 -0
- wxcli/_playbook/docs/reference/call-features-additional.md +2541 -0
- wxcli/_playbook/docs/reference/call-features-major.md +1320 -0
- wxcli/_playbook/docs/reference/call-routing.md +2304 -0
- wxcli/_playbook/docs/reference/contact-center-analytics.md +1049 -0
- wxcli/_playbook/docs/reference/contact-center-core.md +1614 -0
- wxcli/_playbook/docs/reference/contact-center-journey.md +457 -0
- wxcli/_playbook/docs/reference/contact-center-routing.md +1138 -0
- wxcli/_playbook/docs/reference/devices-core.md +1869 -0
- wxcli/_playbook/docs/reference/devices-dect.md +1150 -0
- wxcli/_playbook/docs/reference/devices-platform.md +467 -0
- wxcli/_playbook/docs/reference/devices-workspaces.md +1426 -0
- wxcli/_playbook/docs/reference/emergency-services.md +1122 -0
- wxcli/_playbook/docs/reference/location-calling-core.md +2037 -0
- wxcli/_playbook/docs/reference/location-calling-media.md +1334 -0
- wxcli/_playbook/docs/reference/location-recording-advanced.md +1482 -0
- wxcli/_playbook/docs/reference/meetings-content.md +473 -0
- wxcli/_playbook/docs/reference/meetings-core.md +903 -0
- wxcli/_playbook/docs/reference/meetings-infrastructure.md +899 -0
- wxcli/_playbook/docs/reference/meetings-settings.md +850 -0
- wxcli/_playbook/docs/reference/messaging-bots.md +1091 -0
- wxcli/_playbook/docs/reference/messaging-spaces.md +695 -0
- wxcli/_playbook/docs/reference/person-call-settings-behavior.md +1639 -0
- wxcli/_playbook/docs/reference/person-call-settings-handling.md +1394 -0
- wxcli/_playbook/docs/reference/person-call-settings-media.md +1898 -0
- wxcli/_playbook/docs/reference/person-call-settings-permissions.md +1329 -0
- wxcli/_playbook/docs/reference/provisioning.md +1366 -0
- wxcli/_playbook/docs/reference/reporting-analytics.md +1318 -0
- wxcli/_playbook/docs/reference/self-service-call-settings.md +1020 -0
- wxcli/_playbook/docs/reference/virtual-lines.md +1132 -0
- wxcli/_playbook/docs/reference/webhooks-events.md +1444 -0
- wxcli/_playbook/docs/reference/wxcadm-xsi-realtime.md +953 -0
- wxcli/_version.py +24 -0
- wxcli/auth.py +137 -0
- wxcli/commands/__init__.py +0 -0
- wxcli/commands/_registry.py +181 -0
- wxcli/commands/activation_email.py +103 -0
- wxcli/commands/admin_recordings.py +585 -0
- wxcli/commands/analytics.py +105 -0
- wxcli/commands/announcement_playlists.py +219 -0
- wxcli/commands/announcements.py +519 -0
- wxcli/commands/archive_users.py +36 -0
- wxcli/commands/attachment_actions.py +60 -0
- wxcli/commands/audit_events.py +83 -0
- wxcli/commands/authorizations.py +113 -0
- wxcli/commands/auto_attendant.py +642 -0
- wxcli/commands/broadworks_billing_reports.py +126 -0
- wxcli/commands/broadworks_enterprises.py +160 -0
- wxcli/commands/broadworks_subscribers.py +319 -0
- wxcli/commands/broadworks_workspaces.py +108 -0
- wxcli/commands/call_controls.py +1304 -0
- wxcli/commands/call_park.py +494 -0
- wxcli/commands/call_pickup.py +229 -0
- wxcli/commands/call_queue.py +1878 -0
- wxcli/commands/call_recording.py +707 -0
- wxcli/commands/call_routing.py +1610 -0
- wxcli/commands/call_settings_for_me_phase_5.py +212 -0
- wxcli/commands/caller_reputation.py +169 -0
- wxcli/commands/calling_service.py +305 -0
- wxcli/commands/cc_address_book.py +770 -0
- wxcli/commands/cc_agent_greetings.py +242 -0
- wxcli/commands/cc_agent_summaries.py +39 -0
- wxcli/commands/cc_agent_wellbeing.py +216 -0
- wxcli/commands/cc_agents.py +425 -0
- wxcli/commands/cc_ai_assistant.py +55 -0
- wxcli/commands/cc_ai_feature.py +294 -0
- wxcli/commands/cc_audio_files.py +149 -0
- wxcli/commands/cc_auto_csat.py +311 -0
- wxcli/commands/cc_aux_code.py +458 -0
- wxcli/commands/cc_business_hour.py +353 -0
- wxcli/commands/cc_call_monitoring.py +228 -0
- wxcli/commands/cc_callbacks.py +194 -0
- wxcli/commands/cc_campaign.py +212 -0
- wxcli/commands/cc_captures.py +39 -0
- wxcli/commands/cc_contact_list.py +169 -0
- wxcli/commands/cc_contact_number.py +295 -0
- wxcli/commands/cc_data_sources.py +235 -0
- wxcli/commands/cc_desktop_layout.py +380 -0
- wxcli/commands/cc_desktop_profile.py +322 -0
- wxcli/commands/cc_dial_number.py +511 -0
- wxcli/commands/cc_dial_plan.py +347 -0
- wxcli/commands/cc_dnc.py +101 -0
- wxcli/commands/cc_entry_point.py +545 -0
- wxcli/commands/cc_ewt.py +51 -0
- wxcli/commands/cc_flow.py +477 -0
- wxcli/commands/cc_global_vars.py +430 -0
- wxcli/commands/cc_holiday_list.py +335 -0
- wxcli/commands/cc_journey.py +1261 -0
- wxcli/commands/cc_legacy_flows.py +49 -0
- wxcli/commands/cc_multimedia_profile.py +436 -0
- wxcli/commands/cc_notification.py +51 -0
- wxcli/commands/cc_outdial_ani.py +604 -0
- wxcli/commands/cc_overrides.py +341 -0
- wxcli/commands/cc_queue.py +1083 -0
- wxcli/commands/cc_queue_stats.py +55 -0
- wxcli/commands/cc_realtime.py +51 -0
- wxcli/commands/cc_resource_collection.py +312 -0
- wxcli/commands/cc_search.py +46 -0
- wxcli/commands/cc_site.py +400 -0
- wxcli/commands/cc_skill.py +350 -0
- wxcli/commands/cc_skill_profile.py +289 -0
- wxcli/commands/cc_subscriptions.py +426 -0
- wxcli/commands/cc_summaries.py +130 -0
- wxcli/commands/cc_tasks.py +844 -0
- wxcli/commands/cc_team.py +325 -0
- wxcli/commands/cc_user_profiles.py +349 -0
- wxcli/commands/cc_users.py +701 -0
- wxcli/commands/cc_work_types.py +363 -0
- wxcli/commands/cdr.py +89 -0
- wxcli/commands/classifications.py +38 -0
- wxcli/commands/cleanup.py +1427 -0
- wxcli/commands/client_settings.py +72 -0
- wxcli/commands/conference.py +328 -0
- wxcli/commands/configure.py +72 -0
- wxcli/commands/converged_recordings.py +347 -0
- wxcli/commands/converged_recordings_export.py +310 -0
- wxcli/commands/cq_playlists.py +42 -0
- wxcli/commands/cucm.py +2794 -0
- wxcli/commands/cucm_config.py +129 -0
- wxcli/commands/customer_assist.py +373 -0
- wxcli/commands/data_sources.py +227 -0
- wxcli/commands/dect_devices.py +787 -0
- wxcli/commands/device_configurations.py +77 -0
- wxcli/commands/device_dynamic_settings.py +320 -0
- wxcli/commands/device_settings.py +1489 -0
- wxcli/commands/devices.py +280 -0
- wxcli/commands/domains.py +142 -0
- wxcli/commands/ecm.py +178 -0
- wxcli/commands/emergency_services.py +827 -0
- wxcli/commands/events.py +83 -0
- wxcli/commands/external_voicemail.py +52 -0
- wxcli/commands/groups.py +206 -0
- wxcli/commands/guest_management.py +76 -0
- wxcli/commands/hds.py +340 -0
- wxcli/commands/hot_desk.py +67 -0
- wxcli/commands/hot_desking_members.py +118 -0
- wxcli/commands/hot_desking_portal.py +124 -0
- wxcli/commands/hunt_group.py +577 -0
- wxcli/commands/hybrid_clusters.py +71 -0
- wxcli/commands/hybrid_connectors.py +67 -0
- wxcli/commands/identity_org.py +159 -0
- wxcli/commands/init_playbook.py +155 -0
- wxcli/commands/licenses.py +106 -0
- wxcli/commands/live_monitoring.py +40 -0
- wxcli/commands/location_call_handling.py +577 -0
- wxcli/commands/location_schedules.py +341 -0
- wxcli/commands/location_settings.py +1297 -0
- wxcli/commands/location_voicemail.py +494 -0
- wxcli/commands/locations.py +336 -0
- wxcli/commands/meeting_captions.py +110 -0
- wxcli/commands/meeting_chats.py +63 -0
- wxcli/commands/meeting_invitees.py +234 -0
- wxcli/commands/meeting_messages.py +28 -0
- wxcli/commands/meeting_participants.py +278 -0
- wxcli/commands/meeting_polls.py +111 -0
- wxcli/commands/meeting_preferences.py +515 -0
- wxcli/commands/meeting_qa.py +78 -0
- wxcli/commands/meeting_qualities.py +43 -0
- wxcli/commands/meeting_reports.py +101 -0
- wxcli/commands/meeting_session_types.py +105 -0
- wxcli/commands/meeting_site.py +57 -0
- wxcli/commands/meeting_slido.py +44 -0
- wxcli/commands/meeting_summaries.py +92 -0
- wxcli/commands/meeting_tracking_codes.py +233 -0
- wxcli/commands/meeting_transcripts.py +230 -0
- wxcli/commands/meetings.py +1997 -0
- wxcli/commands/memberships.py +164 -0
- wxcli/commands/messages.py +213 -0
- wxcli/commands/mode_management.py +244 -0
- wxcli/commands/my_call_settings.py +3577 -0
- wxcli/commands/numbers.py +405 -0
- wxcli/commands/operating_modes.py +410 -0
- wxcli/commands/org_contacts.py +284 -0
- wxcli/commands/org_health_cli.py +55 -0
- wxcli/commands/org_settings.py +71 -0
- wxcli/commands/organizations.py +83 -0
- wxcli/commands/paging_group.py +257 -0
- wxcli/commands/partner_admins.py +141 -0
- wxcli/commands/partner_reports.py +188 -0
- wxcli/commands/partner_tags.py +216 -0
- wxcli/commands/people.py +279 -0
- wxcli/commands/person_call_settings.py +71 -0
- wxcli/commands/pstn.py +280 -0
- wxcli/commands/recording_report.py +154 -0
- wxcli/commands/report_templates.py +38 -0
- wxcli/commands/reports.py +144 -0
- wxcli/commands/resource_group_memberships.py +160 -0
- wxcli/commands/resource_groups.py +67 -0
- wxcli/commands/roles.py +63 -0
- wxcli/commands/room_tabs.py +160 -0
- wxcli/commands/rooms.py +225 -0
- wxcli/commands/scim_bulk.py +46 -0
- wxcli/commands/scim_groups.py +246 -0
- wxcli/commands/scim_schemas.py +82 -0
- wxcli/commands/scim_users.py +283 -0
- wxcli/commands/security_audit.py +54 -0
- wxcli/commands/service_apps.py +51 -0
- wxcli/commands/single_number_reach.py +209 -0
- wxcli/commands/team_memberships.py +155 -0
- wxcli/commands/teams.py +153 -0
- wxcli/commands/ucm_profile.py +42 -0
- wxcli/commands/update.py +219 -0
- wxcli/commands/user_settings.py +5116 -0
- wxcli/commands/video_mesh.py +1090 -0
- wxcli/commands/virtual_extensions.py +502 -0
- wxcli/commands/virtual_line_settings.py +2072 -0
- wxcli/commands/webhooks.py +176 -0
- wxcli/commands/wholesale_billing_reports.py +147 -0
- wxcli/commands/wholesale_provisioning.py +523 -0
- wxcli/commands/workspace_locations.py +339 -0
- wxcli/commands/workspace_metrics.py +103 -0
- wxcli/commands/workspace_personalization.py +70 -0
- wxcli/commands/workspace_settings.py +3347 -0
- wxcli/commands/workspaces.py +279 -0
- wxcli/commands/xapi.py +114 -0
- wxcli/config.py +139 -0
- wxcli/errors.py +77 -0
- wxcli/main.py +210 -0
- wxcli/migration/CLAUDE.md +106 -0
- wxcli/migration/__init__.py +1 -0
- wxcli/migration/advisory/CLAUDE.md +196 -0
- wxcli/migration/advisory/__init__.py +46 -0
- wxcli/migration/advisory/advisor.py +107 -0
- wxcli/migration/advisory/advisory_patterns.py +2552 -0
- wxcli/migration/advisory/recommendation_rules.py +835 -0
- wxcli/migration/cucm/CLAUDE.md +74 -0
- wxcli/migration/cucm/__init__.py +5 -0
- wxcli/migration/cucm/connection.py +265 -0
- wxcli/migration/cucm/discovery.py +225 -0
- wxcli/migration/cucm/extractors/__init__.py +1 -0
- wxcli/migration/cucm/extractors/announcements.py +92 -0
- wxcli/migration/cucm/extractors/base.py +90 -0
- wxcli/migration/cucm/extractors/device_profiles.py +98 -0
- wxcli/migration/cucm/extractors/devices.py +193 -0
- wxcli/migration/cucm/extractors/e911.py +103 -0
- wxcli/migration/cucm/extractors/features.py +309 -0
- wxcli/migration/cucm/extractors/helpers.py +73 -0
- wxcli/migration/cucm/extractors/informational.py +295 -0
- wxcli/migration/cucm/extractors/locations.py +221 -0
- wxcli/migration/cucm/extractors/moh.py +100 -0
- wxcli/migration/cucm/extractors/remote_destinations.py +96 -0
- wxcli/migration/cucm/extractors/routing.py +493 -0
- wxcli/migration/cucm/extractors/shared_lines.py +146 -0
- wxcli/migration/cucm/extractors/templates.py +229 -0
- wxcli/migration/cucm/extractors/tier4.py +173 -0
- wxcli/migration/cucm/extractors/users.py +240 -0
- wxcli/migration/cucm/extractors/voicemail.py +243 -0
- wxcli/migration/cucm/extractors/workspaces.py +88 -0
- wxcli/migration/cucm/unity_connection.py +304 -0
- wxcli/migration/execute/CLAUDE.md +372 -0
- wxcli/migration/execute/__init__.py +303 -0
- wxcli/migration/execute/batch.py +277 -0
- wxcli/migration/execute/dependency.py +483 -0
- wxcli/migration/execute/engine.py +964 -0
- wxcli/migration/execute/handlers.py +2232 -0
- wxcli/migration/execute/planner.py +1939 -0
- wxcli/migration/execute/runtime.py +571 -0
- wxcli/migration/export/CLAUDE.md +49 -0
- wxcli/migration/export/__init__.py +8 -0
- wxcli/migration/export/csv_export.py +126 -0
- wxcli/migration/export/deployment_plan.py +479 -0
- wxcli/migration/export/json_export.py +60 -0
- wxcli/migration/models.py +941 -0
- wxcli/migration/phone_models.py +50 -0
- wxcli/migration/preflight/CLAUDE.md +52 -0
- wxcli/migration/preflight/__init__.py +89 -0
- wxcli/migration/preflight/checks.py +911 -0
- wxcli/migration/preflight/runner.py +293 -0
- wxcli/migration/rate_limiter.py +144 -0
- wxcli/migration/report/CLAUDE.md +245 -0
- wxcli/migration/report/__init__.py +7 -0
- wxcli/migration/report/appendix.py +2437 -0
- wxcli/migration/report/assembler.py +183 -0
- wxcli/migration/report/charts.py +263 -0
- wxcli/migration/report/executive.py +776 -0
- wxcli/migration/report/explainer.py +704 -0
- wxcli/migration/report/helpers.py +74 -0
- wxcli/migration/report/ingest.py +152 -0
- wxcli/migration/report/notice_templates.py +192 -0
- wxcli/migration/report/score.py +375 -0
- wxcli/migration/report/styles.py +1052 -0
- wxcli/migration/report/user_diff.py +1052 -0
- wxcli/migration/report/user_notice.py +425 -0
- wxcli/migration/state.py +139 -0
- wxcli/migration/store.py +860 -0
- wxcli/migration/transform/CLAUDE.md +107 -0
- wxcli/migration/transform/__init__.py +12 -0
- wxcli/migration/transform/analysis_pipeline.py +453 -0
- wxcli/migration/transform/analyzers/__init__.py +142 -0
- wxcli/migration/transform/analyzers/css_permission.py +189 -0
- wxcli/migration/transform/analyzers/css_routing.py +335 -0
- wxcli/migration/transform/analyzers/device_compatibility.py +122 -0
- wxcli/migration/transform/analyzers/dn_ambiguity.py +131 -0
- wxcli/migration/transform/analyzers/duplicate_user.py +221 -0
- wxcli/migration/transform/analyzers/extension_conflict.py +173 -0
- wxcli/migration/transform/analyzers/feature_approximation.py +227 -0
- wxcli/migration/transform/analyzers/layout_overflow.py +174 -0
- wxcli/migration/transform/analyzers/location_ambiguity.py +184 -0
- wxcli/migration/transform/analyzers/missing_data.py +300 -0
- wxcli/migration/transform/analyzers/selective_call_handling.py +394 -0
- wxcli/migration/transform/analyzers/shared_line.py +170 -0
- wxcli/migration/transform/analyzers/voicemail_compatibility.py +267 -0
- wxcli/migration/transform/analyzers/workspace_license.py +212 -0
- wxcli/migration/transform/cross_reference.py +1136 -0
- wxcli/migration/transform/cucm_pattern.py +246 -0
- wxcli/migration/transform/decisions.py +301 -0
- wxcli/migration/transform/e164.py +145 -0
- wxcli/migration/transform/engine.py +256 -0
- wxcli/migration/transform/mappers/CLAUDE.md +123 -0
- wxcli/migration/transform/mappers/__init__.py +76 -0
- wxcli/migration/transform/mappers/announcement_mapper.py +122 -0
- wxcli/migration/transform/mappers/base.py +190 -0
- wxcli/migration/transform/mappers/button_template_mapper.py +186 -0
- wxcli/migration/transform/mappers/call_forwarding_mapper.py +228 -0
- wxcli/migration/transform/mappers/call_settings_mapper.py +144 -0
- wxcli/migration/transform/mappers/css_mapper.py +868 -0
- wxcli/migration/transform/mappers/dect_mapper.py +367 -0
- wxcli/migration/transform/mappers/device_layout_mapper.py +289 -0
- wxcli/migration/transform/mappers/device_mapper.py +227 -0
- wxcli/migration/transform/mappers/device_profile_mapper.py +190 -0
- wxcli/migration/transform/mappers/device_settings_mapper.py +464 -0
- wxcli/migration/transform/mappers/e911_mapper.py +129 -0
- wxcli/migration/transform/mappers/ecbn_mapper.py +263 -0
- wxcli/migration/transform/mappers/executive_assistant_mapper.py +156 -0
- wxcli/migration/transform/mappers/feature_mapper.py +1179 -0
- wxcli/migration/transform/mappers/line_mapper.py +310 -0
- wxcli/migration/transform/mappers/location_mapper.py +235 -0
- wxcli/migration/transform/mappers/moh_mapper.py +114 -0
- wxcli/migration/transform/mappers/monitoring_mapper.py +221 -0
- wxcli/migration/transform/mappers/receptionist_mapper.py +245 -0
- wxcli/migration/transform/mappers/routing_mapper.py +821 -0
- wxcli/migration/transform/mappers/snr_mapper.py +201 -0
- wxcli/migration/transform/mappers/softkey_mapper.py +205 -0
- wxcli/migration/transform/mappers/user_mapper.py +264 -0
- wxcli/migration/transform/mappers/voicemail_group_mapper.py +286 -0
- wxcli/migration/transform/mappers/voicemail_mapper.py +514 -0
- wxcli/migration/transform/mappers/workspace_mapper.py +464 -0
- wxcli/migration/transform/normalizers.py +2008 -0
- wxcli/migration/transform/pattern_converter.py +106 -0
- wxcli/migration/transform/pipeline.py +271 -0
- wxcli/migration/transform/rules.py +255 -0
- wxcli/org_health/CLAUDE.md +63 -0
- wxcli/org_health/__init__.py +7 -0
- wxcli/org_health/analyze.py +93 -0
- wxcli/org_health/checks.py +458 -0
- wxcli/org_health/collector.py +62 -0
- wxcli/org_health/models.py +78 -0
- wxcli/org_health/report.py +300 -0
- wxcli/output.py +101 -0
- wxcli-1.2.0.dist-info/METADATA +505 -0
- wxcli-1.2.0.dist-info/RECORD +413 -0
- wxcli-1.2.0.dist-info/WHEEL +5 -0
- wxcli-1.2.0.dist-info/entry_points.txt +2 -0
- wxcli-1.2.0.dist-info/licenses/LICENSE +191 -0
- wxcli-1.2.0.dist-info/scm_file_list.json +751 -0
- wxcli-1.2.0.dist-info/scm_version.json +8 -0
- 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
|