vibego 1.0.2__py3-none-any.whl → 1.0.5__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.
Potentially problematic release.
This version of vibego might be problematic. Click here for more details.
- master.py +4 -2
- scripts/master_healthcheck.py +34 -134
- scripts/start.sh +16 -9
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/METADATA +1 -1
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/RECORD +10 -10
- vibego_cli/__init__.py +1 -1
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/WHEEL +0 -0
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/entry_points.txt +0 -0
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/licenses/LICENSE +0 -0
- {vibego-1.0.2.dist-info → vibego-1.0.5.dist-info}/top_level.txt +0 -0
master.py
CHANGED
|
@@ -2198,7 +2198,8 @@ async def _process_restart_request(
|
|
|
2198
2198
|
|
|
2199
2199
|
lock = _ensure_restart_lock()
|
|
2200
2200
|
async with lock:
|
|
2201
|
-
|
|
2201
|
+
# Use global so the restart flag is shared across concurrent handlers
|
|
2202
|
+
global _restart_in_progress
|
|
2202
2203
|
if _restart_in_progress:
|
|
2203
2204
|
await message.answer("A restart request is already being executed, please try again later. ")
|
|
2204
2205
|
return
|
|
@@ -2258,7 +2259,8 @@ async def cmd_start(message: Message) -> None:
|
|
|
2258
2259
|
|
|
2259
2260
|
async def _perform_restart(message: Message, start_script: Path) -> None:
|
|
2260
2261
|
"""Asynchronous execution ./start.sh,If it fails, roll back the mark and notify the administrator """
|
|
2261
|
-
|
|
2262
|
+
# Use global so restart flag resets affect the module-level state
|
|
2263
|
+
global _restart_in_progress
|
|
2262
2264
|
lock = _ensure_restart_lock()
|
|
2263
2265
|
bot = message.bot
|
|
2264
2266
|
chat_id = message.chat.id
|
scripts/master_healthcheck.py
CHANGED
|
@@ -1,137 +1,65 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Master
|
|
2
|
+
"""Master post-startup health check.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
4. Send a probe message to the chat through the Telegram Bot API to confirm that the sending is successful.
|
|
9
|
-
5. If any step fails, an exception is thrown and an attempt is made to notify the administrator.
|
|
10
|
-
|
|
11
|
-
Note: This script will not automatically retry the restart and will only return a non-zero exit code for processing by the outer script.
|
|
4
|
+
This lightweight variant only verifies that the master process has emitted the
|
|
5
|
+
readiness marker in its log file. Worker bootstrap and Telegram probes are no
|
|
6
|
+
longer executed because master restart confirmation is now limited to the
|
|
7
|
+
controller process itself.
|
|
12
8
|
"""
|
|
13
9
|
from __future__ import annotations
|
|
14
10
|
|
|
15
11
|
import argparse
|
|
16
|
-
import asyncio
|
|
17
12
|
import json
|
|
18
13
|
import os
|
|
19
|
-
import re
|
|
20
14
|
import sys
|
|
21
15
|
import time
|
|
22
16
|
from pathlib import Path
|
|
23
|
-
from typing import Optional
|
|
24
|
-
from urllib.error import URLError, HTTPError
|
|
25
17
|
from urllib.request import Request, urlopen
|
|
26
18
|
|
|
27
|
-
#
|
|
19
|
+
# Make sure the master module can be imported from the repository root
|
|
28
20
|
ROOT_DIR = Path(__file__).resolve().parent.parent
|
|
29
21
|
ROOT_DIR_STR = str(ROOT_DIR)
|
|
30
22
|
if ROOT_DIR_STR not in sys.path:
|
|
31
|
-
# Make sure the master module can be imported from the repository root
|
|
32
23
|
sys.path.insert(0, ROOT_DIR_STR)
|
|
33
24
|
|
|
34
25
|
import master # type: ignore
|
|
35
|
-
|
|
26
|
+
|
|
36
27
|
DEFAULT_MASTER_LOG = master.LOG_ROOT_PATH / "vibe.log"
|
|
37
28
|
DEFAULT_TIMEOUT_MASTER = 60.0
|
|
38
|
-
|
|
39
|
-
PROBE_TEXT = "hello"
|
|
40
|
-
REPOSITORY = ProjectRepository(master.CONFIG_DB_PATH, master.CONFIG_PATH)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def _load_project(project_id: str) -> master.ProjectConfig:
|
|
44
|
-
"""Get the project configuration based on the slug or bot name, and list the options on failure."""
|
|
45
|
-
|
|
46
|
-
record = REPOSITORY.get_by_slug(project_id)
|
|
47
|
-
if record is None:
|
|
48
|
-
record = REPOSITORY.get_by_bot_name(project_id)
|
|
49
|
-
if record is None:
|
|
50
|
-
available = [r.project_slug for r in REPOSITORY.list_projects()]
|
|
51
|
-
raise RuntimeError(f"No items found {project_id}, Optional items: {available}")
|
|
52
|
-
return master.ProjectConfig.from_dict(record.to_dict())
|
|
29
|
+
MASTER_READY_MARKER = "Master Started, listening for administrator commands."
|
|
53
30
|
|
|
54
31
|
|
|
55
32
|
def _wait_for_log_flag(path: Path, pattern: str, timeout: float) -> None:
|
|
56
|
-
"""
|
|
33
|
+
"""Poll the master log until the readiness marker is detected or timeout."""
|
|
57
34
|
|
|
58
35
|
deadline = time.monotonic() + timeout
|
|
59
|
-
|
|
36
|
+
if path.exists():
|
|
37
|
+
position = path.stat().st_size
|
|
38
|
+
initialized = True
|
|
39
|
+
else:
|
|
40
|
+
position = 0
|
|
41
|
+
initialized = False
|
|
60
42
|
while time.monotonic() < deadline:
|
|
61
43
|
if path.exists():
|
|
62
|
-
if
|
|
63
|
-
position =
|
|
44
|
+
if not initialized:
|
|
45
|
+
position = 0
|
|
46
|
+
initialized = True
|
|
64
47
|
with path.open("r", encoding="utf-8", errors="ignore") as fh:
|
|
65
48
|
fh.seek(position)
|
|
66
49
|
while time.monotonic() < deadline:
|
|
67
50
|
line = fh.readline()
|
|
68
51
|
if not line:
|
|
69
52
|
time.sleep(0.5)
|
|
70
|
-
|
|
53
|
+
break
|
|
71
54
|
position = fh.tell()
|
|
72
55
|
if pattern in line:
|
|
73
56
|
return
|
|
74
57
|
time.sleep(0.5)
|
|
75
|
-
raise TimeoutError(f"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def _extract_chat_id_from_logs(log_path: Path) -> Optional[int]:
|
|
79
|
-
"""Find the most recent chat from the log file in reverse order_id."""
|
|
80
|
-
|
|
81
|
-
if not log_path.exists():
|
|
82
|
-
return None
|
|
83
|
-
pattern = re.compile(r"chat=(-?\d+)")
|
|
84
|
-
try:
|
|
85
|
-
lines = log_path.read_text(encoding="utf-8", errors="ignore").splitlines()
|
|
86
|
-
except Exception:
|
|
87
|
-
return None
|
|
88
|
-
for line in reversed(lines[-200:]): # Reverse search for recent records
|
|
89
|
-
match = pattern.search(line)
|
|
90
|
-
if match:
|
|
91
|
-
try:
|
|
92
|
-
return int(match.group(1))
|
|
93
|
-
except ValueError:
|
|
94
|
-
continue
|
|
95
|
-
return None
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def _ensure_chat_id(cfg: master.ProjectConfig, manager: master.MasterManager) -> int:
|
|
99
|
-
"""Make sure the task is assigned chat_id, Backfill from log and write back to state if necessary."""
|
|
100
|
-
|
|
101
|
-
state = manager.state_store.data.get(cfg.project_slug)
|
|
102
|
-
if state and state.chat_id:
|
|
103
|
-
return int(state.chat_id)
|
|
104
|
-
# Fall back to log search
|
|
105
|
-
log_dir = master.LOG_ROOT_PATH / (cfg.default_model.lower()) / cfg.project_slug
|
|
106
|
-
chat_id = _extract_chat_id_from_logs(log_dir / "run_bot.log")
|
|
107
|
-
if chat_id is None:
|
|
108
|
-
raise RuntimeError(
|
|
109
|
-
"Unable to get chat automatically_id, Please manually have a conversation with the bot to write the state/log"
|
|
110
|
-
)
|
|
111
|
-
# will discover chat_id Write back the state for easy reuse next time
|
|
112
|
-
manager.state_store.update(cfg.project_slug, chat_id=chat_id)
|
|
113
|
-
return chat_id
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
def _send_probe(bot_token: str, chat_id: int, text: str, timeout: float) -> None:
|
|
117
|
-
"""Send a probe message to the specified chat to verify that the Telegram API is available."""
|
|
118
|
-
|
|
119
|
-
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
|
120
|
-
payload = json.dumps({"chat_id": chat_id, "text": text, "disable_notification": True}).encode("utf-8")
|
|
121
|
-
request = Request(url, data=payload, headers={"Content-Type": "application/json"}, method="POST")
|
|
122
|
-
try:
|
|
123
|
-
with urlopen(request, timeout=timeout) as resp:
|
|
124
|
-
data = json.loads(resp.read().decode("utf-8"))
|
|
125
|
-
except HTTPError as exc: # pragma: no cover - Thrown when network exception occurs
|
|
126
|
-
raise RuntimeError(f"Failed to send probe message, HTTP {exc.code}: {exc.reason}") from exc
|
|
127
|
-
except URLError as exc: # pragma: no cover - Thrown when network exception occurs
|
|
128
|
-
raise RuntimeError(f"Failed to send probe message: {exc}") from exc
|
|
129
|
-
if not data.get("ok"):
|
|
130
|
-
raise RuntimeError(f"Failed to send probe message: {data}")
|
|
58
|
+
raise TimeoutError(f"No log markers detected within {timeout:.0f}s: {pattern}")
|
|
131
59
|
|
|
132
60
|
|
|
133
61
|
def _format_admin_notice(reason: str) -> str:
|
|
134
|
-
"""
|
|
62
|
+
"""Compose the notification text for administrator alerts."""
|
|
135
63
|
|
|
136
64
|
return (
|
|
137
65
|
"Master Restart health check failed\n"
|
|
@@ -141,7 +69,7 @@ def _format_admin_notice(reason: str) -> str:
|
|
|
141
69
|
|
|
142
70
|
|
|
143
71
|
def _notify_admins(reason: str) -> None:
|
|
144
|
-
"""
|
|
72
|
+
"""Broadcast the failure reason to administrators if the master token exists."""
|
|
145
73
|
|
|
146
74
|
master_token = os.environ.get("MASTER_BOT_TOKEN")
|
|
147
75
|
if not master_token:
|
|
@@ -163,58 +91,30 @@ def _notify_admins(reason: str) -> None:
|
|
|
163
91
|
continue
|
|
164
92
|
|
|
165
93
|
|
|
166
|
-
def _ensure_worker(cfg: master.ProjectConfig) -> master.MasterManager:
|
|
167
|
-
"""Starts the specified project worker and returns the temporarily constructed MasterManager."""
|
|
168
|
-
|
|
169
|
-
records = REPOSITORY.list_projects()
|
|
170
|
-
configs = [master.ProjectConfig.from_dict(record.to_dict()) for record in records]
|
|
171
|
-
state_store = master.StateStore(
|
|
172
|
-
master.STATE_PATH, {item.project_slug: item for item in configs}
|
|
173
|
-
)
|
|
174
|
-
manager = master.MasterManager(configs, state_store=state_store)
|
|
175
|
-
|
|
176
|
-
async def _run() -> None:
|
|
177
|
-
"""The coroutine performs the actual stop/start process."""
|
|
178
|
-
# Make sure to stop the old instance first(If it existsexist)
|
|
179
|
-
try:
|
|
180
|
-
await manager.stop_worker(cfg)
|
|
181
|
-
except Exception:
|
|
182
|
-
pass
|
|
183
|
-
await manager.run_worker(cfg)
|
|
184
|
-
|
|
185
|
-
asyncio.run(_run())
|
|
186
|
-
return manager
|
|
187
|
-
|
|
188
|
-
|
|
189
94
|
def main() -> int:
|
|
190
|
-
"""Command line entry,
|
|
191
|
-
|
|
192
|
-
parser = argparse.ArgumentParser(description="Master
|
|
193
|
-
parser.add_argument("--
|
|
194
|
-
parser.add_argument(
|
|
195
|
-
|
|
196
|
-
|
|
95
|
+
"""Command line entry point, only validates master readiness."""
|
|
96
|
+
|
|
97
|
+
parser = argparse.ArgumentParser(description="Master post-launch health check (master only)")
|
|
98
|
+
parser.add_argument("--master-log", default=str(DEFAULT_MASTER_LOG), help="Master log path")
|
|
99
|
+
parser.add_argument(
|
|
100
|
+
"--master-timeout",
|
|
101
|
+
type=float,
|
|
102
|
+
default=DEFAULT_TIMEOUT_MASTER,
|
|
103
|
+
help="Master log wait timeout (seconds)",
|
|
104
|
+
)
|
|
197
105
|
args = parser.parse_args()
|
|
198
106
|
|
|
199
|
-
project_id = master._sanitize_slug(args.project)
|
|
200
107
|
master_log = Path(args.master_log)
|
|
201
108
|
|
|
202
109
|
try:
|
|
203
|
-
_wait_for_log_flag(master_log,
|
|
204
|
-
cfg = _load_project(project_id)
|
|
205
|
-
manager = _ensure_worker(cfg)
|
|
206
|
-
chat_id = _ensure_chat_id(cfg, manager)
|
|
207
|
-
_send_probe(cfg.bot_token, chat_id, PROBE_TEXT, args.probe_timeout)
|
|
110
|
+
_wait_for_log_flag(master_log, MASTER_READY_MARKER, args.master_timeout)
|
|
208
111
|
except Exception as exc:
|
|
209
112
|
reason = str(exc)
|
|
210
113
|
_notify_admins(reason)
|
|
211
114
|
print(f"[healthcheck] fail: {reason}", file=sys.stderr)
|
|
212
115
|
return 1
|
|
213
116
|
else:
|
|
214
|
-
print(
|
|
215
|
-
"[healthcheck] success: master ready,"
|
|
216
|
-
f"worker={cfg.display_name} Startup completed, chat_id={chat_id}, Probe message sent"
|
|
217
|
-
)
|
|
117
|
+
print("[healthcheck] success: master ready, worker checks skipped by configuration")
|
|
218
118
|
return 0
|
|
219
119
|
|
|
220
120
|
|
scripts/start.sh
CHANGED
|
@@ -118,8 +118,9 @@ ensure_codex_installed() {
|
|
|
118
118
|
ensure_codex_installed
|
|
119
119
|
|
|
120
120
|
select_python_binary() {
|
|
121
|
-
#
|
|
121
|
+
# Select a compatible CPython version; defaults accept 3.9-3.14 and can be overridden via env variables.
|
|
122
122
|
local allow_py313="${VIBEGO_ALLOW_PY313:-}"
|
|
123
|
+
local supported_max_minor="${VIBEGO_MAX_MINOR:-14}"
|
|
123
124
|
local candidates=()
|
|
124
125
|
local chosen=""
|
|
125
126
|
local name
|
|
@@ -152,18 +153,24 @@ select_python_binary() {
|
|
|
152
153
|
if [[ -n "${VIBEGO_PYTHON:-}" && "$name" == "$VIBEGO_PYTHON" ]]; then
|
|
153
154
|
explicit_override=1
|
|
154
155
|
fi
|
|
155
|
-
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor == 13 )) &&
|
|
156
|
-
|
|
157
|
-
|
|
156
|
+
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor == 13 )) && (( explicit_override == 0 )); then
|
|
157
|
+
if [[ "$allow_py313" == "0" ]]; then
|
|
158
|
+
log_line "Skip ${name} (version ${version_raw}): disabled explicitly by VIBEGO_ALLOW_PY313=0" >&2
|
|
159
|
+
continue
|
|
160
|
+
fi
|
|
161
|
+
log_line "Detected ${name} (version ${version_raw}): Python 3.13 accepted by default; use VIBEGO_ALLOW_PY313=1 to prefer or 0 to disable" >&2
|
|
158
162
|
fi
|
|
159
|
-
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor >
|
|
160
|
-
log_line "
|
|
163
|
+
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor > supported_max_minor )) && (( explicit_override == 0 )); then
|
|
164
|
+
log_line "Skip ${name} (version ${version_raw}): above supported ceiling 3.${supported_max_minor}; override with VIBEGO_MAX_MINOR if needed" >&2
|
|
161
165
|
continue
|
|
162
166
|
fi
|
|
163
167
|
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor < 9 )); then
|
|
164
168
|
log_line "jump over ${name} (Version ${version_raw}): less than 3.9, May be missing official wheels" >&2
|
|
165
169
|
continue
|
|
166
170
|
fi
|
|
171
|
+
if [[ "$minor" =~ ^[0-9]+$ ]] && (( minor >= 14 )); then
|
|
172
|
+
log_line "Detected ${name} (version ${version_raw}): ensure dependencies support this Python version" >&2
|
|
173
|
+
fi
|
|
167
174
|
chosen="$name"
|
|
168
175
|
log_line "Using the Python interpreter:${chosen} (Version ${version_raw})" >&2
|
|
169
176
|
break
|
|
@@ -438,13 +445,13 @@ fi
|
|
|
438
445
|
log_info "master Started in background, PID=$MASTER_PID, Log writing ${LOG_FILE}"
|
|
439
446
|
|
|
440
447
|
# Health check: wait for master to come online and verify key workers
|
|
441
|
-
log_info "Start
|
|
448
|
+
log_info "Start master readiness check..."
|
|
442
449
|
HEALTHCHECK_START=$(date +%s)
|
|
443
450
|
|
|
444
|
-
if python scripts/master_healthcheck.py --
|
|
451
|
+
if python scripts/master_healthcheck.py --master-log "$LOG_FILE"; then
|
|
445
452
|
HEALTHCHECK_END=$(date +%s)
|
|
446
453
|
HEALTHCHECK_DURATION=$((HEALTHCHECK_END - HEALTHCHECK_START))
|
|
447
|
-
log_info "OK: Master
|
|
454
|
+
log_info "OK: Master readiness confirmed (elapsed ${HEALTHCHECK_DURATION}s)"
|
|
448
455
|
else
|
|
449
456
|
HEALTHCHECK_END=$(date +%s)
|
|
450
457
|
HEALTHCHECK_DURATION=$((HEALTHCHECK_END - HEALTHCHECK_START))
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
bot.py,sha256=OQj1KgrDie-8ucUdFafOxmFw2LFEElluWW6KKRy9qng,293940
|
|
2
2
|
logging_setup.py,sha256=ViXK11TNVakIbA8QMLKXa6ywpAV_j1ydcws0Hx2QqNo,5084
|
|
3
|
-
master.py,sha256=
|
|
3
|
+
master.py,sha256=7HBIVt3eTT_MDqD03nfsJZ2IkQfDpaPVL4zOTWdCKkE,132144
|
|
4
4
|
project_repository.py,sha256=fdO3xzvt7eBLvek_3mXjXkFpALwllrNWDWeSjtscW2I,17675
|
|
5
5
|
scripts/__init__.py,sha256=Sg-nUv9JfbojPpjpHlxImt6tA0p5-z1AqDA6csaFNZI,74
|
|
6
6
|
scripts/bump_version.sh,sha256=bAV-NHTSmqnjrsHjvrNTF3wS2rxhF-lZ5h5kpK2-Zyc,4462
|
|
7
7
|
scripts/log_writer.py,sha256=65HGLPREiBL1b4QRiMdxGmHfT21WBEUvg9RuCjP73Kc,3957
|
|
8
|
-
scripts/master_healthcheck.py,sha256=
|
|
8
|
+
scripts/master_healthcheck.py,sha256=7uCCuKeyE70SjzWbT_ILxng3OUY1As2A0AeyGSOcaUg,4009
|
|
9
9
|
scripts/publish.sh,sha256=e3tzRFtweJnLpJin0i43xpCWseX4jzeO2sAd2eGcTKk,3686
|
|
10
10
|
scripts/requirements.txt,sha256=ukJbFLJyzqnQYMz6j07O-IOrG87IwXg0oikmn1nfJ9M,91
|
|
11
11
|
scripts/run_bot.sh,sha256=I_b9zyIU1DicVHM8XJ-knAhJnj2pEHYOYpHjeHgZth8,5188
|
|
12
|
-
scripts/start.sh,sha256=
|
|
12
|
+
scripts/start.sh,sha256=nqJHO9iJ-OHbLMaLxAyycRT0o1rprrzSVNwQV4QEphA,16350
|
|
13
13
|
scripts/start_tmux_codex.sh,sha256=zyrLV2vzY8NTua9_d-QLq0cVMZVbMiFCZ-UM5Lwj-FU,4502
|
|
14
14
|
scripts/stop_all.sh,sha256=bvl3--jNnXLt9xUrzPqXt8SWUNLAKTELwlMArU5-8gU,4400
|
|
15
15
|
scripts/stop_bot.sh,sha256=1pI8hxQRIWJTOCLXddWMOmsnk3XIkuAlQwF9mPqRW_k,6163
|
|
@@ -426,15 +426,15 @@ tasks/constants.py,sha256=BNMxSnswF-PTij-p7paMK0G5Tj6wKN-6qpUlMwo1JQA,318
|
|
|
426
426
|
tasks/fsm.py,sha256=6n0hdFNF3j6ZUcpdJ_TwZBgkrE8aMYHNLHppdGbXGO4,1494
|
|
427
427
|
tasks/models.py,sha256=3OJL3F3nVZIQIejL6LplZkPQxYJXgOhCNA9Rikg8ihk,2461
|
|
428
428
|
tasks/service.py,sha256=rzWFcwDh58Xeek0fOABXt7oFmaOC0ubunAeGeaK1_uA,42130
|
|
429
|
-
vibego-1.0.
|
|
430
|
-
vibego_cli/__init__.py,sha256=
|
|
429
|
+
vibego-1.0.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
430
|
+
vibego_cli/__init__.py,sha256=_ZU634Qo6uVGiUlIrzAnCqpBCHB5lHIiD8XjjxnV0aY,349
|
|
431
431
|
vibego_cli/__main__.py,sha256=lM_m-i1x3yVNQhzRt8wqvuIYeeo1OlLNAEVoJVD7tmw,155
|
|
432
432
|
vibego_cli/config.py,sha256=W-n5y4CTrRpencadWlmhpdrhUHX6tdXQEGXJG1pRM0U,3149
|
|
433
433
|
vibego_cli/deps.py,sha256=nFT-DMsfAiD1lLFnDotxe6aYfeeD9V5TrIPbIbAMTF4,1478
|
|
434
434
|
vibego_cli/main.py,sha256=CZAUHWr45GzzEfALoLuSrnvG2VUuCexiFuCpIvyH8Jc,12506
|
|
435
435
|
vibego_cli/data/worker_requirements.txt,sha256=QSt30DSSSHtfucTFPpc7twk9kLS5rVLNTcvDiagxrZg,62
|
|
436
|
-
vibego-1.0.
|
|
437
|
-
vibego-1.0.
|
|
438
|
-
vibego-1.0.
|
|
439
|
-
vibego-1.0.
|
|
440
|
-
vibego-1.0.
|
|
436
|
+
vibego-1.0.5.dist-info/METADATA,sha256=C2ZQFURSlr3I99EstFokPG8quQTlKkQ7SucqugcZRs8,12584
|
|
437
|
+
vibego-1.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
438
|
+
vibego-1.0.5.dist-info/entry_points.txt,sha256=Lsy_zm-dlyxt8-9DL9blBReIwU2k22c8-kifr46ND1M,48
|
|
439
|
+
vibego-1.0.5.dist-info/top_level.txt,sha256=R56CT3nW5H5v3ce0l3QDN4-C4qxTrNWzRTwrxnkDX4U,69
|
|
440
|
+
vibego-1.0.5.dist-info/RECORD,,
|
vibego_cli/__init__.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|