Skip to content

chore: adopt ts-canon for the lint/format toolchain - #26

Merged
SynthLuvr merged 4 commits into
mainfrom
chore/adopt-ts-canon
Aug 28, 2026
Merged

SynthLuvr merged 4 commits into
mainfrom
chore/adopt-ts-canon

Conversation

@SynthLuvr

@SynthLuvr SynthLuvr commented Aug 27, 2026 •

Copy link
Copy Markdown
Owner

What

Wave-1 migration to ts-canon (per its design doc). The lint/format toolchain this template duplicated becomes one devDependency: ts-canon@^0.1.0 from npm (published 2026-08-27; the earlier github: commit pin was only a stopgap while it was unpublished).

  • pnpm lint → ts-canon lint: biome, oxlint+tsgolint, 3 ast-grep rules, pandoc, peer-deps, pnpm audit --prod, jscpd — same steps, same order as before
  • pnpm format → ts-canon format: arrows → braces → biome format → biome check → pandoc — same order as before
  • scripts/{oxlint,pandoc-md,peer-deps}.mts and .ast-grep/rules/ deleted (ported into ts-canon; verified equivalent)
  • biome.json collapses to extends ts-canon/presets/biome.preset.json (config was verified identical modulo $schema)
  • tsconfig.json extends ts-canon/presets/tsconfig.base.json
  • sgconfig.yml copied from the preset so bare ast-grep scan/editor integrations still find the rules
  • vitest.config.ts imports ts-canon/presets/vitest — the preset ships compiled (vitest.mjs + vitest.d.mts, dedicated exports entry; fix: make migrate, the vitest preset, and doctor work from real installs ts-canon#3), so it loads from real installs
  • typescript, vitest, @vitest/coverage-v8, @types/node stay consumer-side; .oxlintrc.json unchanged
  • pnpm-workspace.yaml: adds minimumReleaseAgeExclude: ts-canon@0.1.0 — pnpm's supply-chain age gate (24h) rejects the just-published release, and without the exclusion pnpm install --frozen-lockfile fails with ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION. The entry is inert where no age policy is active, and becomes droppable once the release is >24h old
  • README/AGENTS updated for the ts-canon workflow; CI workflow unchanged (script names identical)
  • Net −506 lines

Verification

  • Baseline pre-migration: build/lint/test green in the worktree
  • Cold rm -rf node_modules && pnpm install --frozen-lockfile (what CI does) — against the npm registry
  • Published tarball inspected: presets (biome/tsconfig/vitest compiled pair), rules, src, bin all shipped
  • pnpm build — tsc resolves the preset extends through the install
  • pnpm lint — all 9 steps pass, biome checked 7 files via the preset extends
  • pnpm test — 3 tests, 100% coverage; config loads ts-canon/presets/vitest from node_modules (no ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING)
  • pnpm format idempotent
  • pnpm lint --fast skips audit/jscpd; path args work
  • ts-canon migrate --dry-run — "would set ts-canon to ^0" (registry spec; git installs are preserved per fix: make migrate, the vitest preset, and doctor work from real installs ts-canon#3)
  • ts-canon doctor — node 26.7.0, pandoc 3.10.2, all bundled tools, consumer typescript 7.0.2; pnpm detected under pnpm exec via packageManager
  • Windows CI (matrix) — to be confirmed by this PR's checks

ts-canon follow-ups

None. All four items from the original draft are resolved: npm publishing (0.1.0 is live), migrate preserving non-registry specs + --version flag, the compiled vitest preset, and doctor's packageManager fallback — the latter three in SynthLuvr/ts-canon#3.

Replace the per-repo toolchain copies with the ts-canon shared package
(pinned to commit ef074c9 until it is published):

- package.json: 14 per-step scripts collapse to ts-canon lint/format;
  9 tool devDependencies swap for ts-canon (typescript, vitest,
  @vitest/coverage-v8, @types/node stay)
- delete scripts/{oxlint,pandoc-md,peer-deps}.mts and .ast-grep/rules/
  (all ported into ts-canon)
- biome.json: 144-line config becomes extends of
  ts-canon/presets/biome.preset.json (content was identical)
- tsconfig.json: extends ts-canon/presets/tsconfig.base.json
- sgconfig.yml: point bare ast-grep/editor integrations at the shipped
  rules
- README/AGENTS: document the ts-canon workflow

vitest.config.ts stays inline (byte-identical to the preset): node
refuses to type-strip ts-canon/presets/vitest.ts from node_modules
(ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING).

Verified: cold pnpm install --frozen-lockfile, pnpm build, pnpm lint
(all 9 steps), pnpm test (100% coverage), pnpm format idempotent,
ts-canon doctor.
ts-canon#3 (merged) resolves the upstream blockers this PR called out:

- presets/vitest now ships compiled (vitest.mjs + vitest.d.mts) under a
  dedicated ./presets/vitest export, so it loads from real installs:
  vitest.config.ts drops its inline copy and imports vitestPreset, same
  shape as ts-canon's own config
- migrate preserves non-registry specs, so the github: pin survives a
  re-run ("would keep ts-canon github:... (non-registry spec)")
- doctor falls back to the packageManager field: pnpm now reported ok
  under pnpm exec

Pin moves ef074c9 -> 2f1fa25 (ts-canon main after #3). Still a git pin:
ts-canon is not published to npm yet.

Verified: pnpm install, pnpm build, pnpm lint (all 9 steps), pnpm test
(3 tests, 100% coverage), ts-canon doctor, migrate --dry-run, pnpm
format idempotent.
@SynthLuvr

Copy link
Copy Markdown
Owner Author

Now that SynthLuvr/ts-canon#3 is merged, rebased this PR onto it (e4c9eed):

  • Pin bumped ef074c9 → 2f1fa25 (ts-canon main after chore(deps): update all dependencies and pnpm to latest #3). Still a git pin — ts-canon remains unpublished on npm (registry 404).
  • vitest preset adopted: vitest.config.ts now imports ts-canon/presets/vitest instead of carrying an inline copy. The compiled preset (vitest.mjs/vitest.d.mts) loads fine from node_modules — pnpm test green, 100% coverage.
  • Consumer-side checks of the chore(deps): update all dependencies and pnpm to latest #3 fixes: migrate --dry-run keeps the github: spec; doctor under pnpm exec reports ok pnpm — 11.22.0 (packageManager).

pnpm build && pnpm lint && pnpm test all green. PR description updated — the only remaining upstream ask is npm publishing.

ts-canon 0.1.0 is on npmjs, so the github: pin (a stopgap from the
original migration) becomes a normal registry range:

- package.json: ^0.1.0 (same content as 2f1fa25 — 0.1.0 is the tag it
  published from; tarball verified to ship presets, rules, src, bin)
- pnpm-workspace.yaml: minimumReleaseAgeExclude ts-canon@0.1.0 — pnpm
  11's supply-chain gate rejects packages younger than 24h, and 0.1.0
  was just published; without this entry pnpm install --frozen-lockfile
  fails (ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION). Drop the entry once
  the release is 24h old, or keep it pinned to this exact version.
- AGENTS.md: "bump the pinned commit" -> "bump its version"

Verified with the registry install: pnpm install --frozen-lockfile,
pnpm build, pnpm lint (all steps), pnpm test (3 tests, 100% coverage),
ts-canon doctor, migrate --dry-run (now "would set ts-canon to ^0"),
pnpm format idempotent.
@SynthLuvr

Copy link
Copy Markdown
Owner Author

ts-canon is on npm now (0.1.0, published 2026-08-27), so this PR switches off the stopgap git pin (b68842a):

  • github:…#2f1fa25 → ^0.1.0 from the registry — I verified the published tarball ships everything the template consumes (biome/tsconfig presets, compiled vitest preset, rules, src/, bin/).
  • One wrinkle: pnpm 11's minimumReleaseAge supply-chain gate rejects packages younger than 24h, so pnpm install --frozen-lockfile failed against the fresh release (ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION). pnpm-workspace.yaml now carries minimumReleaseAgeExclude: ts-canon@0.1.0 (pnpm's own remediation, scoped to the exact version). It's a no-op where no age policy is active and can be dropped once 0.1.0 is >24h old.
  • AGENTS.md wording: "bump the pinned commit" → "bump its version".

Re-verified from the registry install: pnpm build && pnpm lint && pnpm test green (3 tests, 100% coverage), doctor clean, migrate --dry-run now says "would set ts-canon to ^0", pnpm format idempotent. PR description updated — no upstream follow-ups remain.

Comment thread pnpm-workspace.yaml Outdated
ts-canon 0.1.0 was published 2026-08-27T16:39:44Z and is now >24h old,
so pnpm 11's supply-chain age gate no longer rejects it. Verified with
cold pnpm install --frozen-lockfile plus build/lint/test, all green.
@SynthLuvr
SynthLuvr merged commit b2f3f1c into main Aug 28, 2026
2 checks passed
@SynthLuvr
SynthLuvr deleted the chore/adopt-ts-canon branch August 28, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant