Back to home@hunbs-1

dsh-codepect

dsh-codepect is a DSH plugin generating OpenAPI 3.0 from TS/JS. Features: visual docs, versioning, change detection, mock & auto-rescan. Zero-dep, offline, ensures code-doc sync for backend API delivery. dsh-codepect是DSH插件,扫描TS/JS生成OpenAPI3.0文档。支持可视化、多版本、变更检测、Mock及自动重扫。零依赖离线可用,确保代码文档一致,助后端交付API契约。

Stars
0
Language
JavaScript
Created
Aug 29, 2026
Updated
Aug 29, 2026

Introduction

dsh-codepect

dsh-codepect is an automatic API documentation generator built on the DSH dynamic Cordis plugin mechanism. It scans TypeScript/JavaScript sources in the workspace, parses JSDoc comments and NestJS/Express-style route definitions, and generates OpenAPI 3.0 specs (openapi.json / openapi.yaml). Zero external dependencies, works offline.

The name combines "code" and "spec": your source code is turned into an OpenAPI contract.

Quick start

git clone https://github.com/hunbs-1/dsh-codepect.git
cd dsh-codepect
node devtest/host-smoke.cjs   # zero-dependency offline smoke test (no npm install, no network)

The scanner is fully self-contained: cloning and running the smoke test needs no dependencies. To use it as a documentation generator you need a running DSH instance (the plugin is a DSH dynamic Cordis plugin). Load it once per DSH process as described in the usage section.

Detailed usage

Prerequisites: a running DSH instance (the plugin runs inside DSH, not as a standalone program) and your own TypeScript/JavaScript API source that uses JSDoc comments, NestJS decorators or Express routes.

1. Get the plugin

git clone https://github.com/hunbs-1/dsh-codepect.git

Only two files are actually needed by the plugin itself: src/host.js (Host half: scanning, schema inference, OpenAPI generation, mock server, git integration, HTTP routes) and src/client.js (Client half: the embedded "Settings -> API Docs" page and the run-card panel).

2. Add a config file

Place .dsh-api-docs.config.json (the dotless spelling is also accepted) in the folder where you use the plugin, and point include at your source directory. The scan root is the folder containing this config file; nothing outside that folder is ever scanned.

{
  "title": "My API",
  "version": "1.0.0",
  "description": "API docs for my service",
  "language": "zh",
  "include": ["src/**/*.ts"],
  "exclude": ["**/node_modules/**", "**/dist/**"]
}

See the configuration reference below for every field.

3. Load the plugin in a DSH session

Either:

  • ask your DSH assistant to read dsh-codepect/src/host.js and dsh-codepect/src/client.js and register them as a dynamic Cordis plugin (code.host / code.client), or
  • use the cordis_define mechanism manually with src/host.js as code.host and src/client.js as code.client, then run the package and approve if asked.

Note: dynamic plugins live in the DSH process memory only, so after restarting DSH you load the plugin again (the two files are the single source of truth, so this is quick and lossless).

4. Generate the docs

  • Call the model tool api_docs_generate (optionally with { "rescan": true }), or
  • let the plugin's startup scan run automatically when it loads, or
  • change a source file while watch.enabled is on to trigger an auto-rescan.

The scan writes openapi.json and openapi.yaml at the configured output paths and updates the version archive and changelog.

5. View the docs

  • Standalone page: http://localhost:3080/api-docs (search, endpoint expansion, schemas, changelog, copyable examples, mock links, version switch, language and theme toggles)
  • Embedded page: DSH Web UI, Settings -> API Docs
  • Run card: the plugin's status panel (endpoint/schema counts, breaking changes, git revision, output paths)
  • Contract files: http://localhost:3080/api-docs.json (JSON) and /api-docs.yaml (YAML), ready to hand to frontend teams or tooling.

6. Versioning and breaking-change detection

  1. Keep version in the config (e.g. "1.0.0").
  2. Each scan archives the full spec under that version (api-docs/versions.json).
  3. Change your source (add/remove an endpoint, make a parameter required, change a schema), then rescan.
  4. Open the changelog (/api-docs/changelog.json or the changelog toggle in the UI): new entries mark breaking changes (endpoint removed, required parameter added/removed, type changes, request/response structure changes) and non-breaking changes separately, with the git revision captured at scan time.
  5. Browse any archived version at /api-docs/version/{v} (HTML), .../{v}.json or .../{v}.yaml; the version dropdown in the docs pages switches between them.

7. Mock server

Enable mockEnabled (default true). Mock data is generated from each endpoint's 200 response schema and served at mockPrefix + endpoint path, method-aware:

