syster-cli 0.4.3-alpha

Command-line interface for SysML v2 and KerML analysis
Documentation
# Copilot Agent: syster-cli

## Purpose
`syster-cli` is the **command-line interface** for Syster, providing tools for parsing, analyzing, and working with SysML v2 and KerML files from the terminal. It's the user-facing interface for batch operations and developer workflows.

## Scope
- **CLI Commands**: Parse, analyze, validate, format, etc.
- **Terminal UI**: Progress bars, colorized output, error reporting
- **Batch Operations**: Process multiple files, generate reports
- **Developer Tools**: Debug commands, introspection, testing helpers

## Responsibilities

### ✅ This Agent Owns

1. **Command-Line Interface** (`src/`)
   - Argument parsing (clap)
   - Command dispatch
   - Subcommand implementations

2. **Commands** (planned/future)
   - `syster parse` - Parse files and report errors
   - `syster validate` - Semantic validation
   - `syster format` - Code formatting
   - `syster stats` - Project statistics
   - `syster debug` - Debug introspection

3. **Terminal Output** (`src/`)
   - Progress reporting
   - Error formatting (user-friendly)
   - Colorized output
   - Tabular reports

4. **Batch Processing** (`src/`)
   - Multi-file operations
   - Parallel processing (optional)
   - Report generation

### ❌ This Agent Does NOT Own

- **Parser Logic**: Grammar, AST construction (belongs to syster-base)
- **Semantic Analysis**: Symbol resolution, relationship graphs (syster-base)
- **LSP Protocol**: Tower-LSP, editor integration (belongs to syster-lsp)
- **Core Types**: AST, Symbol, Workspace (syster-base)

## Public Surface (Contract)

### Exported Types
```rust
// Minimal exports (mostly a binary crate)
// Public for testing purposes
#[cfg(test)]
pub use commands::*;
```

### Binary Target
```toml
[[bin]]
name = "syster"
path = "src/main.rs"
```

### Command-Line Interface (Stable)
```bash
# Planned stable interface
syster parse <file>           # Parse and report errors
syster validate <file>        # Full semantic validation
syster stats <directory>      # Project statistics
syster debug symbols <file>   # Show symbol table
```

### Stability Guarantees
- **CLI arguments**: Stable (follow semver)
- **Output format**: May evolve (use --json for stable)
- **Exit codes**: Stable (0=success, 1=error, 2=usage error)
- **Internal code**: Free to refactor

## Dependency Rules

### Allowed Dependencies (External)
- `clap` (CLI argument parsing)
-`colored` or `owo-colors` (terminal colors)
-`indicatif` (progress bars)
-`syster-base` (core library - **required**)
-`syster-lsp` (optional, for LSP testing tools)

### Forbidden Dependencies
- **NO** `tower-lsp` (LSP should stay in syster-lsp)
-**NO** direct `pest` usage (use syster-base parser)
-**NO** web frameworks (CLI is terminal-based)
-**NO** GUI frameworks

### Dependency Direction
```
syster-base
syster-lsp (optional)
syster-cli  (depends on both)
```

## Change Sensitivity

### High Sensitivity (Breaking Changes)
- **CLI arguments** (affects user scripts)
- **Exit codes** (affects automation)
- **Stable output formats** (JSON, structured output)

### Medium Sensitivity (Require Coordination)
- **Error messages** (users may parse these)
- **Default behavior** (affects UX)
- **Command names** (aliases can help migration)

### Low Sensitivity (Free to Change)
- **Internal code structure**
- **Progress bar styling**
- **Debug output formatting**
- **Performance optimizations**

## Architectural Constraints

### 1. Thin Command Layer
`syster-cli` should be a **thin interface** to syster-base:
```rust
// ✅ Good: Delegates to syster-base
fn parse_command(path: &Path) -> Result<()> {
    let file = FileLoader::load_and_parse(path)?;  // ← base
    print_parse_result(&file);  // ← format for terminal
    Ok(())
}

// ❌ Bad: Reimplements parsing
fn parse_command(path: &Path) -> Result<()> {
    // Custom parsing logic
    // Should use syster-base!
}
```

### 2. Synchronous by Default
CLI operations are inherently sequential:
- User runs one command at a time
- Output is streamed to terminal
- No need for async complexity (unless doing parallel file processing)

### 3. User-Friendly Errors
Convert technical errors to user-friendly messages:
```rust
// ✅ Good: User-friendly error
match parse_file(path) {
    Err(e) => {
        eprintln!("Failed to parse {}: {}", path.display(), e);
        eprintln!("Hint: Check for syntax errors near line X");
    }
}

// ❌ Bad: Raw debug output
Err(e) => panic!("{:?}", e);  // Users don't want this
```

### 4. Machine-Readable Output (Optional)
For automation, provide structured output:
```bash
# Human-readable (default)
syster parse file.sysml
Error: Missing semicolon at line 10

# Machine-readable (opt-in)
syster parse file.sysml --json
{"status": "error", "line": 10, "message": "Missing semicolon"}
```

## Common Patterns

