Code996 CLI 项目架构总结

November 30, 2025 · View on GitHub

📋 项目概述

Code996 CLI 是一个基于 TypeScript 开发的命令行工具,用于分析 Git 仓库中提交的时间分布,计算项目的"996指数"。该指数基于数学模型,帮助用户了解项目整体的工作时间模式,识别潜在的加班文化。

🏗️ 项目结构

src/
├── cli/                   # CLI界面层
│   ├── index.ts           # CLI主管理器 - 负责命令注册、参数解析和版本管理
│   └── commands/          # 命令实现
│       ├── analyze.ts     # 分析命令 - 核心执行逻辑、时间范围处理
│       ├── multi.ts       # 多仓库分析命令 - 扫描、选择、合并多个仓库数据、默认包含月度趋势分析
│       ├── report/        # 报表输出模块
│       │   ├── printers/  # 打印器模块
│       │   │   ├── core-printer.ts  # 核心结果打印
│       │   │   ├── time-distribution-printer.ts # 时间分布打印
│       │   │   ├── work-time-printer.ts # 工作时间推测打印
│       │   │   ├── overtime-printer.ts # 加班分析打印
│       │   │   ├── user-analysis-printer.ts # 团队工作模式分析打印(按等级分组统计人数)
│       │   │   └── index.ts # 统一导出
│       │   ├── index.ts   # 统一导出接口
│       │   ├── printer.ts # 报表打印统一入口(重新导出)
│       │   ├── analysis.ts # 智能分析与建议生成
│       │   ├── multi-comparison.ts # 多仓库对比报表
│       │   └── trend-printer.ts # 趋势分析报表
│       └── help.ts        # 帮助命令 - 显示使用说明
├── core/                  # 核心算法层
│   ├── calculator.ts      # 996 指数计算
│   ├── end-hour-detector.ts # 下班时间窗口识别
│   ├── work-time-analyzer.ts # 工作时间分析
│   ├── overtime-analyzer.ts  # 加班分析(工作日、周末、深夜)
│   ├── timezone-analyzer.ts  # 跨时区协作检测
│   └── project-classifier.ts # 项目类型识别(公司/开源)
├── git/                   # 数据采集层
│   ├── collectors/        # 采集器模块
│   │   ├── base-collector.ts       # 基础Git命令执行器(默认添加 --no-merges 忽略合并提交)
│   │   ├── time-collector.ts       # 时间分布数据采集
│   │   ├── commit-collector.ts     # 提交详情数据采集
│   │   ├── contributor-collector.ts # 参与者统计采集
│   │   ├── timezone-collector.ts   # 时区数据采集
│   │   └── index.ts                # 统一导出
│   ├── git-collector.ts   # Git数据采集主类 - 整合所有采集器
│   ├── git-data-merger.ts # 多仓库数据合并
│   └── git-parser.ts      # 数据解析和验证 - 数据清洗和996指数计算
├── types/                 # 类型定义
│   └── git-types.ts       # TypeScript类型 - 定义所有数据结构
├── utils/                 # 工具函数
│   ├── terminal.ts        # 终端工具 - 自适应表格和宽度检测
│   ├── formatter.ts       # 格式化工具 - 时间格式化、颜色选择
│   ├── time-aggregator.ts # 时间聚合工具 - 半小时/小时粒度转换
│   ├── timezone-filter.ts # 时区过滤工具 - 源级过滤时区数据
│   ├── workday-checker.ts # 节假日调休工具 - 中国法定节假日和调休判断
│   └── version.ts         # 版本工具 - 读取package.json版本
└── docs/…                 # 文档与示例

🎯 核心功能模块

