npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vitest-plugin-ai-doc

v1.0.1

Published

A Vitest reporter plugin for generating AI-friendly documentation with semantic labels and examples

Downloads

89

Readme

Vitest Plugin AI Docs

一个 Vitest Reporter 插件,用于生成 AI 友好的代码注释和文档。通过分析测试用例和源码 AST,自动提取语义标签、示例代码,并支持多种输出格式。

功能特性

  • 测试用例分析:从测试代码中提取示例和语义信息
  • AST 源码分析:解析 JSDoc 注释,补充测试未覆盖的代码
  • AI 智能补充:支持接入大模型 API,自动补充缺失的描述、标签和示例
  • 多种输出格式:支持 AI-Context.json、.d.ts 注释注入、Markdown 文档
  • 状态标签:支持 @important@outdated@new@ignore 等标签
  • 增量分析:基于文件 hash 的缓存机制,提升性能
  • 覆盖率报告:统计测试覆盖和 AST 分析的覆盖情况
  • CLI 工具:提供命令行工具,支持交互式配置 AI 分析

安装

npm install vitest-plugin-ai-doc --save-dev

快速开始

// vitest.config.js
import { defineConfig } from 'vitest/config'
import DocReporter from 'vitest-plugin-ai-doc'

export default defineConfig({
  test: {
    reporters: [
      new DocReporter({
        outputFormat: 'ai-context',
        outputDir: './docs',
        enableAstAnalysis: true
      })
    ]
  }
})

运行测试后,将在 ./docs 目录生成 AI-Context.json 文件。

工作流程

触发机制

本插件实现了 Vitest 的 Reporter 接口,配置后 Vitest 运行测试时会自动调用:

import type { Reporter, Vitest, File } from 'vitest'

export class DocReporter implements Reporter {
  // 实现生命周期方法
}

触发方式:

# 运行测试时自动触发
vitest run

# 或者 watch 模式
vitest

# 或者通过 npm scripts
npm test

生命周期详解

┌────────────────────────────────────────────────────────────────────┐
│                     Vitest 测试运行流程                              │
├────────────────────────────────────────────────────────────────────┤
│                                                                    │
│  1. vitest 命令执行                                                 │
│       │                                                            │
│       ▼                                                            │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  onInit(ctx: Vitest)                                        │  │
│  │  ─────────────────────                                      │  │
│  │  • Vitest 初始化时调用                                        │  │
│  │  • 我们保存 vitest 上下文                                     │  │
│  │  • 初始化日志输出                                             │  │
│  └─────────────────────────────────────────────────────────────┘  │
│       │                                                            │
│       ▼                                                            │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  onPathsCollected(paths?: string[])                         │  │
│  │  ────────────────────────────────                           │  │
│  │  • Vitest 扫描完测试文件后调用                                 │  │
│  │  • paths 是所有测试文件路径                                    │  │
│  │  • 我们记录文件数量                                           │  │
│  └─────────────────────────────────────────────────────────────┘  │
│       │                                                            │
│       ▼                                                            │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  onCollected(files?: File[])                                │  │
│  │  ──────────────────────────                                 │  │
│  │  • Vitest 解析完测试文件后调用                                 │  │
│  │  • files 包含所有测试用例的 AST 信息                           │  │
│  │  • 【核心】我们在这里收集测试元数据:                           │  │
│  │    - 解析 import 语句                                        │  │
│  │    - 识别测试目标(函数/类/方法)                               │  │
│  │    - 提取语义标签                                             │  │
│  │    - 记录代码片段作为示例                                      │  │
│  └─────────────────────────────────────────────────────────────┘  │
│       │                                                            │
│       ▼                                                            │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  测试执行中...                                                │  │
│  │  • 每个测试用例运行                                           │  │
│  │  • 我们不干预测试执行                                          │  │
│  └─────────────────────────────────────────────────────────────┘  │
│       │                                                            │
│       ▼                                                            │
│  ┌─────────────────────────────────────────────────────────────┐  │
│  │  onFinished()                                               │  │
│  │  ──────────────                                             │  │
│  │  • 所有测试完成后调用                                          │  │
│  │  • 【核心】我们在这里生成文档:                                 │  │
│  │    1. 聚合测试元数据                                          │  │
│  │    2. 生成测试覆盖的注释                                       │  │
│  │    3. 运行 AST 分析(可选)                                    │  │
│  │    4. 合并覆盖率                                              │  │
│  │    5. 输出结果文件                                            │  │
│  └─────────────────────────────────────────────────────────────┘  │
│       │                                                            │
│       ▼                                                            │
│  输出文件生成完成                                                   │
│    - AI-Context.json                                              │
│    - .d.ts 注释                                                   │
│    - API.md                                                       │
│                                                                    │
└────────────────────────────────────────────────────────────────────┘

