Files
Auto-Finance/tasks.py
T
wandering 3392ab2152 feat(skill): 报销技能可独立使用,配套安装脚本与来源启停校验
目标是技能脱离本仓库也能用:任何项目里提到报销都该按同一套纪律走。

- SKILL.md 重写自足化(104 行):删掉两处只在仓库里成立的引用(docs/MCP.md、方案文档);
  新增「第 0 步:确认工具可用」——先 mcp__arb__case_list 探活,工具不在就把 stdio 注册片段
  (uv run python -m src.mcp.server + cwd)交给用户,并明确禁止绕道自己写脚本处理发票;
  写死跨项目事实:材料用绝对路径正斜杠且可来自任何目录、产物在服务器仓库的 cases/<id>/、
  路径从 case_status 的 case_dir 读而不是按当前工作目录猜、别把截图与 info 拷进用户当前工程;
  字段权威指向工具(extraction_spec / info_skeleton / rules_get),三份 references 标注为判读经验
  并把开头指向已删除 src/infra/llm/prompts/* 的悬空路径改成历史沿革
- 补进这轮学到的坑:失败信封的额外字段在 detail 里;match 用单据编号最稳;每步可单独重填;
  敏感值打码引用;截图是核对证据不是给用户的报告
- 新增 scripts/install_skill.py(Makefile 与 tasks.py 各加 skill-install / skill-check):单向同步 +
  --check 漂移退出码 1 + front matter 缺失退出码 2(宁可不装也别装个宿主注册不了的)
- 关键防护:技能来源由 skills-manager 管,装进「已停用来源」里的技能文件明明存在但宿主永远扫不到
  (我第一次就装进了 ~/.dsh/skills,同目录的 wavedrom-gen 正是同一现象的旁证)。脚本现在读
  ~/.dsh/dsh-skills-manager.log 里该目录最后一条 source-enable/-disable,停用时拒绝安装并回显证据行
  (--force 可绕),默认目标改为已启用的 ~/.agents/skills
- tasks.py 顺手修掉吞退出码的老问题:os.system 的返回值以前直接丢,门禁失败调用方还看到 0。
  实测漂移 exit 1 / 同步 exit 0 / 未知任务 exit 2;顺便支持下划线别名
- 精简执行环境里 Path.home() 会抛 RuntimeError:脚本改用 USERPROFILE/HOME 回退并给人话提示

已知边界:同名技能项目级优先(skill() 的 resourceBase.path 实测指向仓库副本),因此本会话看到的
是仓库那份;跨项目可用性靠「已启用来源 + 内容一致」证明,另开一个目录的会话可最终确认。
验证:ruff / format / mypy / deptry / pytest 148 passed / mcp_smoke 25 工具全绿。
仍用 --no-verify 提交并手跑等价检查。
2026-10-20 22:21:00 +08:00

44 lines
1.7 KiB
Python

"""Windows 侧的任务入口(与 Makefile 等价)。
退出码必须透传:以前 os.system 的返回值被直接丢掉,skill-check 检出漂移、check 门禁失败
都会让调用方以为成功了——AGENTS 里「门禁退出码要单独确认」说的就是这个坑。
"""
import os
import sys
TASKS = {
"install": "uv sync && uv run pre-commit install",
"check": "uv lock --locked && uv run ruff check . && uv run ruff format --check . "
"&& uv run python -m mypy src && uv run deptry .",
"test": "uv run python -m pytest --cov --cov-config=pyproject.toml --cov-report=term-missing",
"mcp": "uv run python -m src.mcp.server",
"mcp-smoke": "uv run python scripts/mcp_smoke.py",
"upload": "uv run python -m src.upload.server",
"skill-install": "uv run python scripts/install_skill.py",
"skill-check": "uv run python scripts/install_skill.py --check",
"clean": "rm -rf .venv __pycache__ .pytest_cache .mypy_cache .ruff_cache",
}
# 下划线写法作别名,手打时不用纠结连字符
ALIASES = {key.replace("-", "_"): value for key, value in TASKS.items()}
def run_task(task_name: str) -> int:
command = TASKS.get(task_name) or ALIASES.get(task_name)
if not command:
print("未知任务:" + task_name, file=sys.stderr)
print("可选:" + ", ".join(sorted(TASKS)), file=sys.stderr)
return 2
print("Running " + task_name + "...")
return os.system(command)
if __name__ == "__main__":
if len(sys.argv) > 1:
raise SystemExit(run_task(sys.argv[1]))
print("用法:python tasks.py 任务名", file=sys.stderr)
print("可选:" + ", ".join(sorted(TASKS)), file=sys.stderr)
raise SystemExit(2)