.pi/settings.json is the shared, committed declaration and .pi/npm/ is a gitignored cache pi recreates on a trusted startup, so the generated .gitignore is intentional and nothing needs tracking. Record this in the README tooling notes and close the reproducibility item as resolved by design.
68 lines
6.1 KiB
Markdown
68 lines
6.1 KiB
Markdown
# 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](./CONTRIBUTING.md#feedback-tiers). How the
|
|
`prefix:` in a script name is chosen:
|
|
[§ Script prefix convention](./CONTRIBUTING.md#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](#tooling-decisions); when it runs is in [CONTRIBUTING.md § Feedback tiers](./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`, `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 `.ts` extensions** so `node --strip-types` resolves them at test time. `rewriteRelativeImportExtensions: true` in `tsconfig.build.json` rewrites them to `.js` in the emitted `dist/*` output, so consumers see conventional ESM imports.
|
|
- **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`).
|
|
|
|
## 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](./CONTRIBUTING.md). AI coding agents: your entry point is [AGENTS.md](./AGENTS.md), which points back to CONTRIBUTING.md.
|
|
|
|
- Commit signing (GPG).
|
|
- Type-only tests use `expect-type`'s `expectTypeOf(...)` inside `node --test` cases.
|