virtuai-cli 0.8.3__tar.gz → 0.8.4__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.
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/PKG-INFO +1 -1
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/pyproject.toml +1 -1
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/__init__.py +1 -1
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/runner.py +42 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/PKG-INFO +1 -1
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/README.md +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/setup.cfg +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/__init__.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/ask.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/command.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/history.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/sse.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/tui.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/chat/widgets.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/config.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/executor.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/main.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli/security.py +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/SOURCES.txt +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/dependency_links.txt +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/entry_points.txt +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/requires.txt +0 -0
- {virtuai_cli-0.8.3 → virtuai_cli-0.8.4}/src/virtuai_cli.egg-info/top_level.txt +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""VirtuAI local CLI."""
|
|
2
|
-
__version__ = "0.8.
|
|
2
|
+
__version__ = "0.8.4"
|
|
@@ -42,9 +42,49 @@ def _audit(workdir: Path, command: str, exit_code: int, elapsed: float) -> None:
|
|
|
42
42
|
pass
|
|
43
43
|
|
|
44
44
|
_RECONNECT_DELAYS = [1, 2, 4, 8, 16, 30] # backoff steps
|
|
45
|
+
# Skill file extensions to read from the workdir's skills/ folder.
|
|
46
|
+
_SKILL_EXTENSIONS = {".md", ".txt", ".sh", ".py", ".js", ".ts", ".yaml", ".yml"}
|
|
45
47
|
_RECV_TIMEOUT = 60.0 # seconds of silence before declaring the connection stale
|
|
46
48
|
|
|
47
49
|
|
|
50
|
+
def _read_local_memory(workdir: Path) -> str:
|
|
51
|
+
"""Concatenate all .md files in {workdir}/memory/ into a single seed string.
|
|
52
|
+
|
|
53
|
+
Returns "" if the folder doesn't exist or is empty so the ready frame is
|
|
54
|
+
unchanged for workdirs without a local memory folder.
|
|
55
|
+
"""
|
|
56
|
+
memory_dir = workdir / "memory"
|
|
57
|
+
if not memory_dir.is_dir():
|
|
58
|
+
return ""
|
|
59
|
+
parts: list[str] = []
|
|
60
|
+
for f in sorted(memory_dir.iterdir()):
|
|
61
|
+
if f.is_file() and f.suffix.lower() in {".md", ".txt"}:
|
|
62
|
+
try:
|
|
63
|
+
parts.append(f.read_text(encoding="utf-8", errors="replace"))
|
|
64
|
+
except Exception:
|
|
65
|
+
pass
|
|
66
|
+
return "\n\n".join(parts)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _read_local_skills(workdir: Path) -> dict[str, str]:
|
|
70
|
+
"""Read skill files from {workdir}/skills/ and return {stem: content}.
|
|
71
|
+
|
|
72
|
+
Only read when the directory exists — returns {} otherwise so the ready
|
|
73
|
+
frame is unchanged for workdirs without a local skills folder.
|
|
74
|
+
"""
|
|
75
|
+
skills_dir = workdir / "skills"
|
|
76
|
+
if not skills_dir.is_dir():
|
|
77
|
+
return {}
|
|
78
|
+
skills: dict[str, str] = {}
|
|
79
|
+
for f in sorted(skills_dir.iterdir()):
|
|
80
|
+
if f.is_file() and f.suffix.lower() in _SKILL_EXTENSIONS:
|
|
81
|
+
try:
|
|
82
|
+
skills[f.stem] = f.read_text(encoding="utf-8", errors="replace")
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
85
|
+
return skills
|
|
86
|
+
|
|
87
|
+
|
|
48
88
|
def _default_on_status(level: str, msg: str) -> None:
|
|
49
89
|
style = {"info": "green", "warn": "yellow", "error": "red"}.get(level, "")
|
|
50
90
|
console.print(f"[{style}]{msg}[/{style}]" if style else msg)
|
|
@@ -71,6 +111,8 @@ async def _handle_frame(
|
|
|
71
111
|
"arch": platform.machine(),
|
|
72
112
|
"python": f"{sys.version_info.major}.{sys.version_info.minor}",
|
|
73
113
|
"workdir": str(workdir),
|
|
114
|
+
"local_skills": _read_local_skills(workdir),
|
|
115
|
+
"local_memory": _read_local_memory(workdir),
|
|
74
116
|
}
|
|
75
117
|
await ws.send(json.dumps(reply))
|
|
76
118
|
on_status("info", f"Connected. Workdir: {workdir}")
|
|
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
|