Sprint B.6: CLI guardrails — --dry-run, protected_repos, VULP_AGENT marker

- global --dry-run: sync/release/init/collab/license print 'DRY RUN: would...'
  and exit 0 (no auth needed for previews where possible)
- config protected_repos (name/basename, case-insensitive): mutating commands
  exit 1 on listed repos unless --force; checked before dry-run
- VULP_AGENT env: activity::log centrally appends '· via agent' to detail,
  covering both CLI and TUI writers
- sync: unknown --action now rejected before touching any repo
This commit is contained in:
dualfroz committed 2026-07-06 15:43:14 +02:00
1 parent f1432d1cd3
commit 8119cdeba7
8 files changed
+133 -14

No files matched your search

+15 -1
View File
@@ -89,7 +89,7 @@ pub fn scan_cmd(cfg: &AppConfig, json: bool) -> Result<()> {
}
pub fn sync(
cfg: &AppConfig,
cfg: &AppConfig, guard: super::Guard,
repos: Vec<String>, all: bool, project: Option<String>,
action: &str, message: Option<String>,
) -> Result<()> {
@@ -120,11 +120,25 @@ pub fn sync(
};
let action = action.replace('-', "_"); // commit-push → commit_push
if !["pull", "push", "commit_push"].contains(&action.as_str()) {
die(2, &format!("unknown action '{action}' (pull | push | commit-push)"));
}
if action == "commit_push" && message.is_none() {
die(2, "--message is required for commit-push");
}
let msg = message.unwrap_or_default();
super::guard_protected(cfg, guard.force, &targets);
if guard.dry_run {
for r in &targets {
match action.as_str() {
"commit_push" => println!("DRY RUN: would commit+push {} (message: {msg})", r.name),
a => println!("DRY RUN: would {a} {}", r.name),
}
}
return Ok(());
}
let mut failed = 0usize;
for r in &targets {
eprintln!("── {} [{}]", r.name, action);