forked from ninjahawk/hollow-agentOS
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhollow.py
More file actions
117 lines (95 loc) · 3.48 KB
/
Copy pathhollow.py
File metadata and controls
117 lines (95 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python3
"""
hollow — Hollow AgentOS setup and launcher.
Usage:
python hollow.py first-run setup or re-run if already configured
python hollow.py setup force re-run setup wizard
python hollow.py logs open the live agent monitor
python hollow.py status show current agent status
python hollow.py stop stop all containers
python hollow.py help show this message
"""
import sys
import os
import json
import subprocess
import shutil
import platform
import secrets
import time
import asyncio
from pathlib import Path
# Force UTF-8 on Windows consoles. Without this, `python hollow.py status`
# (and any other command that prints the arrow glyph or other non-cp1252
# characters) crashes with UnicodeEncodeError on Windows cmd.exe / PowerShell
# whose default encoding is still cp1252. Verified by fresh-clone install test
# 2026-05-12.
if hasattr(sys.stdout, "reconfigure"):
try:
sys.stdout.reconfigure(encoding="utf-8")
sys.stderr.reconfigure(encoding="utf-8")
except Exception:
pass
# ── Root directory (wherever hollow.py lives) ─────────────────────────────────
ROOT = Path(__file__).parent.resolve()
CONFIG_PATH = ROOT / "config.json"
CONFIG_EXAMPLE = ROOT / "config.example.json"
ENV_PATH = ROOT / ".env"
COMPOSE_FILE = ROOT / "docker-compose.yml"
# ── CLI dispatch ──────────────────────────────────────────────────────────────
def main():
arg = sys.argv[1].lower() if len(sys.argv) > 1 else ""
if arg == "help":
print(__doc__)
return
if arg in ("logs", "monitor"):
os.chdir(ROOT)
os.execv(sys.executable, [sys.executable, str(ROOT / "thoughts.py")])
return
if arg == "stop":
_run_quiet(["docker", "compose", "stop"], cwd=ROOT)
print(" Hollow stopped.")
return
if arg == "status":
_show_status()
return
if arg in ("setup", "onboarding"):
_run_setup()
return
# Default (no args): wizard if not configured, monitor if already running
if not CONFIG_PATH.exists():
_run_setup()
else:
# Config exists — go straight to the monitor
os.chdir(ROOT)
os.execv(sys.executable, [sys.executable, str(ROOT / "thoughts.py")])
def _run_quiet(cmd, cwd=None):
try:
subprocess.run(cmd, cwd=cwd, capture_output=True)
except Exception:
pass
def _show_status():
"""Quick status check without full TUI."""
import urllib.request
try:
with urllib.request.urlopen("http://localhost:7777/health", timeout=2) as r:
data = json.loads(r.read())
if data.get("ok"):
print(" Hollow is running. http://localhost:7777")
print(" → hollow logs watch agents live")
print(" → hollow stop stop containers")
return
except Exception:
pass
print(" Hollow is not running.")
print(" → hollow setup run setup wizard")
def _run_setup():
try:
from rich.console import Console # noqa: F401
except ImportError:
print(" Installing setup dependencies...")
subprocess.run([sys.executable, "-m", "pip", "install", "rich", "-q"])
from hollow_setup import run_setup
run_setup()
if __name__ == "__main__":
main()