git-slop 0.16.4

A deterministic repository token-defragmenter for humans and AI agents.
Documentation
fn writable_cache_probe(target: &Path) -> Value {
    let mut probe_root = target;
    while !probe_root.exists() {
        let Some(parent) = probe_root.parent() else {
            return json!({"status":"blocked","writable":false,"detail":"no existing parent directory is available"});
        };
        probe_root = parent;
    }
    if !probe_root.is_dir() {
        return json!({"status":"blocked","writable":false,"detail":"the cache path or its nearest existing parent is not a directory"});
    }
    let nonce = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap_or_default()
        .as_nanos();
    let probe = probe_root.join(format!(
        ".git-slop-write-probe-{}-{nonce}",
        std::process::id()
    ));
    match std::fs::OpenOptions::new()
        .write(true)
        .create_new(true)
        .open(&probe)
    {
        Ok(file) => {
            drop(file);
            match fs::remove_file(&probe) {
                Ok(()) => json!({"status":"writable","writable":true}),
                Err(error) => json!({"status":"blocked","writable":false,"detail":format!("write probe succeeded but cleanup failed: {error}")}),
            }
        }
        Err(error) => json!({"status":"blocked","writable":false,"detail":format!("write probe failed: {error}")}),
    }
}

fn doctor_bundle_path(repo_root: &Path, requested: Option<&Path>) -> Option<PathBuf> {
    requested.map(|output| {
        if output == Path::new("__git_slop_active_state_bundle__") {
            config::active_state_dir(repo_root)
                .unwrap_or_else(|_| config::slop_dir(repo_root))
                .join("diagnostic-bundle.json")
        } else if output.is_absolute() {
            output.to_path_buf()
        } else {
            repo_root.join(output)
        }
    })
}

fn write_doctor_bundle(
    output: &Path,
    format: DoctorFormat,
    config_result: &Result<Value>,
    diagnostic: &Value,
    repo: &crate::model::RepoMetadata,
) -> Result<()> {
    if let Some(parent) = output.parent() {
        fs::create_dir_all(parent)?;
    }
    let config_digest = config_result
        .as_ref()
        .ok()
        .and_then(|value| serde_json::to_vec(value).ok())
        .map(|bytes| hex::encode(sha2::Sha256::digest(bytes)));
    let report = &diagnostic["report"];
    let caches = &diagnostic["cache_writability"];
    let payload = json!({
        "schema_version": 1,
        "git_slop_version": VERSION,
        "repository": {
            "name": repo.repo_name,
            "shallow": repo.is_shallow,
            "detached": repo.detached_head,
            "clean": repo.worktree_clean,
            "staged": repo.staged_change_count,
            "modified": repo.modified_tracked_file_count,
            "untracked_count": repo.untracked_file_count
        },
        "adoption": diagnostic["adoption"].clone(),
        "config_digest": config_digest,
        "report_status": report["status"].clone(),
        "report_freshness": report["freshness"].clone(),
        "diagnostics": diagnostic["diagnostics"].clone(),
        "estimate": diagnostic["estimate"].clone(),
        "cache_writability": {
            "detector_state_writable": caches["detector_state"]["writable"].clone(),
            "policy_packs_writable": caches["policy_packs"]["writable"].clone()
        },
        "privacy": {"source_included": false, "raw_tokens_included": false, "absolute_paths_included": false, "author_identities_included": false, "credentials_included": false}
    });
    config::write_text_atomically(output, render_json(&payload)?, false)?;
    if matches!(format, DoctorFormat::Json) {
        eprintln!("Wrote redacted diagnostic bundle to {}.", output.display());
    } else {
        println!("Wrote redacted diagnostic bundle to {}.", output.display());
    }
    Ok(())
}