janito 2.24.1__py3-none-any.whl → 2.26.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 (48) hide show
  1. janito/cli/chat_mode/session.py +2 -2
  2. janito/cli/chat_mode/shell/commands/unrestricted.py +40 -0
  3. janito/cli/cli_commands/list_plugins.py +32 -0
  4. janito/cli/core/getters.py +2 -0
  5. janito/cli/main_cli.py +6 -2
  6. janito/cli/single_shot_mode/handler.py +2 -2
  7. janito/config_manager.py +8 -0
  8. janito/exceptions.py +19 -1
  9. janito/plugins/base.py +53 -2
  10. janito/plugins/config.py +87 -0
  11. janito/plugins/discovery.py +32 -0
  12. janito/plugins/manager.py +56 -2
  13. janito/tools/adapters/local/adapter.py +8 -26
  14. janito/tools/adapters/local/ask_user.py +1 -1
  15. janito/tools/adapters/local/copy_file.py +3 -1
  16. janito/tools/adapters/local/create_directory.py +2 -2
  17. janito/tools/adapters/local/create_file.py +8 -4
  18. janito/tools/adapters/local/fetch_url.py +25 -22
  19. janito/tools/adapters/local/find_files.py +3 -2
  20. janito/tools/adapters/local/get_file_outline/core.py +3 -1
  21. janito/tools/adapters/local/get_file_outline/search_outline.py +1 -1
  22. janito/tools/adapters/local/move_file.py +3 -2
  23. janito/tools/adapters/local/open_html_in_browser.py +1 -1
  24. janito/tools/adapters/local/open_url.py +1 -1
  25. janito/tools/adapters/local/python_file_run.py +2 -0
  26. janito/tools/adapters/local/read_chart.py +61 -54
  27. janito/tools/adapters/local/read_files.py +4 -3
  28. janito/tools/adapters/local/remove_directory.py +2 -0
  29. janito/tools/adapters/local/remove_file.py +3 -3
  30. janito/tools/adapters/local/run_powershell_command.py +1 -0
  31. janito/tools/adapters/local/search_text/core.py +3 -2
  32. janito/tools/adapters/local/validate_file_syntax/core.py +3 -1
  33. janito/tools/adapters/local/view_file.py +3 -1
  34. janito/tools/loop_protection_decorator.py +64 -25
  35. janito/tools/path_utils.py +39 -0
  36. janito/tools/tools_adapter.py +68 -22
  37. {janito-2.24.1.dist-info → janito-2.26.0.dist-info}/METADATA +1 -1
  38. {janito-2.24.1.dist-info → janito-2.26.0.dist-info}/RECORD +47 -39
  39. janito-2.26.0.dist-info/top_level.txt +2 -0
  40. janito-coder/janito_coder/__init__.py +9 -0
  41. janito-coder/janito_coder/plugins/__init__.py +27 -0
  42. janito-coder/janito_coder/plugins/code_navigator.py +618 -0
  43. janito-coder/janito_coder/plugins/git_analyzer.py +273 -0
  44. janito-coder/pyproject.toml +347 -0
  45. janito-2.24.1.dist-info/top_level.txt +0 -1
  46. {janito-2.24.1.dist-info → janito-2.26.0.dist-info}/WHEEL +0 -0
  47. {janito-2.24.1.dist-info → janito-2.26.0.dist-info}/entry_points.txt +0 -0
  48. {janito-2.24.1.dist-info → janito-2.26.0.dist-info}/licenses/LICENSE +0 -0
@@ -12,48 +12,57 @@ _decorator_call_tracker_lock = threading.Lock()
12
12
 
13
13
 
14
14
  def protect_against_loops(
15
- max_calls: int = 5,
16
- time_window: float = 10.0
15
+ max_calls: int = 5, time_window: float = 10.0, key_field: str = None
17
16
  ):
18
17
  """
19
18
  Decorator that adds loop protection to tool run methods.
20
-
19
+
21
20
  This decorator monitors tool executions and prevents excessive calls within
22
21
  a configurable time window. It helps prevent infinite loops or excessive
23
22
  resource consumption when tools are called repeatedly.
24
-
23
+
25
24
  When the configured limits are exceeded, the decorator raises a RuntimeError
26
25
  with a descriptive message. This exception will propagate up the call stack
27
26
  unless caught by a try/except block in the calling code.
28
-
27
+
29
28
  The decorator works by:
30
29
  1. Tracking the number of calls to the decorated function
31
30
  2. Checking if the calls exceed the configured limits
32
31
  3. Raising a RuntimeError if a potential loop is detected
33
32
  4. Allowing the method to proceed normally if the operation is safe
34
-
33
+
35
34
  Args:
36
35
  max_calls (int): Maximum number of calls allowed within the time window.
37
36
  Defaults to 5 calls.
38
37
  time_window (float): Time window in seconds for detecting excessive calls.
39
38
  Defaults to 10.0 seconds.
40
-
39
+ key_field (str, optional): The parameter name to use for key matching instead of function name.
40
+ If provided, the decorator will track calls based on the value of this
41
+ parameter rather than the function name. Useful for tools that operate
42
+ on specific files or resources.
43
+
41
44
  Example:
42
45
  >>> @protect_against_loops(max_calls=3, time_window=5.0)
43
46
  >>> def run(self, path: str) -> str:
44
47
  >>> # Implementation here
45
48
  >>> pass
46
-
49
+
47
50
  >>> @protect_against_loops(max_calls=10, time_window=30.0)
48
51
  >>> def run(self, file_paths: list) -> str:
49
52
  >>> # Implementation here
50
53
  >>> pass
51
-
54
+
55
+ >>> @protect_against_loops(max_calls=5, time_window=10.0, key_field='path')
56
+ >>> def run(self, path: str) -> str:
57
+ >>> # This will track calls per unique path value
58
+ >>> pass
59
+
52
60
  Note:
53
61
  When loop protection is triggered, a RuntimeError will be raised with a
54
62
  descriptive message. This exception will propagate up the call stack
55
63
  unless caught by a try/except block in the calling code.
56
64
  """
