mirror of
https://github.com/codestable/CodeStable.git
synced 2026-09-19 09:03:09 +08:00
30fecaae5e
收敛 CodeStable 主入口、runtime preflight、goal driver 与 skill 工程化评测闭环。 - 根 cs 对行动请求同轮直转,咨询与介绍保持非执行 - feature/issue/refactor/epic/docs 按仓库事实恢复,旧 stage skill 保留兼容薄壳 - repo-local runtime 支持版本检测、安全自动同步和显式 refresh-runtime - 完成 Codex/Claude marketplace 1.0.2、升级文档和回归/评测证据 验证:215 tests passed;package/runtime/diff checks passed;独立 review 与 QA 无 unresolved blocking/important findings。
69 lines
2.2 KiB
Python
69 lines
2.2 KiB
Python
#!/usr/bin/env python3
|
|
"""Report unresolved CodeStable human-review and follow-up backlog items."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from dataclasses import asdict
|
|
from pathlib import Path
|
|
|
|
from codestable_common import is_blocking_follow_up_text, scan_backlog, unit_for_path
|
|
|
|
|
|
BLOCKING_KINDS = {"needs-human-review", "human-review"}
|
|
|
|
|
|
def is_blocking_item(kind: str, text: str) -> bool:
|
|
if kind in BLOCKING_KINDS:
|
|
return True
|
|
if kind != "follow-up":
|
|
return False
|
|
return is_blocking_follow_up_text(text)
|
|
|
|
|
|
def backlog(root: Path) -> dict[str, object]:
|
|
root = root.resolve()
|
|
items = []
|
|
for item in scan_backlog(root):
|
|
payload = asdict(item)
|
|
blocking = is_blocking_item(item.kind, item.text)
|
|
payload["unit"] = unit_for_path(item.path)
|
|
payload["file"] = item.path
|
|
payload["excerpt"] = item.text
|
|
payload["blocking"] = blocking
|
|
payload["severity"] = "P1" if blocking else "P2"
|
|
payload["action"] = (
|
|
"Get human decision before completion."
|
|
if blocking
|
|
else "Resolve, convert to an issue, or explicitly defer."
|
|
)
|
|
items.append(payload)
|
|
return {
|
|
"ok": not any(item["severity"] == "P1" for item in items),
|
|
"items": items,
|
|
"blocking_count": sum(1 for item in items if item["severity"] == "P1"),
|
|
"optional_count": sum(1 for item in items if item["severity"] == "P2"),
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--root", default=".", help="Repository root")
|
|
parser.add_argument("--json", action="store_true", help="Print machine-readable output")
|
|
args = parser.parse_args()
|
|
|
|
payload = backlog(Path(args.root))
|
|
if args.json:
|
|
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
|
else:
|
|
print(f"Blocking backlog: {payload['blocking_count']}")
|
|
print(f"Optional backlog: {payload['optional_count']}")
|
|
for item in payload["items"]:
|
|
print(f"- {item['severity']} {item['kind']} {item['path']}:{item['line']} {item['text']}")
|
|
return 0 if payload["ok"] else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|