feat: wire Vale prose linter into docs CI (#25467)

Wires Vale into docs CI as an advisory (non-blocking) prose-lint step.
Closes [DOCS-40](https://linear.app/codercom/issue/DOCS-40).

> **Integration update (rebased onto `main`).** Since this branch was
opened, `main` consolidated docs linting into the **required**
`lint-docs` job in `ci.yaml` and removed the standalone `docs-ci.yaml`
([#25608](https://github.com/coder/coder/pull/25608)). This PR adds Vale
to that `lint-docs` job instead of resurrecting `docs-ci.yaml`, and the
`docs/.style/` scaffold defers to the merged
[#25466](https://github.com/coder/coder/pull/25466) (DOCS-180). Vale
stays advisory.

> **Post-review refactor.** Following the Coder Agents review, Vale is
now invoked through `mise exec "aqua:errata-ai/vale"` (the same pattern
as `actionlint`/`zizmor`) instead of a bespoke `curl`/`tar` download.
This removed the GNU-only `grep -oP` version extraction and `uname`/arch
mapping that broke on macOS BSD grep, and the prose step now skips paths
a PR deletes. See the resolved review threads for CRF-17/19/20/21/22.

A sample of what this check does is as follows:

<img width="1443" height="1293" alt="image"
src="https://github.com/user-attachments/assets/cf68dbf9-d9df-49ba-8dbf-200875bc289e"
/>

## What changes

- `.vale.ini` at the repo root: Google base + Coder (custom, empty in
v1) + curated write-good. `alex` rules are pulled in a la carte. Inline
comments justify every enable/disable.
- `mise.toml`: pin Vale `3.7.1` via aqua. `mise.lock`: lock that pin
across all platforms so `mise install --locked` (used by `build_image`)
resolves it.
- `Makefile`: a `docs/.style/.vale-synced` sentinel that gates `vale
sync`, and a `lint/prose` target that runs `vale --no-exit`. Both invoke
Vale via `mise exec "aqua:errata-ai/vale" -- vale ...`, so mise owns the
version and the OS/arch download (no hand-rolled install path).
- `.github/workflows/ci.yaml`: append Vale steps to the existing
required `lint-docs` job: `Detect changed Markdown`, `Restore Vale
styles`, `Prepare Vale styles` (`make docs/.style/.vale-synced`), `Vale
prose lint`, and a default-branch-only `Save Vale styles`. They lint
only changed Markdown under `docs/` that still exists on disk, with a
problem matcher for inline PR annotations.
- `.github/vale-problem-matcher.json`: parses `vale --output=line` so
alerts surface as annotations on the Files Changed tab.
- `.gitignore` and the workflow cache `path:`: use
`docs/.style/styles/*` plus a `!docs/.style/styles/Coder` negation so
adding a package does not require parallel edits.
- `.markdownlint-cli2.jsonc`: ignore the synced styles so `make
lint/markdown` does not lint upstream READMEs.

Scaffold prose under `docs/.style/` and
`.claude/docs/DOCS_STYLE_GUIDE.md` / `AGENTS.md` come from the merged
DOCS-180; this PR no longer touches them. Net diff against `main` is the
8 Vale-wiring files only.

## Severity policy (v1)

Rule severity reflects two things together: the rule's false-positive
rate against real Coder docs and the gravity of the rule. Low FPs plus
high gravity argues for `error`; lower gravity or more judgment calls
argue for `warning` or `suggestion`. v1 lands most rules at `warning`
and the wordiness rules at `suggestion`.

A rule promotes to `error` only when (a) its false-positive rate against
real content is effectively zero and (b) the existing-content violation
count for that rule is also zero. Vale exits non-zero only on
error-level alerts regardless of `MinAlertLevel`; the Makefile and CI
invoke Vale with `--no-exit` so the baseline error count from
un-overridden Google rules does not fail the build while real failures
(bad config, missing files) still propagate.

## CI integration

Vale runs as steps appended to the required `lint-docs` job in
`ci.yaml`, gated on changed Markdown:

1. **`Detect changed Markdown`** (`tj-actions/changed-files`) scopes to
changed `**.md`; the prose step re-filters to `docs/` (the `docs/**.md`
glob silently skips dot-prefixed dirs and would miss
`docs/.style/style-guide.md`).
2. **`Restore Vale styles`** (`actions/cache/restore`), keyed off
`hashFiles('.vale.ini', 'mise.toml', 'docs/.style/styles/Coder/**')`.
mise manages the Vale binary, so only the synced styles are cached.
3. **`Prepare Vale styles`** runs `make docs/.style/.vale-synced` (`mise
exec ... vale sync`).
4. **`Vale prose lint`** filters the changed set to `docs/` paths still
present on disk, then runs `mise exec ... vale --no-exit --output=line`,
emitting inline annotations via the problem matcher.
5. **`Save Vale styles`** writes the cache, gated to `refs/heads/main`
only so PR runs cannot poison the cache other branches restore from (the
zizmor `cache-poisoning` concern).

**Every Vale step is `continue-on-error: true`.** This is a deliberate
change from the original standalone-workflow design: now that Vale lives
inside the *required* `lint-docs` job, a transient `vale sync` network
failure (or first-use `mise` install blip) would otherwise block merges.
`continue-on-error` keeps Vale advisory, so only the markdownlint /
table-formatter checks above (`pnpm check-docs`) remain merge-blocking.
`vale --no-exit` additionally keeps the baseline error count from
un-overridden Google rules from failing the step.

## Verification

- `actionlint` clean on `ci.yaml` (local + `make
lint/actions/actionlint`); `zizmor --persona regular` reports no
findings.
- `make lint/prose` on the full `docs/` corpus: ~406 errors, ~5,346
warnings, ~7,928 suggestions across 461 files, exit 0 (`--no-exit`),
Vale `3.7.1` installed by mise.
- Net diff vs `main` is the 8 Vale-wiring files only; the `docs/.style/`
scaffold already matches `main`.

<details>
<summary>Implementation plan and decision log</summary>

### Why this rule set

The Vale evaluation against the full docs corpus (measured 2026-05-18)
produced ~43,940 raw violations across six candidate base styles. The
selection here drops Microsoft and RedHat (overlap with Google, and
RedHat's Spacing rule hammers technical IDs), and proselint (Annotations
rule treats `> [!NOTE]` admonitions as TODO markers).

Within the kept styles:

- **Google** is the base. Disables: `EmDash` (conflicts with `make
lint/emdash`), `Latin` (i.e./e.g. are fine for our audience), `Spacing`
(4,500 errors on `codersdk.SomeType` patterns in the auto-generated API
reference). Softened: `Parens` to `suggestion`, `WordList` to `warning`.
- **write-good** is the base, with `Passive` and `E-Prime` off.
`TooWordy` and `ThereIs` are suggestions; `Weasel` is a warning.
- **alex** is cherry-picked (not in `BasedOnStyles`): `Ablist`,
`Condescending`, `LGBTQ`, `ProfanityLikely`, `Race`, `Suicide` at
warning. The `ProfanityMaybe`/`ProfanityUnlikely` rules trip on
`execute`, `kill`, `failed`, and `attack`, which read as technical
vocabulary in our context.
- **Coder** is in `BasedOnStyles` but the directory is empty in v1.
Rules land through the per-rule tickets in the [Docs style
guide](https://linear.app/codercom/project/docs-style-guide-7828445b9afc)
project.

### Why `mise exec` instead of a download block

Vale is pinned in `mise.toml` like `actionlint` and `zizmor`, so
invoking it via `mise exec "aqua:errata-ai/vale" -- vale ...` makes the
pin the single source of truth and lets mise handle the OS/arch-specific
download. This replaced an earlier ~30-line `curl`/`tar` block whose
GNU-only `grep -oP ...\K` version extraction returned empty on macOS BSD
grep. Note: the bare `vale` short name in `mise exec` ignores the pin
and resolves to the latest release, so the full aqua key is required.

### Why `vale sync` instead of vendoring

The three style packages weigh ~272 KB combined, so vendoring is cheap.
But Vale's ecosystem treats `Packages = ` + `vale sync` as canonical,
the upstream LICENSE files are not in the package tarballs (would need
to be added manually), and the CI cache makes the sync nearly free after
the first run. Sticking with the canonical pattern keeps the repo lean
and the upgrade path obvious.

### Why `lint/prose` is not in `lint:` or `lint-light:`

Vale on the full docs corpus takes ~20s on cold caches. Forcing every
pre-commit through that would be aggressive for a feature that ships as
warnings. `make lint/typos` follows the same pattern (it is in
`lint-light` but not `lint`; CI invokes it directly). v1 keeps Vale
opt-in locally and CI-only by default; promote to `lint:` once the rule
set stabilizes.

### Exit-code handling

Two mechanisms combine, and the choice changed when the step moved into
the required `lint-docs` job:

- `vale --no-exit` suppresses Vale's non-zero exit on alerts, so the
baseline error-level violations from un-overridden Google rules do not
fail the step while the cleanup PRs land. Real failures (config invalid,
file missing) still exit non-zero.
- `continue-on-error: true` on every Vale step. Because the steps now
run inside the *required* `lint-docs` job, a `vale sync`
download/network blip must not block merges. The original (standalone,
non-required) design rejected `continue-on-error` for showing a
misleading yellow badge; in a required job that tradeoff flips, and
advisory-yellow is strictly preferable to merge-blocking-red on an
infrastructure flake. `|| true` in the Makefile was also rejected: it
swallows missing-config failures indiscriminately.

### Pre-mortem

- **Generated docs noise**: `docs/reference/` is dominated by
auto-generated content (clidocgen, apidocgen, auditdocgen,
metricsdocgen). The architectural decision is to fix the generators, not
exclude paths in Vale. Google.Spacing is the only rule silenced
specifically to defer the generator fix; everything else surfaces as
warnings.
- **First-run cost**: `mise` installs the pinned Vale (a single small
binary) and `vale sync` pulls the style packages on a cold run. The
Actions cache keyed off `hashFiles('.vale.ini', 'mise.toml',
'docs/.style/styles/Coder/**')` makes subsequent runs near-instant; the
`Coder/**` hash is defense-in-depth against
[actions/toolkit#713](https://github.com/actions/toolkit/issues/713) so
a future cache release that regresses path-negation cannot serve a stale
`Coder/` from cache.
- **Required-job blast radius**: moving Vale into the required
`lint-docs` job means any Vale step failure would gate merges. Mitigated
by `continue-on-error` on all Vale steps plus a clean skip when no
changed `docs/` Markdown remains on disk, so only `pnpm check-docs`
stays blocking.
- **Cross-platform install**: handled by mise (aqua backend) rather than
a hand-rolled `uname`/arch map, which removes the macOS BSD-grep break
the review flagged.
- **Deleted files**: `all_changed_files` is ACMRD and lists paths a PR
removes; the prose step filters to files still present on disk so Vale
does not error on a missing file.
- **Local-vs-CI parity**: CI lints changed files only; local `make
lint/prose` lints the full tree. This mirrors `make lint/markdown` (full
tree) vs the changed-files CI step. Acceptable for v1.

</details>

---

*Filed via [Coder Agents](https://coder.com/docs/ai-coder/agents) on
Nick's behalf.*
This commit is contained in:
Nick Vigilante
2026-06-22 14:14:31 -04:00
committed by GitHub
parent 917dbde439
commit ee3572ab9a
11 changed files with 311 additions and 8 deletions
+18
View File
@@ -0,0 +1,18 @@
{
"problemMatcher": [
{
"owner": "vale",
"severity": "warning",
"pattern": [
{
"regexp": "^(.+):(\\d+):(\\d+):([^:]+):(.+)$",
"file": 1,
"line": 2,
"column": 3,
"code": 4,
"message": 5
}
]
}
]
}
+90
View File
@@ -162,6 +162,96 @@ jobs:
- name: Check docs
run: pnpm check-docs
# Vale prose linter, advisory only. Scoped to changed Markdown under
# docs/. Every Vale step is `continue-on-error` so this section can
# never block the required `lint-docs` job: a `vale sync` network
# blip or a baseline rule violation surfaces as an annotation, not a
# merge gate. Only markdownlint/table-formatter above stay blocking.
# `vale --no-exit` additionally keeps the baseline error count from
# un-overridden upstream Google rules from failing the step. Lives
# here rather than a standalone workflow so docs lint stays in the
# single required CI umbrella (see #25608). See DOCS-40.
- name: Detect changed Markdown
id: changed-md
continue-on-error: true
uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v45.0.7
with:
files: |
**.md
separator: ","
# `**.md` (not `docs/**.md`) because the action's globber collapses a
# `**` adjacent to `.md` to a single path segment, so `docs/**.md`
# only matches top-level docs/*.md and misses nested pages such as
# docs/.style/style-guide.md. The prose step below re-filters to
# docs/ paths.
# Cache split into restore + conditional save to avoid letting PR
# runs populate a cache that other branches restore from (the
# zizmor `cache-poisoning` concern). Only pushes to the default
# branch may write the cache; PRs may only read it.
- name: Restore Vale styles
id: vale-cache
if: steps.changed-md.outputs.any_changed == 'true'
continue-on-error: true
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
# Negation excludes the hand-authored Coder rules from the cache;
# the key also hashes them so a rule change always invalidates it.
# mise manages the Vale binary, so only the synced styles cache.
path: |
docs/.style/styles/*
!docs/.style/styles/Coder
docs/.style/.vale-synced
key: vale-${{ hashFiles('.vale.ini', 'mise.toml', 'docs/.style/styles/Coder/**') }}
restore-keys: |
vale-
- name: Prepare Vale styles
if: steps.changed-md.outputs.any_changed == 'true'
continue-on-error: true
env:
# Non-interactive: let mise auto-install the pinned Vale on first use.
MISE_YES: "1"
run: make docs/.style/.vale-synced
- name: Vale prose lint
if: steps.changed-md.outputs.any_changed == 'true'
continue-on-error: true
env:
ALL_CHANGED_FILES: ${{ steps.changed-md.outputs.all_changed_files }}
# Non-interactive: let mise auto-install the pinned Vale on first use.
MISE_YES: "1"
run: |
# all_changed_files is ACMRD and so lists paths this PR deleted.
# Vale errors on a missing file (--no-exit only suppresses alert
# exits, not runtime errors), so keep only docs/ paths still on
# disk. See DOCS-40.
files=$(printf '%s\n' "$ALL_CHANGED_FILES" \
| tr ',' '\n' \
| grep -E '^docs/' \
| while IFS= read -r f; do [ -f "$f" ] && printf '%s\n' "$f"; done || true)
if [ -z "$files" ]; then
echo "No changed Markdown files under docs/ on disk; skipping Vale."
exit 0
fi
echo "::add-matcher::.github/vale-problem-matcher.json"
printf '%s\n' "$files" | xargs -d '\n' mise exec "aqua:errata-ai/vale" -- vale --no-exit --output=line
echo "::remove-matcher owner=vale::"
- name: Save Vale styles
# Only the default branch is trusted to write the cache, so PR
# runs cannot poison the cache that subsequent runs restore from.
# Skip when the cache already had an exact key hit (no new content).
if: github.ref == 'refs/heads/main' && steps.changed-md.outputs.any_changed == 'true' && steps.vale-cache.outputs.cache-hit != 'true'
continue-on-error: true
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: |
docs/.style/styles/*
!docs/.style/styles/Coder
docs/.style/.vale-synced
key: ${{ steps.vale-cache.outputs.cache-primary-key }}
# Disabled due to instability. See: https://github.com/coder/coder/issues/14553
# Re-enable once the flake hash calculation is stable.
# update-flake:
+8
View File
@@ -13,6 +13,14 @@ node_modules/
vendor/
yarn-error.log
# Vale (prose linter) pulls package contents into docs/.style/styles/ on
# `vale sync`. Each synced package directory and the sync sentinel are
# gitignored. The Coder/ directory next to them is tracked because it
# holds our custom rules.
docs/.style/.vale-synced
docs/.style/styles/*/
!docs/.style/styles/Coder/
# Test output files
test-output/
+9 -1
View File
@@ -1,3 +1,11 @@
{
"ignores": ["PLAN.md"],
"ignores": [
"PLAN.md",
// Synced Vale packages (pulled by `vale sync`). Keep aligned with the
// Packages directive in .vale.ini so markdownlint never lints upstream
// style files we did not author.
"docs/.style/styles/Google/**",
"docs/.style/styles/alex/**",
"docs/.style/styles/write-good/**"
],
}
+90
View File
@@ -0,0 +1,90 @@
# Vale configuration for Coder documentation.
#
# Curated cherry-pick of Google's developer-docs style, write-good (wordiness),
# and a hand-picked subset of alex (inclusive-language). The choice of base
# styles and disabled rules is documented in DOCS-40 and reproducible via
# `make lint/prose`.
#
# Severity policy. Rules sit at a level that reflects two things
# together: false-positive rate against real Coder docs and the gravity of
# the rule. Low FPs plus high gravity argues for `error`; lower gravity or
# more judgment calls argue for `warning` or `suggestion`. v1 lands most
# rules at `warning` and the wordiness rules at `suggestion`. Promote a
# rule to `error` only when (a) its false-positive rate against real
# content is effectively zero and (b) the existing-content violation count
# for that rule is also zero.
#
# About Vale's exit code: Vale exits non-zero only when error-level alerts
# are found, regardless of `MinAlertLevel`. The Makefile invokes Vale with
# `--no-exit` to suppress that exit while the un-overridden Google
# error-level rules still produce a baseline error count. Real failures
# (bad config, missing files) still propagate. See
# DOCS-40 for the rollout plan.
#
# The styles themselves live under docs/.style/styles/ after `vale sync`,
# which the Makefile target invokes once per .vale.ini change. They are
# gitignored to keep the repo lean.
StylesPath = docs/.style/styles
MinAlertLevel = suggestion
# Packages drives `vale sync`. Pin upstream tags here when reproducibility
# matters more than getting upstream fixes; the unpinned form pulls the
# latest release of each package on `vale sync`.
Packages = Google, alex, write-good
[*.md]
BasedOnStyles = Google, write-good, Coder
# --- Google curation -------------------------------------------------------
# Google.EmDash conflicts with our em-dash ban (see scripts/check_emdash.sh
# and DOCS-44). The repo-level ban covers Unicode U+2014/U+2013 plus the
# ` -- ` ASCII fallback; Google.EmDash would double-flag and use prose
# different from our policy.
Google.EmDash = NO
# Google.Latin flags i.e. and e.g. for non-native readers. Coder docs assume
# a technical audience that reads these fluently; leaving the rule on
# produces noise without value.
Google.Latin = NO
# Soften two high-volume Google rules. The signal-to-noise ratio is low
# at the default warning level.
Google.Parens = suggestion
Google.WordList = warning
# Google.Spacing flags fully-qualified Go type names like
# `codersdk.WorkspaceAgent` as "should have one space." It produces ~4,500
# errors against `docs/reference/api/schemas.md` alone (measured
# 2026-05-18) because codersdk type names match the pattern. The
# architectural decision for generated content is to fix the upstream
# Go generators (clidocgen, apidocgen, auditdocgen, metricsdocgen)
# rather than add Vale path exclusions; this disable buys time until
# those generator changes land. Re-enable then, ideally promoted to
# `error`.
Google.Spacing = NO
# --- write-good curation ---------------------------------------------------
# Passive voice is contextually correct often enough that flagging every
# instance teaches nothing. E-Prime forbids forms of "to be" entirely,
# which is incompatible with normal technical writing.
write-good.Passive = NO
write-good.E-Prime = NO
# Keep the three rules that catch real wordiness problems. Wordiness and
# ThereIs are judgment calls (suggestion); Weasel is sharper (warning).
write-good.TooWordy = suggestion
write-good.Weasel = warning
write-good.ThereIs = suggestion
# --- alex curation ---------------------------------------------------------
# alex is loaded a la carte rather than via BasedOnStyles. ProfanityMaybe
# and ProfanityUnlikely fire on technical terms like `execute`, `kill`,
# `failed`, and `attack`; ProfanityLikely is much more conservative and
# safe to keep on.
alex.Ablist = warning
alex.Condescending = warning
alex.LGBTQ = warning
alex.ProfanityLikely = warning
alex.Race = warning
alex.Suicide = warning
+29
View File
@@ -825,6 +825,35 @@ lint/typos:
typos --config .github/workflows/typos.toml
.PHONY: lint/typos
# Vale (prose linter).
#
# Invoked through `mise exec` like actionlint and zizmor above, so the
# version pinned in mise.toml ("aqua:errata-ai/vale") is the single source
# of truth and mise downloads the right OS/arch build. Always pass the full
# aqua key: the bare `vale` short name ignores the pin and resolves to the
# latest release.
# `vale sync` pulls the packages listed in .vale.ini's Packages directive
# into StylesPath (docs/.style/styles/). The .vale-synced sentinel makes
# sync idempotent across `make lint/prose` calls and lets warm checkouts
# skip the re-sync entirely. Make rebuilds this target when `.vale.ini`
# changes.
docs/.style/.vale-synced: .vale.ini
@echo "$(GREEN)==>$(RESET) $(BOLD)vale sync$(RESET)"
mise exec "aqua:errata-ai/vale" -- vale sync
@touch $@
# Vale exits non-zero only on error-level alerts. `--no-exit` keeps the
# target green while the un-overridden Google error-level rules still
# produce a baseline error count; real failures (bad config, missing
# files) still propagate. Once the baseline error count reaches zero, drop
# `--no-exit` and surface error-level violations as real failures. See
# DOCS-40.
lint/prose: docs/.style/.vale-synced
@echo "$(GREEN)==>$(RESET) $(BOLD)lint/prose$(RESET)"
mise exec "aqua:errata-ai/vale" -- vale --no-exit docs/
.PHONY: lint/prose
# pre-commit and pre-push mirror CI checks locally.
#
# pre-commit runs checks that don't need external services (Docker,
+5 -4
View File
@@ -18,8 +18,8 @@ elsewhere (blog, changelog, Support KB, etc.).
See [`style-guide.md`](style-guide.md) for the prose style guide. The
`styles/Coder/` directory holds the custom Vale rules that enforce parts
of the guide; Vale's `StylesPath` in the repo-root `.vale.ini` (added in
a follow-up PR) points at `docs/.style/styles/`.
of the guide; Vale's `StylesPath` in the repo-root `.vale.ini` points at
`docs/.style/styles/`.
## Why a hidden directory
@@ -56,8 +56,9 @@ directory from the surgical-reindex payload on mixed commits.
`markdownlint-cli2 --fix $(find docs -name '*.md')`.
- `make fmt/markdown` (markdown-table-formatter) reflows tables here for
the same reason.
- Vale, once `.vale.ini` lands in a follow-up PR, lints the entire
`docs/**/*.md` set including `docs/.style/style-guide.md`.
- Vale lints the entire `docs/**/*.md` set, including
`docs/.style/style-guide.md`. See the repo-root `.vale.ini` for the
active configuration; run `make lint/prose` locally to reproduce.
## What does not run against this directory
+2 -1
View File
@@ -76,7 +76,8 @@ The repo-root `.vale.ini` configures Vale to read styles from
- Coder-specific custom rules in `docs/.style/styles/Coder/`
The rationale for the cherry-picked base styles and the severity
policy lives in the follow-up PR that lands `.vale.ini`.
policy lives in `.vale.ini`'s inline comments. Run `make lint/prose`
to reproduce the baseline locally.
## Editor setup
+11 -2
View File
@@ -32,8 +32,17 @@ following third-party references:
## Tools
The following are tools that you can use to edit your writing. However, take the
suggestions provided with a grain of salt.
This repository runs [Vale](https://vale.sh/) on `docs/` as part of CI to
enforce prose style. The configuration is the repo-root `.vale.ini`, and
the curated rule set is documented in
[`docs/.style/style-guide.md`](../../.style/style-guide.md). Run the same
checks locally with `make lint/prose`. Vale runs in advisory mode in
this iteration: warnings surface as inline PR annotations, but they don't
block the build.
The following external tools can also help when drafting. Take their
suggestions with a grain of salt because they aren't tuned for Coder's
voice or product names:
- [alex.js](https://alexjs.com/)
- [Grammarly](https://app.grammarly.com/)
+48
View File
@@ -144,6 +144,54 @@ url = "https://github.com/crate-ci/typos/releases/download/v1.46.1/typos-v1.46.1
checksum = "sha256:a7b042fc79bf7b73b00ece054ec3109858e001136c2642f28004544b571d37a2"
url = "https://github.com/crate-ci/typos/releases/download/v1.46.1/typos-v1.46.1-x86_64-pc-windows-msvc.zip"
[[tools."aqua:errata-ai/vale"]]
version = "3.7.1"
backend = "aqua:errata-ai/vale"
[tools."aqua:errata-ai/vale"."platforms.linux-arm64"]
checksum = "sha256:c485582de0dea90cded2e4b5c560d6129b3b2f160139af2195020a284f8a1670"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_arm64.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.linux-arm64-musl"]
checksum = "sha256:c485582de0dea90cded2e4b5c560d6129b3b2f160139af2195020a284f8a1670"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_arm64.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.linux-x64"]
checksum = "sha256:ba4924bf2c5884499f09b02a6eb3318b29df40a3e81701c0804b9b1aefcd9483"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.linux-x64-baseline"]
checksum = "sha256:ba4924bf2c5884499f09b02a6eb3318b29df40a3e81701c0804b9b1aefcd9483"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.linux-x64-musl"]
checksum = "sha256:ba4924bf2c5884499f09b02a6eb3318b29df40a3e81701c0804b9b1aefcd9483"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.linux-x64-musl-baseline"]
checksum = "sha256:ba4924bf2c5884499f09b02a6eb3318b29df40a3e81701c0804b9b1aefcd9483"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Linux_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.macos-arm64"]
checksum = "sha256:88c9e562bc0bb614f11fa2933a430ca087f9e4d949bd3968f49258617765c79f"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_macOS_arm64.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.macos-x64"]
checksum = "sha256:878775cbebffe93ad2381779e964428f38822dfba32625885d899a0cef429d8b"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_macOS_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.macos-x64-baseline"]
checksum = "sha256:878775cbebffe93ad2381779e964428f38822dfba32625885d899a0cef429d8b"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_macOS_64-bit.tar.gz"
[tools."aqua:errata-ai/vale"."platforms.windows-x64"]
checksum = "sha256:9f14a2552c9efe65e0ab5ef8e45cf01ce89733b436687d68faef7b147c5cfc71"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Windows_64-bit.zip"
[tools."aqua:errata-ai/vale"."platforms.windows-x64-baseline"]
checksum = "sha256:9f14a2552c9efe65e0ab5ef8e45cf01ce89733b436687d68faef7b147c5cfc71"
url = "https://github.com/vale-cli/vale/releases/download/v3.7.1/vale_3.7.1_Windows_64-bit.zip"
[[tools."aqua:jj-vcs/jj"]]
version = "0.41.0"
backend = "aqua:jj-vcs/jj"
+1
View File
@@ -63,6 +63,7 @@ zizmor = "1.11.0"
# `coder external-auth` into `gh`, and a mise shim earlier in
# PATH would bypass it.
"aqua:crate-ci/typos" = "1.46.1"
"aqua:errata-ai/vale" = "3.7.1"
"aqua:jj-vcs/jj" = "0.41.0"
"aqua:watchexec/watchexec" = "2.5.1"
doctl = "1.158.0"