dulus 0.2.41__tar.gz → 0.2.42__tar.gz
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.
- {dulus-0.2.41/dulus.egg-info → dulus-0.2.42}/PKG-INFO +9 -2
- {dulus-0.2.41 → dulus-0.2.42}/README.md +8 -1
- {dulus-0.2.41 → dulus-0.2.42}/common.py +1 -1
- {dulus-0.2.41 → dulus-0.2.42}/data/context.json +42 -12
- {dulus-0.2.41 → dulus-0.2.42/dulus.egg-info}/PKG-INFO +9 -2
- {dulus-0.2.41 → dulus-0.2.42}/dulus.py +45 -1
- {dulus-0.2.41 → dulus-0.2.42}/pyproject.toml +1 -1
- {dulus-0.2.41 → dulus-0.2.42}/task/store.py +10 -0
- {dulus-0.2.41 → dulus-0.2.42}/task/tools.py +17 -6
- {dulus-0.2.41 → dulus-0.2.42}/tools.py +39 -0
- {dulus-0.2.41 → dulus-0.2.42}/webchat_server.py +223 -44
- {dulus-0.2.41 → dulus-0.2.42}/LICENSE +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/MANIFEST.in +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/agent.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/compressor.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/context.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/githook.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/marketplace.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/mempalace_bridge.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/personas.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/plugins.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/server.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/backend/tasks.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/batch_api.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/checkpoint/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/checkpoint/hooks.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/checkpoint/store.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/checkpoint/types.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/claude_code_watcher.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/clipboard_utils.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/cloudsave.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/compaction.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/config.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/context.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/active_persona.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/marketplace.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/personas.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/composio_plugin/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/plugin.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/plugins/composio/plugin_tool.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/data/tasks.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/README.md +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/api.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/architecture.md +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/azure-speech-template.json +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/dashboard/index.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/divider.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/generate.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/hero.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/index.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/news.md +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/nvidia-models.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/particle-playground.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/personas/index.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/poetry-banner.png +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/preview.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-agents.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-brainstorm.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-bridges.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-features.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-freetier.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-memory.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-models.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-perms.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-plugins.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-quickstart.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/sec-ssj.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/spinners.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/split-pane.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/terminal-boot.svg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/docs/uploads/particle-playground.html +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus.egg-info/SOURCES.txt +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus.egg-info/dependency_links.txt +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus.egg-info/entry_points.txt +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus.egg-info/requires.txt +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus.egg-info/top_level.txt +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_gui.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_mcp/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_mcp/client.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_mcp/config.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_mcp/tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/dulus_mcp/types.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/agent_bridge.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/chat_widget.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/main_window.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/personas.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/session_utils.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/settings_dialog.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/sidebar.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/tasks_view.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/themes.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/gui/tool_panel.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/input.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/license_manager.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/audit.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/consolidator.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/context.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/offload.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/palace.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/scan.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/sessions.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/store.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/types.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/memory/vector_search.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/multi_agent/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/multi_agent/subagent.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/multi_agent/tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/offload_helper.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/autoadapter.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/loader.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/recommend.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/store.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/plugin/types.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/providers.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/setup.cfg +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/builtin.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/clawhub.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/executor.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/loader.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skill/tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/skills.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/spinner.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/string_utils.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/subagent.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/task/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/task/types.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_afk_yolo.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_approval_runtime.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_background_task_tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_background_tasks.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_checkpoint.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_clipboard_utils.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_compaction.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_diff_view.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_diff_visualization.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_display_blocks.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_export_import.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_hook_engine.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_injection_fix.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_license.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_mcp.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_memory.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_notification_manager.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_plugin.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_session_fork.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_shell_mode.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_skills.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_steer_input.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_subagent.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_task.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_telegram_buffer.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_think_tool.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_todo_tool.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_todo_visualization.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_tool_registry.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_voice.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tests/test_wire_events.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tmux_offloader.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tmux_tools.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/tool_registry.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/ui/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/ui/input.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/ui/render.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/voice/__init__.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/voice/keyterms.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/voice/recorder.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/voice/stt.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/voice/tts.py +0 -0
- {dulus-0.2.41 → dulus-0.2.42}/webchat.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.42
|
|
4
4
|
Summary: Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace
|
|
5
5
|
Author: KevRojo
|
|
6
6
|
License: GPL-3.0
|
|
@@ -69,7 +69,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
69
69
|
<a href="https://pypi.org/project/dulus/"><img src="https://static.pepy.tech/badge/dulus?style=flat-square" alt="downloads"/></a>
|
|
70
70
|
<img src="https://img.shields.io/badge/python-3.11+-ff6b1f?style=flat-square&labelColor=07070a" alt="python"/>
|
|
71
71
|
<img src="https://img.shields.io/badge/license-GPLv3-ff6b1f?style=flat-square&labelColor=07070a" alt="license"/>
|
|
72
|
-
<img src="https://img.shields.io/badge/version-v0.2.
|
|
72
|
+
<img src="https://img.shields.io/badge/version-v0.2.42-ff6b1f?style=flat-square&labelColor=07070a" alt="version"/>
|
|
73
73
|
<img src="https://img.shields.io/badge/providers-11-ff6b1f?style=flat-square&labelColor=07070a" alt="providers"/>
|
|
74
74
|
<img src="https://img.shields.io/badge/tools-27-ff6b1f?style=flat-square&labelColor=07070a" alt="tools"/>
|
|
75
75
|
<img src="https://img.shields.io/badge/tests-263+-ff6b1f?style=flat-square&labelColor=07070a" alt="tests"/>
|
|
@@ -227,6 +227,13 @@ echo "explain this diff" | git diff | dulus -p --accept-all
|
|
|
227
227
|
|
|
228
228
|
<p align="center"><sub>↑ session boot. soul loaded, gold memory warm, shell sniffed. the little circles are real buttons on your Mac.</sub></p>
|
|
229
229
|
|
|
230
|
+
### 💻 Dulus OS (Sandbox)
|
|
231
|
+
> [!NOTE]
|
|
232
|
+
> **Experimental features:** The folder `sandbox/` contains the early implementation of **Dulus OS** — a mini-operating system that runs entirely in your browser. It is currently in heavy development and not 100% functional yet. It will serve as a secure, isolated environment for browser-based tool execution and visualizations.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
|
|
230
237
|
---
|
|
231
238
|
|
|
232
239
|
<p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/sec-features.svg" alt="Features" width="100%"></p>
|
|
@@ -22,7 +22,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
22
22
|
<a href="https://pypi.org/project/dulus/"><img src="https://static.pepy.tech/badge/dulus?style=flat-square" alt="downloads"/></a>
|
|
23
23
|
<img src="https://img.shields.io/badge/python-3.11+-ff6b1f?style=flat-square&labelColor=07070a" alt="python"/>
|
|
24
24
|
<img src="https://img.shields.io/badge/license-GPLv3-ff6b1f?style=flat-square&labelColor=07070a" alt="license"/>
|
|
25
|
-
<img src="https://img.shields.io/badge/version-v0.2.
|
|
25
|
+
<img src="https://img.shields.io/badge/version-v0.2.42-ff6b1f?style=flat-square&labelColor=07070a" alt="version"/>
|
|
26
26
|
<img src="https://img.shields.io/badge/providers-11-ff6b1f?style=flat-square&labelColor=07070a" alt="providers"/>
|
|
27
27
|
<img src="https://img.shields.io/badge/tools-27-ff6b1f?style=flat-square&labelColor=07070a" alt="tools"/>
|
|
28
28
|
<img src="https://img.shields.io/badge/tests-263+-ff6b1f?style=flat-square&labelColor=07070a" alt="tests"/>
|
|
@@ -180,6 +180,13 @@ echo "explain this diff" | git diff | dulus -p --accept-all
|
|
|
180
180
|
|
|
181
181
|
<p align="center"><sub>↑ session boot. soul loaded, gold memory warm, shell sniffed. the little circles are real buttons on your Mac.</sub></p>
|
|
182
182
|
|
|
183
|
+
### 💻 Dulus OS (Sandbox)
|
|
184
|
+
> [!NOTE]
|
|
185
|
+
> **Experimental features:** The folder `sandbox/` contains the early implementation of **Dulus OS** — a mini-operating system that runs entirely in your browser. It is currently in heavy development and not 100% functional yet. It will serve as a secure, isolated environment for browser-based tool execution and visualizations.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
|
|
183
190
|
---
|
|
184
191
|
|
|
185
192
|
<p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/sec-features.svg" alt="Features" width="100%"></p>
|
|
@@ -9,22 +9,52 @@
|
|
|
9
9
|
"project": {
|
|
10
10
|
"name": "Dulus Command Center",
|
|
11
11
|
"repo_stats": {
|
|
12
|
-
"files":
|
|
13
|
-
"lines":
|
|
12
|
+
"files": 26697,
|
|
13
|
+
"lines": 3602498,
|
|
14
14
|
"languages": {
|
|
15
15
|
".example": 5,
|
|
16
|
-
"
|
|
17
|
-
".
|
|
18
|
-
"
|
|
16
|
+
"no_ext": 16410,
|
|
17
|
+
".py": 60171,
|
|
18
|
+
".html": 15960,
|
|
19
19
|
".in": 2,
|
|
20
20
|
".toml": 123,
|
|
21
|
-
".md":
|
|
22
|
-
".txt":
|
|
23
|
-
".
|
|
24
|
-
".
|
|
25
|
-
".
|
|
26
|
-
".
|
|
27
|
-
".
|
|
21
|
+
".md": 79646,
|
|
22
|
+
".txt": 1018,
|
|
23
|
+
".json": 133634,
|
|
24
|
+
".whl": 17908,
|
|
25
|
+
".gz": 18064,
|
|
26
|
+
".svg": 1168,
|
|
27
|
+
".png": 157513,
|
|
28
|
+
".sh": 144,
|
|
29
|
+
".js": 1992568,
|
|
30
|
+
".ts": 570599,
|
|
31
|
+
".log": 1,
|
|
32
|
+
".jpg": 1076,
|
|
33
|
+
".tsx": 34508,
|
|
34
|
+
".css": 2848,
|
|
35
|
+
".cmd": 476,
|
|
36
|
+
".ps1": 784,
|
|
37
|
+
".tsbuildinfo": 2,
|
|
38
|
+
".mts": 29541,
|
|
39
|
+
".yml": 250,
|
|
40
|
+
".markdown": 763,
|
|
41
|
+
".flow": 21999,
|
|
42
|
+
".cjs": 150052,
|
|
43
|
+
".cts": 44618,
|
|
44
|
+
".map": 5059,
|
|
45
|
+
".mjs": 102525,
|
|
46
|
+
".BSD": 59,
|
|
47
|
+
".lock": 2598,
|
|
48
|
+
".nix": 20,
|
|
49
|
+
".bnf": 32,
|
|
50
|
+
".coffee": 1,
|
|
51
|
+
".1": 164,
|
|
52
|
+
".php": 156,
|
|
53
|
+
".jst": 1840,
|
|
54
|
+
".def": 534,
|
|
55
|
+
".node": 34828,
|
|
56
|
+
".snap": 4138,
|
|
57
|
+
".exe": 98693
|
|
28
58
|
}
|
|
29
59
|
},
|
|
30
60
|
"recent_commits": [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.42
|
|
4
4
|
Summary: Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace
|
|
5
5
|
Author: KevRojo
|
|
6
6
|
License: GPL-3.0
|
|
@@ -69,7 +69,7 @@ SET /sticky_input ON since the first run for the best experience!
|
|
|
69
69
|
<a href="https://pypi.org/project/dulus/"><img src="https://static.pepy.tech/badge/dulus?style=flat-square" alt="downloads"/></a>
|
|
70
70
|
<img src="https://img.shields.io/badge/python-3.11+-ff6b1f?style=flat-square&labelColor=07070a" alt="python"/>
|
|
71
71
|
<img src="https://img.shields.io/badge/license-GPLv3-ff6b1f?style=flat-square&labelColor=07070a" alt="license"/>
|
|
72
|
-
<img src="https://img.shields.io/badge/version-v0.2.
|
|
72
|
+
<img src="https://img.shields.io/badge/version-v0.2.42-ff6b1f?style=flat-square&labelColor=07070a" alt="version"/>
|
|
73
73
|
<img src="https://img.shields.io/badge/providers-11-ff6b1f?style=flat-square&labelColor=07070a" alt="providers"/>
|
|
74
74
|
<img src="https://img.shields.io/badge/tools-27-ff6b1f?style=flat-square&labelColor=07070a" alt="tools"/>
|
|
75
75
|
<img src="https://img.shields.io/badge/tests-263+-ff6b1f?style=flat-square&labelColor=07070a" alt="tests"/>
|
|
@@ -227,6 +227,13 @@ echo "explain this diff" | git diff | dulus -p --accept-all
|
|
|
227
227
|
|
|
228
228
|
<p align="center"><sub>↑ session boot. soul loaded, gold memory warm, shell sniffed. the little circles are real buttons on your Mac.</sub></p>
|
|
229
229
|
|
|
230
|
+
### 💻 Dulus OS (Sandbox)
|
|
231
|
+
> [!NOTE]
|
|
232
|
+
> **Experimental features:** The folder `sandbox/` contains the early implementation of **Dulus OS** — a mini-operating system that runs entirely in your browser. It is currently in heavy development and not 100% functional yet. It will serve as a secure, isolated environment for browser-based tool execution and visualizations.
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
|
|
230
237
|
---
|
|
231
238
|
|
|
232
239
|
<p align="center"><img src="https://raw.githubusercontent.com/KevRojo/Dulus/main/docs/sec-features.svg" alt="Features" width="100%"></p>
|
|
@@ -115,6 +115,8 @@ Slash commands in REPL:
|
|
|
115
115
|
/kimi_chats List recent Kimi conversations
|
|
116
116
|
/webchat [port] Spawn web chat UI (background Flask server)
|
|
117
117
|
/webchat stop Kill the webchat server
|
|
118
|
+
/sandbox Open Dulus Sandbox OS in browser (starts webchat if needed)
|
|
119
|
+
/sandbox stop Stop the webchat server
|
|
118
120
|
/rtk [on|off] Toggle RTK token-optimized shell command rewriting
|
|
119
121
|
/exit /quit Exit
|
|
120
122
|
"""
|
|
@@ -1828,6 +1830,46 @@ def cmd_webchat(args: str, state, config) -> bool:
|
|
|
1828
1830
|
info(f"WebChat spawn timed out -- try opening {local_url} manually or check :{port}")
|
|
1829
1831
|
return True
|
|
1830
1832
|
|
|
1833
|
+
|
|
1834
|
+
def cmd_sandbox(args: str, state, config) -> bool:
|
|
1835
|
+
"""Open the Dulus Sandbox OS in the browser.
|
|
1836
|
+
|
|
1837
|
+
/sandbox — Ensure webchat is running, open /sandbox in browser
|
|
1838
|
+
/sandbox stop — Alias for /webchat stop
|
|
1839
|
+
"""
|
|
1840
|
+
import webbrowser, time, urllib.request
|
|
1841
|
+
|
|
1842
|
+
arg = (args or "").strip().lower()
|
|
1843
|
+
|
|
1844
|
+
if arg in ("stop", "kill", "off"):
|
|
1845
|
+
return cmd_webchat("stop", state, config)
|
|
1846
|
+
|
|
1847
|
+
# Make sure webchat is running first
|
|
1848
|
+
import webchat_server
|
|
1849
|
+
port = config.get("_webchat_port", 5000)
|
|
1850
|
+
|
|
1851
|
+
def _wc_alive(p):
|
|
1852
|
+
try:
|
|
1853
|
+
urllib.request.urlopen(f"http://127.0.0.1:{p}/api/health", timeout=0.5).read(1)
|
|
1854
|
+
return True
|
|
1855
|
+
except Exception:
|
|
1856
|
+
return False
|
|
1857
|
+
|
|
1858
|
+
if not _wc_alive(port):
|
|
1859
|
+
ok("Starting WebChat first...")
|
|
1860
|
+
cmd_webchat("", state, config)
|
|
1861
|
+
# Wait up to 5s for it to be ready
|
|
1862
|
+
for _ in range(20):
|
|
1863
|
+
if _wc_alive(port):
|
|
1864
|
+
break
|
|
1865
|
+
time.sleep(0.25)
|
|
1866
|
+
|
|
1867
|
+
sandbox_url = f"http://127.0.0.1:{port}/sandbox"
|
|
1868
|
+
ok(f"Opening Sandbox OS -> {sandbox_url}")
|
|
1869
|
+
webbrowser.open(sandbox_url)
|
|
1870
|
+
info("Mini OS running in your browser. Use /sandbox stop to shut down the server.")
|
|
1871
|
+
return True
|
|
1872
|
+
|
|
1831
1873
|
def cmd_gui(_args: str, _state, config) -> bool:
|
|
1832
1874
|
"""Launch the desktop GUI from the REPL."""
|
|
1833
1875
|
try:
|
|
@@ -7440,6 +7482,7 @@ COMMANDS = {
|
|
|
7440
7482
|
"voice": cmd_voice,
|
|
7441
7483
|
"git": cmd_git,
|
|
7442
7484
|
"webchat": cmd_webchat,
|
|
7485
|
+
"sandbox": cmd_sandbox,
|
|
7443
7486
|
"gui": cmd_gui,
|
|
7444
7487
|
"brave": cmd_brave,
|
|
7445
7488
|
"rtk": cmd_rtk,
|
|
@@ -7579,7 +7622,8 @@ _CMD_META: dict[str, tuple[str, list[str]]] = {
|
|
|
7579
7622
|
"gemini_chats": ("Manage Gemini Web conversations", ["new"]),
|
|
7580
7623
|
"gemini_harvest": ("Harvest Gemini Web cookies (alias)", []),
|
|
7581
7624
|
"harvest-claude": ("Harvest Claude.ai cookies (alias)", []),
|
|
7582
|
-
"webchat": ("Spawn web chat UI", ["stop"]),
|
|
7625
|
+
"webchat": ("Spawn web chat UI", ["stop", "lan"]),
|
|
7626
|
+
"sandbox": ("Open Dulus Sandbox OS in browser", ["stop"]),
|
|
7583
7627
|
"gui": ("Launch desktop GUI", []),
|
|
7584
7628
|
}
|
|
7585
7629
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dulus"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.42"
|
|
8
8
|
description = "Spanish-first multi-provider AI CLI — 14 NVIDIA models free, Mesa Redonda, voice, TTS, RTK token reducer, MemPalace"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -61,15 +61,25 @@ def _next_id() -> str:
|
|
|
61
61
|
def create_task(
|
|
62
62
|
subject: str,
|
|
63
63
|
description: str,
|
|
64
|
+
status: str = "pending",
|
|
65
|
+
owner: str = "",
|
|
64
66
|
active_form: str = "",
|
|
65
67
|
metadata: dict[str, Any] | None = None,
|
|
66
68
|
) -> Task:
|
|
67
69
|
with _lock:
|
|
68
70
|
_load()
|
|
71
|
+
# Validate status enum
|
|
72
|
+
try:
|
|
73
|
+
task_status = TaskStatus(status)
|
|
74
|
+
except ValueError:
|
|
75
|
+
task_status = TaskStatus.PENDING
|
|
76
|
+
|
|
69
77
|
task = Task(
|
|
70
78
|
id=_next_id(),
|
|
71
79
|
subject=subject,
|
|
72
80
|
description=description,
|
|
81
|
+
status=task_status,
|
|
82
|
+
owner=owner,
|
|
73
83
|
active_form=active_form,
|
|
74
84
|
metadata=metadata or {},
|
|
75
85
|
)
|
|
@@ -26,6 +26,15 @@ _TASK_CREATE_SCHEMA = {
|
|
|
26
26
|
"type": "string",
|
|
27
27
|
"description": "What needs to be done",
|
|
28
28
|
},
|
|
29
|
+
"status": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["pending", "in_progress", "completed", "cancelled"],
|
|
32
|
+
"description": "Current state of the task (default is 'pending')",
|
|
33
|
+
},
|
|
34
|
+
"owner": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "The agent or user responsible (e.g. 'A', 'B', 'User')",
|
|
37
|
+
},
|
|
29
38
|
"active_form": {
|
|
30
39
|
"type": "string",
|
|
31
40
|
"description": (
|
|
@@ -38,7 +47,7 @@ _TASK_CREATE_SCHEMA = {
|
|
|
38
47
|
"description": "Arbitrary key-value metadata to attach to the task",
|
|
39
48
|
},
|
|
40
49
|
},
|
|
41
|
-
"required": ["subject", "description"],
|
|
50
|
+
"required": ["subject", "description", "status", "owner"],
|
|
42
51
|
},
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -128,9 +137,9 @@ _TASK_LIST_SCHEMA = {
|
|
|
128
137
|
|
|
129
138
|
# ── Implementations ────────────────────────────────────────────────────────────
|
|
130
139
|
|
|
131
|
-
def _task_create(subject: str, description: str, active_form: str = "", metadata: dict = None) -> str:
|
|
132
|
-
task = create_task(subject, description, active_form=active_form, metadata=metadata)
|
|
133
|
-
return f"Task #{task.id} created: {task.subject}"
|
|
140
|
+
def _task_create(subject: str, description: str, status: str = "pending", owner: str = "", active_form: str = "", metadata: dict = None) -> str:
|
|
141
|
+
task = create_task(subject, description, status=status, owner=owner, active_form=active_form, metadata=metadata)
|
|
142
|
+
return f"Task #{task.id} created: {task.subject} (Owner: {task.owner}, Status: {task.status.value})"
|
|
134
143
|
|
|
135
144
|
|
|
136
145
|
def _task_update(
|
|
@@ -220,8 +229,10 @@ def _register() -> None:
|
|
|
220
229
|
func=lambda p, c: _task_create(
|
|
221
230
|
p["subject"],
|
|
222
231
|
p["description"],
|
|
223
|
-
p.get("
|
|
224
|
-
p.get("
|
|
232
|
+
status=p.get("status", "pending"),
|
|
233
|
+
owner=p.get("owner", ""),
|
|
234
|
+
active_form=p.get("active_form", ""),
|
|
235
|
+
metadata=p.get("metadata"),
|
|
225
236
|
),
|
|
226
237
|
read_only=False,
|
|
227
238
|
concurrent_safe=True,
|
|
@@ -59,7 +59,20 @@ def _is_in_tg_turn(config: dict) -> bool:
|
|
|
59
59
|
|
|
60
60
|
# ── Tool JSON schemas (sent to Claude API) ─────────────────────────────────
|
|
61
61
|
|
|
62
|
+
_LAUNCH_SANDBOX_SCHEMA = {
|
|
63
|
+
"name": "LaunchSandbox",
|
|
64
|
+
"description": "Start the Dulus Sandbox (mini-OS) web interface in the browser. "
|
|
65
|
+
"Provides a visual desktop experience with integrated Dulus Terminal.",
|
|
66
|
+
"input_schema": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"properties": {
|
|
69
|
+
"stop": {"type": "boolean", "description": "If true, stop the server instead of starting it."}
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
TOOL_SCHEMAS = [
|
|
75
|
+
_LAUNCH_SANDBOX_SCHEMA,
|
|
63
76
|
{
|
|
64
77
|
"name": "Read",
|
|
65
78
|
"description": (
|
|
@@ -2683,6 +2696,30 @@ register_tool(ToolDef(name="GitStatus", schema=_GIT_STATUS_SCHEMA, func=_git_sta
|
|
|
2683
2696
|
register_tool(ToolDef(name="GitLog", schema=_GIT_LOG_SCHEMA, func=_git_log, read_only=True, concurrent_safe=True))
|
|
2684
2697
|
|
|
2685
2698
|
|
|
2699
|
+
def _launch_sandbox(params: dict, config: dict) -> str:
|
|
2700
|
+
# Use the existing command handler from dulus.py
|
|
2701
|
+
try:
|
|
2702
|
+
from dulus import COMMANDS
|
|
2703
|
+
handler = COMMANDS.get("sandbox")
|
|
2704
|
+
if not handler:
|
|
2705
|
+
return "Error: /sandbox command not found in Dulus."
|
|
2706
|
+
|
|
2707
|
+
stop = params.get("stop", False)
|
|
2708
|
+
args = "stop" if stop else ""
|
|
2709
|
+
|
|
2710
|
+
state = config.get("_state")
|
|
2711
|
+
if not state:
|
|
2712
|
+
return "Error: Dulus session state not available to tool."
|
|
2713
|
+
|
|
2714
|
+
handler(args, state, config)
|
|
2715
|
+
return "Dulus Sandbox OS opened in browser." if not stop else "Sandbox stopped."
|
|
2716
|
+
except Exception as e:
|
|
2717
|
+
return f"Error launching sandbox: {e}"
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
register_tool(ToolDef(name="LaunchSandbox", schema=_LAUNCH_SANDBOX_SCHEMA, func=_launch_sandbox))
|
|
2721
|
+
|
|
2722
|
+
|
|
2686
2723
|
# Plugins are loaded once when Dulus starts (not on every reload to avoid overhead)
|
|
2687
2724
|
try:
|
|
2688
2725
|
from plugin.loader import register_plugin_tools
|
|
@@ -2700,3 +2737,5 @@ except Exception:
|
|
|
2700
2737
|
# If plugin system fails, continue with core tools only
|
|
2701
2738
|
_plugin_count = 0
|
|
2702
2739
|
|
|
2740
|
+
|
|
2741
|
+
|