Metadata-Version: 2.4
Name: law-cn-cli
Version: 0.2.2
Summary: Unified CLI for official Chinese legal information sources
License-Expression: PolyForm-Noncommercial-1.0.0
Keywords: china-law,legal-research,regulations,cli
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Legal Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Text Processing :: Indexing
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: beautifulsoup4>=4.12
Requires-Dist: cryptography>=42.0
Requires-Dist: httpx[socks]>=0.27
Requires-Dist: PyYAML>=6.0
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# law-cn-cli

`law-cn-cli` 将 20 个中国境内官方法律、法规、规章、政策和交易规则来源统一为一套命令语法。发行包名称是 `law-cn-cli`，安装后的命令为 `law-cn`：

```text
law-cn search <source-code> <keyword> [统一检索选项]
law-cn search auto <keyword> [--sources code,...] [--view grouped|raw]
law-cn search all <keyword> [--view grouped|raw]
law-cn info <source-code> <document-id-or-official-url>
law-cn article npc <document-id> <条号>
law-cn preview npc <document-id>
law-cn article-search npc <keyword> [--max-laws N]
law-cn download <source-code> <document-id> --format docx|pdf
law-cn skill install|update|status|path|uninstall
```

这是一个从各官网当前实际请求重新验证、独立实现的项目。项目会明确区分公开开发 API、官网前端内部 JSON 接口和 HTML 检索端点；“能被官网调用”不等于“有公开开发文档或稳定性承诺”。

20 个来源均实现了 `info`。国家法律法规数据库使用结构化详情接口；其他来源按各站当前详情接口或官方详情 HTML 解析。URL 型输入会校验来源官方域名，不允许把任意 URL 当成请求目标。

`law-cn article npc` 会调用国家法律法规数据库的官方 DOCX 下载接口，解析后输出完整条文。可用条号（如 `第二十八条`、`第28条`、`28`）或 `--grep` 检索单篇法规内的所有命中条文。短期签名 URL 不会写入输出或缓存；原始官方文件默认进入本地持久化缓存，避免后续条文检索重复下载。

## 安装

需要 Python 3.11 或更高版本。

推荐通过 `uv` 安装为隔离的全局命令：

```bash
uv tool install law-cn-cli
law-cn --version
law-cn sources
```

命令自身带完整帮助，可逐层查看：

```bash
law-cn --help
law-cn search --help
law-cn article-search --help
law-cn skill --help
```

升级或卸载：

```bash
uv tool upgrade law-cn-cli
uv tool uninstall law-cn-cli
```

也可以使用 `pip`：

```bash
python3 -m pip install law-cn-cli
law-cn sources
```

从源码参与开发时，在项目根目录运行：

```bash
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/law-cn --version
```

## 基本用法

```bash
# 查看全部来源
law-cn sources

# 查看单个来源原生支持的检索能力
law-cn capabilities npc

# 查看该来源经官网请求核验过的额外检索字段及请求字段名
law-cn parameters tax --format json

# 国家法律法规数据库：标题检索
law-cn search npc '劳动合同法' --format json

# 国家法律法规数据库：读取官方详情
law-cn info npc 2c909fdd678bf17901678bf74d7106b3

# 国家法律法规数据库：提取完整条文
law-cn article npc 2c909fdd678bf17901678bf74d7106b3 '第二十八条'
law-cn article npc 2c909fdd678bf17901678bf74d7106b3 --grep '劳动报酬'

# 返回完整目录、总条数和全部条号（不抽样）
law-cn preview npc 2c909fdd678bf17901678bf74d7106b3

# 跨法规条文检索；默认处理全部候选法规
law-cn article-search npc '民法典第三百一十一条'

# 只有用户明确希望截断时才设置候选法规数量
law-cn article-search npc '民法典第三百一十一条' --max-laws 20

# 显式下载；格式参数决定官网实际请求的文件格式
law-cn download npc 2c909fdd678bf17901678bf74d7106b3 \
  --format pdf \
  --output './劳动合同法.pdf'

# 检查持久化文件缓存
law-cn cache stats

# 国家法律法规数据库：正文检索具体条文引用
law-cn search npc '民法典第三百一十一条' \
  --scope content \
  --format jsonl

# 国家规章库
law-cn search gov-rules '管理办法' --scope title --sort newest

# 上交所规则
law-cn search sse '信息披露' --scope all

# 金融监管总局，完整写入可审计目录
law-cn search nfra '善意取得' \
  --scope all \
  --output './runs/nfra-good-faith'

# 国家法律法规数据库：搜索建议
law-cn suggest npc '劳动合同'

# 国家法律法规数据库：查看单篇文件中的关键词命中位置
law-cn highlight npc 2c909fdd678bf17901678bf74d7106b3 '劳动报酬'

# 国家法律法规数据库：读取关联资料
law-cn related npc 2c909fdd678bf17901678bf74d7106b3 '劳动合同'

# 国家法律法规数据库：批量下载；所有 ID 都会处理，失败项单独列出
law-cn batch-download npc \
  2c909fdd678bf17901678bf74d7106b3 \
  ANOTHER_DOCUMENT_ID \
  --format docx \
  --output-dir './downloads'

# 网信办高级检索：连续关键词按官网语义作顺序敏感的短语检索
law-cn search cac '生成式人工智能服务管理暂行办法' \
  --scope title \
  --match exact \
  --source-param required_phrase=生成式人工智能 \
  --source-param exclude_terms=征求意见 \
  --source-param directory=网信政务

# 网信办法规栏目 JSON 接口：枚举该分类的全部记录并保存审计清单
law-cn catalog cac \
  --category 部门规章 \
  --format jsonl \
  --output './cac-department-rules'
```

