generated from coulomb/repo-seed
WP-0016 finished: interactive registry maintain with llm-connect automation
Some checks failed
ci / validate-registry (push) Has been cancelled
Some checks failed
ci / validate-registry (push) Has been cancelled
Closes the registry maintenance loop from inside each domain repo: interactive prompting for judgment calls, full automation for safe and high-confidence changes, both backed by the llm-connect HTTP bridge. - New modules: maintain.py, maintain_llm.py, patches.py, interactive.py - Schema: schemas/registry-patch.schema.json - CLI: reuse-surface maintain; establish --scaffold --hook - Sibling templates: Makefile fragment, pre-commit hook - Deterministic signal collectors extended; validate cwd auto-detect - Docs, gap priority 28, SCOPE update - Tests: test_maintain.py, test_interactive.py (59 pytest total) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ from reuse_surface.reports import (
|
||||
from reuse_surface.establish import (
|
||||
discover_capabilities,
|
||||
format_publish_check_markdown,
|
||||
install_registry_hook,
|
||||
publish_check,
|
||||
scaffold_next_steps,
|
||||
scaffold_registry,
|
||||
@@ -52,6 +53,11 @@ from reuse_surface.stats import (
|
||||
format_stats_json,
|
||||
format_stats_markdown,
|
||||
)
|
||||
from reuse_surface.maintain import (
|
||||
format_maintain_json,
|
||||
format_maintain_markdown,
|
||||
run_maintain,
|
||||
)
|
||||
from reuse_surface.registry import (
|
||||
ROOT,
|
||||
capability_paths,
|
||||
@@ -62,13 +68,26 @@ from reuse_surface.registry import (
|
||||
parse_front_matter,
|
||||
parse_vector,
|
||||
registry_paths,
|
||||
resolve_repo_root,
|
||||
)
|
||||
|
||||
|
||||
def _registry_root(args: argparse.Namespace) -> Path:
|
||||
if getattr(args, "root", None):
|
||||
return Path(args.root).resolve()
|
||||
return ROOT
|
||||
return resolve_repo_root(getattr(args, "root", None))
|
||||
|
||||
|
||||
def _make_validate_fn(repo_root: Path) -> Any:
|
||||
def _validate() -> tuple[int, list[str], list[str]]:
|
||||
errors, warnings, _paths = _run_validate(repo_root, target=None, relations=False)
|
||||
for warning in warnings:
|
||||
print(f"warning: {warning}", file=sys.stderr)
|
||||
for error in errors:
|
||||
print(f"error: {error}", file=sys.stderr)
|
||||
if errors:
|
||||
return 1, errors, warnings
|
||||
return 0, errors, warnings
|
||||
|
||||
return _validate
|
||||
|
||||
|
||||
def _check_index_drift(
|
||||
@@ -427,6 +446,9 @@ def cmd_establish(args: argparse.Namespace) -> int:
|
||||
)
|
||||
for path in created:
|
||||
print(f"ok: wrote {path.relative_to(repo_root)}")
|
||||
if args.hook:
|
||||
hook = install_registry_hook(repo_root, force=args.force)
|
||||
print(f"ok: wrote {hook.relative_to(repo_root)}")
|
||||
print(scaffold_next_steps(repo_root))
|
||||
return 0
|
||||
if args.publish_check:
|
||||
@@ -461,6 +483,38 @@ def cmd_establish(args: argparse.Namespace) -> int:
|
||||
return 1
|
||||
|
||||
|
||||
def cmd_maintain(args: argparse.Namespace) -> int:
|
||||
repo_root = Path(args.path or ".").resolve()
|
||||
try:
|
||||
if not args.capability and not args.all:
|
||||
print("error: specify --capability or --all", file=sys.stderr)
|
||||
return 1
|
||||
result = run_maintain(
|
||||
repo_root,
|
||||
capability_id=args.capability,
|
||||
all_capabilities=args.all,
|
||||
git_since=args.from_git_since,
|
||||
llm_url=args.llm_url,
|
||||
no_llm=args.no_llm,
|
||||
auto=args.auto,
|
||||
yes=args.yes,
|
||||
auto_confidence=args.auto_confidence,
|
||||
auto_max_delta=args.auto_max_delta,
|
||||
publish=args.publish,
|
||||
raw_url=args.raw_url,
|
||||
output_format=args.format,
|
||||
validate_fn=_make_validate_fn(repo_root),
|
||||
)
|
||||
if args.format == "json":
|
||||
print(format_maintain_json(result))
|
||||
else:
|
||||
print(format_maintain_markdown(result), end="")
|
||||
return result.exit_code
|
||||
except ValueError as exc:
|
||||
print(f"error: {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
|
||||
def cmd_update(args: argparse.Namespace) -> int:
|
||||
repo_root = Path(args.path or ".").resolve()
|
||||
try:
|
||||
@@ -782,6 +836,11 @@ def main(argv: list[str] | None = None) -> int:
|
||||
establish.add_argument("--raw-url", help="raw Gitea index URL for publish-check")
|
||||
establish.add_argument("--llm-url", help="llm-connect base URL (or LLM_CONNECT_URL)")
|
||||
establish.add_argument("--context-max-files", type=int, default=12)
|
||||
establish.add_argument(
|
||||
"--hook",
|
||||
action="store_true",
|
||||
help="install registry pre-commit hook (with --scaffold)",
|
||||
)
|
||||
establish.set_defaults(func=cmd_establish)
|
||||
|
||||
update = subparsers.add_parser("update", help="refresh registry metadata from repo signals")
|
||||
@@ -795,6 +854,28 @@ def main(argv: list[str] | None = None) -> int:
|
||||
update.add_argument("--format", choices=["markdown", "json"], default="markdown")
|
||||
update.set_defaults(func=cmd_update)
|
||||
|
||||
maintain = subparsers.add_parser(
|
||||
"maintain", help="interactive or automated registry maintenance"
|
||||
)
|
||||
maintain.add_argument("--path", help="repo root (default: cwd)")
|
||||
maintain.add_argument("--capability", help="single capability id")
|
||||
maintain.add_argument("--all", action="store_true")
|
||||
maintain.add_argument("--from-git-since", help="git ref for change detection")
|
||||
maintain.add_argument("--llm-url", help="llm-connect base URL (or LLM_CONNECT_URL)")
|
||||
maintain.add_argument("--no-llm", action="store_true")
|
||||
maintain.add_argument("--auto", action="store_true", help="apply safe + gated LLM patches")
|
||||
maintain.add_argument("--yes", action="store_true", help="non-TTY auto-apply equivalent")
|
||||
maintain.add_argument(
|
||||
"--auto-confidence",
|
||||
choices=["low", "medium", "high"],
|
||||
default="high",
|
||||
)
|
||||
maintain.add_argument("--auto-max-delta", type=int, default=1)
|
||||
maintain.add_argument("--publish", action="store_true")
|
||||
maintain.add_argument("--raw-url", help="raw Gitea index URL for --publish")
|
||||
maintain.add_argument("--format", choices=["markdown", "json"], default="markdown")
|
||||
maintain.set_defaults(func=cmd_maintain)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
return args.func(args)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user