65
+
57
66
  def decorator(func):
58
67
  @functools.wraps(func)
59
68
  def wrapper(*args, **kwargs):
@@ -61,50 +70,80 @@ def protect_against_loops(
61
70
  if not args:
62
71
  # This shouldn't happen in normal usage as methods need self
63
72
  return func(*args, **kwargs)
64
-
65
- # Use the function name as the operation name
66
- op_name = func.__name__
67
-
73
+
74
+ # Determine the operation key
75
+ if key_field:
76
+ # Use the key_field parameter value as the operation key
77
+ key_value = None
78
+ if key_field in kwargs:
79
+ key_value = kwargs[key_field]
80
+ elif len(args) > 1:
81
+ # Handle positional arguments - need to map parameter names
82
+ import inspect
83
+
84
+ try:
85
+ sig = inspect.signature(func)
86
+ param_names = list(sig.parameters.keys())
87
+ if key_field in param_names:
88
+ field_index = param_names.index(key_field)
89
+ if field_index < len(args):
90
+ key_value = args[field_index]
91
+ except (ValueError, TypeError):
92
+ pass
93
+
94
+ if key_value is not None:
95
+ op_name = f"{func.__name__}_{key_value}"
96
+ else:
97
+ op_name = func.__name__
98
+ else:
99
+ # Use the function name as the operation name
100
+ op_name = func.__name__
101
+
68
102
  # Check call limits
69
103
  current_time = time.time()
70
-
104
+
71
105
  with _decorator_call_tracker_lock:
72
106
  # Clean up old entries outside the time window
73
107
  if op_name in _decorator_call_tracker:
74
108
  _decorator_call_tracker[op_name] = [
75
- timestamp for timestamp in _decorator_call_tracker[op_name]
109
+ timestamp
110
+ for timestamp in _decorator_call_tracker[op_name]
76
111
  if current_time - timestamp <= time_window
77
112
  ]
78
-
113
+
79
114
  # Check if we're exceeding the limit
80
115
  if op_name in _decorator_call_tracker:
81
116
  if len(_decorator_call_tracker[op_name]) >= max_calls:
82
117
  # 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]):
118
+ if all(
119
+ current_time - timestamp <= time_window
120
+ for timestamp in _decorator_call_tracker[op_name]
121
+ ):
85
122
  # Define the error reporting function
86
123
  def _report_error_and_raise(args, operation_type):
87
124
  # Get the tool instance to access report_error method if available
88
125
  tool_instance = args[0] if args else None
89
126
  error_msg = f"Loop protection: Too many {operation_type} operations in a short time period ({max_calls} calls in {time_window}s)"
90
-
127
+
91
128
  # Try to report the error through the tool's reporting mechanism
92
- if hasattr(tool_instance, 'report_error'):
129
+ if hasattr(tool_instance, "report_error"):
93
130
  try:
94
131
  tool_instance.report_error(error_msg)
95
132
  except Exception:
96
133
  pass # If reporting fails, we still raise the error
97
-
134
+
98
135
  raise RuntimeError(error_msg)
99
-
136
+
100
137
  _report_error_and_raise(args, op_name)
101
-
138
+
102
139
  # Record this call
103
140
  if op_name not in _decorator_call_tracker:
104
141
  _decorator_call_tracker[op_name] = []
105
142
  _decorator_call_tracker[op_name].append(current_time)
106
-
143
+
107
144
  # Proceed with the original function
108
145
  return func(*args, **kwargs)
146
+
109
147
  return wrapper
110
- return decorator
148
+
149
+ return decorator
@@ -0,0 +1,39 @@
1
+ """
2
+ Path utilities for handling tilde expansion and other path operations.
3
+ """
4
+
5
+ import os
6
+ from pathlib import Path
7
+
8
+
9
+ def expand_path(path: str) -> str:
10
+ """
11
+ Expand a path, handling tilde (~) expansion for user home directory.
12
+
13
+ Args:
14
+ path (str): The path to expand.
15
+
16
+ Returns:
17
+ str: The expanded absolute path.
18
+ """
19
+ if not path:
20
+ return path
21
+
22
+ # Handle tilde expansion
23
+ expanded = os.path.expanduser(path)
24
+
25
+ # Convert to absolute path
26
+ return os.path.abspath(expanded)
27
+
28
+
29
+ def normalize_path(path: str) -> str:
30
+ """
31
+ Normalize a path by expanding tilde and resolving any relative paths.
32
+
33
+ Args:
34
+ path (str): The path to normalize.
35
+
36
+ Returns:
37
+ str: The normalized absolute path.
38
+ """
39
+ return expand_path(path)
@@ -67,8 +67,6 @@ class ToolsAdapterBase:
67
67
  def add_tool(self, tool):
68
68
  self._tools.append(tool)
69
69
 
70
-
71
-
72
70
  def _validate_arguments_against_schema(self, arguments: dict, schema: dict):
73
71
  properties = schema.get("properties", {})
74
72
  required = schema.get("required", [])
@@ -151,7 +149,13 @@ class ToolsAdapterBase:
151
149
  if not accepts_kwargs:
152
150
  unexpected = [k for k in arguments.keys() if k not in params]
153
151
  if unexpected:
154
- return "Unexpected argument(s): " + ", ".join(sorted(unexpected))
152
+ # Build detailed error message with received arguments
153
+ error_parts = ["Unexpected argument(s): " + ", ".join(sorted(unexpected))]
154
+ error_parts.append("Valid parameters: " + ", ".join(sorted(params.keys())))
155
+ error_parts.append("Arguments received:")
156
+ for key, value in arguments.items():
157
+ error_parts.append(f" {key}: {repr(value)} ({type(value).__name__})")
158
+ return "\n".join(error_parts)
155
159
 
156
160
  # Check for missing required arguments (ignoring *args / **kwargs / self)
157
161
  required_params = [
@@ -167,7 +171,17 @@ class ToolsAdapterBase:
167
171
  ]
168
172
  missing = [name for name in required_params if name not in arguments]
169
173
  if missing:
170
- return "Missing required argument(s): " + ", ".join(sorted(missing))
174
+ # Build detailed error message with received arguments
175
+ error_parts = ["Missing required argument(s): " + ", ".join(sorted(missing))]
176
+ error_parts.append("Arguments received:")
177
+ if isinstance(arguments, dict):
178
+ for key, value in arguments.items():
179
+ error_parts.append(f" {key}: {repr(value)} ({type(value).__name__})")
180
+ elif arguments is not None:
181
+ error_parts.append(f" {repr(arguments)} ({type(arguments).__name__})")
182
+ else:
183
+ error_parts.append(" None")
184
+ return "\n".join(error_parts)
171
185
 
172
186
  return None
173
187
 
@@ -221,7 +235,10 @@ class ToolsAdapterBase:
221
235
  message=f"[SECURITY] Path access denied: {sec_err}",
222
236
  action=ReportAction.EXECUTE,
223
237
  tool=tool_name,
224
- context={"arguments": arguments, "request_id": request_id},
238
+ context={
239
+ "arguments": arguments,
240
+ "request_id": request_id,
241
+ },
225
242
  )