如果没有指定 `--scope`，CLI 会为该来源自动选择其支持的优先范围：`title`、`all`、`content`。显式指定了来源不支持的筛选项时，命令会报错，不会悄悄忽略条件。

`suggest`、`highlight`、`related`、`article`、`preview`、`article-search` 和 `batch-download` 当前只支持 `npc`。`catalog` 当前支持 `cac`。批量下载会处理命令中给出的全部 ID；任一项目失败时仍保留其他成功结果，并以非零退出码和 `failures` 字段明确报告。

## 统一检索选项

```text
--scope title|content|all
--match fuzzy|exact
--status VALUE                  可重复
--document-type VALUE           可重复
--authority VALUE               可重复
--publish-from YYYY-MM-DD
--publish-to YYYY-MM-DD
--effective-from YYYY-MM-DD
--effective-to YYYY-MM-DD
--sort relevance|newest|oldest
--limit N
--source-param KEY=VALUE        单站来源特有字段
--source-param SOURCE:KEY=VALUE auto/all 中按来源限定的特有字段
--format table|json|jsonl
--output DIRECTORY
```

不同官网原生能力不同。先运行 `law-cn capabilities <source>`，即可知道某个选项是 `native`、`emulated` 还是不支持。

运行 `law-cn parameters <source>` 可查看该站的高级字段、对应官网请求字段、类型、可重复性和已知枚举。单站检索用 `--source-param KEY=VALUE`；`auto/all` 用 `--source-param SOURCE:KEY=VALUE`，避免把一个网站的字段错误广播到其他网站。未知字段、错误枚举和不允许重复的字段会直接报错。

### 网信办接口说明

网信办适配器使用两条不同的官网数据路径，避免把栏目枚举错误包装成全文检索：

- `law-cn search cac KEYWORD` 调用高级检索 JSP。支持 `title`、`content`、`all`，公布日期区间，相关度/最新/最早排序，以及 `required_phrase`、`exclude_terms`、`directory`。`directory` 只接受官网高级检索表单实际可用的顶层栏目：`全站`、`热点专题`、`要闻`、`网信政务`、`互动服务`。
- `law-cn catalog cac --category CATEGORY` 调用 `/cms/JsonList`，支持 `全部`、`法律`、`行政法规`、`部门规章`、`司法解释`、`规范性文件`、`政策文件`、`政策解读`。该命令返回目录元数据（标题、摘要、日期和官方详情页链接），不把摘要冒充法规全文。

网信办高级检索中，连续关键词具有顺序敏感的短语效果；`--match exact` 表示这一官网“完整连续短语”语义，不表示标题必须与关键词逐字完全相等。中文逗号分隔的主关键词按官网行为表示任一短语命中。官网表单虽存在 `inpro` 字段，但在线验证中该字段未产生可靠结果，因此 CLI 不将它宣称为可用参数。法规深层分类代码也不能由高级检索接口可靠过滤，所以由 `catalog` 命令通过 JSON 栏目接口提供。

`catalog` 的内部每页数量只用于请求分批，不是输出上限。命令根据官网 `totalRec` 持续翻页，默认保留全部原始记录，不抽样、不去重；输出清单中的 `pages_fetched`、`records_written`、`total_reported` 和 `truncated` 可用于核验完整性。

维护仓库中的 20 站请求审计还记录了 CLI 自动维护、但不允许用户覆写的分页、回调、站点范围和动态鉴权字段。该维护档案不属于 wheel/sdist 的公开运行时内容；公开用户应以 `law-cn capabilities` 和 `law-cn parameters` 的实际输出为准。

