Imported from m-paternostro/emitnlog (
AGENTS.md). Install upstream withnpx skills add m-paternostro/emitnlog. Copyright stays with the author.
Guidelines for emitnlog
This repository implements emitnlog, a modern, type‑safe library for logging, event notifications, and observability in JavaScript/TypeScript.
When working on the project interactively with an agent, follow the guidelines below to keep changes clean, consistent, and easy to validate.
Repo Overview
- Zero dependencies, ESM‑first library with CJS bundles produced by
tsup. - Node dependencies are clearly identified in code
src/**/node/** - Targets node JavaScript runtimes offering
neutraloptions (seepackage.json). tscperforms type checking only (no emit). JS conversion is done bytsup.- Source lives under
src/; tests live undertests/and use Vitest; "smoke tests" live undertests-smokeand also use Vitest.
Useful Commands
| Command | Purpose |
|---|---|
npm run format |
Format the code. |
npm run format:check |
Check formatting without writing changes. |
npm run lint |
ESLint with auto‑fix where possible. |
npm run lint:check |
ESLint checks only (no fixes). |
npm run typecheck |
TypeScript checks (no code emit). |
npm run build |
Build ESM/CJS bundles via tsup. |
npm run test |
Run tests with Vitest. |
npm run test:coverage |
Run tests with coverage. |
npm run test:smoke |
Run smoke tests (without rebuilding). |
npm run test:smoke:build |
Build and run the smoke tests. |
npm run validate |
Typecheck → build → format check → lint check (no tests). |
Tip: During an active iteration, run npm run typecheck and npm run test frequently; before handoff, run npm run validate.
Coding Conventions
- TypeScript:
- Type safety is required; NEVER use
any. - Keep code clean, precise, and idiomatic TypeScript consistent with existing patterns.
- Minimize exports: only export what is truly needed.
- Prefer readonly structures:
- APIs should normally use readonly structure.
- Most arrays should be
readonly - Only the method/function that creates a readonly structure can modify it.
- When creating a readonly structure, use
import type { Writable } from 'type-fest'to temporarily convert it to writable - Code that uses a readonly structure (created by a different code) should treat it as a immutable, frozen JavaScript object.
- Prefer members (like
const foo = (...) =>) over functions (function foo(...) {...}) - Prefer
typeoverinterface, unless creating a type that requiresthis. - Do not implement code that uses
continue: choose a different approach to implement the design. - Prefer reusing utilities from
src/utils. If a utility complicates the code, flag it for discussion (it might need improvement or removal). - The default value for optional boolean properties should be
false.
- Type safety is required; NEVER use
- Style and design:
- Follow the project’s logging, testing, and naming conventions.
- Keep duplication very low (both within and cross files); adhere to established design patterns in adjacent code.
- Comments and documentation:
- Line comments are only for non‑obvious design decisions; avoid restating the method name or obvious behavior.
- Exported APIs should have JSDoc unless trivially self‑explanatory.
- Include parameters, return type details (e.g., read‑only arrays, undefined cases), errors thrown/rejected, and gotchas.
- Provide at least one example; if multiple are needed, order from simplest to most complex.
- Maintain consistency with existing documentation patterns and favor usefulness in editors/tooltips.
Tests
- On failures YOU MUST review real code in
srcfirst, then consider test issues. - Framework: Vitest with explicit imports from
vitest. - All "Coding Conventions" apply to the test code.
- Philosophy:
- Focus on validating behavior over implementation details; it’s OK to test internals when flow/timing is complex.
- Prefer real code; use Vitest's
vimocks only when absolutely necessary and keep them minimal. - Maintain high, useful coverage—do not add tests merely for coverage.
- Utilities: See
tests/test-kit.tsfor useful helpers.
Coverage
- The test coverage can be generated by running
npm run test:coverage - The test coverage HTML report files are under
./coverageand reflect thesrcdirectory structure - You should review the existing coverage and related code to plan to how increase coverage
- IMPORTANT: all tests must be meaningful and validate real usage and behavior! In other words, do not add tests that are trivial just to increase coverage.
Imports
- Separate type and value imports into distinct lines; use
typekeyword for type imports.- Example:
import type { Foo } from './foo.ts'andimport { bar } from './bar.ts'.
- Example:
- In
src/: use relative paths and include the.tsextension. - In
tests/: import relatively from eitherindex.tsorindex-node.tsinsrc. - There are lint rules that enforce import order and structure; keep imports tidy.
Runtime Targets
- Primary target is node runtimes. Neutral specifics can be used - they are bundled and exported appropriately.
- ESM and CJS bundles (including Node and neutral variants) are produced with
tsup. - When in doubt, favor neutral implementations and avoid Node‑only APIs in shared code paths.
Documentation
The user‑facing README.md and module documentation under src/<module>/README.md are the primary public documentation. As such it is important to always keep it consistent and accurate. Moreover:
- Always review the documentation whenever behavior, exports, or usage changes. If anything is outdated, update the documents within the same change set.
- For any new API or feature, ask if the documentation should be updated to mention it.
- Keep the
README.mdsimple and direct, adding usage details to the README of the module. - Describe "how to use", not internals.
- Include: what/why/when, quick start, API surface summary, at least one runnable example, and gotchas.
- Skip implementation details or information that is not widely applicable
- Prefer neutral runtime examples. If Node‑only, clearly label the section.
Process & Workflow
- Backwards compatibility can be broken only when it clearly simplifies and cleans the design.
- If anything is unclear, ask clarifying questions before coding.
- For non‑trivial changes:
- Present a concise plan (design, structure, package layout, API surface).
- Proceed to implementation after alignment.
- Keep changes scoped and surgical; do not over‑refactor or change filenames/styles unnecessarily.
- Update documentation as needed to keep it consistent and helpful.
Preparing For Sharing
The request to "prepare for sharing" (or similar) involves performing the following steps.
- First carefully review the changes. Stop and discuss if something is not clear, not properly designed, or not properly implemented.
- When the code is OK, write the tests, following the guidelines described on the Tests section.
- If the tests are not passing, review first the code, then tests. If needed, stop and discuss.
- After the tests:
- If applicable, write the JSDoc on the code, following the guidelines described on the Documentation section.
- If applicable, update the appropriate
src/*/README.md, following the guidelines described on the Documentation section.
- Read the
CHANGELOG.mdto understand the project's style and suggest an appropriate change and change type (patch,minor,major).
Note: NEVER COMMIT OR STAGE CHANGES without an explicit request.
Working With Agents
- Edits:
- Use targeted patches; keep diffs minimal and focused on the task at hand.
- Adhere to existing code style and documentation patterns; do not add external dependencies (project policy is zero dependencies) unless explicitly requested.
- Validation:
- For iteration: run
npm run typecheckandnpm run testas needed; optionally runnpm run test:smokewhen relevant. - Before handoff: run
npm run validateto ensure build and all tests pass. - If validation fails on format or lint: run
npm run formatand thennpm run lint(auto‑fixes some issues), make any remaining code changes as needed, and re‑runnpm run validate.
- For iteration: run
- Tests and builds should not introduce external side effects. Keep CI‑friendly by avoiding network, filesystem, or environment coupling unless already supported by the repo.
Where to Look
- Project README:
README.mdand linked files — overview, examples, and links to component documentation. - Bundling config:
tsup.config.ts— how ESM/CJS/node bundles are produced. - Package exports and entry points:
package.json→exports. - Utilities:
src/utils/— prefer reuse over re‑implementation. - Smoke test README:
tests-smoke/README.md
By following these guidelines, changes stay consistent, type‑safe, and easy to maintain while preserving the project’s runtime neutrality and zero‑dependency design.