janito 2.26.0__py3-none-any.whl → 2.27.1__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.
- janito/cli/chat_mode/session.py +37 -23
- janito/cli/chat_mode/shell/commands/__init__.py +2 -0
- janito/cli/chat_mode/shell/commands/help.py +6 -1
- janito/cli/chat_mode/shell/commands/provider.py +25 -0
- janito/cli/chat_mode/toolbar.py +15 -1
- janito/cli/cli_commands/enable_disable_plugin.py +64 -0
- janito/cli/cli_commands/list_plugins.py +20 -4
- janito/cli/cli_commands/show_config.py +24 -0
- janito/cli/core/getters.py +6 -0
- janito/cli/core/runner.py +15 -1
- janito/cli/core/setters.py +18 -6
- janito/cli/main_cli.py +17 -6
- janito/plugins/builtin.py +84 -0
- janito/plugins/discovery.py +83 -1
- janito/plugins/manager.py +2 -0
- janito/tools/adapters/local/ask_user.py +7 -1
- janito/tools/adapters/local/fetch_url.py +80 -5
- janito/tools/base.py +11 -0
- {janito-2.26.0.dist-info → janito-2.27.1.dist-info}/METADATA +21 -1
- {janito-2.26.0.dist-info → janito-2.27.1.dist-info}/RECORD +24 -25
- janito-2.27.1.dist-info/top_level.txt +1 -0
- janito-2.26.0.dist-info/top_level.txt +0 -2
- janito-coder/janito_coder/__init__.py +0 -9
- janito-coder/janito_coder/plugins/__init__.py +0 -27
- janito-coder/janito_coder/plugins/code_navigator.py +0 -618
- janito-coder/janito_coder/plugins/git_analyzer.py +0 -273
- janito-coder/pyproject.toml +0 -347
- {janito-2.26.0.dist-info → janito-2.27.1.dist-info}/WHEEL +0 -0
- {janito-2.26.0.dist-info → janito-2.27.1.dist-info}/entry_points.txt +0 -0
- {janito-2.26.0.dist-info → janito-2.27.1.dist-info}/licenses/LICENSE +0 -0
janito/cli/chat_mode/session.py
CHANGED
@@ -130,25 +130,39 @@ class ChatSession:
|
|
130
130
|
profile = "Market Analyst"
|
131
131
|
|
132
132
|
if profile is None and role_arg is None and not python_profile and not market_profile:
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
133
|
+
# Skip interactive profile selection for list commands
|
134
|
+
from janito.cli.core.getters import GETTER_KEYS
|
135
|
+
|
136
|
+
# Check if any getter command is active - these don't need interactive mode
|
137
|
+
skip_profile_selection = False
|
138
|
+
if args is not None:
|
139
|
+
for key in GETTER_KEYS:
|
140
|
+
if getattr(args, key, False):
|
141
|
+
skip_profile_selection = True
|
142
|
+
break
|
143
|
+
|
144
|
+
if skip_profile_selection:
|
145
|
+
profile = "Developer with Python Tools" # Default for non-interactive commands
|
146
|
+
else:
|
147
|
+
try:
|
148
|
+
from janito.cli.chat_mode.session_profile_select import select_profile
|
149
|
+
|
150
|
+
result = select_profile()
|
151
|
+
if isinstance(result, dict):
|
152
|
+
profile = result.get("profile")
|
153
|
+
profile_system_prompt = result.get("profile_system_prompt")
|
154
|
+
no_tools_mode = result.get("no_tools_mode", False)
|
155
|
+
elif isinstance(result, str) and result.startswith("role:"):
|
156
|
+
role = result[len("role:") :].strip()
|
157
|
+
profile = "Developer with Python Tools"
|
158
|
+
else:
|
159
|
+
profile = (
|
160
|
+
"Developer with Python Tools"
|
161
|
+
if result == "Developer"
|
162
|
+
else result
|
163
|
+
)
|
164
|
+
except ImportError:
|
165
|
+
profile = "Raw Model Session (no tools, no context)"
|
152
166
|
if role_arg is not None:
|
153
167
|
role = role_arg
|
154
168
|
if profile is None:
|
@@ -209,9 +223,7 @@ class ChatSession:
|
|
209
223
|
|
210
224
|
self.console.print(f"[bold green]Janito Chat Mode v{__version__}[/bold green]")
|
211
225
|
self.console.print(f"[dim]Profile: {self.profile}[/dim]")
|
212
|
-
|
213
|
-
"[green]/help for commands /exit or Ctrl+C to quit[/green]"
|
214
|
-
)
|
226
|
+
|
215
227
|
import os
|
216
228
|
|
217
229
|
cwd = os.getcwd()
|
@@ -226,7 +238,7 @@ class ChatSession:
|
|
226
238
|
|
227
239
|
priv_status = get_privilege_status_message()
|
228
240
|
self.console.print(
|
229
|
-
f"[green]Working Dir:[/green] {cwd_display} | {priv_status}"
|
241
|
+
f"[green]Working Dir:[/green] [cyan]{cwd_display}[/cyan] | {priv_status}"
|
230
242
|
)
|
231
243
|
|
232
244
|
if self.multi_line_mode:
|
@@ -282,6 +294,8 @@ class ChatSession:
|
|
282
294
|
|
283
295
|
def _process_prompt(self, cmd_input):
|
284
296
|
try:
|
297
|
+
# Clear screen before processing new prompt
|
298
|
+
self.console.clear()
|
285
299
|
import time
|
286
300
|
|
287
301
|
final_event = (
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from .base import ShellCmdHandler
|
2
2
|
from .history_view import ViewShellHandler
|
3
3
|
from .lang import LangShellHandler
|
4
|
+
from .provider import ProviderCmdHandler
|
4
5
|
|
5
6
|
from .prompt import PromptShellHandler, RoleShellHandler
|
6
7
|
from .multi import MultiShellHandler
|
@@ -43,6 +44,7 @@ COMMAND_HANDLERS = {
|
|
43
44
|
"/multi": MultiShellHandler,
|
44
45
|
"/help": HelpShellHandler,
|
45
46
|
"/security": SecurityCommand,
|
47
|
+
"/provider": ProviderCmdHandler,
|
46
48
|
}
|
47
49
|
|
48
50
|
|
@@ -7,7 +7,12 @@ class HelpShellHandler(ShellCmdHandler):
|
|
7
7
|
help_text = "Show this help message"
|
8
8
|
|
9
9
|
def run(self):
|
10
|
-
|
10
|
+
# Ensure /provider command is registered before showing help
|
11
|
+
from janito.cli.chat_mode.shell.commands import COMMAND_HANDLERS
|
12
|
+
if "/provider" not in COMMAND_HANDLERS:
|
13
|
+
from janito.cli.chat_mode.shell.commands.provider import ProviderCmdHandler
|
14
|
+
COMMAND_HANDLERS["/provider"] = ProviderCmdHandler
|
15
|
+
|
11
16
|
from ._priv_check import user_has_any_privileges
|
12
17
|
|
13
18
|
shared_console.print("[bold magenta]Available commands:[/bold magenta]")
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from janito.cli.core.getters import get_current_provider
|
2
|
+
from janito.cli.core.setters import set_provider
|
3
|
+
from janito.cli.chat_mode.shell.commands.base import ShellCmdHandler
|
4
|
+
from janito.cli.console import shared_console as console
|
5
|
+
|
6
|
+
class ProviderCmdHandler(ShellCmdHandler):
|
7
|
+
"""Handler for the /provider command to view or change the current provider."""
|
8
|
+
|
9
|
+
help_text = "Manage the current LLM provider. Usage: /provider [provider_name]"
|
10
|
+
|
11
|
+
def run(self):
|
12
|
+
"""Execute the provider command."""
|
13
|
+
if not self.after_cmd_line.strip():
|
14
|
+
# No argument provided, show current provider
|
15
|
+
current = get_current_provider()
|
16
|
+
console.print(f"[bold]Current provider:[/bold] {current}")
|
17
|
+
return
|
18
|
+
|
19
|
+
# Argument provided, attempt to change provider
|
20
|
+
new_provider = self.after_cmd_line.strip()
|
21
|
+
try:
|
22
|
+
set_provider(new_provider)
|
23
|
+
console.print(f"[bold green]Provider changed to:[/bold green] {new_provider}")
|
24
|
+
except ValueError as e:
|
25
|
+
console.print(f"[bold red]Error:[/bold red] {str(e)}")
|
janito/cli/chat_mode/toolbar.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import os
|
1
2
|
from prompt_toolkit.formatted_text import HTML
|
2
3
|
from janito.performance_collector import PerformanceCollector
|
3
4
|
from janito.cli.config import config
|
@@ -17,7 +18,20 @@ def format_tokens(n, tag=None):
|
|
17
18
|
|
18
19
|
|
19
20
|
def assemble_first_line(provider_name, model_name, role, agent=None):
|
20
|
-
|
21
|
+
cwd = os.getcwd()
|
22
|
+
home = os.path.expanduser("~")
|
23
|
+
|
24
|
+
# Convert to relative path if under home directory
|
25
|
+
if cwd.startswith(home):
|
26
|
+
cwd_display = "~" + cwd[len(home):]
|
27
|
+
else:
|
28
|
+
cwd_display = cwd
|
29
|
+
|
30
|
+
# Shorten long paths for display
|
31
|
+
if len(cwd_display) > 50:
|
32
|
+
cwd_display = "..." + cwd_display[-47:]
|
33
|
+
|
34
|
+
return f" Janito {VERSION} | Provider: <provider>{provider_name}</provider> | Model: <model>{model_name}</model> | Dir: <model>{cwd_display}</model>"
|
21
35
|
|
22
36
|
|
23
37
|
def assemble_bindings_line(width, permissions=None):
|
@@ -0,0 +1,64 @@
|
|
1
|
+
"""
|
2
|
+
CLI command to enable/disable plugins by modifying plugins.json configuration.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import argparse
|
6
|
+
import json
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Dict, Any
|
9
|
+
from janito.plugins.config import load_plugins_config, save_plugins_config, get_plugins_config_path
|
10
|
+
from janito.plugins.manager import PluginManager
|
11
|
+
|
12
|
+
|
13
|
+
def handle_enable_plugin(args: argparse.Namespace) -> None:
|
14
|
+
"""Enable a plugin by adding it to plugins.json."""
|
15
|
+
config = load_plugins_config()
|
16
|
+
|
17
|
+
if 'plugins' not in config:
|
18
|
+
config['plugins'] = {}
|
19
|
+
if 'load' not in config['plugins']:
|
20
|
+
config['plugins']['load'] = {}
|
21
|
+
|
22
|
+
# Set the plugin to enabled (True)
|
23
|
+
config['plugins']['load'][args.plugin_name] = True
|
24
|
+
|
25
|
+
if save_plugins_config(config):
|
26
|
+
print(f"Plugin '{args.plugin_name}' has been enabled in {get_plugins_config_path()}")
|
27
|
+
print("Note: You may need to reload the plugin in the current session with 'plugin reload'")
|
28
|
+
else:
|
29
|
+
print(f"Error: Failed to enable plugin '{args.plugin_name}'")
|
30
|
+
|
31
|
+
|
32
|
+
def handle_disable_plugin(args: argparse.Namespace) -> None:
|
33
|
+
"""Disable a plugin by removing it from plugins.json or setting it to False."""
|
34
|
+
config = load_plugins_config()
|
35
|
+
|
36
|
+
if 'plugins' in config and 'load' in config['plugins'] and args.plugin_name in config['plugins']['load']:
|
37
|
+
# Remove the plugin entry or set it to False
|
38
|
+
if args.remove:
|
39
|
+
del config['plugins']['load'][args.plugin_name]
|
40
|
+
action = "removed"
|
41
|
+
else:
|
42
|
+
config['plugins']['load'][args.plugin_name] = False
|
43
|
+
action = "disabled"
|
44
|
+
|
45
|
+
if save_plugins_config(config):
|
46
|
+
print(f"Plugin '{args.plugin_name}' has been {action} in {get_plugins_config_path()}")
|
47
|
+
print("Note: You may need to unload the plugin in the current session with 'plugin unload'")
|
48
|
+
else:
|
49
|
+
print(f"Error: Failed to {action} plugin '{args.plugin_name}'")
|
50
|
+
else:
|
51
|
+
print(f"Plugin '{args.plugin_name}' is not currently configured in plugins.json")
|
52
|
+
print("It may still be loaded in the current session, but won't be loaded on restart")
|
53
|
+
|
54
|
+
|
55
|
+
def add_enable_plugin_args(parser: argparse.ArgumentParser) -> None:
|
56
|
+
"""Add enable-plugin arguments to argument parser."""
|
57
|
+
parser.add_argument('plugin_name', help='Name of the plugin to enable')
|
58
|
+
|
59
|
+
|
60
|
+
def add_disable_plugin_args(parser: argparse.ArgumentParser) -> None:
|
61
|
+
"""Add disable-plugin arguments to argument parser."""
|
62
|
+
parser.add_argument('plugin_name', help='Name of the plugin to disable')
|
63
|
+
parser.add_argument('--remove', action='store_true',
|
64
|
+
help='Completely remove the plugin from config instead of setting to False')
|
@@ -7,6 +7,7 @@ from typing import List, Dict, Any
|
|
7
7
|
from janito.plugins.discovery import list_available_plugins, discover_plugins
|
8
8
|
import os
|
9
9
|
from janito.plugins.manager import PluginManager
|
10
|
+
from janito.plugins.builtin import BuiltinPluginRegistry
|
10
11
|
|
11
12
|
|
12
13
|
def handle_list_plugins(args: argparse.Namespace) -> None:
|
@@ -15,10 +16,23 @@ def handle_list_plugins(args: argparse.Namespace) -> None:
|
|
15
16
|
if getattr(args, 'list_plugins_available', False):
|
16
17
|
# List available plugins
|
17
18
|
available = list_available_plugins()
|
18
|
-
|
19
|
+
builtin_plugins = BuiltinPluginRegistry.list_builtin_plugins()
|
20
|
+
|
21
|
+
if available or builtin_plugins:
|
19
22
|
print("Available plugins:")
|
20
|
-
|
21
|
-
|
23
|
+
|
24
|
+
# Show builtin plugins first
|
25
|
+
if builtin_plugins:
|
26
|
+
print(" Builtin plugins:")
|
27
|
+
for plugin in builtin_plugins:
|
28
|
+
print(f" - {plugin} [BUILTIN]")
|
29
|
+
|
30
|
+
# Show other available plugins
|
31
|
+
other_plugins = [p for p in available if p not in builtin_plugins]
|
32
|
+
if other_plugins:
|
33
|
+
print(" External plugins:")
|
34
|
+
for plugin in other_plugins:
|
35
|
+
print(f" - {plugin}")
|
22
36
|
else:
|
23
37
|
print("No plugins found in search paths")
|
24
38
|
print("Search paths:")
|
@@ -65,8 +79,10 @@ def handle_list_plugins(args: argparse.Namespace) -> None:
|
|
65
79
|
print("Loaded plugins:")
|
66
80
|
for plugin_name in loaded:
|
67
81
|
metadata = manager.get_plugin_metadata(plugin_name)
|
82
|
+
is_builtin = BuiltinPluginRegistry.is_builtin(plugin_name)
|
68
83
|
if metadata:
|
69
|
-
|
84
|
+
builtin_tag = " [BUILTIN]" if is_builtin else ""
|
85
|
+
print(f" - {metadata.name} v{metadata.version}{builtin_tag}")
|
70
86
|
print(f" {metadata.description}")
|
71
87
|
if metadata.author:
|
72
88
|
print(f" Author: {metadata.author}")
|
@@ -42,6 +42,30 @@ def handle_show_config(args):
|
|
42
42
|
console.print(f"[bold yellow]Current provider:[/bold yellow] {provider!r}\n")
|
43
43
|
if model is not None:
|
44
44
|
console.print(f"[bold yellow]Global model:[/bold yellow] {model!r}\n")
|
45
|
+
|
46
|
+
# Show all configuration values
|
47
|
+
console.print("[bold green]Configuration values:[/bold green]")
|
48
|
+
all_config = config.all()
|
49
|
+
if all_config:
|
50
|
+
for key, value in sorted(all_config.items()):
|
51
|
+
# Hide sensitive values like API keys
|
52
|
+
if 'api_key' in key.lower() and value:
|
53
|
+
masked_value = value[:8] + '***' + value[-4:] if len(value) > 12 else '***'
|
54
|
+
console.print(f" {key}: {masked_value!r}")
|
55
|
+
elif key == 'providers' and isinstance(value, dict):
|
56
|
+
# Handle nested provider configs with API keys
|
57
|
+
masked_providers = {}
|
58
|
+
for provider_name, provider_config in value.items():
|
59
|
+
masked_config = dict(provider_config)
|
60
|
+
if 'api_key' in masked_config and masked_config['api_key']:
|
61
|
+
api_key = masked_config['api_key']
|
62
|
+
masked_config['api_key'] = api_key[:8] + '***' + api_key[-4:] if len(api_key) > 12 else '***'
|
63
|
+
masked_providers[provider_name] = masked_config
|
64
|
+
console.print(f" {key}: {masked_providers!r}")
|
65
|
+
else:
|
66
|
+
console.print(f" {key}: {value!r}")
|
67
|
+
else:
|
68
|
+
console.print(" (no configuration values set)")
|
45
69
|
|
46
70
|
# Show disabled tools
|
47
71
|
from janito.tools.disabled_tools import load_disabled_tools_from_config
|
janito/cli/core/getters.py
CHANGED
@@ -13,6 +13,7 @@ from janito.cli.cli_commands.list_providers_region import handle_list_providers_
|
|
13
13
|
from janito.cli.cli_commands.list_plugins import handle_list_plugins
|
14
14
|
from functools import partial
|
15
15
|
from janito.provider_registry import ProviderRegistry
|
16
|
+
from janito.config import config as global_config
|
16
17
|
|
17
18
|
GETTER_KEYS = [
|
18
19
|
"show_config",
|
@@ -30,6 +31,10 @@ GETTER_KEYS = [
|
|
30
31
|
]
|
31
32
|
|
32
33
|
|
34
|
+
def get_current_provider():
|
35
|
+
"""Get the current provider from the global config."""
|
36
|
+
return global_config.get("provider", "none")
|
37
|
+
|
33
38
|
def handle_getter(args, config_mgr=None):
|
34
39
|
provider_instance = None
|
35
40
|
if getattr(args, "list_models", False):
|
@@ -56,6 +61,7 @@ def handle_getter(args, config_mgr=None):
|
|
56
61
|
"region_info": partial(handle_region_info, args),
|
57
62
|
"list_providers_region": partial(handle_list_providers_region, args),
|
58
63
|
"list_plugins": partial(handle_list_plugins, args),
|
64
|
+
"list_plugins_available": partial(handle_list_plugins, args),
|
59
65
|
"list_resources": partial(handle_list_plugins, args),
|
60
66
|
}
|
61
67
|
for arg in GETTER_KEYS:
|
janito/cli/core/runner.py
CHANGED
@@ -174,7 +174,21 @@ def handle_runner(
|
|
174
174
|
"Active LLMDriverConfig (after provider)", llm_driver_config, style="green"
|
175
175
|
)
|
176
176
|
print_verbose_info("Agent role", agent_role, style="green")
|
177
|
-
|
177
|
+
|
178
|
+
# Skip chat mode for list commands - handle them directly
|
179
|
+
from janito.cli.core.getters import GETTER_KEYS
|
180
|
+
skip_chat_mode = False
|
181
|
+
if args is not None:
|
182
|
+
for key in GETTER_KEYS:
|
183
|
+
if getattr(args, key, False):
|
184
|
+
skip_chat_mode = True
|
185
|
+
break
|
186
|
+
|
187
|
+
if skip_chat_mode:
|
188
|
+
# Handle list commands directly without prompt
|
189
|
+
from janito.cli.core.getters import handle_getter
|
190
|
+
handle_getter(args)
|
191
|
+
elif mode == "single_shot":
|
178
192
|
from janito.cli.single_shot_mode.handler import (
|
179
193
|
PromptHandler as SingleShotPromptHandler,
|
180
194
|
)
|
janito/cli/core/setters.py
CHANGED
@@ -101,17 +101,29 @@ def _handle_set_base_url(value):
|
|
101
101
|
return True
|
102
102
|
|
103
103
|
|
104
|
-
def
|
104
|
+
def set_provider(value):
|
105
|
+
"""Set the current provider.
|
106
|
+
|
107
|
+
Args:
|
108
|
+
value (str): The provider name to set
|
109
|
+
|
110
|
+
Raises:
|
111
|
+
ValueError: If the provider is not supported
|
112
|
+
"""
|
105
113
|
try:
|
106
114
|
supported = ProviderRegistry().get_provider(value)
|
107
115
|
except Exception:
|
108
|
-
|
109
|
-
f"Error: Provider '{value}' is not supported. Run '--list-providers' to see the supported list."
|
110
|
-
)
|
111
|
-
return True
|
116
|
+
raise ValueError(f"Provider '{value}' is not supported. Run '--list-providers' to see the supported list.")
|
112
117
|
from janito.provider_config import set_config_provider
|
113
|
-
|
114
118
|
set_config_provider(value)
|
119
|
+
|
120
|
+
|
121
|
+
def _handle_set_config_provider(value):
|
122
|
+
try:
|
123
|
+
set_provider(value)
|
124
|
+
except ValueError as e:
|
125
|
+
print(f"Error: {str(e)}")
|
126
|
+
return True
|
115
127
|
print(f"Provider set to '{value}'.")
|
116
128
|
return True
|
117
129
|
|
janito/cli/main_cli.py
CHANGED
@@ -293,7 +293,8 @@ class JanitoCLI:
|
|
293
293
|
self.parser = argparse.ArgumentParser(
|
294
294
|
description="Janito CLI - A tool for running LLM-powered workflows from the command line."
|
295
295
|
"\n\nExample usage: janito -p moonshotai -m kimi-k1-8k 'Your prompt here'\n\n"
|
296
|
-
"Use -m or --model to set the model for the session."
|
296
|
+
"Use -m or --model to set the model for the session.",
|
297
|
+
|
297
298
|
)
|
298
299
|
self._define_args()
|
299
300
|
self.args = self.parser.parse_args()
|
@@ -404,15 +405,27 @@ class JanitoCLI:
|
|
404
405
|
or self.args.list_drivers
|
405
406
|
or self.args.list_plugins
|
406
407
|
or self.args.list_plugins_available
|
408
|
+
or self.args.list_resources
|
407
409
|
or self.args.ping
|
408
410
|
):
|
409
411
|
self._maybe_print_verbose_provider_model()
|
410
412
|
handle_getter(self.args)
|
411
413
|
return
|
414
|
+
# Handle /rwx prefix for enabling all permissions
|
415
|
+
if self.args.user_prompt and self.args.user_prompt[0] == '/rwx':
|
416
|
+
self.args.read = True
|
417
|
+
self.args.write = True
|
418
|
+
self.args.exec = True
|
419
|
+
# Remove the /rwx prefix from the prompt
|
420
|
+
self.args.user_prompt = self.args.user_prompt[1:]
|
421
|
+
elif self.args.user_prompt and self.args.user_prompt[0].startswith('/'):
|
422
|
+
# Skip LLM processing for other commands that start with /
|
423
|
+
return
|
424
|
+
|
412
425
|
# If running in single shot mode and --profile is not provided, default to 'developer' profile
|
413
|
-
|
414
|
-
|
415
|
-
|
426
|
+
# Skip profile selection for list commands that don't need it
|
427
|
+
if (get_prompt_mode(self.args) == "single_shot" and
|
428
|
+
not getattr(self.args, "profile", None)):
|
416
429
|
self.args.profile = "developer"
|
417
430
|
provider = self._get_provider_or_default()
|
418
431
|
if provider is None:
|
@@ -441,8 +454,6 @@ class JanitoCLI:
|
|
441
454
|
agent_role,
|
442
455
|
verbose_tools=self.args.verbose_tools,
|
443
456
|
)
|
444
|
-
elif run_mode == RunMode.GET:
|
445
|
-
handle_getter(self.args)
|
446
457
|
|
447
458
|
def _run_set_mode(self):
|
448
459
|
if handle_api_key_set(self.args):
|
@@ -0,0 +1,84 @@
|
|
1
|
+
"""
|
2
|
+
Builtin plugin system for janito-packaged plugins.
|
3
|
+
|
4
|
+
This module provides the infrastructure for plugins that are bundled
|
5
|
+
with janito and available by default without requiring external installation.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import importlib
|
9
|
+
from typing import Dict, List, Optional, Type
|
10
|
+
from janito.plugins.base import Plugin
|
11
|
+
|
12
|
+
|
13
|
+
class BuiltinPluginRegistry:
|
14
|
+
"""Registry for builtin plugins that come packaged with janito."""
|
15
|
+
|
16
|
+
_plugins: Dict[str, Type[Plugin]] = {}
|
17
|
+
|
18
|
+
@classmethod
|
19
|
+
def register(cls, name: str, plugin_class: Type[Plugin]) -> None:
|
20
|
+
"""Register a builtin plugin."""
|
21
|
+
cls._plugins[name] = plugin_class
|
22
|
+
|
23
|
+
@classmethod
|
24
|
+
def get_plugin_class(cls, name: str) -> Optional[Type[Plugin]]:
|
25
|
+
"""Get the plugin class for a builtin plugin."""
|
26
|
+
return cls._plugins.get(name)
|
27
|
+
|
28
|
+
@classmethod
|
29
|
+
def list_builtin_plugins(cls) -> List[str]:
|
30
|
+
"""List all registered builtin plugins."""
|
31
|
+
return list(cls._plugins.keys())
|
32
|
+
|
33
|
+
@classmethod
|
34
|
+
def is_builtin(cls, name: str) -> bool:
|
35
|
+
"""Check if a plugin is builtin."""
|
36
|
+
return name in cls._plugins
|
37
|
+
|
38
|
+
|
39
|
+
def register_builtin_plugin(name: str):
|
40
|
+
"""Decorator to register a plugin as builtin."""
|
41
|
+
def decorator(plugin_class: Type[Plugin]) -> Type[Plugin]:
|
42
|
+
BuiltinPluginRegistry.register(name, plugin_class)
|
43
|
+
return plugin_class
|
44
|
+
return decorator
|
45
|
+
|
46
|
+
|
47
|
+
def load_builtin_plugin(name: str) -> Optional[Plugin]:
|
48
|
+
"""Load a builtin plugin by name."""
|
49
|
+
plugin_class = BuiltinPluginRegistry.get_plugin_class(name)
|
50
|
+
if plugin_class:
|
51
|
+
return plugin_class()
|
52
|
+
return None
|
53
|
+
|
54
|
+
|
55
|
+
# Auto-register janito-coder plugins as builtin
|
56
|
+
try:
|
57
|
+
from janito_coder.plugins import (
|
58
|
+
GitAnalyzerPlugin,
|
59
|
+
CodeNavigatorPlugin,
|
60
|
+
DependencyAnalyzerPlugin,
|
61
|
+
CodeFormatterPlugin,
|
62
|
+
TestRunnerPlugin,
|
63
|
+
LinterPlugin,
|
64
|
+
DebuggerPlugin,
|
65
|
+
PerformanceProfilerPlugin,
|
66
|
+
SecurityScannerPlugin,
|
67
|
+
DocumentationGeneratorPlugin,
|
68
|
+
)
|
69
|
+
|
70
|
+
# Register all janito-coder plugins as builtin
|
71
|
+
BuiltinPluginRegistry.register("git_analyzer", GitAnalyzerPlugin)
|
72
|
+
BuiltinPluginRegistry.register("code_navigator", CodeNavigatorPlugin)
|
73
|
+
BuiltinPluginRegistry.register("dependency_analyzer", DependencyAnalyzerPlugin)
|
74
|
+
BuiltinPluginRegistry.register("code_formatter", CodeFormatterPlugin)
|
75
|
+
BuiltinPluginRegistry.register("test_runner", TestRunnerPlugin)
|
76
|
+
BuiltinPluginRegistry.register("linter", LinterPlugin)
|
77
|
+
BuiltinPluginRegistry.register("debugger", DebuggerPlugin)
|
78
|
+
BuiltinPluginRegistry.register("performance_profiler", PerformanceProfilerPlugin)
|
79
|
+
BuiltinPluginRegistry.register("security_scanner", SecurityScannerPlugin)
|
80
|
+
BuiltinPluginRegistry.register("documentation_generator", DocumentationGeneratorPlugin)
|
81
|
+
|
82
|
+
except ImportError:
|
83
|
+
# janito-coder not available, skip registration
|
84
|
+
pass
|