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,820 @@
1
+ ---
2
+ name: cucm-migrate
3
+ description: |
4
+ Execute a CUCM-to-Webex migration using DB-driven skill delegation. Generates an
5
+ assessment report first (complexity score, environment inventory, analog gateway review,
6
+ effort bands), then walks through decision review, executes migration operations
7
+ by delegating to domain skills (provision-calling, configure-features, etc.), and
8
+ finally assembles a customer deliverables bundle (assessment report, user diff,
9
+ user notice, deployment plan, execution report) into a single output directory.
10
+ Use after running the CUCM analysis pipeline (wxcli cucm discover/normalize/map/analyze).
11
+
12
+ Workflow steps:
13
+ 1. Load, verify, assess (assessment report + decision review)
14
+ 2. Auth + preflight
15
+ 3. Present summary + get approval
16
+ 4. Execute via skill delegation (4c: Emergency Call Notification / Kari's Law)
17
+ 5. Generate Customer Deliverables Bundle (idempotent; runnable standalone)
18
+ 6. Report results (execution status)
19
+ allowed-tools: Read, Grep, Glob, Bash, Skill, Agent
20
+ argument-hint: [project name]
21
+ ---
22
+
23
+ # CUCM Migration Execution Workflow
24
+
25
+ **Checkpoint — do NOT proceed until you can answer these:**
26
+ 1. What pipeline stage must be complete before this skill can run? (Answer: ANALYZED — run `wxcli cucm status` to verify. If not at ANALYZED or later, the admin must run the remaining pipeline stages first.)
27
+ 2. What must be resolved before the plan can be generated? (Answer: All PENDING decisions — run `wxcli cucm decisions --status pending` to check. Location addresses must also be imported via `wxcli cucm import-locations`.)
28
+
29
+ If you cannot answer both, you skipped reading this skill. Go back and read it.
30
+
31
+ ## Reference docs for the operator
32
+
33
+ If the operator is unfamiliar with the cucm migration pipeline, point them at:
34
+
35
+ - **[Operator Runbook](../../../docs/runbooks/cucm-migration/operator-runbook.md)** — end-to-end pipeline walkthrough, prerequisites, failure recovery
36
+ - **[Decision Guide](../../../docs/runbooks/cucm-migration/decision-guide.md)** — per-DecisionType and per-advisory-pattern reference
37
+ - **[Tuning Reference](../../../docs/runbooks/cucm-migration/tuning-reference.md)** — config keys, auto-rules, score weights, 5 worked recipes
38
+
39
+ These are the only operator-facing docs for this migration tool. If the operator asks "where do I learn this," send them to the operator runbook first.
40
+
41
+ ## Step 1: Load, Verify, and Assess
42
+
43
+ 1. **Check project exists and pipeline is complete:**
44
+ ```bash
45
+ wxcli cucm status -o json
46
+ ```
47
+ Verify stage is `ANALYZED` or later. If not, tell the admin which pipeline stages remain.
48
+
49
+ 2. **Generate the assessment report:**
50
+ ```bash
51
+ wxcli cucm report --brand "<customer name>" --prepared-by "<admin name>" -p <project>
52
+ ```
53
+ This produces an HTML assessment report at `~/.wxcli/migrations/<project>/assessment-report.html`.
54
+ Open it for the admin:
55
+ ```bash
56
+ open ~/.wxcli/migrations/<project>/assessment-report.html
57
+ ```
58
+
59
+ Present the key findings:
60
+ > "I've generated the migration assessment report. Here's the summary:
61
+ > - **Complexity score:** X/100 (Straightforward/Moderate/Complex)
62
+ > - **Environment:** N users, M devices across K sites
63
+ > - **Analog gateways:** X gateways with ~Y ports (if any — these need manual port mapping)
64
+ > - **Decisions:** N total, M auto-resolved, K need review
65
+ >
66
+ > The full report is open in your browser. Review it before we proceed with decisions."
67
+
68
+ Wait for the admin to confirm they've reviewed the report before continuing.
69
+ If the admin wants to stop here (assessment-only engagement), the workflow ends.
70
+
71
+ 3. **Resolve location addresses (BLOCKING GATE):**
72
+
73
+ CUCM device pools never have street addresses but Webex requires them. Check
74
+ for locations missing addresses:
75
+ ```bash
76
+ wxcli cucm inventory --type location -o json -p <project>
77
+ ```
78
+ Parse each location's `address.address1`. If ANY are null/empty:
79
+
80
+ **Small environment (< 10 locations):** Auto-fill demo addresses without asking:
81
+ ```bash
82
+ wxcli cucm import-locations --demo -p <project>
83
+ ```
84
+ Tell the admin what was set:
85
+ > "I've filled in demo addresses for N locations based on timezone
86
+ > (e.g., San Jose for Pacific, Richardson for Central). These are
87
+ > placeholder addresses for testing — replace with real addresses
88
+ > before a production migration."
89
+
90
+ **Large environment (10+ locations):** Export the worksheet and block:
91
+ ```bash
92
+ wxcli cucm export --format location-worksheet -p <project>
93
+ ```
94
+ Tell the admin:
95
+ > "Your migration has N locations that need street addresses before
96
+ > Webex can create them. I've exported a worksheet to:
97
+ > [path to location-worksheet.csv]
98
+ >
99
+ > Fill in the address1, city, state, and postal_code columns, then run:
100
+ > `wxcli cucm import-locations <path> -p <project>`
101
+ >
102
+ > I'll continue once all locations have addresses."
103
+
104
+ **Do NOT proceed to decision review until all locations have addresses.**
105
+ Re-check after the user says they've imported. If locations are still
106
+ missing addresses, show which ones and repeat.
107
+
108
+ **After addresses are resolved, re-run analyze** to clear stale MISSING_DATA
109
+ decisions that were created before addresses existed:
110
+ ```bash
111
+ wxcli cucm analyze -p <project>
112
+ ```
113
+ This re-evaluates all decisions. Location/device MISSING_DATA decisions that
114
+ are no longer valid will be staled automatically.
115
+
116
+ 4. **Check for pending decisions and generate review file:**
117
+ ```bash
118
+ wxcli cucm decisions --status pending -p <project>
119
+ ```
120
+ If pending decisions exist, generate the review file with JSON output:
121
+ ```bash
122
+ wxcli cucm decisions --export-review -o json -p <project>
123
+ ```
124
+ This does two things:
125
+ - **Writes** `<project>/exports/decision-review.md` for admin offline review
126
+ - **Prints JSON** to stdout with structured `auto_apply` and `needs_input` arrays
127
+
128
+ The JSON includes `review_file` (path to the markdown file). Tell the admin:
129
+ > "I've generated a decision review at [review_file path]. There are N
130
+ > auto-apply decisions and M that need your input."
131
+
132
+ ### Step 1b: Migration Architecture Analysis
133
+
134
+ Launch the migration-advisor agent in analysis mode to produce an architectural reasoning
135
+ narrative with cross-decision analysis, dissent flags, and domain summaries.
136
+
137
+ ```
138
+ Agent(migration-advisor, mode=bypassPermissions, model=opus, prompt="""
139
+ Analyze this CUCM-to-Webex migration and produce an architectural reasoning narrative.
140
+
141
+ Project path: <project>
142
+ Pipeline output:
143
+ - Run `wxcli cucm decisions -o json -p <project>` for all decisions
144
+ - Run `wxcli cucm decisions --type advisory -o json -p <project>` for advisories
145
+ - Run `wxcli cucm inventory -o json -p <project>` for canonical model summary
146
+
147
+ Write the narrative to: <project>/exports/migration-narrative.md
148
+ """)
149
+ ```
150
+
151
+ Wait for the agent to complete. Read the returned summary.
152
+
153
+ **If the agent fails** (error, no narrative file written):
154
+ - Tell the admin: "Architecture analysis unavailable. Proceeding with static recommendations only."
155
+ - Fall through to Step 1c-fallback (the original Phase A/B presentation below).
156
+
157
+ **If the agent succeeds:**
158
+ - Read the full narrative file: `<project>/exports/migration-narrative.md`
159
+ - **Display the entire narrative to the user as direct text in your response.** Do not summarize it, do not just mention the file path. The user must see the full document on screen.
160
+ - Then proceed to Step 1c.
161
+
162
+ ### Step 1c: Decision Review
163
+
164
+ Launch the migration-advisor agent in review mode to guide the admin through
165
+ architecture advisory review and per-decision review with narrative context,
166
+ dissent flags, and CCIE-level explanation.
167
+
168
+ ```
169
+ Agent(migration-advisor, mode=bypassPermissions, model=opus, prompt="""
170
+ Guide the admin through migration decision review.
171
+
172
+ Project path: <project>
173
+ Narrative: <project>/exports/migration-narrative.md
174
+ Pipeline output: Run wxcli cucm commands as needed
175
+
176
+ Present Phase A (architecture advisory) and Phase B (per-decision review)
177
+ with narrative context, dissent flags, and CCIE-level explanation.
178
+ Resolve decisions via: wxcli cucm decide <ID> <option> -p <project>
179
+ After all decisions resolved, apply auto-resolvable decisions and re-plan/re-export.
180
+ """)
181
+ ```
182
+
183
+ Wait for the agent to complete. Verify all decisions are resolved:
184
+ ```bash
185
+ wxcli cucm decisions --status pending -p <project>
186
+ ```
187
+
188
+ If pending decisions remain, inform the admin and ask whether to continue
189
+ with unresolved decisions or re-enter review.
190
+
191
+ > **Operator help:** If the operator asks what a specific decision means, point them at the corresponding entry in [decision-guide.md §Decision Types A–Z](../../../docs/runbooks/cucm-migration/decision-guide.md#decision-types-az). The guide has one entry per non-advisory DecisionType plus one entry per advisory pattern.
192
+
193
+ ### Step 1c-fallback: Static Decision Review
194
+
195
+ **Only used if Step 1b's advisor agent failed.** This is the original Phase A/B
196
+ presentation with static recommendations and no narrative context.
197
+
198
+ #### Phase A: Architecture Review
199
+
200
+ Before per-decision review, present `ARCHITECTURE_ADVISORY` decisions. Pull them:
201
+ ```bash
202
+ wxcli cucm decisions --type advisory -o json -p <project>
203
+ ```
204
+
205
+ Group advisories by category and present:
206
+ ```
207
+ === Architecture Advisory ===
208
+
209
+ ELIMINATE (CUCM workarounds to remove):
210
+ - <ID> <summary> [REC: accept] <reasoning>
211
+ - ...
212
+
213
+ REBUILD (use Webex-native patterns):
214
+ - <ID> <summary> [REC: accept] <reasoning>
215
+ - ...
216
+
217
+ OUT OF SCOPE (separate workstreams):
218
+ - <ID> <summary> [REC: accept] <reasoning>
219
+ - ...
220
+
221
+ MIGRATE AS-IS (informational):
222
+ - <ID> <summary> [REC: accept] <reasoning>
223
+ - ...
224
+
225
+ Accept all advisory recommendations? [Y/n] Or review individually? [r]
226
+ ```
227
+
228
+ - If **Y** (default): run `wxcli cucm decide <ID> accept -p <project>` for each advisory
229
+ - If **n**: skip advisory resolution (admin will handle later)
230
+ - If **r**: present each advisory individually with accept/dismiss options
231
+
232
+ #### Phase B: Per-Decision Review
233
+
234
+ Present remaining (non-advisory) decisions in three groups:
235
+
236
+ **Group 1: Auto-apply (matched by `auto_rules` config)** — applied via `--apply-auto`.
237
+ By default this covers 7 rule types: incompatible devices, hotdesk DN conflicts,
238
+ lossy forwarding, lossy SNR, unmappable buttons, orphaned permission profiles
239
+ (`assigned_users_count == 0`), and missing data on devices that are already
240
+ incompatible. (Convertible devices are not in this list — they auto-convert
241
+ unconditionally at plan time with no decision emitted.) Custom rules in
242
+ `<project>/config.json` extend this set. Edits to `config.json` are picked up the next time `--apply-auto`
243
+ runs — no need to re-run `analyze` first.
244
+
245
+ **Group 2: Recommended** — decisions where `recommendation` is set.
246
+ Present with bulk accept option:
247
+ ```
248
+ RECOMMENDED ({n} decisions):
249
+
250
+ 1. <ID> — <summary>
251
+ Recommended: <option> — <reasoning>. Accept? [Y/n]
252
+
253
+ 2. <ID> — <summary>
254
+ Recommended: <option> — <reasoning>. Accept? [Y/n]
255
+
256
+ Accept all {n} recommended decisions? [Y/a individual/n reject all]
257
+ ```
258
+
259
+ - If **Y** (default): run `wxcli cucm decide <ID> <recommended_option> -p <project>` for each
260
+ - If **a**: present each individually
261
+ - If **n**: leave all unresolved
262
+
263
+ **Group 3: Needs input** — no recommendation, present options normally:
264
+ ```
265
+ NEEDS YOUR INPUT (N decisions):
266
+
267
+ 1. <ID> — <summary>
268
+ [a] <option 1> [b] <option 2> [c] Skip
269
+
270
+ 2. <ID> — <summary>
271
+ [a] <option 1> [b] <option 2> [c] Skip
272
+
273
+ Reply with your choices: "1a, 2b" or "all a"
274
+ ```
275
+
276
+ Rules for the interactive menu:
277
+ - **Number each decision** sequentially (1, 2, 3...)
278
+ - **Letter each option** (a, b, c...) — map to the actual decision option IDs
279
+ - **Show what each option means** in plain language, not internal IDs
280
+ - **Accept compact responses** like "1a, 2a, 3b" or "all a"
281
+ - **Accept natural language** like "accept for 1, workspace for 2 and 3"
282
+ - **Confirm what was applied** with a brief summary
283
+ - If the admin changes their mind, re-run `wxcli cucm decide <ID> <new_choice>`
284
+
285
+ **Do NOT auto-resolve needs-input decisions.** Wait for explicit admin choices.
286
+ After receiving choices, run `wxcli cucm decide <ID> <choice> -p <project>` for each.
287
+
288
+ **CRITICAL — Cascading-impact decisions:** Before resolving ANY decision as "skip",
289
+ check whether downstream objects depend on the skipped resource. If they do, you MUST:
290
+ 1. Tell the admin what data is missing (e.g., "Location X has no street address")
291
+ 2. Show how many downstream operations are blocked (e.g., "18 ops depend on this location: 2 trunks, 4 users, 3 hunt groups...")
292
+ 3. Ask the admin to provide the missing data OR explicitly confirm the skip
293
+ Do NOT silently skip decisions that cascade into blocked downstream operations.
294
+
295
+ 3. **Apply auto-resolvable decisions:**
296
+ After the admin has resolved all needs-input decisions, show what will be
297
+ auto-applied (read from the Auto-Apply section of the review file —
298
+ the section reflects the project's current `auto_rules` config, including
299
+ any custom rules):
300
+ ```
301
+ AUTO-APPLYING (N decisions — matched by current auto-rules):
302
+ <count> <type> → <choice>
303
+ ...
304
+ ```
305
+ Then apply:
306
+ ```bash
307
+ wxcli cucm decide --apply-auto -y -p <project>
308
+ ```
309
+ This re-runs the rules in `<project>/config.json` against any pending
310
+ decisions and resolves matches. Safe to re-run.
311
+
312
+ If the admin has hand-edited `config.json` and wants to restore the
313
+ default rule set, run: `wxcli cucm config reset auto_rules -p <project>`.
314
+ This restores defaults but clobbers any custom rules in `auto_rules`.
315
+
316
+ 4. **Re-plan and re-export:**
317
+ ```bash
318
+ wxcli cucm plan -p <project> && wxcli cucm export -p <project>
319
+ ```
320
+
321
+ ## Known Webex platform limits
322
+
323
+ - Max 5 devices per user (hardware + soft clients). CUCM users with 6+ devices require explicit selection during decision review — see [kb-device-migration.md](../../../docs/knowledge-base/migration/kb-device-migration.md).
324
+
325
+ ## Step 2: Auth + Preflight — [MANDATORY, NOT SKIPPABLE]
326
+
327
+ ### 2a. Verify auth token and expiry
328
+
329
+ ```bash
330
+ wxcli whoami
331
+ ```
332
+
333
+ If this fails with 401/403, stop and troubleshoot auth before proceeding.
334
+
335
+ **Token expiry gate:** Parse the "Token: expires in Xh Ym" line. If the token
336
+ expires in **less than 2 hours**, **do NOT proceed to execution.** Tell the admin:
337
+ > "Your token expires in [time]. A migration needs at least 2 hours of token
338
+ > validity. Please refresh your token (`wxcli configure`) and re-run."
339
+
340
+ This prevents mid-migration auth failures that leave the org in a partial state.
341
+
342
+ ### 2b. Run preflight checks
343
+
344
+ ```bash
345
+ wxcli cucm preflight
346
+ ```
347
+
348
+ **Preflight runs 8 checks** against the Webex target org. If ANY check fails, **do NOT proceed to execution.** Show failures with actionable fixes:
349
+
350
+ | Failure Type | Actionable Fix |
351
+ |---|---|
352
+ | Number conflicts | "These numbers already exist in Webex. Remove them first, or skip via `wxcli cucm decide`" |
353
+ | Duplicate users | "These users already exist. Decide: update in-place or skip" |
354
+ | License shortage | "Need N licenses, only M available. Add licenses in Control Hub or reduce scope" |
355
+ | Location conflicts | "Location names already exist. Decide: reuse existing or rename" |
356
+ | Extension conflicts | "Extensions conflict at target location. Reassign or skip" |
357
+ | Missing prerequisites | "Required resources not found in Webex. Provision them first" |
358
+
359
+ **Preflight failure recovery:**
360
+ 1. Show failures with specific fix instructions
361
+ 2. User resolves blockers
362
+ 3. Re-run: `wxcli cucm preflight` (or `--check <check-name>` for single check)
363
+ 4. Repeat until all pass
364
+
365
+ > **Operator help:** If a preflight check fails, point the operator at the relevant tuning recipe in [tuning-reference.md §Tuning Recipes](../../../docs/runbooks/cucm-migration/tuning-reference.md#tuning-recipes). License shortage → Recipe 1 (baseline assumptions); routing/CSS issues → Recipe 3; trunk issues → Recipe 4.
366
+
367
+ ## Step 3: Present Summary and Get Approval
368
+
369
+ ```bash
370
+ wxcli cucm export --format deployment-plan
371
+ ```
372
+
373
+ Read the generated summary file, then present:
374
+
375
+ ```
376
+ === CUCM Migration Plan Summary ===
377
+ Source: [CUCM cluster]
378
+ Target: [Webex org]
379
+
380
+ Resources to migrate:
381
+ Locations: N to create
382
+ Users: N to provision
383
+ [etc. — from summary]
384
+
385
+ Execution:
386
+ Total operations: N in M batches
387
+ [etc.]
388
+
389
+ Ready to execute? (yes/no)
390
+ ```
391
+
392
+ **Wait for explicit "yes" before proceeding.**
393
+
394
+ ## Step 4: Execute via Skill Delegation
395
+
396
+ This is the core of the workflow. Instead of executing pre-built CLI strings, query the
397
+ DB for operation metadata and delegate each operation to a domain skill.
398
+
399
+ ### 4a. Retrieve license ID (once)
400
+
401
+ ```bash
402
+ wxcli licenses list --output json
403
+ ```
404
+
405
+ Find the license where `name` contains "Calling - Professional" with available capacity.
406
+ Store as `CALLING_LICENSE_ID` for user creation operations. If none available, **stop**.
407
+
408
+ ### 4b. Bulk execution
409
+
410
+ The bulk executor processes all operations concurrently at API throughput (~100 req/min)
411
+ instead of one-at-a-time through the conversational loop. Claude is NOT involved during
412
+ execution — only for failure diagnosis afterward.
413
+
414
+ ```
415
+ 0. IF this is a re-run (prior failed attempt exists):
416
+ Invoke the provision-calling skill with "tear down all resources from org".
417
+ That skill's Operation F has the full dependency-ordered cleanup with:
418
+ - Per-location enumeration for call parks and pickups (org-wide list returns empty)
419
+ - Raw HTTP delete for virtual lines (CLI has ID type mismatch bug)
420
+ - Calling disable + 90s wait before location delete
421
+ See docs/reference/provisioning.md § "Bulk Cleanup / Teardown" for the full procedure.
422
+
423
+ After cleanup, regenerate the plan:
424
+ wxcli cucm plan -p <project>
425
+
426
+ 1. Preview the execution plan:
427
+ wxcli cucm dry-run
428
+
429
+ 2. Show the admin the dry-run summary (operations, batches, estimated time).
430
+ Get explicit confirmation to proceed.
431
+
432
+ 3. Execute:
433
+ wxcli cucm execute --concurrency 20
434
+
435
+ This runs all pending operations using async concurrent API calls.
436
+ Progress is printed per-batch. Failed operations are recorded in the DB.
437
+
438
+ 4. Check results:
439
+ wxcli cucm execution-status -o json
440
+
441
+ 5. IF all completed → proceed to Step 5 (deliverables bundle) then Step 6 (report)
442
+
443
+ 6. IF failures exist:
444
+ Show failure summary to admin.
445
+ FOR EACH failed operation:
446
+ Read the error message from execution-status
447
+ Load the appropriate domain skill (from the dispatch table below)
448
+ Diagnose the failure using the domain skill's knowledge
449
+ Present options: fix+retry | skip | rollback
450
+
451
+ After all failures resolved:
452
+ wxcli cucm retry-failed # resets failed ops to pending
453
+ wxcli cucm execute # picks up remaining ops
454
+
455
+ Repeat until execution-status shows 0 failed, 0 pending.
456
+ ```
457
+
458
+ ### Skill Dispatch Table
459
+
460
+ This table is the PRIMARY execution mechanism. The pipeline says WHAT. The domain skills say HOW.
461
+
462
+ | resource_type | op_type | Delegate To | What the Skill Already Knows |
463
+ |--------------|---------|-------------|------------------------------|
464
+ | location | create | provision-calling | Two-step: `locations create` + `location-settings create` to enable calling |
465
+ | location | enable_calling | provision-calling | Separate API call to enable Webex Calling on the location |
466
+ | user | create | provision-calling | Extension required at creation. License via `--license`. Combines create + assign_number + assign_license |
467
+ | user | configure_settings | manage-call-settings | Read-before-write. `--json-body` format. Per-setting endpoint paths |
468
+ | user | configure_voicemail | manage-call-settings | Same as configure_settings |
469
+ | workspace | create | provision-calling | License tier matters. Basic vs Professional determines which settings work |
470
+ | workspace | assign_number | provision-calling | Number assignment after workspace creation |
471
+ | workspace | configure_settings | manage-call-settings | Workspace settings mirror person settings, Professional license required for some |
472
+ | device | create | manage-devices | MAC validation. Activation code generation. `apply-changes-for` after settings |
473
+ | device | configure_settings | manage-devices | Device settings, line key templates |
474
+ | hunt_group | create | configure-features | Location ID as positional arg. Agents need person IDs. Policy limits |
475
+ | call_queue | create | configure-features | Same as HG. Plus routing policy, queue settings |
476
+ | auto_attendant | create | configure-features | Menus auto-populated. Schedule must exist first |
477
+ | call_park | create | configure-features | Extension required. Location-scoped |
478
+ | pickup_group | create | configure-features | Agents need person IDs |
479
+ | paging_group | create | configure-features | Targets and originators need person IDs |
480
+ | operating_mode | create | configure-features | Schedule — level must be ORGANIZATION |
481
+ | schedule | create | configure-features | Location schedule — requires locationId, type (businessHours/holidays), and events with recurWeekly recurrence. Must exist before AA references it |
482
+ | trunk | create | configure-routing | Type and location immutable after creation. Requires locationId |
483
+ | route_group | create | configure-routing | Requires at least one gateway member |
484
+ | dial_plan | create | configure-routing | Org-wide. Patterns as array |
485
+ | translation_pattern | create | configure-routing | Name and matching_pattern required |
486
+ | shared_line | configure | manage-devices | Device member update + apply-changes-for |
487
+ | virtual_line | create | manage-call-settings | Extension required, settings applied after creation |
488
+ | virtual_line | configure | manage-call-settings | Virtual line settings |
489
+ | calling_permission | create | manage-call-settings | Logical grouping — no standalone API |
490
+ | calling_permission | assign | manage-call-settings | Per-user outgoing permission PUT |
491
+ | line_key_template | create | manage-devices | POST `/telephony/config/devices/lineKeyTemplates`. Filters UNMAPPED keys. Skipped if `phones_using == 0` |
492
+ | call_forwarding | configure | manage-call-settings | PUT `/people/{id}/features/callForwarding`. Returns `[]` if all forwarding types disabled |
493
+ | monitoring_list | configure | manage-call-settings | PUT `/people/{id}/features/monitoring`. Silently omits unresolved members; returns `[]` if none resolve |
494
+ | device_layout | configure | manage-devices | 2-3 calls: optional PUT `.../members`, PUT `.../layout`, POST `.../actions/applyChanges/invoke`. Uses `device_id_surface` to pick cloud vs telephony device ID |
495
+ | softkey_config | configure | manage-devices | Only for `is_psk_target=True` per-device objects. PUT `.../dynamicSettings` + POST `.../actions/applyChanges/invoke`. Template-level objects auto-complete (no API call) |
496
+
497
+ ### Rollback Dispatch Table
498
+
499
+ Use `wxcli cucm rollback-ops` (or `--batch <name>` for a single batch) to get the list.
500
+ Each entry includes resource_type, webex_id, location_webex_id, and canonical data.
501
+
502
+ Delete in the order returned (reverse tier: features → devices → users → routing → locations).
503
+
504
+ | resource_type | Delete Command Pattern | Notes |
505
+ |---|---|---|
506
+ | softkey_config | No rollback needed — reconfigure or reset device to defaults | Configure-only; no resource created |
507
+ | device_layout | No rollback needed — reconfigure or reset device to defaults | Configure-only; no resource created |
508
+ | monitoring_list | `curl -X PUT .../people/{id}/features/monitoring -d '{"enableCallParkNotification":false,"monitoredElements":[]}'` | Clears monitoring list |
509
+ | call_forwarding | `curl -X PUT .../people/{id}/features/callForwarding -d '{"always":{"enabled":false},"busy":{"enabled":false},"noAnswer":{"enabled":false}}'` | Disables all forwarding |
510
+ | line_key_template | `curl -X DELETE .../telephony/config/devices/lineKeyTemplates/{id}` | Remove template; phones revert to default |
511
+ | paging_group | `wxcli paging-group delete <location_webex_id> <webex_id> --force` | |
512
+ | pickup_group | `wxcli call-pickup delete <location_webex_id> <webex_id> --force` | |
513
+ | call_park | `wxcli call-park delete <location_webex_id> <webex_id> --force` | |
514
+ | auto_attendant | `wxcli auto-attendant delete <location_webex_id> <webex_id> --force` | |
515
+ | call_queue | `wxcli call-queue delete <location_webex_id> <webex_id> --force` | |
516
+ | hunt_group | `wxcli hunt-group delete <location_webex_id> <webex_id> --force` | |
517
+ | schedule | `wxcli location-schedules delete <location_webex_id> <schedule_type> <webex_id> --force` | schedule_type from canonical data (businessHours or holidays) |
518
+ | operating_mode | `wxcli operating-modes delete <webex_id> --force` | Org-wide |
519
+ | device | `wxcli devices delete <webex_id> --force` | No location needed |
520
+ | workspace | `wxcli workspaces delete <webex_id> --force` | Deletes associated device too |
521
+ | user | `wxcli users delete <webex_id> --force` | Releases number + license |
522
+ | translation_pattern | `wxcli call-routing delete-translation-patterns-call-routing <webex_id> --force` | Org-level |
523
+ | dial_plan | `wxcli call-routing delete <webex_id> --force` | Remove patterns first |
524
+ | route_group | `wxcli call-routing delete-route-groups <webex_id> --force` | Remove from dial plans first |
525
+ | trunk | `wxcli call-routing delete-trunks <webex_id> --force` | Remove from route groups first |
526
+ | location | `wxcli locations delete <webex_id> --force` | Clear blockers first with CLI/API, then retry. Final delete of a calling-enabled location may still require Control Hub. |
527
+
528
+ **IMPORTANT:**
529
+ - Before deleting locations, verify all users/devices/features at that location are already deleted.
530
+ - Before deleting trunks, verify no route groups reference them (Error 27349 names the blocker).
531
+ - Before deleting schedules, verify no auto attendants reference them.
532
+ - **Call parks and pickups must be listed per-location** — `wxcli call-park list` and `wxcli call-pickup list` without a location arg return empty.
533
+ - **Virtual lines must be deleted via raw HTTP** — `wxcli virtual-extensions delete` uses wrong ID type. Use `curl -X DELETE .../telephony/config/virtualLines/{id}`. Discover VL IDs from `wxcli numbers list -o json` (owner.type == VIRTUAL_LINE).
534
+ - The reverse tier ordering handles dependency order naturally — only override if an op was skipped.
535
+ - See `docs/reference/provisioning.md` § "Bulk Cleanup / Teardown" for the full procedure.
536
+
537
+ ### Delegation examples
538
+
539
+ **location:create:**
540
+ > "Create a Webex Calling location with:
541
+ > - name: [data.name]
542
+ > - timeZone: [data.timeZone]
543
+ > - address: [data.address]
544
+ > The provision-calling skill handles the two-step creation
545
+ > (location create + calling enablement)."
546
+
547
+ **user:create:**
548
+ > "Create a Webex Calling user with:
549
+ > - email: [data.email]
550
+ > - firstName: [data.firstName]
551
+ > - lastName: [data.lastName]
552
+ > - extension: [data.extension]
553
+ > - locationId: [resolved_deps → location webex_id]
554
+ > - license: [CALLING_LICENSE_ID]
555
+ > The provision-calling skill handles extension and license in the create call."
556
+
557
+ **hunt_group:create:**
558
+ > "Create a hunt group with:
559
+ > - name: [data.name]
560
+ > - extension: [data.extension]
561
+ > - enabled: [data.enabled]
562
+ > - locationId: [resolved_deps → location webex_id]
563
+ > - agents: [list of person Webex IDs from resolved_deps as {"id": "WEBEX_ID"}]
564
+ > - callPolicies.policy: [data.policy] (CIRCULAR, REGULAR, SIMULTANEOUS, UNIFORM, WEIGHTED)
565
+ > - callPolicies.noAnswer.nextAgentEnabled: true
566
+ > - callPolicies.noAnswer.nextAgentRings: [data.no_answer_rings or 3]
567
+ > - callPolicies.noAnswer.forwardEnabled: false
568
+ > - callPolicies.noAnswer.numberOfRings: 15
569
+ > - callPolicies.noAnswer.destinationVoicemailEnabled: false
570
+ > The configure-features skill handles the full callPolicies structure.
571
+ > The CLI auto-injects a default callPolicies if omitted, but always pass
572
+ > the canonical policy to preserve the CUCM source configuration."
573
+
574
+ **trunk:create:**
575
+ > "Create a trunk with:
576
+ > - name: [data.name]
577
+ > - locationId: [resolved_deps → location webex_id]
578
+ > - trunkType: [data.trunk_type] ← REQUIRED, always pass from metadata
579
+ > - password: [data.password] ← REQUIRED for REGISTERING type
580
+ > - address: [data.address] ← only for CERTIFICATE_BASED
581
+ > The configure-routing skill handles trunk type and authentication."
582
+
583
+ **schedule:create:**
584
+ > "Create a location schedule with:
585
+ > - locationId: [data.location_id]
586
+ > - name: [data.name]
587
+ > - type: [data.schedule_type] (businessHours or holidays)
588
+ > - events: [data.events] — must use recurWeekly recurrence, NOT recurForEver
589
+ > The configure-features skill handles location schedule creation."
590
+
591
+ ### 4c. Error handling
592
+
593
+ > **Operator help:** For runbook coverage of this failure mode, see [operator-runbook.md §Failure Patterns](../../../docs/runbooks/cucm-migration/operator-runbook.md#failure-patterns).
594
+
595
+ On any failure:
596
+
597
+ **IF 409 Conflict (resource already exists):**
598
+ → Search for existing resource: `wxcli [resource] list --name/--email "..." -o json`
599
+ → If found and matches: `wxcli cucm mark-complete [node_id] --webex-id [existing_id]` — continue
600
+ → If found but different: present to admin for decision
601
+
602
+ **IF 400/500 on user:create (partial creation — most common failure):**
603
+ The People API may create the user record before failing on calling setup, leaving an
604
+ orphaned non-calling user. 409 on retry confirms this. Recovery flow:
605
+ 1. Search: `wxcli people list --email "<email>" --calling-data true -o json`
606
+ 2. If user exists WITHOUT calling (no `phoneNumbers`/`extension` in response):
607
+ → Update to add calling: `wxcli people update <person_id> --calling-data true --json-body '{"extension":"<ext>","locationId":"<loc_id>"}'`
608
+ → If update succeeds: `wxcli cucm mark-complete [node_id] --webex-id <person_id>`
609
+ → If update fails: present error to admin with fix options
610
+ 3. If user exists WITH calling already configured:
611
+ → `wxcli cucm mark-complete [node_id] --webex-id <person_id>` — continue
612
+ 4. If user does NOT exist: genuine failure, present options
613
+
614
+ **IF 400/500 on other create operations (may have partially created):**
615
+ → Search for existing resource (same as 409 flow)
616
+ → If found: resource was created despite error, mark-complete
617
+ → If not found: genuine failure, present options
618
+
619
+ **ALL OTHER errors:**
620
+ → `wxcli cucm mark-failed [node_id] --error "[message]"`
621
+ → Present options:
622
+ (A) Fix and retry — domain skill diagnoses and suggests fix
623
+ (B) Skip this step — `wxcli cucm mark-failed [node_id] --error "..." --skip`
624
+ (C) Rollback this batch
625
+ (D) Rollback all
626
+
627
+ **NEVER fall back to raw HTTP.** If a wxcli command fails, diagnose the CLI issue.
628
+ The `--json-body` bypass fix means all create commands accept JSON body without
629
+ needing individual flags. If a CLI command is genuinely broken, flag it for a
630
+ generator fix.
631
+
632
+ ## Step 4c: Emergency Call Notification
633
+
634
+ One-shot org-level configuration for Kari's Law compliance. Runs AFTER execution
635
+ and BEFORE the final report. Advisory only — never fails the migration if skipped.
636
+
637
+ Kari's Law requires every multi-line telephone system to notify a designated party
638
+ (security desk, front office, facilities) when any user dials 911. Step 4 handled
639
+ per-entity ECBN selection (tier 5 operations); this step covers the org-level
640
+ notification half of the compliance requirement.
641
+
642
+ Prompt the operator:
643
+
644
+ ```
645
+ Emergency Call Notification (Kari's Law compliance)
646
+ When a user dials 911, Webex Calling can email a designated address with
647
+ the caller's identity and location. Enter an email, or press Enter to skip.
648
+
649
+ Notification email: _______________
650
+ ```
651
+
652
+ IF operator provides an email:
653
+
654
+ ```bash
655
+ wxcli emergency-services update-emergency-call-notification-config \
656
+ --json-body '{"emergencyCallNotificationEnabled": true, "allowEmailNotificationAllLocationEnabled": true, "emailAddress": "<provided-email>"}'
657
+ ```
658
+
659
+ Log success and proceed to Step 5.
660
+
661
+ IF operator skips: log a warning in the execution report — "Emergency Call
662
+ Notification not configured. Kari's Law compliance requires this; set manually
663
+ via Control Hub → Calling → Service Settings → Emergency Call Notification
664
+ before cutover." Proceed to Step 5 regardless.
665
+
666
+ ## Step 5: Generate Customer Deliverables Bundle
667
+
668
+ Assemble every customer-facing artifact the SE needs to hand over in a single
669
+ directory. This step is **idempotent** — re-running it overwrites prior copies.
670
+ Operators mid-migration can invoke this skill fresh and jump straight here.
671
+
672
+ ### 5a. Collect parameters up front (one prompt, not drip-fed)
673
+
674
+ Before running any commands, gather the four required inputs. Check
675
+ `~/.wxcli/migrations/<project>/config.json` first; if any of these are already
676
+ present, show them as defaults. Accept them in a single batch from the
677
+ operator / parent agent (e.g., the wxc-calling-builder agent may pass them in
678
+ the spawn prompt — honor those rather than re-prompting):
679
+
680
+ | Param | Used by | Example |
681
+ |---|---|---|
682
+ | `brand` | report, user-notice | "Acme Corp" |
683
+ | `prepared-by` | report | "Adam Hobgood, Cisco SE" |
684
+ | `migration-date` | user-notice | "April 22, 2026" |
685
+ | `helpdesk` | user-notice | "helpdesk@acme.com / x5555" |
686
+ | `output-dir` | copy target (default: `docs/demo/YYYY-MM-DD-<project-slug>/`) | `docs/demo/2026-04-22-acme/` |
687
+
688
+ Present the collected values and ask "Proceed? [Y/n]" before running commands.
689
+
690
+ ### 5b. Generate artifacts (fail loudly on any error)
691
+
692
+ Run in order. If any command is missing or errors, **stop and surface the
693
+ error to the operator** — do not silently skip.
694
+
695
+ ```bash
696
+ # 1. Assessment report (complexity, inventory, effort bands)
697
+ wxcli cucm report \
698
+ --brand "<brand>" \
699
+ --prepared-by "<prepared-by>" \
700
+ -p <project>
701
+ # → ~/.wxcli/migrations/<project>/assessment-report.html
702
+
703
+ # 2. Per-user migration diff (CUCM vs Webex, per user)
704
+ wxcli cucm user-diff -p <project>
705
+ # → ~/.wxcli/migrations/<project>/user-diff.html (default format: html)
706
+
707
+ # 3. User-facing migration notice (communication email/portal copy)
708
+ wxcli cucm user-notice \
709
+ --brand "<brand>" \
710
+ --migration-date "<migration-date>" \
711
+ --helpdesk "<helpdesk>" \
712
+ --prepared-by "<prepared-by>" \
713
+ -p <project>
714
+ # → ~/.wxcli/migrations/<project>/user-notice.html
715
+
716
+ # 4. Deployment plan (generate if not already present; safe to re-run)
717
+ wxcli cucm export --format deployment-plan -p <project>
718
+ # → ~/.wxcli/migrations/<project>/exports/deployment-plan.md
719
+ ```
720
+
721
+ **Flag support confirmed via `--help`:**
722
+ - `report` — `--brand` (required), `--prepared-by` (required), `-p` project
723
+ - `user-diff` — `-p` project, `--format html|csv` (default html), no brand/prepared-by flags
724
+ - `user-notice` — `--brand`, `--migration-date`, `--helpdesk` all required; `--prepared-by` optional; `-p` project
725
+ - `export` — `--format deployment-plan` (default), `-p` project
726
+
727
+ ### 5c. Collect the Step 6 execution report
728
+
729
+ The auto-generated execution report from Step 6 (`docs/plans/YYYY-MM-DD-cucm-migration-report.md`)
730
+ is part of the bundle. If Step 6 has already run (normal end-to-end flow), copy
731
+ its output into the bundle. If you're running Step 5 standalone before Step 6,
732
+ note "execution report will be added after Step 6 completes" in the summary and
733
+ come back to copy it.
734
+
735
+ ### 5d. Copy everything into the output directory
736
+
737
+ ```bash
738
+ mkdir -p <output-dir>
739
+ cp ~/.wxcli/migrations/<project>/assessment-report.html <output-dir>/
740
+ cp ~/.wxcli/migrations/<project>/user-diff.html <output-dir>/
741
+ cp ~/.wxcli/migrations/<project>/user-notice.html <output-dir>/
742
+ cp ~/.wxcli/migrations/<project>/exports/deployment-plan.md <output-dir>/
743
+ # If Step 6 report exists:
744
+ cp docs/plans/<YYYY-MM-DD>-cucm-migration-report.md <output-dir>/ 2>/dev/null || true
745
+ ```
746
+
747
+ Overwrite silently — operators re-run migrations and expect the latest copy.
748
+
749
+ ### 5e. Return the bundle manifest
750
+
751
+ In your final task summary, print the exact absolute paths so stakeholders can
752
+ be pointed at them without hunting:
753
+
754
+ ```
755
+ === Customer Deliverables Bundle ===
756
+ Output directory: <absolute-output-dir>
757
+
758
+ assessment-report.html — complexity score, inventory, effort bands
759
+ user-diff.html — per-user CUCM→Webex diff
760
+ user-notice.html — user-facing migration communication
761
+ deployment-plan.md — human-readable migration plan
762
+ <YYYY-MM-DD>-cucm-migration-report.md — execution results (after Step 6)
763
+ ```
764
+
765
+ ## Step 6: Report Results
766
+
767
+ ```bash
768
+ wxcli cucm execution-status -o json
769
+ ```
770
+
771
+ Generate report from the JSON:
772
+
773
+ ```
774
+ === CUCM Migration Execution Report ===
775
+ Source: [CUCM cluster]
776
+ Target: [Webex org]
777
+ Date: [timestamp]
778
+
779
+ Summary:
780
+ Planned: N operations
781
+ Succeeded: M
782
+ Failed: K
783
+ Skipped: J
784
+
785
+ Resources created:
786
+ [from execution-status by_resource_type breakdown]
787
+
788
+ Failed operations:
789
+ [list failures with error messages]
790
+
791
+ Next steps:
792
+ [manual post-migration tasks]
793
+ ```
794
+
795
+ Save to `docs/plans/YYYY-MM-DD-cucm-migration-report.md`.
796
+
797
+ ---
798
+
799
+ ## Critical Rules
800
+
801
+ 1. **Preflight is mandatory.** No override or bypass.
802
+ 2. **Always show plan summary and get approval.** Wait for explicit "yes".
803
+ 3. **Execute via domain skill delegation.** Read the dispatch table. Load the skill. Pass the data. Let the skill build the commands.
804
+ 4. **Always use `mark-complete` and `mark-failed`.** Never update the migration database directly.
805
+ 5. **On any create failure, always check for existing resource before retry.** Partial creates leave orphaned resources that cause 409 on retry.
806
+ 6. **Never fall back to raw HTTP.** Fix the CLI command. Don't work around it.
807
+ 7. **If `next-batch` returns empty but `execution-status` shows pending ops, there's a dependency deadlock.** Show the failed/skipped dependencies and let the admin decide.
808
+ 8. **Rollback in reverse dependency order.** Feature deletes need location ID + resource ID.
809
+ 9. **The deployment plan is a summary for admin review.** Not executable commands. Never hand-edit it.
810
+ 10. **License ID must be retrieved before user creation.** Fetch once, use for all user:create ops.
811
+
812
+ ---
813
+
814
+ ## Context Compaction Recovery
815
+
816
+ Simplified — no markdown plan to re-parse:
817
+
818
+ 1. `wxcli cucm execution-status -o json` → see what's done
819
+ 2. `wxcli cucm next-batch -o json` → see what's next
820
+ 3. Resume from Step 4b. If execution already shows 0 pending / 0 failed, jump to Step 5 (deliverables bundle) — it is idempotent and safe to re-run standalone.