janito 1.8.0__py3-none-any.whl → 1.9.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 (119) hide show
  1. janito/__init__.py +1 -1
  2. janito/agent/config_defaults.py +23 -0
  3. janito/agent/config_utils.py +0 -9
  4. janito/agent/conversation.py +31 -9
  5. janito/agent/conversation_api.py +32 -2
  6. janito/agent/conversation_history.py +53 -0
  7. janito/agent/conversation_tool_calls.py +11 -8
  8. janito/agent/openai_client.py +11 -3
  9. janito/agent/openai_schema_generator.py +9 -6
  10. janito/agent/providers.py +77 -0
  11. janito/agent/rich_message_handler.py +1 -1
  12. janito/agent/templates/profiles/system_prompt_template_base.txt.j2 +8 -8
  13. janito/agent/tool_executor.py +18 -10
  14. janito/agent/tool_use_tracker.py +16 -0
  15. janito/agent/tools/__init__.py +7 -9
  16. janito/agent/tools/create_directory.py +7 -6
  17. janito/agent/tools/create_file.py +29 -54
  18. janito/agent/tools/delete_text_in_file.py +97 -0
  19. janito/agent/tools/fetch_url.py +11 -3
  20. janito/agent/tools/find_files.py +37 -25
  21. janito/agent/tools/get_file_outline/__init__.py +1 -0
  22. janito/agent/tools/{outline_file/__init__.py → get_file_outline/core.py} +12 -15
  23. janito/agent/tools/get_file_outline/python_outline.py +134 -0
  24. janito/agent/tools/{search_outline.py → get_file_outline/search_outline.py} +9 -0
  25. janito/agent/tools/get_lines.py +15 -11
  26. janito/agent/tools/move_file.py +10 -11
  27. janito/agent/tools/remove_directory.py +2 -2
  28. janito/agent/tools/remove_file.py +11 -13
  29. janito/agent/tools/replace_file.py +62 -0
  30. janito/agent/tools/replace_text_in_file.py +3 -3
  31. janito/agent/tools/run_bash_command.py +3 -7
  32. janito/agent/tools/run_powershell_command.py +39 -28
  33. janito/agent/tools/run_python_command.py +3 -5
  34. janito/agent/tools/search_text.py +10 -14
  35. janito/agent/tools/validate_file_syntax/__init__.py +1 -0
  36. janito/agent/tools/validate_file_syntax/core.py +92 -0
  37. janito/agent/tools/validate_file_syntax/css_validator.py +35 -0
  38. janito/agent/tools/validate_file_syntax/html_validator.py +77 -0
  39. janito/agent/tools/validate_file_syntax/js_validator.py +27 -0
  40. janito/agent/tools/validate_file_syntax/json_validator.py +6 -0
  41. janito/agent/tools/validate_file_syntax/markdown_validator.py +66 -0
  42. janito/agent/tools/validate_file_syntax/ps1_validator.py +32 -0
  43. janito/agent/tools/validate_file_syntax/python_validator.py +5 -0
  44. janito/agent/tools/validate_file_syntax/xml_validator.py +11 -0
  45. janito/agent/tools/validate_file_syntax/yaml_validator.py +6 -0
  46. janito/agent/tools_utils/__init__.py +1 -0
  47. janito/agent/tools_utils/dir_walk_utils.py +23 -0
  48. janito/agent/{tools/outline_file → tools_utils}/formatting.py +5 -2
  49. janito/agent/{tools → tools_utils}/gitignore_utils.py +0 -3
  50. janito/agent/tools_utils/utils.py +30 -0
  51. janito/cli/_livereload_log_utils.py +13 -0
  52. janito/cli/arg_parser.py +45 -3
  53. janito/cli/{runner/cli_main.py → cli_main.py} +120 -20
  54. janito/cli/livereload_starter.py +60 -0
  55. janito/cli/main.py +110 -21
  56. janito/cli/one_shot.py +66 -0
  57. janito/cli/termweb_starter.py +2 -2
  58. janito/livereload/app.py +25 -0
  59. janito/rich_utils.py +0 -22
  60. janito/{cli_chat_shell → shell}/commands/__init__.py +18 -11
  61. janito/{cli_chat_shell → shell}/commands/config.py +4 -4
  62. janito/shell/commands/conversation_restart.py +72 -0
  63. janito/shell/commands/edit.py +21 -0
  64. janito/shell/commands/history_view.py +18 -0
  65. janito/shell/commands/livelogs.py +40 -0
  66. janito/{cli_chat_shell → shell}/commands/prompt.py +10 -6
  67. janito/shell/commands/session.py +32 -0
  68. janito/{cli_chat_shell → shell}/commands/session_control.py +2 -7
  69. janito/{cli_chat_shell → shell}/commands/sum.py +6 -6
  70. janito/{cli_chat_shell → shell}/commands/termweb_log.py +10 -10
  71. janito/shell/commands/tools.py +23 -0
  72. janito/{cli_chat_shell → shell}/commands/utility.py +5 -4
  73. janito/{cli_chat_shell → shell}/commands/verbose.py +1 -1
  74. janito/shell/commands.py +40 -0
  75. janito/shell/main.py +321 -0
  76. janito/{cli_chat_shell/shell_command_completer.py → shell/prompt/completer.py} +1 -1
  77. janito/{cli_chat_shell/chat_ui.py → shell/prompt/session_setup.py} +19 -5
  78. janito/{cli_chat_shell/session_manager.py → shell/session/manager.py} +53 -3
  79. janito/{cli_chat_shell/ui.py → shell/ui/interactive.py} +23 -15
  80. janito/termweb/app.py +3 -3
  81. janito/termweb/static/editor.css +146 -0
  82. janito/termweb/static/editor.css.bak +27 -0
  83. janito/termweb/static/editor.html +15 -213
  84. janito/termweb/static/editor.html.bak +16 -215
  85. janito/termweb/static/editor.js +209 -0
  86. janito/termweb/static/editor.js.bak +227 -0
  87. janito/termweb/static/index.html +2 -3
  88. janito/termweb/static/index.html.bak +2 -3
  89. janito/termweb/static/termweb.css.bak +33 -84
  90. janito/termweb/static/termweb.js +15 -34
  91. janito/termweb/static/termweb.js.bak +18 -36
  92. {janito-1.8.0.dist-info → janito-1.9.0.dist-info}/METADATA +6 -3
  93. janito-1.9.0.dist-info/RECORD +151 -0
  94. {janito-1.8.0.dist-info → janito-1.9.0.dist-info}/WHEEL +1 -1
  95. janito/agent/tools/dir_walk_utils.py +0 -16
  96. janito/agent/tools/memory.py +0 -48
  97. janito/agent/tools/outline_file/python_outline.py +0 -71
  98. janito/agent/tools/present_choices_test.py +0 -18
  99. janito/agent/tools/rich_live.py +0 -44
  100. janito/agent/tools/tools_utils.py +0 -56
  101. janito/agent/tools/utils.py +0 -33
  102. janito/agent/tools/validate_file_syntax.py +0 -163
  103. janito/cli_chat_shell/chat_loop.py +0 -163
  104. janito/cli_chat_shell/chat_state.py +0 -38
  105. janito/cli_chat_shell/commands/history_start.py +0 -37
  106. janito/cli_chat_shell/commands/session.py +0 -48
  107. janito-1.8.0.dist-info/RECORD +0 -127
  108. /janito/agent/tools/{outline_file → get_file_outline}/markdown_outline.py +0 -0
  109. /janito/cli/{runner/_termweb_log_utils.py → _termweb_log_utils.py} +0 -0
  110. /janito/cli/{runner/config.py → config_runner.py} +0 -0
  111. /janito/cli/{runner/formatting.py → formatting_runner.py} +0 -0
  112. /janito/{cli/runner → shell}/__init__.py +0 -0
  113. /janito/{cli_chat_shell → shell}/commands/lang.py +0 -0
  114. /janito/{cli_chat_shell → shell/prompt}/load_prompt.py +0 -0
  115. /janito/{cli_chat_shell/config_shell.py → shell/session/config.py} +0 -0
  116. /janito/{cli_chat_shell/__init__.py → shell/session/history.py} +0 -0
  117. {janito-1.8.0.dist-info → janito-1.9.0.dist-info}/entry_points.txt +0 -0
  118. {janito-1.8.0.dist-info → janito-1.9.0.dist-info}/licenses/LICENSE +0 -0
  119. {janito-1.8.0.dist-info → janito-1.9.0.dist-info}/top_level.txt +0 -0
