bt-cli 0.4.51__tar.gz → 0.4.53__tar.gz

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 (228) hide show
  1. {bt_cli-0.4.51 → bt_cli-0.4.53}/CLAUDE.md +1 -1
  2. {bt_cli-0.4.51 → bt_cli-0.4.53}/PKG-INFO +1 -1
  3. {bt_cli-0.4.51 → bt_cli-0.4.53}/pyproject.toml +1 -1
  4. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/__init__.py +1 -1
  5. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/client/passwordsafe.py +29 -0
  6. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/accounts.py +166 -1
  7. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/secrets.py +4 -5
  8. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/bt/SKILL.md +0 -0
  9. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/entitle/SKILL.md +0 -0
  10. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/epml/SKILL.md +0 -0
  11. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/epmw/SKILL.md +0 -0
  12. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/pra/SKILL.md +0 -0
  13. {bt_cli-0.4.51 → bt_cli-0.4.53}/.claude/skills/pws/SKILL.md +0 -0
  14. {bt_cli-0.4.51 → bt_cli-0.4.53}/.env.example +0 -0
  15. {bt_cli-0.4.51 → bt_cli-0.4.53}/.github/workflows/ci.yml +0 -0
  16. {bt_cli-0.4.51 → bt_cli-0.4.53}/.github/workflows/release.yml +0 -0
  17. {bt_cli-0.4.51 → bt_cli-0.4.53}/.gitignore +0 -0
  18. {bt_cli-0.4.51 → bt_cli-0.4.53}/README.md +0 -0
  19. {bt_cli-0.4.51 → bt_cli-0.4.53}/assets/cli-help.png +0 -0
  20. {bt_cli-0.4.51 → bt_cli-0.4.53}/assets/cli-output.png +0 -0
  21. {bt_cli-0.4.51 → bt_cli-0.4.53}/bt-cli.spec +0 -0
  22. {bt_cli-0.4.51 → bt_cli-0.4.53}/bt_entry.py +0 -0
  23. {bt_cli-0.4.51 → bt_cli-0.4.53}/epml-clients-server-side-filters-plan.md +0 -0
  24. {bt_cli-0.4.51 → bt_cli-0.4.53}/epml-implementation-plan.md +0 -0
  25. {bt_cli-0.4.51 → bt_cli-0.4.53}/pf-implementation-plan.md +0 -0
  26. {bt_cli-0.4.51 → bt_cli-0.4.53}/scripts/bt_entry.py +0 -0
  27. {bt_cli-0.4.51 → bt_cli-0.4.53}/scripts/pf_onboard.py +0 -0
  28. {bt_cli-0.4.51 → bt_cli-0.4.53}/scripts/sync-package-data.sh +0 -0
  29. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/cli.py +0 -0
  30. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/commands/__init__.py +0 -0
  31. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/commands/configure.py +0 -0
  32. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/commands/learn.py +0 -0
  33. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/commands/quick.py +0 -0
  34. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/__init__.py +0 -0
  35. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/auth.py +0 -0
  36. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/client.py +0 -0
  37. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/config.py +0 -0
  38. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/config_file.py +0 -0
  39. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/csv_utils.py +0 -0
  40. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/errors.py +0 -0
  41. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/output.py +0 -0
  42. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/prompts.py +0 -0
  43. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/core/rest_debug.py +0 -0
  44. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/CLAUDE.md +0 -0
  45. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/__init__.py +0 -0
  46. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/bt/SKILL.md +0 -0
  47. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/entitle/SKILL.md +0 -0
  48. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/epml/SKILL.md +0 -0
  49. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/epmw/SKILL.md +0 -0
  50. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/pra/SKILL.md +0 -0
  51. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/pws/SKILL.md +0 -0
  52. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/data/skills/secrets/SKILL.md +0 -0
  53. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/__init__.py +0 -0
  54. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/client/__init__.py +0 -0
  55. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/client/base.py +0 -0
  56. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/__init__.py +0 -0
  57. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/accounts.py +0 -0
  58. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/applications.py +0 -0
  59. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/auth.py +0 -0
  60. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/bundles.py +0 -0
  61. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/integrations.py +0 -0
  62. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/permissions.py +0 -0
  63. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/policies.py +0 -0
  64. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/requests.py +0 -0
  65. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/resources.py +0 -0
  66. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/roles.py +0 -0
  67. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/users.py +0 -0
  68. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/commands/workflows.py +0 -0
  69. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/__init__.py +0 -0
  70. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/bundle.py +0 -0
  71. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/common.py +0 -0
  72. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/integration.py +0 -0
  73. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/permission.py +0 -0
  74. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/policy.py +0 -0
  75. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/resource.py +0 -0
  76. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/role.py +0 -0
  77. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/user.py +0 -0
  78. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/entitle/models/workflow.py +0 -0
  79. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/__init__.py +0 -0
  80. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/client/__init__.py +0 -0
  81. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/client/base.py +0 -0
  82. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/__init__.py +0 -0
  83. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/audit.py +0 -0
  84. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/auth.py +0 -0
  85. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/client_pkg.py +0 -0
  86. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/clients.py +0 -0
  87. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/external_apis.py +0 -0
  88. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/hosts.py +0 -0
  89. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/iolog.py +0 -0
  90. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/license.py +0 -0
  91. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/quick.py +0 -0
  92. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_cmdgrps.py +0 -0
  93. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_entitlement.py +0 -0
  94. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_hostgrps.py +0 -0
  95. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_policy.py +0 -0
  96. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_roles.py +0 -0
  97. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_tests.py +0 -0
  98. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_tmdategrps.py +0 -0
  99. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_tx.py +0 -0
  100. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/rbp_usergrps.py +0 -0
  101. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/settings.py +0 -0
  102. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/siems.py +0 -0
  103. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/commands/users.py +0 -0
  104. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epml/models/__init__.py +0 -0
  105. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/__init__.py +0 -0
  106. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/client/__init__.py +0 -0
  107. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/client/base.py +0 -0
  108. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/__init__.py +0 -0
  109. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/audits.py +0 -0
  110. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/auth.py +0 -0
  111. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/computers.py +0 -0
  112. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/events.py +0 -0
  113. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/groups.py +0 -0
  114. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/policies.py +0 -0
  115. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/quick.py +0 -0
  116. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/requests.py +0 -0
  117. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/roles.py +0 -0
  118. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/tasks.py +0 -0
  119. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/commands/users.py +0 -0
  120. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/epmw/models/__init__.py +0 -0
  121. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/__init__.py +0 -0
  122. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/client/__init__.py +0 -0
  123. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/client/base.py +0 -0
  124. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/__init__.py +0 -0
  125. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/auth.py +0 -0
  126. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/group_policies.py +0 -0
  127. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/import_export.py +0 -0
  128. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/jump_clients.py +0 -0
  129. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/jump_groups.py +0 -0
  130. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/jump_items.py +0 -0
  131. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/jumpoints.py +0 -0
  132. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/policies.py +0 -0
  133. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/quick.py +0 -0
  134. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/teams.py +0 -0
  135. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/users.py +0 -0
  136. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/commands/vault.py +0 -0
  137. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/__init__.py +0 -0
  138. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/common.py +0 -0
  139. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/group_policy.py +0 -0
  140. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/jump_client.py +0 -0
  141. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/jump_group.py +0 -0
  142. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/jump_item.py +0 -0
  143. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/jumpoint.py +0 -0
  144. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/team.py +0 -0
  145. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/user.py +0 -0
  146. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pra/models/vault.py +0 -0
  147. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/__init__.py +0 -0
  148. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/client/__init__.py +0 -0
  149. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/client/base.py +0 -0
  150. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/client/beyondinsight.py +0 -0
  151. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/__init__.py +0 -0
  152. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/assets.py +0 -0
  153. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/attributes.py +0 -0
  154. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/auth.py +0 -0
  155. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/clouds.py +0 -0
  156. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/config.py +0 -0
  157. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/credentials.py +0 -0
  158. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/databases.py +0 -0
  159. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/directories.py +0 -0
  160. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/functional.py +0 -0
  161. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/import_export.py +0 -0
  162. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/platforms.py +0 -0
  163. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/quick.py +0 -0
  164. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/search.py +0 -0
  165. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/systems.py +0 -0
  166. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/users.py +0 -0
  167. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/commands/workgroups.py +0 -0
  168. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/config.py +0 -0
  169. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/models/__init__.py +0 -0
  170. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/models/account.py +0 -0
  171. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/models/asset.py +0 -0
  172. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/models/common.py +0 -0
  173. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/pws/models/system.py +0 -0
  174. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/__init__.py +0 -0
  175. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/client/__init__.py +0 -0
  176. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/client/base.py +0 -0
  177. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/__init__.py +0 -0
  178. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/_hints.py +0 -0
  179. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/auth.py +0 -0
  180. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/dynamic.py +0 -0
  181. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/folders.py +0 -0
  182. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/integrations.py +0 -0
  183. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/leases.py +0 -0
  184. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/commands/static.py +0 -0
  185. {bt_cli-0.4.51 → bt_cli-0.4.53}/src/bt_cli/secrets/models/__init__.py +0 -0
  186. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/__init__.py +0 -0
  187. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/conftest.py +0 -0
  188. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/core/__init__.py +0 -0
  189. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/core/test_auth.py +0 -0
  190. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/core/test_config.py +0 -0
  191. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/core/test_errors.py +0 -0
  192. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/core/test_rest_debug.py +0 -0
  193. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/entitle/__init__.py +0 -0
  194. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/entitle/test_client.py +0 -0
  195. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/entitle/test_commands.py +0 -0
  196. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/entitle-smoke-test.sh +0 -0
  197. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epml/__init__.py +0 -0
  198. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epml/test_client.py +0 -0
  199. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epml/test_commands.py +0 -0
  200. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epmw/__init__.py +0 -0
  201. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epmw/test_client.py +0 -0
  202. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epmw/test_commands.py +0 -0
  203. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/epmw-quick-test-plan.md +0 -0
  204. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/fixtures/__init__.py +0 -0
  205. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/fixtures/responses.py +0 -0
  206. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/__init__.py +0 -0
  207. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/conftest.py +0 -0
  208. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/helpers.py +0 -0
  209. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_entitle_integration.py +0 -0
  210. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_epmw_integration.py +0 -0
  211. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_epmw_lifecycle.py +0 -0
  212. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_pra_integration.py +0 -0
  213. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_pra_lifecycle.py +0 -0
  214. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_pws_integration.py +0 -0
  215. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/integration/test_pws_lifecycle.py +0 -0
  216. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pra/__init__.py +0 -0
  217. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pra/test_client.py +0 -0
  218. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pra/test_commands.py +0 -0
  219. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pra-smoke-test.sh +0 -0
  220. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pra-test-plan.md +0 -0
  221. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pws/__init__.py +0 -0
  222. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pws/test_client.py +0 -0
  223. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pws/test_commands.py +0 -0
  224. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pws-quick-test-plan.md +0 -0
  225. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/pws-smoke-test.sh +0 -0
  226. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/secrets/__init__.py +0 -0
  227. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/secrets/test_client.py +0 -0
  228. {bt_cli-0.4.51 → bt_cli-0.4.53}/tests/secrets/test_commands.py +0 -0