1. CLI 界面层 (Command Line Interface)

  • 命令注册:使用 Commander.js 注册默认根命令、多仓库分析命令和帮助命令
  • 参数解析:支持年份快捷方式(-y)、日期范围(--since/--until)、全量分析(--all-time)、作者过滤(--self)、半小时粒度展示(--half-hour)、时区过滤(--timezone)、节假日调休(--cn)、多仓库扫描(--max)等选项
  • 用户交互:提供彩色输出、自适应表格和进度指示器
  • 多仓库支持multi 命令支持交互式仓库选择、批量数据采集、结果合并、作者过滤和默认的月度趋势分析
  • 报表输出:模块化的报表系统,支持核心结果、详细分析、时间分布(24小时/48半小时双模式)、加班分析、月度趋势分析(multi专属)、团队工作模式分析(--team)等多维度展示

2. 数据采集层 (Git Collector)

  • 数据收集: 收集仓库的所有提交数据(默认忽略合并提交)
  • Git命令执行: 执行 git log、git rev-list 等命令获取提交数据,采用分钟级时间格式(%H:%M)和 ISO 8601 格式(%ai
  • 数据验证: 验证 Git 仓库的有效性和数据完整性
  • 时间范围处理: 支持自定义开始和结束日期
  • 粒度聚合: 自动将分钟级数据聚合为48个半小时点,保留精细信息
  • 时区检测: 收集所有提交的时区偏移信息,用于跨时区协作检测

3. 核心算法层 (Calculator)

  • 996 指数计算:基于加班比例的数学模型,输出数值与描述
  • 工作时间识别:利用每日首提分位数与晚间拐点推断上下班区间,并在加班计算阶段只保留上班后的前 9 小时作为正常工时
  • 项目类型识别:通过工作时间规律性、周末活跃度、晚间活跃模式三个维度,自动识别项目是"公司项目"还是"开源项目"
  • 跨时区协作检测:通过时区离散度和"睡眠时段"提交比例分析,识别跨时区项目(阈值:非主导时区 >1%)
  • 节假日调休识别:当主要时区为 +0800 且占比超过 50% 时,自动启用中国节假日调休判断(工作日/周末会考虑法定节假日和调休),其他时区可通过 --cn 参数手动开启
  • 附加模块end-hour-detector.ts 封装下班时间窗口推断逻辑,timezone-analyzer.ts 封装跨时区检测逻辑,project-classifier.ts 封装项目类型识别逻辑,workday-checker.ts 封装节假日调休判断逻辑

4. 数据解析层 (Git Parser)

  • 数据清洗:解析 git log 输出,转换为结构化数据
  • 时间分析:按半小时(48点)、按星期统计提交分布
  • 粒度转换:算法处理时自动聚合为24小时,保证996指数计算稳定性
  • 工作时间转换:将原始统计结果交给核心算法识别上下班区间
  • 指数计算:组织数据并交给 calculator 输出最终结果

🔄 功能交互流程

单仓库分析流程 (默认根命令)

用户输入 → CLI 参数解析 → Git 数据采集 → 时间分布统计 → 工作时间推断 → 996 指数计算 → 结果输出
   ↓           ↓              ↓               ↓              ↓           ↓
终端命令   Commander.js    git log        byHour/byDay    分位数+拐点   表格展示

多仓库分析流程 (multi 命令)

用户输入 → 目录扫描 → 交互式选择 → 批量采集 → 数据合并 → 统一分析 → 对比报表
   ↓        ↓         ↓           ↓         ↓         ↓         ↓
multi命令  fs扫描    inquirer   串行git   按维度累加 分位数+拐点 多仓库对比

📊 数据流分析

输入数据

  • Git仓库路径: 默认当前目录,支持指定路径
  • 时间范围:
    • 默认:以上一次提交往前 365 天
    • 年份模式:-y 2025-y 2023-2025 快速指定年份范围
    • 精确模式:通过 --since/--until 指定精确日期
    • 全量模式:--all-time 分析整个仓库历史
  • 展示选项:
    • --half-hour: 以半小时粒度展示时间分布(默认按小时)
  • 多仓库配置(multi 命令):
    • 扫描范围:当前目录子目录或指定目录列表
    • 选择方式:交互式选择,支持批量选择和数量限制
    • 合并策略:按小时、按星期累加统计,合并每日首末提交时间

数据处理

  1. 原始数据采集:通过 git log 获取分钟级时间(%H:%M),聚合为48个半小时点
  2. 数据结构化:整理为半小时数组(48点)、星期统计、每日首提等结构
  3. 时间分析
    • 底层存储:48个半小时点(保留完整信息)
    • 算法处理:自动聚合为24小时(保证稳定性)
    • 用户展示:根据 --half-hour 参数选择粒度
  4. 工作时间推断:使用分位数与晚间拐点识别上下班区间(基于24小时聚合数据)
  5. 指数计算:基于加班比例的数学模型生成 996 指数

输出数据

  • 核心指标printer.ts):
    • 996指数: 0-300+ 的数值,表示加班程度
    • 描述等级: 根据指数范围提供中文描述
    • 加班比例: 百分比形式显示加班提交占比
    • 总提交数: 分析时段内的总提交统计
  • 详细分析analysis.ts):
    • 智能分析: 基于多维度指标的人性化分析文本
    • 综合建议: 根据加班强度给出行动建议(快跑/警惕/可接受/很好等)
  • 时间分布printer.ts):
    • 24小时提交分布图(默认)或48半小时粒度图(--half-hour
    • 工作日/周末分布图
    • 工作时间推测(上下班时间)
  • 加班分析printer.ts):
    • 工作日加班分布(周一至周五)
    • 周末加班分析(真正加班 vs 临时修复)
    • 深夜加班分析(晚间、深夜、凌晨时段)
  • 跨时区协作检测:
    • 时区离散度分析:识别非主导时区占比(阈值 >1%)
    • 睡眠时段分析:检测连续5小时最少提交窗口的提交占比
    • 智能警告:仅在未指定 --timezone 参数时显示
    • 时区过滤:支持通过 --timezone 参数指定单一时区进行分析
  • 团队工作模式分析:
    • 每日首末提交分布:展示团队成员的上下班时间分布
    • 工作强度分布:按996指数等级分组统计人数(较轻松/中等/较累/很累)
    • 团队健康度评估:综合评估团队整体工作强度和健康状况
  • 多仓库对比(multi 命令):
    • 汇总报表:合并所有仓库的统一分析结果
    • 对比表格:各仓库独立指标对比,按996指数降序排列
    • 统计摘要:成功分析仓库数、最严重/最轻松仓库信息
  • 月度趋势表(multi 命令自动包含,11列完整版):
    • 核心指标:996指数、平均工时、工作时间稳定性
    • 时间分布:平均开始提交时间、平均结束提交时间、最晚结束提交时间
    • 团队信息:提交数、参与人数、工作天数
    • 质量评估:数据质量标记(✓/⚠/✗)、置信度等级(✓✓/✓/✗)
    • 智能过滤:自动排除周末、短时工作(<4小时)、异常早结束(<15:00)
    • 凌晨处理:0-6点提交归入前一天,显示为"02:27+1"表示次日凌晨
    • 置信度算法:综合提交数和工作天数(高=提交≥100且天≥10,中=提交≥50或天≥5)
    • 进度提示:实时显示分析进度(如"正在分析... 3/12: 2019-03")

