8c2855aa9247651d402d567be80fe503b56d9c99
`use:git-commit-message` is referenced by CONTRIBUTING.md but appears in none of the lists that define the script vocabulary, so the rule "reuse an existing prefix, never invent one" is currently violated by its own exception. Recorded as a task rather than fixed here: the prefix wants a name that says what it is for, and that is the same decision as naming a prefix for the other lifecycle scripts, so the two should be chosen together.
tiny-pattern-ts
Pattern matching for TypeScript/ESM environments (F#-style, not regex).
Development
- Build:
npm run build - Test:
npm run test,npm run test:ci - Watch:
npm run watch - Checks:
npm run check,npm run fix - Verify:
npm run verify— the definition of done - Maintenance:
npm run maintain— advisory only - Individual fixes:
npm run fix:oxfmt,npm run fix:oxlint
What each tier runs, when it fires and what it costs:
CONTRIBUTING.md § Feedback tiers. How the
prefix: in a script name is chosen:
§ Script prefix convention.
Tooling
- TypeScript 7 — type checker and build (
tsc). - node --test +
--experimental-strip-types— test runner (Node 22.6+, flag dropped on Node 24). - c8 — code coverage for
test:ci. - oxlint — Rust-based linter, with type-aware rules powered by oxlint-tsgolint (typescript-go).
- oxfmt — Rust-based formatter (Prettier-compatible). Formats JS/TS, JSON/JSONC, YAML, Markdown, MDX, and more; built-in
package.jsonkey sorting replacessort-package-json. - cspell — spell checking.
- knip — finds unused dependencies, exports, and files.
- check-outdated — reports dependencies behind the registry; it exits non-zero whenever any dependency is outdated.
- publint — validates
package.jsonfor ESM publishing correctness. - @arethetypeswrong/cli (
attw) — validates.d.tsdeclarations against multiple module-resolution scenarios. - lefthook — git hooks.
- @spences10/pi-lsp — read-only LSP code intelligence for AI coding agents (project-local
.pi/settings.json). Talks to this repo's TypeScript 7 viatsc --lsp --stdio.
Each tool's configuration trade-off is recorded in Tooling decisions; when it runs is in CONTRIBUTING.md § Feedback tiers.
Tooling decisions
The choice and configuration of each tool above is the result of deliberate trade-offs, not defaults. The non-obvious ones:
tsconfig.jsonextends@tsconfig/strictest+@tsconfig/node26;tsconfig.build.jsonextends it to add the emit-only options (declaration,sourceMap,outDir,target: es2024,rewriteRelativeImportExtensions: true) and to exclude test files. This separation lets the editor and CI type-check from one config while the build emits from the other.- Source imports use
.tsextensions sonode --strip-typesresolves them at test time.rewriteRelativeImportExtensions: trueintsconfig.build.jsonrewrites them to.jsin the emitteddist/*output, so consumers see conventional ESM imports. - Type-aware oxlint is enabled declaratively via
options.typeAware: truein.oxlintrc.json(powered byoxlint-tsgolint). The script commands stay clean — no CLI flag — and type-aware mode is a property of the config, not the invocation. - Source-level
oxlint-disabledirectives are used for known type-aware false positives (seesrc/pattern.ts,src/match.ts,src/index.test.ts). The disable lives next to the code it silences, not in.oxlintrc.json, so the trade-off is visible to anyone reading the source. knip --include dependencies,exports,filesintentionally omits thetypescategory, which produces systematic false positives for libraries whose exported types are part of the public API. The targeted scope keeps the signal high without config-file boilerplate.attw --profile esm-onlyis semantically correct: this package is intentionally ESM-only (no CommonJS shim), so CJS resolution scenarios are out of scope by design, not a bug.check:tscruns first in thenpm run checkchain so a type error short-circuits the rest (faster feedback than letting oxlint/oxfmt run and then failing on tsc at the end).- The pre-commit hook sets the
LEFTHOOK_FILESenv var to the staged-files list, and the affected scripts use${LEFTHOOK_FILES:-<default>}to default to the whole project when invoked manually. This keepspackage.json#scriptsas the single source of truth for the underlying commands —lefthook.ymlonly describes what to run on which files. tslibandtype-festare deliberately not used.tslibis a runtime helper for old ES3/ES5 targets (the project targets ES2024);type-festwas never imported. knip caught both.@spences10/pi-lspis pinned to0.0.46and is read-only by design. The package inspectsnode_modules/typescript, sees major ≥ 7 with nolib/tsserver.js(true of thetypescript-go/tsgoport), and spawns the repo's owntsc --lsp --stdiobinary — notypescript-language-serverdependency is required. Earlier releases (≤ 0.0.10) hard-wire totypescript-language-server --stdioand are TS6-only. The tool is intermediate agent feedback (hover, references, definition, symbols, diagnostics); it has no rename / code-action / apply-edit surface, and never a correctness gate —npm run check/verifyremain that.
Requirements
- Node.js >= 26 (engines field; pinned via
.node-version).
VSCode integration
- Recommended extensions: see
.vscode/extensions.json(oxc, cspell). - TypeScript 7 is used via the
typescriptteam.native-previewextension. - oxc extension provides oxlint squiggles and oxfmt format-on-save.
Contributing
For maintainer and contributor docs — the script prefix convention, the feedback-tier system, the rules the tools don't enforce, and the publishing workflow — see CONTRIBUTING.md. AI coding agents: your entry point is AGENTS.md, which points back to CONTRIBUTING.md.
- Commit signing (GPG).
- Type-only tests use
expect-type'sexpectTypeOf(...)insidenode --testcases.