@@ -24,11 +24,10 @@
24
24
  <img src="/static/termicon.svg" alt="TermWeb Logo" class="header-logo">
25
25
  <span class="header-title">TermWeb</span>
26
26
  <span class="header-subtitle">Explorador de Projetos com IA</span>
27
- <button class="theme-switcher" id="theme-switcher">Alternate para tema claro</button>
27
+ <button class="theme-switcher" id="theme-switcher" title="Alternate tema"><span id="theme-icon">🌙</span></button>
28
28
  </div>
29
29
  <div class="toolbar" id="explorer-toolbar">
30
- <button id="view-list" class="view-toggle active" title="Visualização em Lista">&#9776; List</button>
31
- <button id="view-icons" class="view-toggle" title="Visualização em Ícones">&#9632; Icons</button>
30
+
32
31
  </div>
33
32
  <div class="main">
34
33
  <div id="explorer-main"></div>
@@ -24,11 +24,10 @@
24
24
  <img src="/static/termicon.svg" alt="TermWeb Logo" class="header-logo">
25
25
  <span class="header-title">TermWeb</span>
26
26
  <span class="header-subtitle">Explorador de Projetos com IA</span>
27
- <button class="theme-switcher" id="theme-switcher">Alternar para tema claro</button>
27
+ <button class="theme-switcher" id="theme-switcher" title="Alternar tema"><span id="theme-icon">🌙</span></button>
28
28
  </div>
29
29
  <div class="toolbar" id="explorer-toolbar">
30
- <button id="view-list" class="view-toggle active" title="Visualização em Lista">&#9776; List</button>
31
- <button id="view-icons" class="view-toggle" title="Visualização em Ícones">&#9632; Icons</button>
30
+
32
31
  </div>
33
32
  <div class="main">
34
33
  <div id="explorer-main"></div>
@@ -81,30 +81,48 @@ body.light-theme .header {
81
81
  .main {
82
82
  flex: 1 1 auto;
83
83
  display: flex;
84
- flex-direction: column;
85
- justify-content: stretch;
86
- align-items: stretch;
87
- min-height: 0;
88
- padding: 0;
84
+ flex-direction: row;
85
+ gap: 2em;
86
+ padding: 2em;
87
+ min-height: 60vh;
89
88
  background: transparent;
90
89
  }
90
+ #explorer-main, #explorer-preview {
91
+ background: #22262b;
92
+ border-radius: 1.1em;
93
+ box-shadow: 0 4px 24px #0004;
94
+ border: 1px solid #1a73e8;
95
+ padding: 1.5em 1.2em;
96
+ min-height: 40vh;
97
+ overflow: auto;
98
+ }
99
+ #explorer-main {
100
+ margin-right: 0.5em;
101
+ }
102
+ #explorer-preview {
103
+ margin-left: 0.5em;
104
+ display: flex;
105
+ flex-direction: column;
106
+ flex: 1 1 0;
107
+ min-width: 0;
108
+ }
91
109
 
92
- .editor-pane {
110
+ /* --- CodeMirror Integration for Preview --- */
111
+ #explorer-codemirror-preview {
93
112
  flex: 1 1 auto;
113
+ min-height: 0;
114
+ min-width: 0;
94
115
  display: flex;
95
116
  flex-direction: column;
96
- height: 100%;
97
- min-height: 0;
98
117
  }
99
-
100
118
  .CodeMirror {
101
119
  flex: 1 1 auto;
102
- height: 100% !important;
120
+ height: 60vh !important;
103
121
  min-height: 0;
104
122
  font-size: 1.1em;
105
123
  background: #23272b;
106
124
  color: #f8f8f2;
107
- border-radius: 0;
125
+ border-radius: 0.5em;
108
126
  border: none;
109
127
  transition: background 0.2s, color 0.2s;
110
128
  }
@@ -198,81 +216,9 @@ body.light-theme .explorer-link, body.light-theme .explorer-link:visited {
198
216
  color: #42a5f5;
199
217
  }
200
218
  body.light-theme .explorer-link:hover {
201
- color: #0d47a1;
202
- }
203
-
204
- /* Error and status messages */
205
- .error {
206
- color: #ff5252;
207
- background: #2d2d2d;
208
- padding: 0.5em 1em;
209
- border-radius: 4px;
210
- margin: 1em 0;
211
- }
212
- body.light-theme .error {
213
- color: #b71c1c;
214
- background: #fff3f3;
215
- }
216
-
217
- /* Spinner for loading */
218
- .spinner {
219
- border: 4px solid #f3f3f3;
220
- border-top: 4px solid #1976d2;
221
- border-radius: 50%;
222
- width: 24px;
223
- height: 24px;
224
- animation: spin 1s linear infinite;
225
- display: inline-block;
226
- }
227
- @keyframes spin {
228
- 0% { transform: rotate(0deg); }
229
- 100% { transform: rotate(360deg); }
219
+ color: #1565c0;
230
220
  }
231
221
 