`--limit` 没有默认值。未明确传入时，适配器会按照官网返回的总数或总页数继续翻页，不会为了方便静默截断。传入 `--limit` 是用户明确要求截断；输出清单会记录 `explicit_limit` 和 `truncated`。

## 跨来源规则路由

`law-cn search auto KEYWORD` 使用可审计的确定性分层路由，而不是在 CLI 内调用大模型。默认双核心是国家法律法规数据库
`npc` 与国家规章库 `gov-rules`；规章库默认限定为“部门规章”。关键词出现明确
省级地域或“地方政府规章”时，规章库切换为“地方政府规章”。随后按司法、检察、
政策、网信、金融、市场监管、税务、生态环境、交易所、条约等主题增加对应专业
来源。

```bash
# 查看路由计划，不发出搜索请求
law-cn search auto '上海市生成式人工智能管理规定' --explain-routing

# 执行规则路由并按同一文件聚类展示
law-cn search auto '生成式人工智能服务管理暂行办法' --format json

# 显式限定参与的来源
law-cn search auto '量刑建议' --sources npc,gov-rules,spp

# 在跨来源检索中覆盖某一站的原生字段
law-cn search auto '北京市人工智能' \
  --source-param gov-rules:category=地方政府规章

# 请求全部 20 个来源
law-cn search all '善意取得' --view raw --format jsonl
```

实际网络请求会按来源并发执行，结果仍按路由计划中的来源顺序稳定汇总。一个来源
失败不会阻塞其他来源。

`auto/all` 的默认 `grouped` 视图只用于减少视觉重复。每个聚类的 `records`
字段仍保留全部来源记录；`--view raw` 直接输出所有原始记录。标准化标题一致的
记录归入同一文件族；发布日期、文号或发布机关存在冲突时，在族内拆为 `versions`
并标记 `version_conflict=true`，不会把冲突版本当成同一份文本。

跨源相关度分数不直接相加。聚类选择展示记录时按文件类型优先规范文本或制定机关
官网，但不会删除其他官方来源。输出 `manifest.json` 记录所选来源、路由理由、
逐源检索清单、跳过原因、来源失败、原始记录数和聚类数。一个来源失败时保留其他
来源结果并以非零退出码明确报告，不静默吞掉失败。

`auto/all` 没有默认结果上限；`--limit N` 在联邦检索中明确表示“每个来源最多
N 条”，并写入 `explicit_limit_per_source`。来源特有参数必须写成
`SOURCE:KEY=VALUE`；未限定来源的写法会直接报错。

## 安装 Agent Skill

包内自带 `law-cn-search` Skill，用于让支持 Skills 的 Agent 在运行 CLI 前进行实时
查询规划、全网候选发现、官方回查、效力核验和证据分级。它不会自动写入用户目录；
安装必须由用户显式执行：

```bash
law-cn skill install --agent auto
law-cn skill status --agent auto
law-cn skill path --agent auto
```

`auto` 会优先识别 Codex 的 Skills 目录，其次识别通用 `~/.agents/skills`。也可以
用 `--agent codex|agents` 或 `--target-root PATH` 明确指定位置。升级包后运行：

```bash
law-cn skill update --agent auto
```

安装器通过文件哈希记录自身写入的文件。若用户修改了 Skill，更新和卸载会拒绝
覆盖或删除；只有显式传入 `--force` 才会处理修改过的已登记文件。卸载命令为
`law-cn skill uninstall`。

Skill 由一个入口 `SKILL.md`、Agent 元数据和六份按需读取的 reference 组成：
研究流程、实时查询规划、来源路由、CLI 命令、证据核验和输出契约。宽泛概念不会
依赖无法穷尽的本地同义词表；Agent 实时生成候选查询，并保留用户原始检索词。
网页搜索或 AI 记忆只能产生候选，最终法源仍须回到 CLI 或制定机关官网核验。

## 原文文件缓存

NPC 的 `article`、`preview`、`article-search` 和 `download` 默认复用持久化的官方 DOCX/PDF：

- 默认目录：`~/.cache/law_cn/documents`
- 默认有效期：7 天，命令帮助和缓存元数据均明确记录为 `604800` 秒
- 缓存键：来源 + 官方 document ID + 文件格式
- 缓存内容：原始公开文件及哈希、大小、缓存时间；不保存短期签名 URL
- `--refresh`：强制重新获取并更新缓存
- `--no-cache`：本次既不读取也不写入缓存
- `--cache-dir PATH`、`--cache-max-age-days N`：显式调整位置和有效期
- `law-cn cache stats`：查看条目、大小、路径和有效期
- `law-cn cache clear`：仅清理由 law-cn 标记并拥有的缓存目录

