Follow-up to #20, which was merged before this landed. bot-agents has no `package.json` `imports` aliases (`src/` is flat and everything imports relatively), so no code changes. This records the new rule in the docs: - `.agents/memory/imports-aliases-barrels.md`: aliases may target only a direct subfolder of `src/` (its `index.ts` or a `#x/*` pattern); nothing outside `src/`, not `src/` itself, not deeper folders; such code imports relatively. - `.agents/memory/tests-layout-vitest.md`: `tests/` reach the public entry through a relative import, not a `#plugin` alias. - `.agents/skills/migrate-deno-repo/SKILL.md` and `AGENTS.md`: same rule. `vp check`, `vp test`, and `damem doctor` pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #21 Reviewed-by: bot <noreply@capsulizers.com> Co-authored-by: Danny Kim <temeddix@gmail.com> Co-committed-by: Danny Kim <temeddix@gmail.com>
3.1 KiB
description
| description |
|---|
| Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included); imports name only .ts files or .js/.mts/.mjs 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
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.
tsconfig.json: no allowJs, no jsx, and exactly this strictness set (user
decision, 2026-10-18): strict (written out), noUncheckedIndexedAccess,
noPropertyAccessFromIndexSignature, noImplicitReturns, noUnusedLocals,
noUnusedParameters, noImplicitOverride, noFallthroughCasesInSwitch,
erasableSyntaxOnly, and allowUnreachableCode: false plus
allowUnusedLabels: false (user decision, 2026-10-18; on in the Deno setup),
plus the mechanical verbatimModuleSyntax, allowImportingTsExtensions, and
noEmit (packages also keep declaration and isolatedDeclarations).
exactOptionalPropertyTypes is off everywhere: write { key: maybeUndefined }
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)
project/no-asset-imports (in scripts/project-lint.ts; it was
no-non-ts-imports before 2026-10-16) fails:
- a relative, absolute,
#, or package-subpath specifier whose last segment has an extension other than.ts,.js,.mts, or.mjs:.css,.json,.svg,.jsx,.tsx, and every other asset; - any
?querysuffix (?raw,?url,?inline); - any import attributes (
with { type: "json" },with { type: "text" }).
.js, .mts, and .mjs are allowed (user decision, 2026-10-17) for package
subpaths such as lit/decorators.js or pdfjs-dist/legacy/build/pdf.mjs;
our own files are still .ts only. .jsx and .tsx stay banned. Bare
packages (lit, @types/json-schema, lodash.debounce), # aliases, and
node: builtins pass. @fortawesome/x/svgs/a.svg fails.
import "./theme.css"; // no
import data from "./scenes.json" with { type: "json" }; // no
import icon from "./lock.svg?raw"; // no
import { scenes } from "#data/scenes"; // yes: scenes.ts
What to do instead
- CSS: load it from HTML with
<link rel="stylesheet" href="...">. Never import CSS from TS, not even for Vite. (This also removes most of theimport/no-unassigned-importhits thesuspiciouscategory reports.) - JSON data: turn it into a
.tsmodule exporting a typed constant. - SVG: a
.tsmodule exporting the markup. package.jsonfields at runtime: neverimport pkg from "./package.json"and there is no#packagealias. Write the value out in.tsand add a test intests/that readspackage.jsonwithnode:fsand fails on drift (the plugin repos do this formeta.name/meta.version).- Reading a file is not importing it.
readFileSync+JSON.parseis fine in tooling and tests. - A tool's CLI file: prefer the package entry or spawning the package's
bin over importing
pkg/cli.js, which runs the CLI as a side effect.