4 Commits

Author SHA1 Message Date
Danny Kim 0920a4e91b Use the unscoped eslint-plugin names in the notes
Check / check (pull_request) Successful in 38s
2026-10-18 22:18:55 +09:00
Danny Kim 627458fb5f Limit the parent-path ban in the notes to imports
Check / check (pull_request) Successful in 1m24s
2026-10-18 03:50:14 +09:00
Danny Kim 50df193a8c Limit the #testing note to tests that use its helpers
Check / check (pull_request) Successful in 58s
2026-10-18 03:40:16 +09:00
Danny Kim 5b568f9ea6 Turn off unreachable code and unused labels in tsconfig
Check / check (pull_request) Successful in 39s
2026-10-18 03:18:25 +09:00
7 changed files with 47 additions and 38 deletions
@@ -1,5 +1,5 @@
--- ---
description: bot-agents migration decisions: live @main action for six repos, JSON profiles, Node 24.2+, Deno kept only for agents, no @cunarist plugins needed description: bot-agents migration decisions: live @main action for six repos, JSON profiles, Node 24.2+, Deno kept only for agents, no eslint-plugin-* packages needed
--- ---
Decisions for `commons/bot-agents` (Capsulizers Gitea), from the Deno to Decisions for `commons/bot-agents` (Capsulizers Gitea), from the Deno to
@@ -22,10 +22,13 @@ Node + Vite+ migration (PR #20, `node-migration`, 2026-10-15/16):
because the agents still check Deno-based consumer repos (memona, because the agents still check Deno-based consumer repos (memona,
memona-home). Remove it once those repos have moved; it is not a memona-home). Remove it once those repos have moved; it is not a
dependency of this repo's TypeScript. dependency of this repo's TypeScript.
- **No `@cunarist/eslint-plugin-*`.** The Deno setup enabled no plugin, so - **No `eslint-plugin-*` packages** (`eslint-plugin-explicit-types`,
this repo depends on none and CI passes without them being published. `eslint-plugin-import-structure`, `eslint-plugin-lit-robust`; unscoped
Planned (2026-10-17): once the plugins are on npm, add since 2026-10-18, formerly `@cunarist/...`). The Deno setup enabled no
`@cunarist/eslint-plugin-modules` here for its import checks. plugin, so this repo depends on none and CI passes without them being
published. Planned (2026-10-17): once the plugins are on npm, add
`eslint-plugin-import-structure` (rule prefix `import-structure/`) here for
its import checks.
- **Stricter input checks were accepted** in the migration: Gitea `/user` and - **Stricter input checks were accepted** in the migration: Gitea `/user` and
comment responses, the runtime manifest, and the outcome's profile type are comment responses, the runtime manifest, and the outcome's profile type are
validated; some type errors became `TypeError` with the same messages. validated; some type errors became `TypeError` with the same messages.
+11 -9
View File
@@ -11,23 +11,25 @@ unbuilt. `vp pack` inlines them, so they never reach package consumers.
One rule for every file, never tied to folder or file names (user rule One rule for every file, never tied to folder or file names (user rule
2026-10-17; it replaces the earlier "aliases only point at direct `src/` 2026-10-17; it replaces the earlier "aliases only point at direct `src/`
subfolders" rule as the general rule, and the "modules plugin checks only subfolders" rule as the general rule, and the "import-structure plugin
aliased folders" scope; this repo keeps the stricter rule as a local checks only aliased folders" scope; this repo keeps the stricter rule as a
convention, see the last section): local convention, see the last section):
- **An alias may point anywhere** and owns its target. An alias to a - **An alias may point anywhere** and owns its target. An alias to a
folder's `index.ts` owns that folder and everything below it; an alias to folder's `index.ts` owns that folder and everything below it; an alias to
any other file owns only that file. any other file owns only that file.
- **No overlap.** No file may be owned by 2 aliases: no alias inside another - **No overlap.** No file may be owned by 2 aliases: no alias inside another
alias's area, and no 2 aliases with the same target. The modules plugin's alias's area, and no 2 aliases with the same target. The import-structure
`enforce-layer-order` reports it once at the top of every file 2 aliases plugin's `enforce-layer-order` reports it once at the top of every file 2
claim. Fix by merging the aliases or moving files apart. aliases claim. Fix by merging the aliases or moving files apart.
- **Outside an area, only the exact alias reaches it.** A deeper alias - **Outside an area, only the exact alias reaches it.** A deeper alias
specifier (`#a/one.ts`, `no-barrel-bypass`) and a relative path into the specifier (`#a/one.ts`, `no-barrel-bypass`) and a relative path into the
area (`./a/one.ts`, `no-relative-bypass`; `./b/f.ts` to a file alias, area (`./a/one.ts`, `no-relative-bypass`; `./b/f.ts` to a file alias,
`prefer-alias-import`, fixed to the alias) are bypasses. `prefer-alias-import`, fixed to the alias) are bypasses.
- **Inside an area, relative imports of siblings and subfolders are free.** - **Inside an area, relative imports of siblings and subfolders are free.**
- **`../` is banned in every file**, owned or not (`no-parent-import`). - **A `../` import is banned in every file**, owned or not (`no-parent-import`).
Runtime file URLs (`new URL("../prompt.md", import.meta.url)`) are not
imports and are allowed.
Anything above a file needs an alias. Anything above a file needs an alias.
- **Files no alias owns** need no `index.ts` and no alias, and import `./` - **Files no alias owns** need no `index.ts` and no alias, and import `./`
siblings and subfolders freely. siblings and subfolders freely.
@@ -89,8 +91,8 @@ Relative imports are written with the `.ts` extension.
## Local convention: aliases target direct `src/` subfolders ## Local convention: aliases target direct `src/` subfolders
This is a convention of this repo only, stricter than the general rule above This is a convention of this repo only, stricter than the general rule above
(which the published modules plugin checks and which allows more). It is not (which the published import-structure plugin checks and which allows more).
a plugin rule. It is not a plugin rule.
- Every `package.json` `imports` alias points only at the `index.ts` of a - Every `package.json` `imports` alias points only at the `index.ts` of a
direct subfolder of `src/`, e.g. `"#helpers": "./src/helpers/index.ts"`. direct subfolder of `src/`, e.g. `"#helpers": "./src/helpers/index.ts"`.
+3 -3
View File
@@ -8,7 +8,7 @@ turn on whole categories, then list only what parity or a real need adds.
```ts ```ts
lint: { lint: {
plugins: ["typescript", "unicorn", "oxc", "import"], plugins: ["typescript", "unicorn", "oxc", "import"],
jsPlugins: ["@cunarist/eslint-plugin-explicit-types", "./scripts/project-lint.ts"], jsPlugins: ["eslint-plugin-explicit-types", "./scripts/project-lint.ts"],
categories: { correctness: "error", suspicious: "error", pedantic: "error", perf: "error" }, categories: { correctness: "error", suspicious: "error", pedantic: "error", perf: "error" },
rules: { ...explicitTypes.configs.concrete.rules, ...projectLint.configs.project.rules }, rules: { ...explicitTypes.configs.concrete.rules, ...projectLint.configs.project.rules },
ignorePatterns: ["src/generated/**"], // generated files only, see below ignorePatterns: ["src/generated/**"], // generated files only, see below
@@ -40,8 +40,8 @@ lint: {
Hand-written code is never ignored. Hand-written code is never ignored.
- **No lint disable comments**: [[lint-no-disable-comments]]. - **No lint disable comments**: [[lint-no-disable-comments]].
- **Parity:** [[lint-parity-never-shrinks]]. **Naming:** [[naming-id-match]]. - **Parity:** [[lint-parity-never-shrinks]]. **Naming:** [[naming-id-match]].
- Don't add a second import sorter; the modules plugin's `enforce-import-order` is - Don't add a second import sorter; the import-structure plugin's
the only one, and Oxfmt's `sortImports` stays off. `enforce-import-order` is the only one, and Oxfmt's `sortImports` stays off.
`perf` came last: in the template it flagged nine `.includes` on constant `perf` came last: in the template it flagged nine `.includes` on constant
arrays, fixed as `ReadonlySet` + `.has()` rather than by turning a rule off. arrays, fixed as `ReadonlySet` + `.has()` rather than by turning a rule off.
+2 -2
View File
@@ -9,7 +9,7 @@ Oxfmt's standard `package.json` sorting is accepted: there is no
replaces the earlier hand-written order (metadata, `scripts`, `exports`, replaces the earlier hand-written order (metadata, `scripts`, `exports`,
`imports`, `devDependencies`, `dependencies`). `imports`, `devDependencies`, `dependencies`).
The `imports` key order can carry meaning: the modules plugin's The `imports` key order can carry meaning: the import-structure plugin'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.
## Fields ## Fields
@@ -23,7 +23,7 @@ The `imports` key order can carry meaning: the modules plugin's
- **No `peerDependencies`, ever** (user preference, 2026-10-14). If something - **No `peerDependencies`, ever** (user preference, 2026-10-14). If something
is needed at runtime, it goes in `dependencies`. is needed at runtime, it goes in `dependencies`.
- **`dependencies`** = what runs or is type-referenced at runtime by consumers - **`dependencies`** = what runs or is type-referenced at runtime by consumers
(the lit plugin ships `parse5`, `oxc-parser`, `oxc-resolver`, and (the lit-robust plugin ships `parse5`, `oxc-parser`, `oxc-resolver`, and
`@eslint/core` for its public types; they stay external, never bundled). `@eslint/core` for its public types; they stay external, never bundled).
- **`devDependencies`** = everything else: `vite-plus`, `eslint`, - **`devDependencies`** = everything else: `vite-plus`, `eslint`,
`@typescript-eslint/parser`, `eslint-doc-generator`, `esbuild`, `@typescript-eslint/parser`, `eslint-doc-generator`, `esbuild`,
+9 -8
View File
@@ -6,16 +6,17 @@ The user's rule, from the Deno days and restated for Node (2026-10-12): "No
JS, not even JSX/TSX, only TS." Source, scripts, tests, and configs are all JS, not even JSX/TSX, only TS." Source, scripts, tests, and configs are all
plain `.ts`. Build output in a gitignored folder is the only JS. plain `.ts`. Build output in a gitignored folder is the only JS.
`tsconfig.json`: no `allowJs`, no `jsx`, and exactly this strictness set `tsconfig.json`: no `allowJs`, no `jsx`, and exactly this strictness set (user
(user decision, 2026-10-18): `strict` (written out), `noUncheckedIndexedAccess`, decision, 2026-10-18): `strict` (written out), `noUncheckedIndexedAccess`,
`noPropertyAccessFromIndexSignature`, `noImplicitReturns`, `noUnusedLocals`, `noPropertyAccessFromIndexSignature`, `noImplicitReturns`, `noUnusedLocals`,
`noUnusedParameters`, `noImplicitOverride`, `noFallthroughCasesInSwitch`, `noUnusedParameters`, `noImplicitOverride`, `noFallthroughCasesInSwitch`,
`erasableSyntaxOnly`, plus the mechanical `verbatimModuleSyntax`, `erasableSyntaxOnly`, and `allowUnreachableCode: false` plus
`allowImportingTsExtensions`, and `noEmit` (packages also keep `declaration` `allowUnusedLabels: false` (user decision, 2026-10-18; on in the Deno setup),
and `isolatedDeclarations`). `exactOptionalPropertyTypes` is off everywhere: plus the mechanical `verbatimModuleSyntax`, `allowImportingTsExtensions`, and
write `{ key: maybeUndefined }` rather than leaving the key out to please it. `noEmit` (packages also keep `declaration` and `isolatedDeclarations`).
If a tool or framework seems to need a JS or TSX file, stop and flag it `exactOptionalPropertyTypes` is off everywhere: write `{ key: maybeUndefined }`
instead of adding one. rather than leaving the key out to please it. If a tool or framework seems to
need a JS or TSX file, stop and flag it instead of adding one.
## No asset imports (2026-10-14, widened 2026-10-16 and 2026-10-17) ## No asset imports (2026-10-14, widened 2026-10-16 and 2026-10-17)
+11 -10
View File
@@ -29,16 +29,17 @@ below it; an alias to any other file owns only that file. No overlap: no file
may be owned by 2 aliases, so no alias inside another alias's area and no 2 may be owned by 2 aliases, so no alias inside another alias's area and no 2
aliases with the same target. Outside an area, only the exact alias reaches aliases with the same target. Outside an area, only the exact alias reaches
it; a deeper alias specifier or a relative path into the area is a bypass. it; a deeper alias specifier or a relative path into the area is a bypass.
Inside an area, relative imports of siblings and subfolders are free. `../` Inside an area, relative imports of siblings and subfolders are free. A `../`
is banned in every file, owned or not import is banned in every file, owned or not
(`import/no-relative-parent-imports`). Files no alias owns need no `index.ts` (`import/no-relative-parent-imports`); runtime file URLs such as
and no alias, and import `./` siblings and subfolders freely. The one alias `new URL("../prompt.md", import.meta.url)` are paths, not imports, and stay.
is `#testing` (`./src/testing/index.ts`): every test imports it by alias, and Files no alias owns need no `index.ts` and no alias, and import `./` siblings
`tests/` reaches `src/` only through it. Local convention, stricter than the and subfolders freely. The one alias is `#testing` (`./src/testing/index.ts`):
general rule above: in this repo, aliases point only at a direct subfolder of tests that use its helpers import it by alias, and `tests/` imports `src/`
`src/` (`"#helpers": "./src/helpers/index.ts"`), and code outside `src/` uses only through it. Local convention, stricter than the general rule above: in
`./` relative imports. `scripts/` is flat: one file per this repo, aliases point only at a direct subfolder of `src/`
tool, no subfolders and no `index.ts`, imported directly by file path (`"#helpers": "./src/helpers/index.ts"`), and code outside `src/` uses `./`
relative imports. `scripts/` is flat: one file per tool, no subfolders and no `index.ts`, imported directly by file path
([.agents/memory/imports-aliases-barrels.md](.agents/memory/imports-aliases-barrels.md)). ([.agents/memory/imports-aliases-barrels.md](.agents/memory/imports-aliases-barrels.md)).
The only config files are `package.json`, `tsconfig.json`, and The only config files are `package.json`, `tsconfig.json`, and
+3 -1
View File
@@ -15,6 +15,8 @@
"noImplicitReturns": true, "noImplicitReturns": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true "noUnusedParameters": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false
} }
} }