@@ -1,6 +1,6 @@
1
1
  # BT-CLI
2
2
 
3
- BeyondTrust Platform CLI for Password Safe, Entitle, PRA, EPM Windows, EPM Linux, and the BeyondTrust Secrets API. **Version: 0.4.51**
3
+ BeyondTrust Platform CLI for Password Safe, Entitle, PRA, EPM Windows, EPM Linux, and the BeyondTrust Secrets API. **Version: 0.4.53**
4
4
 
5
5
  ## Setup
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bt-cli
3
- Version: 0.4.51
3
+ Version: 0.4.53
4
4
  Summary: BeyondTrust Platform CLI (unofficial) - Password Safe, Entitle, PRA, EPM
5
5
  Author-email: Dave Grendysz <dgrendysz@beyondtrust.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "bt-cli"
7
- version = "0.4.51"
7
+ version = "0.4.53"
8
8
  description = "BeyondTrust Platform CLI (unofficial) - Password Safe, Entitle, PRA, EPM"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """BeyondTrust Unified Admin CLI."""
2
2
 
3
- __version__ = "0.4.51"
3
+ __version__ = "0.4.53"
@@ -80,6 +80,35 @@ class PasswordSafeMixin:
80
80
  """
81
81
  return self.get(f"/ManagedAccounts/{account_id}")
82
82
 
83
+ # =========================================================================
84
+ # Synced Accounts
85
+ # =========================================================================
86
+
87
+ def list_synced_accounts(
88
+ self: "PasswordSafeClient", account_id: int
89
+ ) -> list[dict[str, Any]]:
90
+ """List accounts synced to a managed account."""
91
+ result = self.get(f"/ManagedAccounts/{account_id}/SyncedAccounts")
92
+ return result if isinstance(result, list) else []
93
+
94
+ def add_synced_account(
95
+ self: "PasswordSafeClient", account_id: int, synced_account_id: int
96
+ ) -> dict[str, Any]:
97
+ """Add a synced account relationship."""
98
+ return self.post(f"/ManagedAccounts/{account_id}/SyncedAccounts/{synced_account_id}")
99
+
100
+ def remove_synced_account(
101
+ self: "PasswordSafeClient", account_id: int, synced_account_id: int
102
+ ) -> None:
103
+ """Remove a specific synced account."""
104
+ self.delete(f"/ManagedAccounts/{account_id}/SyncedAccounts/{synced_account_id}")
105
+
106
+ def remove_all_synced_accounts(
107
+ self: "PasswordSafeClient", account_id: int
108
+ ) -> None:
109
+ """Remove all synced accounts from a managed account."""
110
+ self.delete(f"/ManagedAccounts/{account_id}/SyncedAccounts")
111
+
83
112
  def get_managed_account_by_name(
84
113
  self: "PasswordSafeClient",
85
114
  system_name: str,
@@ -8,7 +8,7 @@ import typer
8
8
  from rich.console import Console
9
9
  from rich.table import Table
10
10
 
11
- from ...core.output import print_api_error
11
+ from ...core.output import print_api_error, print_success
12
12
  from ..client.base import get_client
13
13
 
14
14
  app = typer.Typer(no_args_is_help=True, help="""Manage managed accounts in Password Safe.
