janito 2.21.0__py3-none-any.whl → 2.24.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 (55) hide show
  1. janito/agent/setup_agent.py +48 -4
  2. janito/agent/templates/profiles/system_prompt_template_Developer_with_Python_Tools.txt.j2 +59 -11
  3. janito/agent/templates/profiles/system_prompt_template_developer.txt.j2 +53 -7
  4. janito/agent/templates/profiles/system_prompt_template_market_analyst.txt.j2 +110 -0
  5. janito/agent/templates/profiles/system_prompt_template_model_conversation_without_tools_or_context.txt.j2 +53 -1
  6. janito/cli/chat_mode/session.py +8 -1
  7. janito/cli/chat_mode/session_profile_select.py +20 -3
  8. janito/cli/chat_mode/shell/commands/__init__.py +2 -0
  9. janito/cli/chat_mode/shell/commands/security/__init__.py +1 -0
  10. janito/cli/chat_mode/shell/commands/security/allowed_sites.py +94 -0
  11. janito/cli/chat_mode/shell/commands/security_command.py +51 -0
  12. janito/cli/cli_commands/list_plugins.py +45 -0
  13. janito/cli/cli_commands/list_profiles.py +29 -1
  14. janito/cli/cli_commands/show_system_prompt.py +24 -10
  15. janito/cli/core/getters.py +4 -0
  16. janito/cli/core/runner.py +7 -2
  17. janito/cli/core/setters.py +10 -1
  18. janito/cli/main_cli.py +25 -3
  19. janito/cli/single_shot_mode/handler.py +3 -1
  20. janito/config_manager.py +10 -0
  21. janito/plugins/__init__.py +17 -0
  22. janito/plugins/base.py +93 -0
  23. janito/plugins/discovery.py +160 -0
  24. janito/plugins/manager.py +185 -0
  25. janito/providers/ibm/model_info.py +9 -0
  26. janito/tools/adapters/local/__init__.py +2 -0
  27. janito/tools/adapters/local/adapter.py +55 -0
  28. janito/tools/adapters/local/ask_user.py +2 -0
  29. janito/tools/adapters/local/fetch_url.py +184 -11
  30. janito/tools/adapters/local/find_files.py +2 -0
  31. janito/tools/adapters/local/get_file_outline/core.py +2 -0
  32. janito/tools/adapters/local/get_file_outline/search_outline.py +2 -0
  33. janito/tools/adapters/local/open_html_in_browser.py +2 -0
  34. janito/tools/adapters/local/open_url.py +2 -0
  35. janito/tools/adapters/local/python_code_run.py +15 -10
  36. janito/tools/adapters/local/python_command_run.py +14 -9
  37. janito/tools/adapters/local/python_file_run.py +15 -10
  38. janito/tools/adapters/local/read_chart.py +252 -0
  39. janito/tools/adapters/local/read_files.py +2 -0
  40. janito/tools/adapters/local/replace_text_in_file.py +1 -1
  41. janito/tools/adapters/local/run_bash_command.py +18 -12
  42. janito/tools/adapters/local/run_powershell_command.py +15 -9
  43. janito/tools/adapters/local/search_text/core.py +2 -0
  44. janito/tools/adapters/local/validate_file_syntax/core.py +6 -0
  45. janito/tools/adapters/local/validate_file_syntax/jinja2_validator.py +47 -0
  46. janito/tools/adapters/local/view_file.py +2 -0
  47. janito/tools/loop_protection.py +115 -0
  48. janito/tools/loop_protection_decorator.py +110 -0
  49. janito/tools/url_whitelist.py +121 -0
  50. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/METADATA +1 -1
  51. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/RECORD +55 -41
  52. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/WHEEL +0 -0
  53. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/entry_points.txt +0 -0
  54. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/licenses/LICENSE +0 -0
  55. {janito-2.21.0.dist-info → janito-2.24.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,115 @@
1
+ import time
2
+ import threading
3
+ from typing import Dict, List, Tuple
4
+ from janito.tools.tool_use_tracker import normalize_path
5
+
6
+
7
+ class LoopProtection:
8
+ """
9
+ Provides loop protection for tool calls by tracking repeated operations
10
+ on the same resources within a short time period.
11
+
12
+ This class monitors file operations and prevents excessive reads on the same
13
+ file within a configurable time window. It helps prevent infinite loops or
14
+ excessive resource consumption when tools repeatedly access the same files.
15
+
16
+ The default configuration allows up to 5 operations on the same file within
17
+ a 10-second window. Operations outside this window are automatically cleaned
18
+ up to prevent memory accumulation.
19
+ """
20
+
21
+ _instance = None
22
+ _lock = threading.Lock()
23
+
24
+ def __new__(cls):
25
+ if not cls._instance:
26
+ with cls._lock:
27
+ if not cls._instance:
28
+ cls._instance = super().__new__(cls)
29
+ cls._instance._init_protection()
30
+ return cls._instance
31
+
32
+ def _init_protection(self):
33
+ # Track file operations: {normalized_path: [(timestamp, operation_type), ...]}
34
+ self._file_operations: Dict[str, List[Tuple[float, str]]] = {}
35
+ # Time window for detecting loops (in seconds)
36
+ self._time_window = 10.0
37
+ # Maximum allowed operations on the same file within time window
38
+ self._max_operations = 5
39
+
40
+ """
41
+ Configuration parameters:
42
+
43
+ _time_window: Time window in seconds for detecting excessive operations.
44
+ Default is 10.0 seconds.
45
+
46
+ _max_operations: Maximum number of operations allowed on the same file
47
+ within the time window. Default is 5 operations.
48
+ """
49
+
50
+ def check_file_operation_limit(self, path: str, operation_type: str) -> bool:
51
+ """
52
+ Check if performing an operation on a file would exceed the limit.
53
+
54
+ This method tracks file operations and prevents excessive reads on the same
55
+ file within a configurable time window (default 10 seconds). It helps prevent
56
+ infinite loops or excessive resource consumption when tools repeatedly access
57
+ the same files.
58
+
59
+ Args:
60
+ path: The file path being operated on
61
+ operation_type: Type of operation (e.g., "view_file", "read_files")
62
+
63
+ Returns:
64
+ bool: True if operation is allowed, False if it would exceed the limit
65
+
66
+ Example:
67
+ >>> loop_protection = LoopProtection.instance()
68
+ >>> if loop_protection.check_file_operation_limit("/path/to/file.txt", "view_file"):
69
+ ... # Safe to proceed with file operation
70
+ ... content = read_file("/path/to/file.txt")
71
+ ... else:
72
+ ... # Would exceed limit - potential loop detected
73
+ ... raise RuntimeError("Too many operations on the same file")
74
+ """
75
+ norm_path = normalize_path(path)
76
+ current_time = time.time()
77
+
78
+ # Clean up old operations outside the time window
79
+ if norm_path in self._file_operations:
80
+ self._file_operations[norm_path] = [
81
+ (timestamp, op_type)
82
+ for timestamp, op_type in self._file_operations[norm_path]
83
+ if current_time - timestamp <= self._time_window
84
+ ]
85
+
86
+ # Check if we're exceeding the limit
87
+ if norm_path in self._file_operations:
88
+ operations = self._file_operations[norm_path]
89
+ if len(operations) >= self._max_operations:
90
+ # Check if all recent operations are within the time window
91
+ if all(current_time - timestamp <= self._time_window
92
+ for timestamp, _ in operations):
93
+ return False # Would exceed limit - potential loop
94
+
95
+ # Record this operation
96
+ if norm_path not in self._file_operations:
97
+ self._file_operations[norm_path] = []
98
+ self._file_operations[norm_path].append((current_time, operation_type))
99
+
100
+ return True # Operation allowed
101
+
102
+ def reset_tracking(self):
103
+ """
104
+ Reset all tracking data.
105
+
106
+ This method clears all recorded file operations, effectively resetting
107
+ the loop protection state. This can be useful in testing scenarios or
108
+ when you want to explicitly clear the tracking history.
109
+ """
110
+ with self._lock:
111
+ self._file_operations.clear()
112
+
113
+ @classmethod
114
+ def instance(cls):
115
+ return cls()
@@ -0,0 +1,110 @@
1
+ import functools
2
+ import time
3
+ import threading
4
+ from typing import Callable, Any
5
+ from janito.tools.loop_protection import LoopProtection
6
+ from janito.tools.tool_use_tracker import normalize_path
7
+
8
+
9
+ # Global tracking for decorator-based loop protection
10
+ _decorator_call_tracker = {}
11
+ _decorator_call_tracker_lock = threading.Lock()
12
+
13
+
14
+ def protect_against_loops(
15
+ max_calls: int = 5,
16
+ time_window: float = 10.0
17
+ ):
18
+ """
19
+ Decorator that adds loop protection to tool run methods.
20
+
21
+ This decorator monitors tool executions and prevents excessive calls within
22
+ a configurable time window. It helps prevent infinite loops or excessive
23
+ resource consumption when tools are called repeatedly.
24
+
25
+ When the configured limits are exceeded, the decorator raises a RuntimeError
26
+ with a descriptive message. This exception will propagate up the call stack
27
+ unless caught by a try/except block in the calling code.
28
+
29
+ The decorator works by:
30
+ 1. Tracking the number of calls to the decorated function
31
+ 2. Checking if the calls exceed the configured limits
32
+ 3. Raising a RuntimeError if a potential loop is detected
33
+ 4. Allowing the method to proceed normally if the operation is safe
34
+
35
+ Args:
36
+ max_calls (int): Maximum number of calls allowed within the time window.
37
+ Defaults to 5 calls.
38
+ time_window (float): Time window in seconds for detecting excessive calls.
39
+ Defaults to 10.0 seconds.
40
+
41
+ Example:
42
+ >>> @protect_against_loops(max_calls=3, time_window=5.0)
43
+ >>> def run(self, path: str) -> str:
44
+ >>> # Implementation here
45
+ >>> pass
46
+
47
+ >>> @protect_against_loops(max_calls=10, time_window=30.0)
48
+ >>> def run(self, file_paths: list) -> str:
49
+ >>> # Implementation here
50
+ >>> pass
51
+
52
+ Note:
53
+ When loop protection is triggered, a RuntimeError will be raised with a
54
+ descriptive message. This exception will propagate up the call stack
55
+ unless caught by a try/except block in the calling code.
56
+ """
57
+ def decorator(func):
58
+ @functools.wraps(func)
59
+ def wrapper(*args, **kwargs):
60
+ # Get the tool instance (self)
61
+ if not args:
62
+ # This shouldn't happen in normal usage as methods need self
63
+ return func(*args, **kwargs)
64
+
65
+ # Use the function name as the operation name
66
+ op_name = func.__name__
67
+
68
+ # Check call limits
69
+ current_time = time.time()
70
+
71
+ with _decorator_call_tracker_lock:
72
+ # Clean up old entries outside the time window
73
+ if op_name in _decorator_call_tracker:
74
+ _decorator_call_tracker[op_name] = [
75
+ timestamp for timestamp in _decorator_call_tracker[op_name]
76
+ if current_time - timestamp <= time_window
77
+ ]
78
+
79
+ # Check if we're exceeding the limit
80
+ if op_name in _decorator_call_tracker:
81
+ if len(_decorator_call_tracker[op_name]) >= max_calls:
82
+ # Check if all recent calls are within the time window
83
+ if all(current_time - timestamp <= time_window
84
+ for timestamp in _decorator_call_tracker[op_name]):
85
+ # Define the error reporting function
86
+ def _report_error_and_raise(args, operation_type):
87
+ # Get the tool instance to access report_error method if available
88
+ tool_instance = args[0] if args else None
89
+ error_msg = f"Loop protection: Too many {operation_type} operations in a short time period ({max_calls} calls in {time_window}s)"
90
+
91
+ # Try to report the error through the tool's reporting mechanism
92
+ if hasattr(tool_instance, 'report_error'):
93
+ try:
94
+ tool_instance.report_error(error_msg)
95
+ except Exception:
96
+ pass # If reporting fails, we still raise the error
97
+
98
+ raise RuntimeError(error_msg)
99
+
100
+ _report_error_and_raise(args, op_name)
101
+
102
+ # Record this call
103
+ if op_name not in _decorator_call_tracker:
104
+ _decorator_call_tracker[op_name] = []
105
+ _decorator_call_tracker[op_name].append(current_time)
106
+
107
+ # Proceed with the original function
108
+ return func(*args, **kwargs)
109
+ return wrapper
110
+ return decorator
@@ -0,0 +1,121 @@
1
+ """URL whitelist management for fetch_url tool."""
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Set, List, Optional
6
+ from urllib.parse import urlparse
7
+
8
+
9
+ class UrlWhitelistManager:
10
+ """Manages allowed sites for the fetch_url tool."""
11
+
12
+ def __init__(self):
13
+ self.config_path = Path.home() / ".janito" / "url_whitelist.json"
14
+ self._allowed_sites = self._load_whitelist()
15
+ self._unrestricted_mode = False
16
+
17
+ def set_unrestricted_mode(self, enabled: bool = True):
18
+ """Enable or disable unrestricted mode (bypasses whitelist)."""
19
+ self._unrestricted_mode = enabled
20
+
21
+ def _load_whitelist(self) -> Set[str]:
22
+ """Load the whitelist from config file."""
23
+ if not self.config_path.exists():
24
+ return set()
25
+
26
+ try:
27
+ with open(self.config_path, 'r', encoding='utf-8') as f:
28
+ data = json.load(f)
29
+ return set(data.get('allowed_sites', []))
30
+ except (json.JSONDecodeError, IOError):
31
+ return set()
32
+
33
+ def _save_whitelist(self):
34
+ """Save the whitelist to config file."""
35
+ self.config_path.parent.mkdir(parents=True, exist_ok=True)
36
+ try:
37
+ with open(self.config_path, 'w', encoding='utf-8') as f:
38
+ json.dump({'allowed_sites': list(self._allowed_sites)}, f, indent=2)
39
+ except IOError:
40
+ pass # Silently fail if we can't write
41
+
42
+ def is_url_allowed(self, url: str) -> bool:
43
+ """Check if a URL is allowed based on the whitelist."""
44
+ if self._unrestricted_mode:
45
+ return True # Unrestricted mode bypasses all whitelist checks
46
+
47
+ if not self._allowed_sites:
48
+ return True # No whitelist means all sites allowed
49
+
50
+ try:
51
+ parsed = urlparse(url)
52
+ domain = parsed.netloc.lower()
53
+
54
+ # Check exact matches and subdomain matches
55
+ for allowed in self._allowed_sites:
56
+ allowed = allowed.lower()
57
+ if domain == allowed or domain.endswith('.' + allowed):
58
+ return True
59
+
60
+ return False
61
+ except Exception:
62
+ return False # Invalid URLs are blocked
63
+
64
+ def add_allowed_site(self, site: str) -> bool:
65
+ """Add a site to the whitelist."""
66
+ # Clean up the site format
67
+ site = site.strip().lower()
68
+ if site.startswith('http://') or site.startswith('https://'):
69
+ parsed = urlparse(site)
70
+ site = parsed.netloc
71
+
72
+ if site and site not in self._allowed_sites:
73
+ self._allowed_sites.add(site)
74
+ self._save_whitelist()
75
+ return True
76
+ return False
77
+
78
+ def remove_allowed_site(self, site: str) -> bool:
79
+ """Remove a site from the whitelist."""
80
+ site = site.strip().lower()
81
+ if site.startswith('http://') or site.startswith('https://'):
82
+ parsed = urlparse(site)
83
+ site = parsed.netloc
84
+
85
+ if site in self._allowed_sites:
86
+ self._allowed_sites.remove(site)
87
+ self._save_whitelist()
88
+ return True
89
+ return False
90
+
91
+ def get_allowed_sites(self) -> List[str]:
92
+ """Get the list of allowed sites."""
93
+ return sorted(self._allowed_sites)
94
+
95
+ def set_allowed_sites(self, sites: List[str]):
96
+ """Set the complete list of allowed sites."""
97
+ self._allowed_sites = set()
98
+ for site in sites:
99
+ site = site.strip().lower()
100
+ if site.startswith('http://') or site.startswith('https://'):
101
+ parsed = urlparse(site)
102
+ site = parsed.netloc
103
+ if site:
104
+ self._allowed_sites.add(site)
105
+ self._save_whitelist()
106
+
107
+ def clear_whitelist(self):
108
+ """Clear all allowed sites."""
109
+ self._allowed_sites.clear()
110
+ self._save_whitelist()
111
+
112
+
113
+ # Global singleton
114
+ _url_whitelist_manager = None
115
+
116
+ def get_url_whitelist_manager() -> UrlWhitelistManager:
117
+ """Get the global URL whitelist manager instance."""
118
+ global _url_whitelist_manager
119
+ if _url_whitelist_manager is None:
120
+ _url_whitelist_manager = UrlWhitelistManager()
121
+ return _url_whitelist_manager
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.21.0
3
+ Version: 2.24.0
4
4
  Summary: A new Python package called janito.
5
5
  Author-email: João Pinto <janito@ikignosis.org>
6
6
  Project-URL: Homepage, https://github.com/ikignosis/janito
@@ -3,7 +3,7 @@ janito/__init__.py,sha256=a0pFui3A_AfWJiUfg93yE-Vf4868bqG3y9yg2fkTIuY,244
3
3
  janito/__main__.py,sha256=lPQ8kAyYfyeS1KopmJ8EVY5g1YswlIqCS615mM_B_rM,70
4
4
  janito/_version.py,sha256=PtAVr2K9fOS5sv6aXzmcb7UaR5NLGMFOofL7Ndjh75o,2344
5
5
  janito/config.py,sha256=DXuC74NEywKvpTkOSrrxJGvHdL_tvXEf27pkedV3XZA,313
6
- janito/config_manager.py,sha256=KoA_jmJzCv33jzXGSab0x6JyWL0cExoqnltES9oT-JU,5433
6
+ janito/config_manager.py,sha256=mj6SKydJyef0z4iRE3iewdU1Ki9Ws2V34qPQwdpPDuc,5893
7
7
  janito/conversation_history.py,sha256=GqqEJElTVONzOMRe-9g25WCMcDi0PF7DOnqGWLTrY_8,897
8
8
  janito/dir_walk_utils.py,sha256=ON9EyVH7Aaik8WtCH5z8DQis9ycdoNVkjNvU16HH498,1193
9
9
  janito/driver_events.py,sha256=51ab7KW_W6fVZVeO0ez-HJFY4NbTI327ZlEmEsEkxQc,3405
@@ -20,15 +20,16 @@ janito/provider_registry.py,sha256=Qh2ujKjaa5HZmr7YOHxUy983jSDaCD-AXaZFBVC85XY,7
20
20
  janito/report_events.py,sha256=m72U9TQfbQfKcCDT8O4nYhVI6IFfQQG1ZXQa3Vhq0y4,940
21
21
  janito/shell.bak.zip,sha256=hznHbmgfkAkjuQDJ3w73XPQh05yrtUZQxLmtGbanbYU,22
22
22
  janito/utils.py,sha256=eXSsMgM69YyzahgCNrJQLcEbB8ssLI1MQqaa20ONxbE,376
23
- janito/agent/setup_agent.py,sha256=HQU_h1P8VXiOVURjQ4SwvO-R3rujs6xUcPvrNniRDok,11618
24
- janito/agent/templates/profiles/system_prompt_template_Developer_with_Python_Tools.txt.j2,sha256=28TITVITH4RTdOwPpNZFSygm6OSpFb_Jr4mHprrLBhc,2584
25
- janito/agent/templates/profiles/system_prompt_template_developer.txt.j2,sha256=zj0ZA17iYt-6c0usgjUw_cLKnb5qDuixpxS9et5ECyw,2272
26
- janito/agent/templates/profiles/system_prompt_template_model_conversation_without_tools_or_context.txt.j2,sha256=dTV9aF8ji2r9dzi-l4b9r95kHrbKmjvnRxk5cVpopN4,28
23
+ janito/agent/setup_agent.py,sha256=K6hiFnMtKAUXt_xl4HFjITUow6NNyz-jWe-Q7u_iegM,13465
24
+ janito/agent/templates/profiles/system_prompt_template_Developer_with_Python_Tools.txt.j2,sha256=R-LxBq4wtsOeexZoQSYrdfGNdp5rdzHCP5Lt0pbejzE,3600
25
+ janito/agent/templates/profiles/system_prompt_template_developer.txt.j2,sha256=vO0RGuj_tkL-o_rrrd0H7iD7bVe9NWGcyBR4h0T81hY,3283
26
+ janito/agent/templates/profiles/system_prompt_template_market_analyst.txt.j2,sha256=A4WxfDdcGA1g1ndUP3Swu5lQSAMl7nP7W7MVPgyKcZM,3764
27
+ janito/agent/templates/profiles/system_prompt_template_model_conversation_without_tools_or_context.txt.j2,sha256=K7sYNF0Yh7DchdqyhhvCLpbqiCJ36gX1M67XRZMw20c,1256
27
28
  janito/cli/__init__.py,sha256=xaPDOrWphBbCR63Xpcx_yfpXSJIlCaaICc4j2qpWqrM,194
28
29
  janito/cli/config.py,sha256=HkZ14701HzIqrvaNyDcDhGlVHfpX_uHlLp2rHmhRm_k,872
29
30
  janito/cli/console.py,sha256=gJolqzWL7jEPLxeuH-CwBDRFpXt976KdZOEAB2tdBDs,64
30
31
  janito/cli/main.py,sha256=s5odou0txf8pzTf1ADk2yV7T5m8B6cejJ81e7iu776U,312
31
- janito/cli/main_cli.py,sha256=aLkWYT3qG4AmGGx7RXkLJACgVhurhpwFrz6_0rwpQCQ,15703
32
+ janito/cli/main_cli.py,sha256=eD0uS3FslmAFQgH6rPqQOBiKS41Kr0zGAY-LecK79k8,16217
32
33
  janito/cli/prompt_core.py,sha256=F68J4Xl6jZMYFN4oBBYZFj15Jp-HTYoLub4bw2XpNRU,11648
33
34
  janito/cli/prompt_handler.py,sha256=SnPTlL64noeAMGlI08VBDD5IDD8jlVMIYA4-fS8zVLg,215
34
35
  janito/cli/prompt_setup.py,sha256=1SSvvgS568-3BO_4Sw9A-QF_iLWiIXsNHT0JVqaLwkU,2120
@@ -39,14 +40,14 @@ janito/cli/chat_mode/bindings.py,sha256=odjc5_-YW1t2FRhBUNRNoBMoQIg5sMz3ktV7xG0A
39
40
  janito/cli/chat_mode/chat_entry.py,sha256=RFdPd23jsA2DMHRacpjAdwI_1dFBaWrtnwyQEgb2fHA,475
40
41
  janito/cli/chat_mode/prompt_style.py,sha256=vsqQ9xxmrYjj1pWuVe9CayQf39fo2EIXrkKPkflSVn4,805
41
42
  janito/cli/chat_mode/script_runner.py,sha256=wOwEn4bgmjqHqjTqtfyaSOnRPsGf4ZVW-YAWhEeqxXU,6507
42
- janito/cli/chat_mode/session.py,sha256=gY87m6PlC_fNfSTdaJ5T-iq2i3Xc6JRb6rz9NraIUc4,15572
43
- janito/cli/chat_mode/session_profile_select.py,sha256=CJ2g3VbPGWfBNrNkYYX57oIJZJ-hIZBNGB-zcdjC9vk,5379
43
+ janito/cli/chat_mode/session.py,sha256=lDoEAvCHvRA5MZG1CsCBt7uJNsMUS81_qaxQbzS0rqA,15967
44
+ janito/cli/chat_mode/session_profile_select.py,sha256=23al0mw0unBlTqRg-ZI3RJa-XV8hdwVsizYJw_Lg2xY,6363
44
45
  janito/cli/chat_mode/toolbar.py,sha256=bJ9jPaTInp2gB3yjSVJp8mpNEFiOslzNhVaiqpXJhKc,3025
45
46
  janito/cli/chat_mode/shell/autocomplete.py,sha256=lE68MaVaodbA2VfUM0_YLqQVLBJAE_BJsd5cMtwuD-g,793
46
47
  janito/cli/chat_mode/shell/commands.bak.zip,sha256=I7GFjXg2ORT5NzFpicH1vQ3kchhduQsZinzqo0xO8wU,74238
47
48
  janito/cli/chat_mode/shell/input_history.py,sha256=9620dKYSpXfGhdd2msbuqnkNW3Drv0dZ0eisWBaGKbg,2586
48
49
  janito/cli/chat_mode/shell/session.bak.zip,sha256=m1GyO3Wy4G4D9sVgRO6ZDyC0VjclsmnEJsiQoer4LzI,5789
49
- janito/cli/chat_mode/shell/commands/__init__.py,sha256=Ux4h86ewY9yR9xjaK6Zt2vOws3uCjMBmnMhOHLWS1BE,2302
50
+ janito/cli/chat_mode/shell/commands/__init__.py,sha256=xt7kAUJYvxbYoLuUEervCDoTmXzNLMoq0EF-WKWB5U0,2384
50
51
  janito/cli/chat_mode/shell/commands/_priv_check.py,sha256=OBPRMZlFlLSJSfbXrLqRCqD3ISKqR0QNzBJpa7g30Ro,206
51
52
  janito/cli/chat_mode/shell/commands/_priv_status.py,sha256=WgCEK38Hllz3Bz4TgVgODdmo0BDaBey5t0uMyA3125k,478
52
53
  janito/cli/chat_mode/shell/commands/bang.py,sha256=qVCUM8ZnGE1J3yG1hjYYw7upY4PR6bhNNYfJa-NfnI4,1860
@@ -63,19 +64,23 @@ janito/cli/chat_mode/shell/commands/privileges.py,sha256=pkTnteM8nURTaw2JzVIxLxA
63
64
  janito/cli/chat_mode/shell/commands/prompt.py,sha256=6mj1oUO6bodyED19-_tJVO0x-l3REzYjKhp8OKFFWy4,1790
64
65
  janito/cli/chat_mode/shell/commands/read.py,sha256=3uKHkaIl6d4euS8rKGcYqUwVjvzVSwDjJgQTmt8nysw,2299
65
66
  janito/cli/chat_mode/shell/commands/role.py,sha256=4Mt3okuNwOjqHbNhOFawcWB9KCLkpTDuLoDJFeXr3-E,1079
67
+ janito/cli/chat_mode/shell/commands/security_command.py,sha256=7Xgjb8Gunk9CjKxz1xwI-bAo1mOp_-VrqOhzuN2lcRw,1779
66
68
  janito/cli/chat_mode/shell/commands/session.py,sha256=9wsw5U24-KJgTT70KAwnGuS8MVPyvpxCJfAt_Io76O0,1574
67
69
  janito/cli/chat_mode/shell/commands/session_control.py,sha256=tmMGJ8IvWoBwSIJu7T6GPnFYFrmXWIG2Gr9tTni4y3U,1307
68
70
  janito/cli/chat_mode/shell/commands/tools.py,sha256=8BWgqB0j5sp7mYupxoAjYvLWjb_wODOfCk-I8yNfk-U,3473
69
71
  janito/cli/chat_mode/shell/commands/utility.py,sha256=K982P-UwgPLzpEvSuSBGwiQ3zC34S_6T2ork_djweQw,847
70
72
  janito/cli/chat_mode/shell/commands/verbose.py,sha256=HDTe0NhdcjBuhh-eJSW8iLPDeeBO95K5iSDAMAljxa4,953
71
73
  janito/cli/chat_mode/shell/commands/write.py,sha256=bpvJzHY7wlpgsB-cpslzfQQl7h6n-NLqj2gFCuJfjVk,2309
74
+ janito/cli/chat_mode/shell/commands/security/__init__.py,sha256=cU_LW0W2PbzFpwq4lvtwOlGEhcXMwau2tiz014X9m2Y,49
75
+ janito/cli/chat_mode/shell/commands/security/allowed_sites.py,sha256=dGiikM3VU8vmIzdMTkW0ImZClo3DYVKbQ_rVkF9LU7Q,3303
72
76
  janito/cli/chat_mode/shell/session/__init__.py,sha256=uTYE_QpZFEn7v9QE5o1LdulpCWa9vmk0OsefbBGWg_c,37
73
77
  janito/cli/chat_mode/shell/session/history.py,sha256=tYav6GgjAZkvWhlI_rfG6OArNqW6Wn2DTv39Hb20QYc,1262
74
78
  janito/cli/chat_mode/shell/session/manager.py,sha256=MwD9reHsRaly0CyRB-S1JJ0wPKz2g8Xdj2VvlU35Hgc,1001
75
79
  janito/cli/cli_commands/list_config.py,sha256=oiQEGaGPjwjG-PrOcakpNMbbqISTsBEs7rkGH3ceQsI,1179
76
80
  janito/cli/cli_commands/list_drivers.py,sha256=r2ENykUcvf_9XYp6LHd3RvLXGXyVUA6oe_Pr0dyv92I,5124
77
81
  janito/cli/cli_commands/list_models.py,sha256=7Cyjfwht77nm6_h1DRY2A-Nkkm1Kiy0e339EYglVqEI,1619
78
- janito/cli/cli_commands/list_profiles.py,sha256=9-HV2EbtP2AdubbMoakjbu7Oq4Ss9UDyO7Eb6CC52wI,2681
82
+ janito/cli/cli_commands/list_plugins.py,sha256=Z4qiomhc7sedG5v87AC0ewrJRpCA_saC_8dxrrtON74,1517
83
+ janito/cli/cli_commands/list_profiles.py,sha256=Duonbhko9GmkT9odJerlYKg9fE1kHTTaU7P2W2_51qk,3557
79
84
  janito/cli/cli_commands/list_providers.py,sha256=3ywm1Ohv7yVqV1E9hB-3Jz8BwzhyCScKxffq6iDI4nA,391
80
85
  janito/cli/cli_commands/list_providers_region.py,sha256=qrMj_gtgEMty8UH0P_O5SgWCVJ9ZKxGUp_GdsE4_EH4,2548
81
86
  janito/cli/cli_commands/list_tools.py,sha256=JFRdlhPeA3BzhJ2PkjIt3u137IJoNc-vYSjUuPlaOXw,3593
@@ -84,16 +89,16 @@ janito/cli/cli_commands/model_utils.py,sha256=PO64PW-TIlWyPY8CzYnI0y5Zp6ukV_NjaS
84
89
  janito/cli/cli_commands/ping_providers.py,sha256=U3iTETPXDEGr3dqlJqNTPvpkhKo2KfXe_bN2_LGJtx0,2015
85
90
  janito/cli/cli_commands/set_api_key.py,sha256=ZItSuB0HO14UsbyXXCgTKAXS-EUCHfCkntzg3WAAtK0,1048
86
91
  janito/cli/cli_commands/show_config.py,sha256=eYMcuvU-d7mvvuctbQacZFERqcKHEnxaRRjasyj-_lE,2004
87
- janito/cli/cli_commands/show_system_prompt.py,sha256=9ZJGW7lIGJ9LX2JZiWVEm4AbaD0qEQO7LF89jPgk52I,5232
92
+ janito/cli/cli_commands/show_system_prompt.py,sha256=YKOVHKzz6pzwvJGlqVEK2R4i98HGrUZHsrsFNvBBEd8,5898
88
93
  janito/cli/core/__init__.py,sha256=YH95fhgY9yBX8RgqX9dSrEkl4exjV0T4rbmJ6xUpG-Y,196
89
94
  janito/cli/core/event_logger.py,sha256=1X6lR0Ax7AgF8HlPWFoY5Ystuu7Bh4ooTo78vXzeGB0,2008
90
- janito/cli/core/getters.py,sha256=qk1wO9f77gKOJB2dsqDMv2DgcKT3KE1VPL8-pxv7yys,2335
95
+ janito/cli/core/getters.py,sha256=rVgDyBqbDNYpx0sr6W2u3Kh_Lv_DERjr3x9ny7bAjX0,2518
91
96
  janito/cli/core/model_guesser.py,sha256=jzkkiQ-J2buT2Omh6jYZHa8-zCJxqKQBL08Z58pe1_o,1741
92
- janito/cli/core/runner.py,sha256=3vP92XEUzzHeOWbMHg82iISsXVUAM7y8YKWGNSIMyA8,8337
93
- janito/cli/core/setters.py,sha256=PD3aT1y1q8XWQVtRNfrU0dtlW4JGdn6BMJyP7FCQWhc,4623
97
+ janito/cli/core/runner.py,sha256=uF4NZUm6TyALKzZD3CjeUlBDpdMbftWSEAAEUEqgAZA,8587
98
+ janito/cli/core/setters.py,sha256=cHoZsKAtMfRXfn_sLWWaXAh8WWL1XIvHTjUxcDmIM94,5077
94
99
  janito/cli/core/unsetters.py,sha256=FEw9gCt0vRvoCt0kRSNfVB2tzi_TqppJIx2nHPP59-k,2012
95
100
  janito/cli/single_shot_mode/__init__.py,sha256=Ct99pKe9tINzVW6oedZJfzfZQKWpXz-weSSCn0hrwHY,115
96
- janito/cli/single_shot_mode/handler.py,sha256=uZ3iYy6TJqdujAB6B0GEb_mrWUz_JMXckzt5n7FGzgk,5405
101
+ janito/cli/single_shot_mode/handler.py,sha256=deECFk2Zj2uqxNS7D8yH4pHv6UurLTktjIQxmneXXF8,5523
97
102
  janito/docs/GETTING_STARTED.md,sha256=zbsOfHi3H4I5qM-cj9wp4QUkmqNcq28cJc0kZMAlgIU,4978
98
103
  janito/drivers/dashscope.bak.zip,sha256=9Pv4Xyciju8jO1lEMFVgYXexoZkxmDO3Ig6vw3ODfL8,4936
99
104
  janito/drivers/openai_responses.bak.zip,sha256=E43eDCHGa2tCtdjzj_pMnWDdnsOZzj8BJTR5tJp8wcM,13352
@@ -124,6 +129,10 @@ janito/llm/driver_input.py,sha256=Zq7IO4KdQPUraeIo6XoOaRy1IdQAyYY15RQw4JU30uA,38
124
129
  janito/llm/message_parts.py,sha256=QY_0kDjaxdoErDgKPRPv1dNkkYJuXIBmHWNLiOEKAH4,1365
125
130
  janito/llm/model.py,sha256=EioBkdgn8hJ0iQaKN-0KbXlsrk3YKmwR9IbvoEbdVTE,1159
126
131
  janito/llm/provider.py,sha256=3FbhQPrWBSEoIdIi-5DWIh0DD_CM570EFf1NcuGyGko,7961
132
+ janito/plugins/__init__.py,sha256=7OGyRl_RUXDJE-7OwNMRDzH3RAb5p1j5oKp4ERfnye8,399
133
+ janito/plugins/base.py,sha256=0oVCdlX2FTYcCB3P2lgamLYSCsfsoyOwA3-xxjcbHKA,2389
134
+ janito/plugins/discovery.py,sha256=LPJ_YkkEprpW0PV3g43pjW2iKy_ezntnxr--KPjWEOg,4861
135
+ janito/plugins/manager.py,sha256=hb9rTlFWG6hKpxjLiP7_3DKuj7pHHjLQvBJkkNmWWlw,6484
127
136
  janito/providers/__init__.py,sha256=SWXtbW3lU7ORi6d9Ro04qnGDDNJ2Cwq0hfbKdZeResg,530
128
137
  janito/providers/dashscope.bak.zip,sha256=BwXxRmZreEivvRtmqbr5BR62IFVlNjAf4y6DrF2BVJo,5998
129
138
  janito/providers/registry.py,sha256=Ygwv9eVrTXOKhv0EKxSWQXO5WMHvajWE2Q_Lc3p7dKo,730
@@ -145,7 +154,7 @@ janito/providers/google/model_info.py,sha256=AakTmzvWm1GPvFzGAq6-PeE_Dpq7BmAAqmh
145
154
  janito/providers/google/provider.py,sha256=NQVG5kovHOc2SDgWjVIwYGMqshvMUAqRAk9iMntQ52k,3606
146
155
  janito/providers/ibm/README.md,sha256=5RLzoS8n0i4yxDrg7qbubbIc5wkqycvhFMn_JRdBY00,2621
147
156
  janito/providers/ibm/__init__.py,sha256=xwB2n-GP1oUsi8LuYKMgziclSSE2yJoFR9WImuUgqNw,26
148
- janito/providers/ibm/model_info.py,sha256=GTErYUoM146cDxVy3dUSACrut6y8BI5C5jEdbcUDW_0,2281
157
+ janito/providers/ibm/model_info.py,sha256=ZUz_j0cEiVcT87I0xAMiIWeGgA38fFx77zJ4RO8pchM,2538
149
158
  janito/providers/ibm/provider.py,sha256=PvFseMD527XuBtg9SImIzwyohjnzvE7KgK-ix3Ly8K0,5362
150
159
  janito/providers/mistral/__init__.py,sha256=L8X53_KdP8xjmwdxwPmcDHY5iiVZm2xKE4xixsjibHk,27
151
160
  janito/providers/mistral/model_info.py,sha256=1Zlac_Bss3wuMELROXTVDfeSeWaI1quhhi0ISEE9NQU,2266
@@ -170,6 +179,8 @@ janito/tools/README.md,sha256=5HkLpF5k4PENJER7SlDPRXj0yo9mpHvAHW4uuzhq4ak,115
170
179
  janito/tools/__init__.py,sha256=W1B39PztC2UF7PS2WyLH6el32MFOETMlN1-LurOROCg,1171
171
180
  janito/tools/disabled_tools.py,sha256=Tx__16wtMWZ9z34cYLdH1gukwot5MCL-9kLjd5MPX6Y,2110
172
181
  janito/tools/inspect_registry.py,sha256=Jo7PrMPRKLuR-j_mBAk9PBcTzeJf1eQrS1ChGofgQk0,538
182
+ janito/tools/loop_protection.py,sha256=DoOuQZ53PZ-Zmn7MD76KwOgjbd0esV2ESnXTDHV9IE4,4804
183
+ janito/tools/loop_protection_decorator.py,sha256=tI3zpdkjrxk6WR4QFItKS-dZVOIrA-jva8AbC4yP2QI,5096
173
184
  janito/tools/outline_file.bak.zip,sha256=EeI2cBXCwTdWVgJDNiroxKeYlkjwo6NLKeXz3J-2iZI,15607
174
185
  janito/tools/path_security.py,sha256=40b0hV0X3449Dht93A04Q3c9AYSsBQsBFy2BjzM83lA,8214
175
186
  janito/tools/permissions.py,sha256=_viTVXyetZC01HjI2s5c3klIJ8-RkWB1ShdOaV__loY,1508
@@ -181,44 +192,47 @@ janito/tools/tool_use_tracker.py,sha256=IaEmA22D6RuL1xMUCScOMGv0crLPwEJVGmj49cyd
181
192
  janito/tools/tool_utils.py,sha256=alPm9DvtXSw_zPRKvP5GjbebPRf_nfvmWk2TNlL5Cws,1219
182
193
  janito/tools/tools_adapter.py,sha256=aPzyJnm1pNwsEKNcXs-gKFurlOaZqzxkiktHOjITp_8,18724
183
194
  janito/tools/tools_schema.py,sha256=rGrKrmpPNR07VXHAJ_haGBRRO-YGLOF51BlYRep9AAQ,4415
195
+ janito/tools/url_whitelist.py,sha256=bFUba5h4P0aXGbVRqwF_x4I5uzHtlLXnpb24BndOkCM,4395
184
196
  janito/tools/adapters/__init__.py,sha256=XKixOKtUJs1R-rGwGDXSLVLg5-Kp090gvWbsseWT4LI,92
185
- janito/tools/adapters/local/__init__.py,sha256=_nxMg2uPX18DHNtyHR6SDwYMZvDLpy6gyaCt-75unao,2172
186
- janito/tools/adapters/local/adapter.py,sha256=A5pVq3KglDbUFAqhOqPlMeJ2wyPGJFhn0GV4gy4gfFI,7289
187
- janito/tools/adapters/local/ask_user.py,sha256=x7CwmLgjB6PSd1YgkohPBGkvhLkpK3Jb09bkn-iFTSY,3600
197
+ janito/tools/adapters/local/__init__.py,sha256=8xJw8Qv3T_wwkiGBVVgs9p7pH1ONIAipccEUqY2II8A,2231
198
+ janito/tools/adapters/local/adapter.py,sha256=-jMfwCMnQ9wl-uLpDnXomwBveLaqhwpwvBeDF8eZIr0,9559
199
+ janito/tools/adapters/local/ask_user.py,sha256=drL7wARk2_qBhDRc_3vh6_HHf-boY-5Q1TrOksQyyi8,3733
188
200
  janito/tools/adapters/local/copy_file.py,sha256=MSa0VtbIXFGz00q-nW2KdtzER0icm6Y1w7MKKE6A6us,3582
189
201
  janito/tools/adapters/local/create_directory.py,sha256=cmSbNUsqsY8wZ2RsX-g2c9FZkkTIM5jIvFyKKqvZKxM,2565
190
202
  janito/tools/adapters/local/create_file.py,sha256=fDdLzKchyGMx6o2L6k-_KYxDofcktdrXcV7lKuiZMMo,3458
191
203
  janito/tools/adapters/local/delete_text_in_file.py,sha256=uEeedRxXAR7_CqUc_qhbEdM0OzRi_pgnP-iDjs2Zvjk,5087
192
- janito/tools/adapters/local/fetch_url.py,sha256=8pk2zUq-_KZq0XPIDbH0z1JxL5Xnwl82JhO88q9exME,6034
193
- janito/tools/adapters/local/find_files.py,sha256=sRdvWZ58ximset-dcwtmDj1E32kruGC6kTGjTlSZtb0,6023
204
+ janito/tools/adapters/local/fetch_url.py,sha256=ksQHSbqxPAo7OFxwvxY_y0eYpoM0q73tnvSBZ-we6ic,13057
205
+ janito/tools/adapters/local/find_files.py,sha256=dsZqRgFqx7hZq3w2Yn4EzJEtvha3BojtskP_KiqBfrs,6156
194
206
  janito/tools/adapters/local/move_file.py,sha256=PBVp_gcmNxOLJeJsAtENg40SUG-lP7ijWE4sOG72jDk,4620
195
- janito/tools/adapters/local/open_html_in_browser.py,sha256=T3h3XUPgyGdXbiO-Ei-R2lSnAhUqKn_erAKr4YxAq7c,1950
196
- janito/tools/adapters/local/open_url.py,sha256=WHOJ2TaUVye2iUnrcdu93A_xKBx2lYcK0LUhZ0WvIsE,1402
197
- janito/tools/adapters/local/python_code_run.py,sha256=UrQ_rv_qVjY1vNdpACDAma5eFbAj_WhvgQjghRpv9hg,6681
198
- janito/tools/adapters/local/python_command_run.py,sha256=M-TxoGND45zKSMrYPjD6juSo0UhfsilXEBiyQdzQkiI,6621
199
- janito/tools/adapters/local/python_file_run.py,sha256=OsHc9rpyGWUjLE7Zin9Gl7YOLf9QVe8NoXXcdTkpJyE,6466
200
- janito/tools/adapters/local/read_files.py,sha256=2wYo60G6FCzpcpiBFv9-XBqSD6j4oO2AUe3v7Gm90kQ,2092
207
+ janito/tools/adapters/local/open_html_in_browser.py,sha256=FJz-QUmqyareA1C-upFZbAwkQsIuJ2QnEWHVZOW79IQ,2083
208
+ janito/tools/adapters/local/open_url.py,sha256=StsdwsVQ1VR9H0UBFMpnVDo5scRMszkCxUbtFTMifmA,1535
209
+ janito/tools/adapters/local/python_code_run.py,sha256=HdDuiRb7Fd7WC6bFS292XnSI1EYhn9XKlh8Hs_4Cz8E,6981
210
+ janito/tools/adapters/local/python_command_run.py,sha256=jtdUHt6KvjoaUbeDmOirsXcnoYFwBpuzY_uSsW9CIr4,6917
211
+ janito/tools/adapters/local/python_file_run.py,sha256=w4ffylzsNnLXT5540wy2GWgzVWwAkz7c0PTYMyrZJUk,6766
212
+ janito/tools/adapters/local/read_chart.py,sha256=Lxv0sbpk41KK8drfKT5HnT5DRf4WdpVaUNvo3Glahuc,10721
213
+ janito/tools/adapters/local/read_files.py,sha256=L_EehkNfqISV5AGWjNNkF-l4YyBMlKgrTeansC9i3WU,2225
201
214
  janito/tools/adapters/local/remove_directory.py,sha256=g1wkHcWNgtv3mfuZ4GfvqtKU3th-Du_058FMcNmc1TA,1830
202
215
  janito/tools/adapters/local/remove_file.py,sha256=cSs7EIhEqblnLmwjUKrUq2M8axyT2oTXJqZs5waOAFw,2090
203
- janito/tools/adapters/local/replace_text_in_file.py,sha256=zFGWORuaw50ZlEFf3q_s7K25Tt0QXu8yOXDeodY6kcE,10791
204
- janito/tools/adapters/local/run_bash_command.py,sha256=iiOz2oBiPcyYG6ySOIS8zOuQ9XpYv6DiUwGiPKciADw,7623
205
- janito/tools/adapters/local/run_powershell_command.py,sha256=p9SNZ2D4CMgbwtCIQ3jwlWWNYXMOPzosdQnkToT8QKI,8961
206
- janito/tools/adapters/local/view_file.py,sha256=-6Li0SegDUcUdH9jAulunQZj-Bm4A2MhSVbmtBFXtXQ,7137
216
+ janito/tools/adapters/local/replace_text_in_file.py,sha256=Y6mbPuoTpsFXKrSp51s0rz7Hhz1WHkG1sY4pZ3RoZsU,10790
217
+ janito/tools/adapters/local/run_bash_command.py,sha256=7fABqAeAu7WJwzzwHmT54_m5OSwPMcgpQ74lQhPG7TA,7955
218
+ janito/tools/adapters/local/run_powershell_command.py,sha256=EMqPZvjkYZTDBriuRH0Sbx5GvzS97ti-qwCS46J2wWQ,9263
219
+ janito/tools/adapters/local/view_file.py,sha256=iM0KgMwo5k-3c-R7xCV08vqGR878Jga9lSjPfC59MLg,7270
207
220
  janito/tools/adapters/local/get_file_outline/__init__.py,sha256=OKV_BHnoD9h-vkcVoW6AHmsuDjjauHPCKNK0nVFl4sU,37
208
- janito/tools/adapters/local/get_file_outline/core.py,sha256=L_fS39v5ufLc9BK02tWMiH0nWQcXPAmbmwBNv1s_IhU,4373
221
+ janito/tools/adapters/local/get_file_outline/core.py,sha256=bgo4fpt2B8i6o7cWdGTQLbu8WZ3HWdA-kN2ubVStvro,4506
209
222
  janito/tools/adapters/local/get_file_outline/java_outline.py,sha256=_UeUY5JoQEUdlHcK8aqGTqYJl0T2KxIFXPTdwum9gKQ,1825
210
223
  janito/tools/adapters/local/get_file_outline/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
211
224
  janito/tools/adapters/local/get_file_outline/python_outline.py,sha256=RAcf9Vxec08lA06drYaNre5HCJ2lTzrRAskZ3rlyE-U,10326
212
- janito/tools/adapters/local/get_file_outline/search_outline.py,sha256=D2-42n2dON3QHKCJUsIrEBbJ8IrbwMmxpMGjr8Ik--Y,1197
225
+ janito/tools/adapters/local/get_file_outline/search_outline.py,sha256=wzJZT0dzfuNzGv18LFShusBVkK4DO_hMUQ2PQbIMQIw,1330
213
226
  janito/tools/adapters/local/search_text/__init__.py,sha256=FEYpF5tTtf0fiAyRGIGSn-kV-MJDkhdFIbus16mYW8Y,34
214
- janito/tools/adapters/local/search_text/core.py,sha256=925y-xI25TZcN-AG7AONNnS1fLOxVio01sxSLKborNc,7655
227
+ janito/tools/adapters/local/search_text/core.py,sha256=FQ2lx0LLnfgkdY4rnhLc5uU9bzH8j-CTdGvAe9nAsJs,7788
215
228
  janito/tools/adapters/local/search_text/match_lines.py,sha256=RLR8fZFP-Q57rY0fTENbMItmt3dJZiYX0otmGHVRjfw,2131
216
229
  janito/tools/adapters/local/search_text/pattern_utils.py,sha256=D7vtAr8oT0tGV0C_UUarAXS9XQtP-MTYmmc8Yg8iVTg,2362
217
230
  janito/tools/adapters/local/search_text/traverse_directory.py,sha256=EpL1qywAV0H29pm8-QsHrjKchKP4i4sRUOENVuNptCo,4000
218
231
  janito/tools/adapters/local/validate_file_syntax/__init__.py,sha256=P53RHmas4BbHL90cMxH9m-RpMCJI8JquoJb0rpkPVVk,29
219
- janito/tools/adapters/local/validate_file_syntax/core.py,sha256=VuFtqJiQoS1lTF2zI-Z3PpVMKdCj-LqVcoZtji0V-L0,3322
232
+ janito/tools/adapters/local/validate_file_syntax/core.py,sha256=VEwbx_QpmE8ghiz5tBQBFTzysXdMeLgybUf5XiVxNC8,3613
220
233
  janito/tools/adapters/local/validate_file_syntax/css_validator.py,sha256=jE5d26C_fU9k9azujbGVISn2WIRL-Ys6de4dsCq30bo,1351
221
234
  janito/tools/adapters/local/validate_file_syntax/html_validator.py,sha256=VV93BRcAeUraXHc9dUyH1cs9gRwRwO84K1-L5zbJnYU,3207
235
+ janito/tools/adapters/local/validate_file_syntax/jinja2_validator.py,sha256=SEVvl1m8CJbMhwEHLSDOgC2FGe7iSftc3K08IPphH3o,1797
222
236
  janito/tools/adapters/local/validate_file_syntax/js_validator.py,sha256=42LvgyMVhG9c2EAaSz3J9pu-yuh1oyIvRp0wN2rHiDQ,998
223
237
  janito/tools/adapters/local/validate_file_syntax/json_validator.py,sha256=muCB0-bdxk9zNulzH1It3hWpYzJC3hD8LbxCnE0P5is,150
224
238
  janito/tools/adapters/local/validate_file_syntax/markdown_validator.py,sha256=k4UT88fXvtclygz-nFhCMHJL5sk5WlGD-fP_cWqWMyU,3511
@@ -226,9 +240,9 @@ janito/tools/adapters/local/validate_file_syntax/ps1_validator.py,sha256=TeIkPt0
226
240
  janito/tools/adapters/local/validate_file_syntax/python_validator.py,sha256=BfCO_K18qy92m-2ZVvHsbEU5e11OPo1pO9Vz4G4616E,130
227
241
  janito/tools/adapters/local/validate_file_syntax/xml_validator.py,sha256=AijlsP_PgNuC8ZbGsC5vOTt3Jur76otQzkd_7qR0QFY,284
228
242
  janito/tools/adapters/local/validate_file_syntax/yaml_validator.py,sha256=TgyI0HRL6ug_gBcWEm5TGJJuA4E34ZXcIzMpAbv3oJs,155
229
- janito-2.21.0.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
230
- janito-2.21.0.dist-info/METADATA,sha256=YCkSoe96woQWCrwi_bRPCY7vnPUOqvcPG6j98r6GTmc,16365
231
- janito-2.21.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
232
- janito-2.21.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
233
- janito-2.21.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
234
- janito-2.21.0.dist-info/RECORD,,
243
+ janito-2.24.0.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
244
+ janito-2.24.0.dist-info/METADATA,sha256=uTOM-WfNS-8TIdqVbEAK-vgj6dQd79A3rhWY4LM8KoE,16365
245
+ janito-2.24.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
246
+ janito-2.24.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
247
+ janito-2.24.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
248
+ janito-2.24.0.dist-info/RECORD,,