eslint-rules
Create custom ESLint rules for the hyperfrontend Nx monorepo.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Create custom ESLint rules for the hyperfrontend Nx monorepo.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Write conventional commits for the hyperfrontend monorepo — types, scopes (Nx project names), one-line subjects, atomic commits, versioning-harness boundaries. Use when committing, splitting work into commits, choosing a commit scope/type, or asked about commit format.
Register friction found while building hyperfrontend demos into the showcase findings registry. Use when a demo consuming @hyperfrontend/features surfaces an unclear API, confusing error, missing feature, docs gap, packaging snag, or DX papercut — file the finding before writing the workaround.
Write README.md files for hyperfrontend libraries and sub-modules. Use when creating library documentation, writing sub-module READMEs, documenting API tables, adding quick start guides, or reviewing README structure compliance.
Write ARCHITECTURE.md files for hyperfrontend libraries. Use when creating architecture documentation, documenting design decisions, adding system overview diagrams, or explaining module composition and data flow.
Coding conventions for the hyperfrontend Nx monorepo. Use when refactoring, adding features, fixing bugs, or writing any new code across libs/, apps/, tools/, or plugins/.
Achieve 100% code coverage for custom ESLint rules. Use when reviewing ESLint rules for coverage gaps, adding missing tests, or applying istanbul ignore comments.
| name | eslint-rules |
| version | 1.0.0 |
| description | Create custom ESLint rules for the hyperfrontend Nx monorepo. |
| allowed-tools | ["Read","Write","Edit","Grep","Glob","Terminal"] |
Create rules in tools/eslint-rules/. REUSE shared utilities. Follow existing patterns.
| What | Where |
|---|---|
| Existing rules | tools/eslint-rules/src/rules/*.ts |
| Rule documentation | tools/eslint-rules/docs/*.md |
| Shared utilities | tools/eslint-rules/src/utils/ |
| Test infrastructure | tools/eslint-rules/src/testing/ |
| Registration | tools/eslint-rules/src/index.ts |
| Config | eslint.base.config.cjs |
Before creating a rule: Read tools/eslint-rules/docs/ to check for existing rules. Do not duplicate.
lib-* — Publishable library enforcement (package.json, project.json, README). Guard with isPublishableLibrary().no-* — Prohibitions (enums, unsafe patterns, async fs).prefer-* — Style preferences with autofixes.require-* — Mandate presence (node: protocol).A library is publishable if project.json has projectType: 'library' AND both build + publish targets.
import { isPublishableLibrary } from '../utils/nx-project'
if (!isPublishableLibrary(dirname(context.filename))) return {}
JSON rules require this cast for the listener return:
return { ... } as unknown as Rule.RuleListener
const createRule = ESLintUtils.RuleCreator(
(name) => `https://github.com/AndrewRedican/hyperfrontend/blob/main/tools/eslint-rules/docs/${name}.md`
)
In tools/eslint-rules/src/index.ts:
[RULE_NAME]: rule as unknown as Rule.RuleModule
utils/fs.ts first — Do not reimplement file operationsreadFileSync, writeFileSync, existsSync (never async)writeFileSync(path, data, { mode: 0o644 })readJsonFileIfExists(), readFileIfExists() from utilsstartsWith(), endsWith(), includes(), split()NODE_BUILTIN_MODULES.has() not regex patternsisPublishableLibrary(projectRoot) — Check if lib has build+publish targetsisPublishableProjectJson(json) — Check parsed project.jsonreadProjectJson(dir) / readPackageJson(dir) — Parse config filesfindPublishableLibraryDirectories(dir) — Find all publishable libsgetAllPublishableLibraries(root, subdir) — Full metadata for allfindWorkspaceRoot(path) — Monorepo rootfindProjectRoot(path) — Nearest project rootfindNxWorkspaceRoot(path) — Find nx.json locationfindWorkspaceRootByMarker(path, marker) — Custom root detectionexists(path) / isDirectory(path) — Path checksreadJsonFileIfExists(path) / readFileIfExists(path) — Safe readsreadDirectory(path) — List contentsgetImportCategory(source) — Returns 0-4 (NodeBuiltin→CurrentDir)compareImportSources(a, b) — Sort comparatorImportCategory enum — NodeBuiltin=0, External=1, Hyperfrontend=2, Relative=3, CurrentDir=4NODE_BUILTIN_MODULES — Set of all Node.js builtinsisNodeBuiltinWithoutPrefix(name) — Missing node: prefix?addNodePrefix(name) — Add node: prefixcreateRuleLogger(ruleName) — Scoped debug loggerTests run with Jest. 100% code coverage required.
Use assertive language. No "should":
should report error when...reports error when...flags missing fieldallows valid importimport { createTypeScriptRuleTester, createPackageJsonRuleTester, createProjectJsonRuleTester } from '../testing'
import { createTempWorkspaceManager, PUBLISHABLE_LIBRARY_PROJECT_JSON } from '../testing'
const manager = createTempWorkspaceManager()
afterAll(() => manager.cleanupAll())
const ws = manager.create({ projectJson: PUBLISHABLE_LIBRARY_PROJECT_JSON, files: {...} })
// Use: { code: '...', filename: ws.getPath('package.json') }
project.json: PUBLISHABLE_LIBRARY_PROJECT_JSON, NON_PUBLISHABLE_LIBRARY_PROJECT_JSON, APPLICATION_PROJECT_JSON, E2E_PROJECT_JSON
package.json: PUBLISHABLE_PACKAGE_JSON, MINIMAL_PACKAGE_JSON, PACKAGE_JSON_WITH_PACKAGE_EXPORT
Factories: createPublishableProjectJson(overrides), createPackageJson(overrides)
RULE_NAME constantisPublishableLibrary()index.ts with casttools/eslint-rules/docs/{name}.mdeslint.base.config.cjs