@mickmister/openlint
v0.1.0
Published
Global YAML-first lint/static-analysis runner with managed policy presets.
Readme
OpenLint
OpenLint is a global policy-driven CLI for running JS/TS lint and static analysis tools across many repos without checking duplicated config into every repo.
V1 is implemented as a Rust CLI with two binaries:
openlintol
npm install smoke target
The V1 npm package is named @mickmister/openlint and exposes the same
openlint and ol commands. The package depends on @ast-grep/cli and the
Node wrapper prepends its local node_modules/.bin directory to PATH, so
environment policy ast-grep rule packs can run after a global install without a
separate ast-grep installation:
npm install -g @mickmister/openlint
ol policy status
ol check --preset tsx-view-boundary /path/to/projecttsx-view-boundary is expected to come from the canonical environment policy
directory, for example /home/vkuser/.config/openlint in this server
environment. OpenLint no longer silently treats packaged TSX rules as the real
team policy when the default policy directory is missing.
Current package automation can publish a package with prebuilt native binaries
through GitHub Actions OIDC trusted publishing once npm trusted publisher setup
is complete. Local npm pack and global-install smokes are supported now. See
docs/release/openlint-npm-release.md for the prerelease asset checklist, OIDC
publisher setup, and npm publish prerequisites.
V1 commands
ol check [PATH...] # human output by default
ol check --json [PATH...] # agent-friendly JSON
ol check --last-commit # patch-only linting for HEAD~1..HEAD, or HEAD root commit
ol check --commit-range A..B # patch-only linting for a commit range
ol check --preset fences,oxlint # comma-separated multi-preset selection
ol check --preset tsx-view-boundary /path/to/project
ol check --rule 'oxlint/complexity(max=80)'
ol check --native-rule oxlint:complexity --level error --option max=80
ol check --with-defaults --preset focused
ol check --no-repo-local # ignore checked-in repo openlint.yaml for this run
ol check --fix --tool oxlint # run integrations that declare safe fix commands
ol check --timeout-secs 120 # override per-tool policy timeouts
ol explain --json # resolved plan/provenance
ol print-config --json # ephemeral generated config content
ol list --kind tools
ol list --kind packs
ol policy status --json # default policy path/existence/onboarding
ol doctor --json
ol doctor --target . --json # includes repo-local policy provenance/commands
ol config rule oxlint/complexity-80 --integration oxlint --native-rule complexity --level error --option max=80
ol config pack ui-fences --rule 'jsx/attribute-ban(attribute=style)'
ol config preset weekly-dev --integration oxlint --rule 'oxlint/complexity(max=80)'
ol config defaults --preset weekly-dev
ol config apply preset weekly-dev --repo springboard --branch main
ol new rule ast-grep no-console --policy-dir ~/.config/openlint
ol init typescript --target . --policy-dir ~/.config/openlintPolicy loading
Policy is loaded from:
--policy-dirOPENLINT_POLICY_DIR$XDG_CONFIG_HOME/openlint$HOME/.config/openlint
OpenLint looks for openlint.yaml, openlint.yml, policy.yaml, or
policy.yml. If no policy exists, V1 uses optional bundled YAML integration
defaults for generic tools only; team-specific presets such as
tsx-view-boundary must come from the canonical environment policy. Named
presets that are unavailable produce onboarding that points to ol policy
status. When a target repo contains openlint.yaml or openlint.yml, that
checked-in repo-local file is merged as an override by default. Repo-local
integration entries are patches: omitted enabled / required values preserve
the global policy defaults instead of resetting them.
YAML-first integration model
V1 policy is an integrations:-only hard break. Legacy tools: and
yaml_exec: policy keys are rejected. Bundled YAML specs define Oxlint, tsc,
ast-grep, Semgrep, and Fallow through shell-style multiline command templates
backed by reusable Rust primitives for:
- shell interpolation and quoting;
- optional
availability.commandchecks for shell integrations; - generated config files;
- repo config
ignore,merge, andprefer-repo; - rule support validation through
rule_support; - process execution and timeouts;
- generic JSON/text diagnostics mapping;
- normalized output and explain provenance.
Custom one-off integrations are also expressed under integrations: with inline
YAML specs. Integrations that can consume --rule requests must declare
rule_support (generated_config, rule_files, command_args, or all);
otherwise explicit or preset rules fail planning instead of silently succeeding.
Shell templates can reference checked-in policy-repo assets with
{{policy_file:relative/path.yml}}; OpenLint resolves the path under the policy
directory and rejects traversal.
The bundled ast-grep integration is optional and skips when no sgconfig.yml
exists in the target repo. The bundled Fallow integration parses the current
Fallow JSON category-array schema.
The TSX view-boundary rule pack is expected to be defined in the canonical
environment policy, not hardcoded as the real team policy. Package assets and
fixtures may show example TSX rule files for migration/testing, but plain
ol check --preset tsx-view-boundary /path should resolve that preset from the
configured environment policy directory.
Rule, pack, and preset model
Policy can define first-class OpenLint rules under top-level rules:. A rule
maps an OpenLint ID to an integration/native rule with either a concrete value
or a typed dynamic template. Packs are reusable rule groups; presets are
runnable compositions that can include packs, integrations, rules, and other
presets:
rules:
oxlint/complexity:
integration: oxlint
native_rule: complexity
params:
max: { type: integer, required: true }
level: { type: severity, default: error }
value_template: ["{{level}}", { max: "{{max}}" }]
packs:
no-inline-style:
rules: ["jsx/attribute-ban(attribute=style)"]
presets:
weekly-dev:
packs: [no-inline-style]
integrations: [oxlint]
rules: ["oxlint/complexity(max=80)"]Conflicting selected rules that target the same native rule with different
values are configuration errors. Explicit CLI --rule must resolve to a
top-level OpenLint rule definition; native ad hoc checks use --native-rule.
defaults.presets apply to plain runs; any explicit CLI selection replaces
defaults unless --with-defaults is passed. ol config is the safe editor for
common rule/preset/default/override changes, while direct YAML editing remains
supported.
examples/policies/server-global/openlint.yaml shows the git-committable server
global policy shape for enabling Oxlint complexity at error with max: 80
through a dynamic first-class rule.
Missing tools
Missing tools are skipped unless the policy marks the tool as required: true.
Required missing tools fail ol check and ol doctor --strict.
Explicit V1 deferrals
- SARIF
- coverage management
- non-JS adapters
- baselines
- managed installs
- separate
tsgoadapter
See docs/test-plans/openlint-v1.md and
docs/research/001-js-ts-v1-tool-contracts.md for details. See
docs/design/openlint-cli-spec.md for --rule and planning semantics. See
docs/recipes/tsx-view-boundary-custom-rules.md for a merge-tested ast-grep
custom-rule workflow against unstaged TSX changes.