226
243
  )
227
244
  return f"Security error: {sec_err}"
@@ -234,7 +251,7 @@ class ToolsAdapterBase:
234
251
  try:
235
252
  # Normalize arguments to ensure proper type handling
236
253
  normalized_args = self._normalize_arguments(arguments, tool, func)
237
-
254
+
238
255
  if isinstance(normalized_args, (list, tuple)):
239
256
  # Positional arguments supplied as an array → expand as *args
240
257
  result = self.execute(tool, *normalized_args, **kwargs)
@@ -245,7 +262,14 @@ class ToolsAdapterBase:
245
262
  # Single positional argument (scalar/str/int/…)
246
263
  result = self.execute(tool, normalized_args, **kwargs)
247
264
  except Exception as e:
248
- self._handle_execution_error(tool_name, request_id, e, arguments)
265
+ # Handle exception and return error message instead of raising
266
+ error_result = self._handle_execution_error(
267
+ tool_name, request_id, e, arguments
268
+ )
269
+ if error_result is not None:
270
+ return error_result
271
+ # If _handle_execution_error returns None, re-raise
272
+ raise
249
273
  self._print_verbose(
250
274
  f"[tools-adapter] Tool execution finished: {tool_name} -> {result}"
251
275
  )
@@ -303,7 +327,7 @@ class ToolsAdapterBase:
303
327
  def _normalize_arguments(self, arguments, tool, func):
304
328
  """
305
329
  Normalize arguments to ensure proper type handling at the adapter level.
306
-
330
+
307
331
  This handles cases where:
308
332
  1. String is passed instead of list for array parameters
309
333
  2. JSON string parsing issues
@@ -311,51 +335,57 @@ class ToolsAdapterBase:
311
335
  """
312
336
  import inspect
313
337
  import json
314
-
338
+
315
339
  # If arguments is already a dict or None, return as-is
316
340
  if isinstance(arguments, dict) or arguments is None:
317
341
  return arguments
318
-
342
+
319
343
  # If arguments is a list/tuple, return as-is (positional args)
320
344
  if isinstance(arguments, (list, tuple)):
321
345
  return arguments
322
-
346
+
323
347
  # Handle string arguments
324
348
  if isinstance(arguments, str):
325
349
  # Try to parse as JSON if it looks like JSON
326
350
  stripped = arguments.strip()
327
- if (stripped.startswith('{') and stripped.endswith('}')) or \
328
- (stripped.startswith('[') and stripped.endswith(']')):
351
+ if (stripped.startswith("{") and stripped.endswith("}")) or (
352
+ stripped.startswith("[") and stripped.endswith("]")
353
+ ):
329
354
  try:
330
355
  parsed = json.loads(arguments)
331
356
  return parsed
332
357
  except json.JSONDecodeError:
333
358
  # If it looks like JSON but failed, try to handle common issues
334
359
  pass
335
-
360
+
336
361
  # Check if the function expects a list parameter
337
362
  try:
338
363
  sig = inspect.signature(func)
339
364
  params = list(sig.parameters.values())
340
-
365
+
341
366
  # Skip 'self' parameter for methods
342
- if len(params) > 0 and params[0].name == 'self':
367
+ if len(params) > 0 and params[0].name == "self":
343
368
  params = params[1:]
344
-
369
+
345
370
  # If there's exactly one parameter that expects a list, wrap string in list
346
371
  if len(params) == 1:
347
372
  param = params[0]
348
373
  annotation = param.annotation
349
-
374
+
350
375
  # Check if annotation is list[str] or similar
351
- if hasattr(annotation, '__origin__') and annotation.__origin__ is list:
376
+ if (
377
+ hasattr(annotation, "__origin__")
378
+ and annotation.__origin__ is list
379
+ ):
352
380
  return [arguments]
353
- elif str(annotation).startswith('list[') or str(annotation) == 'list':
381
+ elif (
382
+ str(annotation).startswith("list[") or str(annotation) == "list"
383
+ ):
354
384
  return [arguments]
355
-
385
+
356
386
  except (ValueError, TypeError):
357
387
  pass
358
-
388
+
359
389
  # Return original arguments for other cases
360
390
  return arguments
361
391
 
@@ -420,6 +450,22 @@ class ToolsAdapterBase:
420
450
  raise ToolCallException(tool_name, error_msg, arguments=arguments)
421
451
 