🔧 核心算法

996指数计算公式

// 计算加班比例
const overTimeRadio = ((workHourPl[1].count * 1.5 + workWeekPl[1].count * 2) / totalCommits) * 100

// 计算996指数
const index996 = overTimeRadio * 3

工作时间识别算法

  • 统计最近样本的每日首提,过滤清晨与周末噪音
  • 取 10%~20% 分位构建上班时间区间,并向下取半小时保证最大覆盖 1 小时
  • 对小时分布应用阈值与累积分位,识别晚间提交拐点作为下班区间
  • 若未检测到显著拐点,则退回“上班时间 + 9 小时”的标准工时兜底
  • 计算 996 指数时仅保留上班后的前 9 小时时段作为正常工时,超出的小时数全部记为加班

🛠️ 技术栈

核心技术

  • TypeScript 5.x: 提供完整的类型安全
  • Node.js: 运行时环境
  • Commander.js: CLI命令行界面框架
  • Chalk: 彩色终端输出
  • Ora: 进度指示器

数据处理

  • Git命令行工具: 数据采集
  • Cli-table3: 表格格式输出
  • 自适应终端宽度: 响应式表格布局

测试与构建

  • Jest: 单元测试框架
  • TypeScript Compiler: 代码编译
  • NPM Scripts: 构建和部署脚本