`article`、`preview` 输出 `file_cache_hit`；`article-search` 输出 `cache_hits` 和 `files_downloaded`；显式下载输出 `cache_hit`，因此是否发生重复下载可以直接审计。

## 输出与审计

### 检索输出

每条记录统一包含：

- `source`、`source_name`、`source_document_id`
- `title`、`official_url`
- `document_type`、`issuing_authority`、`document_number`
- `publish_date`、`effective_date`
- `validity_status`、`validity_explicit`
- `summary`、`content`、`download_urls`
- `retrieved_at`、`source_rank`
- `raw_metadata`

### 详情输出（`law-cn info`）

结构化 JSON，至少包含：

- `official_url`、`title`、`source_document_id`
- `body`、`body_availability`、`body_note`、`content_outline`
- `document_type`、`issuing_authority`、`publish_date`、`effective_date`、`validity_status`
- `attachments`（官方 `ossFile` 路径及不含签名的 `download_endpoint` 模板）
- `retrieved_at`、`raw_metadata`

当详情接口只返回目录/条文标题而无正文时，`body_availability` 为 `outline_only`；当接口未返回正文结构、仅列出可下载附件时为 `download_only`。CLI 不会下载或解析附件内容。

### 条文输出（`law-cn article npc`）

`article` 使用官方 DOCX 下载接口取得原文并解析。输出包含官方详情页、法规标题、检索条件、完整命中条文和 `file_cache_hit`。原始文件按上文规则进入持久化缓存，但不输出带签名的临时下载 URL。

`article-search` 的每条命中都携带所属法规 ID、标题、官方详情页、条号和条文文本；任何下载或解析失败都会进入 `failures`，不会静默丢弃。未传 `--max-laws` 时处理全部候选法规；显式设置后，输出会记录候选总数、本批偏移、明确请求的法规数、实际解析数和下一批偏移。

使用 `--output` 时生成：

```text
DIRECTORY/
├── records.jsonl
└── manifest.json
```

`manifest.json` 记录抓取页数、写入条数、官网报告总数、显式限制以及是否截断。已有同名文件时命令拒绝覆盖。

## 来源与能力

| code | 官方来源 | 传输方式 | 检索范围 | 其他原生筛选 |
|---|---|---|---|---|
| `npc` | 国家法律法规数据库 | JSON | title, content | exact, status, 类型, 制定机关 |
| `gov-rules` | 国家规章库 | JSON + 官网动态鉴权 | title, all | newest |
| `gov-policy` | 国务院政策文件库 | JSON | title, content, all | newest；文件库、分类、标签、文号、年份、部门、日期 |
| `moj` | 司法部行政法规库 | HTML | title, content | status, 公布/施行日期, newest/oldest |
| `court` | 最高人民法院 | HTML | all | — |
| `spp` | 最高人民检察院法律法规库 | 官方静态 HTML 栏目 | title | exact, 公布日期, newest/oldest；宪法、法律、司法解释、规范文件 |
| `party` | 党内法规库 | JSONP | title, content | newest |
| `treaty` | 外交部条约数据库 | HTML | title | 施行日期；条约分类、缔约国、领域、签署日期、港澳分类 |
| `tax` | 国家税务总局政策法规库 | JSON | title, all | exact, 公布日期, status, newest；效力级别、税种及二级分类、文号、行业、制定年份 |
| `mee` | 生态环境部法规标准 | HTML | title, content, all | 公布日期, newest/oldest |
| `csrc` | 证监会证券期货法规数据库 | JSON | title, content（可组合） | exact, authority, status, 公布日期, newest；标题/正文各三词 AND/OR、法规体系 |
| `samr` | 市场监管法律法规规章数据库 | JSON | title, content | 类型（可多选）, status, 公布/施行日期 |
| `miit` | 工业和信息化部政策法规 | JSON | title, content, all, 文号 | 公布日期, newest；文件类型、部门、主题 |
| `nfra` | 国家金融监督管理总局 | JSON | title, content, all | 公布日期, newest/oldest；栏目、机构、相对时间 |
| `cac` | 国家互联网信息办公室 | HTML 高级检索 + JSON 法规栏目 | title, content, all | 连续短语, 排除词, 顶层栏目, 公布日期, newest/oldest；法规七分类全量枚举 |
| `mod` | 国防部法规文献 | JSON + 官网动态凭据 | title, content, author | exact；标准/模糊/二次检索 |
| `sse` | 上海证券交易所规则 | JSONP | title, content, all | exact, 公布日期, newest |
| `szse` | 深圳证券交易所规则 | JSON | title, content, all | exact, newest |
| `bse` | 北京证券交易所规则 | JSONP | all | 公布日期, newest |
| `neeq` | 全国股转系统规则 | JSONP | all | 公布日期, newest |

