@agentunion/kite 1.2.0 → 1.3.0

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +208 -0
  2. package/README.md +48 -0
  3. package/cli.js +1 -1
  4. package/extensions/agents/assistant/entry.py +30 -81
  5. package/extensions/agents/assistant/module.md +1 -1
  6. package/extensions/agents/assistant/server.py +83 -122
  7. package/extensions/channels/acp_channel/entry.py +30 -81
  8. package/extensions/channels/acp_channel/module.md +1 -1
  9. package/extensions/channels/acp_channel/server.py +83 -122
  10. package/extensions/event_hub_bench/entry.py +81 -121
  11. package/extensions/services/backup/entry.py +213 -85
  12. package/extensions/services/model_service/entry.py +213 -85
  13. package/extensions/services/watchdog/entry.py +513 -460
  14. package/extensions/services/watchdog/monitor.py +55 -69
  15. package/extensions/services/web/entry.py +11 -108
  16. package/extensions/services/web/server.py +120 -77
  17. package/{core/registry → kernel}/entry.py +65 -37
  18. package/{core/event_hub/hub.py → kernel/event_hub.py} +61 -81
  19. package/kernel/module.md +33 -0
  20. package/{core/registry/store.py → kernel/registry_store.py} +13 -4
  21. package/kernel/rpc_router.py +388 -0
  22. package/kernel/server.py +267 -0
  23. package/launcher/__init__.py +10 -0
  24. package/launcher/__main__.py +6 -0
  25. package/launcher/count_lines.py +258 -0
  26. package/{core/launcher → launcher}/entry.py +693 -767
  27. package/launcher/logging_setup.py +289 -0
  28. package/{core/launcher → launcher}/module_scanner.py +11 -6
  29. package/main.py +11 -350
  30. package/package.json +6 -9
  31. package/__init__.py +0 -1
  32. package/__main__.py +0 -15
  33. package/core/event_hub/BENCHMARK.md +0 -94
  34. package/core/event_hub/__init__.py +0 -0
  35. package/core/event_hub/bench.py +0 -459
  36. package/core/event_hub/bench_extreme.py +0 -308
  37. package/core/event_hub/bench_perf.py +0 -350
  38. package/core/event_hub/entry.py +0 -436
  39. package/core/event_hub/module.md +0 -20
  40. package/core/event_hub/server.py +0 -269
  41. package/core/kite_log.py +0 -241
  42. package/core/launcher/__init__.py +0 -0
  43. package/core/registry/__init__.py +0 -0
  44. package/core/registry/module.md +0 -30
  45. package/core/registry/server.py +0 -339
  46. package/extensions/services/backup/server.py +0 -244
  47. package/extensions/services/model_service/server.py +0 -236
  48. package/extensions/services/watchdog/server.py +0 -229
  49. /package/{core → kernel}/__init__.py +0 -0
  50. /package/{core/event_hub → kernel}/dedup.py +0 -0
  51. /package/{core/event_hub → kernel}/router.py +0 -0
  52. /package/{core/launcher → launcher}/module.md +0 -0
  53. /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()