GET http://localhost:3080/api-mock/api/users/123
POST http://localhost:3080/api-mock/api/users

8. Request examples

Each endpoint gets a cURL and a JavaScript Fetch example (path/query parameters filled with example values, example request body when present), stored in the x-examples extension and shown in the docs UI (the standalone page has a copy button).

9. Language switching

The UI language defaults to config.language ("zh" or "en"). Both the standalone page and the embedded page have an in-page language button; the standalone page remembers the choice in localStorage. Plugin-generated texts (response descriptions, changelog entries, validation and scan messages) follow the configured language at scan time.

10. Watch mode

Set watch.enabled to auto-rescan when a scanned source file changes:

"watch": { "enabled": true, "intervalSeconds": 5 }

11. The model tool

api_docs_generate supports two flags:

  • rescan: true — force a full rescan now
  • diagnoseBase: true — return the workspace root resolution diagnostics (which directory was chosen as scan root and why)

12. Move the plugin to another project

Copy src/host.js, src/client.js and a .dsh-api-docs.config.json whose include points at that project's sources. Because the scan root is the config file's folder, the plugin scans exactly that project and nothing else.

Configuration reference

Place .dsh-api-docs.config.json (dotless spelling also accepted) in the folder you use the plugin in:

{
  "title": "Demo User Service API",
  "version": "1.0.0",
  "description": "Sample API documentation generated by the dsh-codepect plugin",
  "language": "en",
  "include": ["demo-api/**/*.ts"],
  "exclude": ["**/node_modules/**", "**/.git/**", "**/dist/**"],
  "outputPath": "demo-api/openapi.json",
  "yamlOutputPath": "demo-api/openapi.yaml",
  "versionArchivePath": "api-docs/versions.json",
  "changelogPath": "api-docs/changelog.json",
  "mockEnabled": true,
  "mockPrefix": "/api-mock",
  "examplesEnabled": true,
  "watch": { "enabled": true, "intervalSeconds": 5 }
}
FieldDefaultDescription
titleAPI DocumentationSpec title, shown in the docs page header
version1.0.0Current spec version; archived per scan under versionArchivePath
descriptionemptySpec info description, shown under the title
languagezhUI language: zh or en (in-page toggle still available)
include["**/*.ts", "**/*.js"]Glob patterns of source files, relative to the config folder
excludenode_modules/.git/dist/build/coverageGlob patterns to skip
outputPathapi-docs/openapi.jsonJSON spec output path (relative to the config folder)
yamlOutputPathapi-docs/openapi.yamlYAML spec output path
versionArchivePathapi-docs/versions.jsonVersion archive file
changelogPathapi-docs/changelog.jsonChangelog file
mockEnabledtrueEnable the /api-mock/* mock server
mockPrefix/api-mockMock server URL prefix
examplesEnabledtrueGenerate cURL/Fetch examples into x-examples
watch{ "enabled": false, "intervalSeconds": 60 }Auto-rescan on source change

Scan scope

The scan root is the directory that contains the plugin config file; that directory is probed first and takes priority over any session or sticky directory, so the plugin only ever scans the folder where it is used. include / exclude patterns are resolved relative to that directory, and escaping patterns (absolute paths or ../) are rejected with a warning — nothing outside the config directory is ever scanned.

HTTP routes

RouteDescription
GET /api-docsStandalone docs page (version switch, changelog, copyable examples, mock links, language/theme toggles)
GET /api-docs.json / /api-docs.yamlCurrent OpenAPI spec (JSON / YAML)
GET /api-docs/versions.jsonVersion index
GET /api-docs/version/{v} / .../{v}.json / .../{v}.yamlHistorical version docs (page / JSON / YAML)
GET /api-docs/changelog.jsonChangelog
`GETPOST

Source annotation guide

The plugin reads documentation from your source comments — no separate doc files to maintain:

/** User management endpoints */
@Controller('api/users')
export class UserController {
  /**
   * Get user details
   * Returns the full user record for a user id
   */
  @Get(':id')
  async getUser(
    /** The user id */
    @Param('id') id: string
  ): Promise<User> { ... }
}
  • Summary: the first line of a JSDoc block before a controller/method/route.
  • Description: following lines of the same JSDoc block.
  • Parameters: @param {type} name - description (Express), @Param/@Query/@Headers decorators with inline JSDoc (NestJS).
  • Request body: @Body() parameter type (NestJS), @param body (Express).
  • Return type: the method's TypeScript return type / @returns {type}.
  • Schemas: interface / type / enum declarations with inline field comments.
  • Deprecation: @deprecated.

