Skip to main content
Glama
README.md
# hag — 软著申请材料生成器

把本地代码项目整理成中国软件著作权登记(**R11**)所需的申请材料。既可双击 EXE 直接使用,也可作为 MCP Server 供 agent 调用。

> 状态:可用。572 项测试通过,已在真实 Django/Vue 项目上端到端验证。

## 它做什么

| 产出 | 说明 |
| --- | --- |
| 程序鉴别材料 | 源程序前 30 页 + 后 30 页,每页 50 行,注释与空行剔除,输出 PDF |
| 申请表信息 | 25 个字段值(填报辅助;申请表本体须在官网在线填报) |
| 提取清单 | 每个文件的来源、剔除方式、材料行数,可逐文件回溯 |
| 校验报告 | 逐项 PASS / WARN / FAIL,附带法规依据与处理建议 |
| 敏感信息脱敏 | 密钥、内网 IP、手机号、邮箱在写入 PDF 前替换为 `****` |
| 内容提示 | 他人公司名、具体日期、过早年份、代码量偏小 |\n| 图标表整行跳过 | 一行含 3 个以上字体无法显示的字符时整行跳过,避免满页 `<U+xxxx>` 占位符 |
| 环境检查 | 图形界面「环境检查」按钮,或 MCP `check_environment`:Python、PDF 库、字体、目录可写 |

## 选材与内容处理

除了「删空行和注释」,实务中还有一些不成文但常被审查关注的点,工具按以下方式处理:

| 事项 | 处理 | 性质 |
|---|---|---|
| 密钥 / 内网 IP / 手机号 / 邮箱 | **默认脱敏**为 `****`,保留代码结构 | 安全 |
| 他人公司名称 | 警告,列出文件与行号 | 实践 |
| 具体日期、过早年份 | 警告 | 实践 |
| 代码总量偏小(< 2000 行) | 警告,提示说明独创性 | 实践 |
| 首页是否为入口 / 完整体 | 优先把 `main.py`、`manage.py` 等入口文件排到首页 | 实践 |
| 首行为缩进代码、末行以分号结尾 | 警告,可能被看作截断 | 实践 |

脱敏不会删除代码:`API_KEY = "****"` 仍是一行合法的赋值语句,删掉反而会让代码不完整。

> 「页脚标注页码」这类说法与官方问答原文冲突(官方为「右上角标注页码」),本工具按官方执行。

## 它不做什么

- **不生成申请表本体**。官方为在线填报,签章页须本人打印签章,程序不得代生成或代签。
- **不代为提交**。
- **不做 R21**(转让合同登记)。
- **不编造代码**,也**不代写手册正文**——脚本只做结构校验与排版。
- **默认不修改你的代码**。见下文「中文行处理」。

## 安装

```bash
pip install -e ".[all]"
```

或按需安装可选依赖:`[pdf]`(fpdf2)、`[docx]`、`[images]`、`[test]`。

## 三种用法

### 双击 EXE(推荐给普通用户)

