janito 3.4.0__py3-none-any.whl → 3.5.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 (162) hide show
  1. janito/README.md +3 -0
  2. janito/cli/chat_mode/bindings.py +50 -0
  3. janito/cli/chat_mode/session.py +12 -1
  4. janito/cli/chat_mode/shell/commands/multi.py +5 -0
  5. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +47 -33
  6. janito/cli/cli_commands/check_tools.py +212 -0
  7. janito/cli/cli_commands/list_plugins.py +52 -43
  8. janito/cli/core/getters.py +3 -0
  9. janito/cli/core/model_guesser.py +40 -24
  10. janito/cli/main_cli.py +9 -12
  11. janito/cli/prompt_core.py +47 -9
  12. janito/cli/rich_terminal_reporter.py +2 -2
  13. janito/drivers/openai/driver.py +1 -0
  14. janito/drivers/zai/driver.py +1 -0
  15. janito/i18n/it.py +46 -46
  16. janito/llm/agent.py +32 -16
  17. janito/llm/auth_utils.py +14 -5
  18. janito/llm/cancellation_manager.py +63 -0
  19. janito/llm/driver.py +8 -0
  20. janito/llm/enter_cancellation.py +107 -0
  21. janito/plugin_system/__init__.py +10 -0
  22. janito/{plugins → plugin_system}/base.py +5 -2
  23. janito/plugin_system/core_loader.py +217 -0
  24. janito/plugin_system/core_loader_fixed.py +225 -0
  25. janito/plugins/__init__.py +31 -12
  26. janito/plugins/auto_loader.py +12 -11
  27. janito/plugins/auto_loader_fixed.py +12 -11
  28. janito/plugins/builtin.py +15 -1
  29. janito/plugins/core/__init__.py +7 -0
  30. janito/plugins/core/codeanalyzer/__init__.py +43 -0
  31. janito/plugins/core/filemanager/__init__.py +124 -0
  32. janito/plugins/core/filemanager/tools/create_file.py +87 -0
  33. janito/plugins/core/filemanager/tools/replace_text_in_file.py +270 -0
  34. janito/plugins/core/imagedisplay/__init__.py +14 -0
  35. janito/plugins/core/imagedisplay/plugin.py +51 -0
  36. janito/plugins/core/imagedisplay/tools/__init__.py +1 -0
  37. janito/plugins/core/imagedisplay/tools/show_image.py +83 -0
  38. janito/{tools/adapters/local → plugins/core/imagedisplay/tools}/show_image_grid.py +13 -5
  39. janito/plugins/core/system/__init__.py +23 -0
  40. janito/plugins/core_adapter.py +89 -11
  41. janito/plugins/dev/__init__.py +7 -0
  42. janito/plugins/dev/pythondev/__init__.py +37 -0
  43. janito/plugins/dev/visualization/__init__.py +23 -0
  44. janito/plugins/discovery.py +5 -5
  45. janito/plugins/discovery_core.py +14 -9
  46. janito/plugins/example_plugin.py +108 -0
  47. janito/plugins/manager.py +1 -1
  48. janito/plugins/tools/__init__.py +10 -0
  49. janito/{tools/adapters/local → plugins/tools}/ask_user.py +3 -3
  50. janito/plugins/tools/copy_file.py +87 -0
  51. janito/plugins/tools/core_tools_plugin.py +87 -0
  52. janito/plugins/tools/create_directory.py +70 -0
  53. janito/{tools/adapters/local → plugins/tools}/create_file.py +6 -6
  54. janito/plugins/tools/decorators.py +19 -0
  55. janito/plugins/tools/delete_text_in_file.py +134 -0
  56. janito/{tools/adapters/local → plugins/tools}/fetch_url.py +3 -3
  57. janito/plugins/tools/find_files.py +143 -0
  58. janito/plugins/tools/get_file_outline/__init__.py +7 -0
  59. janito/plugins/tools/get_file_outline/core.py +122 -0
  60. janito/plugins/tools/get_file_outline/java_outline.py +47 -0
  61. janito/plugins/tools/get_file_outline/markdown_outline.py +14 -0
  62. janito/plugins/tools/get_file_outline/python_outline.py +303 -0
  63. janito/plugins/tools/get_file_outline/search_outline.py +36 -0
  64. janito/plugins/tools/move_file.py +131 -0
  65. janito/plugins/tools/open_html_in_browser.py +51 -0
  66. janito/plugins/tools/open_url.py +37 -0
  67. janito/plugins/tools/python_code_run.py +172 -0
  68. janito/plugins/tools/python_command_run.py +171 -0
  69. janito/plugins/tools/python_file_run.py +172 -0
  70. janito/plugins/tools/read_chart.py +259 -0
  71. janito/plugins/tools/read_files.py +58 -0
  72. janito/plugins/tools/remove_directory.py +55 -0
  73. janito/plugins/tools/remove_file.py +58 -0
  74. janito/{tools/adapters/local → plugins/tools}/replace_text_in_file.py +4 -4
  75. janito/plugins/tools/run_bash_command.py +183 -0
  76. janito/plugins/tools/run_powershell_command.py +218 -0
  77. janito/plugins/tools/search_text/__init__.py +7 -0
  78. janito/plugins/tools/search_text/core.py +205 -0
  79. janito/plugins/tools/search_text/match_lines.py +67 -0
  80. janito/plugins/tools/search_text/pattern_utils.py +73 -0
  81. janito/plugins/tools/search_text/traverse_directory.py +145 -0
  82. janito/{tools/adapters/local → plugins/tools}/show_image.py +15 -6
  83. janito/plugins/tools/show_image_grid.py +85 -0
  84. janito/plugins/tools/validate_file_syntax/__init__.py +7 -0
  85. janito/plugins/tools/validate_file_syntax/core.py +114 -0
  86. janito/plugins/tools/validate_file_syntax/css_validator.py +35 -0
  87. janito/plugins/tools/validate_file_syntax/html_validator.py +100 -0
  88. janito/plugins/tools/validate_file_syntax/jinja2_validator.py +50 -0
  89. janito/plugins/tools/validate_file_syntax/js_validator.py +27 -0
  90. janito/plugins/tools/validate_file_syntax/json_validator.py +6 -0
  91. janito/plugins/tools/validate_file_syntax/markdown_validator.py +109 -0
  92. janito/plugins/tools/validate_file_syntax/ps1_validator.py +32 -0
  93. janito/plugins/tools/validate_file_syntax/python_validator.py +5 -0
  94. janito/plugins/tools/validate_file_syntax/xml_validator.py +11 -0
  95. janito/plugins/tools/validate_file_syntax/yaml_validator.py +6 -0
  96. janito/plugins/tools/view_file.py +172 -0
  97. janito/plugins/ui/__init__.py +7 -0
  98. janito/plugins/ui/userinterface/__init__.py +16 -0
  99. janito/plugins/ui/userinterface/tools/ask_user.py +110 -0
  100. janito/plugins/web/__init__.py +7 -0
  101. janito/plugins/web/webtools/__init__.py +33 -0
  102. janito/plugins/web/webtools/tools/fetch_url.py +458 -0
  103. janito/providers/__init__.py +1 -0
  104. janito/providers/together/__init__.py +1 -0
  105. janito/providers/together/model_info.py +69 -0
  106. janito/providers/together/provider.py +108 -0
  107. janito/tools/__init__.py +31 -7
  108. janito/tools/adapters/__init__.py +6 -1
  109. janito/tools/adapters/local/__init__.py +7 -70
  110. janito/tools/cli_initializer.py +88 -0
  111. janito/tools/initialize.py +70 -0
  112. janito/tools/loop_protection_decorator.py +114 -117
  113. janito-3.5.0.dist-info/METADATA +229 -0
  114. {janito-3.4.0.dist-info → janito-3.5.0.dist-info}/RECORD +158 -86
  115. janito/plugins/core_loader.py +0 -120
  116. janito/plugins/core_loader_fixed.py +0 -125
  117. janito/tools/function_adapter.py +0 -65
  118. janito-3.4.0.dist-info/METADATA +0 -84
  119. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/__init__.py +0 -0
  120. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/core.py +0 -0
  121. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/java_outline.py +0 -0
  122. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/markdown_outline.py +0 -0
  123. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/python_outline.py +0 -0
  124. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/get_file_outline/search_outline.py +0 -0
  125. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/search_text/__init__.py +0 -0
  126. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/search_text/core.py +0 -0
  127. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/search_text/match_lines.py +0 -0
  128. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/search_text/pattern_utils.py +0 -0
  129. /janito/{tools/adapters/local → plugins/core/codeanalyzer/tools}/search_text/traverse_directory.py +0 -0
  130. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/copy_file.py +0 -0
  131. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/create_directory.py +0 -0
  132. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/delete_text_in_file.py +0 -0
  133. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/find_files.py +0 -0
  134. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/move_file.py +0 -0
  135. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/read_files.py +0 -0
  136. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/remove_directory.py +0 -0
  137. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/remove_file.py +0 -0
  138. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/__init__.py +0 -0
  139. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/core.py +0 -0
  140. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/css_validator.py +0 -0
  141. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/html_validator.py +0 -0
  142. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/jinja2_validator.py +0 -0
  143. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/js_validator.py +0 -0
  144. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/json_validator.py +0 -0
  145. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/markdown_validator.py +0 -0
  146. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/ps1_validator.py +0 -0
  147. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/python_validator.py +0 -0
  148. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/xml_validator.py +0 -0
  149. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/validate_file_syntax/yaml_validator.py +0 -0
  150. /janito/{tools/adapters/local → plugins/core/filemanager/tools}/view_file.py +0 -0
  151. /janito/{tools/adapters/local → plugins/core/system/tools}/run_bash_command.py +0 -0
  152. /janito/{tools/adapters/local → plugins/core/system/tools}/run_powershell_command.py +0 -0
  153. /janito/{tools/adapters/local → plugins/dev/pythondev/tools}/python_code_run.py +0 -0
  154. /janito/{tools/adapters/local → plugins/dev/pythondev/tools}/python_command_run.py +0 -0
  155. /janito/{tools/adapters/local → plugins/dev/pythondev/tools}/python_file_run.py +0 -0
  156. /janito/{tools/adapters/local → plugins/dev/visualization/tools}/read_chart.py +0 -0
  157. /janito/{tools/adapters/local → plugins/web/webtools/tools}/open_html_in_browser.py +0 -0
  158. /janito/{tools/adapters/local → plugins/web/webtools/tools}/open_url.py +0 -0
  159. {janito-3.4.0.dist-info → janito-3.5.0.dist-info}/WHEEL +0 -0
  160. {janito-3.4.0.dist-info → janito-3.5.0.dist-info}/entry_points.txt +0 -0
  161. {janito-3.4.0.dist-info → janito-3.5.0.dist-info}/licenses/LICENSE +0 -0
  162. {janito-3.4.0.dist-info → janito-3.5.0.dist-info}/top_level.txt +0 -0