生命周期阶段总结

| 阶段 | 方法 | 我们做的事情 | |------|------|-------------| | 初始化 | onInit | 保存上下文,输出日志 | | 文件收集 | onPathsCollected | 记录文件数量 | | 测试解析 | onCollected | 收集测试元数据 | | 测试完成 | onFinished | 生成文档输出 |

内部处理流程

┌─────────────────────────────────────────────────────────────────┐
│                        onFinished 内部流程                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│       ┌─────────────────────────────────┐                       │
│       │     测试用例分析                  │                       │
│       │  - 聚合测试元数据                 │                       │
│       │  - 生成注释数据                   │                       │
│       └──────────────┬──────────────────┘                       │
│                      │                                          │
│       ┌──────────────▼──────────────────┐                       │
│       │     AST 源码分析(可选)           │                       │
│       │  - 扫描源码目录                   │                       │
│       │  - 解析 JSDoc 注释               │                       │
│       │  - 提取未覆盖的导出               │                       │
│       └──────────────┬──────────────────┘                       │
│                      │                                          │
│       ┌──────────────▼──────────────────┐                       │
│       │     覆盖率合并                    │                       │
│       │  - 合并测试 + AST 结果            │                       │
│       │  - 计算覆盖率统计                 │                       │
│       └──────────────┬──────────────────┘                       │
│                      │                                          │
│       ┌──────────────▼──────────────────┐                       │
│       │     输出生成                      │                       │
│       │  - AI-Context.json              │                       │
│       │  - .d.ts 注释注入               │                       │
│       │  - API.md 文档                  │                       │
│       └─────────────────────────────────┘                       │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

配置项

interface ReporterOptions {
  verbose?: boolean              // 是否输出详细日志,默认 false
  outputDir?: string             // 输出目录,默认 './docs'
  dtsPath?: string               // .d.ts 文件路径,用于注入注释
  semanticKeywords?: Record<string, string[]>  // 自定义语义关键词
  sourceDir?: string             // 源码目录,默认 './src'
  cachePath?: string             // 缓存文件路径
  enableAstAnalysis?: boolean    // 启用 AST 分析,默认 true
  outputFormat?: OutputFormat    // 输出格式,默认 'both'
  aiContextFileName?: string     // AI-Context 文件名,默认 'AI-Context.json'
  enableAI?: boolean             // 启用 AI 补充分析,默认 false
  aiConfig?: AIConfig            // AI 配置
}

interface AIConfig {
  enabled: boolean               // 是否启用
  apiUrl?: string                // API 地址
  apiKey?: string                // API 密钥
  modelName?: string             // 模型名称
  maxTokens?: number             // 最大 token 数,默认 500
  temperature?: number           // 温度参数,默认 0.3
}

type OutputFormat = 'ai-context' | 'dts' | 'both'

配置示例

只生成 AI-Context.json

new DocReporter({
  outputFormat: 'ai-context',
  outputDir: './docs',
  aiContextFileName: 'AI-Context.json'
})

只注入 .d.ts 注释

new DocReporter({
  outputFormat: 'dts',
  dtsPath: './dist/index.d.ts'
})

生成所有输出

new DocReporter({
  outputFormat: 'both',
  outputDir: './docs',
  dtsPath: './dist/index.d.ts',
  sourceDir: './src',
  enableAstAnalysis: true,
  verbose: true
})

自定义语义关键词

new DocReporter({
  semanticKeywords: {
    '请求': ['request', 'fetch', 'http', 'api'],
    '超时': ['timeout', 'expire', 'delay'],
    '重试': ['retry', 'repeat', 'again']
  }
})

AI 智能补充分析

当测试用例和 AST 分析都无法获取完整的文档信息时,可以启用 AI 智能补充功能,自动调用大模型 API 生成缺失的描述、语义标签和示例代码。

⚠️ 重要风险警告

