Skip to content

#1262 Hoist unreadable for-of expressions and promote the lint rule to an error - #1276

Merged
williamthorsen merged 3 commits into
mainfrom
1262
Aug 10, 2026
Merged

#1262 Hoist unreadable for-of expressions and promote the lint rule to an error#1276
williamthorsen merged 3 commits into
mainfrom
1262

Conversation

@williamthorsen

@williamthorsen williamthorsen commented Aug 10, 2026

Copy link
Copy Markdown
Owner

What

Fixes lint in the agents package: Every for…of header now names what it iterates rather than burying the expression inline.

Why

unicorn/no-unreadable-for-of-expression fired at more sites in the agents package than any other rule on that package's deferral list, and the deferral held it at warn, so fresh violations landed unnoticed alongside the backlog. Clearing the sites is what lets the rule bind, and it is a prerequisite for retiring the deferral list entirely.

Details

♻️ Refactoring

  • 31 loop headers across 20 files bind their iterable expression to a named const immediately above the loop. Four expression shapes were involved: an awaited call, a nullish fallback, an awaited call with a trailing method, and a new Set(…) over a mapped array. Each hoist is mechanical: for…of evaluates its right-hand side once before the first iteration, so the binding holds exactly what the header produced.
  • Each binding is named for its contents. Where the obvious plural was already taken, the hoist reaches for a precise alternative rather than a suffix — listSkillDirectories binds subdirectoryNames because names is the function's own accumulator.
  • The three nullish-fallback sites sit inside an outer loop over ARTIFACT_TYPE_VALUES, and their hoists stay inside it, so each fallback is still evaluated per outer iteration.
  • With the sites cleared, the rule's entry leaves packages/agents/.config/eslint/deferred-lint-rules.ts and it takes the shared preset's error severity. Ten entries remain on the list, and both consumers of the object — eslint.config.ts and .config/strict-lint.config.ts — read it as before.

🧪 Tests

  • 17 of the 31 sites sit in the agents test suite, where the rewrite is confined to loop headers.

Closes #1262

Loop headers under `packages/agents/src` now bind their iterable expression to a named `const` above the loop, clearing `unicorn/no-unreadable-for-of-expression` from the package's library code. `for…of` resolves its right-hand side once before iterating, so every hoist preserves behavior.
Loop headers across the agents test suite now bind their iterable expression to a named `const` above the loop, clearing the last `unicorn/no-unreadable-for-of-expression` sites in the package. No test's expectations or fixtures change.
`unicorn/no-unreadable-for-of-expression` no longer sits on the agents deferral list, so a complex `for…of` header now fails the lint gate instead of accruing as an unread warning.
@williamthorsen williamthorsen added refactoring Improvement to code without change in functionality scope:agents labels Aug 10, 2026
@github-actions

Copy link
Copy Markdown

Dependency audit

Production dependency audit passed.

@williamthorsen williamthorsen self-assigned this Aug 10, 2026
@williamthorsen
williamthorsen marked this pull request as ready for review August 10, 2026 12:09
@williamthorsen
williamthorsen merged commit ddf57fe into main Aug 10, 2026
3 checks passed
@williamthorsen
williamthorsen deleted the 1262 branch August 10, 2026 14:05
williamthorsen added a commit that referenced this pull request Aug 13, 2026
…e-v0.3.0 codeassembly-v0.9.0 factory-v0.2.6 codeassembly-mcp-v0.2.5

codeassembly-v0.9.0
- #1288 feat: State mutability and name the lede reader at the artifact type lists (#1303)
- #1285 fix: Require plain bullets for checklists on both update-jira-ticket paths (#1302)
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1294 feat: Specify artifact mutability and its sanctioned exceptions (#1297)
- #1293 fix: Present and classify discretionary findings as actionable (#1295)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1280 feat: Add a refresh path that edits an existing AGENTS.md instead of redrafting it (#1287)
- #1055 feat: Replace the lede doctrine with corpus-derived guidance and retire the changelog-writer (#1286)
- deps: Upgrade all deps to latest version
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1263 refactor: Retire the deferred-lint mechanism and adopt toolbelt.errors in agents (#1279)
- #1262 refactor: Hoist unreadable for-of expressions and promote the lint rule to an error (#1276)
- #1267 fix: Extend the no-hard-wrapping instruction to every GitHub composer (#1275)
- #1177 fix: Rewrite links, tokens, and template variables in a Markdown file support entry (#1273)
- #1176 feat: Add a ticketing-preferences hook to the skills that split and create tickets (#1268)
- #1252 fix: Keep a skill's own sections out of injected guidance (#1266)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)
- #1247 feat: Add a personal tooling-preferences rulebook (#1257)
- #1251 feat: Let a rulebook declare that a guidance hook is how it is reached (#1259)
- #1246 feat: Guard home-domain writes and record their provenance (#1254)
- #1175 feat: Link new tickets to their blockers and parents (#1249)

factory-v0.2.6
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- deps: Upgrade all deps to latest version
- deps: Upgrade all deps to latest version
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)

kb-v0.6.0
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)

codeassembly-lifecycle-v0.4.0
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)

codeassembly-mcp-v0.2.5
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)

codeassembly-run-core-v0.3.0
- deps: Upgrade all deps to latest version
- #1290 tooling: Upgrade eslint-config-typescript to 10 and complete manifest metadata (#1301)
- #1289 tooling: Remove shelled nmr calls from package manifests (#1291)
- #1264 refactor: Consolidate error-message extraction on toolbelt.errors' describeError (#1284)
- #1261 feat: Attach causes to kb's loader errors and retire its lint deferral (#1272)
- #1260 refactor: Fix lint and retire rule deferrals (#1265)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactoring Improvement to code without change in functionality scope:agents

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Hoist agents' unreadable for-of iterable expressions and retire the rule's deferral

1 participant