preflight

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

preflight

preflight

Change-gated, branch-scoped lint preflight. It lints only the categories relevant to
origin/<base>...HEAD
, on changed paths only — not a whole-repo
pnpm lint
— then classifies each violation as introduced (on a line this branch added or changed) or pre-existing (already there, in a file the branch happens to touch).
This skill is the single source of truth for the preflight loop. It is invoked two ways:
  • Standalone (
    /preflight
    ) — a quick "will my branch pass scoped lint?" check, leaving any fixes in the working tree.
  • Inside a ship flow (e.g.
    /send-it
    ) — the lint gate that runs after commits and before the changelog/push steps.
All bundled scripts use only Node built-ins — no
npm install
, no build step. They operate on the consumer repo's root (run them from the repo root, where
git
resolves the branch diff).
基于变更校验的、分支范围的Lint预检工具。它仅针对
origin/<base>...HEAD
相关的类别,只在变更路径上执行Lint——而非全仓库的
pnpm lint
——然后将每个违规项分为新增(分支添加或修改的行)或已有(文件中原本就存在,只是分支恰好触及该文件)。
这个Skill是预检循环的唯一可信来源。它有两种调用方式:
  • 独立运行
    /preflight
    )——快速检查“我的分支能否通过范围化Lint?”,修复内容留在工作区。
  • 在发布流程中运行(例如
    /send-it
    )——作为Lint校验关卡,在提交后、变更日志/推送步骤前执行。
所有捆绑脚本仅使用Node内置模块——无需
npm install
,无需构建步骤。它们在使用该工具的仓库根目录运行(从仓库根目录执行,
git
会解析分支差异)。

Running it

运行步骤

  1. Make sure the base branch is up to date:
    git fetch origin <base>
    (the base is auto-detected — see Configuration).
  2. Run the preflight:
    node skills/preflight/scripts/preflight.mjs
    (append
    --dry-run
    to report categories and scoped file lists without classifying violations).
    --dry-run
    is a true preview — every linter reports
    would-run
    and nothing is written, including
    .preflight-summary.json
    .
  3. Read
    .preflight-summary.json
    for the categories run and the violation counts (
    passed
    ,
    deferred
    ,
    blocking
    ). Written only on a real run, not under
    --dry-run
    . It is a transient scratch artefact, never committed — consumer repos gitignore it (the
    initialise-skills
    skill adds the entry when it reconciles a repo).
The script's exit code drives the loop:
  • Exit 0 — pass. No introduced violations and every linter ran cleanly. Continue.
  • Exit 1 — introduced violations (blocking). Run
    node skills/preflight/scripts/lint-fix.mjs
    on the branch-scoped paths, then re-run preflight. Repeat until introduced violations clear or the user aborts. (Inside a ship flow, commit the fixes; standalone, leave them in the working tree for the user to review and commit.) Only introduced errors block by default — introduced ESLint warnings are reported as a non-blocking notice and don't fail the gate, matching
    pnpm lint
    / CI (which exit 0 on warnings). Set
    blockOnWarnings: true
    to gate on them too (see Configuration).
  • Exit 2 — pre-existing violations only. Show the list and ask the user to choose:
    • Fix now — apply the fixes, (commit if shipping), re-run preflight.
    • Defer — open a debt issue in the project's tracker (assign the maintainer; link the branch/PR context), then decide whether to continue or abort.
Exit 1 can also signal a linter that failed to run (non-zero exit with no parseable violations) — inspect its stderr; this is blocking too.
  1. 确保基准分支是最新的:
    git fetch origin <base>
    (基准分支会自动检测——见配置部分)。
  2. 运行预检:
    node skills/preflight/scripts/preflight.mjs
    (添加
    --dry-run
    参数可报告类别和范围化文件列表,但不会分类违规项)。
    --dry-run
    是真实预览——每个Linter都会报告
    would-run
    ,不会写入任何内容,包括
    .preflight-summary.json
  3. 读取
    .preflight-summary.json
    获取已运行的类别和违规计数(
    passed
    deferred
    blocking
    )。仅在真实运行时写入,
    --dry-run
    模式下不会生成。这是一个临时文件,永远不会提交——使用该工具的仓库会忽略它(
    initialise-skills
    Skill在协调仓库时会添加忽略条目)。
