@agentunion/kite 1.6.1 → 1.6.3
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.
- package/cli.js +3 -2
- package/kite_cli/commands/install_skill.py +3 -1
- package/launcher/entry.py +25 -1
- package/main.py +99 -3
- package/package.json +1 -1
package/cli.js
CHANGED
|
@@ -69,7 +69,7 @@ for (let i = 0; i < args.length; i++) {
|
|
|
69
69
|
const versionDir = path.join(kiteHome, 'versions', useVersion);
|
|
70
70
|
|
|
71
71
|
// Check if first arg is a CLI command or help/version flag
|
|
72
|
-
const cliCommands = ['install', 'uninstall', 'update', 'list', 'search', 'info', 'log', 'rollback', 'clean', 'doctor', 'history'];
|
|
72
|
+
const cliCommands = ['install', 'uninstall', 'update', 'list', 'search', 'info', 'log', 'rollback', 'clean', 'doctor', 'history', 'install-skill'];
|
|
73
73
|
const helpFlags = ['-h', '-H', '--help', 'help'];
|
|
74
74
|
const versionFlags = ['-v', '-V', '--version', 'version'];
|
|
75
75
|
|
|
@@ -136,7 +136,8 @@ if (args[0] === 'start') {
|
|
|
136
136
|
...process.env,
|
|
137
137
|
KITE_PROJECT: cliWorkDir,
|
|
138
138
|
KITE_MODULES: modulesDir,
|
|
139
|
-
KITE_DATA: dataDir
|
|
139
|
+
KITE_DATA: dataDir,
|
|
140
|
+
KITE_CALLER_DIR: process.cwd()
|
|
140
141
|
}
|
|
141
142
|
});
|
|
142
143
|
result.on('exit', code => process.exit(code ?? 0));
|
|
@@ -32,7 +32,9 @@ def get_user_skill_dir():
|
|
|
32
32
|
|
|
33
33
|
def get_project_skill_dir():
|
|
34
34
|
"""获取项目级 skill 目录"""
|
|
35
|
-
cwd
|
|
35
|
+
# cli.js 会把 cwd 改成包目录,用 KITE_CALLER_DIR 获取用户的实际目录
|
|
36
|
+
caller_dir = os.environ.get("KITE_CALLER_DIR", "")
|
|
37
|
+
cwd = Path(caller_dir) if caller_dir else Path.cwd()
|
|
36
38
|
return cwd / ".claude" / "skills" / "kite"
|
|
37
39
|
|
|
38
40
|
|
package/launcher/entry.py
CHANGED
|
@@ -907,7 +907,24 @@ class Launcher:
|
|
|
907
907
|
print(f"\033[33m[launcher] 提示: 已连续 {attempt} 次无法连接 Kernel (端口 {self.kernel_port})")
|
|
908
908
|
if self.kernel_port < 1024:
|
|
909
909
|
print(f"[launcher] ⚠ 端口 {self.kernel_port} 异常偏低,可能是 Kernel 端口绑定失败或配置错误")
|
|
910
|
-
print(f"[launcher] 请检查: 1) Kernel 进程是否存活 2) kernel/module.md 中 preferred_port
|
|
910
|
+
print(f"[launcher] 请检查: 1) Kernel 进程是否存活 2) kernel/module.md 中 preferred_port 配置是否正确")
|
|
911
|
+
# Check if Kernel crashed due to missing dependencies
|
|
912
|
+
crash_log = os.path.join(os.environ.get("KITE_INSTANCE_DIR", ""), "kernel", "log", "crashes.jsonl")
|
|
913
|
+
if os.path.exists(crash_log):
|
|
914
|
+
try:
|
|
915
|
+
with open(crash_log, "r", encoding="utf-8") as f:
|
|
916
|
+
last_line = None
|
|
917
|
+
for line in f:
|
|
918
|
+
last_line = line
|
|
919
|
+
if last_line:
|
|
920
|
+
crash = json.loads(last_line)
|
|
921
|
+
if "ModuleNotFoundError" in crash.get("error_type", ""):
|
|
922
|
+
print(f"[launcher] ⚠ 检测到依赖缺失: {crash.get('error_type', '')}")
|
|
923
|
+
print(f"[launcher] 提示: 直接运行 'python3 main.py' 会跳过依赖检查")
|
|
924
|
+
print(f"[launcher] 请使用 'kite start' 或手动安装依赖: pip3 install uvicorn fastapi httpx json5")
|
|
925
|
+
except Exception:
|
|
926
|
+
pass
|
|
927
|
+
print("\033[0m")
|
|
911
928
|
self._ws = None
|
|
912
929
|
if self._thread_shutdown.is_set():
|
|
913
930
|
return
|
|
@@ -4486,6 +4503,13 @@ def start_launcher():
|
|
|
4486
4503
|
|
|
4487
4504
|
print("[launcher] Kite 启动中...")
|
|
4488
4505
|
|
|
4506
|
+
# Print OS info
|
|
4507
|
+
import platform
|
|
4508
|
+
os_name = platform.system()
|
|
4509
|
+
os_version = platform.release()
|
|
4510
|
+
os_arch = platform.machine()
|
|
4511
|
+
print(f"[launcher] 操作系统: {os_name} {os_version} ({os_arch})")
|
|
4512
|
+
|
|
4489
4513
|
# Create and run launcher
|
|
4490
4514
|
token = secrets.token_hex(32)
|
|
4491
4515
|
launcher = Launcher(kite_token=token)
|
package/main.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Kite development entry point.
|
|
3
|
-
1.
|
|
4
|
-
2.
|
|
3
|
+
1. Check dependencies (if bypassing cli.js)
|
|
4
|
+
2. Run code stats
|
|
5
|
+
3. Start launcher
|
|
5
6
|
|
|
6
|
-
注意:环境检查已在 Node.js 层(cli.js
|
|
7
|
+
注意:环境检查已在 Node.js 层(cli.js)完成,但直接运行 python3 main.py 会绕过检查
|
|
7
8
|
"""
|
|
8
9
|
import sys
|
|
9
10
|
from pathlib import Path
|
|
@@ -18,6 +19,101 @@ if "--stop" in sys.argv:
|
|
|
18
19
|
stop_instances()
|
|
19
20
|
sys.exit(0)
|
|
20
21
|
|
|
22
|
+
# --daemon / -d: 后台运行模式,脱离终端,关闭终端不影响进程
|
|
23
|
+
if "--daemon" in sys.argv or "-d" in sys.argv:
|
|
24
|
+
import os
|
|
25
|
+
import subprocess
|
|
26
|
+
|
|
27
|
+
# 构建子进程参数:去掉 --daemon / -d,其余保留
|
|
28
|
+
child_args = [sys.executable, os.path.abspath(__file__)]
|
|
29
|
+
for arg in sys.argv[1:]:
|
|
30
|
+
if arg not in ("--daemon", "-d"):
|
|
31
|
+
child_args.append(arg)
|
|
32
|
+
|
|
33
|
+
# 日志输出到实例目录(复用 start_launcher 的路径逻辑)
|
|
34
|
+
home = os.environ.get("HOME") or os.environ.get("USERPROFILE") or os.path.expanduser("~")
|
|
35
|
+
workspace = os.environ.get("KITE_WORKSPACE") or os.path.join(home, ".kite", "workspace")
|
|
36
|
+
basename = os.path.basename(os.getcwd().rstrip(os.sep)) or "default"
|
|
37
|
+
instance_dir = os.path.join(workspace, basename)
|
|
38
|
+
log_dir = os.path.join(instance_dir, "launcher", "log")
|
|
39
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
40
|
+
daemon_log = os.path.join(log_dir, "daemon.log")
|
|
41
|
+
|
|
42
|
+
log_fd = open(daemon_log, "w", encoding="utf-8")
|
|
43
|
+
|
|
44
|
+
kwargs = {
|
|
45
|
+
"stdout": log_fd,
|
|
46
|
+
"stderr": log_fd,
|
|
47
|
+
"stdin": subprocess.DEVNULL,
|
|
48
|
+
"cwd": os.getcwd(),
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if sys.platform == "win32":
|
|
52
|
+
# Windows: 脱离控制台,创建新进程组
|
|
53
|
+
CREATE_NEW_PROCESS_GROUP = 0x00000200
|
|
54
|
+
CREATE_NO_WINDOW = 0x08000000
|
|
55
|
+
kwargs["creationflags"] = CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW
|
|
56
|
+
else:
|
|
57
|
+
# Linux / macOS: 新会话,脱离终端
|
|
58
|
+
kwargs["start_new_session"] = True
|
|
59
|
+
|
|
60
|
+
proc = subprocess.Popen(child_args, **kwargs)
|
|
61
|
+
print(f"[Kite] 后台启动成功 (PID: {proc.pid})")
|
|
62
|
+
print(f"[Kite] 日志: {daemon_log}")
|
|
63
|
+
print(f"[Kite] 停止: python main.py --stop")
|
|
64
|
+
sys.exit(0)
|
|
65
|
+
|
|
66
|
+
# --no-tls: 禁用 TLS 要求(本地开发用)
|
|
67
|
+
if "--no-tls" in sys.argv:
|
|
68
|
+
import os
|
|
69
|
+
os.environ["KITE_REQUIRE_TLS"] = "false"
|
|
70
|
+
sys.argv.remove("--no-tls")
|
|
71
|
+
|
|
72
|
+
# 0. Check critical dependencies (only if bypassing cli.js)
|
|
73
|
+
def check_critical_deps():
|
|
74
|
+
"""检查关键依赖,如果缺失则自动安装"""
|
|
75
|
+
missing = []
|
|
76
|
+
try:
|
|
77
|
+
import uvicorn
|
|
78
|
+
except ImportError:
|
|
79
|
+
missing.append("uvicorn")
|
|
80
|
+
try:
|
|
81
|
+
import fastapi
|
|
82
|
+
except ImportError:
|
|
83
|
+
missing.append("fastapi")
|
|
84
|
+
try:
|
|
85
|
+
import httpx
|
|
86
|
+
except ImportError:
|
|
87
|
+
missing.append("httpx")
|
|
88
|
+
try:
|
|
89
|
+
import json5
|
|
90
|
+
except ImportError:
|
|
91
|
+
missing.append("json5")
|
|
92
|
+
|
|
93
|
+
if missing:
|
|
94
|
+
print("\033[93m[Kite] 检测到缺少关键依赖库:\033[0m")
|
|
95
|
+
for pkg in missing:
|
|
96
|
+
print(f" - {pkg}")
|
|
97
|
+
print()
|
|
98
|
+
print("\033[96m[Kite] 正在自动安装依赖...\033[0m")
|
|
99
|
+
|
|
100
|
+
import subprocess
|
|
101
|
+
try:
|
|
102
|
+
subprocess.check_call(
|
|
103
|
+
[sys.executable, "-m", "pip", "install"] + missing,
|
|
104
|
+
stdout=subprocess.DEVNULL,
|
|
105
|
+
stderr=subprocess.PIPE
|
|
106
|
+
)
|
|
107
|
+
print("\033[92m[Kite] 依赖安装成功\033[0m")
|
|
108
|
+
print()
|
|
109
|
+
except subprocess.CalledProcessError as e:
|
|
110
|
+
print("\033[91m[Kite] 依赖安装失败\033[0m")
|
|
111
|
+
print(f"\033[93m请手动安装: pip3 install {' '.join(missing)}\033[0m")
|
|
112
|
+
print()
|
|
113
|
+
sys.exit(1)
|
|
114
|
+
|
|
115
|
+
check_critical_deps()
|
|
116
|
+
|
|
21
117
|
# 1. Run code stats
|
|
22
118
|
from launcher.count_lines import run_stats
|
|
23
119
|
run_stats()
|