ns-typescript
TypeScript overlay for ns-style projects. Use when editing or reviewing TS in this repo: tsconfig baseline, pnpm/Vitest/oxlint/oxfmt/native tsc commands, relative .ts imports, workspace subpath exports, and the exactOptionalPropertyTypes spread idiom. Repo-specific enforcement (test lanes, time seams, style guard) lives in the host repo's AGENTS.md.
- License 许可
- MIT
- 所属仓库
- nseng-ai/ns
- 最近更新
- 2026-10-02
- Stars
- ★ 2
- Forks
- 0
01 前言 Front Matter
- name
- ns-typescript
- references
- [ "references/internal-import-alternatives" ]
- description
- TypeScript overlay for ns-style projects. Use when editing or reviewing TS in this repo: tsconfig baseline, pnpm/Vitest/oxlint/oxfmt/native tsc commands, relative .ts imports, workspace subpath exports, and the exactOptionalPropertyTypes spread idiom. Repo-specific enforcement (test lanes, time seams, style guard) lives in the host repo's AGENTS.md.
02 资源文件 1
03 SKILL.md 正文
ns-typescript
Follow typescript-style for how TypeScript code reads. This skill is the project overlay:
toolchain, compiler baseline, import conventions, and construction idioms. It is written for reuse
in other projects that adopt the same stack; repo-specific enforcement — test-lane hard gates, the
time-seam package inventory, and the style-guard lane — is owned by the host repository's agent
instructions (in ns: ts/AGENTS.md).
Load this after typescript-style whenever the task touches TypeScript in this repository.
Toolchain baseline
- Package manager: pnpm 11 in
ts/. - Runtime: Node 24.12 or newer.
- Dependency governance: pnpm catalog plus Syncpack via
just ts-deps-check. - Default tests: Vitest 4 via
pnpm --dir ts run testorjust ts-test. - Development typecheck: stable native TypeScript 7 /
tsc, viapnpm --dir ts run checkorjust ts-check. - Formatting: oxfmt via
pnpm --dir ts run fmt:check/just ts-format-check; autofix withpnpm --dir ts run fmt/just ts-format-fix. - Linting: oxlint via
pnpm --dir ts run lint/just ts-lint; autofix withpnpm --dir ts run lint:fix/just ts-lint-fix. - Repo Markdown/TOML formatting remains dprint via
dprint check/just dprint-check; autofix withjust dprint-fix.
Compiler baseline
ts/tsconfig.json is intentionally strict and strip-only; treat it as the project contract. The
flags this skill gives behavioral guidance about:
exactOptionalPropertyTypes: truenoUncheckedIndexedAccess: trueerasableSyntaxOnly: truenoUnusedLocals: true/noUnusedParameters: true
Prefer small, complete changes that leave no dead scaffolding.
Import convention
- Intra-package imports are relative and include the explicit
.tssuffix:../failures.ts,./models.ts. - Cross-package imports use curated workspace package exports, for example
@nseng-ai/foundation/primitives,@nseng-ai/foundation/exec, and@nseng-ai/clinkr/raw. - Do not deep-import another package's
src/tree. - Bring project-owned types used in type signatures into scope with a top-level
import type. Do not embed import type expressions such asfunction load(): import("./module.ts").LoadResultortype Item = import("./module.ts").Itemin signatures. This does not prohibit runtime dynamic imports such asawait import("./module.ts")when lazy or optional loading is intentional. - Do not add root-only barrels that hide ownership. Prefer explicit subpath exports for public package surfaces.
The #-subpath import alternative is documented in
references/internal-import-alternatives.md; it is not the current standard and should not be migrated
opportunistically.
Optional properties under exactOptionalPropertyTypes
When conditionally including an optional property, use object spread to omit the key entirely when the
value is undefined:
const options = {
cwd: request.cwd,
...(request.env === undefined ? {} : { env: request.env }),
};
This is intentional. Do not copy rules from projects that ban this pattern unless they also share
ns exactOptionalPropertyTypes contract. Under this setting, { env: undefined } is not equivalent
to omitting env.
Preferred review fix: when a finding is caused by prop: maybeUndefined, rewrite construction to omit
the key with the conditional spread above instead of widening the field type just to make the object
literal type-check or silence review.
Use these type shapes deliberately:
foo?: Tmeans omission is the state; if the key is present, the value is a realT.foo: T | undefinedmeans the key is part of the shape, but the value may be unavailable.- Raw
foo?: T | undefinedis suspicious unless explicit present-keyundefinedis a meaningful contract. - Permanent explicit-undefined support should be expressed as
foo?: ExplicitUndefined<Reason, T>from@nseng-ai/foundation/primitives.
ExplicitUndefined<Reason, T> is for permanent API/input/compatibility/external contracts, such as env
maps, abort-signal seams, external schema mirrors, null-tolerant inputs, key-event payloads,
overload selectors, or deliberate DI seams. It is not a convenience escape hatch for object
construction sites.
Review guidance:
- For domain, context, result, command metadata, registry/catalog entry, and durable record objects,
prefer
foo?: Tplus omission on construction; question raw?: T | undefinedunless explicitundefinedis a meaningful present-key state. - If every consumer expects the property to exist and checks the value, prefer
foo: T | undefined. - Option/input/override/compatibility bags may legitimately accept explicit
undefined; permanent explicit-undefinedsupport usesExplicitUndefined<Reason, T>.
Encoded contracts over ambient bags
Per the typescript-style ambient-bags rule (core-rules.md):
in ns, ctx.extensions dynamic data remains available only for genuinely project-local or
extension-owned dynamic data. Do not use it to transport first-party SDK or ns-extension values
between packages; promote those values to typed SDK fields, extension package API parameters, or
gateway seams. For
example, prefer ctx.renderCapabilities: RenderCapabilities over
ctx.extensions?.["ns.clinkr.caps"].
Time seams
Production code does not hand-roll raw timers or wall-clock reads: inject clock and timer-scheduler
seams and drive them with manual test helpers in default tests. The host repo's AGENTS.md owns the
package-level seam inventory and the enforcement ban (in ns: ts/AGENTS.md "Time seams",
NS_TS_BAN_RAW_PRODUCTION_TIMERS).
Test lanes and shared-cache safety
Default tests are fake-driven. Integration tests retain actual external-system compatibility. Tests
whose subject genuinely requires ambient product/runtime module or process state belong in the isolated
lane. A separate sanity lane may invoke a concrete real adapter while mocking only low-level runtime or
vendor modules when code-unchanged adapter testing requires it; it must use isolate: true and must not
mock domain/workflow logic, semantic gateways, or the adapter subject. Isolation is not an
adapter-mocking technique, an integration synonym, or a general slow-test lane. First prefer injected
dependencies, gateways, manual time helpers, explicit env/cwd, or a narrow owned lifecycle seam. The
shared-lane hard bans, per-ban remediation, exact paths and commands, and CI split are owned by the host
repo's agent instructions and testing docs (in ns: ts/AGENTS.md and ts/TESTING.md).
Style-guard enforcement
Rule semantics and preferred fixes for the mechanical hard bans — as unknown as laundering,
first-party import aliases, empty interface extension, imported-binding local aliases — live in
typescript-style (core-rules.md, checklist.md). The host repo's AGENTS.md owns the enforced-id
inventory and the guard-lane command (in ns: ts/AGENTS.md "TypeScript style guard",
just ts-test-typescript-style-guard).
Run the TypeScript validation gates before declaring TypeScript work done:
just ts-deps-check
just ts-format-check
just ts-lint
just ts-check
just ts-test
just ts-test-integration
just ts-test-isolated
just ts-test-sanity
just ts-test-typescript-style-guard
04 同仓库更多 Skills
pr-make-accountable
Interview a PR author to establish shared understanding of intent and design decisions, then co-author the What / Why / Changes PR body with opt-in Requested reviewer focus.
typescript-style
Opinionated style guide for strict, portable TypeScript. Use when writing, designing, or reviewing TypeScript: type design, boundary validation, error handling, module architecture, and review discipline.
typescript-fake-driven-testing
TypeScript fake-driven testing architecture. Use when writing or reviewing TS code with external dependencies, gateway interfaces, real adapters, in-memory fakes, or CLI scenario tests.
ns-typescript-style-tripwire
Invoke the ns TypeScript style Tripwire against a supplied diff or current branch.
skill-management
Manage skills with `npx skills`: add, edit, remove, rename, update, or list skills (local or GitHub), and the nested `skills/<disposition>/.../<name>/` / flat `.agents/skills/` layout conventions.
review-thermonuclear-review
Invoke the Thermonuclear Review review against a supplied diff or current branch.