@agentunion/kite 1.2.0 → 1.3.1
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/CHANGELOG.md +208 -0
- package/README.md +48 -0
- package/cli.js +1 -1
- package/extensions/agents/assistant/entry.py +30 -81
- package/extensions/agents/assistant/module.md +1 -1
- package/extensions/agents/assistant/server.py +83 -122
- package/extensions/channels/acp_channel/entry.py +30 -81
- package/extensions/channels/acp_channel/module.md +1 -1
- package/extensions/channels/acp_channel/server.py +83 -122
- package/extensions/event_hub_bench/entry.py +81 -121
- package/extensions/services/backup/entry.py +213 -85
- package/extensions/services/model_service/entry.py +213 -85
- package/extensions/services/watchdog/entry.py +513 -460
- package/extensions/services/watchdog/monitor.py +55 -69
- package/extensions/services/web/entry.py +11 -108
- package/extensions/services/web/server.py +120 -77
- package/{core/registry → kernel}/entry.py +65 -37
- package/{core/event_hub/hub.py → kernel/event_hub.py} +61 -81
- package/kernel/module.md +33 -0
- package/{core/registry/store.py → kernel/registry_store.py} +13 -4
- package/kernel/rpc_router.py +388 -0
- package/kernel/server.py +267 -0
- package/launcher/__init__.py +10 -0
- package/launcher/__main__.py +6 -0
- package/launcher/count_lines.py +258 -0
- package/{core/launcher → launcher}/entry.py +693 -767
- package/launcher/logging_setup.py +289 -0
- package/{core/launcher → launcher}/module_scanner.py +11 -6
- package/main.py +11 -350
- package/package.json +6 -9
- package/__init__.py +0 -1
- package/__main__.py +0 -15
- package/core/event_hub/BENCHMARK.md +0 -94
- package/core/event_hub/__init__.py +0 -0
- package/core/event_hub/bench.py +0 -459
- package/core/event_hub/bench_extreme.py +0 -308
- package/core/event_hub/bench_perf.py +0 -350
- package/core/event_hub/entry.py +0 -436
- package/core/event_hub/module.md +0 -20
- package/core/event_hub/server.py +0 -269
- package/core/kite_log.py +0 -241
- package/core/launcher/__init__.py +0 -0
- package/core/registry/__init__.py +0 -0
- package/core/registry/module.md +0 -30
- package/core/registry/server.py +0 -339
- package/extensions/services/backup/server.py +0 -244
- package/extensions/services/model_service/server.py +0 -236
- package/extensions/services/watchdog/server.py +0 -229
- /package/{core → kernel}/__init__.py +0 -0
- /package/{core/event_hub → kernel}/dedup.py +0 -0
- /package/{core/event_hub → kernel}/router.py +0 -0
- /package/{core/launcher → launcher}/module.md +0 -0
- /package/{core/launcher → launcher}/process_manager.py +0 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
代码行数统计工具
|
|
4
|
+
统计 Kite 项目的代码行数并记录到 JSONL 文件
|
|
5
|
+
"""
|
|
6
|
+
import json
|
|
7
|
+
import sys
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Enable ANSI colors on Windows
|
|
12
|
+
if sys.platform == "win32":
|
|
13
|
+
try:
|
|
14
|
+
import ctypes
|
|
15
|
+
kernel32 = ctypes.windll.kernel32
|
|
16
|
+
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
17
|
+
except Exception:
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def count_lines_in_file(file_path: Path) -> int:
|
|
22
|
+
"""统计单个文件的行数"""
|
|
23
|
+
try:
|
|
24
|
+
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
|
|
25
|
+
return sum(1 for _ in f)
|
|
26
|
+
except Exception:
|
|
27
|
+
return 0
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def count_lines(root_dir: Path, pattern: str, exclude_dirs: set[str]) -> int:
|
|
31
|
+
"""统计指定模式的文件行数"""
|
|
32
|
+
total = 0
|
|
33
|
+
for file_path in root_dir.rglob(pattern):
|
|
34
|
+
# 检查是否在排除目录中
|
|
35
|
+
if any(excluded in file_path.parts for excluded in exclude_dirs):
|
|
36
|
+
continue
|
|
37
|
+
total += count_lines_in_file(file_path)
|
|
38
|
+
return total
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def count_all(root_dir: Path) -> dict:
|
|
42
|
+
"""统计所有类型的代码行数"""
|
|
43
|
+
stats = {}
|
|
44
|
+
|
|
45
|
+
# 排除的目录
|
|
46
|
+
exclude_dirs = {
|
|
47
|
+
"__pycache__",
|
|
48
|
+
"node_modules",
|
|
49
|
+
".git",
|
|
50
|
+
".venv",
|
|
51
|
+
"venv",
|
|
52
|
+
".idea",
|
|
53
|
+
".vscode",
|
|
54
|
+
".dev", # 开发相关(变更日志、发布备份)
|
|
55
|
+
".claude", # Claude 工作目录
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# Python 代码
|
|
59
|
+
stats["python"] = count_lines(root_dir, "*.py", exclude_dirs)
|
|
60
|
+
|
|
61
|
+
# JavaScript 代码
|
|
62
|
+
stats["javascript"] = count_lines(root_dir, "*.js", exclude_dirs)
|
|
63
|
+
|
|
64
|
+
# Markdown 文档
|
|
65
|
+
stats["markdown"] = count_lines(root_dir, "*.md", exclude_dirs)
|
|
66
|
+
|
|
67
|
+
# YAML 配置
|
|
68
|
+
stats["yaml"] = count_lines(root_dir, "*.yaml", exclude_dirs) + \
|
|
69
|
+
count_lines(root_dir, "*.yml", exclude_dirs)
|
|
70
|
+
|
|
71
|
+
# JSON 配置(排除 package-lock.json)
|
|
72
|
+
json_total = 0
|
|
73
|
+
for file_path in root_dir.rglob("*.json"):
|
|
74
|
+
if any(excluded in file_path.parts for excluded in exclude_dirs):
|
|
75
|
+
continue
|
|
76
|
+
if file_path.name == "package-lock.json":
|
|
77
|
+
continue
|
|
78
|
+
json_total += count_lines_in_file(file_path)
|
|
79
|
+
stats["json"] = json_total
|
|
80
|
+
|
|
81
|
+
# 总计
|
|
82
|
+
stats["total"] = sum(stats.values())
|
|
83
|
+
|
|
84
|
+
return stats
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def save_record(stats: dict, record_file: Path):
|
|
88
|
+
"""保存统计记录到 JSONL 文件(仅在有变化时)"""
|
|
89
|
+
# 读取最后一条记录
|
|
90
|
+
last_stats = None
|
|
91
|
+
if record_file.exists():
|
|
92
|
+
try:
|
|
93
|
+
with open(record_file, "r", encoding="utf-8") as f:
|
|
94
|
+
lines = f.readlines()
|
|
95
|
+
if lines:
|
|
96
|
+
last_record = json.loads(lines[-1])
|
|
97
|
+
last_stats = last_record.get("stats")
|
|
98
|
+
except (json.JSONDecodeError, IndexError):
|
|
99
|
+
pass
|
|
100
|
+
|
|
101
|
+
# 如果统计结果与上次完全相同,跳过保存
|
|
102
|
+
if last_stats == stats:
|
|
103
|
+
return
|
|
104
|
+
|
|
105
|
+
record = {
|
|
106
|
+
"timestamp": datetime.now().isoformat(),
|
|
107
|
+
"stats": stats,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# 追加到 JSONL 文件
|
|
111
|
+
record_file.parent.mkdir(parents=True, exist_ok=True)
|
|
112
|
+
with open(record_file, "a", encoding="utf-8") as f:
|
|
113
|
+
f.write(json.dumps(record, ensure_ascii=False) + "\n")
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def print_stats(stats: dict):
|
|
117
|
+
"""打印统计结果"""
|
|
118
|
+
# ANSI 颜色代码
|
|
119
|
+
BOLD = "\033[1m"
|
|
120
|
+
RESET = "\033[0m"
|
|
121
|
+
|
|
122
|
+
print("\n" + "=" * 50)
|
|
123
|
+
print("Kite 项目代码统计")
|
|
124
|
+
print("=" * 50)
|
|
125
|
+
print(f"Python 代码: {BOLD}{stats['python']:>8,} 行{RESET}")
|
|
126
|
+
print(f"JavaScript 代码: {BOLD}{stats['javascript']:>8,} 行{RESET}")
|
|
127
|
+
print(f"Markdown 文档: {BOLD}{stats['markdown']:>8,} 行{RESET}")
|
|
128
|
+
print(f"YAML 配置: {BOLD}{stats['yaml']:>8,} 行{RESET}")
|
|
129
|
+
print(f"JSON 配置: {BOLD}{stats['json']:>8,} 行{RESET}")
|
|
130
|
+
print("-" * 50)
|
|
131
|
+
print(f"总计: {BOLD}{stats['total']:>8,} 行{RESET}")
|
|
132
|
+
print("=" * 50 + "\n")
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def show_history(record_file: Path, limit: int = 10):
|
|
136
|
+
"""显示历史记录"""
|
|
137
|
+
# ANSI 颜色代码
|
|
138
|
+
GREEN = "\033[32m"
|
|
139
|
+
RED = "\033[31m"
|
|
140
|
+
BOLD = "\033[1m"
|
|
141
|
+
RESET = "\033[0m"
|
|
142
|
+
|
|
143
|
+
if not record_file.exists():
|
|
144
|
+
print("暂无历史记录")
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
records = []
|
|
148
|
+
with open(record_file, "r", encoding="utf-8") as f:
|
|
149
|
+
for line in f:
|
|
150
|
+
try:
|
|
151
|
+
records.append(json.loads(line))
|
|
152
|
+
except json.JSONDecodeError:
|
|
153
|
+
continue
|
|
154
|
+
|
|
155
|
+
if not records:
|
|
156
|
+
print("暂无历史记录")
|
|
157
|
+
return
|
|
158
|
+
|
|
159
|
+
print("\n" + "=" * 80)
|
|
160
|
+
print("历史记录(最近 {} 次)".format(min(limit, len(records))))
|
|
161
|
+
print("=" * 80)
|
|
162
|
+
print(f"{'时间':<25} {'Python':>10} {'JS':>10} {'MD':>10} {'总计':>10} {'变化':>10}")
|
|
163
|
+
print("-" * 80)
|
|
164
|
+
|
|
165
|
+
recent = records[-limit:]
|
|
166
|
+
for i, record in enumerate(recent):
|
|
167
|
+
ts = record["timestamp"][:19].replace("T", " ")
|
|
168
|
+
stats = record["stats"]
|
|
169
|
+
|
|
170
|
+
# 计算与上一次的变化
|
|
171
|
+
if i > 0:
|
|
172
|
+
prev_total = recent[i-1]["stats"]["total"]
|
|
173
|
+
diff = stats["total"] - prev_total
|
|
174
|
+
if diff > 0:
|
|
175
|
+
diff_str = f"{GREEN}+{diff:,}{RESET}"
|
|
176
|
+
elif diff < 0:
|
|
177
|
+
diff_str = f"{RED}{diff:,}{RESET}"
|
|
178
|
+
else:
|
|
179
|
+
diff_str = "0"
|
|
180
|
+
else:
|
|
181
|
+
diff_str = "-"
|
|
182
|
+
|
|
183
|
+
print(f"{ts:<25} {stats['python']:>10,} {stats['javascript']:>10,} "
|
|
184
|
+
f"{stats['markdown']:>10,} {BOLD}{stats['total']:>10,}{RESET} {diff_str:>10}")
|
|
185
|
+
|
|
186
|
+
print("=" * 80 + "\n")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def run_stats():
|
|
190
|
+
"""Run code stats from main.py entry point (simplified output)."""
|
|
191
|
+
script_dir = Path(__file__).parent
|
|
192
|
+
root_dir = script_dir.parent
|
|
193
|
+
record_file = root_dir / "data" / "stats" / "lines.jsonl"
|
|
194
|
+
|
|
195
|
+
print("[launcher] 正在统计代码行数...")
|
|
196
|
+
try:
|
|
197
|
+
stats = count_all(root_dir)
|
|
198
|
+
save_record(stats, record_file)
|
|
199
|
+
|
|
200
|
+
# Print stats
|
|
201
|
+
BRIGHT_GREEN = "\033[92m"
|
|
202
|
+
BOLD = "\033[1m"
|
|
203
|
+
RESET = "\033[0m"
|
|
204
|
+
|
|
205
|
+
print("")
|
|
206
|
+
print("=" * 50)
|
|
207
|
+
print("Kite 项目代码统计")
|
|
208
|
+
print("=" * 50)
|
|
209
|
+
print(f"Python 代码: {BRIGHT_GREEN}{stats['python']:>8,}{RESET} 行")
|
|
210
|
+
print(f"JavaScript 代码: {BRIGHT_GREEN}{stats['javascript']:>8,}{RESET} 行")
|
|
211
|
+
print(f"Markdown 文档: {BRIGHT_GREEN}{stats['markdown']:>8,}{RESET} 行")
|
|
212
|
+
print(f"YAML 配置: {BRIGHT_GREEN}{stats['yaml']:>8,}{RESET} 行")
|
|
213
|
+
print(f"JSON 配置: {BRIGHT_GREEN}{stats['json']:>8,}{RESET} 行")
|
|
214
|
+
print("-" * 50)
|
|
215
|
+
print(f"总计: {BOLD}{BRIGHT_GREEN}{stats['total']:>8,}{RESET} 行")
|
|
216
|
+
print("=" * 50)
|
|
217
|
+
print("")
|
|
218
|
+
|
|
219
|
+
# Show history trend (last 8 records)
|
|
220
|
+
show_history(record_file, limit=8)
|
|
221
|
+
except Exception as e:
|
|
222
|
+
print(f"[launcher] 统计异常: {e}")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def main():
|
|
226
|
+
# 获取项目根目录
|
|
227
|
+
script_dir = Path(__file__).parent
|
|
228
|
+
root_dir = script_dir.parent
|
|
229
|
+
|
|
230
|
+
# 记录文件路径
|
|
231
|
+
record_file = root_dir / "data" / "stats" / "lines.jsonl"
|
|
232
|
+
|
|
233
|
+
# 解析命令行参数
|
|
234
|
+
show_hist = "--history" in sys.argv or "-h" in sys.argv
|
|
235
|
+
quiet = "--quiet" in sys.argv or "-q" in sys.argv
|
|
236
|
+
|
|
237
|
+
if show_hist:
|
|
238
|
+
# 只显示历史记录
|
|
239
|
+
show_history(record_file)
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
# 统计代码行数
|
|
243
|
+
if not quiet:
|
|
244
|
+
print("正在统计代码行数...")
|
|
245
|
+
stats = count_all(root_dir)
|
|
246
|
+
|
|
247
|
+
# 保存记录
|
|
248
|
+
save_record(stats, record_file)
|
|
249
|
+
|
|
250
|
+
# 打印结果
|
|
251
|
+
if not quiet:
|
|
252
|
+
print_stats(stats)
|
|
253
|
+
# 显示最近 8 次记录
|
|
254
|
+
show_history(record_file, limit=8)
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
main()
|