chore: enforce max-lines suppression ratchet (#107315)

* ci: enforce max-lines suppression ratchet

* chore: prune stale max-lines suppression

* fix: close max-lines ratchet enforcement gaps

* fix: harden max-lines ratchet checks

* fix(ci): satisfy max-lines ratchet checks

* style: format max-lines declarations

* fix(ci): match oxlint suppression grammar

* test: isolate max-lines git fixtures

* chore: prune resolved max-lines debt

* test: skip newline path fixture on Windows

* fix: harden max-lines suppression ratchet

* chore: refresh max-lines baseline

* fix: close max-lines ratchet bypasses

* fix: derive ratchet base from PR merge tree

* fix: support older Git in staged ratchet

* fix: align max-lines declarations and baseline

* chore: refresh max-lines baseline for current main

* fix: exclude generated wizard locales from max-lines

* chore: prune resolved max-lines debt
This commit is contained in:
Peter Steinberger
2026-07-14 09:27:02 -07:00
committed by GitHub
parent cbe012ec70
commit f81f9d8570
1257 changed files with 3581 additions and 1015 deletions
+8 -9
View File
@@ -215,16 +215,15 @@ Stop watchers before ending the turn or switching strategy.
failed child; never rebuild an immutable version that already published
7. If a required PR CI run is capacity-stalled with queued jobs and no active
jobs, do not cancel unrelated work or accept a generic manual dispatch.
First check the target-owned workflow with `git show
<full-pr-sha>:.github/workflows/ci.yml | rg -q '^ +pr_number:'`. When it
declares `pr_number`, dispatch the explicit exact-SHA fallback:
First verify the PR head carries the current fallback schema:
`gh api 'repos/openclaw/openclaw/contents/.github/workflows/ci.yml?ref=<pr-head-branch>'
--jq .content | base64 --decode | rg -q 'pull_request_number:'`. If absent,
refresh the PR head from `main` and use the new head SHA; let normal CI run
before considering another fallback.
From the PR head branch, dispatch the explicit exact-SHA fallback:
`gh workflow run ci.yml --repo openclaw/openclaw --ref <pr-head-branch> -f
target_ref=<full-pr-sha> -f pr_number=<pr-number> -f include_android=true -f
release_gate=true`.
The workflow authenticates that PR's head/base, validates GitHub's current
synthetic merge tree, and runs the LOC task from that tree. Older workflow
schemas cannot provide equivalent LOC evidence; update the head to contain the current `pr_number` workflow, then
restart exact-head proof on the new SHA instead of dispatching them.
target_ref=<full-pr-sha> -f pull_request_number=<pr-number> -f
include_android=true -f release_gate=true`.
It runs on GitHub-hosted runners and is accepted only when its run title is
`CI release gate <full-pr-sha>`. Record the stalled Blacksmith run and the
fallback run in release evidence.
@@ -167,16 +167,14 @@ a workflow fix that the existing parent run cannot consume.
gates on the newly pushed SHA, then run `prepare-run` again.
- If an exact PR-head CI run has no active jobs because Blacksmith capacity is
stalled, a maintainer may dispatch the explicit GitHub-hosted fallback from
the PR head branch. Check the target-owned workflow with `git show
<full-pr-sha>:.github/workflows/ci.yml | rg -q '^ +pr_number:'`. When it
declares `pr_number`, run:
the PR head branch. First verify its workflow carries the current schema with
`gh api 'repos/openclaw/openclaw/contents/.github/workflows/ci.yml?ref=<pr-head-branch>'
--jq .content | base64 --decode | rg -q 'pull_request_number:'`. If absent,
refresh the PR head from `main`, use the new SHA, and let normal CI run before
considering another fallback. Then dispatch:
`gh workflow run ci.yml --repo openclaw/openclaw --ref <pr-head-branch> -f
target_ref=<full-pr-sha> -f pr_number=<pr-number> -f include_android=true -f
release_gate=true`.
The workflow authenticates that PR's head/base, validates GitHub's current
synthetic merge tree, and runs the LOC task from that tree. Older workflow
schemas cannot provide equivalent LOC evidence; update the head to contain the current `pr_number` workflow, then
restart exact-head proof on the new SHA instead of dispatching them.
target_ref=<full-pr-sha> -f pull_request_number=<pr-number> -f
include_android=true -f release_gate=true`.
Use it only for an observed provider queue stall, never for failed CI or as a
routine shortcut. The run must be named `CI release gate <full-pr-sha>` and
pass on that exact SHA; the native hosted-gate verifier rejects generic manual
+123 -131
View File
@@ -8,16 +8,6 @@ on:
required: false
default: ""
type: string
pr_number:
description: Pull request number required by the exact-SHA release gate
required: false
default: ""
type: string
loc_base_ref:
description: Optional exact LOC comparison-base SHA for standalone manual runs
required: false
default: ""
type: string
include_android:
description: Run Android lanes for this manual CI dispatch.
required: false
@@ -28,6 +18,11 @@ on:
required: false
default: false
type: boolean
pull_request_number:
description: Pull request number required by the exact-SHA release gate.
required: false
default: ""
type: string
dispatch_id:
description: Optional parent workflow dispatch identifier
required: false
@@ -89,15 +84,12 @@ jobs:
preflight:
permissions:
contents: read
pull-requests: read
needs: [runner-admission]
if: github.event_name != 'pull_request' || !github.event.pull_request.draft
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
timeout-minutes: 20
outputs:
checkout_revision: ${{ steps.checkout_ref.outputs.sha }}
loc_base_sha: ${{ steps.release_gate_loc_tree.outputs.base_sha || inputs.loc_base_ref || '' }}
loc_head_sha: ${{ steps.release_gate_loc_tree.outputs.head_sha || '' }}
docs_only: ${{ steps.manifest.outputs.docs_only }}
docs_changed: ${{ steps.manifest.outputs.docs_changed }}
run_node: ${{ steps.manifest.outputs.run_node }}
@@ -141,7 +133,8 @@ jobs:
- name: Validate release-gate dispatch
if: github.event_name == 'workflow_dispatch' && inputs.release_gate
env:
PR_NUMBER: ${{ inputs.pr_number }}
HISTORICAL_TARGET_TAG: ${{ inputs.historical_target_tag }}
PULL_REQUEST_NUMBER: ${{ inputs.pull_request_number }}
TARGET_REF: ${{ inputs.target_ref }}
run: |
set -euo pipefail
@@ -151,8 +144,8 @@ jobs:
exit 1
fi
if [[ ! "$PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
echo "release_gate requires pr_number to identify an open pull request" >&2
if [[ ! "$PULL_REQUEST_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
echo "release_gate requires pull_request_number" >&2
exit 1
fi
@@ -161,14 +154,8 @@ jobs:
exit 1
fi
- name: Validate manual LOC base input
if: github.event_name == 'workflow_dispatch' && inputs.loc_base_ref != ''
env:
LOC_BASE_REF: ${{ inputs.loc_base_ref }}
run: |
set -euo pipefail
if [[ ! "$LOC_BASE_REF" =~ ^[0-9a-f]{40}$ ]]; then
echo "loc_base_ref must be a full commit SHA" >&2
if [[ -n "$HISTORICAL_TARGET_TAG" ]]; then
echo "release_gate cannot be combined with historical_target_tag" >&2
exit 1
fi
@@ -255,67 +242,6 @@ jobs:
id: checkout_ref
run: echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
- name: Validate release-gate PR merge tree
id: release_gate_loc_tree
if: github.event_name == 'workflow_dispatch' && inputs.release_gate
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ inputs.pr_number }}
TARGET_REF: ${{ inputs.target_ref }}
run: |
set -euo pipefail
merge_sha=""
pr_base_sha=""
for attempt in {1..12}; do
pr_json="$(gh api --method GET "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}")"
pr_state="$(jq -r '.state // ""' <<<"$pr_json")"
pr_head_sha="$(jq -r '.head.sha // ""' <<<"$pr_json")"
pr_base_sha="$(jq -r '.base.sha // ""' <<<"$pr_json")"
pr_base_repo="$(jq -r '.base.repo.full_name // ""' <<<"$pr_json")"
if [[ "$pr_state" != "open" || "$pr_base_repo" != "$GITHUB_REPOSITORY" ]]; then
echo "release_gate pr_number must identify an open pull request in ${GITHUB_REPOSITORY}" >&2
exit 1
fi
if [[ "$pr_head_sha" != "$TARGET_REF" ]]; then
echo "release_gate target_ref must match pull request ${PR_NUMBER} head ${pr_head_sha}" >&2
exit 1
fi
if [[ ! "$pr_base_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Could not resolve pull request ${PR_NUMBER} base SHA." >&2
exit 1
fi
mergeable="$(jq -r 'if .mergeable == null then "pending" else (.mergeable | tostring) end' <<<"$pr_json")"
if [[ "$mergeable" == "true" ]]; then
merge_sha="$(jq -r '.merge_commit_sha // ""' <<<"$pr_json")"
if [[ ! "$merge_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Could not resolve pull request ${PR_NUMBER} test merge commit." >&2
exit 1
fi
break
fi
if [[ "$mergeable" == "false" ]]; then
echo "Pull request ${PR_NUMBER} is not mergeable with its current base." >&2
exit 1
fi
if [[ "$attempt" == "12" ]]; then
echo "Timed out waiting for pull request ${PR_NUMBER} mergeability." >&2
exit 1
fi
sleep 2
done
merge_ref="refs/remotes/origin/release-gate-merge"
git fetch --no-tags --depth=2 origin \
"+refs/pull/${PR_NUMBER}/merge:${merge_ref}"
resolved_merge_sha="$(git rev-parse "$merge_ref")"
merge_base_parent="$(git rev-parse "${merge_ref}^1")"
merge_head_parent="$(git rev-parse "${merge_ref}^2")"
if [[ "$resolved_merge_sha" != "$merge_sha" || "$merge_base_parent" != "$pr_base_sha" || "$merge_head_parent" != "$TARGET_REF" ]]; then
echo "release_gate pull request merge ref does not match the current base and head" >&2
exit 1
fi
echo "base_sha=${pr_base_sha}" >> "$GITHUB_OUTPUT"
echo "head_sha=${merge_sha}" >> "$GITHUB_OUTPUT"
- name: Validate historical release target
id: historical_target
if: inputs.historical_target_tag != ''
@@ -404,7 +330,6 @@ jobs:
OPENCLAW_CI_RUN_CONTROL_UI_I18N: ${{ github.event_name == 'workflow_dispatch' && 'true' || steps.changed_scope.outputs.run_control_ui_i18n || 'false' }}
OPENCLAW_CI_RUN_UI_TESTS: ${{ github.event_name == 'workflow_dispatch' && 'true' || steps.changed_scope.outputs.run_ui_tests || 'false' }}
OPENCLAW_CI_RUN_NATIVE_I18N: ${{ github.event_name == 'workflow_dispatch' && 'true' || steps.changed_scope.outputs.run_native_i18n || 'false' }}
OPENCLAW_CI_RUN_TS_LOC: ${{ github.event_name == 'workflow_dispatch' && 'true' || steps.changed_scope.outputs.run_ts_loc || 'false' }}
OPENCLAW_CI_CHANGED_PATHS_JSON: ${{ steps.changed_scope.outputs.changed_paths_json || 'null' }}
OPENCLAW_CI_CHECKOUT_REVISION: ${{ steps.checkout_ref.outputs.sha }}
OPENCLAW_CI_HISTORICAL_TARGET: ${{ steps.historical_target.outputs.eligible || 'false' }}
@@ -551,7 +476,6 @@ jobs:
parseBoolean(process.env.OPENCLAW_CI_RUN_NATIVE_I18N) &&
!docsOnly &&
(!frozenTarget || supportsNativeI18n);
const runTsLoc = parseBoolean(process.env.OPENCLAW_CI_RUN_TS_LOC) && !docsOnly;
const targetWorkflow = existsSync(".github/workflows/ci.yml")
? readFileSync(".github/workflows/ci.yml", "utf8")
: "";
@@ -560,8 +484,15 @@ jobs:
const supportsFormatCheck =
targetWorkflow.split("pnpm format:check").length - 1 >= 2;
const runFormatCheck = !frozenTarget || supportsFormatCheck;
const checksFastCoreTasks = runTsLoc
? [{ check_name: "checks-fast-loc-ratchet", runtime: "node", task: "loc-ratchet" }]
const checksFastCoreTasks =
runNode && !frozenTarget
? [
{
check_name: "checks-fast-max-lines-ratchet",
runtime: "node",
task: "max-lines-ratchet",
},
]
: [];
if (runNodeFull) {
checksFastCoreTasks.push(
@@ -1233,6 +1164,7 @@ jobs:
checks-fast-core:
permissions:
contents: read
pull-requests: read
name: ${{ matrix.check_name }}
needs: [preflight]
if: needs.preflight.outputs.run_checks_fast_core == 'true'
@@ -1244,26 +1176,56 @@ jobs:
matrix: ${{ fromJson(needs.preflight.outputs.checks_fast_core_matrix) }}
steps:
- *linux_node_checkout_step
- name: Checkout verified release-gate LOC merge tree
if: matrix.task == 'loc-ratchet' && needs.preflight.outputs.loc_head_sha != ''
- name: Prepare release-gate max-lines merge tree
if: matrix.task == 'max-lines-ratchet' && github.event_name == 'workflow_dispatch' && inputs.release_gate
env:
LOC_HEAD_SHA: ${{ needs.preflight.outputs.loc_head_sha }}
LOC_PR_NUMBER: ${{ inputs.pr_number }}
GH_TOKEN: ${{ github.token }}
PULL_REQUEST_NUMBER: ${{ inputs.pull_request_number }}
TARGET_SHA: ${{ inputs.target_ref }}
shell: bash
run: |
set -euo pipefail
if [[ ! "$LOC_PR_NUMBER" =~ ^[1-9][0-9]*$ ]]; then
echo "A release-gate LOC head requires a pull request number." >&2
prepared=false
for attempt in {1..6}; do
pr_info="$(
gh api --method GET "repos/${GITHUB_REPOSITORY}/pulls/${PULL_REQUEST_NUMBER}" |
jq -r --arg repo "$GITHUB_REPOSITORY" --arg target "$TARGET_SHA" '
select(.state == "open" and .head.sha == $target and .base.repo.full_name == $repo)
| [.base.sha, (if .mergeable == null then "unknown" else (.mergeable | tostring) end)]
| @tsv
'
)"
if [[ -z "$pr_info" ]]; then
echo "release-gate pull request must be open and match the target head" >&2
exit 1
fi
IFS=$'\t' read -r base_sha mergeable <<<"$pr_info"
if [[ "$mergeable" == "false" ]]; then
echo "release-gate pull request is not mergeable" >&2
exit 1
fi
if [[ "$mergeable" == "true" ]] &&
git fetch --no-tags --depth=2 origin \
"+refs/pull/${PULL_REQUEST_NUMBER}/merge:refs/remotes/origin/ci-max-lines-merge"; then
merge_sha="$(git rev-parse refs/remotes/origin/ci-max-lines-merge)"
read -r merge_base merge_head extra_parent <<<"$(git show -s --format=%P "$merge_sha")"
if [[ "$merge_base" == "$base_sha" && "$merge_head" == "$TARGET_SHA" && -z "$extra_parent" ]]; then
prepared=true
break
fi
fi
if [[ "$attempt" != "6" ]]; then
sleep 5
fi
done
if [[ "$prepared" != "true" ]]; then
echo "release-gate merge tree did not refresh to the current pull request base and head" >&2
exit 1
fi
git fetch --no-tags --depth=2 origin \
"+refs/pull/${LOC_PR_NUMBER}/merge:refs/remotes/origin/ci-head"
resolved_loc_head="$(git rev-parse refs/remotes/origin/ci-head)"
if [[ "$resolved_loc_head" != "$LOC_HEAD_SHA" ]]; then
echo "Pull request ${LOC_PR_NUMBER} merge ref moved before the LOC check." >&2
exit 1
fi
git checkout --detach refs/remotes/origin/ci-head
git checkout --detach "$merge_sha"
echo "RATCHET_RELEASE_BASE_SHA=${base_sha}" >> "$GITHUB_ENV"
echo "RATCHET_RELEASE_MERGE_TREE=true" >> "$GITHUB_ENV"
- name: Setup Node environment
uses: ./.github/actions/setup-node-env
with:
@@ -1271,10 +1233,12 @@ jobs:
- name: Run ${{ matrix.task }} (${{ matrix.runtime }})
env:
HISTORICAL_TARGET: ${{ needs.preflight.outputs.compatibility_target }}
LOC_BASE_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.sha || github.event_name == 'push' && github.event.before || needs.preflight.outputs.loc_base_sha || '' }}
LOC_EXPECTED_PR_HEAD: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || needs.preflight.outputs.loc_head_sha != '' && inputs.target_ref || '' }}
GH_TOKEN: ${{ matrix.task == 'max-lines-ratchet' && github.token || '' }}
OPENCLAW_TEST_PROJECTS_PARALLEL: 3
RATCHET_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
RATCHET_EVENT_BASE_SHA: ${{ github.event_name == 'push' && github.event.before || '' }}
RATCHET_MANUAL_TARGET_SHA: ${{ github.event_name == 'workflow_dispatch' && !inputs.release_gate && needs.preflight.outputs.checkout_revision || '' }}
RATCHET_PR_HEAD_SHA: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || '' }}
TASK: ${{ matrix.task }}
shell: bash
run: |
@@ -1297,33 +1261,61 @@ jobs:
ci-routing)
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/ci-changed-node-test-plan.test.ts test/scripts/ci-workflow-guards.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
;;
loc-ratchet)
# Frozen compatibility targets were governed by their original CI. Comparing
# them with moving main would turn unrelated branch drift into release failures.
if [[ "$HISTORICAL_TARGET" != "true" ]] && [ -n "$LOC_BASE_SHA" ] && [[ ! "$LOC_BASE_SHA" =~ ^0+$ ]]; then
loc_base_ref="refs/remotes/origin/ci-base"
if [ -n "$LOC_EXPECTED_PR_HEAD" ]; then
# Pull-request merge refs can advance past the event base as main moves.
# Compare with the base parent of the exact merge tree under test.
if ! git rev-parse --verify HEAD^1 >/dev/null 2>&1 || ! git rev-parse --verify HEAD^2 >/dev/null 2>&1; then
loc_merge_sha="$(git rev-parse HEAD)"
git fetch --no-tags --depth=2 origin "+${loc_merge_sha}:refs/remotes/origin/ci-loc-merge"
fi
merge_head="$(git rev-parse HEAD^2)"
if [[ "$merge_head" != "$LOC_EXPECTED_PR_HEAD" ]]; then
echo "LOC merge tree head ${merge_head} does not match expected pull-request head ${LOC_EXPECTED_PR_HEAD}." >&2
exit 1
fi
loc_base_ref="$(git rev-parse HEAD^1)"
else
git fetch --no-tags --depth=1 origin "+${LOC_BASE_SHA}:${loc_base_ref}"
fi
if has_package_script "check:loc"; then
pnpm check:loc --base "$loc_base_ref" --head HEAD
else
echo "Current CI targets must provide the check:loc package script." >&2
max-lines-ratchet)
if ! has_package_script "check:max-lines-ratchet"; then
echo "Current CI targets must provide check:max-lines-ratchet." >&2
exit 1
fi
base_sha="${RATCHET_EVENT_BASE_SHA:-${RATCHET_RELEASE_BASE_SHA:-}}"
if [[ "$base_sha" == "0000000000000000000000000000000000000000" ]]; then
base_sha=""
fi
base_ref=""
if [[ -n "${RATCHET_PR_HEAD_SHA:-}" ]]; then
mapfile -t merge_parents < <(git cat-file -p HEAD | sed -n 's/^parent //p')
if [[ "${#merge_parents[@]}" != "2" || "${merge_parents[1]:-}" != "$RATCHET_PR_HEAD_SHA" ]]; then
echo "Pull request checkout is not the expected two-parent merge tree." >&2
exit 1
fi
merge_base="${merge_parents[0]}"
git fetch --no-tags --depth=1 origin \
"+${merge_base}:refs/remotes/origin/ci-max-lines-base"
base_ref="refs/remotes/origin/ci-max-lines-base"
elif [[ -n "$base_sha" ]]; then
git fetch --no-tags --depth=1 origin \
"+${base_sha}:refs/remotes/origin/ci-max-lines-base"
base_ref="refs/remotes/origin/ci-max-lines-base"
elif [[ -n "${RATCHET_MANUAL_TARGET_SHA:-}" ]]; then
default_branch="${RATCHET_DEFAULT_BRANCH:-main}"
default_sha="$(
git ls-remote origin "refs/heads/${default_branch}" | awk 'NR == 1 { print $1 }'
)"
if [[ ! "$default_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Could not resolve the default branch head for the max-lines ratchet." >&2
exit 1
fi
merge_base_sha="$(
gh api --method GET \
"repos/${GITHUB_REPOSITORY}/compare/${default_sha}...${RATCHET_MANUAL_TARGET_SHA}" \
--jq '.merge_base_commit.sha'
)"
if [[ ! "$merge_base_sha" =~ ^[0-9a-f]{40}$ ]]; then
echo "Could not resolve the manual target merge base for the max-lines ratchet." >&2
exit 1
fi
git fetch --no-tags --depth=1 origin \
"+${merge_base_sha}:refs/remotes/origin/ci-max-lines-base"
base_ref="refs/remotes/origin/ci-max-lines-base"
else
default_branch="${RATCHET_DEFAULT_BRANCH:-main}"
git fetch --no-tags --depth=1 origin \
"+refs/heads/${default_branch}:refs/remotes/origin/ci-max-lines-base"
base_ref="refs/remotes/origin/ci-max-lines-base"
fi
unset GH_TOKEN
pnpm check:max-lines-ratchet --base "$base_ref"
if [[ "${RATCHET_RELEASE_MERGE_TREE:-}" == "true" ]]; then
node scripts/run-oxlint.mjs src ui/src packages extensions
fi
;;
bun-launcher)
+90
View File
@@ -271,6 +271,96 @@
"rules": {
"typescript/no-explicit-any": "off"
}
},
{
"files": [
"src/**/*.{js,ts,mts,cts}",
"ui/src/**/*.{js,ts,mts,cts}",
"packages/**/*.{js,ts,mts,cts}",
"extensions/**/*.{js,ts,mts,cts}"
],
"excludeFiles": [
"**/*.test.*",
"**/*.spec.*",
"**/__generated__/**",
"**/generated/**",
"**/protocol-gen/**",
"**/*.generated.*",
"**/dist/**",
"ui/src/i18n/locales/**",
"src/wizard/i18n/locales/**"
],
"rules": {
"max-lines": ["error", { "max": 700, "skipBlankLines": true, "skipComments": true }]
}
},
{
"files": [
"src/**/*.{jsx,tsx}",
"ui/src/**/*.{jsx,tsx}",
"packages/**/*.{jsx,tsx}",
"extensions/**/*.{jsx,tsx}"
],
"excludeFiles": [
"**/*.test.*",
"**/*.spec.*",
"**/__generated__/**",
"**/generated/**",
"**/protocol-gen/**",
"**/*.generated.*",
"**/dist/**",
"ui/src/i18n/locales/**",
"src/wizard/i18n/locales/**"
],
"rules": {
"max-lines": ["error", { "max": 700, "skipBlankLines": true, "skipComments": true }]
}
},
{
"files": [
"src/**/*.{mjs,cjs}",
"ui/src/**/*.{mjs,cjs}",
"packages/**/*.{mjs,cjs}",
"extensions/**/*.{mjs,cjs}"
],
"excludeFiles": [
"**/*.test.*",
"**/*.spec.*",
"**/__generated__/**",
"**/generated/**",
"**/protocol-gen/**",
"**/*.generated.*",
"**/dist/**",
"ui/src/i18n/locales/**",
"src/wizard/i18n/locales/**"
],
"rules": {
"max-lines": ["error", { "max": 800, "skipBlankLines": true, "skipComments": true }]
}
},
{
"files": [
"src/**/*.test.*",
"src/**/*.spec.*",
"ui/src/**/*.test.*",
"ui/src/**/*.spec.*",
"packages/**/*.test.*",
"packages/**/*.spec.*",
"extensions/**/*.test.*",
"extensions/**/*.spec.*"
],
"excludeFiles": [
"**/__generated__/**",
"**/generated/**",
"**/protocol-gen/**",
"**/*.generated.*",
"**/dist/**",
"ui/src/i18n/locales/**",
"src/wizard/i18n/locales/**"
],
"rules": {
"max-lines": ["error", { "max": 1000, "skipBlankLines": true, "skipComments": true }]
}
}
]
}
+1
View File
@@ -265,6 +265,7 @@ Skills own workflows; root owns hard policy and routing.
- Cycles: keep `pnpm check:import-cycles` + architecture/madge green.
- Classes: no prototype mixins/mutations. Prefer inheritance/composition. Tests prefer per-instance stubs.
- Split files around ~700 LOC when clarity/testability improves.
- Never add a `max-lines` suppression. Existing suppressions are grandfathered TODOs; split the file and remove its suppression plus baseline entry.
- Naming: **OpenClaw** product/docs; `openclaw` CLI/package/path/config.
- English: American spelling.
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -33,7 +33,7 @@ dispatch.
| `pnpm-store-warmup` | Warm the lockfile-pinned pnpm store cache without blocking Linux Node shards | Node or docs-check lanes selected |
| `build-artifacts` | Build `dist/`, Control UI, built-CLI smoke checks, startup memory, and embedded built-artifact checks | Node-relevant changes |
| `control-ui-i18n` | Verify generated Control UI locale bundles, metadata, and translation memory; advisory on automatic runs, blocking on manual release CI | Control UI i18n-relevant changes and manual CI |
| `checks-fast-core` | Fast Linux correctness lanes: changed-file TypeScript LOC ratchet, bundled + protocol, Bun launcher, and the CI-routing fast task | Node-relevant or production TypeScript changes |
| `checks-fast-core` | Fast Linux correctness lanes: suppression-baseline max-lines ratchet, bundled + protocol, Bun launcher, and the CI-routing fast task | Node-relevant changes |
| `qa-smoke-ci-profile` | Two self-contained balanced parts of the bounded automatic QA Smoke representative set; full taxonomy coverage remains available through explicit QA profiles | Node-relevant changes |
| `checks-fast-contracts-plugins-*` | Two weighted plugin contract shards | Node-relevant changes |
| `checks-fast-contracts-channels-*` | Two weighted channel contract shards | Node-relevant changes |
@@ -148,7 +148,7 @@ Treat GitHub titles, comments, bodies, review text, branch names, and commit mes
Manual CI dispatches run the same job graph as normal CI but force every non-Android scoped lane on: Linux Node shards, bundled-plugin shards, plugin and channel contract shards, Node 22 compatibility, `check-*`, `check-additional-*`, built-artifact smoke checks, docs checks, Python skills, Windows, macOS, iOS build, and Control UI i18n. Control UI locale parity is advisory on automatic PR and `main` runs because the standalone refresh workflow repairs generated drift in the background; it is blocking on manual CI and therefore on Full Release Validation. Standalone manual CI dispatches run Android only with `include_android=true` (the `release_gate` input also forces Android); the full release umbrella enables Android by passing `include_android=true`. Plugin prerelease static checks, the release-only `agentic-plugins` shard, the full extension batch sweep, and plugin prerelease Docker lanes are excluded from CI. The Docker prerelease suite runs only when `Full Release Validation` dispatches the separate `Plugin Prerelease` workflow with the release-validation gate enabled.
Manual runs use a unique concurrency group so a release-candidate full suite is not cancelled by another push or PR run on the same ref. The optional `target_ref` input lets a trusted caller run that graph against a branch, tag, or full commit SHA while using the workflow file from the selected dispatch ref. The optional `loc_base_ref` supplies an exact comparison SHA for standalone manual runs. The `release_gate` input is an exact-SHA maintainer fallback for capacity-stalled PR CI: it requires `target_ref` to be a full commit SHA that matches the dispatched branch head and `pr_number` to identify the open pull request. The workflow authenticates that PR's current head and base, waits for GitHub to finish computing mergeability, pins the reported test merge commit, fetches GitHub's synthetic pull-request merge ref, verifies its SHA and both parents, then checks out that tree before installing dependencies and running the changed-file TypeScript LOC ratchet. This matches automatic PR CI's merged tree and policy implementation. Target-owned workflow revisions without `pr_number` cannot provide equivalent merge-tree evidence; update the PR head to the current workflow and restart exact-head proof instead of using the fallback.
PR max-lines checks derive the baseline from the checked-out synthetic merge tree and verify its head parent against the event head. Manual runs use a unique concurrency group so a release-candidate full suite is not cancelled by another push or PR run on the same ref. The optional `target_ref` input lets a trusted caller run that graph against a branch, tag, or full commit SHA while using the workflow file from the selected dispatch ref; the max-lines baseline is compared with the target's merge base against the default-branch head resolved for that run. The `release_gate` input is an exact-SHA maintainer fallback for capacity-stalled PR CI: it requires `target_ref` to be a full commit SHA that matches the dispatched branch head and `pull_request_number` to identify the open PR whose merge tree is validated.
```bash
gh workflow run ci.yml --ref release/YYYY.M.PATCH
+1
View File
@@ -788,3 +788,4 @@ export async function prepareAcpxCodexAuthConfig(params: {
},
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -2232,3 +2232,4 @@ describe("AcpxRuntime fresh reset wrapper", () => {
expect(defaultProbe).not.toHaveBeenCalled();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1400,3 +1400,4 @@ export const testing = {
export type { AcpAgentRegistry, AcpRuntimeOptions, AcpSessionRecord, AcpSessionStore };
export { testing as __testing };
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -6460,3 +6460,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1594,3 +1594,4 @@ describe("amazon-bedrock provider plugin", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1182,3 +1182,4 @@ export const testing = {
resolveSimpleBedrockOptions,
shouldUseExplicitBedrockEndpoint,
};
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1258,3 +1258,4 @@ describe("anthropic provider replay hooks", () => {
]);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -924,3 +924,4 @@ export function registerAnthropicPlugin(api: OpenClawPluginApi): void {
api.registerNodeInvokePolicy(policy);
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1164,3 +1164,4 @@ describe("Claude session catalog", () => {
]);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1336,3 +1336,4 @@ export function registerClaudeSessionCatalog(api: OpenClawPluginApi): void {
};
api.registerSessionCatalog(provider);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2530,3 +2530,4 @@ describe("browser tool upload inbound media fallback (#83544)", () => {
).rejects.toThrow("path outside allowed directories");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1013,3 +1013,4 @@ export function createBrowserTool(opts?: {
},
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -934,3 +934,4 @@ export async function snapshotRoleViaCdp(opts: {
{ commandTimeoutMs: opts.timeoutMs ?? 5000 },
);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3039,3 +3039,4 @@ describe("chrome MCP page parsing", () => {
expect(closeMock).toHaveBeenCalledTimes(1);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2495,3 +2495,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -905,3 +905,4 @@ export function resolveBrowserExecutableForPlatform(
}
return null;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2147,3 +2147,4 @@ describe("chrome.ts internal", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1465,3 +1465,4 @@ export async function stopOpenClawChrome(
);
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1193,3 +1193,4 @@ describe("browser config", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -898,3 +898,4 @@ export class ExtensionRelayBridge {
this.childSessions.clear();
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1220,3 +1220,4 @@ describe("pw-session selected-page interaction request guard", () => {
).rejects.toBe(cleanupError);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2445,3 +2445,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1316,3 +1316,4 @@ describe("pw-tools-core browser SSRF guards", () => {
);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1736,3 +1736,4 @@ describe("pw-tools-core interaction navigation guard", () => {
expect(dispose).toHaveBeenCalledOnce();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2139,3 +2139,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -877,3 +877,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -882,3 +882,4 @@ export function registerBrowserAgentSnapshotRoutes(
}
});
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -893,3 +893,4 @@ export function registerBrowserManageCommands(
});
});
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1175,3 +1175,4 @@ describe("codex doctor contract", () => {
expect(original.plugins.entries.codex.config.appServer.approvalPolicy).toBe("on-failure");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2636,3 +2636,4 @@ describe("Codex app-server approval bridge", () => {
expect(payload.description).toBe(`${"d".repeat(252)}...`);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1393,3 +1393,4 @@ function joinDescriptionLinesWithinLimit(lines: string[], maxLength: number): st
function formatErrorMessage(error: unknown): string {
return error instanceof Error ? error.message : String(error);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1062,3 +1062,4 @@ function normalizeCodexDynamicToolName(name: string): string {
function isNonEmptyString(value: unknown): value is string {
return typeof value === "string" && value.length > 0;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2634,3 +2634,4 @@ describe("bridgeCodexAppServerStartOptions", () => {
}
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1,3 +1,4 @@
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
// Codex plugin module implements auth bridge behavior.
import { createHash } from "node:crypto";
import fsSync from "node:fs";
@@ -1025,3 +1025,4 @@ function formatExitValue(value: unknown): string {
}
return "unknown";
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2025,3 +2025,4 @@ function createFakeCodexClient(
completeCompaction,
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -914,3 +914,4 @@ function formatCompactionError(error: unknown): string {
}
return String(error);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1403,3 +1403,4 @@ function pluginSummary(
interface: null,
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1261,3 +1261,4 @@ function resolveComputerUseConfig(
overrides,
});
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2881,3 +2881,4 @@ allowed_sandbox_modes = ["read-only", "workspace-write"]
expect(appServerProperties.approvalsReviewer?.default).toBeUndefined();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2487,3 +2487,4 @@ function splitShellWords(value: string): string[] {
}
return words;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1584,3 +1584,4 @@ describe("Codex app-server dynamic tool build", () => {
expect(automaticSchema.properties).not.toHaveProperty("final");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -934,3 +934,4 @@ function shouldForceMessageTool(params: EmbeddedRunAttemptParams): boolean {
params.disableMessageTool !== true && params.sourceReplyDeliveryMode === "message_tool_only"
);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3766,3 +3766,4 @@ describe("createCodexDynamicToolBridge", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1514,3 +1514,4 @@ function isCronAddAction(args: Record<string, unknown>): boolean {
const action = args.action;
return typeof action === "string" && action.trim().toLowerCase() === "add";
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1770,3 +1770,4 @@ describe("Codex app-server elicitation bridge", () => {
expect(() => encodeURIComponent(approvalCallParams.description ?? "")).not.toThrow();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -991,3 +991,4 @@ function readFirstString(record: JsonObject | undefined, keys: string[]): string
}
return undefined;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -6055,3 +6055,4 @@ describe("CodexAppServerEventProjector", () => {
expect(started.scope).toBe("thread");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3498,3 +3498,4 @@ function readItem(value: JsonValue | undefined): CodexThreadItem | undefined {
}
return value as CodexThreadItem;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1826,3 +1826,4 @@ describe("CodexNativeSubagentMonitor", () => {
}
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1629,3 +1629,4 @@ function unrefTimer(timer: ReturnType<typeof setTimeout>): void {
(timer as { unref: () => void }).unref();
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1967,3 +1967,4 @@ async function buildReadyGoogleCalendarThreadConfig(
},
});
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -774,3 +774,4 @@ function normalizeText(value: string | null | undefined): string | undefined {
const text = value?.trim();
return text ? text : undefined;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2121,3 +2121,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -6532,3 +6532,4 @@ describe("runCodexAppServerAttempt", () => {
expect(fastEvents.map((event) => event.data?.summary)).toEqual(["💨Fast: auto-on"]);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -5389,3 +5389,4 @@ describe("runCodexAppServerAttempt turn watches", () => {
expect(result.timedOut).toBe(false);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -833,3 +833,4 @@ export async function validateCodexAppServerRuntimeArtifact(
return false;
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1425,3 +1425,4 @@ describe("Codex app-server binding store", () => {
).toThrow("requires an agent id");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1429,3 +1429,4 @@ export function resolveCodexAppServerBindingModelProvider(
(isCodexAppServerNativeAuthProfile(params) ? PUBLIC_OPENAI_MODEL_PROVIDER : undefined)
);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1871,3 +1871,4 @@ function rawDataToText(data: RawData): string {
}
return Buffer.from(data).toString("utf8");
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1237,3 +1237,4 @@ function collectSharedClients(state: SharedCodexAppServerClientState): CodexAppS
),
];
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3083,3 +3083,4 @@ describe("runCodexAppServerSideQuestion", () => {
);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1322,3 +1322,4 @@ function formatCodexErrorMessage(params: JsonObject, rateLimits: JsonValue | und
"Codex /btw side thread failed.";
return new Error(formatErrorMessage(message));
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2883,3 +2883,4 @@ describe("Codex app-server thread lifecycle bindings", () => {
expect(binding.modelProvider).toBeUndefined();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2995,3 +2995,4 @@ describe("native Codex Ultra turn mapping", () => {
expect(request).not.toHaveProperty("multiAgentMode");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3195,3 +3195,4 @@ export function resolveReasoningEffort(
}
return null;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1196,3 +1196,4 @@ describe("mirrorCodexAppServerTranscript", () => {
);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -2559,3 +2559,4 @@ function normalizeComputerUseStringOverrides(
}
return normalized;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -5128,3 +5128,4 @@ function computerUseReadyStatus(): CodexComputerUseStatus {
message: "Computer Use is ready.",
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2334,3 +2334,4 @@ describe("codex conversation binding", () => {
expect(sharedClientMocks.getSharedCodexAppServerClient).not.toHaveBeenCalled();
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1241,3 +1241,4 @@ export const codexConversationBindingRuntime = {
handleInboundClaim: handleCodexConversationInboundClaim,
handleBindingResolved: handleCodexConversationBindingResolved,
};
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -2583,3 +2583,4 @@ function pluginSummary(id: string, overrides: Partial<v2.PluginSummary> = {}): v
...overrides,
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -891,3 +891,4 @@ export const stateMigrations: PluginDoctorStateMigration[] = [
},
},
];
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3429,3 +3429,4 @@ describe("Codex supervision actions", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1336,3 +1336,4 @@ export const codexSessionCatalogRuntime = {
continueNode: continueNodeCodexSession,
archiveLocal: archiveLocalCodexSession,
};
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1222,3 +1222,4 @@ export function createCodexSupervisionTools(options: CodexSupervisionToolsOption
},
];
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1087,3 +1087,4 @@ describe("comfy image-generation provider", () => {
expect(extraData?.api_key_comfy_org).toBe("profile-key");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -877,3 +877,4 @@ export async function runComfyWorkflow(params: {
outputNodeIds: uniqueStrings(outputFiles.map((entry) => entry.nodeId)),
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -2667,3 +2667,4 @@ describe("createCopilotAgentHarness", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1132,3 +1132,4 @@ export function createCopilotAgentHarness(
},
};
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -3628,3 +3628,4 @@ function toLintErrorObject(value: unknown, fallbackMessage: string): Error {
}
return error;
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1783,3 +1783,4 @@ function isSdkSendAndWaitTimeoutError(error: unknown): boolean {
}
return /^Timeout after \d+ms waiting for session\.idle$/.test(message);
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1152,3 +1152,4 @@ describe("attachEventBridge", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1763,3 +1763,4 @@ describe("convertOpenClawToolToSdkTool", () => {
expect(getError(result as ToolResultObject)).toBe("aborted during execute");
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1175,6 +1175,7 @@ describe("Crabbox worker provider", () => {
]);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
describe("Crabbox binary resolution", () => {
it("prefers explicit, then sibling, then PATH, then the bare command", () => {
+1
View File
@@ -1459,3 +1459,4 @@ describe("device-pair /pair approve", () => {
expect(result).toEqual({ text: "✅ Paired Victim Phone (ios)." });
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1011,3 +1011,4 @@ export default definePluginEntry({
});
},
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -5494,3 +5494,4 @@ describe("diagnostics-otel service", () => {
await service.stop?.(ctx);
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -1065,3 +1065,4 @@ export const testApi = {
recordDiagnosticEvent,
renderPrometheusMetrics,
};
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -735,3 +735,4 @@ export async function handleDiscordGuildAction(
throw new Error(`Unknown action: ${action}`);
}
}
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
@@ -3470,3 +3470,4 @@ describe("handleDiscordAction per-account gating", () => {
});
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -789,3 +789,4 @@ export const discordPlugin: ChannelPlugin<ResolvedDiscordAccount, DiscordProbe>
}),
},
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */
+1
View File
@@ -1421,3 +1421,4 @@ describe("discord reaction notification modes", () => {
}
});
});
/* oxlint-disable max-lines -- TODO: split this grandfathered oversized file. */

Some files were not shown because too many files have changed in this diff Show More