# 压缩包解包Skill 设计

## 1. Skill 定位

`压缩包解包Skill` 负责压缩包解包，是资料包导入链路中的文件展开能力。它需要支持 `zip`、`rar`、`7z`，并确保解包过程安全、可追踪、可复核。

本 Skill 的输出是“解包后的文件树”，不是文档审核结论。

英文实现标识建议使用 `ArchiveExtractionSkill`，用于 Python 类名和 Tool Registry 注册处理器。

## 2. 输入

```python
@dataclass
class ArchiveExtractionInput:
    archive_path: Path
    target_dir: Path
    source_archive_name: str
    max_file_count: int = 1000
    max_total_size: int | None = None
```

## 3. 输出

```python
@dataclass
class ArchiveExtractionOutput:
    status: str
    archive_type: str
    extracted_files: list[ExtractedFile]
    skipped_items: list[SkippedArchiveItem]
    warnings: list[dict]
```

`ExtractedFile` 字段：

1. `absolute_path`
2. `relative_path`
3. `file_size`
4. `source_archive_name`
5. `file_hash`

## 4. 支持格式与技术

| 格式 | 技术 |
|---|---|
| `zip` | Python 标准库 `zipfile` |
| `rar` | 纯 Python rar 解析依赖，优先选择不依赖系统命令的库 |
| `7z` | `py7zr` |

V1 可以先完成 `zip`，同时保留 `rar`、`7z` 的接口和失败提示。正式验收前需要补齐纯 Python 解包能力。

## 5. 核心方法

### 5.1 `run(input) -> ArchiveExtractionOutput`

主入口方法。

处理顺序：

1. 识别压缩包类型。
2. 打开压缩包。
3. 遍历成员文件。
4. 校验成员路径安全性。
5. 校验数量和大小限制。
6. 解包到批次隔离目录。
7. 生成解包结果。

### 5.2 `detect_archive_type(path) -> str`

根据扩展名和文件头识别压缩包类型。

返回：

1. `zip`
2. `rar`
3. `7z`
4. `unsupported`

### 5.3 `validate_member_path(member_name) -> str`

路径安全校验。

拒绝：

1. 绝对路径。
2. 包含 `..` 的路径。
3. Windows 盘符路径。
4. 空路径。
5. 控制字符。

### 5.4 `extract_zip(input) -> list[ExtractedFile]`

使用 `zipfile` 解包。

### 5.5 `extract_rar(input) -> list[ExtractedFile]`

使用纯 Python rar 依赖解包。

如果当前环境依赖未安装，返回 `unsupported_archive`，并提示需要安装对应依赖。

### 5.6 `extract_7z(input) -> list[ExtractedFile]`

使用 `py7zr` 解包。

### 5.7 `build_file_hash(path) -> str`

使用 `sha256` 生成文件指纹，用于重复文件识别。

## 6. 状态设计

| 状态 | 含义 |
|---|---|
| `extracted` | 解包成功 |
| `partial_extracted` | 部分成员解包失败 |
| `empty_archive` | 压缩包为空 |
| `encrypted_archive` | 加密压缩包 |
| `unsupported_archive` | 格式不支持 |
| `path_rejected` | 存在危险路径 |
| `extract_failed` | 解包失败 |

## 7. 异常处理

1. 加密压缩包：不尝试暴力解析，标记为待人工处理。
2. 路径穿越：拒绝危险成员并记录安全拦截。
3. 超大压缩包：超过配置限制时停止处理。
4. 成员数量过多：停止处理并提示资料包异常。
5. 文件名乱码：保留原始名称，展示层提示人工复核。

## 8. 测试要点

1. 普通 zip 解包成功。
2. 多层目录相对路径被保留。
3. `../evil.docx` 被拒绝。
4. 空压缩包返回 `empty_archive`。
5. 不支持格式返回 `unsupported_archive`。
6. 解包后文件哈希生成稳定。
