ida-hcli 0.0.0__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 (78) hide show
  1. ida_hcli-0.0.0/LICENSE +21 -0
  2. ida_hcli-0.0.0/PKG-INFO +152 -0
  3. ida_hcli-0.0.0/README.md +106 -0
  4. ida_hcli-0.0.0/pyproject.toml +99 -0
  5. ida_hcli-0.0.0/setup.cfg +4 -0
  6. ida_hcli-0.0.0/src/hcli/__init__.py +1 -0
  7. ida_hcli-0.0.0/src/hcli/commands/__init__.py +36 -0
  8. ida_hcli-0.0.0/src/hcli/commands/auth/__init__.py +21 -0
  9. ida_hcli-0.0.0/src/hcli/commands/auth/default.py +65 -0
  10. ida_hcli-0.0.0/src/hcli/commands/auth/key/__init__.py +22 -0
  11. ida_hcli-0.0.0/src/hcli/commands/auth/key/create.py +77 -0
  12. ida_hcli-0.0.0/src/hcli/commands/auth/key/install.py +85 -0
  13. ida_hcli-0.0.0/src/hcli/commands/auth/key/list.py +76 -0
  14. ida_hcli-0.0.0/src/hcli/commands/auth/key/revoke.py +65 -0
  15. ida_hcli-0.0.0/src/hcli/commands/auth/key/uninstall.py +17 -0
  16. ida_hcli-0.0.0/src/hcli/commands/auth/list.py +85 -0
  17. ida_hcli-0.0.0/src/hcli/commands/auth/switch.py +82 -0
  18. ida_hcli-0.0.0/src/hcli/commands/commands.py +68 -0
  19. ida_hcli-0.0.0/src/hcli/commands/common.py +96 -0
  20. ida_hcli-0.0.0/src/hcli/commands/download.py +162 -0
  21. ida_hcli-0.0.0/src/hcli/commands/extension/__init__.py +15 -0
  22. ida_hcli-0.0.0/src/hcli/commands/extension/create.py +12 -0
  23. ida_hcli-0.0.0/src/hcli/commands/extension/list.py +17 -0
  24. ida_hcli-0.0.0/src/hcli/commands/ida/__init__.py +14 -0
  25. ida_hcli-0.0.0/src/hcli/commands/ida/install.py +71 -0
  26. ida_hcli-0.0.0/src/hcli/commands/license/__init__.py +18 -0
  27. ida_hcli-0.0.0/src/hcli/commands/license/common.py +263 -0
  28. ida_hcli-0.0.0/src/hcli/commands/license/get.py +77 -0
  29. ida_hcli-0.0.0/src/hcli/commands/license/install.py +104 -0
  30. ida_hcli-0.0.0/src/hcli/commands/license/list.py +137 -0
  31. ida_hcli-0.0.0/src/hcli/commands/login.py +107 -0
  32. ida_hcli-0.0.0/src/hcli/commands/logout.py +179 -0
  33. ida_hcli-0.0.0/src/hcli/commands/plugin/__init__.py +22 -0
  34. ida_hcli-0.0.0/src/hcli/commands/plugin/enable.py +195 -0
  35. ida_hcli-0.0.0/src/hcli/commands/plugin/install.py +192 -0
  36. ida_hcli-0.0.0/src/hcli/commands/plugin/search.py +64 -0
  37. ida_hcli-0.0.0/src/hcli/commands/plugin/update.py +157 -0
  38. ida_hcli-0.0.0/src/hcli/commands/share/__init__.py +20 -0
  39. ida_hcli-0.0.0/src/hcli/commands/share/delete.py +66 -0
  40. ida_hcli-0.0.0/src/hcli/commands/share/get.py +92 -0
  41. ida_hcli-0.0.0/src/hcli/commands/share/list.py +207 -0
  42. ida_hcli-0.0.0/src/hcli/commands/share/put.py +75 -0
  43. ida_hcli-0.0.0/src/hcli/commands/update.py +43 -0
  44. ida_hcli-0.0.0/src/hcli/commands/whoami.py +17 -0
  45. ida_hcli-0.0.0/src/hcli/env.py +30 -0
  46. ida_hcli-0.0.0/src/hcli/lib/__init__.py +1 -0
  47. ida_hcli-0.0.0/src/hcli/lib/api/__init__.py +1 -0
  48. ida_hcli-0.0.0/src/hcli/lib/api/asset.py +212 -0
  49. ida_hcli-0.0.0/src/hcli/lib/api/auth.py +25 -0
  50. ida_hcli-0.0.0/src/hcli/lib/api/common.py +293 -0
  51. ida_hcli-0.0.0/src/hcli/lib/api/customer.py +44 -0
  52. ida_hcli-0.0.0/src/hcli/lib/api/index.py +36 -0
  53. ida_hcli-0.0.0/src/hcli/lib/api/keys.py +48 -0
  54. ida_hcli-0.0.0/src/hcli/lib/api/license.py +130 -0
  55. ida_hcli-0.0.0/src/hcli/lib/api/plugins.py +117 -0
  56. ida_hcli-0.0.0/src/hcli/lib/auth/__init__.py +552 -0
  57. ida_hcli-0.0.0/src/hcli/lib/commands/__init__.py +160 -0
  58. ida_hcli-0.0.0/src/hcli/lib/config/__init__.py +76 -0
  59. ida_hcli-0.0.0/src/hcli/lib/console.py +18 -0
  60. ida_hcli-0.0.0/src/hcli/lib/constants/__init__.py +6 -0
  61. ida_hcli-0.0.0/src/hcli/lib/constants/auth.py +92 -0
  62. ida_hcli-0.0.0/src/hcli/lib/constants/cli.py +27 -0
  63. ida_hcli-0.0.0/src/hcli/lib/ida/__init__.py +428 -0
  64. ida_hcli-0.0.0/src/hcli/lib/ida/plugin.py +426 -0
  65. ida_hcli-0.0.0/src/hcli/lib/util/__init__.py +1 -0
  66. ida_hcli-0.0.0/src/hcli/lib/util/crc32.py +98 -0
  67. ida_hcli-0.0.0/src/hcli/lib/util/io.py +286 -0
  68. ida_hcli-0.0.0/src/hcli/lib/util/output.py +221 -0
  69. ida_hcli-0.0.0/src/hcli/lib/util/python.py +215 -0
  70. ida_hcli-0.0.0/src/hcli/lib/util/string.py +381 -0
  71. ida_hcli-0.0.0/src/hcli/lib/util/version.py +217 -0
  72. ida_hcli-0.0.0/src/hcli/main.py +112 -0
  73. ida_hcli-0.0.0/src/ida_hcli.egg-info/PKG-INFO +152 -0
  74. ida_hcli-0.0.0/src/ida_hcli.egg-info/SOURCES.txt +76 -0
  75. ida_hcli-0.0.0/src/ida_hcli.egg-info/dependency_links.txt +1 -0
  76. ida_hcli-0.0.0/src/ida_hcli.egg-info/entry_points.txt +3 -0
  77. ida_hcli-0.0.0/src/ida_hcli.egg-info/requires.txt +34 -0
  78. ida_hcli-0.0.0/src/ida_hcli.egg-info/top_level.txt +1 -0