232
- /* --- Enhanced Toolbar & Panes --- */
233
- .toolbar {
234
- display: flex;
235
- justify-content: flex-end;
236
- align-items: center;
237
- gap: 0.7em;
238
- background: #23272b;
239
- border-bottom: 1px solid #1a73e8;
240
- padding: 0.7em 2em;
241
- margin-bottom: 0.5em;
242
- box-shadow: 0 2px 8px #0002;
243
- }
244
- .view-toggle {
245
- background: #23272b;
246
- color: #90caf9;
247
- border: 1px solid #1a73e8;
248
- border-radius: 0.5em;
249
- padding: 0.5em 1.2em;
250
- font-size: 1.1em;
251
- cursor: pointer;
252
- transition: background 0.15s, color 0.15s, box-shadow 0.15s;
253
- margin-left: 0.2em;
254
- }
255
- .view-toggle.active, .view-toggle:hover {
256
- background: #1a73e8;
257
- color: #fff;
258
- box-shadow: 0 2px 8px #1976d255;
259
- }
260
-
261
- #explorer-main, #explorer-preview {
262
- background: #22262b;
263
- border-radius: 1.1em;
264
- box-shadow: 0 4px 24px #0004;
265
- border: 1px solid #1a73e8;
266
- padding: 1.5em 1.2em;
267
- min-height: 40vh;
268
- overflow: auto;
269
- }
270
- #explorer-main {
271
- margin-right: 0.5em;
272
- }
273
- #explorer-preview {
274
- margin-left: 0.5em;
275
- }
276
222
  @media (max-width: 900px) {
277
223
  .main {
278
224
  flex-direction: column;
@@ -283,4 +229,7 @@ body.light-theme .error {
283
229
  min-height: 20vh;
284
230
  padding: 1em 0.7em;
285
231
  }
232
+ #explorer-preview {
233
+ margin-left: 0;
234
+ }
286
235
  }
@@ -16,8 +16,6 @@ function getPaiPath(path) {
16
16
  function setExplorerView(view) {
17
17
  explorerView = view;
18
18
  localStorage.setItem('explorerView', view);
19
- document.getElementById('view-list').classList.toggle('active', view === 'list');
20
- document.getElementById('view-icons').classList.toggle('active', view === 'icons');
21
19
  }
22
20
 
23
21
  function normalizeExplorerPath(path) {
@@ -63,22 +61,8 @@ function renderExplorer(path, pushUrl=true) {
63
61
  }
64
62
  }
65
63
  html += '</ul>';
66
- } else {
67
- html += `<div class='explorer-icons'>`;
68
- if (data.path !== '.') {
69
- const parent = getPaiPath(data.path);
70
- html += `<div class='explorer-icon'><a href='#' data-path='${parent}' class='explorer-link' title='Pai'>(..)</a></div>`;
71
- }
72
- for (const entry of data.entries) {
73
- const entryPath = data.path === '.' ? entry.name : data.path + '/' + entry.name;
74
- if (entry.is_dir) {
75
- html += `<div class='explorer-icon'><a href='#' data-path='${entryPath}' class='explorer-link' title='${entry.name}'>📁<br>${entry.name}</a></div>`;
76
- } else {
77
- html += `<div class='explorer-icon'><a href='#' data-path='${entryPath}' class='explorer-link file-link' title='${entry.name}'>📄<br>${entry.name}</a></div>`;
78
- }
79
- }
80
- html += '</div>';
81
64
  }
65
+
82
66
  main.innerHTML = html;
83
67
  // Clear preview panel when changing directories
84
68
  const preview = document.getElementById('explorer-preview');
@@ -131,7 +115,7 @@ window.renderCodePreview = function(container, content, mode) {
131
115
  var textarea = document.createElement('textarea');
132
116
  textarea.value = (typeof content === 'string') ? content : '';
133
117
  container.appendChild(textarea);
134
- if (window.CodeMirror && container.offsetPai !== null) {
118
+ if (window.CodeMirror) {
135
119
  var editor = CodeMirror.fromTextArea(textarea, {
136
120
  lineNumbers: true,
137
121
  mode: mode || 'python',
@@ -140,7 +124,7 @@ window.renderCodePreview = function(container, content, mode) {
140
124
  indentUnit: 4,
141
125
  tabSize: 4,
142
126
  });
143
- editor.setSize('100%', 'calc(60vh)');
127
+ editor.setSize('100%', '60vh');
144
128
  return editor;
145
129
  } else {
146
130
  container.innerHTML = '<pre>' + (content ? String(content) : '') + '</pre>';
@@ -148,7 +132,7 @@ window.renderCodePreview = function(container, content, mode) {
148
132
  } catch (e) {
149
133
  container.innerHTML = '<pre>' + (content ? String(content) : '') + '</pre>';
150
134
  }
151
- }
135
+ };
152
136
 
153
137
  // Theme switcher logic
154
138
  function setTheme(dark) {
@@ -156,31 +140,28 @@ function setTheme(dark) {
156
140
  document.body.classList.add('dark-theme');
157
141
  document.body.classList.remove('light-theme');
158
142
  localStorage.setItem('theme', 'dark');
159
- document.getElementById('theme-switcher').textContent = 'Switch to Light Theme';
143
+ var themeIcon = document.getElementById('theme-icon');
144
+ if (themeIcon) themeIcon.textContent = '🌙'; // Moon for dark theme
160
145
  } else {
161
146
  document.body.classList.remove('dark-theme');
162
147
  document.body.classList.add('light-theme');
163
148
  localStorage.setItem('theme', 'light');
164
- document.getElementById('theme-switcher').textContent = 'Switch to Dark Theme';
149
+ var themeIcon = document.getElementById('theme-icon');
150
+ if (themeIcon) themeIcon.textContent = '☀️'; // Sun for light theme
165
151
  }
166
152
  }
167
153
  document.addEventListener('DOMContentLoaded', function() {
168
154
  // Initial theme
169
155
  var theme = localStorage.getItem('theme') || 'dark';
170
156
  setTheme(theme === 'dark');
171
- document.getElementById('theme-switcher').onclick = function() {
172
- setTheme(document.body.classList.contains('light-theme'));
173
- };
157
+ var themeSwitcher = document.getElementById('theme-switcher');
158
+ if (themeSwitcher) {
159
+ themeSwitcher.onclick = function() {
160
+ setTheme(document.body.classList.contains('light-theme'));
161
+ };
162
+ }
163
+ setExplorerView('list'); // Always use list view
174
164
  renderExplorer('.')
175
- setExplorerView(localStorage.getItem('explorerView') || 'list');
176
- document.getElementById('view-list').onclick = function() {
177
- setExplorerView('list');
178
- renderExplorer('.')
179
- };
180
- document.getElementById('view-icons').onclick = function() {
181
- setExplorerView('icons');
182
- renderExplorer('.')
183
- };
184
165
  });
185
166
 
186
167
  window.renderExplorer = renderExplorer;
@@ -16,8 +16,7 @@ function getPaiPath(path) {
16
16
  function setExplorerView(view) {
17
17
  explorerView = view;
18
18
  localStorage.setItem('explorerView', view);
19
- document.getElementById('view-list').classList.toggle('active', view === 'list');
20
- document.getElementById('view-icons').classList.toggle('active', view === 'icons');
19
+
21
20
  }
22
21
 
23
22
  function normalizeExplorerPath(path) {
@@ -52,33 +51,19 @@ function renderExplorer(path, pushUrl=true) {
52
51
  html += `<ul class='explorer-list'>`;
53
52
  if (data.path !== '.') {
54
53
  const parent = getPaiPath(data.path);
55
- html += `<li><a href='#' data-path='${parent}' class='explorer-link'><span class='explorer-entry'><span class='explorer-icon'>\u2b06\ufe0f</span><span class='explorer-name'>(.. parent)</span></span></a></li>`;
54
+ html += `<li><a href='#' data-path='${parent}' class='explorer-link'><span class='explorer-entry'><span class='explorer-icon'>⬆️</span><span class='explorer-name'>(.. parent)</span></span></a></li>`;
56
55
  }
57
56
  for (const entry of data.entries) {
58
57
  const entryPath = data.path === '.' ? entry.name : data.path + '/' + entry.name;
59
58
  if (entry.is_dir) {
60
- html += `<li><a href='#' data-path='${entryPath}' class='explorer-link'><span class='explorer-entry'><span class='explorer-icon'>\ud83d\udcc1</span><span class='explorer-name'>${entry.name}</span></span></a></li>`;
59
+ html += `<li><a href='#' data-path='${entryPath}' class='explorer-link'><span class='explorer-entry'><span class='explorer-icon'>📁</span><span class='explorer-name'>${entry.name}</span></span></a></li>`;
61
60
  } else {
62
- html += `<li><a href='#' data-path='${entryPath}' class='explorer-link file-link'><span class='explorer-entry'><span class='explorer-icon'>\ud83d\udcc4</span><span class='explorer-name'>${entry.name}</span></span></a></li>`;
61
+ html += `<li><a href='#' data-path='${entryPath}' class='explorer-link file-link'><span class='explorer-entry'><span class='explorer-icon'>📄</span><span class='explorer-name'>${entry.name}</span></span></a></li>`;
63
62
  }
64
63
  }
65
64
  html += '</ul>';
66
- } else {
67
- html += `<div class='explorer-icons'>`;
68
- if (data.path !== '.') {
69
- const parent = getPaiPath(data.path);
70
- html += `<div class='explorer-icon'><a href='#' data-path='${parent}' class='explorer-link' title='Pai'>(..)</a></div>`;
71
- }
72
- for (const entry of data.entries) {
73
- const entryPath = data.path === '.' ? entry.name : data.path + '/' + entry.name;
74
- if (entry.is_dir) {
75
- html += `<div class='explorer-icon'><a href='#' data-path='${entryPath}' class='explorer-link' title='${entry.name}'>\ud83d\udcc1<br>${entry.name}</a></div>`;
76
- } else {
77
- html += `<div class='explorer-icon'><a href='#' data-path='${entryPath}' class='explorer-link file-link' title='${entry.name}'>\ud83d\udcc4<br>${entry.name}</a></div>`;
78
- }
79
- }
80
- html += '</div>';
81
65
  }
66
+
82
67
  main.innerHTML = html;
83
68
  // Clear preview panel when changing directories
84
69
  const preview = document.getElementById('explorer-preview');
@@ -131,7 +116,7 @@ window.renderCodePreview = function(container, content, mode) {
131
116
  var textarea = document.createElement('textarea');
132
117
  textarea.value = (typeof content === 'string') ? content : '';
133
118
  container.appendChild(textarea);
134
- if (window.CodeMirror && container.offsetPai !== null) {
119
+ if (window.CodeMirror) {
135
120
  var editor = CodeMirror.fromTextArea(textarea, {
136
121
  lineNumbers: true,
137
122
  mode: mode || 'python',
@@ -140,7 +125,7 @@ window.renderCodePreview = function(container, content, mode) {
140
125
  indentUnit: 4,
141
126
  tabSize: 4,
142
127
  });
143
- editor.setSize('100%', 'calc(60vh)');
128
+ editor.setSize('100%', '60vh');
144
129
  return editor;
145
130
  } else {
146
131
  container.innerHTML = '<pre>' + (content ? String(content) : '') + '</pre>';
@@ -156,31 +141,28 @@ function setTheme(dark) {
156
141
  document.body.classList.add('dark-theme');
157
142
  document.body.classList.remove('light-theme');
158
143
  localStorage.setItem('theme', 'dark');
159
- document.getElementById('theme-switcher').textContent = 'Switch to Light Theme';
144
+ var themeIcon = document.getElementById('theme-icon');
145
+ if (themeIcon) themeIcon.textContent = '🌙'; // Moon for dark theme
160
146
  } else {
161
147
  document.body.classList.remove('dark-theme');
162
148
  document.body.classList.add('light-theme');
163
149
  localStorage.setItem('theme', 'light');
164
- document.getElementById('theme-switcher').textContent = 'Switch to Dark Theme';
150
+ var themeIcon = document.getElementById('theme-icon');
151
+ if (themeIcon) themeIcon.textContent = '☀️'; // Sun for light theme
165
152
  }
166
153
  }
167
154
  document.addEventListener('DOMContentLoaded', function() {
168
155
  // Initial theme
169
156
  var theme = localStorage.getItem('theme') || 'dark';
170
157
  setTheme(theme === 'dark');
171
- document.getElementById('theme-switcher').onclick = function() {
172
- setTheme(document.body.classList.contains('light-theme'));
173
- };
158
+ var themeSwitcher = document.getElementById('theme-switcher');
159
+ if (themeSwitcher) {
160
+ themeSwitcher.onclick = function() {
161
+ setTheme(document.body.classList.contains('light-theme'));
162
+ };
163
+ }
164
+ setExplorerView('list'); // Always use list view
174
165
  renderExplorer('.')
175
- setExplorerView(localStorage.getItem('explorerView') || 'list');
176
- document.getElementById('view-list').onclick = function() {
177
- setExplorerView('list');
178
- renderExplorer('.')
179
- };
180
- document.getElementById('view-icons').onclick = function() {
181
- setExplorerView('icons');
182
- renderExplorer('.')
183
- };
184
166
  });
185
167
 
186
168
  window.renderExplorer = renderExplorer;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: janito
3
- Version: 1.8.0
3
+ Version: 1.9.0
4
4
  Summary: Natural Language Coding Agent,
5
5
  Author-email: João Pinto <joao.pinto@gmail.com>
6
6
  License-Expression: MIT
@@ -22,6 +22,7 @@ Requires-Dist: prompt_toolkit
22
22
  Requires-Dist: requests
23
23
  Requires-Dist: rich
24
24
  Requires-Dist: toml
25
+ Requires-Dist: lxml
25
26
  Provides-Extra: docs
26
27
  Requires-Dist: mkdocs>=1.5.3; extra == "docs"
27
28
  Requires-Dist: mkdocs-material>=9.4.8; extra == "docs"
@@ -29,14 +30,14 @@ Dynamic: license-file
29
30
 
30
31
  # 🚀 Janito: Natural Language Coding Agent
31
32
 
32
- **Current Version: 1.7.0**
33
+ **Current Version: 1.8.1**
33
34
  See [CHANGELOG.md](./CHANGELOG.md) for details on the latest release.
34
35
 
35
36
  Janito is an AI-powered assistant for the command line and web that interprets natural language system_prompt_template to edit code, manage files, and analyze projects using patterns and tools designed by experienced software engineers. It prioritizes transparency, interactive clarification, and precise, reviewable changes.
36
37
 
37
38
  For a technical overview, see the [Architecture Guide](docs/reference/architecture.md).
38
39
 
39
- ## 🧪 Experimental Feature: Liteweb File Viewer
40
+ ## 🧪 Experimental Feature: termweb File Viewer
40
41
 
41
42
  Janito now includes an experimental lightweight web file viewer for use with the CLI chat shell. This feature allows you to click on file paths in the terminal (when using a Rich-compatible terminal) and instantly preview file contents in your browser—no full IDE required!
42
43
 
@@ -46,6 +47,7 @@ Janito now includes an experimental lightweight web file viewer for use with the
46
47
  ```bash
47
48
  janito --termweb
48
49
  ```
50
+ - To disable the termweb file viewer, use the `--no-termweb` flag.
49
51
  - By default, the viewer runs at http://localhost:8088 (or the next available port up to 8100).
50
52
  - To specify a port, use `--termweb-port 8090`.
51
53
  - File paths in CLI output become clickable links that open the file in your browser.
@@ -94,6 +96,7 @@ You can alter Janito's behavior in any interface using these flags:
94
96
  - `--no-tools`: Disable all tool usage (Janito will only use the language model, no file/code/shell actions).
95
97
  - `--trust-tools`/`-T`: Trusted tools mode (suppresses all tool output, only shows output file locations).
96
98
  - `--vanilla`: Disables tools, system prompt, and temperature settings for a pure LLM chat experience.
99
+ - `--no-termweb`: Disables the termweb file viewer for terminal links.
97
100
 
98
101
  These modifiers can be combined with any interface mode for tailored workflows.
99
102
 
@@ -0,0 +1,151 @@
1
+ janito/__init__.py,sha256=l2eVHfMNFg4kPmiXtGSDPYsmLE4H8f13ozPPxATkS5s,23
2
+ janito/__main__.py,sha256=KKIoPBE9xPcb54PRYO2UOt0ti04iAwLeJlg8YY36vew,76
3
+ janito/rich_utils.py,sha256=T_DxBFwv4ZYP1qpZn-vzWRB2SzH46j0M6Upqf_bf6Pc,531
4
+ janito/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ janito/agent/config.py,sha256=SMpyt9k1LhLn8DimhHcaOFmyk_iexEPnOREM1tWcMow,4616
6
+ janito/agent/config_defaults.py,sha256=nzlOPZ2xllzcXLdFt5hSkjVKg6hT5NVkHiGEqj8WKvg,1324
7
+ janito/agent/config_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ janito/agent/content_handler.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ janito/agent/conversation.py,sha256=Re6RrA7wlr30hq4HvYlEMHU8H8PaXfZIyvtvg-CAeck,8105
10
+ janito/agent/conversation_api.py,sha256=fLs2LQg1NAajXM2Q_ikTojYlVwyhhQYvEg-s3ZpfWpI,9369
11
+ janito/agent/conversation_exceptions.py,sha256=Aw7PRLb3eUfyDOGynKds5F48dgjyiOrTCEcWSprYC58,381
12
+ janito/agent/conversation_history.py,sha256=hV2zzlYrbOsCaMEiu39grE1TK8MQ7Lsq5dtIb_3Y--4,1929
13
+ janito/agent/conversation_tool_calls.py,sha256=wz9FFtwNXgnyJQbcLzZfHfCPkiLfItE2vJ1JqjpKucA,1553
14
+ janito/agent/conversation_ui.py,sha256=y4f0IoJQoWGrFMB3yi7uIwXokuTjhFtJGK_R7zcTv3w,397
15
+ janito/agent/event.py,sha256=1jcua88NT-T4jA0mGIyIF1LvqXKu2GDT8NMjlelWmCI,517
16
+ janito/agent/event_dispatcher.py,sha256=eFNDfGY8o63yNLFdMe82LqfmDyGWjrAw9CpyUAcLJAM,856
17
+ janito/agent/event_handler_protocol.py,sha256=uIIf9u82BWm8pha4sZxydeEwgbxDoiWVSyplBPI0knE,130
18
+ janito/agent/event_system.py,sha256=QxPSQ2XeTyiWV6ejcmS8kTqTBrs7fLHRVXdhyeVHpas,608
19
+ janito/agent/message_handler.py,sha256=oZJ2u0C7OewHiHwlJslT2o3RPlvY2HhPXPoRcSsBv4M,856
20
+ janito/agent/message_handler_protocol.py,sha256=E8PLl9ucNvPK_xmhLEkV-vhQzfO_P_BMvzpqDvUkcVY,150
21
+ janito/agent/openai_client.py,sha256=5l45zgMK3lC5k7xS83hKC6jUEyZIjgsY7VwKWmxGaDY,4996
22
+ janito/agent/openai_schema_generator.py,sha256=cquQLJYBIKaiA6ErDo-JRRF2mYl0kAu3bZzL6xcFHLQ,5925
23
+ janito/agent/platform_discovery.py,sha256=yp6KTvc-_u22Dr8-J4cdjVMUS8HkCf343aeSGRu2wek,2712
24
+ janito/agent/profile_manager.py,sha256=B-bwo1ZhtD2DaVPAfn0bNv1_inoduZhKGd694Pfy5GM,3231
25
+ janito/agent/providers.py,sha256=fiLrYHR_rqUs6mlKXv_QMbOwzSrf3GqoabBVV4JXA9U,2199
26
+ janito/agent/queued_message_handler.py,sha256=sjsZneGWkqvfuJNac9QERdHasp9lWZvNcow8dul7tVU,1844
27
+ janito/agent/rich_live.py,sha256=NKWU89hRakiJ-0N6FPg40bYREOxQizqicbDv9eUfsKs,927
28
+ janito/agent/rich_message_handler.py,sha256=HOm6-xUq7UrrGkE7UlDGtUPXz4BS6LZJuFv2Io1qZFs,2408
29
+ janito/agent/runtime_config.py,sha256=xSx0-RD-WVA9niSCEmEn2ZPLFbQfRhPwwGIa8tid_v8,901
30
+ janito/agent/test_handler_protocols.py,sha256=4o1IitFDUN1fdw48oQCRizKWahahumdmEZ4URHrlmiY,1404
31
+ janito/agent/tool_base.py,sha256=rf88iEX_uZ7MwkeDl4gGMtHeESg0dlFKUo2Jr_ZqDTY,1900
32
+ janito/agent/tool_executor.py,sha256=FuWpE4itUxtOS6n0JflCJePrBtXjed06R7haxZVIxmE,4677
33
+ janito/agent/tool_registry.py,sha256=FlZ8YEoHdk2n7t8vZ26bVbu-fi4UeSE_yu2mZq8pusU,1594
34
+ janito/agent/tool_use_tracker.py,sha256=QdzDieMJvmBk60Yd5NTyob0QE-9lSVraDjROw5jz-E4,2096
35
+ janito/agent/templates/profiles/system_prompt_template_base.txt.j2,sha256=Z_Nu6tsJIJ01QF7RgUP6oYZOF0Gl5xRpMpPeaRtwr7k,913
36
+ janito/agent/templates/profiles/system_prompt_template_base_pt.txt.j2,sha256=FX8piXbR9XNOEKkOSMt4ieZ2wn5fzQlffeQFf8d7gIc,723
37
+ janito/agent/tests/__init__.py,sha256=QuXHKEzUJ_DooaKqenv_tKuNH-HabuIVZhvW5JNaeIc,52
38
+ janito/agent/tools/__init__.py,sha256=EC8IPYi3VML4kH78CujL3b-bKBJp0mG5BslL4HNqDnw,1098
39
+ janito/agent/tools/ask_user.py,sha256=DL-jBU-njSjwhNSbgi23RZCrRBt5beDgZq_PG4yzbWM,3217
40
+ janito/agent/tools/create_directory.py,sha256=KFI2v3H3Mq_O2wN7jrOaIXiiZg7baJPanLoCNoLVJWM,2504
41
+ janito/agent/tools/create_file.py,sha256=On8vIPbbbCOTw_xL1vJ_anQbIpPisouoKuUM-i6e53k,2225
42
+ janito/agent/tools/delete_text_in_file.py,sha256=WIUDPgaaPK2Dk1WzKTPdfyckcoA6p51cwAf0SMiJj8c,3494
43
+ janito/agent/tools/fetch_url.py,sha256=KQI9w71N5KI6ThBeSlLqNRdLL9WCxYDdIMTwYTa9wrI,2371
44
+ janito/agent/tools/find_files.py,sha256=N467bqpx3j0VDUxc3wQGlK786vRYj-sQ3tQ7yXgkqj0,4137
45
+ janito/agent/tools/get_lines.py,sha256=LhH8tQexESRIuAWWkBypq0yUkW6J2njcjWlYx4M1brI,5099
46
+ janito/agent/tools/move_file.py,sha256=1EYe55JT-osFTXDzeCYHtEV7-i0cjPcc7tASzcOJyjI,4336
47
+ janito/agent/tools/present_choices.py,sha256=e7SpOs3RIUXL6zi6PoeFc64akTVVuiQe2yLrm0rKpNs,2327
48
+ janito/agent/tools/remove_directory.py,sha256=xXVqkaseRcjXSO3FwciJaf6WKaV00fkgHb-VC1ECaW4,2409
49
+ janito/agent/tools/remove_file.py,sha256=rm74sNFbP9Ikc6R5G-y2x--Cdm_Xhs037jZKR-L9Q78,2294
50
+ janito/agent/tools/replace_file.py,sha256=fxnrNeHNudexYL_Ko_CzrERGGKDAoC9pTUCgUEE8QPg,2840
51
+ janito/agent/tools/replace_text_in_file.py,sha256=E-efxMYKZMgrf2Gb38qRdJnd4AvfoOBguVKVZtQd_CY,9451
52
+ janito/agent/tools/run_bash_command.py,sha256=4tpHwJmBekVBb75vSnT6R8vlpxp8LD_FHhzmq6TxbV0,7474
53
+ janito/agent/tools/run_powershell_command.py,sha256=geqse-o2fZrc8u5Rr6fFH-9HNKL3V389GStcmUe4dXU,8230
54
+ janito/agent/tools/run_python_command.py,sha256=ti7yfjvRC8ZjvOucXp7ixeKgT4pY8i10uDeAjl3_1DY,6991
55
+ janito/agent/tools/search_text.py,sha256=eqvlZkdXHt5TQrSn8IDnZfgnnQF2asF9diSU2AeLuVo,9298
56
+ janito/agent/tools/get_file_outline/__init__.py,sha256=OKV_BHnoD9h-vkcVoW6AHmsuDjjauHPCKNK0nVFl4sU,37
57
+ janito/agent/tools/get_file_outline/core.py,sha256=crpumYww-2JXYGjWNO13sWy3rzWWlJjcUDjpdxWs4Jw,3235
58
+ janito/agent/tools/get_file_outline/markdown_outline.py,sha256=bXEBg0D93tEBDNy8t-wh4i7WxsxfpQ2C3dX1_rmtj08,434
59
+ janito/agent/tools/get_file_outline/python_outline.py,sha256=P_GDB3ElMZtrLc5D3pQIueIA_7MxoOiyUbdcQXClyWo,4998
60
+ janito/agent/tools/get_file_outline/search_outline.py,sha256=l6yk1BJLpYRLbM2u4igvxMXeAmOXmyThT_Q-5Pj_B0o,987
61
+ janito/agent/tools/validate_file_syntax/__init__.py,sha256=P53RHmas4BbHL90cMxH9m-RpMCJI8JquoJb0rpkPVVk,29
62
+ janito/agent/tools/validate_file_syntax/core.py,sha256=tXcXWyQUQKOMwESOt3uSVC93FK4Qc3obJzwAQiyIS2M,3162
63
+ janito/agent/tools/validate_file_syntax/css_validator.py,sha256=tRnCzNkpiYKQ_X9yvPeDPqZvc59He2T-2CbXmCs8Hjw,1371
64
+ janito/agent/tools/validate_file_syntax/html_validator.py,sha256=X1sS0-ZJn1d0hlfN-sIPHjCLME_o1PIs_G_YsswNqiA,2739
65
+ janito/agent/tools/validate_file_syntax/js_validator.py,sha256=oVkGxK9wBbZ3cFqwrV_aF76FDQwKPDvbXxXn1tL4We0,1018
66
+ janito/agent/tools/validate_file_syntax/json_validator.py,sha256=jfft16AjPqo4opIlv36Yc1QhpwiYVlMOyfeAJuhRZ8U,170
67
+ janito/agent/tools/validate_file_syntax/markdown_validator.py,sha256=CJBG9ERfXy0Liy2FtbkdnkQS1yNq1hxzMlL8UJx4T6E,2863
68
+ janito/agent/tools/validate_file_syntax/ps1_validator.py,sha256=DQbsIIC3oaFkbeK7BMjZcIzy-zkPHX1JbhMMS3q_rmc,1172
69
+ janito/agent/tools/validate_file_syntax/python_validator.py,sha256=SN9eNgk9Uormr_kfyan9hCZClZ1LB5guObOzbZRyo6c,150
70
+ janito/agent/tools/validate_file_syntax/xml_validator.py,sha256=nDHMnrSdjAyQhbSIJZcDuqEkeiJmjvTALlKdtn_Ny0k,304
71
+ janito/agent/tools/validate_file_syntax/yaml_validator.py,sha256=zDg0F-7y9WDU5ur75tBEicIreQjZ8pXjc_FYyTUuXmo,175
72
+ janito/agent/tools_utils/__init__.py,sha256=tMniEJ8rcFeiztKqidRe-sCRJh02gMw_s1OjcQB1Rg4,28
73
+ janito/agent/tools_utils/dir_walk_utils.py,sha256=0r86VlWt_7TL0MtKpYR_G3KTESMl5seRT0fsY61CSVo,1081
74
+ janito/agent/tools_utils/formatting.py,sha256=p781lIQ1tqGMQgOlo5KyddPmurqoromrsNVdxKKJQDY,1132
75
+ janito/agent/tools_utils/gitignore_utils.py,sha256=vVcUqd5XGNp3BMMAxiGTzbaDPfjemHpbIVZrKMllo4Q,1340
76
+ janito/agent/tools_utils/utils.py,sha256=nVFOqaclfs18z4XB2rvr0JlwPa-RH1H-eSs8ejdXR5k,966
77
+ janito/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ janito/cli/_livereload_log_utils.py,sha256=BGhf1VT3dVR2ZhyTnZeTFg4I8Zj2tAn2UslME-ouxXA,482
79
+ janito/cli/_print_config.py,sha256=C_27QdwzhqorzeJflBFK0f46zTUtqqmdYe3EBurjOOE,3574
80
+ janito/cli/_termweb_log_utils.py,sha256=QpH40uxPhksrJHWqthW4cR7BhcSSYakpza_qTeFGABs,722
81
+ janito/cli/_utils.py,sha256=tRAUMDWKczd81ZvKYkwpsHWSeLzQoVlOoQ-lOw9Iujw,291
82
+ janito/cli/arg_parser.py,sha256=uQLDOr-m4azb1xQ9_HEXNPRR6qolx2l6jLrl30Gjcrw,8271
83
+ janito/cli/cli_main.py,sha256=SCCxKC9WIBb4qNqsSsfxW3KiyO8WiDLGIZgUFFCaDck,11265
84
+ janito/cli/config_commands.py,sha256=vfU7XciVMRNR5kDvn6tnCo1PLvSEXg0Y0PzLcDEFI9w,8539
85
+ janito/cli/config_runner.py,sha256=Nzam25C8P55dFlT_f6IlEj2ZvFwS63AAbnkIWe3oNsg,1702
86
+ janito/cli/formatting_runner.py,sha256=k0mtHoglqR8fKcebSK81iWTT_EL-gDl7eNfjlFZRY6g,287
87
+ janito/cli/livereload_starter.py,sha256=JivN7PRG9_dCEEOobXETQcJ7Ro9ELczg8AUbI8LHFPI,2285
88
+ janito/cli/logging_setup.py,sha256=_KLF69xqq1xLPIfkXxy0EIewO-Ef2eYoxNVjqjsC0vc,1361
89
+ janito/cli/main.py,sha256=wjmvbF2DdjMs8thZQQi80RSey62PObK2BNNOqtW2Ltc,8874
90
+ janito/cli/one_shot.py,sha256=Iqaj3DlcrqjUzwqqOKpKmsMIbLfNvqRvFIqHy4t7nIc,2696
91
+ janito/cli/termweb_starter.py,sha256=lN_MXGr_Glr82kS983caPyCXdKmhwzcEERmpCrfgcDA,2797
92
+ janito/i18n/__init__.py,sha256=7HYvwOTTf51pVm4adU79rl1FCtAjgOy6GzeShfYCdQY,970
93
+ janito/i18n/messages.py,sha256=fBuwOTFoygyHPkYphm6Y0r1iE8497Z4iryVAmPhMEkg,1851
94
+ janito/i18n/pt.py,sha256=52-ENCIrPW4A1tXFRT28xA8TwuUFoihs6ezJj-m3-Y4,4260
95
+ janito/livereload/app.py,sha256=oJTKDN5vpix26d1MA5iQz9mPLDu4VaHisAW8wtOUEhY,666
96
+ janito/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
+ janito/shell/commands.py,sha256=gqMKLvb6MrESPx51O28OP5I9hDZuBkRMaom3hT_ACqA,1586
98
+ janito/shell/main.py,sha256=hzsoflpMRVP6CXaw5YdKeh7JGeWR_OsJ88SoKgVz5R4,12551
99
+ janito/shell/commands/__init__.py,sha256=XGnXf6w_JZqpREJG3YN_UI9Zfc2uKK0Z_K9JMJ8gmfg,2002
100
+ janito/shell/commands/config.py,sha256=UTNbyNOLpIqlAle_JpCiffP7h5IOk7wxih-10_ok62w,959
101
+ janito/shell/commands/conversation_restart.py,sha256=IGCNO7Br9iHj1JH327B-R4Ps73g4qJOq2IvCZvJY-T0,2752
102
+ janito/shell/commands/edit.py,sha256=6o7T1FM18S2bGPadE61rvO3feWxGa5dfDFqtI4BwX9w,720
103
+ janito/shell/commands/history_view.py,sha256=m_-Olds5BI3gAdjZmx0i4kDBaMpLgmNBHVIIGDd6zq4,812
104
+ janito/shell/commands/lang.py,sha256=cG_gX61LUgzv_Bxk-UPTTNF1JQFfcUVaYBnPovUylNw,521
105
+ janito/shell/commands/livelogs.py,sha256=7lM7RRcsyisZz26Tk00_BYSkd9gvDuco_8z31xr49Ug,1753
106
+ janito/shell/commands/prompt.py,sha256=HW3z_JuJT6Zc5Yx8wJHDh4n2PZphu4ONTIMabVRTFnk,1949
107
+ janito/shell/commands/session.py,sha256=AHWC8eDrV5jta9Ak77FXu57qQvxEQC_8hVCICbkglRQ,1192
108
+ janito/shell/commands/session_control.py,sha256=nWxrc6OEX0ih872EwSEtodYhzBNPUC7rMr-ghmDw7ns,1249
109
+ janito/shell/commands/sum.py,sha256=WB89_NY34GrulqzKJchR5ovXmyJSYX7LP3sdaOgCT_E,1884
110
+ janito/shell/commands/termweb_log.py,sha256=jaVDefd2Sz-xBxGPcJqvsTRIpeynmVdi8vR2rP_nwCY,3321
111
+ janito/shell/commands/tools.py,sha256=_cnxXdu-xNkElcUnAv_lSrh3l9AKX5mH0E4HR1hZCU4,917
112
+ janito/shell/commands/utility.py,sha256=mfxv1J-VCzL4V2pAKMxQo1Rk8ZbyTFJ1PNh9hmqRVn0,1232
113
+ janito/shell/commands/verbose.py,sha256=vNtWCfpKxRY2t3Pzcz7FC1A9kZxMD26-zHSpE1JhuHc,1008
114
+ janito/shell/prompt/completer.py,sha256=6gNu0DNNSbUUVgjk8Y0hWwJwk-jbN8Lm6Y4u0mRu930,755
115
+ janito/shell/prompt/load_prompt.py,sha256=gHedc5TtaFBKiGgwRM_u9nVnBuLHDTSa8VPlPOtoMEA,2125
116
+ janito/shell/prompt/session_setup.py,sha256=ry4TqiXYyw3JmZfGRGIpvAgNMXGeWltCwz56NoiBqSY,1531
117
+ janito/shell/session/config.py,sha256=sG04S_z27wI7nXKMaVDcwDpBCuo6Cvd4uhutUQesJKo,3807
118
+ janito/shell/session/history.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
+ janito/shell/session/manager.py,sha256=E8TNBhiXHCbdNhhvzhUp4Zr_S3tdWagh1veDprwFTHY,3919
120
+ janito/shell/ui/interactive.py,sha256=XhR1vEZlLG8LijsZJqZCqvRoZVqruXHny3z-911XO6Q,7669
121
+ janito/termweb/app.py,sha256=co4a7cw6pC2P79dMZaNxjPJrP_B9suTGRIWTgqK5ccw,3322
122
+ janito/termweb/static/editor.css,sha256=rPSbQIVBCBnLlFJOQjHBOy2wWZkdbPDt4z8dWEBB83s,2870
123
+ janito/termweb/static/editor.css.bak,sha256=KPjMz7YwryaxOUmyHJNAlOv96KYtcMLj0zfYkUuc9Vs,924
124
+ janito/termweb/static/editor.html,sha256=XZpNejyIyzc1JVHnLGzc7dfUZO0ID_hX__rHpach9HU,2377
125
+ janito/termweb/static/editor.html.bak,sha256=X7t-EBYzv5RorkdM_kc0JerD6lXoNes4_ZIF8aFFfzs,2245
126
+ janito/termweb/static/editor.js,sha256=5FdYuQiWbmn3WUmHoUqkx_FAk6MVr8NXsglWeNl0re0,8331
127
+ janito/termweb/static/editor.js.bak,sha256=orBXq043dheUYwZP7HSnhkaIlR6cvGCBsoOroK-JaIg,8841
128
+ janito/termweb/static/explorer.html.bak,sha256=PM1fcbaQJm545WT94mVEekUNW3jduBAHOz6rwJBR1FA,2568
129
+ janito/termweb/static/favicon.ico,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
+ janito/termweb/static/favicon.ico.bak,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
+ janito/termweb/static/index.html,sha256=lwF9j4C0wL56rBEU3f0s3HzdSGOWxf64LbQhBUh5fxU,2934
132
+ janito/termweb/static/index.html.bak,sha256=PBEA-FxIhIYOGkyGKzefn7tsk8UxDIhSNtVkqPplQbs,2933
133
+ janito/termweb/static/index.html.bak.bak,sha256=dsKoC2lE0oJCGUUDTWcnIQE3s5Uoqd12WoTkWEwbH_c,6626
134
+ janito/termweb/static/landing.html.bak,sha256=JGwIcATj0B8MhHXLoXg2clypqsKJwi54NtW-rRDUsMs,1403
135
+ janito/termweb/static/termicon.svg,sha256=vc2Z3q-ADVK3pLzE3wnw_qpR6vDguWKEdH_pWObPjbw,229
136
+ janito/termweb/static/termweb.css,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
137
+ janito/termweb/static/termweb.css.bak,sha256=9AxhC2R8CzS82NHg9bk0GD-kxKt_NeRSRFGgTyi-3zI,4870
138
+ janito/termweb/static/termweb.js,sha256=hVzFd4gGMPEPvJEicQsXQpePp9mTjKVB_tS29xfWPhs,7720
139
+ janito/termweb/static/termweb.js.bak,sha256=G1UQJqtWMZOoPFMiSm4MRo-Pm1OqX1oMZ_Jcm4bsDq8,7721
140
+ janito/termweb/static/termweb.js.bak.bak,sha256=SQeqc9YwdreCmFJ7LtCYlHOjRHi8rsoW_fZ3x5WroWQ,7692
141
+ janito/termweb/static/termweb_quickopen.js,sha256=HNT85JjWAvjI5ROwukOU-oI4ZVVjCO6yg5IT115pdXI,5379
142
+ janito/termweb/static/termweb_quickopen.js.bak,sha256=sk_zbEw6HJt1iZSAYlaW0qAhq0to-KcBsOKx0AZqkKA,4814
143
+ janito/web/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
+ janito/web/__main__.py,sha256=5Ck6okOZmxKYkQ-ir4mxXDH7XWMNR-9szgsm0UyQLE0,734
145
+ janito/web/app.py,sha256=NarccXYgeYEMvws1lQSGZtArrzJIvw94LSNR0rW9Dq4,7331
146
+ janito-1.9.0.dist-info/licenses/LICENSE,sha256=sHBqv0bvtrb29H7WRR-Z603YHm9pLtJIo3nHU_9cmgE,1091
147
+ janito-1.9.0.dist-info/METADATA,sha256=Cxe4t_iI7poul_W8JwJX2ErMvdWZfQat18eD2Onphtw,12640
148
+ janito-1.9.0.dist-info/WHEEL,sha256=wXxTzcEDnjrTwFYjLPcsW_7_XihufBwmpiBeiXNBGEA,91
149
+ janito-1.9.0.dist-info/entry_points.txt,sha256=wIo5zZxbmu4fC-ZMrsKD0T0vq7IqkOOLYhrqRGypkx4,48
150
+ janito-1.9.0.dist-info/top_level.txt,sha256=m0NaVCq0-ivxbazE2-ND0EA9Hmuijj_OGkmCbnBcCig,7
151
+ janito-1.9.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.0.0)
2
+ Generator: setuptools (80.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,16 +0,0 @@
1
- import os
2
- from janito.agent.tools.gitignore_utils import filter_ignored
3
-
4
-
5
- def walk_dir_with_gitignore(root_dir, max_depth=0):
6
- """
7
- Walks the directory tree starting at root_dir, yielding (root, dirs, files) tuples,
8
- with .gitignore rules applied. If max_depth > 0, limits recursion to that depth.
9
- """
10
- for root, dirs, files in os.walk(root_dir):
11
- rel_path = os.path.relpath(root, root_dir)
12
- depth = 0 if rel_path == "." else rel_path.count(os.sep) + 1
13
- if max_depth > 0 and depth > max_depth:
14
- continue
15
- dirs, files = filter_ignored(root, dirs, files)
16
- yield root, dirs, files