feat(operit): 增强转译层并接入 5 个 Operit 市场插件
operit_loader.py: - OkHttp 新增 newClient()(真实市场插件普遍使用,而非 newBuilder) - OkHttpRequest.execute() 改为 async,与 Operit 运行时异步语义对齐 - OkHttpResponse 新增 json() 与 statusMessage()(基于 http.HTTPStatus) operit_translate.py(新增): - Operit .ts 插件 -> xiaoli-cli .py 脚手架生成器 - 自动提取 METADATA、生成 exports 胶水,原 TS 作参考注释保留 plugins/operit_scripts/ 新增 5 个已跑通的真实插件: - market_time 时间查询/格式化 - market_duckduckgo 网页内容抓取与清洗 - market_crossref Crossref 学术文献检索 - market_network_test HTTP 连通性测试 - market_reader 本地代码递归搜索 注: 工具需注册为 async 包装函数,同步 lambda 会导致 complete() 不执行的假阳性
This commit is contained in:
1 parent
f7f7033e57
commit
388ac493af
7 files changed
+868
-1
No files matched your search
@@ -0,0 +1,85 @@
|
||||
# METADATA
|
||||
# {
|
||||
# "name": "reader",
|
||||
# "display_name": { "zh": "代码读取器", "en": "Code Reader" },
|
||||
# "description": { "zh": "在文件夹中搜索匹配的代码(本地文件,无需 Android)", "en": "Search matching code in a folder." },
|
||||
# "category": "File",
|
||||
# "tools": [
|
||||
# { "name": "search_code_in_folder", "description": { "zh": "在文件夹中搜索匹配的代码", "en": "Search matching code in a folder" } }
|
||||
# ]
|
||||
# }
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
def getErrorMessage(error):
|
||||
return str(error) if error else "unknown"
|
||||
|
||||
|
||||
def getErrorStack(error):
|
||||
import traceback
|
||||
return traceback.format_exc()
|
||||
|
||||
|
||||
async def search_code_in_folder(params):
|
||||
folder_path = params.get("folder_path")
|
||||
pattern = params.get("pattern")
|
||||
file_extensions = params.get("file_extensions", ".js,.ts,.jsx,.tsx,.java,.cs,.py")
|
||||
recursive = str(params.get("recursive", "true")).lower() in ("true", "1", "yes")
|
||||
if not folder_path:
|
||||
return {"success": False, "message": "文件夹路径不能为空"}
|
||||
if not pattern:
|
||||
return {"success": False, "message": "搜索模式不能为空"}
|
||||
try:
|
||||
exts = [e.strip().lower() for e in file_extensions.split(",") if e.strip()]
|
||||
rx = re.compile(pattern, re.MULTILINE)
|
||||
files = []
|
||||
if recursive:
|
||||
for root, _, fnames in os.walk(folder_path):
|
||||
for fn in fnames:
|
||||
if any(fn.lower().endswith(e) for e in exts):
|
||||
files.append(os.path.join(root, fn))
|
||||
else:
|
||||
for fn in os.listdir(folder_path):
|
||||
fp = os.path.join(folder_path, fn)
|
||||
if os.path.isfile(fp) and any(fn.lower().endswith(e) for e in exts):
|
||||
files.append(fp)
|
||||
|
||||
results = []
|
||||
for fp in files:
|
||||
try:
|
||||
with open(fp, "r", encoding="utf-8", errors="replace") as fh:
|
||||
content = fh.read()
|
||||
except Exception as e:
|
||||
console.error(f"处理文件 {fp} 时出错: {getErrorMessage(e)}")
|
||||
continue
|
||||
matches = []
|
||||
for m in rx.finditer(content):
|
||||
ln = content.count("\n", 0, m.start()) + 1
|
||||
matches.append({"match": m.group(0), "line": ln,
|
||||
"content": content.split("\n")[ln - 1] if ln - 1 < len(content.split("\n")) else ""})
|
||||
if matches:
|
||||
results.append({"file": fp, "matches": matches})
|
||||
total = sum(len(r["matches"]) for r in results)
|
||||
return {"success": True, "message": f"在 {len(files)} 个文件中找到 {total} 处匹配",
|
||||
"data": {"files_searched": len(files), "files_with_matches": len(results),
|
||||
"total_matches": total, "results": results[:50]}}
|
||||
except Exception as e:
|
||||
return {"success": False, "message": f"搜索失败: {getErrorMessage(e)}"}
|
||||
|
||||
|
||||
async def wrap(func, params, ok_msg="操作成功", err_msg="操作失败"):
|
||||
try:
|
||||
result = await func(params)
|
||||
complete({"success": True, "message": result.get("message", ok_msg),
|
||||
"data": result.get("data"), **{k: v for k, v in result.items() if k not in ("success", "message", "data")}})
|
||||
except Exception as error:
|
||||
console.error(f"Error: {getErrorMessage(error)}")
|
||||
complete({"success": False, "message": getErrorMessage(error), "error_stack": getErrorStack(error)})
|
||||
|
||||
|
||||
async def search_code_in_folder_wrapper(params):
|
||||
await wrap(search_code_in_folder, params, "代码搜索完成", "代码搜索失败")
|
||||
|
||||
|
||||
exports.search_code_in_folder = search_code_in_folder_wrapper
|
||||
Reference in new issue
Block a user