@@ -1,120 +0,0 @@
1
- """
2
- Core plugin loader that properly handles function-based plugins.
3
-
4
- This module provides a simplified approach to load core plugins
5
- without the complex discovery mechanism.
6
- """
7
-
8
- import importlib.util
9
- import sys
10
- from pathlib import Path
11
- from typing import Optional
12
-
13
- from janito.plugins.base import Plugin, PluginMetadata
14
- from janito.tools.function_adapter import create_function_tool
15
- from janito.tools.tool_base import ToolBase
16
-
17
-
18
- class CorePlugin(Plugin):
19
- """Simple core plugin implementation."""
20
-
21
- def __init__(self, name: str, description: str, tools: list):
22
- super().__init__()
23
- self._plugin_name = name
24
- self._description = description
25
- self._tools = tools
26
- self._tool_classes = []
27
-
28
- def get_metadata(self) -> PluginMetadata:
29
- return PluginMetadata(
30
- name=self._plugin_name,
31
- version="1.0.0",
32
- description=self._description,
33
- author="Janito",
34
- license="MIT",
35
- )
36
-
37
- def get_tools(self) -> list:
38
- return self._tool_classes
39
-
40
- def initialize(self):
41
- """Initialize by creating tool classes."""
42
- self._tool_classes = []
43
- for tool_func in self._tools:
44
- if callable(tool_func):
45
- tool_class = create_function_tool(tool_func)
46
- self._tool_classes.append(tool_class)
47
-
48
-
49
- def load_core_plugin(plugin_name: str) -> Optional[Plugin]:
50
- """
51
- Load a core plugin by name.
52
-
53
- Args:
54
- plugin_name: Name of the plugin (e.g., 'core.filemanager')
55
-
56
- Returns:
57
- Plugin instance if loaded successfully
58
- """
59
- try:
60
- # Parse plugin name
61
- if "." not in plugin_name:
62
- return None
63
-
64
- parts = plugin_name.split(".")
65
- if len(parts) != 2:
66
- return None
67
-
68
- package_name, submodule_name = parts
69
-
70
- # Build path to plugin
71
- plugin_path = Path("plugins") / package_name / submodule_name / "__init__.py"
72
- if not plugin_path.exists():
73
- return None
74
-
75
- # Load the module
76
- spec = importlib.util.spec_from_file_location(plugin_name, plugin_path)
77
- if spec is None or spec.loader is None:
78
- return None
79
-
80
- module = importlib.util.module_from_spec(spec)
81
- spec.loader.exec_module(module)
82
-
83
- # Get plugin info
84
- name = getattr(module, "__plugin_name__", plugin_name)
85
- description = getattr(module, "__plugin_description__", f"Core plugin: {plugin_name}")
86
- tools = getattr(module, "__plugin_tools__", [])
87
-
88
- if not tools:
89
- return None
90
-
91
- # Create plugin
92
- plugin = CorePlugin(name, description, tools)
93
- plugin.initialize()
94
- return plugin
95
-
96
- except Exception as e:
97
- print(f"Error loading core plugin {plugin_name}: {e}")
98
- return None
99
-
100
-
101
- def get_core_plugins() -> list:
102
- """Get list of all available core plugins."""
103
- core_plugins = [
104
- "core.filemanager",
105
- "core.codeanalyzer",
106
- "core.system",
107
- "core.imagedisplay",
108
- "dev.pythondev",
109
- "dev.visualization",
110
- "ui.userinterface",
111
- "web.webtools",
112
- ]
113
-
114
- available = []
115
- for plugin_name in core_plugins:
116
- plugin = load_core_plugin(plugin_name)
117
- if plugin:
118
- available.append(plugin_name)
119
-
120
- return available
@@ -1,125 +0,0 @@
1
- """
2
- Fixed core plugin loader.
3
-
4
- This module provides a working implementation to load core plugins
5
- by directly using the Plugin base class properly.
6
- """
7
-
8
- import importlib.util
9
- import sys
10
- from pathlib import Path
11
- from typing import Optional, List, Type
12
-
13
- from janito.plugins.base import Plugin, PluginMetadata
14
- from janito.tools.function_adapter import create_function_tool
15
- from janito.tools.tool_base import ToolBase
16
-
17
-
18
- class CorePlugin(Plugin):
19
- """Working core plugin implementation."""
20
-
21
- def __init__(self, name: str, description: str, tools: list):
22
- self._plugin_name = name
23
- self._description = description
24
- self._tools = tools
25
- self._tool_classes = []
26
- super().__init__() # Call super after setting attributes
27
-
28
- def get_metadata(self) -> PluginMetadata:
29
- return PluginMetadata(
30
- name=self._plugin_name,
31
- version="1.0.0",
32
- description=self._description,
33
- author="Janito",
34
- license="MIT",
35
- )
36
-
37
- def get_tools(self) -> List[Type[ToolBase]]:
38
- return self._tool_classes
39
-
40
- def initialize(self):
41
- """Initialize by creating tool classes."""
42
- self._tool_classes = []
43
- for tool_func in self._tools:
44
- if callable(tool_func):
45
- tool_class = create_function_tool(tool_func)
46
- self._tool_classes.append(tool_class)
47
-
48
-
49
- def load_core_plugin(plugin_name: str) -> Optional[Plugin]:
50
- """
51
- Load a core plugin by name.
52
-
53
- Args:
54
- plugin_name: Name of the plugin (e.g., 'core.filemanager')
55
-
56
- Returns:
57
- Plugin instance if loaded successfully
58
- """
59
- try:
60
- # Parse plugin name
61
- if "." not in plugin_name:
62
- return None
63
-
64
- parts = plugin_name.split(".")
65
- if len(parts) != 2:
66
- return None
67
-
68
- package_name, submodule_name = parts
69
-
70
- # Handle imagedisplay specially
71
- if plugin_name == "core.imagedisplay":
72
- # Import the actual plugin class
73
- try:
74
- from plugins.core.imagedisplay.plugin import ImageDisplayPlugin
75
- return ImageDisplayPlugin()
76
- except ImportError:
77
- # If import fails, return None - don't return True
78
- return None
79
-
80
- # Build path to plugin
81
- plugin_path = Path("plugins") / package_name / submodule_name / "__init__.py"
82
- if not plugin_path.exists():
83
- return None
84
-
85
- # Load the module
86
- spec = importlib.util.spec_from_file_location(plugin_name, plugin_path)
87
- if spec is None or spec.loader is None:
88
- return None
89
-
90
- module = importlib.util.module_from_spec(spec)
91
- spec.loader.exec_module(module)
92
-
93
- # Get plugin info
94
- name = getattr(module, "__plugin_name__", plugin_name)
95
- description = getattr(module, "__plugin_description__", f"Core plugin: {plugin_name}")
96
- tools = getattr(module, "__plugin_tools__", [])
97
-
98
- if not tools:
99
- return None
100
-
101
- # Create plugin
102
- plugin = CorePlugin(name, description, tools)
103
- plugin.initialize()
104
- return plugin
105
-
106
- except Exception as e:
107
- print(f"Error loading core plugin {plugin_name}: {e}")
108
- return None
109
-
110
-
111
- def get_core_plugins() -> list:
112
- """Get list of all available core plugins."""
113
- core_plugins = [
114
- "core.filemanager",
115
- "core.codeanalyzer",
116
- "core.system",
117
- "core.imagedisplay",
118
- "dev.pythondev",
119
- "dev.visualization",
120
- "ui.userinterface",
121
- "web.webtools",
122
- ]
123
-
124
- # All core plugins are always available
125
- return core_plugins
@@ -1,65 +0,0 @@
1
- """
2
- Function-to-Tool adapter for core plugins.
3
-
4
- This module provides a way to wrap function-based tools into proper ToolBase classes.
5
- """
6
-
7
- import inspect
8
- from typing import Any, Dict, List, Optional, get_type_hints
9
- from janito.tools.tool_base import ToolBase, ToolPermissions
10
-
11
-
12
- class FunctionToolAdapter(ToolBase):
13
- """Adapter that wraps a function into a ToolBase class."""
14
-
15
- def __init__(self, func, tool_name: str = None, description: str = None):
16
- super().__init__()
17
- self._func = func
18
- self.tool_name = tool_name or func.__name__
19
- self._description = description or func.__doc__ or f"Tool: {self.tool_name}"
20
- self.permissions = ToolPermissions(read=True, write=True, execute=True)
21
-
22
- def run(self, **kwargs) -> Any:
23
- """Execute the wrapped function."""
24
- return self._func(**kwargs)
25
-
26
- def get_signature(self) -> Dict[str, Any]:
27
- """Get function signature for documentation."""
28
- sig = inspect.signature(self._func)
29
- type_hints = get_type_hints(self._func)
30
-
31
- params = {}
32
- for name, param in sig.parameters.items():
33
- param_info = {
34
- "type": str(type_hints.get(name, Any)),
35
- "default": param.default if param.default != inspect.Parameter.empty else None,
36
- "required": param.default == inspect.Parameter.empty,
37
- }
38
- params[name] = param_info
39
-
40
- return {
41
- "name": self.tool_name,
42
- "description": self._description,
43
- "parameters": params,
44
- "return_type": str(type_hints.get("return", Any))
45
- }
46
-
47
-
48
- def create_function_tool(func, tool_name: str = None, description: str = None) -> type:
49
- """
50
- Create a ToolBase class from a function.
51
-
52
- Args:
53
- func: The function to wrap
54
- tool_name: Optional custom tool name
55
- description: Optional custom description
56
-
57
- Returns:
58
- A ToolBase subclass that wraps the function
59
- """
60
-
61
- class DynamicFunctionTool(FunctionToolAdapter):
62
- def __init__(self):
63
- super().__init__(func, tool_name, description)
64
-
65
- return DynamicFunctionTool
@@ -1,84 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: janito
3
- Version: 3.4.0
4
- Summary: A new Python package called janito.
5
- Author-email: João Pinto <janito@ikignosis.org>
6
- Project-URL: Homepage, https://github.com/ikignosis/janito
7
- Requires-Python: >=3.7
8
- Description-Content-Type: text/markdown
9
- License-File: LICENSE
10
- Requires-Dist: attrs==25.3.0
11
- Requires-Dist: rich==14.0.0
12
- Requires-Dist: pathspec==0.12.1
13
- Requires-Dist: setuptools>=61.0
14
- Requires-Dist: pyyaml>=6.0
15
- Requires-Dist: jinja2>=3.0.0
16
- Requires-Dist: prompt_toolkit>=3.0.51
17
- Requires-Dist: lxml>=5.4.0
18
- Requires-Dist: requests>=2.32.4
19
- Requires-Dist: bs4>=0.0.2
20
- Requires-Dist: questionary>=2.0.1
21
- Requires-Dist: openai>=1.68.0
22
- Requires-Dist: Pillow>=10.0.0
23
- Provides-Extra: dev
24
- Requires-Dist: pytest; extra == "dev"
25
- Requires-Dist: pre-commit; extra == "dev"
26
- Requires-Dist: ruff==0.11.9; extra == "dev"
27
- Requires-Dist: detect-secrets==1.4.0; extra == "dev"
28
- Requires-Dist: codespell==2.4.1; extra == "dev"
29
- Requires-Dist: black; extra == "dev"
30
- Requires-Dist: questionary>=2.0.1; extra == "dev"
31
- Requires-Dist: setuptools_scm>=8.0; extra == "dev"
32
- Provides-Extra: coder
33
- Requires-Dist: janito-coder; extra == "coder"
34
- Dynamic: license-file
35
-
36
- # nctl
37
-
38
- ```bash
39
- $ nctl --help
40
- Usage: nctl <command>
41
-
42
- Interact with Nine API resources. See https://docs.nineapis.ch for the full API docs.
43
-
44
- Run "nctl <command> --help" for more information on a command.
45
- ```
46
-
47
- ## Setup
48
-
49
- ```bash
50
- # If you have go already installed
51
- go install github.com/ninech/nctl@latest
52
-
53
- # Homebrew
54
- brew install ninech/taps/nctl
55
-
56
- # Debian/Ubuntu
57
- echo "deb [trusted=yes] https://repo.nine.ch/deb/ /" | sudo tee /etc/apt/sources.list.d/repo.nine.ch.list
58
- sudo apt-get update
59
- sudo apt-get install nctl
60
-
61
- # Fedora/RHEL
62
- cat <<EOF > /etc/yum.repos.d/repo.nine.ch.repo
63
- [repo.nine.ch]
64
- name=Nine Repo
65
- baseurl=https://repo.nine.ch/yum/
66
- enabled=1
67
- gpgcheck=0
68
- EOF
69
- dnf install nctl
70
-
71
- # Arch
72
- # Install yay: https://github.com/Jguer/yay#binary
73
- yay --version
74
- yay -S nctl-bin
75
- ```
76
-
77
- For Windows users, nctl is also built for arm64 and amd64. You can download the
78
- latest exe file from the [releases](https://github.com/ninech/nctl/releases) and
79
- install it.
80
-
81
- ## Getting started
82
-
83
- * login to the API using `nctl auth login`
84
- * run `nctl --help` to get a list of all available commands
File without changes