ida_hcli-0.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Hex-Rays SA
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,152 @@
1
+ Metadata-Version: 2.4
2
+ Name: ida-hcli
3
+ Version: 0.0.0
4
+ Summary: HCLI - Hex-Rays CLI Utility.
5
+ Author-email: Hex-Rays SA <support@hex-rays.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://hex-rays.com/
8
+ Project-URL: Repository, https://github.com/HexRaysSA/ida-hcli
9
+ Project-URL: Issues, https://github.com/HexRaysSA/ida-hcli/issues
10
+ Keywords: ida,ida-pro,reverse-engineering,disassembler,binary-analysis,malware-analysis,security
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: click
15
+ Requires-Dist: rich
16
+ Requires-Dist: rich-click
17
+ Requires-Dist: httpx
18
+ Requires-Dist: supabase
19
+ Requires-Dist: pydantic
20
+ Requires-Dist: platformdirs
21
+ Requires-Dist: packaging
22
+ Requires-Dist: questionary
23
+ Requires-Dist: ida-domain>=0.0.1.dev29
24
+ Provides-Extra: dev
25
+ Requires-Dist: mypy>=1.16.0; extra == "dev"
26
+ Requires-Dist: ruff; extra == "dev"
27
+ Requires-Dist: bandit; extra == "dev"
28
+ Requires-Dist: pre-commit>=4.2.0; extra == "dev"
29
+ Requires-Dist: safety>=3.5.2; extra == "dev"
30
+ Requires-Dist: python-semantic-release>=10.3.1; extra == "dev"
31
+ Provides-Extra: test
32
+ Requires-Dist: pytest>=7.0.0; extra == "test"
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
34
+ Requires-Dist: pytest-mock>=3.10.0; extra == "test"
35
+ Requires-Dist: pytest-httpx>=0.21.0; extra == "test"
36
+ Requires-Dist: pexpect>=4.9.0; extra == "test"
37
+ Provides-Extra: docs
38
+ Requires-Dist: mkdocs-material; extra == "docs"
39
+ Requires-Dist: mkdocs-click>=0.9.0; extra == "docs"
40
+ Requires-Dist: mkdocstrings[python]>=0.20.0; extra == "docs"
41
+ Requires-Dist: mkdocs-gen-files>=0.5.0; extra == "docs"
42
+ Requires-Dist: mkdocs-include-markdown-plugin>=7.1.5; extra == "docs"
43
+ Requires-Dist: mkdocs-literate-nav>=0.6.2; extra == "docs"
44
+ Requires-Dist: pymdown-extensions>=10.15; extra == "docs"
45
+ Dynamic: license-file
46
+
47
+ # IDA HCLI
48
+
49
+ ![](docs/assets/screenshot.png)
50
+
51
+ change #1 : chore
52
+ change #2 : fix
53
+ change #3 : feature
54
+ change #4 : fix: azeaze
55
+
56
+ A modern command-line interface for managing IDA Pro licenses, plugins, ...
57
+
58
+ [![PyPI version](https://badge.fury.io/py/ida-hcli.svg)](https://badge.fury.io/py/ida-hcli)
59
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
60
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
61
+
62
+ # Documentation
63
+
64
+ See [https://hcli.docs.hex-rays.com/](hcli.docs.hex-rays.com/)
65
+
66
+ ## Contributing
67
+
68
+ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to:
69
+
70
+ - Report bugs and suggest features
71
+ - Submit pull requests with proper testing
72
+ - Set up your development environment with Hatch
73
+ - Generate and update documentation automatically
74
+
75
+ ## License
76
+
77
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
78
+
79
+ ## Issues and Support
80
+
81
+ - **Bug Reports & Feature Requests**: [GitHub Issues](https://github.com/HexRaysSA/ida-hcli/issues)
82
+ - **Questions & Discussions**: [Discussions](https://community.hex-rays.com/)
83
+ - **Documentation**: Auto-generated from source code at build time
84
+ - **Commercial Support**: Contact support@hex-rays.com
85
+ - **Hex-Rays Website**: [hex-rays.com](https://hex-rays.com/)
86
+
87
+ ## Development
88
+
89
+ ### Prerequisites
90
+
91
+ - Python 3.10 or higher
92
+ - [uv](https://docs.astral.sh/uv/) package manager
93
+
94
+ ### Setup
95
+
96
+ ```bash
97
+ # Clone the repository
98
+ git clone https://github.com/HexRaysSA/ida-hcli.git
99
+ cd ida-hcli
100
+
101
+ # Install dependencies
102
+ uv sync
103
+
104
+ # Run in development mode
105
+ uv run hcli --help
106
+ ```
107
+
108
+ ### Build System
109
+
110
+ ```bash
111
+ # Install with development dependencies
112
+ uv sync --extra dev
113
+
114
+ # Build package
115
+ uv build
116
+
117
+ # Run development tools
118
+ uv run ruff format
119
+ uv run ruff check --fix
120
+ uv run ruff check --select I --fix
121
+ ```
122
+
123
+ ### Documentation
124
+
125
+ Documentation is **automatically generated** from source code:
126
+
127
+ ```bash
128
+ # Build documentation
129
+ uv run mkdocs build
130
+
131
+ # Serve documentation locally
132
+ uv run mkdocs serve
133
+
134
+ # Documentation includes:
135
+ # - CLI commands (from Click help text)
136
+ # - API reference (from Python docstrings)
137
+ # - Usage examples (auto-generated)
138
+ ```
139
+
140
+ ### Testing
141
+
142
+ ```bash
143
+ # Run tests
144
+ uv run pytest
145
+
146
+ # Test CLI commands
147
+ uv run hcli whoami
148
+ uv run hcli plugin list
149
+ ```
150
+
151
+
152
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed development guidelines.
@@ -0,0 +1,106 @@
1
+ # IDA HCLI
2
+
3
+ ![](docs/assets/screenshot.png)
4
+
5
+ change #1 : chore
6
+ change #2 : fix
7
+ change #3 : feature
8
+ change #4 : fix: azeaze
9
+
10
+ A modern command-line interface for managing IDA Pro licenses, plugins, ...
11
+
12
+ [![PyPI version](https://badge.fury.io/py/ida-hcli.svg)](https://badge.fury.io/py/ida-hcli)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
14
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
15
+
16
+ # Documentation
17
+
18
+ See [https://hcli.docs.hex-rays.com/](hcli.docs.hex-rays.com/)
19
+
20
+ ## Contributing
21
+
22
+ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details on how to:
23
+
24
+ - Report bugs and suggest features
25
+ - Submit pull requests with proper testing
26
+ - Set up your development environment with Hatch
27
+ - Generate and update documentation automatically
28
+
29
+ ## License
30
+
31
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
32
+
33
+ ## Issues and Support
34
+
35
+ - **Bug Reports & Feature Requests**: [GitHub Issues](https://github.com/HexRaysSA/ida-hcli/issues)
36
+ - **Questions & Discussions**: [Discussions](https://community.hex-rays.com/)
37
+ - **Documentation**: Auto-generated from source code at build time
38
+ - **Commercial Support**: Contact support@hex-rays.com
39
+ - **Hex-Rays Website**: [hex-rays.com](https://hex-rays.com/)
40
+
41
+ ## Development
42
+
43
+ ### Prerequisites
44
+
45
+ - Python 3.10 or higher
46
+ - [uv](https://docs.astral.sh/uv/) package manager
47
+
48
+ ### Setup
49
+
50
+ ```bash
51
+ # Clone the repository
52
+ git clone https://github.com/HexRaysSA/ida-hcli.git
53
+ cd ida-hcli
54
+
55
+ # Install dependencies
56
+ uv sync
57
+
58
+ # Run in development mode
59
+ uv run hcli --help
60
+ ```
61
+
62
+ ### Build System
63
+
64
+ ```bash
65
+ # Install with development dependencies
66
+ uv sync --extra dev
67
+
68
+ # Build package
69
+ uv build
70
+
71
+ # Run development tools
72
+ uv run ruff format
73
+ uv run ruff check --fix
74
+ uv run ruff check --select I --fix
75
+ ```
76
+
77
+ ### Documentation
78
+
79
+ Documentation is **automatically generated** from source code:
80
+
81
+ ```bash
82
+ # Build documentation
83
+ uv run mkdocs build
84
+
85
+ # Serve documentation locally
86
+ uv run mkdocs serve
87
+
88
+ # Documentation includes:
89
+ # - CLI commands (from Click help text)
90
+ # - API reference (from Python docstrings)
91
+ # - Usage examples (auto-generated)
92
+ ```
93
+
94
+ ### Testing
95
+
96
+ ```bash
97
+ # Run tests
98
+ uv run pytest
99
+
100
+ # Test CLI commands
101
+ uv run hcli whoami
102
+ uv run hcli plugin list
103
+ ```
104
+
105
+
106
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed development guidelines.
@@ -0,0 +1,99 @@
1
+ [project]
2
+ name = "ida-hcli"
3
+ version = "0.0.0"
4
+ description = "HCLI - Hex-Rays CLI Utility."
5
+ requires-python = ">=3.10"
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ keywords = ["ida", "ida-pro", "reverse-engineering", "disassembler", "binary-analysis", "malware-analysis", "security"]
9
+ authors = [
10
+ { name = "Hex-Rays SA", email = "support@hex-rays.com" }
11
+ ]
12
+
13
+ dependencies = [
14
+ "click",
15
+ "rich",
16
+ "rich-click",
17
+ "httpx",
18
+ "supabase",
19
+ "pydantic",
20
+ "platformdirs",
21
+ "packaging",
22
+ "questionary",
23
+ "ida-domain>=0.0.1.dev29",
24
+ ]
25
+
26
+
27
+ [project.urls]
28
+ Homepage = "https://hex-rays.com/"
29
+ Repository = "https://github.com/HexRaysSA/ida-hcli"
30
+ Issues = "https://github.com/HexRaysSA/ida-hcli/issues"
31
+
32
+ [project.scripts]
33
+ hcli = "hcli.main:cli"
34
+ ida-hcli = "hcli.main:cli"
35
+
36
+ [build-system]
37
+ requires = ["setuptools>=61.0", "wheel"]
38
+ build-backend = "setuptools.build_meta"
39
+
40
+ [project.optional-dependencies]
41
+ dev = [
42
+ "mypy>=1.16.0",
43
+ "ruff",
44
+ "bandit",
45
+ "pre-commit>=4.2.0",
46
+ "safety>=3.5.2",
47
+ "python-semantic-release>=10.3.1",
48
+ ]
49
+ test = [
50
+ "pytest>=7.0.0",
51
+ "pytest-asyncio>=0.21.0",
52
+ "pytest-mock>=3.10.0",
53
+ "pytest-httpx>=0.21.0",
54
+ "pexpect>=4.9.0",
55
+ ]
56
+ docs = [
57
+ "mkdocs-material",
58
+ "mkdocs-click>=0.9.0",
59
+ "mkdocstrings[python]>=0.20.0",
60
+ "mkdocs-gen-files>=0.5.0",
61
+ "mkdocs-include-markdown-plugin>=7.1.5",
62
+ "mkdocs-literate-nav>=0.6.2",
63
+ "pymdown-extensions>=10.15"
64
+ ]
65
+
66
+ [tool.setuptools.packages.find]
67
+ where = ["src"]
68
+
69
+ [tool.ruff]
70
+ line-length = 120
71
+ target-version = "py310"
72
+ fix = true
73
+
74
+ [tool.mypy]
75
+ check_untyped_defs = true
76
+
77
+ [tool.semantic_release]
78
+ version_toml = ["pyproject.toml:project.version"] # or wherever your version is
79
+ version_variables = ["src/hcli/__init__.py:__version__"] # update your actual path
80
+ build_command = """
81
+ uv lock --upgrade-package "$PACKAGE_NAME"
82
+ git add uv.lock
83
+ uv build
84
+ """
85
+ dist_path = "dist/"
86
+ major_on_zero = false # Stay in 0.x.x range
87
+ allow_zero_version = true
88
+
89
+ # Dev branch - development releases
90
+ [tool.semantic_release.branches.main]
91
+ match = "main"
92
+ prerelease = true
93
+ prerelease_token = "dev"
94
+
95
+ # Release branch - stable releases
96
+ [tool.semantic_release.branches.release]
97
+ match = "release"
98
+ prerelease = false
99
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1 @@
1
+ __version__ = "0.0.0.dev1"
@@ -0,0 +1,36 @@
1
+ from __future__ import annotations
2
+
3
+ import rich_click as click
4
+
5
+
6
+ def register_commands(cli: click.Group) -> None:
7
+ """Register all commands to the CLI group."""
8
+ from .download import download
9
+ from .commands import commands
10
+ from .login import login
11
+ from .logout import logout
12
+ from .update import update
13
+ from .whoami import whoami
14
+ # placeholder for more commands
15
+
16
+ cli.add_command(login)
17
+ cli.add_command(logout)
18
+ cli.add_command(whoami)
19
+ cli.add_command(update)
20
+ cli.add_command(download)
21
+ cli.add_command(commands)
22
+
23
+ # groups
24
+ from .auth import auth
25
+ from .ida import ida
26
+ from .license import license
27
+ from .plugin import plugin
28
+ from .share import share
29
+ from .extension import extension
30
+
31
+ cli.add_command(auth)
32
+ cli.add_command(ida)
33
+ cli.add_command(plugin)
34
+ cli.add_command(share)
35
+ cli.add_command(license)
36
+ cli.add_command(extension)
@@ -0,0 +1,21 @@
1
+ from __future__ import annotations
2
+
3
+ import rich_click as click
4
+
5
+
6
+ @click.group()
7
+ def auth() -> None:
8
+ """Authentication commands."""
9
+ pass
10
+
11
+
12
+ # Subcommands
13
+ from .key import key # noqa: E402
14
+ from .list import list_credentials # noqa: E402
15
+ from .switch import switch_credentials # noqa: E402
16
+ from .default import set_default_credentials # noqa: E402
17
+
18
+ auth.add_command(key)
19
+ auth.add_command(list_credentials)
20
+ auth.add_command(switch_credentials)
21
+ auth.add_command(set_default_credentials)
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+
3
+ import rich_click as click
4
+
5
+ from hcli.lib.auth import get_auth_service
6
+ from hcli.lib.console import console
7
+
8
+
9
+ @click.command(name="default")
10
+ @click.argument("name", required=False)
11
+ def set_default_credentials(name: str | None) -> None:
12
+ """Set or show the default credentials."""
13
+ auth_service = get_auth_service()
14
+ auth_service.init()
15
+
16
+ if name is None:
17
+ # Show current default
18
+ default_name = auth_service.get_default_credentials_name()
19
+ if default_name:
20
+ default_source = auth_service.get_current_credentials()
21
+ if default_source:
22
+ console.print(f"[green]Default credentials: {default_name}[/green]")
23
+ console.print(f"Email: {default_source.email}")
24
+ console.print(f"Type: {default_source.type.title()}")
25
+ else:
26
+ console.print(f"[yellow]Default set to '{default_name}' but source not found.[/yellow]")
27
+ else:
28
+ console.print("[yellow]No default credentials set.[/yellow]")
29
+
30
+ # Show all available sources
31
+ sources = auth_service.list_credentials()
32
+ if sources:
33
+ console.print(f"\nAvailable sources: {', '.join(s.name for s in sources)}")
34
+ return
35
+
36
+ # Set new default
37
+ sources = auth_service.list_credentials()
38
+
39
+ if not sources:
40
+ console.print("[yellow]No credentialss found.[/yellow]")
41
+ console.print("Use '[bold]hcli login[/bold]' or '[bold]hcli auth key install[/bold]' to add credentialss.")
42
+ return
43
+
44
+ # Check if source exists
45
+ source_names = [s.name for s in sources]
46
+ if name not in source_names:
47
+ console.print(f"[red]Credentials '{name}' not found.[/red]")
48
+ console.print(f"Available sources: {', '.join(source_names)}")
49
+ return
50
+
51
+ # Check if already default
52
+ current_default = auth_service.get_default_credentials_name()
53
+ if name == current_default:
54
+ console.print(f"[yellow]'{name}' is already the default credentials.[/yellow]")
55
+ return
56
+
57
+ # Set as default
58
+ if auth_service.set_default_credentials(name):
59
+ console.print(f"[green]Set '{name}' as the default credentials.[/green]")
60
+
61
+ # Show the updated auth info
62
+ console.print()
63
+ auth_service.show_login_info()
64
+ else:
65
+ console.print(f"[red]Failed to set '{name}' as default credentials.[/red]")
@@ -0,0 +1,22 @@
1
+ from __future__ import annotations
2
+
3
+ import rich_click as click
4
+
5
+ from hcli.commands.auth.key.create import create
6
+ from hcli.commands.auth.key.install import install_key
7
+ from hcli.commands.auth.key.list import list_keys
8
+ from hcli.commands.auth.key.revoke import revoke
9
+ from hcli.commands.auth.key.uninstall import uninstall_key
10
+
11
+
12
+ @click.group()
13
+ def key() -> None:
14
+ """API key management."""
15
+ pass
16
+
17
+
18
+ key.add_command(create)
19
+ key.add_command(list_keys, name="list")
20
+ key.add_command(revoke)
21
+ key.add_command(install_key)
22
+ key.add_command(uninstall_key)
@@ -0,0 +1,77 @@
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+
5
+ import questionary
6
+ import rich_click as click
7
+
8
+ from hcli.commands.common import safe_ask_async
9
+ from hcli.lib.api.keys import keys
10
+ from hcli.lib.auth import get_auth_service
11
+ from hcli.lib.commands import async_command, require_auth
12
+ from hcli.lib.console import console
13
+
14
+
15
+ @click.command()
16
+ @click.argument("name", required=False)
17
+ @require_auth
18
+ @async_command
19
+ async def create(name: str | None) -> None:
20
+ """Create a new API key."""
21
+ console.print("[yellow]The key will be displayed only once, so make sure to save it in a secure place.[/yellow]")
22
+
23
+ # Get the key name from argument or prompt
24
+ key_name = name or await safe_ask_async(questionary.text("Enter the name for this key", default="hcli"))
25
+ if not key_name:
26
+ console.print("[red]Key name is required[/red]")
27
+ return
28
+
29
+ try:
30
+ # Check if a key with the same name already exists
31
+ existing_keys = await keys.get_keys()
32
+ if any(k.name == key_name for k in existing_keys):
33
+ console.print(f"[red]An API key with name [underline]{key_name}[/underline] already exists.[/red]")
34
+ sys.exit(1)
35
+
36
+ # Confirm key creation
37
+ if not await safe_ask_async(questionary.confirm(f"Do you want to create a new API key {key_name}?")):
38
+ console.print("[yellow]Key creation cancelled.[/yellow]")
39
+ return
40
+
41
+ # Create the key
42
+ console.print(f"[blue]Creating API key '[bold]{key_name}[/bold]'...[/blue]")
43
+ token = await keys.create_key(key_name)
44
+ console.print(f"[green]API key created:[/green] [bold]{token}[/bold]")
45
+
46
+ # Ask if user wants to install this key for hcli
47
+ if await safe_ask_async(questionary.confirm("Do you want to use this key for hcli?")):
48
+ auth_service = get_auth_service()
49
+ auth_service.init()
50
+
51
+ console.print("[blue]Installing API key as credentials...[/blue]")
52
+ source = await auth_service.add_api_key_credentials(key_name, token)
53
+
54
+ if source:
55
+ sources_count_before = len(auth_service.list_credentials()) - 1
56
+
57
+ if sources_count_before == 0:
58
+ # First credentials - simplified message
59
+ console.print(f"[green]API key credentials installed for {source.email}[/green]")
60
+ else:
61
+ # Additional credentials - detailed message
62
+ console.print(f"[green]API key credentials '{source.name}' created successfully![/green]")
63
+ console.print(f"Email: {source.email}")
64
+
65
+ # Ask if user wants to set as default
66
+ set_default = await safe_ask_async(
67
+ questionary.confirm(f"Set '{source.name}' as the default credentials?", default=True)
68
+ )
69
+ if set_default:
70
+ auth_service.set_default_credentials(source.name)
71
+ console.print(f"[green]'{source.name}' set as default credentials.[/green]")
72
+ else:
73
+ console.print("[red]Failed to create credentials. The API key may be invalid.[/red]")
74
+
75
+ except Exception as e:
76
+ console.print(f"[red]Failed to create API key: {e}[/red]")
77
+ sys.exit(1)