📈 扩展性设计

模块化架构

  • 清晰的分层设计:各层职责明确(CLI → 采集 → 解析 → 计算 → 输出)
  • 报表模块化:输出层独立为 report/ 模块,职责单一易维护
  • 工具函数复用:格式化工具集中在 utils/formatter.ts,便于复用
  • 模块间低耦合:模块间通过接口交互,便于独立开发和测试
  • 类型定义完整:支持良好的IDE体验和编译时检查

可扩展点

  • 新的输出格式: 在 report/ 模块中添加新的 Printer(如 JSON、HTML、PDF)
  • 新的分析维度: 在 analysis.ts 中扩展智能分析规则
  • 算法优化: 替换或增强工作时间识别算法
  • 数据源扩展: 支持其他版本控制系统(SVN、Mercurial等)
  • 国际化支持: 可以重新添加多语言支持

近期重构与新功能(v0.1.3+)

  • ✅ 将 754 行的 analyze.ts 拆分为多个职责清晰的模块(减少 73% 代码量)
  • ✅ 新增 report/ 模块:printer.ts(报表打印)+ analysis.ts(智能分析)
  • ✅ 新增 utils/formatter.ts:统一管理格式化工具函数
  • ✅ 新增 --year/-y 参数:支持快速按年份查询(如 -y 2025-y 2023-2025
  • ✅ 新增 multi 命令:支持多仓库扫描、交互式选择和数据合并分析
  • ✅ 优化数据合并策略:支持按小时、按星期累加统计,合并每日首末提交时间
  • ✅ 增强报表输出:支持多仓库对比表格、彩色标识和统计摘要
  • 项目类型识别(v0.1.9+) ✨:
    • 自动识别项目是"公司项目"、"开源项目"或"不确定"
    • 识别维度:工作时间规律性(核心)、周末活跃度、晚间活跃模式
    • 单仓库模式:检测到开源项目时显示醒目的黄色表格提示
    • 多仓库模式:显示项目类型对比表格,列举每个仓库的项目类型和置信度
    • 智能隐藏:开源项目自动隐藏"996指数"和"详细分析"等不适用模块
    • 提高样本要求:最低commit数从20提升到50,确保分析可靠性
  • ✅ 新增半小时粒度功能(v0.1.4+):
    • 数据采集:分钟级采集(%H:%M),自动聚合为48个半小时点
    • 算法适配:自动聚合为24小时用于工作时间识别和996指数计算
    • 双模式展示:默认按小时展示(24点),--half-hour 参数展示半小时粒度(48点)
    • 工具支持:新增 utils/time-aggregator.ts 提供粒度转换工具
  • ✅ 月度趋势分析增强(v0.1.6+):
    • 11列完整趋势表:新增平均开始/结束提交时间、参与人数、置信度
    • 分钟级精度:DailyLatestCommit 从小时改为分钟,平均时间精确到分钟
    • 凌晨提交处理:0-6点提交归入前一天,支持跨天显示(如"02:27+1")
    • 智能过滤:只统计正常工作日(排除周末、工作跨度<4h、15:00前结束、合并提交)
    • 置信度评估:综合提交数和工作天数,分为高(✓✓)/中(✓)/低(✗)三级
    • 进度提示:实时显示分析进度(如"3/12: 2019-03")
    • 跨时区协作检测:在月度趋势分析后自动检测并显示跨时区警告(如未使用 --timezone 参数)
  • ✅ 跨时区协作检测与过滤(v0.1.7+):
    • 时区数据采集:新增 timezone-collector.ts,采集所有提交的时区偏移信息(使用 ISO 8601 格式 %ai
    • 跨时区智能检测:新增 timezone-analyzer.ts,采用两维度检测算法:
      • 时区离散度分析:非主导时区占比 >1% 视为跨时区项目
      • 睡眠时段分析:连续5小时最少提交窗口的提交占比 >10% 视为跨时区项目
    • 时区过滤功能:新增 --timezone 参数,支持指定单一时区进行精准分析(例如 --timezone="+0800"
    • 智能警告显示:在月度趋势分析后显示跨时区警告,提供可用时区列表和建议(仅在未使用 --timezone 时显示)
    • 合并提交过滤base-collector.ts 默认添加 --no-merges 参数,自动排除合并提交的干扰
    • 输出顺序优化:跨时区警告放置在月度趋势分析之后、使用提示之前
  • ✅ 节假日调休智能识别(v0.2.0+):
    • 自动检测时区:系统自动检测项目的主要时区(提交数最多的时区)
    • 智能启用:当主要时区为 +0800 且占比超过 50% 时,自动启用中国节假日调休判断
    • 手动开启支持:新增 --cn 参数,非 +0800 时区项目也可手动强制开启(适用于海外华人团队)
    • 节假日调休判断:使用 holiday-calendar 包,工作日/周末判断会考虑中国法定节假日和调休工作日
    • 可配置启用/禁用WorkdayChecker 支持启用/禁用参数,未启用时回退到基础判断(周一到周五为工作日)
    • 全流程传递:所有分析模块(GitParserOvertimeAnalyzerWorkSpanCalculatorTrendAnalyzer)都正确传递并使用节假日调休配置
    • 用户提示:启用时在报告中显示蓝色提示 🇨🇳 已启用中国节假日调休判断 及启用原因(自动检测或用户强制)
    • 源级过滤:时区过滤功能从后处理改为源级过滤,在 Git 命令执行和数据解析时直接过滤时区,确保所有分析结果准确

架构优化(v0.1.5+)

  • ✅ 拆分 git-collector.ts(556行 → 4个专门采集器):

    • 降低复杂度60%:将单一大文件拆分为职责清晰的模块
    • base-collector.ts(155行):基础Git命令执行和通用功能
    • time-collector.ts(128行):时间分布数据采集
    • commit-collector.ts(181行):提交详情数据采集
    • contributor-collector.ts(71行):参与者统计采集
    • git-collector.ts(91行):主类整合所有采集器
  • ✅ 拆分 printer.ts(395行 → 4个专门打印器):

    • 降低文件大小75%:按报表类型细分打印功能
    • core-printer.ts(84行):核心结果打印
    • time-distribution-printer.ts(76行):时间分布打印
    • work-time-printer.ts(78行):工作时间推测打印
    • overtime-printer.ts(207行):加班分析打印
    • printer.ts(15行):统一导出入口(保持向后兼容)

优化收益

  • 🎯 职责单一:每个文件专注一个领域,易于理解和维护
  • 🧪 可测试性:独立模块便于单元测试
  • 🔧 可扩展性:添加新功能不影响现有代码
  • 📖 可读性:文件行数降低,代码结构更清晰
  • 👥 团队协作:多人开发时减少代码冲突

🎯 项目特点

优势

  • 类型安全: 完整的TypeScript类型定义
  • 性能优化: 批量数据处理和并行计算
  • 用户体验: 彩色输出和进度指示
  • 代码质量: 清晰的架构和完整的错误处理

创新点

  • 工作时间识别:基于分位数与晚间拐点的组合推断,兼顾上下班弹性与加班识别
  • 自适应表格输出:根据终端宽度自动调整列宽
  • 智能粒度转换:底层48点精细采集,算法24点稳定计算,展示层灵活切换

这个架构设计体现了现代TypeScript CLI工具的最佳实践,具有良好的可维护性和扩展性。