脚本的退出码驱动循环:
  • 退出码0——通过。没有新增违规,所有Linter运行正常。继续流程。
  • 退出码1——新增违规(阻塞)。在分支范围路径上运行
    node skills/preflight/scripts/lint-fix.mjs
    ,然后重新运行预检。重复直到新增违规清除或用户中止。(在发布流程中,提交修复;独立运行时,修复内容留在工作区供用户审核和提交。)默认情况下仅新增_错误_会阻塞——新增的ESLint警告会作为非阻塞通知报告,不会导致校验关卡失败,与
    pnpm lint
    /CI的行为一致(警告时退出码为0)。如果需要也拦截警告,设置
    blockOnWarnings: true
    (见配置部分)。
  • 退出码2——仅存在已有违规。显示列表并让用户选择:
    • 立即修复——应用修复,(如果是发布流程则提交),重新运行预检。
    • 延迟处理——在项目跟踪器中创建一个债务问题(分配给维护者;关联分支/PR上下文),然后决定继续还是中止。
退出码1也可能表示Linter运行失败(非零退出且无可解析的违规)——检查其stderr;这也会阻塞流程。

Categories

类别

Each category is gated on what the branch changed (mirrors CI path triggers, narrower scope):
CategoryRuns whenSkipped when
ESLintBranch diff includes lintable code or eslint/tsconfig config pathsMarkdown-only or non-lintable changes
markdownlintBranch diff includes
.md
/
.mdx
(respecting repo ignores)
No markdown changes; warns and skips if the
markdownlint-cli2
binary is missing
actionlintBranch diff includes
.github/workflows/*.yml
or
.github/actionlint.yaml
No workflow changes; config-only changes lint all tracked workflows; warns and skips if
actionlint
binary missing
ESLint runs per workspace (via
pnpm --filter
), plus a root/scripts bucket. Typecheck, tests, and framework checks (e.g.
astro check
) are not part of preflight — they stay in CI.
每个类别是否执行取决于分支的变更内容(镜像CI路径触发器,范围更窄):
类别执行时机跳过时机
ESLint分支差异包含可Lint的代码或eslint/tsconfig配置路径时仅Markdown变更或不可Lint的变更时
markdownlint分支差异包含
.md
/
.mdx
文件(遵循仓库忽略规则)时
无Markdown变更;如果
markdownlint-cli2
二进制文件缺失则发出警告并跳过
actionlint分支差异包含
.github/workflows/*.yml
.github/actionlint.yaml
文件时
无工作流变更;仅配置变更时会Lint所有已跟踪的工作流;如果
actionlint
二进制文件缺失则发出警告并跳过
ESLint按工作区运行(通过
pnpm --filter
),加上根目录/脚本目录。类型检查、测试和框架检查(例如
astro check
不属于预检的一部分——它们留在CI中执行。

Standalone vs inside a ship flow

独立运行 vs 发布流程中运行

  • Standalone (
    /preflight
    )
    does the lint preflight and the exit-code loop, then reports. On introduced violations it may run
    node skills/preflight/scripts/lint-fix.mjs
    and re-run, but it leaves fixes in the working tree — it never commits, writes a changelog, pushes, or opens a PR.
  • Inside
    /send-it
    the same loop runs as the lint gate (after commits, before changelog work); fixes are committed so the branch is clean before the changelog is written. The changelog and its validation are separate gates owned by the ship flow — they are not part of this skill.
  • 独立运行(
    /preflight
    执行Lint预检和退出码循环,然后报告结果
    。如果有新增违规,它可能会运行
    node skills/preflight/scripts/lint-fix.mjs
    并重新运行,但修复内容留在工作区——它永远不会提交、写入变更日志、推送或打开PR。
  • /send-it
    中运行
    时,同样的循环作为Lint校验关卡运行(提交后、变更日志编写前);修复内容会被提交,以便分支在编写变更日志前保持干净。变更日志及其验证是发布流程独立的校验关卡——不属于本Skill的一部分。

Configuration

配置

The two repo-specific inputs are auto-detected — a consuming repo edits nothing in the common case:
  • Linted workspaces are derived from
    pnpm-workspace.yaml
    plus each package's
    package.json
    : a workspace is included only if it declares a
    lint
    script. This auto-excludes intentionally-unlinted workspaces and non-package directories without a hand-maintained list.
  • Base branch is detected from
    origin/HEAD
    (e.g.
    main
    ,
    master
    ,
    develop
    ), falling back to
    main
    when that symbolic ref is absent.
To override either, add a
preflight.config.json
at the consumer repo root (a
config.example.json
ships beside this file as a template):
json
{
  "baseBranch": "main",
  "blockOnWarnings": false,
  "workspaces": {
    "web": { "filter": "@acme/web", "prefix": "apps/web/" }
  }
}
Any key may be supplied on its own; the others are still auto-detected/defaulted. Use the override for non-pnpm repos, deliberate exclusions, or nested workspace globs the detector does not expand.
  • blockOnWarnings
    (default
    false
    ) — whether introduced ESLint warning-severity findings block the gate. Off by default, preflight blocks only on introduced errors (and linters that fail to run); introduced warnings are surfaced non-blockingly, matching
    pnpm lint
    / CI semantics. Set
    true
    for repos that want warn-level findings the branch adds to gate as well. markdownlint/actionlint findings always block — the warn/error split is ESLint-only.
两个仓库特定的输入会自动检测——一般情况下使用该工具的仓库无需编辑任何内容:
  • Lint工作区
    pnpm-workspace.yaml
    以及每个包的
    package.json
    派生:只有声明了
    lint
    脚本的工作区才会被包含。这会自动排除有意不Lint的工作区和没有
    package.json
    的非包目录,无需手动维护列表。
  • 基准分支
    origin/HEAD
    检测(例如
    main
    master
    develop
    ),如果该符号引用不存在则回退到
    main
要覆盖任意一项,在使用该工具的仓库根目录添加
preflight.config.json
(本文件附带一个
config.example.json
作为模板):
json
{
  "baseBranch": "main",
  "blockOnWarnings": false,
  "workspaces": {
    "web": { "filter": "@acme/web", "prefix": "apps/web/" }
  }
}
可以只提供任意一个键;其他键仍会自动检测/使用默认值。对于非pnpm仓库、有意排除的工作区,或者检测器无法展开的嵌套工作区通配符,使用覆盖配置。
  • blockOnWarnings
    (默认
    false
    )——新增的ESLint警告级别的发现是否会阻塞校验关卡。默认关闭,预检仅拦截新增的错误(以及运行失败的Linter);新增的警告会以非阻塞方式显示,与
    pnpm lint
    /CI的语义一致。如果仓库希望分支新增的警告级发现也触发校验关卡拦截,设置为
    true
    。markdownlint/actionlint的发现始终会阻塞——仅ESLint区分警告/错误。

Implementation

实现细节

The bundled scripts live beside this file under
scripts/
and are invoked directly with
node
— no
pnpm
aliases, no
npm install
:
  • scripts/preflight.mjs
    — the change-gated preflight and exit-code contract.
  • scripts/lint-fix.mjs
    — scoped
    eslint --fix
    /
    markdownlint-cli2 --fix
    on the branch-changed paths.
  • scripts/classify-lint.mjs
    — parse + classify violations as introduced vs pre-existing.
  • scripts/lib/{scope,diff-lines,paths}.mjs
    — shared helpers (workspace/base-branch detection, diff-line mapping, path normalisation).
They have no external npm dependencies (Node built-ins only).
捆绑的脚本位于本文件旁边的
scripts/
目录下,直接用
node
调用——无需pnpm别名,无需
npm install
  • scripts/preflight.mjs
    ——基于变更的预检和退出码约定。
  • scripts/lint-fix.mjs
    ——对分支变更路径执行范围化的
    eslint --fix
    /
    markdownlint-cli2 --fix
  • scripts/classify-lint.mjs
    ——解析并将违规分类为新增或已有。
  • scripts/lib/{scope,diff-lines,paths}.mjs
    ——共享辅助工具(工作区/基准分支检测、差异行映射、路径规范化)。
它们没有外部npm依赖(仅使用Node内置模块)。

Arguments

参数

$ARGUMENTS
$ARGUMENTS