### Adding a New Command
```rust
// 1. Define in CLI args (main.rs or cli.rs)
#[derive(Parser)]
enum Commands {
    Parse { file: PathBuf },
    NewCommand { /* args */ },  // ← Add here
}

// 2. Implement handler (commands/new_command.rs)
pub fn run(args: NewCommandArgs) -> Result<()> {
    // Delegate to syster-base
    let workspace = Workspace::new();
    // ... use base APIs
    
    // Format output for terminal
    println!("Result: {:?}", result);
    Ok(())
}

// 3. Wire up in main dispatch
match cli.command {
    Commands::Parse { file } => commands::parse::run(file),
    Commands::NewCommand { .. } => commands::new_command::run(..),
}
```

### Progress Reporting
```rust
use indicatif::{ProgressBar, ProgressStyle};

let pb = ProgressBar::new(file_count as u64);
pb.set_style(ProgressStyle::default_bar()
    .template("[{bar:40}] {pos}/{len} {msg}"));

for file in files {
    pb.set_message(file.display().to_string());
    process_file(file)?;
    pb.inc(1);
}
pb.finish_with_message("Complete!");
```

### Error Formatting
```rust
use colored::Colorize;

fn print_error(error: &Error, path: &Path) {
    eprintln!(
        "{} Failed to process {}",
        "error:".red().bold(),
        path.display()
    );
    eprintln!("  {}", error);
}
```

## Testing Requirements

### Must Test
- ✅ Command parsing (clap integration)
- ✅ Each command's core logic
- ✅ Error handling and user messages
- ✅ Exit codes (success/failure)

### Test Organization
- Unit tests: `src/tests/` (moved from crate root)
- Integration tests: `tests/cli_tests.rs`
- Test fixtures: `tests/fixtures/`

### Coverage Goals
- Command handlers: 80%+ coverage
- Error formatting: Manual verification (UX)
- Integration tests: All main workflows

## Integration with syster-base

### Required APIs
The CLI uses these syster-base APIs:
- `FileLoader::load_and_parse()` - Load files
- `StdLibLoader::load()` - Load standard library
- `Workspace::new()` - Create workspace
- `Workspace::add_file()`, `populate_all()` - Analyze
- `SymbolTable`, `RelationshipGraph` - Introspection

### Required syster-lsp APIs (Optional)
If providing LSP testing commands:
- `LspServer::new()` - Create test server
- Testing utilities from syster-lsp

### Assumptions About Dependencies
- syster-base is **synchronous** (CLI doesn't need async)
- Parsing may be **slow** (show progress for multiple files)
- Errors are **structured** (can be formatted nicely)

## Performance Expectations

### Responsiveness
- Single file operations: <1 second
- Large project analysis: Show progress bar
- Batch operations: Parallelize if >10 files

### Resource Usage
- Memory: Proportional to files processed
- CPU: Single-threaded unless explicitly parallel
- Disk: Read-only (unless implementing format/fix)

## Known Limitations

### Current State
1. **Minimal implementation**
   - Only basic commands exist
   - Most features planned for future
   - CLI is a work in progress

2. **No formatting yet**
   - `syster format` not implemented
   - Would require formatter in syster-base first

3. **No fixing mode**
   - Can't auto-fix errors yet
   - Would need fix logic in syster-base

## Review Checklist

Before approving changes to syster-cli:
- [ ] No parser/semantic logic duplicated from syster-base
- [ ] User-friendly error messages (not raw debug)
- [ ] CLI arguments follow conventions (--flag, not -f)
- [ ] Help text is clear and accurate
- [ ] Exit codes are correct (0/1/2)
- [ ] Tests cover main command workflows
- [ ] No forbidden dependencies added
- [ ] Performance acceptable for typical use

## Future Commands (Planned)

### Parse Command
```bash
syster parse <file>
# Output: Errors, warnings, success message
# Exit: 0 if parse succeeds, 1 if errors
```

### Validate Command
```bash
syster validate <file>
# Output: Semantic errors, type errors
# Exit: 0 if valid, 1 if invalid
```

### Stats Command
```bash
syster stats <directory>
# Output: File count, symbol count, complexity metrics
# Exit: 0 always (informational)
```

### Debug Command
```bash
syster debug symbols <file>
# Output: Symbol table dump
syster debug ast <file>
# Output: AST tree
syster debug events <file>
# Output: Event trace
```

### Format Command (Future)
```bash
syster format <file>
# Output: Formatted code (or overwrite with --write)
# Exit: 0 if successful, 1 if error
```

## Coordination with Other Crates

### When syster-base Changes Affect CLI

**API changes**:
```
If: syster-base changes FileLoader API
Then: Update parse command
Impact: Medium (may need release coordination)
```

**Error types**:
```
If: syster-base changes error structure
Then: Update error formatting
Impact: Low (internal only)
```

**New features**:
```
If: syster-base adds new analysis
Then: Consider adding CLI command to expose it
Impact: Opportunity (opt-in)
```

### When syster-lsp Changes Affect CLI

**LSP testing**:
```
If: Providing LSP test commands
Then: May need to coordinate with syster-lsp changes
Impact: Low (testing only)
```

## Agent Metadata
- **Crate**: syster-cli
- **Responsibility Level**: Low (user interface, not core logic)
- **Breaking Change Impact**: Medium (affects user workflows)
- **Created**: 2025-12-17
- **Last Updated**: 2025-12-17
- **Schema Version**: 1.0