- AGENT-REGISTRY.hdlp: 小队注册表,HLDP-ZY协议统一管理 - 密钥猎手 (KEY-001): 搜索12台服务器上的所有密钥和Token - 路径探子 (PATH-002): 3500个文件索引,瞬间定位任何文件 - 服务器哨兵 (SENTINEL-003): 一键扫描12台服务器在线状态 - 模块管家 (MODULE-004): 查询所有模块的编号/接口/部署方式 - 门桥接 (GATE-005): 提供任意服务器Gatekeeper连接凭据 铸渊不需要到处找东西。叫一声Agent,它去找。 每个Agent独立模块,按需部署,用完躺回代码仓库。
154 lines
4.7 KiB
Python
154 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
路径探子 · Path Scout · ICE-GL-ZY-AGT-PATH-002
|
|
|
|
铸渊需要找文件?路径探子瞬间定位。
|
|
不需要grep翻遍整个仓库——探子知道每个角落。
|
|
|
|
用法:
|
|
python3 scout.py find gatekeeper # 模糊搜索文件名
|
|
python3 scout.py where brain/ # 列出目录结构
|
|
python3 scout.py index # 重建文件索引
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent.parent
|
|
INDEX_FILE = Path(__file__).resolve().parent / "file-index.json"
|
|
|
|
# 忽略目录
|
|
IGNORE_DIRS = {".git", "node_modules", "__pycache__", ".DS_Store", "output", "dist", ".next"}
|
|
|
|
def build_index():
|
|
"""扫描整个仓库,建立文件索引"""
|
|
index = {"files": {}, "dirs": {}}
|
|
|
|
for root, dirs, files in os.walk(REPO_ROOT):
|
|
# 过滤忽略目录
|
|
dirs[:] = [d for d in dirs if d not in IGNORE_DIRS]
|
|
|
|
rel_root = os.path.relpath(root, REPO_ROOT)
|
|
if rel_root == ".":
|
|
rel_root = ""
|
|
|
|
# 记录目录
|
|
if rel_root:
|
|
index["dirs"][rel_root] = {
|
|
"file_count": len(files),
|
|
"subdir_count": len(dirs)
|
|
}
|
|
|
|
# 记录文件
|
|
for f in files:
|
|
rel_path = os.path.join(rel_root, f) if rel_root else f
|
|
full_path = os.path.join(root, f)
|
|
try:
|
|
size = os.path.getsize(full_path)
|
|
except:
|
|
size = 0
|
|
index["files"][rel_path] = {
|
|
"size": size,
|
|
"ext": os.path.splitext(f)[1]
|
|
}
|
|
|
|
# 保存索引
|
|
INDEX_FILE.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(INDEX_FILE, "w") as f:
|
|
json.dump(index, f, indent=2, ensure_ascii=False)
|
|
|
|
return {
|
|
"status": "ok",
|
|
"total_files": len(index["files"]),
|
|
"total_dirs": len(index["dirs"]),
|
|
"index_file": str(INDEX_FILE)
|
|
}
|
|
|
|
def load_index():
|
|
"""加载已有索引"""
|
|
if INDEX_FILE.exists():
|
|
with open(INDEX_FILE) as f:
|
|
return json.load(f)
|
|
return None
|
|
|
|
def find_file(pattern):
|
|
"""搜索文件"""
|
|
index = load_index()
|
|
if not index:
|
|
return {"error": "索引不存在,先运行 scout.py index"}
|
|
|
|
matches = []
|
|
pattern_lower = pattern.lower()
|
|
for path, info in index["files"].items():
|
|
if pattern_lower in path.lower():
|
|
matches.append({"path": path, "size": info["size"]})
|
|
|
|
# 按路径排序
|
|
matches.sort(key=lambda x: x["path"])
|
|
return {"pattern": pattern, "matches": matches, "count": len(matches)}
|
|
|
|
def list_dir(path=""):
|
|
"""列出目录结构"""
|
|
index = load_index()
|
|
if not index:
|
|
return {"error": "索引不存在,先运行 scout.py index"}
|
|
|
|
# 列出直接子目录和文件
|
|
subdirs = []
|
|
files = []
|
|
|
|
prefix = path.rstrip("/") + "/" if path else ""
|
|
|
|
for d in index["dirs"]:
|
|
if d.startswith(prefix) and d != prefix.rstrip("/"):
|
|
rel = d[len(prefix):]
|
|
if "/" not in rel:
|
|
subdirs.append(d)
|
|
|
|
for f in index["files"]:
|
|
if f.startswith(prefix):
|
|
rel = f[len(prefix):]
|
|
if "/" not in rel:
|
|
files.append({"name": rel, "size": index["files"][f]["size"]})
|
|
|
|
return {"path": path or "/", "subdirs": subdirs, "files": files}
|
|
|
|
def search_content(pattern, file_pattern="*"):
|
|
"""在文件中搜索内容"""
|
|
import subprocess
|
|
cmd = ["grep", "-rl", "--include=" + file_pattern, pattern, str(REPO_ROOT)]
|
|
try:
|
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
|
files = [os.path.relpath(f, REPO_ROOT) for f in result.stdout.strip().split("\n") if f]
|
|
return {"pattern": pattern, "matches": files, "count": len(files)}
|
|
except:
|
|
return {"error": "搜索失败"}
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print("用法: scout.py <index|find|where|grep> [参数]")
|
|
sys.exit(1)
|
|
|
|
action = sys.argv[1]
|
|
|
|
if action == "index":
|
|
result = build_index()
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
|
|
elif action == "find" and len(sys.argv) > 2:
|
|
result = find_file(sys.argv[2])
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
|
|
elif action == "where":
|
|
path = sys.argv[2] if len(sys.argv) > 2 else ""
|
|
result = list_dir(path)
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
|
|
elif action == "grep" and len(sys.argv) > 2:
|
|
pattern = sys.argv[2]
|
|
fp = sys.argv[3] if len(sys.argv) > 3 else "*"
|
|
result = search_content(pattern, fp)
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|