bt-cli 0.4.13__tar.gz → 0.4.14__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 (174) hide show
  1. {bt_cli-0.4.13 → bt_cli-0.4.14}/PKG-INFO +1 -1
  2. {bt_cli-0.4.13 → bt_cli-0.4.14}/pyproject.toml +1 -1
  3. bt_cli-0.4.14/scripts/sync-package-data.sh +21 -0
  4. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/policies.py +17 -3
  5. bt_cli-0.4.14/src/bt_cli/pws/commands/import_export.py +627 -0
  6. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/secrets.py +5 -5
  7. bt_cli-0.4.13/src/bt_cli/pws/commands/import_export.py +0 -452
  8. {bt_cli-0.4.13 → bt_cli-0.4.14}/.claude/skills/bt/SKILL.md +0 -0
  9. {bt_cli-0.4.13 → bt_cli-0.4.14}/.claude/skills/entitle/SKILL.md +0 -0
  10. {bt_cli-0.4.13 → bt_cli-0.4.14}/.claude/skills/epmw/SKILL.md +0 -0
  11. {bt_cli-0.4.13 → bt_cli-0.4.14}/.claude/skills/pra/SKILL.md +0 -0
  12. {bt_cli-0.4.13 → bt_cli-0.4.14}/.claude/skills/pws/SKILL.md +0 -0
  13. {bt_cli-0.4.13 → bt_cli-0.4.14}/.env.example +0 -0
  14. {bt_cli-0.4.13 → bt_cli-0.4.14}/.github/workflows/ci.yml +0 -0
  15. {bt_cli-0.4.13 → bt_cli-0.4.14}/.github/workflows/release.yml +0 -0
  16. {bt_cli-0.4.13 → bt_cli-0.4.14}/.gitignore +0 -0
  17. {bt_cli-0.4.13 → bt_cli-0.4.14}/CLAUDE.md +0 -0
  18. {bt_cli-0.4.13 → bt_cli-0.4.14}/README.md +0 -0
  19. {bt_cli-0.4.13 → bt_cli-0.4.14}/assets/cli-help.png +0 -0
  20. {bt_cli-0.4.13 → bt_cli-0.4.14}/assets/cli-output.png +0 -0
  21. {bt_cli-0.4.13 → bt_cli-0.4.14}/bt-cli.spec +0 -0
  22. {bt_cli-0.4.13 → bt_cli-0.4.14}/bt_entry.py +0 -0
  23. {bt_cli-0.4.13 → bt_cli-0.4.14}/scripts/bt_entry.py +0 -0
  24. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/__init__.py +0 -0
  25. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/cli.py +0 -0
  26. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/commands/__init__.py +0 -0
  27. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/commands/configure.py +0 -0
  28. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/commands/learn.py +0 -0
  29. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/commands/quick.py +0 -0
  30. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/__init__.py +0 -0
  31. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/auth.py +0 -0
  32. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/client.py +0 -0
  33. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/config.py +0 -0
  34. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/config_file.py +0 -0
  35. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/csv_utils.py +0 -0
  36. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/errors.py +0 -0
  37. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/output.py +0 -0
  38. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/prompts.py +0 -0
  39. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/core/rest_debug.py +0 -0
  40. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/CLAUDE.md +0 -0
  41. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/__init__.py +0 -0
  42. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/skills/bt/SKILL.md +0 -0
  43. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/skills/entitle/SKILL.md +0 -0
  44. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/skills/epmw/SKILL.md +0 -0
  45. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/skills/pra/SKILL.md +0 -0
  46. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/data/skills/pws/SKILL.md +0 -0
  47. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/__init__.py +0 -0
  48. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/client/__init__.py +0 -0
  49. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/client/base.py +0 -0
  50. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/__init__.py +0 -0
  51. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/accounts.py +0 -0
  52. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/applications.py +0 -0
  53. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/auth.py +0 -0
  54. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/bundles.py +0 -0
  55. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/integrations.py +0 -0
  56. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/permissions.py +0 -0
  57. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/policies.py +0 -0
  58. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/resources.py +0 -0
  59. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/roles.py +0 -0
  60. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/users.py +0 -0
  61. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/commands/workflows.py +0 -0
  62. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/__init__.py +0 -0
  63. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/bundle.py +0 -0
  64. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/common.py +0 -0
  65. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/integration.py +0 -0
  66. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/permission.py +0 -0
  67. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/policy.py +0 -0
  68. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/resource.py +0 -0
  69. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/role.py +0 -0
  70. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/user.py +0 -0
  71. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/entitle/models/workflow.py +0 -0
  72. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/__init__.py +0 -0
  73. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/client/__init__.py +0 -0
  74. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/client/base.py +0 -0
  75. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/__init__.py +0 -0
  76. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/audits.py +0 -0
  77. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/auth.py +0 -0
  78. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/computers.py +0 -0
  79. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/events.py +0 -0
  80. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/groups.py +0 -0
  81. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/quick.py +0 -0
  82. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/requests.py +0 -0
  83. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/roles.py +0 -0
  84. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/tasks.py +0 -0
  85. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/commands/users.py +0 -0
  86. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/epmw/models/__init__.py +0 -0
  87. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/__init__.py +0 -0
  88. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/client/__init__.py +0 -0
  89. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/client/base.py +0 -0
  90. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/__init__.py +0 -0
  91. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/auth.py +0 -0
  92. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/import_export.py +0 -0
  93. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/jump_clients.py +0 -0
  94. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/jump_groups.py +0 -0
  95. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/jump_items.py +0 -0
  96. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/jumpoints.py +0 -0
  97. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/policies.py +0 -0
  98. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/quick.py +0 -0
  99. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/teams.py +0 -0
  100. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/users.py +0 -0
  101. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/commands/vault.py +0 -0
  102. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/__init__.py +0 -0
  103. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/common.py +0 -0
  104. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/jump_client.py +0 -0
  105. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/jump_group.py +0 -0
  106. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/jump_item.py +0 -0
  107. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/jumpoint.py +0 -0
  108. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/team.py +0 -0
  109. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/user.py +0 -0
  110. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pra/models/vault.py +0 -0
  111. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/__init__.py +0 -0
  112. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/client/__init__.py +0 -0
  113. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/client/base.py +0 -0
  114. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/client/beyondinsight.py +0 -0
  115. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/client/passwordsafe.py +0 -0
  116. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/__init__.py +0 -0
  117. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/accounts.py +0 -0
  118. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/assets.py +0 -0
  119. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/auth.py +0 -0
  120. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/clouds.py +0 -0
  121. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/config.py +0 -0
  122. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/credentials.py +0 -0
  123. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/databases.py +0 -0
  124. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/directories.py +0 -0
  125. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/functional.py +0 -0
  126. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/platforms.py +0 -0
  127. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/quick.py +0 -0
  128. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/search.py +0 -0
  129. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/systems.py +0 -0
  130. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/users.py +0 -0
  131. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/commands/workgroups.py +0 -0
  132. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/config.py +0 -0
  133. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/models/__init__.py +0 -0
  134. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/models/account.py +0 -0
  135. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/models/asset.py +0 -0
  136. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/models/common.py +0 -0
  137. {bt_cli-0.4.13 → bt_cli-0.4.14}/src/bt_cli/pws/models/system.py +0 -0
  138. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/__init__.py +0 -0
  139. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/conftest.py +0 -0
  140. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/core/__init__.py +0 -0
  141. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/core/test_auth.py +0 -0
  142. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/core/test_config.py +0 -0
  143. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/core/test_errors.py +0 -0
  144. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/core/test_rest_debug.py +0 -0
  145. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/entitle/__init__.py +0 -0
  146. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/entitle/test_client.py +0 -0
  147. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/entitle/test_commands.py +0 -0
  148. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/entitle-smoke-test.sh +0 -0
  149. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/epmw/__init__.py +0 -0
  150. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/epmw/test_client.py +0 -0
  151. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/epmw/test_commands.py +0 -0
  152. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/epmw-quick-test-plan.md +0 -0
  153. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/fixtures/__init__.py +0 -0
  154. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/fixtures/responses.py +0 -0
  155. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/__init__.py +0 -0
  156. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/conftest.py +0 -0
  157. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/helpers.py +0 -0
  158. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_entitle_integration.py +0 -0
  159. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_epmw_integration.py +0 -0
  160. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_epmw_lifecycle.py +0 -0
  161. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_pra_integration.py +0 -0
  162. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_pra_lifecycle.py +0 -0
  163. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_pws_integration.py +0 -0
  164. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/integration/test_pws_lifecycle.py +0 -0
  165. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pra/__init__.py +0 -0
  166. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pra/test_client.py +0 -0
  167. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pra/test_commands.py +0 -0
  168. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pra-smoke-test.sh +0 -0
  169. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pra-test-plan.md +0 -0
  170. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pws/__init__.py +0 -0
  171. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pws/test_client.py +0 -0
  172. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pws/test_commands.py +0 -0
  173. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pws-quick-test-plan.md +0 -0
  174. {bt_cli-0.4.13 → bt_cli-0.4.14}/tests/pws-smoke-test.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bt-cli
