dulus 0.2.26__tar.gz → 0.2.27__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.26/dulus.egg-info → dulus-0.2.27}/PKG-INFO +2 -2
- {dulus-0.2.26 → dulus-0.2.27}/README.md +1 -1
- {dulus-0.2.26 → dulus-0.2.27}/docs/news.md +2 -0
- {dulus-0.2.26 → dulus-0.2.27/dulus.egg-info}/PKG-INFO +2 -2
- {dulus-0.2.26 → dulus-0.2.27}/dulus.py +30 -2
- {dulus-0.2.26 → dulus-0.2.27}/pyproject.toml +1 -1
- {dulus-0.2.26 → dulus-0.2.27}/LICENSE +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/MANIFEST.in +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/agent.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/compressor.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/context.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/githook.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/marketplace.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/mempalace_bridge.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/personas.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/plugins.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/server.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/backend/tasks.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/batch_api.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/checkpoint/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/checkpoint/hooks.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/checkpoint/store.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/checkpoint/types.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/claude_code_watcher.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/clipboard_utils.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/cloudsave.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/common.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/compaction.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/config.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/context.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/active_persona.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/context.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/marketplace.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/personas.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/composio_plugin/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/composio_plugin/session_manager.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/composio_plugin/tool_generator.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/plugin.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/plugins/composio/plugin_tool.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/data/tasks.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/README.md +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/api.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/architecture.md +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/azure-speech-template.json +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/dashboard/index.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/divider.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/generate.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/hero.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/index.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/nvidia-models.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/particle-playground.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/personas/index.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/poetry-banner.png +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/preview.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-agents.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-brainstorm.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-bridges.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-features.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-freetier.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-memory.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-models.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-perms.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-plugins.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-quickstart.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/sec-ssj.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/spinners.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/split-pane.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/terminal-boot.svg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/docs/uploads/particle-playground.html +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus.egg-info/SOURCES.txt +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus.egg-info/dependency_links.txt +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus.egg-info/entry_points.txt +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus.egg-info/requires.txt +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus.egg-info/top_level.txt +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_gui.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_mcp/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_mcp/client.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_mcp/config.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_mcp/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/dulus_mcp/types.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/agent_bridge.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/chat_widget.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/main_window.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/personas.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/session_utils.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/settings_dialog.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/sidebar.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/tasks_view.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/themes.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/gui/tool_panel.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/input.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/license_manager.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/audit.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/consolidator.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/context.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/offload.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/palace.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/scan.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/sessions.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/store.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/types.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/memory/vector_search.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/multi_agent/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/multi_agent/subagent.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/multi_agent/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/offload_helper.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/autoadapter.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/loader.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/recommend.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/store.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/plugin/types.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/providers.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/setup.cfg +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/builtin.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/clawhub.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/executor.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/loader.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skill/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/skills.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/spinner.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/string_utils.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/subagent.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/task/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/task/store.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/task/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/task/types.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_checkpoint.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_compaction.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_diff_view.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_injection_fix.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_license.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_mcp.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_memory.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_plugin.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_skills.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_subagent.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_task.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_telegram_buffer.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_tool_registry.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tests/test_voice.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tmux_offloader.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tmux_tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tool_registry.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/tools.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/ui/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/ui/input.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/ui/render.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/voice/__init__.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/voice/keyterms.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/voice/recorder.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/voice/stt.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/voice/tts.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/webchat.py +0 -0
- {dulus-0.2.26 → dulus-0.2.27}/webchat_server.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.27
|
|
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.27-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"/>
|
|
@@ -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.27-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"/>
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
## 🔥🔥🔥 News (Pacific Time)
|
|
4
4
|
|
|
5
5
|
|
|
6
|
+
- May 09, 2026 (**v0.2.27**): **`/bg` no longer leaves stale state** — when something else (a REPL, an old daemon) is already on `127.0.0.1:5151`, `/bg start` now refuses to spawn a duplicate that would just fail to bind, explains what's happening, and clears the stale PID file. `/bg status` self-heals: when it sees a stale PID it auto-removes it instead of complaining on every call. The previous "Some Dulus is listening on IPC, but our PID file is stale" warning is gone for good.
|
|
7
|
+
|
|
6
8
|
- May 09, 2026 (**v0.2.26**): **`/bg start` daemon crash fix + defensive `clr()` + composio fallback**
|
|
7
9
|
- **Daemon was silently crashing on launch.** `_run_daemon` printed its banner with `clr("...", "accent", "bold")`, but the default theme palette only ships {blue, cyan, gray, green, magenta, red, white, yellow} — `"accent"` raised `KeyError` and killed the process before the prompt loop started. WebChat + IPC threads, being daemon=True, died with it. Switched the banner to `"yellow"` and wrapped in try/except so a stale theme color name never takes the daemon down.
|
|
8
10
|
- **`clr()` is now defensive.** Missing color keys are silently dropped instead of raising. One typo in a theme name no longer crashes the REPL.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dulus
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.27
|
|
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.27-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"/>
|
|
@@ -218,7 +218,7 @@ try:
|
|
|
218
218
|
from importlib.metadata import version as _pkg_version
|
|
219
219
|
VERSION = _pkg_version("dulus")
|
|
220
220
|
except Exception:
|
|
221
|
-
VERSION = "0.2.
|
|
221
|
+
VERSION = "0.2.27" # dev fallback — keep in sync with pyproject.toml
|
|
222
222
|
|
|
223
223
|
# ── ANSI helpers (used even with rich for non-markdown output) ─────────────
|
|
224
224
|
from common import C, clr, info, ok, warn, err, stream_thinking, print_tool_start, print_tool_end, sanitize_text
|
|
@@ -1581,9 +1581,22 @@ def cmd_bg(args: str, _state, config) -> bool:
|
|
|
1581
1581
|
elif alive and not ipc:
|
|
1582
1582
|
warn(f"PID {pid} alive but IPC port not responding (still booting?)")
|
|
1583
1583
|
elif ipc:
|
|
1584
|
-
warn("
|
|
1584
|
+
warn("Another Dulus (REPL or older daemon) is on the IPC port.")
|
|
1585
|
+
info(f" IPC: 127.0.0.1:{DULUS_IPC_PORT} (responding, but not our daemon)")
|
|
1586
|
+
info(" You can still reach it via `dulus \"...\"` from any shell.")
|
|
1587
|
+
info(" /bg start won't spawn a duplicate — kill the other one first if needed.")
|
|
1588
|
+
# Clear the stale PID file so this warning self-heals next time.
|
|
1589
|
+
try:
|
|
1590
|
+
BG_PID.unlink()
|
|
1591
|
+
except FileNotFoundError:
|
|
1592
|
+
pass
|
|
1585
1593
|
else:
|
|
1586
1594
|
info("Dulus background: NOT RUNNING")
|
|
1595
|
+
# Clean up any stale PID file just in case.
|
|
1596
|
+
try:
|
|
1597
|
+
BG_PID.unlink()
|
|
1598
|
+
except FileNotFoundError:
|
|
1599
|
+
pass
|
|
1587
1600
|
return True
|
|
1588
1601
|
|
|
1589
1602
|
# ── /bg stop ──────────────────────────────────────────────────────────
|
|
@@ -1639,6 +1652,21 @@ def cmd_bg(args: str, _state, config) -> bool:
|
|
|
1639
1652
|
info(f"Already running (PID {existing_pid}). Use `/bg status` for details.")
|
|
1640
1653
|
return True
|
|
1641
1654
|
|
|
1655
|
+
# Some other Dulus (a REPL on this machine, an old daemon, etc.) is
|
|
1656
|
+
# holding the IPC port. Spawning a new daemon would just fail to bind
|
|
1657
|
+
# and leave a stale PID. Better: tell the user what's up.
|
|
1658
|
+
if _ipc_alive():
|
|
1659
|
+
warn(f"Port {DULUS_IPC_PORT} is already in use by another Dulus process.")
|
|
1660
|
+
info("If that's a REPL you're running, this Dulus is already reachable")
|
|
1661
|
+
info(f" via `dulus \"...\"` from any shell — no /bg start needed.")
|
|
1662
|
+
info("If it's a stale daemon, find and kill it manually, then retry.")
|
|
1663
|
+
# Clean up the stale PID file so /bg status stops complaining.
|
|
1664
|
+
try:
|
|
1665
|
+
BG_PID.unlink()
|
|
1666
|
+
except FileNotFoundError:
|
|
1667
|
+
pass
|
|
1668
|
+
return True
|
|
1669
|
+
|
|
1642
1670
|
# Parse --web-port
|
|
1643
1671
|
web_port = config.get("_webchat_port", 5000)
|
|
1644
1672
|
if "--web-port" in parts:
|
|
@@ -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.27"
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|