yncli 1.0.4__tar.gz → 1.0.5__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.
- {yncli-1.0.4 → yncli-1.0.5}/PKG-INFO +1 -1
- {yncli-1.0.4 → yncli-1.0.5}/pyproject.toml +1 -1
- {yncli-1.0.4 → yncli-1.0.5}/setup.py +1 -1
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tui.py +13 -13
- {yncli-1.0.4 → yncli-1.0.5}/yncli/update_checker.py +27 -24
- yncli-1.0.5/yncli/version.py +1 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/PKG-INFO +1 -1
- yncli-1.0.4/yncli/version.py +0 -1
- {yncli-1.0.4 → yncli-1.0.5}/README.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/setup.cfg +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/__init__.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/agent.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/architect.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/code_review.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/debug_oracle.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/debugger.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/polyglot.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/refactor_master.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/security_auditor.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/system_architect.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/test_runner.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/built_in_skills/ultrabrain.md +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/clean_text.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/client.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/config.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/language_detector.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/main.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/skills_manager.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/system_prompt.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tools/__init__.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tools/file_tools.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tools/polyglot_tools.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tools/search_tools.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/tools/system_tools.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/workspace_memory.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli/workspace_scanner.py +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/SOURCES.txt +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/dependency_links.txt +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/entry_points.txt +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/requires.txt +0 -0
- {yncli-1.0.4 → yncli-1.0.5}/yncli.egg-info/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ long_description = (this_directory / "README.md").read_text(encoding="utf-8") if
|
|
|
6
6
|
|
|
7
7
|
setup(
|
|
8
8
|
name="yncli",
|
|
9
|
-
version="1.0.
|
|
9
|
+
version="1.0.5",
|
|
10
10
|
description="Autonomous Polyglot AI Coding Agent & TUI",
|
|
11
11
|
long_description=long_description,
|
|
12
12
|
long_description_content_type="text/markdown",
|
|
@@ -17,7 +17,7 @@ from yncli.agent import Agent
|
|
|
17
17
|
from yncli.config import save_config, CONFIG_DIR
|
|
18
18
|
from yncli.clean_text import clean_text_for_terminal
|
|
19
19
|
from yncli.version import __version__
|
|
20
|
-
from yncli.update_checker import
|
|
20
|
+
from yncli.update_checker import check_for_updates_fast
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
class TerminalUI:
|
|
@@ -69,24 +69,12 @@ class TerminalUI:
|
|
|
69
69
|
return self.session
|
|
70
70
|
|
|
71
71
|
def print_banner(self) -> None:
|
|
72
|
-
trigger_background_update_check()
|
|
73
72
|
cwd = Path(self.agent.workspace_dir).resolve()
|
|
74
73
|
folder_name = cwd.name or str(cwd)
|
|
75
74
|
cwd_str = str(cwd).replace(str(Path.home()), "~")
|
|
76
75
|
mode_title = self.agent.mode.capitalize()
|
|
77
76
|
mode_color = "#38bdf8" if self.agent.mode == "plan" else ("#10b981" if self.agent.mode == "build" else "#f59e0b")
|
|
78
77
|
|
|
79
|
-
# Check for available update
|
|
80
|
-
update_info = get_cached_update()
|
|
81
|
-
if update_info:
|
|
82
|
-
update_panel = Panel(
|
|
83
|
-
f"[bold yellow]🔔 Update Tersedia:[/] [dim]v{update_info['current']}[/] → [bold green]v{update_info['latest']}[/]\n"
|
|
84
|
-
f"[dim]Perbarui sekarang:[reset] [cyan]pip install -U yncli[/cyan] [dim]atau[/dim] [cyan]npm i -g @yanzyuyu/yncli[/cyan]",
|
|
85
|
-
border_style="yellow",
|
|
86
|
-
padding=(0, 2)
|
|
87
|
-
)
|
|
88
|
-
self.console.print(update_panel)
|
|
89
|
-
|
|
90
78
|
# Top pill badge
|
|
91
79
|
self.console.print()
|
|
92
80
|
pill = Text()
|
|
@@ -115,6 +103,18 @@ class TerminalUI:
|
|
|
115
103
|
|
|
116
104
|
cols = Columns([logo, info], padding=(0, 3))
|
|
117
105
|
self.console.print(cols)
|
|
106
|
+
|
|
107
|
+
# Check for available update (Fast check & cache)
|
|
108
|
+
update_info = check_for_updates_fast(timeout_sec=0.8)
|
|
109
|
+
if update_info:
|
|
110
|
+
update_panel = Panel(
|
|
111
|
+
f"[bold yellow]🔔 Update Tersedia:[/] [dim]v{update_info['current']}[/] → [bold green]v{update_info['latest']}[/]\n"
|
|
112
|
+
f"[dim]Perbarui sekarang:[reset] [cyan]pip install -U yncli[/cyan] [dim]atau[/dim] [cyan]npm i -g @yanzyuyu/yncli[/cyan]",
|
|
113
|
+
border_style="yellow",
|
|
114
|
+
padding=(0, 2)
|
|
115
|
+
)
|
|
116
|
+
self.console.print(update_panel)
|
|
117
|
+
|
|
118
118
|
self.console.print("─" * 60, style="dim #334155")
|
|
119
119
|
|
|
120
120
|
loaded_count = len(self.agent.workspace_memory.indexed_files)
|
|
@@ -8,7 +8,7 @@ from yncli.version import __version__
|
|
|
8
8
|
from yncli.config import CONFIG_DIR
|
|
9
9
|
|
|
10
10
|
CACHE_FILE = CONFIG_DIR / "update_cache.json"
|
|
11
|
-
CHECK_INTERVAL_SECONDS =
|
|
11
|
+
CHECK_INTERVAL_SECONDS = 2 * 3600 # 2 hours
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def parse_version_tuple(v: str):
|
|
@@ -20,10 +20,10 @@ def parse_version_tuple(v: str):
|
|
|
20
20
|
return (0, 0, 0)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def _fetch_latest_version_pypi() -> Optional[str]:
|
|
23
|
+
def _fetch_latest_version_pypi(timeout_sec: float = 1.0) -> Optional[str]:
|
|
24
24
|
try:
|
|
25
25
|
import requests
|
|
26
|
-
resp = requests.get("https://pypi.org/pypi/yncli/json", timeout=
|
|
26
|
+
resp = requests.get("https://pypi.org/pypi/yncli/json", timeout=timeout_sec)
|
|
27
27
|
if resp.status_code == 200:
|
|
28
28
|
data = resp.json()
|
|
29
29
|
return data.get("info", {}).get("version")
|
|
@@ -51,33 +51,36 @@ def get_cached_update() -> Optional[Dict[str, Any]]:
|
|
|
51
51
|
return None
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
def
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
last_checked = 0
|
|
60
|
-
if CACHE_FILE.exists():
|
|
61
|
-
try:
|
|
62
|
-
data = json.loads(CACHE_FILE.read_text(encoding="utf-8"))
|
|
63
|
-
last_checked = data.get("last_checked", 0)
|
|
64
|
-
except Exception:
|
|
65
|
-
pass
|
|
54
|
+
def check_for_updates_fast(timeout_sec: float = 1.0) -> Optional[Dict[str, Any]]:
|
|
55
|
+
"""Checks cache first, and if not cached or expired, queries PyPI quickly."""
|
|
56
|
+
cached = get_cached_update()
|
|
57
|
+
if cached:
|
|
58
|
+
return cached
|
|
66
59
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
try:
|
|
61
|
+
now = time.time()
|
|
62
|
+
last_checked = 0
|
|
63
|
+
if CACHE_FILE.exists():
|
|
64
|
+
try:
|
|
65
|
+
data = json.loads(CACHE_FILE.read_text(encoding="utf-8"))
|
|
66
|
+
last_checked = data.get("last_checked", 0)
|
|
67
|
+
except Exception:
|
|
68
|
+
pass
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
if (now - last_checked) > CHECK_INTERVAL_SECONDS:
|
|
71
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
72
|
+
latest = _fetch_latest_version_pypi(timeout_sec=timeout_sec)
|
|
73
73
|
if latest:
|
|
74
74
|
cache_data = {
|
|
75
75
|
"last_checked": now,
|
|
76
76
|
"latest_version": latest
|
|
77
77
|
}
|
|
78
78
|
CACHE_FILE.write_text(json.dumps(cache_data, indent=2), encoding="utf-8")
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
curr_tuple = parse_version_tuple(__version__)
|
|
80
|
+
latest_tuple = parse_version_tuple(latest)
|
|
81
|
+
if latest_tuple > curr_tuple:
|
|
82
|
+
return {"current": __version__, "latest": latest}
|
|
83
|
+
except Exception:
|
|
84
|
+
pass
|
|
81
85
|
|
|
82
|
-
|
|
83
|
-
t.start()
|
|
86
|
+
return None
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.0.5"
|
yncli-1.0.4/yncli/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.0.4"
|
|
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
|