demo-api/ is a complete demo project showing all of the above.

Features

Core (MVP)

ModuleDescription
Source scanningRecursively discovers include-matched TS/JS files and parses JSDoc blocks (summary / description / @param / @returns / @deprecated / @tag)
Route discoveryNestJS: @Controller('base') + @Get/@Post/@Put/@Patch/@Delete/@All('path'); Express: app.get/post/...('path')
Parameter extractionNestJS: @Param('id') -> path, @Query('page') -> query, @Headers('x-t') -> header, @Body() -> requestBody; Express: :id path tokens + JSDoc @param
Schema inferencePrimitives, arrays, union enums, nested objects, $ref, optional fields, Promise/Partial/Readonly/Record unwrapping, Date -> date-time, cycle guard
Spec generationStandard OpenAPI 3.0: paths + parameters + requestBody + responses + components.schemas
Output filesopenapi.json (pretty JSON) + openapi.yaml (hand-rolled YAML serializer, round-trip validated)
Doc pages1. DSH Web UI "Settings -> API Docs" embedded page 2. Standalone page /api-docs 3. Run-card status panel
Model toolapi_docs_generate tool: { "rescan": true } forces a rescan

Extensions (V2)

FeatureDescription
Multi-version docsEach generation archives a version (api-docs/versions.json); routes /api-docs/version/{v} (HTML) / .json / .yaml; version dropdown in UI
Breaking-change detectionDiffs against the previous version and flags Breaking Changes (removed endpoint, required param added/removed, type changes, request/response structure changes) plus non-breaking changes (new endpoint, new optional param); changelog at api-docs/changelog.json, viewable in the UI
Mock serverGenerates mock data from the OpenAPI schema (enum/example values, nested objects, arrays, $ref resolution); prefix /api-mock + endpoint path, e.g. /api-mock/api/users/123, method-aware
Git integrationRecords the current commit per scan (git rev-parse --short HEAD, persisted with the changelog); built-in spec validation ($ref integrity, duplicate params, missing responses); optional watch mode auto-rescans on source changes
Request examplesGenerates cURL and JavaScript Fetch examples per endpoint (path/query filling, example request body), shown in x-examples and in the docs UI (copy button on the standalone page)
i18nUI language switchable between Chinese and English (default from config.language, in-page toggle button)

Project structure

dsh-codepect/
├── src/
│   ├── host.js        # Plugin Host source (scanner / schema inference / OpenAPI gen / mock / git)
│   └── client.js      # Plugin Client source (DSH Web UI embedded docs page + run card)
├── demo-api/src/      # Demo project (NestJS controller + DTOs + enum + Express routes)
├── devtest/           # Test scripts (offline smoke, HTTP E2E, browser interaction)
├── .dsh-api-docs.config.json  # Plugin config example
├── README.md          # This file
└── LICENSE            # MIT

demo-api/openapi.json, demo-api/openapi.yaml and api-docs/ are generated artifacts and are gitignored; run one scan after cloning to regenerate them.

Testing

node devtest/e2e-check.cjs        # 22 HTTP feature checks, expected 22/22
node devtest/host-smoke.cjs       # offline pipeline smoke test (scan + YAML round-trip)

Suggested manual flow for breaking-change detection:

  1. Note the current endpoint count (8 for the demo)
  2. Remove a @Get method or make a query param required in demo-api/src/user.controller.ts
  3. Wait ~5 seconds (watch mode auto-rescans), open the changelog
  4. Expect a new entry with a red "breaking changes" marker, endpoint count updated

Implementation notes

  • Path anchoring: the plugin config file's directory is the scan root and is probed first; only if no config file is found does it fall back to the initiating session/workspace cascade. Writes carry an explicit { mode: 'workspace-write', workspaceRoot: <workspace> } sandbox policy.
  • Lifecycle: all routes/tools/RPC/timers are disposed with the plugin fiber; a scanning lock prevents re-entrant scans.
  • Error isolation: a single-file parse failure is recorded in status.errors and does not abort the whole scan.
  • i18n: the standalone page and the embedded React page both translate via a zh->en string map (tr()), toggled by the in-page language button (standalone page remembers the choice in localStorage); the default comes from config.language.

Known limitations

  • Generic instantiations (e.g. Paginated<User>) and complex function types degrade to {}
  • Interface properties written as object literals with semicolons parse incompletely
  • With multiple @Controller classes in one file, the last base path wins
  • Change detection is structural (JSON Schema equality), not semantic compatibility analysis
  • Mock data is deterministic sample values; no randomization or custom scripts

License

MIT