tmu 224afa9afb 👷 Publish tag coverage to the pages server
The build job bind-mounts the shared pages tree (the runner whitelists it
via container.valid_volumes) and, on tag pushes, wipes
/data/gitea-pages/<owner>/<repo>/<tag>/coverage before copying the c8 report
into it. Only this tag's coverage/ is touched; older tags and sibling
docs/landing trees are left for manual pruning.

Add a `tags: ["*"]` push trigger: a `branches` filter alone matches no tag
ref, so the tag-gated publish job (and this coverage step) could never run.

Track per-branch coverage as a backlog task.
2026-09-13 20:38:59 +00:00
2026-09-08 20:47:22 +02:00
2026-09-10 22:49:01 +00:00
2026-09-11 22:06:05 +00:00
2026-09-06 00:13:12 +02:00
2026-09-10 23:49:09 +00:00
2026-02-02 13:38:42 +01:00
2026-09-11 20:04:33 +00:00
2026-09-10 22:43:04 +00:00
2025-04-29 13:43:07 +02:00
2026-09-11 20:04:33 +00:00
2026-09-11 20:04:33 +00:00

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 + --strip-types — test runner.
  • 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.json key sorting replaces sort-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.json for ESM publishing correctness.
  • @arethetypeswrong/cli (attw) — validates .d.ts declarations 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 via tsc --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.json extends @tsconfig/strictest + @tsconfig/node26; tsconfig.build.json extends it to add the emit-only options (declaration, sourceMap, inlineSources, outDir, target: es2024, rewriteRelativeImportExtensions: true) and to exclude test files. inlineSources embeds the original TypeScript in dist/*.js.map, so debuggers can map into src/ without it being shipped; declarationMap is intentionally off because a .d.ts.map cannot embed source and would dangle. This separation lets the editor and CI type-check from one config while the build emits from the other.
  • npm run build first runs a prebuild hook that empties dist/. tsc does not prune orphaned emit output — dropping declarationMap, for example, left stale *.d.ts.map files behind — so the build must start from an empty dist/ to be reproducible. prebuild removes only dist; the manual clean still resets dist + coverage, so a local coverage report survives a build.
  • Source imports use .ts extensions so node --strip-types resolves them at test time. rewriteRelativeImportExtensions: true in tsconfig.build.json rewrites them to .js in the emitted JavaScript; the emitted .d.ts keep the .ts specifier, which TypeScript >= 5.0 resolves (see Requirements), so no post-processing step is needed.
  • Type-aware oxlint is enabled declaratively via options.typeAware: true in .oxlintrc.json (powered by oxlint-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-disable directives are used for known type-aware false positives (see src/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,files intentionally omits the types category, 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-only is 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:tsc runs first in the npm run check chain 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_FILES env var to the staged-files list, and the affected scripts use ${LEFTHOOK_FILES:-<default>} to default to the whole project when invoked manually. This keeps package.json#scripts as the single source of truth for the underlying commands — lefthook.yml only describes what to run on which files.
  • tslib and type-fest are deliberately not used. tslib is a runtime helper for old ES3/ES5 targets (the project targets ES2024); type-fest was never imported. knip caught both.
  • @spences10/pi-lsp is pinned to 0.0.46 and is read-only by design. The package inspects node_modules/typescript, sees major ≥ 7 with no lib/tsserver.js (true of the typescript-go / tsgo port), and spawns the repo's own tsc --lsp --stdio binary — no typescript-language-server dependency is required. Earlier releases (≤ 0.0.10) hard-wire to typescript-language-server --stdio and 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 / verify remain that. .pi/settings.json is the shared, committed declaration; .pi/npm/ is a gitignored install cache that pi recreates automatically on a trusted startup (it runs npm install for any missing project package), so the cache is deliberately not tracked.

Requirements

  • Node.js >= 26 (engines field; pinned via .node-version).
  • TypeScript >= 5.0 to consume the published declarations. The emitted .d.ts use const type parameters (TS 5.0) and keep their relative .ts specifiers; both resolve on TS >= 5.0 in node10/node16/nodenext/bundler.

VSCode integration

  • Recommended extensions: see .vscode/extensions.json (oxc, cspell, TypeScript native-preview, EditorConfig, todo-tasks).
  • TypeScript 7 is used via the typescriptteam.native-preview extension.
  • oxc extension provides oxlint squiggles and oxfmt format-on-save; .vscode/settings.json pins it per language so a user's local [language] formatter settings cannot override the project's choice.

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's expectTypeOf(...) inside node --test cases.
S
Description
No description provided
Readme MIT
1.5 MiB
0 Stars 1 Watchers 0 Forks
0.9.0
Latest
2026-09-29 23:57:54 +02:00
Languages
TypeScript 88.4%
Shell 9.9%
Dockerfile 1.7%