┌─────────────────────────────────────────────────────────────────┐
│                    AI 推导分析风险说明                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ⚠️  AI 分析基于静态源码推断,非事实基准                          │
│                                                                 │
│  1. AI 可能产生错误判断、幻觉或编造信息                           │
│  2. 生成的文档内容需要人工审核确认                                │
│  3. 不建议直接用于生产环境文档                                    │
│  4. 分析对象为原始静态源码文件(.ts/.js),非 .d.ts 或生成文档     │
│                                                                 │
│  请谨慎使用,务必审核 AI 生成的内容!                             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

分析对象说明

AI 分析基于原始静态源码文件.ts.js.tsx.jsx),而非:

  • ❌ TypeScript 声明文件(.d.ts
  • ❌ 已生成的文档(AI-Context.json
  • ❌ 打包后的代码

这确保 AI 能够分析完整的代码实现,而非仅类型定义。

内置默认大模型

本插件内置了默认大模型,无需配置 API Key,开箱即用:

  • 模型: Qwen/Qwen3.5-35B-A3B
  • API: https://api-ai.gitcode.com/v1/chat/completions
  • 优势: 无需注册账号、无需配置密钥、直接使用

配置方式

方式一:在 vitest.config.js 中配置

import { defineConfig } from 'vitest/config'
import DocReporter from 'vitest-plugin-ai-doc'

export default defineConfig({
  test: {
    reporters: [
      new DocReporter({
        outputFormat: 'dts',
        outputDir: './docs',
        enableAstAnalysis: true,
        enableAI: true,
        aiConfig: {
          enabled: true
        }
      })
    ]
  }
})

方式二:使用 CLI 工具交互式配置

# 安装后直接运行
npx vitest-plugin-ai-doc

# 或全局安装后运行
npm install -g vitest-plugin-ai-doc
vitest-plugin-ai-doc

CLI 会依次提示输入:

  1. 最大 token 数(默认 500)
  2. 温度参数(默认 0.3)

AI 配置项

interface AIConfig {
  enabled: boolean           // 是否启用
  maxTokens?: number        // 最大 token 数,默认 500
  temperature?: number      // 温度参数,默认 0.3
}

AI 分析流程

┌─────────────────────────────────────────────────────────────────┐
│                        AI 分析流程                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  1. 测试用例分析 → 获取测试覆盖的导出信息                          │
│       │                                                         │
│       ▼                                                         │
│  2. AST 源码分析 → 获取未覆盖的导出信息                           │
│       │   (分析原始 .ts/.js 源码文件)                          │
│       │                                                         │
│       ▼                                                         │
│  3. 检测缺失信息                                                 │
│       │   - 缺少描述 (description)                               │
│       │   - 缺少语义标签 (tags)                                  │
│       │   - 缺少示例代码 (example)                               │
│       │                                                         │
│       ▼                                                         │
│  4. AI 补充分析(仅对缺失信息的导出)                             │
│       │   - 读取原始源码实现                                     │
│       │   - 构建分析 prompt(包含源码片段)                       │
│       │   - 调用大模型 API                                       │
│       │   - 解析返回结果                                         │
│       │   ⚠️ 结果需人工审核                                      │
│       │                                                         │
│       ▼                                                         │
│  5. 合并结果 → 生成完整文档                                      │
│       │   - 标记 AI 生成的内容                                   │
│       │   - 输出警告信息                                         │
│       │                                                         │
└─────────────────────────────────────────────────────────────────┘

AI 分析示例

假设有一个未覆盖的导出(原始源码):

export function formatDate(date: Date, format: string): string {
  const tokens: Record<string, () => string> = {
    'YYYY': () => date.getFullYear().toString(),
    'MM': () => (date.getMonth() + 1).toString().padStart(2, '0'),
    'DD': () => date.getDate().toString().padStart(2, '0')
  }
  return format.replace(/YYYY|MM|DD/g, match => tokens[match]())
}

AI 分析后会补充:

{
  "_aiGenerated": true,
  "name": "formatDate",
  "type": "function",
  "description": "格式化日期为指定格式的字符串",
  "tags": ["日期", "格式化", "工具"],
  "example": "formatDate(new Date(), 'YYYY-MM-DD')"
}

⚠️ 注意:_aiGenerated 字段标记该内容由 AI 生成,需人工审核确认。

JSDoc 标签支持

基础标签

| 标签 | 说明 | 示例 | |------|------|------| | @description | 描述 | @description HTTP 客户端 | | @semantic / @tags / @category | 语义标签 | @semantic HTTP, 请求, 网络 | | @example / @usage | 示例代码 | @example const client = new HttpClient() | | @param / @arg | 参数说明 | @param {string} url - 请求地址 | | @returns / @return | 返回值 | @returns {Promise} 响应数据 | | @throws / @exception | 异常 | @throws {Error} 网络错误 | | @deprecated | 废弃说明 | @deprecated 请使用 HttpClient | | @since | 版本 | @since 1.0.0 | | @see | 参见 | @see HttpClient |

状态标签

| 标签 | 状态值 | 说明 | |------|--------|------| | @ignore | ignore | 忽略,不生成注释 | | @important | important | 重要,AI 优先关注 | | @outdated | outdated | 过时,需指定替代方案 | | @new | new | 新版 API,替代旧版本 |

状态标签示例

/**
 * HTTP 客户端类
 * @important
 * @semantic HTTP, 网络, 请求
 * @example const client = new HttpClient({ timeout: 5000 })
 */
export class HttpClient { ... }

/**
 * 旧版请求方法
 * @outdated HttpClient.request
 */
export function request(url: string) { ... }

/**
 * 新版请求方法
 * @new[request]
 */
export class HttpClient {
  request(url: string) { ... }
}

/**
 * 内部方法
 * @ignore
 */
function _internal() { ... }

输出格式

💡 输出格式选择建议

┌─────────────────────────────────────────────────────────────────┐
│                    输出格式选择指南                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  🏆 强烈推荐: .d.ts 格式                                         │
│                                                                 │
│  原因:                                                          │
│  1. AI 编程助手(Cursor、Copilot、Claude 等)会 100% 读取此文件   │
│  2. .d.ts 包含完整的类型定义,AI 能更好地理解代码结构              │
│  3. 注释与类型定义紧密结合,上下文更清晰                           │
│  4. IDE 会自动加载,提供智能提示                                  │
│                                                                 │
│  ⚠️  AI-Context.json 的局限性:                                  │
│  - 需要额外配置 AI 工具读取此文件                                 │
│  - 不是所有 AI 工具都支持自定义上下文文件                          │
│  - 可能被忽略或优先级较低                                         │
│                                                                 │
│  📋 建议: 优先选择 .d.ts,或选择 both 同时生成两种格式             │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

格式对比

| 特性 | .d.ts | AI-Context.json | |------|-------|-----------------| | AI 读取率 | 100% | 需配置 | | 类型信息 | ✅ 完整 | ❌ 无 | | IDE 支持 | ✅ 原生 | ❌ 无 | | 结构化数据 | ❌ | ✅ | | 易于解析 | ❌ | ✅ |

AI-Context.json

{
  "exports": {
    "HttpClient": {
      "kind": "class",
      "desc": "HTTP 客户端类",
      "tags": ["HTTP", "网络", "请求"],
      "example": "const client = new HttpClient({ timeout: 5000 })",
      "status": "important",
      "props": {
        "timeout": {
          "desc": "超时时间(ms)",
          "tags": ["配置"],
          "example": "client.timeout = 10000",
          "status": "normal"
        }
      },
      "methods": {
        "request": {
          "desc": "发送请求",
          "tags": ["请求", "异步"],
          "example": "await client.request('/api/data')",
          "status": "normal"
        }
      }
    },
    "request": {
      "kind": "function",
      "desc": "旧版请求方法",
      "tags": [],
      "example": "",
      "status": "outdated",
      "replacement": "HttpClient.request"
    }
  }
}

.d.ts 注释

/** HTTP 客户端类 @tags HTTP, 网络, 请求 @example const client = new HttpClient({ timeout: 5000 }) @status important */
export class HttpClient {
  /** 发送请求 @tags 请求, 异步 @example await client.request('/api/data') */
  request(url: string): Promise<Response>
}

/** 旧版请求方法 @tags  @example  @status outdated @replacement HttpClient.request */
export function request(url: string): void

注释格式兼容性

| 注释类型 | 支持 | 示例 | |----------|------|------| | /** ... */ JSDoc | ✅ | /** HTTP 客户端 */ | | /* ... */ 块注释 | ✅ | /* 这是一个工具函数 */ | | // 单行注释 | ✅ | // 发送请求 | | 连续 // 注释 | ✅ | 多行 // 会合并 |

API

DocReporter

主 Reporter 类。

import { DocReporter } from 'vitest-plugin-ai-doc'

const reporter = new DocReporter({
  outputFormat: 'ai-context',
  outputDir: './docs'
})

其他导出

// 类型
export type { 
  ReporterOptions, 
  GeneratedComment, 
  TestMetadata, 
  TargetLevel,
  ExportStatus,
  OutputFormat,
  SourceExport,
  JSDocInfo,
  JSDocTag,
  AIConfig
} from 'vitest-plugin-ai-doc'

// 工具函数
export { TestCollector } from 'vitest-plugin-ai-doc'
export { CommentAggregator, formatComment } from 'vitest-plugin-ai-doc'
export { DtsInjector, findDtsFiles } from 'vitest-plugin-ai-doc'
export { SourceAnalyzer } from 'vitest-plugin-ai-doc'
export { CacheManager, computeFileHash } from 'vitest-plugin-ai-doc'
export { BundleAnalyzer } from 'vitest-plugin-ai-doc'
export { CoverageMerger } from 'vitest-plugin-ai-doc'
export { AIService, needsAIAnalysis, mergeAIResult } from 'vitest-plugin-ai-doc'
export { PreviewManager } from 'vitest-plugin-ai-doc'

CLI 命令

安装后可使用命令行工具:

vitest-plugin-ai-doc [命令]

命令

| 命令 | 说明 | |------|------| | analyze | 运行 AI 文档补充分析(默认命令) | | confirm | 确认预览文件中的内容并写入 | | status | 查看当前预览状态 | | reject | 拒绝所有 AI 生成内容并删除预览文件 | | help | 显示帮助信息 |

选项

| 选项 | 说明 | |------|------| | -h, --help | 显示帮助信息 | | --preview-only | 只生成预览文件,不进入交互模式 |

示例

# 运行 AI 分析(交互模式)
vitest-plugin-ai-doc

# 同上
vitest-plugin-ai-doc analyze

# 只生成预览文件
vitest-plugin-ai-doc analyze --preview-only

# 确认预览内容
vitest-plugin-ai-doc confirm

# 查看预览状态
vitest-plugin-ai-doc status

# 拒绝所有内容
vitest-plugin-ai-doc reject

# 显示帮助
vitest-plugin-ai-doc help

预览确认流程

AI 分析完成后,会进入预览确认模式:

┌─────────────────────────────────────────────────────────────────┐
│  📋 预览确认模式                                                 │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  请选择操作:                                                     │
│    [A] 接受全部 AI 生成内容                                      │
│    [S] 选择性确认(逐项审核)                                    │
│    [V] 查看预览文件后手动确认                                    │
│    [Q] 取消,不保存任何内容                                      │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

选择性确认示例

┌──────────────────────────────────────────────────────────────────┐
│ [1/3] formatDate                                                │
├──────────────────────────────────────────────────────────────────┤
│ 描述:                                                           │
│   原始: (空)                                                     │
│   AI生成: 格式化日期为指定格式的字符串  [AI]                      │
│                                                                 │
│ 标签:                                                           │
│   原始: (空)                                                     │
│   AI生成: 日期, 格式化, 工具  [AI]                               │
│                                                                 │
│ 示例:                                                           │
│   原始: (空)                                                     │
│   AI生成: formatDate(new Date(), 'YYYY-MM-DD')  [AI]            │
│                                                                 │
│ 状态: ⏳ 待确认                                                  │
└──────────────────────────────────────────────────────────────────┘

操作: [y] 接受  [n] 拒绝  [s] 跳过剩余  [q] 取消全部
请选择: 

预览文件结构

预览文件保存在 {outputDir}/ai-preview.json

{
  "_meta": {
    "warning": "AI 生成内容基于静态源码推断,可能存在错误,请人工审核后使用",
    "generatedAt": "2024-01-15T10:30:00Z",
    "modelName": "deepseek-chat"
  },
  "stats": {
    "total": 3,
    "newDescription": 3,
    "newTags": 2,
    "newExample": 1
  },
  "pending": [
    {
      "target": "formatDate",
      "type": "function",
      "original": { "description": "", "tags": [], "example": "" },
      "aiGenerated": {
        "description": "格式化日期为指定格式的字符串",
        "tags": ["日期", "格式化", "工具"],
        "example": "formatDate(new Date(), 'YYYY-MM-DD')"
      },
      "accepted": null
    }
  ]
}

开发

# 安装依赖
npm install

# 类型检查
npm run typecheck

# 构建
npm run build

# 开发模式(监听变化)
npm run dev

License

MIT