Imported from diplodoc-platform/cli (
AGENTS.md). Install upstream withnpx skills add diplodoc-platform/cli. Copyright stays with the author.
AGENTS.md
This file contains instructions for AI agents working with the @diplodoc/cli project.
Module Documentation
If a module contains a MODULE.md file, it is considered part of the module's context and should be consulted when working with that module. These files provide module-specific documentation, architecture decisions, and implementation details that complement the general project documentation.
Project Description
@diplodoc/cli is a CLI tool for building documentation from Markdown files with Yandex Flavored Markdown (YFM) support. The project allows you to build full-fledged documentation with navigation, internal transitions, and full YFM support.
Project Structure
Main Directories
src/— source code of the projectcommands/— CLI commands (build, publish, translate)core/— core logic (config, logger, markdown, toc, etc.)extensions/— extensions (openapi, generic-includer, local-search)steps/— DEPRECATED processing steps (do not add new code here)
build/— compiled code (generated during build)lib/— libraries (generated during build)tests/— project testse2e/— end-to-end testscases/— test casesfixtures/— test fixturesmocks/— test mocks
Packaged tests contract: tests/ and vitest.integration.config.ts are shipped in the npm package (see files in package.json). Downstream consumers run the integration suite from the packaged layout against their own binary via the DIPLODOC_BINARY_PATH env variable. Therefore specs under tests/ must not depend on anything outside tests/ and the built CLI - in particular not on scripts/ or src/, which are not shipped. A spec that needs them must be excluded from the package with a !-pattern in files (see tests/e2e/translate-eval.spec.ts).
CLI Commands
-
build — main command for building documentation
- Location:
src/commands/build/ - Subcommands and features are located in
src/commands/build/features/
- Location:
-
publish — publishing documentation
- Location:
src/commands/publish/
- Location:
-
translate — translating documentation
- Location:
src/commands/translate/
- Location:
-
content — render a single file to stdout/file (md or html content fragment)
- Location:
src/commands/content/ - Reuses the build
Run, itsnormalize/validateandbuildConfigDefaults(src/commands/build/config.ts),MarkdownCollector/SELF_CONTAINED(md) andgetBaseMdItPlugins(html). - Root/file resolution is the pure
resolveContentConfig(src/commands/content/config-resolve.ts): picks the project root from-c's directory or CWD (falling back to the file's own dir when it lives outside that root), setsconfig.input/outputto that root withoriginAsInput = true, stores the target asconfig.file, and populatesconfig.templateitself (build'sTemplatingfeature is not run). - stdout has two modes: default wraps the result in
CONTENT_START/CONTENT_ENDmarkers (so it can be fished out of the framework banners);--raw(config.raw) emits only the content. In raw modesrc/index.tsalso skips the version/timer/completion banners viaisRawContentRun(argv)(exported from the content command).-oalways writes raw (no markers), regardless of--raw. - Note:
resolveConfigtreatsENOTDIRlikeENOENTso a single-file--inputdoesn't break config discovery. - Tests: unit specs co-located in
src/commands/content/*.spec.ts(resolution, render md/html, emit stdout/-o, watch paths/rebuild,ContentWatcher) drive Sonar coverage; e2e lives intests/e2e/content.spec.ts(out-of-process, not counted by Sonar).
- Location:
Tech Stack
- Language: TypeScript
- Runtime: Node.js >= 22
- Testing: Vitest
- Build: esbuild
- Linting: ESLint (via
@diplodoc/lint)
Development Commands
# Build project
npm run build
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run E2E tests
npm run e2e
# Type checking
npm run typecheck
# Linting
npm run lint
npm run lint:fix
Working with Code
Imports
The project uses path aliases:
~/— points tosrc/- Example:
import {Program} from '~/core/program'
Architecture
-
Program — main class that manages command execution
- Located in
src/commands/index.ts - Uses decorator pattern (
@withConfigDefaults)
- Located in
-
Commands — CLI commands inherit from
BaseProgram- Each command can have its own options, hooks, and handlers
-
Features — functionality is grouped into features
- Examples:
output-html,search,watch, etc. - Each feature can have its own configuration and hooks
- Examples:
-
Hooks — hook system for extending functionality
- Uses
tapablelibrary
- Uses
Command Structure
Every command should follow a well-defined structure to ensure maintainability and separation of concerns.
Command Organization
- Main logic is concisely gathered in
index.ts - Implementation is divided into separate functionalities through
features/ - Features do not depend on each other
- A command can extract part of functionality into services, located in
services/directory - Services do not depend on each other
- If multiple features need to use the same computed data, such data (and logic for working with them) should be extracted into a service
- If multiple features use the same logic for processing their own data, such logic should likely be extracted into a common utility in the
utils/directory at the same level asfeatures/andservices/ - Utils may depend on each other
- Utils cannot depend on anything outside of
utils/
Command Files
index.ts— main entry point with concise core logichooks.ts— command hooks for external interaction are always described hereconfig.ts— command and feature configurations for CLI are described heretypes.ts— public types are always described here and exported from the module viaindex.ts- Only public types are exported from
types.ts - Common types used only at the module level should be described next to the entity that produces these types
- Only public types are exported from
Features
Features represent separate functionalities of a command:
- Located in
features/[feature-name]/directory - Features are independent and do not depend on each other
- Each feature can have its own:
index.ts— feature implementationconfig.ts— feature configurationhooks.ts— feature hooks (optional)
Services
Services contain shared business logic:
- Located in
services/[service-name]/directory - Services are independent and do not depend on each other
- Services are used when multiple features need shared computed data or logic
- Services can have:
index.ts— service implementationtypes.ts— service-specific typeshooks.ts— service hooks (optional)
Utils
Utility functions for shared logic:
- Located in
utils/directory at the same level asfeatures/andservices/ - Utils may depend on each other
- Utils cannot depend on anything outside of
utils/(no dependencies on features, services, or external modules) - Use utils when multiple features need the same data processing logic
Core Modules
The core/ directory contains logic common to all commands:
- Most often this logic is organized into services
- But base (abstract) classes are also possible, for example
BaseProgram - Used in external extensions in a fully bundled form, i.e., dependencies from
coreare fully bundled
Core Structure Rules
The same rules apply to core/ as to commands:
types.ts— only public types are exportedhooks.ts— hooks are always described here- Service concept applies — logic is organized into services
- Common types used only at the module level should be described next to the entity that produces these types
Code Conventions
-
File naming:
- Type files:
types.ts - Configuration:
config.ts - Main module file:
index.ts - Tests:
*.spec.tsor*.test.ts
- Type files:
-
Comments and documentation:
- All code comments must be in English
- All documentation files (ADR, AGENTS.md, README, etc.) must be in English
- JSDoc comments are used for exported functions/classes
-
Variables:
- Avoid single-letter variable names
- Don't use overly long variable names
Testing
-
Unit tests:
- Uses Vitest
- Tests are next to code or in
__tests__/ - Prefer using
vitest-whenfor mocking instead of standardmockImplementation
-
E2E tests:
- Located in
tests/e2e/ - Snapshots are used for output verification
- Located in
-
Test fixtures:
- Data preparation (Arrange) should be grouped into helper functions when the same setup is repeated across tests
Working with Playwright (if used)
- Prefer using
page.goto()instead ofpage.evaluate()for navigation - Avoid
page.locator(selector).first()— use more explicit and reliable selectors
Key Modules
Core Modules
core/config/— configuration managementcore/logger/— loggingcore/markdown/— Markdown processingcore/toc/— table of contents managementcore/vcs/— version control systems integrationcore/program/— base program and extension system
Build Command
Main build logic is located in:
src/commands/build/handler.ts— command handlersrc/commands/build/run.ts— command executionsrc/commands/build/features/— various build features
llms.txt OpenAPI companions
src/commands/build/features/llms/ collects entries from the resolved TOC recursively while
excluding hidden subtrees and external links. Preserve the parent TOC item name on collected
entries: for an OpenAPI include, the parent name labels the whole API section, while
leadingPage.name labels only the generated landing page. In llms.txt, emit the companion
*.openapi.json link with the parent name immediately before its matching landing-page link.
run.openapiCompanions provides the leadingPage -> companionPath mapping.
Extensions
Extensions integrate with CLI through hooks. There are two integration patterns based on initialization approach:
- Independent extensions — extensions that are not automatically initialized by CLI (can use
peerDependencyregardless of monorepo membership) - Auto-initialized extensions — extensions that CLI automatically imports and initializes on startup (require wrapper logic in
src/extensions/to avoid circular dependencies)
For details, see ADR-001: Dependent Extensions.
Auto-initialized extensions:
extensions/openapi/— OpenAPI support (wrapper for@diplodoc/openapi-extension)extensions/generic-includer/— generic includerextensions/local-search/— local search (wrapper for@diplodoc/search-extension)extensions/github-vcs/— GitHub integrationextensions/arcadia-vcs/— Arcadia integration
Configuration
The project supports configuration via:
.yfmfile (YAML)- Command-line arguments
- Environment variables
Main configuration files:
YFM_CONFIG_FILENAME— configuration file name (usually.yfm)
Additional Resources
README.md— main documentationCONTRIBUTING.md— contributor guideCHANGELOG.md— change historyadr/arch-quality.md— architectural quality principlesadr/ADR-001-dependent-extensions.md— architecture decision record for extension integration patterns
Module Documentation
MODULE.md— if present in a module directory, this file contains module-specific documentation and is part of the module's context for AI agents- Provides module architecture, implementation details, and usage patterns
- Should be consulted when working with that specific module
- Example locations:
src/core/MODULE.md,src/commands/build/MODULE.md, etc.
Common Tasks
Adding a New Command
- Create directory in
src/commands/[command-name]/ - Create command class inheriting from
BaseProgram - Register command in
src/commands/index.ts
Adding a New Feature to Build
- Create directory in
src/commands/build/features/[feature-name]/ - Implement feature with hooks
- Register feature in
src/commands/build/index.ts
Adding a New Extension
- Create directory in
src/extensions/[extension-name]/ - Implement extension
- Register in project configuration
Important Notes
- The project uses a monorepo (nx)
- All changes must pass linter and tests
- Types must be correct (checked via
npm run typecheck) - When working with VCS (GitHub/Arcadia), token configuration is required in
.envor.yfm - All comments and documentation files (ADR, AGENTS.md, README, etc.) must be written in English
- The
src/steps/directory is deprecated. Do not add new code there. If you need to fix existing code, carefully move it tocommands/build/features/ - When changing TypeScript types that have a corresponding schema in
schemas/, always update the schema to match, and vice versa