@@ -370,3 +370,168 @@ def rotate_password(
370
370
  except Exception as e:
371
371
  print_api_error(e, "manage accounts")
372
372
  raise typer.Exit(1)
373
+
374
+
375
+ # =============================================================================
376
+ # Synced Accounts
377
+ # =============================================================================
378
+
379
+ @app.command("synced-list")
380
+ def synced_list(
381
+ account_id: int = typer.Argument(..., help="Parent managed account ID"),
382
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table or json"),
383
+ ) -> None:
384
+ """List accounts synced to a managed account.
385
+
386
+ Examples:
387
+ bt pws accounts synced-list 14
388
+ bt pws accounts synced-list 14 -o json
389
+ """
390
+ try:
391
+ with get_client() as client:
392
+ client.authenticate()
393
+ accounts = client.list_synced_accounts(account_id)
394
+
395
+ if output == "json":
396
+ console.print_json(json.dumps(accounts, default=str))
397
+ elif accounts:
398
+ table = Table(title=f"Synced Accounts (parent ID: {account_id})")
399
+ table.add_column("Acct ID", style="cyan", no_wrap=True)
400
+ table.add_column("Account Name", style="green")
401
+ table.add_column("Domain", style="yellow")
402
+ table.add_column("Sys ID", style="blue", no_wrap=True)
403
+ table.add_column("Description", style="dim")
404
+ for a in accounts:
405
+ table.add_row(
406
+ str(a.get("ManagedAccountID", "")),
407
+ a.get("AccountName", ""),
408
+ a.get("DomainName") or "-",
409
+ str(a.get("ManagedSystemID", "")),
410
+ (a.get("Description") or "-")[:50],
411
+ )
412
+ console.print(table)
413
+ else:
414
+ console.print("[yellow]No synced accounts.[/yellow]")
415
+
416
+ except httpx.HTTPStatusError as e:
417
+ print_api_error(e, "synced-list")
418
+ raise typer.Exit(1)
419
+ except httpx.RequestError as e:
420
+ print_api_error(e, "synced-list")
421
+ raise typer.Exit(1)
422
+ except Exception as e:
423
+ print_api_error(e, "synced-list")
424
+ raise typer.Exit(1)
425
+
426
+
427
+ @app.command("synced-add")
428
+ def synced_add(
429
+ account_id: int = typer.Argument(..., help="Parent managed account ID"),
430
+ synced_account_id: int = typer.Argument(..., help="Account ID to sync"),
431
+ output: str = typer.Option("table", "--output", "-o", help="Output format: table or json"),
432
+ ) -> None:
433
+ """Add a synced account relationship.
434
+
435
+ Synced accounts share password changes with the parent account.
436
+
437
+ Examples:
438
+ bt pws accounts synced-add 14 25
439
+ bt pws accounts synced-add 14 25 -o json
440
+ """
441
+ try:
442
+ with get_client() as client:
443
+ client.authenticate()
444
+ result = client.add_synced_account(account_id, synced_account_id)
445
+
446
+ if output == "json":
447
+ console.print_json(json.dumps(result, default=str))
448
+ else:
449
+ name = result.get("AccountName", str(synced_account_id))
450
+ print_success(f"Synced account '{name}' (ID: {synced_account_id}) added to account ID: {account_id}")
451
+
452
+ except httpx.HTTPStatusError as e:
453
+ print_api_error(e, "synced-add")
454
+ raise typer.Exit(1)
455
+ except httpx.RequestError as e:
456
+ print_api_error(e, "synced-add")
457
+ raise typer.Exit(1)
458
+ except Exception as e:
459
+ print_api_error(e, "synced-add")
460
+ raise typer.Exit(1)
461
+
462
+
463
+ @app.command("synced-remove")
464
+ def synced_remove(
465
+ account_id: int = typer.Argument(..., help="Parent managed account ID"),
466
+ synced_account_id: int = typer.Argument(..., help="Synced account ID to remove"),
467
+ force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"),
468
+ ) -> None:
469
+ """Remove a specific synced account.
470
+
471
+ Examples:
472
+ bt pws accounts synced-remove 14 25
473
+ bt pws accounts synced-remove 14 25 --force
474
+ """
475
+ try:
476
+ with get_client() as client:
477
+ client.authenticate()
478
+
479
+ if not force:
480
+ confirm = typer.confirm(f"Remove synced account {synced_account_id} from account {account_id}?")
481
+ if not confirm:
482
+ console.print("[yellow]Cancelled.[/yellow]")
483
+ raise typer.Exit(0)
484
+
485
+ client.remove_synced_account(account_id, synced_account_id)
486
+
487
+ print_success(f"Removed synced account ID: {synced_account_id} from account ID: {account_id}")
488
+
489
+ except httpx.HTTPStatusError as e:
490
+ print_api_error(e, "synced-remove")
491
+ raise typer.Exit(1)
492
+ except httpx.RequestError as e:
493
+ print_api_error(e, "synced-remove")
494
+ raise typer.Exit(1)
495
+ except typer.Exit:
496
+ raise
497
+ except Exception as e:
498
+ print_api_error(e, "synced-remove")
499
+ raise typer.Exit(1)
500
+
501
+
502
+ @app.command("synced-clear")
503
+ def synced_clear(
504
+ account_id: int = typer.Argument(..., help="Parent managed account ID"),
505
+ force: bool = typer.Option(False, "--force", "-f", help="Skip confirmation"),
506
+ ) -> None:
507
+ """Remove all synced accounts from a managed account.
508
+
509
+ Examples:
510
+ bt pws accounts synced-clear 14
511
+ bt pws accounts synced-clear 14 --force
512
+ """
513
+ try:
514
+ with get_client() as client:
515
+ client.authenticate()
516
+
517
+ if not force:
518
+ confirm = typer.confirm(f"Remove ALL synced accounts from account {account_id}?")
519
+ if not confirm:
520
+ console.print("[yellow]Cancelled.[/yellow]")
521
+ raise typer.Exit(0)
522
+
523
+ client.remove_all_synced_accounts(account_id)
524
+
525
+ print_success(f"All synced accounts removed from account ID: {account_id}")
526
+
527
+ except httpx.HTTPStatusError as e:
528
+ print_api_error(e, "synced-clear")
529
+ raise typer.Exit(1)
530
+ except httpx.RequestError as e:
531
+ print_api_error(e, "synced-clear")
532
+ raise typer.Exit(1)
533
+ except typer.Exit:
534
+ raise
535
+ except Exception as e:
536
+ print_api_error(e, "synced-clear")
537
+ raise typer.Exit(1)
@@ -693,9 +693,8 @@ def show_password(
693
693
 
694
694
  # Warn if running interactively (stdout is a terminal)
695
695
  if sys.stdout.isatty():
696
- console.print(
697
- "[yellow]Warning:[/yellow] Password will be displayed. "
698
- "Press Ctrl+C to cancel.",
696
+ typer.echo(
697
+ "Warning: Password will be displayed. Press Ctrl+C to cancel.",
699
698
  err=True,
700
699
  )
701
700
 
@@ -703,7 +702,7 @@ def show_password(
703
702
  print(password)
704
703
 
705
704
  except Exception as e:
706
- console.print(f"[red]Error:[/red] {e}", err=True)
705
+ typer.echo(f"Error: {e}", err=True)
707
706
  raise typer.Exit(1)
708
707
 
709
708
 
@@ -994,7 +993,7 @@ def show_text_content(
994
993
  print(text)
995
994
 
996
995
  except Exception as e:
997
- console.print(f"[red]Error:[/red] {e}", err=True)
996
+ typer.echo(f"Error: {e}", err=True)
998
997
  raise typer.Exit(1)
999
998
 
1000
999
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes