janito 1.14.3__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- janito/__init__.py +6 -1
- janito/__main__.py +1 -1
- janito/agent/setup_agent.py +139 -0
- janito/agent/templates/profiles/{system_prompt_template_base.txt.j2 → system_prompt_template_main.txt.j2} +1 -1
- janito/cli/__init__.py +9 -0
- janito/cli/chat_mode/bindings.py +37 -0
- janito/cli/chat_mode/chat_entry.py +23 -0
- janito/cli/chat_mode/prompt_style.py +19 -0
- janito/cli/chat_mode/session.py +272 -0
- janito/{shell/prompt/completer.py → cli/chat_mode/shell/autocomplete.py} +7 -6
- janito/cli/chat_mode/shell/commands/__init__.py +55 -0
- janito/cli/chat_mode/shell/commands/base.py +9 -0
- janito/cli/chat_mode/shell/commands/clear.py +12 -0
- janito/{shell → cli/chat_mode/shell}/commands/conversation_restart.py +34 -30
- janito/cli/chat_mode/shell/commands/edit.py +25 -0
- janito/cli/chat_mode/shell/commands/help.py +16 -0
- janito/cli/chat_mode/shell/commands/history_view.py +93 -0
- janito/cli/chat_mode/shell/commands/lang.py +25 -0
- janito/cli/chat_mode/shell/commands/last.py +137 -0
- janito/cli/chat_mode/shell/commands/livelogs.py +49 -0
- janito/cli/chat_mode/shell/commands/multi.py +51 -0
- janito/cli/chat_mode/shell/commands/prompt.py +64 -0
- janito/cli/chat_mode/shell/commands/role.py +36 -0
- janito/cli/chat_mode/shell/commands/session.py +40 -0
- janito/{shell → cli/chat_mode/shell}/commands/session_control.py +2 -2
- janito/cli/chat_mode/shell/commands/termweb_log.py +92 -0
- janito/cli/chat_mode/shell/commands/tools.py +32 -0
- janito/{shell → cli/chat_mode/shell}/commands/utility.py +4 -7
- janito/{shell → cli/chat_mode/shell}/commands/verbose.py +5 -5
- janito/cli/chat_mode/shell/session/__init__.py +1 -0
- janito/{shell → cli/chat_mode/shell}/session/manager.py +9 -1
- janito/cli/chat_mode/toolbar.py +90 -0
- janito/cli/cli_commands/list_models.py +35 -0
- janito/cli/cli_commands/list_providers.py +9 -0
- janito/cli/cli_commands/list_tools.py +53 -0
- janito/cli/cli_commands/model_selection.py +50 -0
- janito/cli/cli_commands/model_utils.py +84 -0
- janito/cli/cli_commands/set_api_key.py +19 -0
- janito/cli/cli_commands/show_config.py +51 -0
- janito/cli/cli_commands/show_system_prompt.py +62 -0
- janito/cli/config.py +28 -0
- janito/cli/console.py +3 -0
- janito/cli/core/__init__.py +4 -0
- janito/cli/core/event_logger.py +59 -0
- janito/cli/core/getters.py +31 -0
- janito/cli/core/runner.py +141 -0
- janito/cli/core/setters.py +174 -0
- janito/cli/core/unsetters.py +54 -0
- janito/cli/main.py +8 -196
- janito/cli/main_cli.py +312 -0
- janito/cli/prompt_core.py +230 -0
- janito/cli/prompt_handler.py +6 -0
- janito/cli/rich_terminal_reporter.py +101 -0
- janito/cli/single_shot_mode/__init__.py +6 -0
- janito/cli/single_shot_mode/handler.py +137 -0
- janito/cli/termweb_starter.py +73 -24
- janito/cli/utils.py +25 -0
- janito/cli/verbose_output.py +196 -0
- janito/config.py +5 -0
- janito/config_manager.py +110 -0
- janito/conversation_history.py +30 -0
- janito/{agent/tools_utils/dir_walk_utils.py → dir_walk_utils.py} +3 -2
- janito/driver_events.py +98 -0
- janito/drivers/anthropic/driver.py +113 -0
- janito/drivers/azure_openai/driver.py +36 -0
- janito/drivers/driver_registry.py +33 -0
- janito/drivers/google_genai/driver.py +54 -0
- janito/drivers/google_genai/schema_generator.py +67 -0
- janito/drivers/mistralai/driver.py +41 -0
- janito/drivers/openai/driver.py +334 -0
- janito/event_bus/__init__.py +2 -0
- janito/event_bus/bus.py +68 -0
- janito/event_bus/event.py +15 -0
- janito/event_bus/handler.py +31 -0
- janito/event_bus/queue_bus.py +57 -0
- janito/exceptions.py +23 -0
- janito/formatting_token.py +54 -0
- janito/i18n/pt.py +1 -0
- janito/llm/__init__.py +5 -0
- janito/llm/agent.py +443 -0
- janito/llm/auth.py +62 -0
- janito/llm/driver.py +239 -0
- janito/llm/driver_config.py +34 -0
- janito/llm/driver_config_builder.py +34 -0
- janito/llm/driver_input.py +12 -0
- janito/llm/message_parts.py +60 -0
- janito/llm/model.py +38 -0
- janito/llm/provider.py +187 -0
- janito/perf_singleton.py +3 -0
- janito/performance_collector.py +167 -0
- janito/provider_config.py +98 -0
- janito/provider_registry.py +152 -0
- janito/providers/__init__.py +7 -0
- janito/providers/anthropic/model_info.py +22 -0
- janito/providers/anthropic/provider.py +65 -0
- janito/providers/azure_openai/model_info.py +15 -0
- janito/providers/azure_openai/provider.py +72 -0
- janito/providers/deepseek/__init__.py +1 -0
- janito/providers/deepseek/model_info.py +16 -0
- janito/providers/deepseek/provider.py +91 -0
- janito/providers/google/__init__.py +1 -0
- janito/providers/google/model_info.py +40 -0
- janito/providers/google/provider.py +69 -0
- janito/providers/mistralai/model_info.py +37 -0
- janito/providers/mistralai/provider.py +69 -0
- janito/providers/openai/__init__.py +1 -0
- janito/providers/openai/model_info.py +137 -0
- janito/providers/openai/provider.py +107 -0
- janito/providers/openai/schema_generator.py +63 -0
- janito/providers/provider_static_info.py +21 -0
- janito/providers/registry.py +26 -0
- janito/report_events.py +38 -0
- janito/termweb/app.py +1 -1
- janito/tools/__init__.py +16 -0
- janito/tools/adapters/__init__.py +1 -0
- janito/tools/adapters/local/__init__.py +54 -0
- janito/tools/adapters/local/adapter.py +92 -0
- janito/{agent/tools → tools/adapters/local}/ask_user.py +30 -13
- janito/tools/adapters/local/copy_file.py +84 -0
- janito/{agent/tools → tools/adapters/local}/create_directory.py +11 -10
- janito/tools/adapters/local/create_file.py +82 -0
- janito/tools/adapters/local/delete_text_in_file.py +136 -0
- janito/{agent/tools → tools/adapters/local}/fetch_url.py +18 -19
- janito/tools/adapters/local/find_files.py +140 -0
- janito/tools/adapters/local/get_file_outline/core.py +151 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/python_outline.py +125 -0
- janito/tools/adapters/local/get_file_outline/python_outline_v2.py +156 -0
- janito/{agent/tools → tools/adapters/local}/get_file_outline/search_outline.py +12 -7
- janito/{agent/tools → tools/adapters/local}/move_file.py +13 -9
- janito/tools/adapters/local/open_html_in_browser.py +34 -0
- janito/{agent/tools → tools/adapters/local}/open_url.py +7 -5
- janito/tools/adapters/local/python_code_run.py +165 -0
- janito/tools/adapters/local/python_command_run.py +163 -0
- janito/tools/adapters/local/python_file_run.py +162 -0
- janito/{agent/tools → tools/adapters/local}/remove_directory.py +15 -9
- janito/{agent/tools → tools/adapters/local}/remove_file.py +17 -14
- janito/{agent/tools → tools/adapters/local}/replace_text_in_file.py +27 -22
- janito/tools/adapters/local/run_bash_command.py +176 -0
- janito/tools/adapters/local/run_powershell_command.py +219 -0
- janito/{agent/tools → tools/adapters/local}/search_text/core.py +32 -12
- janito/{agent/tools → tools/adapters/local}/search_text/match_lines.py +13 -4
- janito/{agent/tools → tools/adapters/local}/search_text/pattern_utils.py +12 -4
- janito/{agent/tools → tools/adapters/local}/search_text/traverse_directory.py +15 -2
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/core.py +12 -11
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/css_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/html_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/js_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/json_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/markdown_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/ps1_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/python_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/xml_validator.py +1 -1
- janito/{agent/tools → tools/adapters/local}/validate_file_syntax/yaml_validator.py +1 -1
- janito/{agent/tools/get_lines.py → tools/adapters/local/view_file.py} +45 -27
- janito/tools/inspect_registry.py +17 -0
- janito/tools/tool_base.py +105 -0
- janito/tools/tool_events.py +58 -0
- janito/tools/tool_run_exception.py +12 -0
- janito/{agent → tools}/tool_use_tracker.py +2 -4
- janito/{agent/tools_utils/utils.py → tools/tool_utils.py} +18 -9
- janito/tools/tools_adapter.py +207 -0
- janito/tools/tools_schema.py +104 -0
- janito/utils.py +11 -0
- janito/version.py +4 -0
- janito-2.0.1.dist-info/METADATA +232 -0
- janito-2.0.1.dist-info/RECORD +181 -0
- janito/agent/__init__.py +0 -0
- janito/agent/api_exceptions.py +0 -4
- janito/agent/config.py +0 -147
- janito/agent/config_defaults.py +0 -12
- janito/agent/config_utils.py +0 -0
- janito/agent/content_handler.py +0 -0
- janito/agent/conversation.py +0 -238
- janito/agent/conversation_api.py +0 -306
- janito/agent/conversation_exceptions.py +0 -18
- janito/agent/conversation_tool_calls.py +0 -39
- janito/agent/conversation_ui.py +0 -17
- janito/agent/event.py +0 -24
- janito/agent/event_dispatcher.py +0 -24
- janito/agent/event_handler_protocol.py +0 -5
- janito/agent/event_system.py +0 -15
- janito/agent/llm_conversation_history.py +0 -82
- janito/agent/message_handler.py +0 -20
- janito/agent/message_handler_protocol.py +0 -5
- janito/agent/openai_client.py +0 -149
- janito/agent/openai_schema_generator.py +0 -187
- janito/agent/profile_manager.py +0 -96
- janito/agent/queued_message_handler.py +0 -50
- janito/agent/rich_live.py +0 -32
- janito/agent/rich_message_handler.py +0 -115
- janito/agent/runtime_config.py +0 -36
- janito/agent/test_handler_protocols.py +0 -47
- janito/agent/test_openai_schema_generator.py +0 -93
- janito/agent/tests/__init__.py +0 -1
- janito/agent/tool_base.py +0 -63
- janito/agent/tool_executor.py +0 -122
- janito/agent/tool_registry.py +0 -49
- janito/agent/tools/__init__.py +0 -47
- janito/agent/tools/create_file.py +0 -59
- janito/agent/tools/delete_text_in_file.py +0 -97
- janito/agent/tools/find_files.py +0 -106
- janito/agent/tools/get_file_outline/core.py +0 -81
- janito/agent/tools/present_choices.py +0 -64
- janito/agent/tools/python_command_runner.py +0 -201
- janito/agent/tools/python_file_runner.py +0 -199
- janito/agent/tools/python_stdin_runner.py +0 -208
- janito/agent/tools/replace_file.py +0 -72
- janito/agent/tools/run_bash_command.py +0 -218
- janito/agent/tools/run_powershell_command.py +0 -251
- janito/agent/tools_utils/__init__.py +0 -1
- janito/agent/tools_utils/action_type.py +0 -7
- janito/agent/tools_utils/test_gitignore_utils.py +0 -46
- janito/cli/_livereload_log_utils.py +0 -13
- janito/cli/_print_config.py +0 -96
- janito/cli/_termweb_log_utils.py +0 -17
- janito/cli/_utils.py +0 -9
- janito/cli/arg_parser.py +0 -272
- janito/cli/cli_main.py +0 -281
- janito/cli/config_commands.py +0 -211
- janito/cli/config_runner.py +0 -35
- janito/cli/formatting_runner.py +0 -12
- janito/cli/livereload_starter.py +0 -60
- janito/cli/logging_setup.py +0 -38
- janito/cli/one_shot.py +0 -80
- janito/livereload/app.py +0 -25
- janito/rich_utils.py +0 -59
- janito/shell/__init__.py +0 -0
- janito/shell/commands/__init__.py +0 -61
- janito/shell/commands/config.py +0 -22
- janito/shell/commands/edit.py +0 -24
- janito/shell/commands/history_view.py +0 -18
- janito/shell/commands/lang.py +0 -19
- janito/shell/commands/livelogs.py +0 -42
- janito/shell/commands/prompt.py +0 -62
- janito/shell/commands/termweb_log.py +0 -94
- janito/shell/commands/tools.py +0 -26
- janito/shell/commands/track.py +0 -36
- janito/shell/main.py +0 -326
- janito/shell/prompt/load_prompt.py +0 -57
- janito/shell/prompt/session_setup.py +0 -57
- janito/shell/session/config.py +0 -109
- janito/shell/session/history.py +0 -0
- janito/shell/ui/interactive.py +0 -226
- janito/termweb/static/editor.css +0 -158
- janito/termweb/static/editor.css.bak +0 -145
- janito/termweb/static/editor.html +0 -46
- janito/termweb/static/editor.html.bak +0 -46
- janito/termweb/static/editor.js +0 -265
- janito/termweb/static/editor.js.bak +0 -259
- janito/termweb/static/explorer.html.bak +0 -59
- janito/termweb/static/favicon.ico +0 -0
- janito/termweb/static/favicon.ico.bak +0 -0
- janito/termweb/static/index.html +0 -53
- janito/termweb/static/index.html.bak +0 -54
- janito/termweb/static/index.html.bak.bak +0 -175
- janito/termweb/static/landing.html.bak +0 -36
- janito/termweb/static/termicon.svg +0 -1
- janito/termweb/static/termweb.css +0 -214
- janito/termweb/static/termweb.css.bak +0 -237
- janito/termweb/static/termweb.js +0 -162
- janito/termweb/static/termweb.js.bak +0 -168
- janito/termweb/static/termweb.js.bak.bak +0 -157
- janito/termweb/static/termweb_quickopen.js +0 -135
- janito/termweb/static/termweb_quickopen.js.bak +0 -125
- janito/tests/test_rich_utils.py +0 -44
- janito/web/__init__.py +0 -0
- janito/web/__main__.py +0 -25
- janito/web/app.py +0 -145
- janito-1.14.3.dist-info/METADATA +0 -313
- janito-1.14.3.dist-info/RECORD +0 -162
- janito-1.14.3.dist-info/licenses/LICENSE +0 -21
- /janito/{shell → cli/chat_mode/shell}/input_history.py +0 -0
- /janito/{shell/commands/session.py → cli/chat_mode/shell/session/history.py} +0 -0
- /janito/{agent/tools_utils/formatting.py → formatting.py} +0 -0
- /janito/{agent/tools_utils/gitignore_utils.py → gitignore_utils.py} +0 -0
- /janito/{agent/platform_discovery.py → platform_discovery.py} +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/get_file_outline/markdown_outline.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/search_text/__init__.py +0 -0
- /janito/{agent/tools → tools/adapters/local}/validate_file_syntax/__init__.py +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/WHEEL +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/entry_points.txt +0 -0
- {janito-1.14.3.dist-info → janito-2.0.1.dist-info}/top_level.txt +0 -0
@@ -1,46 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<link rel="icon" type="image/svg+xml" href="/static/termicon.svg">
|
5
|
-
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico">
|
6
|
-
<meta charset="UTF-8">
|
7
|
-
<title>Janito Light Editor</title>
|
8
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css">
|
9
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/theme/dracula.min.css">
|
10
|
-
<link rel="stylesheet" href="/static/termweb.css">
|
11
|
-
<link rel="stylesheet" href="/static/editor.css">
|
12
|
-
</head>
|
13
|
-
<body>
|
14
|
-
<div class="header">
|
15
|
-
<div class="header-title">Janito Light Editor</div>
|
16
|
-
<span id="filename-display" class="filename-display"></span>
|
17
|
-
<div style="flex:1 1 auto;"></div>
|
18
|
-
<button class="theme-switcher" id="theme-switcher" title="Alternator tema">
|
19
|
-
<span id="theme-icon" aria-label="Switch theme" style="pointer-events:none;">🌙</span>
|
20
|
-
</button>
|
21
|
-
</div>
|
22
|
-
<div class="main">
|
23
|
-
<div class="editor-pane">
|
24
|
-
<textarea id="code" name="code"></textarea>
|
25
|
-
<div id="save-popup" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;background:#2196f3;color:#fff;padding:14px 28px;border-radius:8px;box-shadow:0 4px 16px #1976d288;border:2px solid #1976d2;font-size:1.1em;">Saved!</div>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
<div class="footer">
|
29
|
-
<button class="save-btn" id="save-btn">Save</button>
|
30
|
-
|
31
|
-
</div>
|
32
|
-
<div id="save-popup" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;background:#2196f3;color:#fff;padding:14px 28px;border-radius:8px;box-shadow:0 4px 16px #1976d288;border:2px solid #1976d2;font-size:1.1em;">Saved!</div>
|
33
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.js"></script>
|
34
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/python/python.min.js"></script>
|
35
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/django/django.min.js"></script>
|
36
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/theme/dracula.min.js"></script>
|
37
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/selection/active-line.min.js"></script>
|
38
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/search/search.min.js"></script>
|
39
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/search/searchcursor.min.js"></script>
|
40
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/dialog/dialog.min.js"></script>
|
41
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/mode/overlay.min.js"></script>
|
42
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/dialog/dialog.min.css">
|
43
|
-
|
44
|
-
<script src="/static/editor.js"></script>
|
45
|
-
</body>
|
46
|
-
</html>
|
@@ -1,46 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<link rel="icon" type="image/svg+xml" href="/static/termicon.svg">
|
5
|
-
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico">
|
6
|
-
<meta charset="UTF-8">
|
7
|
-
<title>Janito Light Editor</title>
|
8
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.css">
|
9
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/theme/dracula.min.css">
|
10
|
-
<link rel="stylesheet" href="/static/termweb.css">
|
11
|
-
<link rel="stylesheet" href="/static/editor.css">
|
12
|
-
</head>
|
13
|
-
<body>
|
14
|
-
<div class="header">
|
15
|
-
<div class="header-title">Janito Light Editor</div>
|
16
|
-
<span id="filename-display" class="filename-display"></span>
|
17
|
-
<div style="flex:1 1 auto;"></div>
|
18
|
-
<button class="theme-switcher" id="theme-switcher" title="Alternator tema">
|
19
|
-
<span id="theme-icon" aria-label="Switch theme" style="pointer-events:none;">🌙</span>
|
20
|
-
</button>
|
21
|
-
</div>
|
22
|
-
<div class="main">
|
23
|
-
<div class="editor-pane">
|
24
|
-
<textarea id="code" name="code"></textarea>
|
25
|
-
<div id="save-popup" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;background:#323b4c;color:#fff;padding:14px 28px;border-radius:8px;box-shadow:0 2px 12px #0007;font-size:1.1em;">Saved!</div>
|
26
|
-
</div>
|
27
|
-
</div>
|
28
|
-
<div class="footer">
|
29
|
-
<button class="save-btn" id="save-btn">Save</button>
|
30
|
-
|
31
|
-
</div>
|
32
|
-
<div id="save-popup" style="display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);z-index:9999;background:#323b4c;color:#fff;padding:14px 28px;border-radius:8px;box-shadow:0 2px 12px #0007;font-size:1.1em;">Saved!</div>
|
33
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/codemirror.min.js"></script>
|
34
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/python/python.min.js"></script>
|
35
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/mode/django/django.min.js"></script>
|
36
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/theme/dracula.min.js"></script>
|
37
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/selection/active-line.min.js"></script>
|
38
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/search/search.min.js"></script>
|
39
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/search/searchcursor.min.js"></script>
|
40
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/dialog/dialog.min.js"></script>
|
41
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/mode/overlay.min.js"></script>
|
42
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.13/addon/dialog/dialog.min.css">
|
43
|
-
|
44
|
-
<script src="/static/editor.js"></script>
|
45
|
-
</body>
|
46
|
-
</html>
|
janito/termweb/static/editor.js
DELETED
@@ -1,265 +0,0 @@
|
|
1
|
-
// --- Load file content via AJAX if ?path=... is present ---
|
2
|
-
function getQueryParam(name) {
|
3
|
-
const url = new URL(window.location.href);
|
4
|
-
return url.searchParams.get(name);
|
5
|
-
}
|
6
|
-
const filePath = getQueryParam('path');
|
7
|
-
|
8
|
-
// Updates the theme icon based on the current theme
|
9
|
-
function updateThemeIcon() {
|
10
|
-
var icon = document.getElementById('theme-icon');
|
11
|
-
if (!icon) return;
|
12
|
-
if (document.body.classList.contains('light-theme')) {
|
13
|
-
icon.textContent = '☀️'; // Sun for light mode
|
14
|
-
icon.title = 'Switch to dark mode';
|
15
|
-
} else {
|
16
|
-
icon.textContent = '🌙'; // Moon for dark mode
|
17
|
-
icon.title = 'Switch to light mode';
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
document.addEventListener('DOMContentLoaded', function() {
|
22
|
-
// Display filename in header if present
|
23
|
-
if (filePath) {
|
24
|
-
const filename = filePath.split(/[\\\/]/).pop();
|
25
|
-
const filenameDisplay = document.getElementById('filename-display');
|
26
|
-
if (filenameDisplay) {
|
27
|
-
filenameDisplay.textContent = '— ' + filePath;
|
28
|
-
filenameDisplay.title = filePath;
|
29
|
-
}
|
30
|
-
}
|
31
|
-
|
32
|
-
let initialContent = "";
|
33
|
-
if (filePath) {
|
34
|
-
fetch(`/api/explorer/${encodeURIComponent(filePath)}`)
|
35
|
-
.then(resp => resp.json())
|
36
|
-
.then(data => {
|
37
|
-
if (data.type === 'file') {
|
38
|
-
initialContent = data.content;
|
39
|
-
if (window.editorInstance) {
|
40
|
-
window.editorInstance.setValue(initialContent);
|
41
|
-
}
|
42
|
-
} else if (data.error) {
|
43
|
-
initialContent = '# Error: ' + data.error;
|
44
|
-
if (window.editorInstance) {
|
45
|
-
window.editorInstance.setValue(initialContent);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
})
|
49
|
-
.catch(err => {
|
50
|
-
initialContent = '# Error ao carregar arquivo: ' + err;
|
51
|
-
if (window.editorInstance) {
|
52
|
-
window.editorInstance.setValue(initialContent);
|
53
|
-
}
|
54
|
-
});
|
55
|
-
}
|
56
|
-
|
57
|
-
// --- Detect file extension and set CodeMirror mode ---
|
58
|
-
function detectMode(filename) {
|
59
|
-
if (!filename) return 'python';
|
60
|
-
const ext = filename.split('.').pop().toLowerCase();
|
61
|
-
const map = {
|
62
|
-
'py': 'python',
|
63
|
-
'js': 'javascript',
|
64
|
-
'json': 'javascript',
|
65
|
-
'md': 'markdown',
|
66
|
-
'html': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
67
|
-
'htm': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
68
|
-
'jinja': 'django',
|
69
|
-
'j2': 'django',
|
70
|
-
'jinja2': 'django',
|
71
|
-
'css': 'css',
|
72
|
-
'sh': 'shell',
|
73
|
-
'bash': 'shell',
|
74
|
-
'yml': 'yaml',
|
75
|
-
'yaml': 'yaml',
|
76
|
-
};
|
77
|
-
return map[ext] || 'python';
|
78
|
-
}
|
79
|
-
var initialMode = detectMode(filePath);
|
80
|
-
var editorInstance = CodeMirror.fromTextArea(document.getElementById('code'), {
|
81
|
-
lineNumbers: true,
|
82
|
-
mode: initialMode,
|
83
|
-
theme: 'dracula',
|
84
|
-
indentUnit: 4,
|
85
|
-
tabSize: 4,
|
86
|
-
styleActiveLine: true,
|
87
|
-
});
|
88
|
-
// If file loaded later, update mode
|
89
|
-
if (filePath) {
|
90
|
-
const mode = detectMode(filePath);
|
91
|
-
editorInstance.setOption('mode', mode);
|
92
|
-
}
|
93
|
-
window.editorInstance = editorInstance;
|
94
|
-
|
95
|
-
|
96
|
-
// Add Ctrl-F handler for find
|
97
|
-
editorInstance.addKeyMap({
|
98
|
-
'Ctrl-F': function(cm) {
|
99
|
-
cm.execCommand('find');
|
100
|
-
},
|
101
|
-
'Cmd-F': function(cm) {
|
102
|
-
cm.execCommand('find');
|
103
|
-
},
|
104
|
-
'Ctrl-S': function(cm) {
|
105
|
-
document.getElementById('save-btn').click();
|
106
|
-
// Prevent default browser save dialog
|
107
|
-
return false;
|
108
|
-
},
|
109
|
-
'Cmd-S': function(cm) {
|
110
|
-
document.getElementById('save-btn').click();
|
111
|
-
return false;
|
112
|
-
},
|
113
|
-
'Alt-W': function(cm) {
|
114
|
-
const current = cm.getOption('lineWrapping');
|
115
|
-
cm.setOption('lineWrapping', !current);
|
116
|
-
}
|
117
|
-
});
|
118
|
-
// --- Custom floating find navigation panel ---
|
119
|
-
function createFindPanel() {
|
120
|
-
let panel = document.getElementById('find-nav-panel');
|
121
|
-
if (!panel) {
|
122
|
-
panel = document.createElement('div');
|
123
|
-
panel.id = 'find-nav-panel';
|
124
|
-
panel.style.position = 'absolute';
|
125
|
-
panel.style.top = '70px';
|
126
|
-
panel.style.right = '30px';
|
127
|
-
panel.style.zIndex = 200;
|
128
|
-
panel.style.background = 'rgba(40,42,54,0.98)';
|
129
|
-
panel.style.color = '#fff';
|
130
|
-
panel.style.borderRadius = '6px';
|
131
|
-
panel.style.boxShadow = '0 2px 8px #0008';
|
132
|
-
panel.style.padding = '4px 10px 4px 8px';
|
133
|
-
panel.style.display = 'flex';
|
134
|
-
panel.style.alignItems = 'center';
|
135
|
-
panel.style.gap = '8px';
|
136
|
-
panel.style.fontSize = '1em';
|
137
|
-
panel.style.userSelect = 'none';
|
138
|
-
panel.innerHTML = `
|
139
|
-
<button id="find-prev-btn" title="Previous match" style="background:none;border:none;color:#fff;font-size:1.2em;cursor:pointer;">⏮️</button>
|
140
|
-
<span id="find-match-info">1/1</span>
|
141
|
-
<button id="find-next-btn" title="Next match" style="background:none;border:none;color:#fff;font-size:1.2em;cursor:pointer;">⏭️</button>
|
142
|
-
`;
|
143
|
-
document.body.appendChild(panel);
|
144
|
-
}
|
145
|
-
return panel;
|
146
|
-
}
|
147
|
-
function removeFindPanel() {
|
148
|
-
let panel = document.getElementById('find-nav-panel');
|
149
|
-
if (panel) panel.remove();
|
150
|
-
}
|
151
|
-
// Hook into CodeMirror search dialog
|
152
|
-
let lastSearchState = null;
|
153
|
-
function updateFindPanel(cm) {
|
154
|
-
let state = cm.state.search;
|
155
|
-
if (!state || !state.query) {
|
156
|
-
removeFindPanel();
|
157
|
-
return;
|
158
|
-
}
|
159
|
-
let matches = 0, current = 0;
|
160
|
-
if (state.overlay && state.overlay.matches) {
|
161
|
-
matches = state.overlay.matches.length;
|
162
|
-
current = state.overlay.matches.findIndex(m => m.from && cm.getCursor().line === m.from.line && cm.getCursor().ch >= m.from.ch && cm.getCursor().ch <= m.to.ch) + 1;
|
163
|
-
}
|
164
|
-
// fallback: count marked text
|
165
|
-
if (!matches) {
|
166
|
-
let marks = cm.getAllMarks();
|
167
|
-
let found = marks.filter(m => m.className && m.className.includes('cm-searching'));
|
168
|
-
matches = found.length;
|
169
|
-
let cur = cm.getCursor();
|
170
|
-
current = found.findIndex(m => {
|
171
|
-
let pos = m.find();
|
172
|
-
return pos && pos.from.line === cur.line && cur.ch >= pos.from.ch && cur.ch <= pos.to.ch;
|
173
|
-
}) + 1;
|
174
|
-
}
|
175
|
-
if (!matches) matches = 1;
|
176
|
-
if (!current) current = 1;
|
177
|
-
createFindPanel();
|
178
|
-
document.getElementById('find-match-info').textContent = `${current}/${matches}`;
|
179
|
-
}
|
180
|
-
editorInstance.on('cursorActivity', function(cm) {
|
181
|
-
updateFindPanel(cm);
|
182
|
-
});
|
183
|
-
editorInstance.on('search', function(cm) {
|
184
|
-
updateFindPanel(cm);
|
185
|
-
});
|
186
|
-
// Listen for dialog open/close
|
187
|
-
let observer = new MutationObserver(function() {
|
188
|
-
let dialogs = document.querySelectorAll('.CodeMirror-dialog');
|
189
|
-
if (dialogs.length) {
|
190
|
-
setTimeout(() => updateFindPanel(editorInstance), 100);
|
191
|
-
} else {
|
192
|
-
removeFindPanel();
|
193
|
-
}
|
194
|
-
});
|
195
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
196
|
-
// Button handlers
|
197
|
-
document.body.addEventListener('click', function(e) {
|
198
|
-
if (e.target && e.target.id === 'find-next-btn') {
|
199
|
-
editorInstance.execCommand('findNext');
|
200
|
-
} else if (e.target && e.target.id === 'find-prev-btn') {
|
201
|
-
editorInstance.execCommand('findPrev');
|
202
|
-
}
|
203
|
-
});
|
204
|
-
// --- END custom find panel ---
|
205
|
-
// Dynamically calculate available height
|
206
|
-
function resizeEditor() {
|
207
|
-
var header = document.querySelector('.header');
|
208
|
-
var headerHeight = header ? header.offsetHeight : 0;
|
209
|
-
var availableHeight = window.innerHeight - headerHeight;
|
210
|
-
editorInstance.setSize('100%', availableHeight + 'px');
|
211
|
-
}
|
212
|
-
window.addEventListener('resize', resizeEditor);
|
213
|
-
setTimeout(resizeEditor, 0);
|
214
|
-
editorInstance.setValue(initialContent);
|
215
|
-
updateThemeIcon();
|
216
|
-
|
217
|
-
// Set initial state
|
218
|
-
document.body.classList.remove('light-theme');
|
219
|
-
editorInstance.setOption('theme', 'dracula');
|
220
|
-
updateThemeIcon();
|
221
|
-
|
222
|
-
// Theme switch button logic
|
223
|
-
var themeSwitcher = document.getElementById('theme-switcher');
|
224
|
-
if (themeSwitcher) {
|
225
|
-
themeSwitcher.addEventListener('click', function() {
|
226
|
-
var isLight = document.body.classList.toggle('light-theme');
|
227
|
-
if (isLight) {
|
228
|
-
editorInstance.setOption('theme', 'default');
|
229
|
-
} else {
|
230
|
-
editorInstance.setOption('theme', 'dracula');
|
231
|
-
}
|
232
|
-
updateThemeIcon();
|
233
|
-
});
|
234
|
-
}
|
235
|
-
// Botão de Gravar
|
236
|
-
var saveBtn = document.getElementById('save-btn');
|
237
|
-
saveBtn.addEventListener('click', function() {
|
238
|
-
if (!filePath) {
|
239
|
-
alert('Nenhum arquivo aberto para gravar.');
|
240
|
-
return;
|
241
|
-
}
|
242
|
-
const content = editorInstance.getValue();
|
243
|
-
fetch(`/api/explorer/${encodeURIComponent(filePath)}`, {
|
244
|
-
method: 'POST',
|
245
|
-
headers: {
|
246
|
-
'Content-Type': 'application/json',
|
247
|
-
},
|
248
|
-
body: JSON.stringify({ content }),
|
249
|
-
})
|
250
|
-
.then(resp => resp.json())
|
251
|
-
.then(data => {
|
252
|
-
if (data.success) {
|
253
|
-
// Show popup
|
254
|
-
var popup = document.getElementById('save-popup');
|
255
|
-
popup.style.display = 'block';
|
256
|
-
setTimeout(() => { popup.style.display = 'none'; }, 1500);
|
257
|
-
} else {
|
258
|
-
alert('Error saving: ' + (data.error || 'desconhecido'));
|
259
|
-
}
|
260
|
-
})
|
261
|
-
.catch(err => {
|
262
|
-
alert('Error saving: ' + err);
|
263
|
-
});
|
264
|
-
});
|
265
|
-
});
|
@@ -1,259 +0,0 @@
|
|
1
|
-
// --- Load file content via AJAX if ?path=... is present ---
|
2
|
-
function getQueryParam(name) {
|
3
|
-
const url = new URL(window.location.href);
|
4
|
-
return url.searchParams.get(name);
|
5
|
-
}
|
6
|
-
const filePath = getQueryParam('path');
|
7
|
-
|
8
|
-
// Updates the theme icon based on the current theme
|
9
|
-
function updateThemeIcon() {
|
10
|
-
var icon = document.getElementById('theme-icon');
|
11
|
-
if (!icon) return;
|
12
|
-
if (document.body.classList.contains('light-theme')) {
|
13
|
-
icon.textContent = '☀️'; // Sun for light mode
|
14
|
-
icon.title = 'Switch to dark mode';
|
15
|
-
} else {
|
16
|
-
icon.textContent = '🌙'; // Moon for dark mode
|
17
|
-
icon.title = 'Switch to light mode';
|
18
|
-
}
|
19
|
-
}
|
20
|
-
|
21
|
-
document.addEventListener('DOMContentLoaded', function() {
|
22
|
-
// Display filename in header if present
|
23
|
-
if (filePath) {
|
24
|
-
const filename = filePath.split(/[\\\/]/).pop();
|
25
|
-
const filenameDisplay = document.getElementById('filename-display');
|
26
|
-
if (filenameDisplay) {
|
27
|
-
filenameDisplay.textContent = '— ' + filePath;
|
28
|
-
filenameDisplay.title = filePath;
|
29
|
-
}
|
30
|
-
}
|
31
|
-
|
32
|
-
let initialContent = "";
|
33
|
-
if (filePath) {
|
34
|
-
fetch(`/api/explorer/${encodeURIComponent(filePath)}`)
|
35
|
-
.then(resp => resp.json())
|
36
|
-
.then(data => {
|
37
|
-
if (data.type === 'file') {
|
38
|
-
initialContent = data.content;
|
39
|
-
if (window.editorInstance) {
|
40
|
-
window.editorInstance.setValue(initialContent);
|
41
|
-
}
|
42
|
-
} else if (data.error) {
|
43
|
-
initialContent = '# Error: ' + data.error;
|
44
|
-
if (window.editorInstance) {
|
45
|
-
window.editorInstance.setValue(initialContent);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
})
|
49
|
-
.catch(err => {
|
50
|
-
initialContent = '# Error ao carregar arquivo: ' + err;
|
51
|
-
if (window.editorInstance) {
|
52
|
-
window.editorInstance.setValue(initialContent);
|
53
|
-
}
|
54
|
-
});
|
55
|
-
}
|
56
|
-
|
57
|
-
// --- Detect file extension and set CodeMirror mode ---
|
58
|
-
function detectMode(filename) {
|
59
|
-
if (!filename) return 'python';
|
60
|
-
const ext = filename.split('.').pop().toLowerCase();
|
61
|
-
const map = {
|
62
|
-
'py': 'python',
|
63
|
-
'js': 'javascript',
|
64
|
-
'json': 'javascript',
|
65
|
-
'md': 'markdown',
|
66
|
-
'html': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
67
|
-
'htm': {name: 'htmlmixed', scriptingModeSpec: 'django'},
|
68
|
-
'jinja': 'django',
|
69
|
-
'j2': 'django',
|
70
|
-
'jinja2': 'django',
|
71
|
-
'css': 'css',
|
72
|
-
'sh': 'shell',
|
73
|
-
'bash': 'shell',
|
74
|
-
'yml': 'yaml',
|
75
|
-
'yaml': 'yaml',
|
76
|
-
};
|
77
|
-
return map[ext] || 'python';
|
78
|
-
}
|
79
|
-
var initialMode = detectMode(filePath);
|
80
|
-
var editorInstance = CodeMirror.fromTextArea(document.getElementById('code'), {
|
81
|
-
lineNumbers: true,
|
82
|
-
mode: initialMode,
|
83
|
-
theme: 'dracula',
|
84
|
-
indentUnit: 4,
|
85
|
-
tabSize: 4,
|
86
|
-
styleActiveLine: true,
|
87
|
-
});
|
88
|
-
// If file loaded later, update mode
|
89
|
-
if (filePath) {
|
90
|
-
const mode = detectMode(filePath);
|
91
|
-
editorInstance.setOption('mode', mode);
|
92
|
-
}
|
93
|
-
window.editorInstance = editorInstance;
|
94
|
-
// Add Ctrl-F handler for find
|
95
|
-
editorInstance.addKeyMap({
|
96
|
-
'Ctrl-F': function(cm) {
|
97
|
-
cm.execCommand('find');
|
98
|
-
},
|
99
|
-
'Cmd-F': function(cm) {
|
100
|
-
cm.execCommand('find');
|
101
|
-
},
|
102
|
-
'Ctrl-S': function(cm) {
|
103
|
-
document.getElementById('save-btn').click();
|
104
|
-
// Prevent default browser save dialog
|
105
|
-
return false;
|
106
|
-
},
|
107
|
-
'Cmd-S': function(cm) {
|
108
|
-
document.getElementById('save-btn').click();
|
109
|
-
return false;
|
110
|
-
}
|
111
|
-
});
|
112
|
-
// --- Custom floating find navigation panel ---
|
113
|
-
function createFindPanel() {
|
114
|
-
let panel = document.getElementById('find-nav-panel');
|
115
|
-
if (!panel) {
|
116
|
-
panel = document.createElement('div');
|
117
|
-
panel.id = 'find-nav-panel';
|
118
|
-
panel.style.position = 'absolute';
|
119
|
-
panel.style.top = '70px';
|
120
|
-
panel.style.right = '30px';
|
121
|
-
panel.style.zIndex = 200;
|
122
|
-
panel.style.background = 'rgba(40,42,54,0.98)';
|
123
|
-
panel.style.color = '#fff';
|
124
|
-
panel.style.borderRadius = '6px';
|
125
|
-
panel.style.boxShadow = '0 2px 8px #0008';
|
126
|
-
panel.style.padding = '4px 10px 4px 8px';
|
127
|
-
panel.style.display = 'flex';
|
128
|
-
panel.style.alignItems = 'center';
|
129
|
-
panel.style.gap = '8px';
|
130
|
-
panel.style.fontSize = '1em';
|
131
|
-
panel.style.userSelect = 'none';
|
132
|
-
panel.innerHTML = `
|
133
|
-
<button id="find-prev-btn" title="Previous match" style="background:none;border:none;color:#fff;font-size:1.2em;cursor:pointer;">⏮️</button>
|
134
|
-
<span id="find-match-info">1/1</span>
|
135
|
-
<button id="find-next-btn" title="Next match" style="background:none;border:none;color:#fff;font-size:1.2em;cursor:pointer;">⏭️</button>
|
136
|
-
`;
|
137
|
-
document.body.appendChild(panel);
|
138
|
-
}
|
139
|
-
return panel;
|
140
|
-
}
|
141
|
-
function removeFindPanel() {
|
142
|
-
let panel = document.getElementById('find-nav-panel');
|
143
|
-
if (panel) panel.remove();
|
144
|
-
}
|
145
|
-
// Hook into CodeMirror search dialog
|
146
|
-
let lastSearchState = null;
|
147
|
-
function updateFindPanel(cm) {
|
148
|
-
let state = cm.state.search;
|
149
|
-
if (!state || !state.query) {
|
150
|
-
removeFindPanel();
|
151
|
-
return;
|
152
|
-
}
|
153
|
-
let matches = 0, current = 0;
|
154
|
-
if (state.overlay && state.overlay.matches) {
|
155
|
-
matches = state.overlay.matches.length;
|
156
|
-
current = state.overlay.matches.findIndex(m => m.from && cm.getCursor().line === m.from.line && cm.getCursor().ch >= m.from.ch && cm.getCursor().ch <= m.to.ch) + 1;
|
157
|
-
}
|
158
|
-
// fallback: count marked text
|
159
|
-
if (!matches) {
|
160
|
-
let marks = cm.getAllMarks();
|
161
|
-
let found = marks.filter(m => m.className && m.className.includes('cm-searching'));
|
162
|
-
matches = found.length;
|
163
|
-
let cur = cm.getCursor();
|
164
|
-
current = found.findIndex(m => {
|
165
|
-
let pos = m.find();
|
166
|
-
return pos && pos.from.line === cur.line && cur.ch >= pos.from.ch && cur.ch <= pos.to.ch;
|
167
|
-
}) + 1;
|
168
|
-
}
|
169
|
-
if (!matches) matches = 1;
|
170
|
-
if (!current) current = 1;
|
171
|
-
createFindPanel();
|
172
|
-
document.getElementById('find-match-info').textContent = `${current}/${matches}`;
|
173
|
-
}
|
174
|
-
editorInstance.on('cursorActivity', function(cm) {
|
175
|
-
updateFindPanel(cm);
|
176
|
-
});
|
177
|
-
editorInstance.on('search', function(cm) {
|
178
|
-
updateFindPanel(cm);
|
179
|
-
});
|
180
|
-
// Listen for dialog open/close
|
181
|
-
let observer = new MutationObserver(function() {
|
182
|
-
let dialogs = document.querySelectorAll('.CodeMirror-dialog');
|
183
|
-
if (dialogs.length) {
|
184
|
-
setTimeout(() => updateFindPanel(editorInstance), 100);
|
185
|
-
} else {
|
186
|
-
removeFindPanel();
|
187
|
-
}
|
188
|
-
});
|
189
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
190
|
-
// Button handlers
|
191
|
-
document.body.addEventListener('click', function(e) {
|
192
|
-
if (e.target && e.target.id === 'find-next-btn') {
|
193
|
-
editorInstance.execCommand('findNext');
|
194
|
-
} else if (e.target && e.target.id === 'find-prev-btn') {
|
195
|
-
editorInstance.execCommand('findPrev');
|
196
|
-
}
|
197
|
-
});
|
198
|
-
// --- END custom find panel ---
|
199
|
-
// Dynamically calculate available height
|
200
|
-
function resizeEditor() {
|
201
|
-
var header = document.querySelector('.header');
|
202
|
-
var headerHeight = header ? header.offsetHeight : 0;
|
203
|
-
var availableHeight = window.innerHeight - headerHeight;
|
204
|
-
editorInstance.setSize('100%', availableHeight + 'px');
|
205
|
-
}
|
206
|
-
window.addEventListener('resize', resizeEditor);
|
207
|
-
setTimeout(resizeEditor, 0);
|
208
|
-
editorInstance.setValue(initialContent);
|
209
|
-
updateThemeIcon();
|
210
|
-
|
211
|
-
// Set initial state
|
212
|
-
document.body.classList.remove('light-theme');
|
213
|
-
editorInstance.setOption('theme', 'dracula');
|
214
|
-
updateThemeIcon();
|
215
|
-
|
216
|
-
// Theme switch button logic
|
217
|
-
var themeSwitcher = document.getElementById('theme-switcher');
|
218
|
-
if (themeSwitcher) {
|
219
|
-
themeSwitcher.addEventListener('click', function() {
|
220
|
-
var isLight = document.body.classList.toggle('light-theme');
|
221
|
-
if (isLight) {
|
222
|
-
editorInstance.setOption('theme', 'default');
|
223
|
-
} else {
|
224
|
-
editorInstance.setOption('theme', 'dracula');
|
225
|
-
}
|
226
|
-
updateThemeIcon();
|
227
|
-
});
|
228
|
-
}
|
229
|
-
// Botão de Gravar
|
230
|
-
var saveBtn = document.getElementById('save-btn');
|
231
|
-
saveBtn.addEventListener('click', function() {
|
232
|
-
if (!filePath) {
|
233
|
-
alert('Nenhum arquivo aberto para gravar.');
|
234
|
-
return;
|
235
|
-
}
|
236
|
-
const content = editorInstance.getValue();
|
237
|
-
fetch(`/api/explorer/${encodeURIComponent(filePath)}`, {
|
238
|
-
method: 'POST',
|
239
|
-
headers: {
|
240
|
-
'Content-Type': 'application/json',
|
241
|
-
},
|
242
|
-
body: JSON.stringify({ content }),
|
243
|
-
})
|
244
|
-
.then(resp => resp.json())
|
245
|
-
.then(data => {
|
246
|
-
if (data.success) {
|
247
|
-
// Show popup
|
248
|
-
var popup = document.getElementById('save-popup');
|
249
|
-
popup.style.display = 'block';
|
250
|
-
setTimeout(() => { popup.style.display = 'none'; }, 1500);
|
251
|
-
} else {
|
252
|
-
alert('Error saving: ' + (data.error || 'desconhecido'));
|
253
|
-
}
|
254
|
-
})
|
255
|
-
.catch(err => {
|
256
|
-
alert('Error saving: ' + err);
|
257
|
-
});
|
258
|
-
});
|
259
|
-
});
|
@@ -1,59 +0,0 @@
|
|
1
|
-
<!DOCTYPE html>
|
2
|
-
<html lang="en">
|
3
|
-
<head>
|
4
|
-
<link rel="icon" type="image/svg+xml" href="/static/termicon.svg">
|
5
|
-
<link rel="shortcut icon" type="image/x-icon" href="/static/favicon.ico">
|
6
|
-
<meta charset="UTF-8">
|
7
|
-
<title>TermWeb File Explorer — janito.dev</title>
|
8
|
-
<link rel="stylesheet" href="/static/termweb.css">
|
9
|
-
</head>
|
10
|
-
<body>
|
11
|
-
<div class="header">
|
12
|
-
TermWeb File Explorer
|
13
|
-
<button class="theme-switcher" id="theme-switcher">Switch to Light Theme</button>
|
14
|
-
</div>
|
15
|
-
<div class="toolbar" id="explorer-toolbar">
|
16
|
-
<button id="view-list" class="view-toggle active" title="List View">☰</button>
|
17
|
-
<button id="view-icons" class="view-toggle" title="Icon View">■</button>
|
18
|
-
</div>
|
19
|
-
<div class="main" id="explorer-main">
|
20
|
-
<!-- Directory/File browser will be injected here -->
|
21
|
-
</div>
|
22
|
-
<div class="footer">
|
23
|
-
<div class="subtitle">
|
24
|
-
Powered by <a href="https://janito.dev" target="_blank">janito.dev</a> — AI-powered coding agent
|
25
|
-
</div>
|
26
|
-
<ul>
|
27
|
-
<li>🌐 <a href="https://janito.dev" target="_blank">janito.dev</a></li>
|
28
|
-
<li>📚 <a href="https://docs.janito.dev" target="_blank">Documentation</a></li>
|
29
|
-
<li>💻 <a href="https://github.com/joaompinto/janito" target="_blank">GitHub</a></li>
|
30
|
-
</ul>
|
31
|
-
<span style="font-size:0.9em;opacity:0.7;">_generated by janito.dev_</span>
|
32
|
-
</div>
|
33
|
-
<script src="/static/termweb.js"></script>
|
34
|
-
<script>
|
35
|
-
// Theme switcher logic
|
36
|
-
function setTheme(dark) {
|
37
|
-
if (dark) {
|
38
|
-
document.body.classList.add('dark-theme');
|
39
|
-
document.body.classList.remove('light-theme');
|
40
|
-
localStorage.setItem('theme', 'dark');
|
41
|
-
document.getElementById('theme-switcher').textContent = 'Switch to Light Theme';
|
42
|
-
} else {
|
43
|
-
document.body.classList.remove('dark-theme');
|
44
|
-
document.body.classList.add('light-theme');
|
45
|
-
localStorage.setItem('theme', 'light');
|
46
|
-
document.getElementById('theme-switcher').textContent = 'Switch to Dark Theme';
|
47
|
-
}
|
48
|
-
}
|
49
|
-
document.addEventListener('DOMContentLoaded', function() {
|
50
|
-
// Initial theme
|
51
|
-
var theme = localStorage.getItem('theme') || 'dark';
|
52
|
-
setTheme(theme === 'dark');
|
53
|
-
document.getElementById('theme-switcher').onclick = function() {
|
54
|
-
setTheme(document.body.classList.contains('light-theme'));
|
55
|
-
};
|
56
|
-
});
|
57
|
-
</script>
|
58
|
-
</body>
|
59
|
-
</html>
|