其中最高法、国防部官网的检索接口是全站索引，结果会保留官网返回的栏目分类；它们不应被误解为只包含司法解释或军事法规。最高检站内搜索跳转至第三方开普云服务，当前直连稳定性不足，因此 `spp` 使用最高检官方四类静态栏目全量分页并在本地执行标题匹配；不会把第三方服务宣称为最高检公开 API。网信办、司法部、最高法、最高检等 HTML 来源通常比 JSON 来源更容易受页面结构和 WAF 变化影响。

## 已知限制与在线巡检

自动化测试用于固定请求和解析契约，不能替代官网在线状态。历史巡检覆盖加入最高检之前的 18 个非 NPC 来源；最高检已于 2026-07-25 单独完成官方栏目全分页与详情在线验证。下一次全来源巡检将覆盖 19 个非 NPC 来源。此前详情严格校验中有 14 个完整通过，以下 4 个存在官网侧或文件形态限制：

- 证监会详情接口偶发超时或返回 504。
- 工信部部分官方详情页返回站点配置错误。
- 市场监管总局部分文件只提供 PDF/DOCX 附件，结构化接口中的 `content` 为 `null`。
- 上交所部分完整规则正文只通过官方 DOCX 附件提供。

因此，调用 `info` 后应检查 `body_availability`、`body_note` 和 `attachments`，不能只凭 HTTP 成功就认定已取得全文。官网接口、WAF 和页面结构可能随时变化；具体研究任务仍应核对 `official_url` 指向的官方页面。

## 数据保留规则

- 不设置默认条数、页数或摘要长度。
- 不静默去重。工信部搜索返回相似结果分组时，会逐条保留每个组成员；最高检同一文件出现在多个官方栏目时，也逐条保留并标记栏目。
- 不根据标题自行推定文件效力。仅在官网明确提供效力状态时设置 `validity_explicit=true`。
- 不把 Cookie、动态接口凭据或令牌写入源码、输出和清单。
- 国家规章库与国防部需要的官网前端鉴权值在运行时读取，只在内存中使用。
- 对官网硬性分页限制或异常字段采用显式适配，并在维护档案中记录证据和处理方式。

## 隐私与网络行为

- 安装包不包含维护者或用户的浏览器 Cookie、访问令牌、API Key、个人 IP 地址或本机路径。
- CLI 没有中心服务器、账户系统或遥测上报；检索请求由用户本机直接发往所选官方来源。
- 与任何网络访问一样，目标官网会看到请求出口的公网 IP；如果配置代理，则通常看到代理出口 IP。
- 少数官网会在请求过程中下发临时 Cookie 或动态鉴权值。适配器只在当前 HTTP 客户端内存中使用，不写入源码、输出、清单或持久化缓存。
- NPC 原始公开文件默认缓存在 `~/.cache/law_cn/documents`；可用 `--no-cache` 禁用，或用 `law-cn cache clear` 显式清理。

## 故障排查

- 先运行 `law-cn --version`、`law-cn sources`、`law-cn capabilities <source>` 和 `law-cn parameters <source>`，确认版本、来源代码和支持参数。
- PyPI 已发布但本地版本较旧时，运行 `uv tool upgrade law-cn-cli`，再用 `law-cn --version` 核对。
- 官网超时、WAF 拦截或 HTML 结构变化时，CLI 会返回非零退出码。不要把失败当成“没有检索结果”，可稍后重试并核对官方页面。
- 搜索默认不设条数或页数上限；只有显式传入 `--limit` 才截断，输出清单会记录截断状态。

## 开发与验证

```bash
.venv/bin/python -m pytest
.venv/bin/python -m pytest --cov=law_cn --cov-report=term-missing
uv build
uvx twine check dist/*
```

维护仓库中的来源研究档案记录官网入口、检索端点、分页字段、支持能力、验证日期及稳定性说明，但不会打入面向用户的 wheel/sdist。

## 许可证

本项目采用 [PolyForm Noncommercial License 1.0.0](https://polyformproject.org/licenses/noncommercial/1.0.0)，SPDX 标识为 `PolyForm-Noncommercial-1.0.0`。

允许个人研究、学习、测试以及该许可证列明的非商业组织使用；不授权商业使用。企业内部使用、商业产品或服务集成、收费服务等商业用途应事先另行取得商业授权。完整法律条款以随安装包分发的 [`LICENSE`](LICENSE) 为准。
