Prune migration notes and align the notes with the current lint setup
Check / check (pull_request) Successful in 39s
Check / check (pull_request) Successful in 39s
This commit is contained in:
@@ -12,7 +12,9 @@ Node + Vite+ migration (PR #20, `node-migration`, 2026-10-15/16):
|
|||||||
consumer (`uses: .../commons/bot-agents@<branch>`) on a throwaway PR.
|
consumer (`uses: .../commons/bot-agents@<branch>`) on a throwaway PR.
|
||||||
- **Profiles are JSON.** `profiles.yml` became `profiles.json` with the same
|
- **Profiles are JSON.** `profiles.yml` became `profiles.json` with the same
|
||||||
content (encrypted `v1:` values unchanged), read with `JSON.parse`. That
|
content (encrypted `v1:` values unchanged), read with `JSON.parse`. That
|
||||||
removed the only runtime dependency (`@std/yaml`); keep it dependency-free.
|
removed the only runtime dependency (`@std/yaml`); keep it free of runtime
|
||||||
|
dependencies (`@eslint/core` and the other devDependencies serve only the
|
||||||
|
tooling).
|
||||||
- **Node 24.2+**, not 22: `src/post.ts` uses `import.meta.main`. `engines.node`
|
- **Node 24.2+**, not 22: `src/post.ts` uses `import.meta.main`. `engines.node`
|
||||||
is `>=24.2`, which the user accepted for this repo
|
is `>=24.2`, which the user accepted for this repo
|
||||||
([[bot-agents-runtime-no-build]]).
|
([[bot-agents-runtime-no-build]]).
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
---
|
---
|
||||||
description: bot-agents lint has prefer-readonly-parameter-types off (Node/web types can't satisfy it) and one scripts/** override for no-unsafe-enum-comparison; nothing else
|
description: bot-agents lint has prefer-readonly-parameter-types off (Node/web types can't satisfy it) and no overrides; nothing else
|
||||||
---
|
---
|
||||||
|
|
||||||
The repo follows [[lint-config-shape]] with two recorded exceptions, both
|
The repo follows [[lint-config-shape]] with one recorded exception, present
|
||||||
present when the migration PR was approved:
|
when the migration PR was approved:
|
||||||
|
|
||||||
- `typescript/prefer-readonly-parameter-types` is `"off"` in
|
- `typescript/prefer-readonly-parameter-types` is `"off"` in
|
||||||
`scripts/project-lint.ts`, as in the explicit-types template, because
|
`scripts/project-lint.ts`, as in the explicit-types template, because
|
||||||
Node/web types (`Response`, `Stats`, `RequestInit`) can never satisfy it.
|
Node/web types (`Response`, `Stats`, `RequestInit`) can never satisfy it.
|
||||||
- `vite.config.ts` has one `overrides` entry, for `scripts/**` only:
|
- `vite.config.ts` has no `overrides`. The `scripts/**` override for
|
||||||
`typescript/no-unsafe-enum-comparison` off, because the lint plugin compares
|
`typescript/no-unsafe-enum-comparison` was removed (2026-10-16):
|
||||||
AST node `type`s, which the AST types declare as an enum. This is the
|
`scripts/project-lint.ts` compares node types with `AST_NODE_TYPES` members
|
||||||
tooling exception [[lint-overrides-policy]] allows.
|
from `@typescript-eslint/types` instead of string literals
|
||||||
|
([[lint-overrides-policy]]).
|
||||||
|
|
||||||
Oxlint's default size limits apply to `src/`; the migration split `run.ts`
|
Oxlint's default size limits apply to `src/`; the migration split `run.ts`
|
||||||
into `run-context.ts`, `agents.ts`, and `agent-{claude,codex,opencode}.ts`,
|
into `run-context.ts`, `agents.ts`, and `agent-{claude,codex,opencode}.ts`,
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
description: Every repo moved from Deno to Node + Vite+ in Oct 2026 because Cloudflare bought Deno; nothing goes back to Deno
|
|
||||||
---
|
|
||||||
|
|
||||||
On 2026-10-12 the user moved every project from Deno to Node.js + Vite+
|
|
||||||
(`vp`). Cloudflare bought Deno on 2026-10-09; the runtime gets roughly 12
|
|
||||||
months of maintenance and Deno Deploy shuts down around April 2027. None of the
|
|
||||||
repos used Deploy or KV, so the move is about the toolchain, not hosting.
|
|
||||||
|
|
||||||
Do not reintroduce `deno.json`, `deno.lock`, `Deno.*` APIs, `jsr:` or `npm:`
|
|
||||||
specifiers, `mod.ts` entries, or `deno task` anywhere, docs and scripts
|
|
||||||
included.
|
|
||||||
|
|
||||||
## Order the migration followed
|
|
||||||
|
|
||||||
1. The custom Deno lint plugins were ported to npm first, as
|
|
||||||
`@cunarist/eslint-plugin-explicit-types`, `-import-check`, and `-lit`.
|
|
||||||
`cunarist/eslint-plugin-explicit-types` is the template every other repo
|
|
||||||
copies (config shape, `scripts/project-lint.ts`, AGENTS.md, notes).
|
|
||||||
2. Then `commons/bot-agents` (six repos use it as an action), then the apps:
|
|
||||||
home, eximium, stockvibe, brain, memona, memona-home.
|
|
||||||
3. deno-practice, interview-practice, web-landing, and vemium were left out
|
|
||||||
(archivable). Old `cunarist/deno-*` repos are archived one at a time, and
|
|
||||||
only after their `eslint-plugin-*` replacement is published to npm.
|
|
||||||
|
|
||||||
## What "migrated" means
|
|
||||||
|
|
||||||
- Same behavior. A migration PR changes tooling, not features.
|
|
||||||
- Lint coverage is at least what Deno enforced: [[lint-parity-never-shrinks]].
|
|
||||||
- Only three config files and only `.ts`: [[toolchain-node-vite-plus]],
|
|
||||||
[[ts-only-files-and-imports]].
|
|
||||||
- Deno.test suites became Vitest: [[tests-layout-vitest]].
|
|
||||||
|
|
||||||
The custom plugins' Deno names map like this:
|
|
||||||
|
|
||||||
| Deno | npm |
|
|
||||||
| ----------------------------------------------- | ---------------------------------------- |
|
|
||||||
| `jsr:@cunarist/deno-lint-plugin-explicit-types` | `@cunarist/eslint-plugin-explicit-types` |
|
|
||||||
| `jsr:@cunarist/deno-import-check` (`./lint`) | `@cunarist/eslint-plugin-import-check` |
|
|
||||||
| `jsr:@cunarist/deno-lint-plugin-lit` | `@cunarist/eslint-plugin-lit` |
|
|
||||||
| `scripts/deno-lint-plugin.ts` (per app) | `scripts/project-lint.ts` (per app) |
|
|
||||||
|
|
||||||
Until those packages are on npm, a repo that depends on them fails `npm ci` in
|
|
||||||
CI; that is expected and stated in the PR, never worked around by committing
|
|
||||||
tarballs or `file:` dependencies.
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
description: Shared code comes through # aliases in package.json imports, each directory's entry is index.ts, barrels keep imports few; never ../ out of a directory
|
description: Shared code comes through # aliases in package.json imports, each src/ subfolder's entry is index.ts, barrels keep imports few; never ../ out of a directory
|
||||||
---
|
---
|
||||||
|
|
||||||
## `#` aliases
|
## `#` aliases
|
||||||
@@ -44,8 +44,9 @@ so they never reach package consumers.
|
|||||||
|
|
||||||
## `index.ts` entries and barrels
|
## `index.ts` entries and barrels
|
||||||
|
|
||||||
- Every directory's entry file is `index.ts`, never `mod.ts` (decided
|
- Every `src/` subfolder's entry file is `index.ts`, never `mod.ts` (decided
|
||||||
2026-10-12; import-check's `enforce-mod-file` now requires `index.ts`).
|
2026-10-12; import-check's `enforce-mod-file` requires it only in folders a
|
||||||
|
`#` alias owns). Folders outside `src/`, such as `scripts/`, have none.
|
||||||
- A directory used from outside exposes its API through its `index.ts`
|
- A directory used from outside exposes its API through its `index.ts`
|
||||||
barrel, and callers import the barrel (`#ui`), not files inside it
|
barrel, and callers import the barrel (`#ui`), not files inside it
|
||||||
(`no-barrel-bypass`).
|
(`no-barrel-bypass`).
|
||||||
|
|||||||
@@ -22,11 +22,10 @@ lint: {
|
|||||||
- **Default limits stay** (2026-10-16): pedantic's `max-lines` 300,
|
- **Default limits stay** (2026-10-16): pedantic's `max-lines` 300,
|
||||||
`max-lines-per-function` 50, `max-classes-per-file` 1,
|
`max-lines-per-function` 50, `max-classes-per-file` 1,
|
||||||
`max-dependencies` 10, `max-params` 3, `complexity` 20. Don't raise them to
|
`max-dependencies` 10, `max-params` 3, `complexity` 20. Don't raise them to
|
||||||
make code pass; refactor (see [[lint-overrides-policy]]). Apps follow this
|
make code pass; refactor (see [[lint-overrides-policy]]). `max-lines` stays
|
||||||
strictly. The plugin template already turns off `max-lines`,
|
at 300 everywhere, `scripts/` included, with no override (2026-10-16): split
|
||||||
`max-lines-per-function`, `typescript/prefer-readonly-parameter-types`, and
|
a long file by theme instead. Do not add new opt-outs anywhere without
|
||||||
`typescript/no-unsafe-enum-comparison` because AST visitors fight them; do
|
asking the user.
|
||||||
not add new opt-outs anywhere without asking the user.
|
|
||||||
- **`vite.config.ts` names no rule.** Every rule id, built-in ones included,
|
- **`vite.config.ts` names no rule.** Every rule id, built-in ones included,
|
||||||
lives in `configs.project` of `scripts/project-lint.ts`
|
lives in `configs.project` of `scripts/project-lint.ts`
|
||||||
([[project-lint-plugin]]). `vite.config.ts` only spreads configs.
|
([[project-lint-plugin]]). `vite.config.ts` only spreads configs.
|
||||||
|
|||||||
@@ -29,9 +29,10 @@ registerHooks({
|
|||||||
```
|
```
|
||||||
|
|
||||||
- Node runs the `.ts` script directly (type stripping), so no build step.
|
- Node runs the `.ts` script directly (type stripping), so no build step.
|
||||||
- **Gotcha:** the obvious `await import("lit-analyzer/cli.js")` fails
|
- Import the package entry, or spawn the package's bin with
|
||||||
`project/no-non-ts-imports` (a `.js` subpath). Import the package entry, or
|
`node:child_process`, rather than `await import("lit-analyzer/cli.js")`.
|
||||||
spawn the package's bin with `node:child_process`, instead.
|
`project/no-asset-imports` allows `.js` subpaths, but the CLI file runs on
|
||||||
|
import and bypasses the package's public entry.
|
||||||
- CI runs `npm run lit-check` as its own step.
|
- CI runs `npm run lit-check` as its own step.
|
||||||
- It is tooling under `scripts/`: no tests; a narrow `overrides` entry for it
|
- It is tooling under `scripts/`: no tests; a narrow `overrides` entry for it
|
||||||
(e.g. `no-console`) is allowed if truly needed.
|
(e.g. `no-console`) is allowed if truly needed.
|
||||||
|
|||||||
@@ -1,32 +1,13 @@
|
|||||||
---
|
---
|
||||||
description: package.json key order is metadata, scripts, exports, imports, devDependencies, dependencies; standard fields only; no peerDependencies or packageManager
|
description: package.json keys follow Oxfmt's standard order (vp check --fix); standard fields only; no peerDependencies or packageManager
|
||||||
---
|
---
|
||||||
|
|
||||||
## Key order (2026-10-14)
|
## Key order (2026-10-16)
|
||||||
|
|
||||||
Metadata first, then `scripts`, `exports`, `imports`, `devDependencies`,
|
Oxfmt's standard `package.json` sorting is accepted: there is no
|
||||||
`dependencies`. Oxfmt would re-sort the file, so `vite.config.ts` sets
|
`fmt: { sortPackageJson: false }`, and `vp check --fix` sets the order. This
|
||||||
`fmt: { sortPackageJson: false }`; keep it, and keep the order by hand.
|
replaces the earlier hand-written order (metadata, `scripts`, `exports`,
|
||||||
|
`imports`, `devDependencies`, `dependencies`).
|
||||||
```jsonc
|
|
||||||
{
|
|
||||||
"name": "@cunarist/eslint-plugin-x",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"description": "...",
|
|
||||||
"keywords": ["eslint", "eslint-plugin", "eslintplugin", "oxlint"],
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": { "type": "git", "url": "git+https://github.com/..." },
|
|
||||||
"type": "module",
|
|
||||||
"files": ["dist"],
|
|
||||||
"engines": { "node": ">=22" },
|
|
||||||
"eslint-doc-generator": {/* tool options that can only live here */},
|
|
||||||
"scripts": { "docs": "eslint-doc-generator" },
|
|
||||||
"exports": { ".": "./dist/index.js" },
|
|
||||||
"imports": { "#helpers": "./src/helpers/index.ts" },
|
|
||||||
"devDependencies": { "vite-plus": "^1.1.0" },
|
|
||||||
"dependencies": {},
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `imports` key order can carry meaning: import-check's
|
The `imports` key order can carry meaning: import-check's
|
||||||
`enforce-layer-order` reads it as the layer order. Never reorder it casually.
|
`enforce-layer-order` reads it as the layer order. Never reorder it casually.
|
||||||
|
|||||||
@@ -11,11 +11,15 @@ Oxlint plugin with `meta.name` `"project"`, loaded through `jsPlugins` in
|
|||||||
plugin configs: Deno parity rules, extras, per-rule options, and opt-outs,
|
plugin configs: Deno parity rules, extras, per-rule options, and opt-outs,
|
||||||
built-in Oxlint ids included (`curly`, `id-match`, `import/no-cycle`, ...).
|
built-in Oxlint ids included (`curly`, `id-match`, `import/no-cycle`, ...).
|
||||||
- **Custom rules**, enabled as `project/<rule>`. Every repo has
|
- **Custom rules**, enabled as `project/<rule>`. Every repo has
|
||||||
`no-disable-comments` and `no-non-ts-imports`. Apps also port the rules of
|
`no-disable-comments` and `no-asset-imports`. Apps also port the rules of
|
||||||
their old `scripts/deno-lint-plugin.ts` here under the same names and
|
their old `scripts/deno-lint-plugin.ts` here under the same names and
|
||||||
behavior (`no-self-sync`, `app-module-conventions`, `restricted-types`, ...).
|
behavior (`no-self-sync`, `app-module-conventions`, `restricted-types`, ...).
|
||||||
|
|
||||||
Rules and plugin stay in this one file; don't add `scripts/rules/`.
|
`scripts/` stays flat; don't add `scripts/rules/`. A file that would pass
|
||||||
|
`max-lines` (300) splits into flat themed files sharing the prefix:
|
||||||
|
`scripts/project-lint.ts` keeps the plugin object and the rule list and
|
||||||
|
imports the others (`project-lint-modules.ts`, `project-lint-types.ts`,
|
||||||
|
`project-lint-lit.ts`, ...).
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { DummyRuleMap } from "vite-plus/lint";
|
import type { DummyRuleMap } from "vite-plus/lint";
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Standing convention (2026-10-12), applied to every package:
|
|||||||
(`--generate-notes`, edited there). There is no `CHANGELOG.md`; never add
|
(`--generate-notes`, edited there). There is no `CHANGELOG.md`; never add
|
||||||
one.
|
one.
|
||||||
- **The version lives in two places in plugin packages:** `package.json` and
|
- **The version lives in two places in plugin packages:** `package.json` and
|
||||||
`meta.version` in `src/index.ts`; `tests/package-meta.test.ts` fails if they
|
`meta.version` in `src/plugin/index.ts`; `tests/package-meta.test.ts` fails if they
|
||||||
differ.
|
differ.
|
||||||
- **Before 1.0**, a change that breaks users (renamed rule id, a rule that
|
- **Before 1.0**, a change that breaks users (renamed rule id, a rule that
|
||||||
fires on more code, removed behavior) is a minor bump.
|
fires on more code, removed behavior) is a minor bump.
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ before any push. CI installs the toolchain with `voidzero-dev/setup-vp`.
|
|||||||
|
|
||||||
- `vp check` does **not** report `isolatedDeclarations` errors (TS9010); only
|
- `vp check` does **not** report `isolatedDeclarations` errors (TS9010); only
|
||||||
`vp pack` does, so packages run `vp pack` in CI on every PR.
|
`vp pack` does, so packages run `vp pack` in CI on every PR.
|
||||||
- Oxfmt sorts `package.json` keys by default, which destroys the required key
|
- Oxfmt sorts `package.json` keys by default; that order is accepted, so
|
||||||
order. Set `fmt: { sortPackageJson: false }` ([[package-json-shape]]).
|
there is no `fmt` option for it ([[package-json-shape]]).
|
||||||
- Oxlint and Oxfmt skip what `.gitignore` lists; that is the only reason
|
- Oxlint and Oxfmt skip what `.gitignore` lists; that is the only reason
|
||||||
`dist/` and `node_modules/` are not linted. Keep build output gitignored.
|
`dist/` and `node_modules/` are not linted. Keep build output gitignored.
|
||||||
- Vite+ bundles `vite.config.ts` itself and resolves `#` imports in it.
|
- Vite+ bundles `vite.config.ts` itself and resolves `#` imports in it.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
description: Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included) and source imports only .ts; CSS comes from HTML, JSON/SVG become .ts modules
|
description: Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included); imports name only .ts files or .js package subpaths; CSS comes from HTML, JSON/SVG become .ts modules
|
||||||
---
|
---
|
||||||
|
|
||||||
The user's rule, from the Deno days and restated for Node (2026-10-12): "No
|
The user's rule, from the Deno days and restated for Node (2026-10-12): "No
|
||||||
@@ -12,12 +12,14 @@ plain `.ts`. Build output in a gitignored folder is the only JS.
|
|||||||
`noUncheckedIndexedAccess`). If a tool or framework seems to need a JS or TSX
|
`noUncheckedIndexedAccess`). If a tool or framework seems to need a JS or TSX
|
||||||
file, stop and flag it instead of adding one.
|
file, stop and flag it instead of adding one.
|
||||||
|
|
||||||
## Only `.ts` imports (2026-10-14)
|
## No asset imports (2026-10-14, widened 2026-10-16)
|
||||||
|
|
||||||
`project/no-non-ts-imports` (in `scripts/project-lint.ts`) fails:
|
`.ts` and `.js` imports are allowed: our own files stay `.ts`, and `.js`
|
||||||
|
covers package subpaths such as `lit/decorators.js`.
|
||||||
|
`project/no-asset-imports` (in `scripts/project-lint.ts`) fails:
|
||||||
|
|
||||||
- a relative, absolute, `#`, or package-subpath specifier whose last segment
|
- a relative, absolute, `#`, or package-subpath specifier whose last segment
|
||||||
has a non-`.ts` extension: `.css`, `.json`, `.svg`, `.js`, `.mjs`, `.tsx`;
|
has any other extension: `.css`, `.json`, `.svg`, `.mjs`, `.tsx`;
|
||||||
- any `?query` suffix (`?raw`, `?url`, `?inline`);
|
- any `?query` suffix (`?raw`, `?url`, `?inline`);
|
||||||
- any import attributes (`with { type: "json" }`, `with { type: "text" }`).
|
- any import attributes (`with { type: "json" }`, `with { type: "text" }`).
|
||||||
|
|
||||||
@@ -44,5 +46,6 @@ import { scenes } from "#data/scenes"; // yes: scenes.ts
|
|||||||
and fails on drift (the plugin repos do this for `meta.name`/`meta.version`).
|
and fails on drift (the plugin repos do this for `meta.name`/`meta.version`).
|
||||||
- **Reading a file is not importing it.** `readFileSync` + `JSON.parse` is
|
- **Reading a file is not importing it.** `readFileSync` + `JSON.parse` is
|
||||||
fine in tooling and tests.
|
fine in tooling and tests.
|
||||||
- **A tool's `.js` entry:** don't `import("pkg/cli.js")`; use the package
|
- **A tool's CLI file:** prefer the package entry or spawning the package's
|
||||||
entry or spawn the package's bin ([[lit-analyzer-ts6]]).
|
bin over importing `pkg/cli.js`, which runs the CLI as a side effect
|
||||||
|
([[lit-analyzer-ts6]]).
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
---
|
|
||||||
name: migrate-deno-repo
|
|
||||||
description: Checklist for moving a Deno repo (or a leftover Deno part of one) to Node 22+ + Vite+ with npm, same behavior, full lint parity, one PR
|
|
||||||
---
|
|
||||||
|
|
||||||
Template: `cunarist/eslint-plugin-explicit-types` on `main`. Read its
|
|
||||||
`AGENTS.md`, `vite.config.ts`, `scripts/project-lint.ts`, `package.json`, and
|
|
||||||
CI before starting, and copy their shape. Never ask the user mid-way when
|
|
||||||
they're away: decide by the memories, record the choice in the PR.
|
|
||||||
|
|
||||||
Branch `node-migration` (apps) or `initial-port` (new plugin repos); one PR
|
|
||||||
with everything.
|
|
||||||
|
|
||||||
**Inventory first**
|
|
||||||
|
|
||||||
- [ ] List every `deno.json` task, import-map entry, lint rule (tags,
|
|
||||||
includes, `@hugoalh`, custom plugins), test, `Deno.*` call, JSON/CSS/SVG
|
|
||||||
import, and every place the output is consumed (Rust, HTML,
|
|
||||||
Containerfile, CI).
|
|
||||||
|
|
||||||
**Toolchain**
|
|
||||||
|
|
||||||
- [ ] `package.json` in the required key order, `engines.node ">=22"`, no
|
|
||||||
`packageManager`, no `peerDependencies`; `npm install`; commit
|
|
||||||
`package-lock.json`.
|
|
||||||
- [ ] `tsconfig.json` from the template; `vite.config.ts` with `fmt:
|
|
||||||
{ sortPackageJson: false }` and the category-based `lint` block.
|
|
||||||
- [ ] Delete `deno.json`, `deno.lock`, and Deno-only files. `mod.ts` →
|
|
||||||
`index.ts`; `deno.json` imports → `package.json` `imports` (`#x/*`
|
|
||||||
patterns for trailing-slash mappings; aliases may target only direct
|
|
||||||
subfolders of `src/`, anything else becomes a relative import);
|
|
||||||
`jsr:`/`npm:` → npm packages.
|
|
||||||
|
|
||||||
**Code**
|
|
||||||
|
|
||||||
- [ ] Only `.ts` files; no non-`.ts` imports: CSS via `<link>`, JSON and SVG
|
|
||||||
as `.ts` modules, icons in memona's style.
|
|
||||||
- [ ] `Deno.*` → `node:*` / `process`. Generated JS written as `.ts`, built,
|
|
||||||
gitignored.
|
|
||||||
- [ ] Decorators stay standard with `accessor`; add `scripts/decorators.ts`
|
|
||||||
if the repo has any. Lit repos: `scripts/lit-check.ts` + `npm run
|
|
||||||
lit-check`.
|
|
||||||
- [ ] `scripts/` is flat: no subfolders, no `index.ts` (barrels live only in
|
|
||||||
`src/`); `vite.config.ts` imports `./scripts/<name>.ts` directly. A
|
|
||||||
scripts subfolder that is really an app moves under `src/`.
|
|
||||||
|
|
||||||
**Lint**
|
|
||||||
|
|
||||||
- [ ] `scripts/project-lint.ts` copied; old local Deno lint rules ported into
|
|
||||||
it; parity mapping for every former rule; `id-match`; no disable
|
|
||||||
comments; no source `overrides`; refactor size-rule hits.
|
|
||||||
|
|
||||||
**Tests**
|
|
||||||
|
|
||||||
- [ ] `Deno.test` → Vitest (codemod, then finish TODOs); unit tests next to
|
|
||||||
code, integration in `tests/`; no case dropped.
|
|
||||||
|
|
||||||
**Build, ship, CI**
|
|
||||||
|
|
||||||
- [ ] `vp build` in app mode with the same output paths, or `vp pack` for
|
|
||||||
packages. Containerfile node stage on `node:24-alpine`. CI with
|
|
||||||
`setup-vp`: `vp check`, build, `vp test` (+ lit-check). Packages:
|
|
||||||
release-triggered `publish.yml`.
|
|
||||||
- [ ] `AGENTS.md` with the damem header, `.agents/` notes from the damem kit,
|
|
||||||
README updated (Node.js 22+, no Deno instructions). `damem doctor`
|
|
||||||
clean.
|
|
||||||
|
|
||||||
**Finish**
|
|
||||||
|
|
||||||
- [ ] `vp check`, `vp test`, build all pass locally; the app runs.
|
|
||||||
- [ ] Commit in plain imperative sentences; open the PR (summary, changes,
|
|
||||||
parity mapping, deviations/risks, "CI fails until @cunarist/eslint-plugin-*
|
|
||||||
are published" if relevant, verification, footer line).
|
|
||||||
- [ ] Run `review-cycle`. Never merge, publish, or archive.
|
|
||||||
Reference in New Issue
Block a user