冰朔 56514a1250 feat: 情报Agent小分队 — 铸渊的五人情报小队
- AGENT-REGISTRY.hdlp: 小队注册表,HLDP-ZY协议统一管理
- 密钥猎手 (KEY-001): 搜索12台服务器上的所有密钥和Token
- 路径探子 (PATH-002): 3500个文件索引,瞬间定位任何文件
- 服务器哨兵 (SENTINEL-003): 一键扫描12台服务器在线状态
- 模块管家 (MODULE-004): 查询所有模块的编号/接口/部署方式
- 门桥接 (GATE-005): 提供任意服务器Gatekeeper连接凭据

铸渊不需要到处找东西。叫一声Agent,它去找。
每个Agent独立模块,按需部署,用完躺回代码仓库。
2026-05-28 22:30:12 +08:00

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))