spreadsheet-kit 0.11.1

Core spreadsheet automation primitives — shared types, edit normalization, and session traits for agent-facing surfaces
Documentation
use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Output};
use std::time::{SystemTime, UNIX_EPOCH};

fn repo_root() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("../..")
        .canonicalize()
        .expect("resolve workspace root")
}

fn run_checker(repo_root: &Path, matrix_override: Option<&Path>) -> Output {
    let script = repo_root.join("scripts/check_surface_matrix_drift.py");
    assert!(
        script.exists(),
        "drift checker script missing at {}",
        script.display()
    );

    let mut cmd = Command::new("python3");
    cmd.arg(&script).current_dir(repo_root);
    if let Some(matrix_path) = matrix_override {
        cmd.env("SURFACE_MATRIX_MD", matrix_path);
    }

    cmd.output().expect("run matrix drift checker")
}

fn write_temp_file(prefix: &str, content: &str) -> PathBuf {
    let stamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("clock before epoch")
        .as_nanos();
    let path = std::env::temp_dir().join(format!("{prefix}-{stamp}.md"));
    fs::write(&path, content).expect("write temp matrix file");
    path
}

#[test]
fn surface_matrix_drift_check_passes() {
    let root = repo_root();
    let output = run_checker(&root, None);

    if !output.status.success() {
        panic!(
            "surface matrix drift check failed (status: {:?})\nstdout:\n{}\nstderr:\n{}",
            output.status.code(),
            String::from_utf8_lossy(&output.stdout),
            String::from_utf8_lossy(&output.stderr)
        );
    }
}

#[test]
fn surface_matrix_drift_check_fails_when_variant_row_missing() {
    let root = repo_root();
    let matrix_path = root.join("docs/architecture/surface-capability-matrix.md");
    let original = fs::read_to_string(&matrix_path).expect("read matrix");

    let modified = original
        .lines()
        .filter(|line| !line.contains("`read export --format grid`"))
        .collect::<Vec<_>>()
        .join("\n");

    let temp_path = write_temp_file("surface-matrix-missing-variant", &modified);
    let output = run_checker(&root, Some(&temp_path));

    assert!(
        !output.status.success(),
        "checker should fail when a required variant row is removed"
    );

    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("Missing CLI entries") || stdout.contains("read export --format grid"),
        "expected missing variant diagnostics, got:\n{stdout}"
    );

    let _ = fs::remove_file(temp_path);
}

#[test]
fn surface_matrix_drift_check_fails_on_stale_row() {
    let root = repo_root();
    let matrix_path = root.join("docs/architecture/surface-capability-matrix.md");
    let original = fs::read_to_string(&matrix_path).expect("read matrix");

    let marker = "| `analyze ref-impact` |";
    let fake_row = "| `fake-command-for-drift-check` | _(none)_ | CLI_ONLY | `adapter-cli.fake` | n/a | test stale row | `crates/spreadsheet-kit/src/cli/mod.rs` | `crates/spreadsheet-kit/tests/surface_matrix_drift_check.rs` |";
    let modified = if let Some(pos) = original.find(marker) {
        let mut out = String::with_capacity(original.len() + fake_row.len() + 2);
        out.push_str(&original[..pos]);
        out.push_str(fake_row);
        out.push('\n');
        out.push_str(&original[pos..]);
        out
    } else {
        panic!("failed to locate insertion marker '{marker}' in matrix");
    };

    let temp_path = write_temp_file("surface-matrix-stale", &modified);
    let output = run_checker(&root, Some(&temp_path));

    assert!(
        !output.status.success(),
        "checker should fail on stale matrix entries"
    );

    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("Stale CLI entries") || stdout.contains("fake-command-for-drift-check"),
        "expected stale row diagnostics, got:\n{stdout}"
    );

    let _ = fs::remove_file(temp_path);
}

#[test]
fn surface_matrix_drift_check_fails_on_missing_required_metadata() {
    let root = repo_root();
    let matrix_path = root.join("docs/architecture/surface-capability-matrix.md");
    let original = fs::read_to_string(&matrix_path).expect("read matrix");

    let target_row = "| `read sheets` | `list_sheets` | ALL | `core.read.list_sheets` | mvp | Shared read primitive | `crates/spreadsheet-kit/src/cli/commands/read.rs::list_sheets` | `crates/spreadsheet-kit/tests/core_runtime_parity.rs` |";
    let broken_row = "| `read sheets` | `list_sheets` | ALL | `core.read.list_sheets` | mvp | Shared read primitive | `crates/spreadsheet-kit/src/cli/commands/read.rs::list_sheets` |  |";

    let modified = original.replacen(target_row, broken_row, 1);
    assert_ne!(
        modified, original,
        "failed to rewrite target row for required-metadata test"
    );

    let temp_path = write_temp_file("surface-matrix-metadata", &modified);
    let output = run_checker(&root, Some(&temp_path));

    assert!(
        !output.status.success(),
        "checker should fail when required metadata columns are blank"
    );

    let stdout = String::from_utf8_lossy(&output.stdout);
    assert!(
        stdout.contains("parity test owner must be non-empty")
            || stdout.contains("Matrix validation errors"),
        "expected metadata validation diagnostics, got:\n{stdout}"
    );

    let _ = fs::remove_file(temp_path);
}