1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use clap::{Parser, Subcommand, ValueEnum};
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "schemalint")]
#[command(
about = "Static analysis tool for JSON Schema compatibility with LLM structured-output providers"
)]
#[command(version)]
pub struct Cli {
#[command(subcommand)]
pub command: Commands,
}
#[derive(Subcommand)]
pub enum Commands {
/// Check JSON Schemas against a capability profile
Check(CheckArgs),
/// Check Pydantic models via Python subprocess
CheckPython(CheckPythonArgs),
/// Check Zod schemas via Node.js subprocess
CheckNode(CheckNodeArgs),
/// List built-in capability profiles and their provider aliases
Profiles(ProfilesArgs),
/// Start JSON-RPC server mode
Server(ServerArgs),
}
#[derive(Parser)]
pub struct CheckArgs {
/// Built-in profile ID or path to a TOML capability profile (repeatable).
/// Accepts bare provider names ("openai", "anthropic") and
/// "<provider>.so.latest" as aliases for that provider's latest profile.
/// Optional: if omitted, the provider is auto-detected from package.json
/// dependencies near the schema path (falling back to openai.so.2026-04-30).
/// Run `schemalint profiles` to list all built-in profiles.
#[arg(short, long = "profile")]
pub profiles: Vec<PathBuf>,
/// Output format
#[arg(short, long, value_enum)]
pub format: Option<OutputFormat>,
/// Write output to a file instead of stdout
#[arg(short, long)]
pub output: Option<PathBuf>,
/// Schema files or directories to check
pub paths: Vec<String>,
}
#[derive(Parser)]
pub struct ProfilesArgs {}
#[derive(Parser)]
pub struct ServerArgs {}
#[derive(Parser)]
pub struct CheckPythonArgs {
/// Python package names to discover Pydantic models from (repeatable)
#[arg(short = 'P', long = "package")]
pub packages: Vec<String>,
/// Built-in profile ID or TOML capability profile path (repeatable; overrides
/// pyproject.toml). Accepts bare provider names ("openai", "anthropic") and
/// "<provider>.so.latest" as aliases. Run `schemalint profiles` to list all.
#[arg(short, long = "profile")]
pub profiles: Vec<PathBuf>,
/// Path to pyproject.toml (default: ./pyproject.toml)
#[arg(long = "config")]
pub config: Option<PathBuf>,
/// Path to Python executable (default: python3)
#[arg(long = "python-path")]
pub python_path: Option<String>,
/// Output format
#[arg(short, long, value_enum)]
pub format: Option<OutputFormat>,
/// Write output to a file instead of stdout
#[arg(short, long)]
pub output: Option<PathBuf>,
}
#[derive(Parser)]
pub struct CheckNodeArgs {
/// TypeScript source globs to discover Zod schemas from (repeatable)
#[arg(short = 'S', long = "source")]
pub sources: Vec<String>,
/// Built-in profile ID or TOML capability profile path (repeatable; overrides
/// package.json). Accepts bare provider names ("openai", "anthropic") and
/// "<provider>.so.latest" as aliases. Optional: if omitted, the provider is
/// auto-detected from source imports or package.json dependencies (falling
/// back to openai.so.2026-04-30). Run `schemalint profiles` to list all.
#[arg(short, long = "profile")]
pub profiles: Vec<PathBuf>,
/// Path to package.json (default: ./package.json)
#[arg(long = "config")]
pub config: Option<PathBuf>,
/// Path to Node/tsx executable (default: auto-detect tsx)
#[arg(long = "node-path")]
pub node_path: Option<String>,
/// Output format
#[arg(short, long, value_enum)]
pub format: Option<OutputFormat>,
/// Write output to a file instead of stdout
#[arg(short, long)]
pub output: Option<PathBuf>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum)]
pub enum OutputFormat {
/// Human-readable rustc-style output
Human,
/// Structured JSON output
Json,
/// SARIF v2.1.0 output
Sarif,
/// GitHub Actions workflow commands
Gha,
/// JUnit XML output
Junit,
}