422
452
  def _handle_execution_error(self, tool_name, request_id, exception, arguments):
453
+ # Check if this is a loop protection error that should be returned as a string
454
+ if isinstance(exception, RuntimeError) and "Loop protection:" in str(exception):
455
+ error_msg = str(exception) # Return the loop protection message directly
456
+ if self._event_bus:
457
+ self._event_bus.publish(
458
+ ToolCallError(
459
+ tool_name=tool_name,
460
+ request_id=request_id,
461
+ error=error_msg,
462
+ exception=exception,
463
+ arguments=arguments,
464
+ )
465
+ )
466
+ # Return the error message instead of raising an exception
467
+ return error_msg
468
+
423
469
  error_msg = f"Exception during execution of tool '{tool_name}': {exception}"
424
470
  if self._event_bus:
425
471
  self._event_bus.publish(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 2.24.1
3
+ Version: 2.26.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,11 +3,11 @@ 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=mj6SKydJyef0z4iRE3iewdU1Ki9Ws2V34qPQwdpPDuc,5893
6
+ janito/config_manager.py,sha256=OlH2njpc_JUh9HAyhJ9Oy8CFnIIzTHCCzngxUKRwvBs,6277
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
10
- janito/exceptions.py,sha256=l4AepRdWwAuLp5fUygrBBgO9rpwgfV6JvY1afOdq2pw,913
10
+ janito/exceptions.py,sha256=PVjTas5XH09B63nxDyn6oHLRueXiKpqR7a9fY7toWs8,1770
11
11
  janito/formatting.py,sha256=SMvOmL6bst3KGcI7OLa5D4DE127fQYuHZS3oY8OPsn8,2031
12
12
  janito/formatting_token.py,sha256=UefBF8Nn3BU8bJNQRrJWB3i3zXEwkRRZMPGuAOJaDYI,2440
13
13
  janito/gitignore_utils.py,sha256=P3iF9fMWAomqULq2xsoqHtI9uNIFSPcagljrxZshmLw,4110
@@ -29,7 +29,7 @@ janito/cli/__init__.py,sha256=xaPDOrWphBbCR63Xpcx_yfpXSJIlCaaICc4j2qpWqrM,194
29
29
  janito/cli/config.py,sha256=HkZ14701HzIqrvaNyDcDhGlVHfpX_uHlLp2rHmhRm_k,872
30
30
  janito/cli/console.py,sha256=gJolqzWL7jEPLxeuH-CwBDRFpXt976KdZOEAB2tdBDs,64
31
31
  janito/cli/main.py,sha256=s5odou0txf8pzTf1ADk2yV7T5m8B6cejJ81e7iu776U,312
32
- janito/cli/main_cli.py,sha256=eD0uS3FslmAFQgH6rPqQOBiKS41Kr0zGAY-LecK79k8,16217
32
+ janito/cli/main_cli.py,sha256=GzuWWHYqvK_ebbvXKNvqKaSh0lObQH5qYSNN2mvsf14,16380
33
33
  janito/cli/prompt_core.py,sha256=F68J4Xl6jZMYFN4oBBYZFj15Jp-HTYoLub4bw2XpNRU,11648
34
34
  janito/cli/prompt_handler.py,sha256=SnPTlL64noeAMGlI08VBDD5IDD8jlVMIYA4-fS8zVLg,215
35
35
  janito/cli/prompt_setup.py,sha256=1SSvvgS568-3BO_4Sw9A-QF_iLWiIXsNHT0JVqaLwkU,2120
@@ -40,7 +40,7 @@ janito/cli/chat_mode/bindings.py,sha256=odjc5_-YW1t2FRhBUNRNoBMoQIg5sMz3ktV7xG0A
40
40
  janito/cli/chat_mode/chat_entry.py,sha256=RFdPd23jsA2DMHRacpjAdwI_1dFBaWrtnwyQEgb2fHA,475
41
41
  janito/cli/chat_mode/prompt_style.py,sha256=vsqQ9xxmrYjj1pWuVe9CayQf39fo2EIXrkKPkflSVn4,805
42
42
  janito/cli/chat_mode/script_runner.py,sha256=wOwEn4bgmjqHqjTqtfyaSOnRPsGf4ZVW-YAWhEeqxXU,6507
43
- janito/cli/chat_mode/session.py,sha256=lDoEAvCHvRA5MZG1CsCBt7uJNsMUS81_qaxQbzS0rqA,15967
43
+ janito/cli/chat_mode/session.py,sha256=-AcgXu8NOvcxR_1GVpPWkcIHQ0GZs1awmRyKzlz-PcQ,15973
44
44
  janito/cli/chat_mode/session_profile_select.py,sha256=23al0mw0unBlTqRg-ZI3RJa-XV8hdwVsizYJw_Lg2xY,6363
45
45
  janito/cli/chat_mode/toolbar.py,sha256=bJ9jPaTInp2gB3yjSVJp8mpNEFiOslzNhVaiqpXJhKc,3025
46
46
  janito/cli/chat_mode/shell/autocomplete.py,sha256=lE68MaVaodbA2VfUM0_YLqQVLBJAE_BJsd5cMtwuD-g,793
@@ -68,6 +68,7 @@ janito/cli/chat_mode/shell/commands/security_command.py,sha256=7Xgjb8Gunk9CjKxz1
68
68
  janito/cli/chat_mode/shell/commands/session.py,sha256=9wsw5U24-KJgTT70KAwnGuS8MVPyvpxCJfAt_Io76O0,1574
69
69
  janito/cli/chat_mode/shell/commands/session_control.py,sha256=tmMGJ8IvWoBwSIJu7T6GPnFYFrmXWIG2Gr9tTni4y3U,1307
70
70
  janito/cli/chat_mode/shell/commands/tools.py,sha256=8BWgqB0j5sp7mYupxoAjYvLWjb_wODOfCk-I8yNfk-U,3473
71
+ janito/cli/chat_mode/shell/commands/unrestricted.py,sha256=cVlQ0o-Zq0ll1ZMCq5TLm52fAee44TwwiRen0kN6hWU,1699
71
72
  janito/cli/chat_mode/shell/commands/utility.py,sha256=K982P-UwgPLzpEvSuSBGwiQ3zC34S_6T2ork_djweQw,847
72
73
  janito/cli/chat_mode/shell/commands/verbose.py,sha256=HDTe0NhdcjBuhh-eJSW8iLPDeeBO95K5iSDAMAljxa4,953
73
74
  janito/cli/chat_mode/shell/commands/write.py,sha256=bpvJzHY7wlpgsB-cpslzfQQl7h6n-NLqj2gFCuJfjVk,2309
@@ -79,7 +80,7 @@ janito/cli/chat_mode/shell/session/manager.py,sha256=MwD9reHsRaly0CyRB-S1JJ0wPKz
79
80
  janito/cli/cli_commands/list_config.py,sha256=oiQEGaGPjwjG-PrOcakpNMbbqISTsBEs7rkGH3ceQsI,1179
80
81
  janito/cli/cli_commands/list_drivers.py,sha256=r2ENykUcvf_9XYp6LHd3RvLXGXyVUA6oe_Pr0dyv92I,5124
81
82
  janito/cli/cli_commands/list_models.py,sha256=7Cyjfwht77nm6_h1DRY2A-Nkkm1Kiy0e339EYglVqEI,1619
82
- janito/cli/cli_commands/list_plugins.py,sha256=Z4qiomhc7sedG5v87AC0ewrJRpCA_saC_8dxrrtON74,1517
83
+ janito/cli/cli_commands/list_plugins.py,sha256=Is4ewXl7QE9L_H3tMq3uloItHzE9BCf0e0viVwB5tdM,2981
83
84
  janito/cli/cli_commands/list_profiles.py,sha256=Duonbhko9GmkT9odJerlYKg9fE1kHTTaU7P2W2_51qk,3557
84
85
  janito/cli/cli_commands/list_providers.py,sha256=3ywm1Ohv7yVqV1E9hB-3Jz8BwzhyCScKxffq6iDI4nA,391
85
86
  janito/cli/cli_commands/list_providers_region.py,sha256=qrMj_gtgEMty8UH0P_O5SgWCVJ9ZKxGUp_GdsE4_EH4,2548
@@ -92,13 +93,13 @@ janito/cli/cli_commands/show_config.py,sha256=eYMcuvU-d7mvvuctbQacZFERqcKHEnxaRR
92
93
  janito/cli/cli_commands/show_system_prompt.py,sha256=YKOVHKzz6pzwvJGlqVEK2R4i98HGrUZHsrsFNvBBEd8,5898
93
94
  janito/cli/core/__init__.py,sha256=YH95fhgY9yBX8RgqX9dSrEkl4exjV0T4rbmJ6xUpG-Y,196
94
95
  janito/cli/core/event_logger.py,sha256=1X6lR0Ax7AgF8HlPWFoY5Ystuu7Bh4ooTo78vXzeGB0,2008
95
- janito/cli/core/getters.py,sha256=rVgDyBqbDNYpx0sr6W2u3Kh_Lv_DERjr3x9ny7bAjX0,2518
96
+ janito/cli/core/getters.py,sha256=WMoiCPsOwAPjxPrOH1phUaWt7T9BIzGl7qtM25g93Sg,2604
96
97
  janito/cli/core/model_guesser.py,sha256=jzkkiQ-J2buT2Omh6jYZHa8-zCJxqKQBL08Z58pe1_o,1741
97
98
  janito/cli/core/runner.py,sha256=uF4NZUm6TyALKzZD3CjeUlBDpdMbftWSEAAEUEqgAZA,8587
98
99
  janito/cli/core/setters.py,sha256=cHoZsKAtMfRXfn_sLWWaXAh8WWL1XIvHTjUxcDmIM94,5077
99
100
  janito/cli/core/unsetters.py,sha256=FEw9gCt0vRvoCt0kRSNfVB2tzi_TqppJIx2nHPP59-k,2012
100
101
  janito/cli/single_shot_mode/__init__.py,sha256=Ct99pKe9tINzVW6oedZJfzfZQKWpXz-weSSCn0hrwHY,115
101
- janito/cli/single_shot_mode/handler.py,sha256=deECFk2Zj2uqxNS7D8yH4pHv6UurLTktjIQxmneXXF8,5523
102
+ janito/cli/single_shot_mode/handler.py,sha256=d251ObY-5bkUyccV9NYkKDF0VCKrQTrGEnwt3mtj61w,5529
102
103
  janito/docs/GETTING_STARTED.md,sha256=zbsOfHi3H4I5qM-cj9wp4QUkmqNcq28cJc0kZMAlgIU,4978
103
104
  janito/drivers/dashscope.bak.zip,sha256=9Pv4Xyciju8jO1lEMFVgYXexoZkxmDO3Ig6vw3ODfL8,4936
104
105
  janito/drivers/openai_responses.bak.zip,sha256=E43eDCHGa2tCtdjzj_pMnWDdnsOZzj8BJTR5tJp8wcM,13352
@@ -130,9 +131,10 @@ janito/llm/message_parts.py,sha256=QY_0kDjaxdoErDgKPRPv1dNkkYJuXIBmHWNLiOEKAH4,1
130
131
  janito/llm/model.py,sha256=EioBkdgn8hJ0iQaKN-0KbXlsrk3YKmwR9IbvoEbdVTE,1159
131
132
  janito/llm/provider.py,sha256=3FbhQPrWBSEoIdIi-5DWIh0DD_CM570EFf1NcuGyGko,7961
132
133
  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
134
+ janito/plugins/base.py,sha256=rpCiASpEjvBngZmoq4pM9AkdR8hHPIOgNZjz1kh-rGU,4252
135
+ janito/plugins/config.py,sha256=ncenRCT0h3SyE2JCzuIDMnMSvdQKK7H0q0ZzZoydtKE,2449
136
+ janito/plugins/discovery.py,sha256=byEAn3Hl-PhyjkGoHwGJeRDRcVNL63SrKOHRl1MTXPg,6001
137
+ janito/plugins/manager.py,sha256=iqvRRJRM9nlicxQHO9nid9qwY8IyZLYABNWZ8akCqcY,8321
136
138
  janito/providers/__init__.py,sha256=SWXtbW3lU7ORi6d9Ro04qnGDDNJ2Cwq0hfbKdZeResg,530
137
139
  janito/providers/dashscope.bak.zip,sha256=BwXxRmZreEivvRtmqbr5BR62IFVlNjAf4y6DrF2BVJo,5998
138
140
  janito/providers/registry.py,sha256=Ygwv9eVrTXOKhv0EKxSWQXO5WMHvajWE2Q_Lc3p7dKo,730
@@ -180,9 +182,10 @@ janito/tools/__init__.py,sha256=W1B39PztC2UF7PS2WyLH6el32MFOETMlN1-LurOROCg,1171
180
182
  janito/tools/disabled_tools.py,sha256=Tx__16wtMWZ9z34cYLdH1gukwot5MCL-9kLjd5MPX6Y,2110
181
183
  janito/tools/inspect_registry.py,sha256=Jo7PrMPRKLuR-j_mBAk9PBcTzeJf1eQrS1ChGofgQk0,538
182
184
  janito/tools/loop_protection.py,sha256=DoOuQZ53PZ-Zmn7MD76KwOgjbd0esV2ESnXTDHV9IE4,4804
183
- janito/tools/loop_protection_decorator.py,sha256=tI3zpdkjrxk6WR4QFItKS-dZVOIrA-jva8AbC4yP2QI,5096
185
+ janito/tools/loop_protection_decorator.py,sha256=bS28p9MTVEDlrw2vRYX2B-HADFJL3768aThz65U24qw,6668
184
186
  janito/tools/outline_file.bak.zip,sha256=EeI2cBXCwTdWVgJDNiroxKeYlkjwo6NLKeXz3J-2iZI,15607
185
187
  janito/tools/path_security.py,sha256=40b0hV0X3449Dht93A04Q3c9AYSsBQsBFy2BjzM83lA,8214
188
+ janito/tools/path_utils.py,sha256=jY2frgKxE1495Nmzxrlq1-NzguTkICrp9pYWjYWhpKE,862
186
189
  janito/tools/permissions.py,sha256=_viTVXyetZC01HjI2s5c3klIJ8-RkWB1ShdOaV__loY,1508
187
190
  janito/tools/permissions_parse.py,sha256=LHadt0bWglm9Q2BbbVVbKePg4oa7QLeRQ-ChQZsE_dI,384
188
191
  janito/tools/tool_base.py,sha256=6meJZwbsqDIerh84T_C6K9G706wqoSkoR1vnrRk6mvo,3693
@@ -190,46 +193,46 @@ janito/tools/tool_events.py,sha256=czRtC2TYakAySBZvfHS_Q6_NY_7_krxzAzAL1ggRFWA,1
190
193
  janito/tools/tool_run_exception.py,sha256=43yWgTaGBGEtRteo6FvTrane6fEVGo9FU1uOdjMRWJE,525
191
194
  janito/tools/tool_use_tracker.py,sha256=IaEmA22D6RuL1xMUCScOMGv0crLPwEJVGmj49cydIaM,2662
192
195
  janito/tools/tool_utils.py,sha256=alPm9DvtXSw_zPRKvP5GjbebPRf_nfvmWk2TNlL5Cws,1219
193
- janito/tools/tools_adapter.py,sha256=aPzyJnm1pNwsEKNcXs-gKFurlOaZqzxkiktHOjITp_8,18724
196
+ janito/tools/tools_adapter.py,sha256=_L6HtVHvlE2yrjAAAtSZ4PANocXrA1fiWwPZ5sirz2s,20836
194
197
  janito/tools/tools_schema.py,sha256=rGrKrmpPNR07VXHAJ_haGBRRO-YGLOF51BlYRep9AAQ,4415
195
198
  janito/tools/url_whitelist.py,sha256=bFUba5h4P0aXGbVRqwF_x4I5uzHtlLXnpb24BndOkCM,4395
196
199
  janito/tools/adapters/__init__.py,sha256=XKixOKtUJs1R-rGwGDXSLVLg5-Kp090gvWbsseWT4LI,92
197
200
  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
200
- janito/tools/adapters/local/copy_file.py,sha256=MSa0VtbIXFGz00q-nW2KdtzER0icm6Y1w7MKKE6A6us,3582
201
- janito/tools/adapters/local/create_directory.py,sha256=cmSbNUsqsY8wZ2RsX-g2c9FZkkTIM5jIvFyKKqvZKxM,2565
202
- janito/tools/adapters/local/create_file.py,sha256=fDdLzKchyGMx6o2L6k-_KYxDofcktdrXcV7lKuiZMMo,3458
201
+ janito/tools/adapters/local/adapter.py,sha256=u4nLHTaYdwZXMi1J8lsKvlG6rOmdq9xjey_3zeyCG4k,8707
202
+ janito/tools/adapters/local/ask_user.py,sha256=A2FT_bubNYXmxQg8TwdieKDh3rnhiUA_1WDjMbX_PME,3755
203
+ janito/tools/adapters/local/copy_file.py,sha256=SBJm19Ipe5dqRE1Mxl6JSrn4bNmfObVnDr5b1mcEu6c,3682
204
+ janito/tools/adapters/local/create_directory.py,sha256=LxwqQEsnOrEphCIoaMRRx9P9bu0MzidP3Fc5q6letxc,2584
205
+ janito/tools/adapters/local/create_file.py,sha256=Y3cSYg0nWt2HGPj0j4Ut25joSkecsXOcw3OUc28IZCg,3764
203
206
  janito/tools/adapters/local/delete_text_in_file.py,sha256=uEeedRxXAR7_CqUc_qhbEdM0OzRi_pgnP-iDjs2Zvjk,5087
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
206
- janito/tools/adapters/local/move_file.py,sha256=PBVp_gcmNxOLJeJsAtENg40SUG-lP7ijWE4sOG72jDk,4620
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
207
+ janito/tools/adapters/local/fetch_url.py,sha256=IhqAqT-htHJbCcPYs2ENDVCXpsiq63foDGC3XpgjJ9c,13010
208
+ janito/tools/adapters/local/find_files.py,sha256=Zbag3aP34vc7ffJh8bOqAwXj3KiZhV--uzTVHtNb-fI,6250
209
+ janito/tools/adapters/local/move_file.py,sha256=LMGm8bn3NNyIPJG4vrlO09smXQcgzA09EwoooZxkIA8,4695
210
+ janito/tools/adapters/local/open_html_in_browser.py,sha256=XqICIwVx5vEE77gHkaNAC-bAeEEy0DBmDksATiL-sRY,2101
211
+ janito/tools/adapters/local/open_url.py,sha256=V3Sv7iLynUreLjVl5-bl-XFH_LzpTeBrS8-cvzp_7rM,1552
209
212
  janito/tools/adapters/local/python_code_run.py,sha256=HdDuiRb7Fd7WC6bFS292XnSI1EYhn9XKlh8Hs_4Cz8E,6981
210
213
  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
214
- janito/tools/adapters/local/remove_directory.py,sha256=g1wkHcWNgtv3mfuZ4GfvqtKU3th-Du_058FMcNmc1TA,1830
215
- janito/tools/adapters/local/remove_file.py,sha256=cSs7EIhEqblnLmwjUKrUq2M8axyT2oTXJqZs5waOAFw,2090
214
+ janito/tools/adapters/local/python_file_run.py,sha256=k0qK6yNAQx_bbYibuZsGtEpV9aAFGw6lhAcYgYSTQE8,6857
215
+ janito/tools/adapters/local/read_chart.py,sha256=qQebp_MEE_x2AL_pl85uA58A4lbhLQsyGl7wiG_Cjhc,10411
216
+ janito/tools/adapters/local/read_files.py,sha256=LzlNrQEadYF8dF97Wm8AHde2nuqbMkN5vVskQLhvFdA,2329
217
+ janito/tools/adapters/local/remove_directory.py,sha256=DEhHdmwJRl5Yp9eEukIIooMrpATCtXcv5HmaDRn8vH8,1913
218
+ janito/tools/adapters/local/remove_file.py,sha256=Imra4jGkBfAd6pnUAmbUsjN0exj2vzZWuNRXq_GOMsI,2093
216
219
  janito/tools/adapters/local/replace_text_in_file.py,sha256=Y6mbPuoTpsFXKrSp51s0rz7Hhz1WHkG1sY4pZ3RoZsU,10790
217
220
  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
221
+ janito/tools/adapters/local/run_powershell_command.py,sha256=x_RHJ8gKUo2I7vUbGB_KL1MS9gEhTmvewQJ-I0dsJsY,9312
222
+ janito/tools/adapters/local/view_file.py,sha256=cBKcbwbfH-UMyvQ7PmYTgsshcFmorjWtyH1kaYi7oNY,7379
220
223
  janito/tools/adapters/local/get_file_outline/__init__.py,sha256=OKV_BHnoD9h-vkcVoW6AHmsuDjjauHPCKNK0nVFl4sU,37
221
- janito/tools/adapters/local/get_file_outline/core.py,sha256=bgo4fpt2B8i6o7cWdGTQLbu8WZ3HWdA-kN2ubVStvro,4506
224
+ janito/tools/adapters/local/get_file_outline/core.py,sha256=25k6a8PaDYxAfxnEAvZvOWg2BgUcgKU_BkzJmZKUMEA,4611
222
225
  janito/tools/adapters/local/get_file_outline/java_outline.py,sha256=_UeUY5JoQEUdlHcK8aqGTqYJl0T2KxIFXPTdwum9gKQ,1825
223
226
  janito/tools/adapters/local/get_file_outline/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
224
227
  janito/tools/adapters/local/get_file_outline/python_outline.py,sha256=RAcf9Vxec08lA06drYaNre5HCJ2lTzrRAskZ3rlyE-U,10326
225
- janito/tools/adapters/local/get_file_outline/search_outline.py,sha256=wzJZT0dzfuNzGv18LFShusBVkK4DO_hMUQ2PQbIMQIw,1330
228
+ janito/tools/adapters/local/get_file_outline/search_outline.py,sha256=bski24TpnJVf3L0TNzkx3HfvaXwttQl4EVkwk2POQOw,1348
226
229
  janito/tools/adapters/local/search_text/__init__.py,sha256=FEYpF5tTtf0fiAyRGIGSn-kV-MJDkhdFIbus16mYW8Y,34
227
- janito/tools/adapters/local/search_text/core.py,sha256=FQ2lx0LLnfgkdY4rnhLc5uU9bzH8j-CTdGvAe9nAsJs,7788
230
+ janito/tools/adapters/local/search_text/core.py,sha256=Ryi3XOZNvk2dx5c1rAttXJKQI5yBKckav2baKYMKqyM,7882
228
231
  janito/tools/adapters/local/search_text/match_lines.py,sha256=RLR8fZFP-Q57rY0fTENbMItmt3dJZiYX0otmGHVRjfw,2131
229
232
  janito/tools/adapters/local/search_text/pattern_utils.py,sha256=D7vtAr8oT0tGV0C_UUarAXS9XQtP-MTYmmc8Yg8iVTg,2362
230
233
  janito/tools/adapters/local/search_text/traverse_directory.py,sha256=EpL1qywAV0H29pm8-QsHrjKchKP4i4sRUOENVuNptCo,4000
231
234
  janito/tools/adapters/local/validate_file_syntax/__init__.py,sha256=P53RHmas4BbHL90cMxH9m-RpMCJI8JquoJb0rpkPVVk,29
232
- janito/tools/adapters/local/validate_file_syntax/core.py,sha256=VEwbx_QpmE8ghiz5tBQBFTzysXdMeLgybUf5XiVxNC8,3613
235
+ janito/tools/adapters/local/validate_file_syntax/core.py,sha256=oYCpk_kyCbseKG_xX5xQjW91bPSpzzl18TPm7mMpwPI,3714
233
236
  janito/tools/adapters/local/validate_file_syntax/css_validator.py,sha256=jE5d26C_fU9k9azujbGVISn2WIRL-Ys6de4dsCq30bo,1351
234
237
  janito/tools/adapters/local/validate_file_syntax/html_validator.py,sha256=VV93BRcAeUraXHc9dUyH1cs9gRwRwO84K1-L5zbJnYU,3207
235
238
  janito/tools/adapters/local/validate_file_syntax/jinja2_validator.py,sha256=SEVvl1m8CJbMhwEHLSDOgC2FGe7iSftc3K08IPphH3o,1797
@@ -240,9 +243,14 @@ janito/tools/adapters/local/validate_file_syntax/ps1_validator.py,sha256=TeIkPt0
240
243
  janito/tools/adapters/local/validate_file_syntax/python_validator.py,sha256=BfCO_K18qy92m-2ZVvHsbEU5e11OPo1pO9Vz4G4616E,130
241
244
  janito/tools/adapters/local/validate_file_syntax/xml_validator.py,sha256=AijlsP_PgNuC8ZbGsC5vOTt3Jur76otQzkd_7qR0QFY,284
242
245
  janito/tools/adapters/local/validate_file_syntax/yaml_validator.py,sha256=TgyI0HRL6ug_gBcWEm5TGJJuA4E34ZXcIzMpAbv3oJs,155
243
- janito-2.24.1.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
244
- janito-2.24.1.dist-info/METADATA,sha256=CbWK1X1j0gRaPEGtF-bOXclbaj_n77MTGnRUbSI82N4,16365
245
- janito-2.24.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
246
- janito-2.24.1.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
247
- janito-2.24.1.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
248
- janito-2.24.1.dist-info/RECORD,,
246
+ janito-2.26.0.dist-info/licenses/LICENSE,sha256=GSAKapQH5ZIGWlpQTA7v5YrfECyaxaohUb1vJX-qepw,1090
247
+ janito-coder/pyproject.toml,sha256=HPJgGe6YJ4CV93YxD8DYw_A18F51MW-iqweCXLVFko4,12990
248
+ janito-coder/janito_coder/__init__.py,sha256=QbCJXOHgiXXohtJeUc8frav8mee12ve-eUifpACndrY,198
249
+ janito-coder/janito_coder/plugins/__init__.py,sha256=NdjMhAEu8FEnVxEkYAN-Cz17Cx2qbMq8dMZMOQwBc-k,844
250
+ janito-coder/janito_coder/plugins/code_navigator.py,sha256=9f8mt713yXVjuM4RFXrR2Y1ibznOYOaLyeTqfnt2wvE,22101
251
+ janito-coder/janito_coder/plugins/git_analyzer.py,sha256=DEF_6J8z1-_Fshl1RAesz5b-aYC2nhf7COla44FdntE,8398
252
+ janito-2.26.0.dist-info/METADATA,sha256=Oonv_g1pinVq5NUzHGZgAtKgiEOKs1a96ByKNZ1Y9jw,16365
253
+ janito-2.26.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
254
+ janito-2.26.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
255
+ janito-2.26.0.dist-info/top_level.txt,sha256=rL2_EzEekHIjO_EteQ1nOywm0B9Ywb0ZeqSKtzZMGUc,20
256
+ janito-2.26.0.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ janito
2
+ janito-coder
@@ -0,0 +1,9 @@
1
+ """
2
+ Janito Coder - Extra plugins for software development and coding tasks.
3
+ """
4
+
5
+ __version__ = "0.1.0"
6
+ __author__ = "João Pinto"
7
+ __email__ = "janito@ikignosis.org"
8
+
9
+ from .plugins import *
@@ -0,0 +1,27 @@
1
+ """
2
+ Janito Coder plugins package.
3
+ """
4
+
5
+ from .git_analyzer import GitAnalyzerPlugin
6
+ from .code_navigator import CodeNavigatorPlugin
7
+ from .dependency_analyzer import DependencyAnalyzerPlugin
8
+ from .code_formatter import CodeFormatterPlugin
9
+ from .test_runner import TestRunnerPlugin
10
+ from .linter import LinterPlugin
11
+ from .debugger import DebuggerPlugin
12
+ from .performance_profiler import PerformanceProfilerPlugin
13
+ from .security_scanner import SecurityScannerPlugin
14
+ from .documentation_generator import DocumentationGeneratorPlugin
15
+
16
+ __all__ = [
17
+ "GitAnalyzerPlugin",
18
+ "CodeNavigatorPlugin",
19
+ "DependencyAnalyzerPlugin",
20
+ "CodeFormatterPlugin",
21
+ "TestRunnerPlugin",
22
+ "LinterPlugin",
23
+ "DebuggerPlugin",
24
+ "PerformanceProfilerPlugin",
25
+ "SecurityScannerPlugin",
26
+ "DocumentationGeneratorPlugin",
27
+ ]