3
- Version: 0.4.13
3
+ Version: 0.4.14
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.13"
7
+ version = "0.4.14"
8
8
  description = "BeyondTrust Platform CLI (unofficial) - Password Safe, Entitle, PRA, EPM"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,21 @@
1
+ #!/bin/bash
2
+ # Sync skills and CLAUDE.md to package data directory before building
3
+ # Run this before `python -m build` to ensure package has latest content
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
8
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
9
+
10
+ echo "Syncing package data..."
11
+
12
+ # Sync skills
13
+ rm -rf "$PROJECT_ROOT/src/bt_cli/data/skills"
14
+ cp -r "$PROJECT_ROOT/.claude/skills" "$PROJECT_ROOT/src/bt_cli/data/skills"
15
+ echo " ✓ Synced .claude/skills -> src/bt_cli/data/skills"
16
+
17
+ # Sync CLAUDE.md
18
+ cp "$PROJECT_ROOT/CLAUDE.md" "$PROJECT_ROOT/src/bt_cli/data/CLAUDE.md"
19
+ echo " ✓ Synced CLAUDE.md -> src/bt_cli/data/CLAUDE.md"
20
+
21
+ echo "Done. Ready to build."
@@ -288,15 +288,29 @@ def revert_policy(
288
288
  @app.command("download")
289
289
  def download_policy(
290
290
  policy_id: str = typer.Argument(..., help="Policy ID (UUID)"),
291
+ file: Optional[str] = typer.Option(None, "--file", "-f", help="Save to file instead of stdout"),
291
292
  ):
292
- """Download policy content (XML format)."""
293
+ """Download policy content (XML format).
294
+
295
+ Examples:
296
+ bt epmw policies download <policy_id>
297
+ bt epmw policies download <policy_id> --file policy.xml
298
+ bt epmw policies download <policy_id> > policy.xml
299
+ """
293
300
  from bt_cli.epmw.client import get_client
294
301
 
295
302
  try:
296
303
  client = get_client()
297
304
  content = client.download_policy(policy_id)
298
- # Policy content is XML
299
- typer.echo(content)
305
+
306
+ if file:
307
+ # Write to file
308
+ with open(file, "w", encoding="utf-8") as f:
309
+ f.write(content)
310
+ print_success(f"Policy saved to: {file}")
311
+ else:
312
+ # Output to stdout
313
+ typer.echo(content)
300
314
  except httpx.HTTPStatusError as e:
301
315
  print_api_error(e, "download policy")
302
316
  raise typer.Exit(1)