下载 [`hag-softcopyright.exe`](https://github.com/heyuan29171/software-copyright-generator-hag/releases/latest),双击即可使用。**只有一个窗口,不会弹出命令行**,也不需要安装 Python 或任何依赖。

1. 点「浏览…」选定项目目录
2. 填写软件全称、著作权人、开发完成日期
3. 切到「环境与功能」页,填写开发目的、主要功能等
4. 点「生成材料」

材料会输出到项目目录下的 `软件著作权申请资料/`,点「打开输出目录」即可查看。窗口内会显示生成的页数,或未通过校验的具体原因。

**同一个 exe 也能给 agent 用。** 双击时打开窗口;由 MCP 客户端启动时(带 `--mcp`)直接提供全部工具,不弹窗口:

```json
{
  "mcpServers": {
    "hag": {
      "command": "D:/路径/hag-softcopyright.exe",
      "args": ["--mcp"]
    }
  }
}
```

| 启动方式 | 行为 |
|---|---|
| 双击 / 无参数 | 打开图形界面 |
| `--mcp` | 以 stdio 提供 MCP 工具,供 agent 调用 |
| `--self-test` | 自检:真实生成一份材料并检查字体,用于验证打包结果 |

### 图形界面(开发者,无需打包)

```bash
pip install -e ".[all]"
hag-gui
```

与 EXE 完全相同,只是通过 Python 启动。

### MCP(供 agent 调用)

| 工具 | 用途 |
| --- | --- |
| `inspect_project` | 扫描项目,列出候选文件、各语言占比、每个被跳过文件的原因 |
| `estimate_material` | 预测前/后段页数,判断能否精确凑成 30+30,不渲染 |
| `generate_materials` | 生成 PDF、申请表信息、提取清单与校验报告 |
| `check_fields` | 单独校验申请表字段,不必等生成完 |
| `check_environment` | 检查本机能否正常生成材料 |
| `explain_rules` | 返回排版规则及其依据,便于回答"为什么 50 行" |

接入客户端:

```json
{
  "mcpServers": {
    "hag": { "command": "hag" }
  }
}
```

## 中文行处理

软著审核并不限制中文行数,但中文密集的页面读起来像文档而不像程序。默认策略是**换选源文件,不修改代码**:

- 每个文件统计含中文的行数占比,选材时优先取占比低的
- **前段和后段各自独立选材**,都从较干净的文件里取(早期版本只优化了前段,导致后 30 页平均 18.7 行中文)
- 若仍不够理想,可在界面上勾选「额外删除纯中文行」,或在 MCP 调用时传 `drop_cjk=true`

即使开启删除,也只删**不含任何代码的行**:

```
这是一段纯中文说明文字        → 删除
// 纯中文注释                 → 删除
label = "中文"                → 保留(有代码)
verbose_name="羊只状态"        → 保留(有代码)
```

删掉后者等于删代码,所以不删。校验报告会记录本次用了哪种方式。

## 关键约束(为什么这样设计)

这些不是偏好,是硬要求,见 [`docs/STANDARDS.md`](docs/STANDARDS.md):

- **每页 50 行**。正文区 756.85pt,50 行 × 15pt = 750pt,只余 6.85pt;51 行就会溢出。
- **字号 10.0pt、行距 15pt 固定、边距 上2/下1/左右2cm**。这四项必须一起定:把下边距改回 2cm,正文区只剩 728.5pt,就装不下 50 行了。
- **页数取渲染后回读值**。申请表"页数"与实际不符会触发不予登记。
- **页数是拼合后重新分页的结果**,不等于前段页数加后段页数——部分页会被合并。
- **每段不得超过 30 页**,且必须整页对齐(1500 行)。否则拼接后两页会合并成 59 页。
- **可以在文件内部切分**。法规只说"连续 30 页",未要求按文件切。一个 2836 行的 Vue 组件若不切分就无法使用。切点落在文件自身基准缩进处,且避开闭包符与续行。
- **折行在分页之前完成**,否则渲染期换行会悄悄多出一页。
- **不变量失败即中止**,不降级、不猜。

## 开发

```bash
pip install -e ".[all,test]"
python -m pytest
```

需要 Python 3.11+。

### 打包 EXE

```bash
pip install pyinstaller
python scripts/build_exe.py
```

产物:`dist/软著申请材料生成器.exe`,单文件、无控制台、约 53 MB。发布时改名为 `hag-softcopyright.exe`,避免中文文件名在各平台出错。

打包后必须验证功能而不只是能开窗:

```bash
# 三种模式都要过
dist/软著申请材料生成器.exe --self-test
```

`--self-test` 会真实生成一份 60 页 PDF 并检查字体。MCP 模式需另用客户端探测(见 `scripts/` 下的探针脚本说明)。

> 构建脚本把 `mcp` 显式列入 hidden-import 与 collect-submodules。早期版本曾把 `mcp` 放进 exclude 列表,导致 exe 无法供 agent 调用——这类问题只有真正跑一遍 MCP 握手才会暴露。

## 文档

| 文件 | 内容 |
| --- | --- |
| [`docs/SPEC.md`](docs/SPEC.md) | 实现规格:法规映射、流水线契约、MCP 接口、验收标准、官方来源核对 |
| [`docs/STANDARDS.md`](docs/STANDARDS.md) | 全部格式标准逐项列全:官方 / 各主流工具取值 / 最终选择 + 理由 |

## 已知限制

- 申请表**字段长度限制**标为【审】(行业实践)而非【官】,因官方在线表单需实名认证,未能直接核对。
- 部分语言(Shell/Ruby/SQL/YAML/TOML 等)只能剔除整行注释,行尾注释可能残留,会在报告中标为警告并要求人工复核。
- 手册正文需由使用者(或 agent)撰写,本工具不生成叙述性内容。

## 许可证

MIT