YaronKoresh/pakem

GitHub: YaronKoresh/pakem

pakem 是一个将源代码仓库序列化为可移植制品的打包系统,支持多种输出格式、增量差异、云存储及 LLM 索引集成。

Stars: 0 | Forks: 0

# pakem `pakem` 是一个仓库打包系统,旨在将源代码树转换为可移植的制品,用于分析、索引、共享和恢复工作流。 它支持面向文档的输出(`xml`、`json`、`proto`)和二进制存档格式(`pakem`),并提供可选的压缩、可逆加密、分割输出、增量状态跟踪和差异报告功能。 ## 目录 1. [使命与范围](#mission-and-scope) 2. [功能矩阵](#capability-matrix) 3. [系统架构](#system-architecture) 4. [数据流与控制流](#data-flow-and-control-flow) 5. [安装与运行环境](#installation-and-environment) 6. [CLI 参考](#cli-reference) 7. [输出格式与文件规范](#output-formats-and-file-specifications) 8. [状态、差异与恢复语义](#state-delta-and-restore-semantics) 9. [安全与信任模型](#security-and-trust-model) 10. [性能与可扩展性调优](#performance-and-scalability-tuning) 11. [验证与质量门禁](#validation-and-quality-gates) 12. [Python API 用法](#python-api-usage) 13. [运维手册](#operational-playbooks) 14. [故障排除](#troubleshooting) 15. [模块内部原理](#module-by-module-internals) 16. [贡献与发布工作流](#contributing-and-release-workflow) 17. [术语表](#glossary) 18. [许可证](#license) ## 使命与范围 `pakem` 的存在是为了很好地解决一个问题: - 确定性地扫描仓库。 - 分析文本源代码文件。 - 序列化规范化的元数据和内容。 - 可选地跟踪历史状态,以进行面向差异的操作。 - 可选地生成二进制制品,以便日后恢复。 ### 主要用例 | 用例 | 输入 | 输出 | 典型消费者 | |---|---|---|---| | LLM 上下文打包 | 源代码仓库 | XML/JSON/Proto/LLM Prompt | Prompt pipeline、RAG 预处理器 | | 增量仓库快照 | 源代码 + 状态文件 | XML/JSON/Proto/Pakem + 更新后的状态 | CI 和定时任务 | | 仅变更制品生成 | 源代码 + 先前状态 + `--delta` | 差异子集 + diff 清单 | 审查与同步自动化 | | 归档和恢复工作流 | 源代码 | `.pakem`(单文件或分割文件) | 备份、传输、迁移 | | 归档间变更分析 | 两个制品 | 新增/修改/删除报告 | 回归分类和发布验证 | | 云端制品传输 | 本地源代码 + 云 URI(`s3://`、`gs://`、`az://`) | 通过对象存储读写制品 | 远程备份和 pipeline 自动化 | | 归档检查与报告 | 现有制品 | TUI/纯文本浏览器和 HTML 差异报告 | 发布工程和审计 | | 生态系统加载器 | 现有制品 | LangChain 文档 / LlamaIndex 节点 | RAG 和索引服务 | | 忽略规则诊断 | 源代码 + 忽略模式/文件 | 打印被忽略的列表 | 构建工程和 DevEx | ## 功能矩阵 | 功能 | xml | json | proto | pakem | llm-prompt | |---|---:|---:|---:|---:|---:| | 完整仓库元数据 | 是 | 是 | 是 | 是 | | 文件行级内容 | 是 | 是 | 是 | 打包的 payload | 结构化 prompt 块 | | 增量状态跟踪(`--state`) | 是 | 是 | 是 | 是 | | 差异模式(`--delta`) | 是 | 是 | 是 | 是 | | Diff 清单输出(`diff --diff-out`) | 是 | 是 | 是 | 是 | | HTML 差异报告(`--html-diff-out` / `archive-diff --html-out`) | 是 | 是 | 是 | 是 | | 可选压缩(`--compress zlib/zstd/lz4`) | 否 | 否 | 否 | 是 | | 可选可逆加密(`--encrypt-key`) | 否 | 否 | 否 | 是 | | 可选分割输出(`--split-size`) | 否 | 否 | 否 | 是 | | 块级去重(`--dedup-chunks`) | 否 | 否 | 否 | 是 | | 恢复支持(`restore`) | 否 | 否 | 否 | 是 | 否 | | 语义分块(`--semantic-chunking`) | 是 | 是 | 是 | 是 | 是 | | Git 跟踪文件模式(`--tracked-files`) | 是 | 是 | 是 | 是 | 是 | | 分布式分片过滤(`--distributed-shards` + `--distributed-index`) | 是 | 是 | 是 | 是 | 是 | | 分析缓存模式(`--cache-mode`) | 是 | 是 | 是 | 是 | 是 | | 云 URI 输出/输入(`s3://`、`gs://`、`az://`) | 是 | 是 | 是 | 是 | 是 | ## 系统架构 ### 高层模块拓扑 ``` flowchart TB CLI[cli.py] --> CMD[commands.py] CMD --> PACKER[packer.py] PACKER --> FS[fs.py] PACKER --> ANALYZE[analyze.py] PACKER --> STATE[state.py] PACKER --> SERIALIZE[serialize.py] PACKER --> VALIDATE[validation.py] ANALYZE --> TOKEN[tokenizer.py] FS --> IGNORE[ignore.py] ``` ### 命令分发模型 ``` flowchart LR A[argv] --> B{normalize argv} B -->|no subcommand| C[prepend pack] B -->|has subcommand| D[keep argv] C --> E[argparse subparsers] D --> E[argparse subparsers] E --> F{command} F -->|pack| G[PackCommand.execute] F -->|diff| H[DiffCommand.execute] F -->|restore| I[RestoreCommand.execute] F -->|archive-diff| J[ArchiveDiffCommand.execute] F -->|explore| K[ExploreCommand.execute] F -->|setup-precommit| L[SetupPrecommitCommand.execute] ``` ### 打包执行 Pipeline ``` flowchart TD START[RepoPacker.pack] --> SR[start_repository] SR --> WALK[walk file tree] WALK --> FILTER[ignore + binary filter] FILTER --> ANALYSIS[parallel analyze_entry] ANALYSIS --> STATEUPD[update current state] STATEUPD --> SERIAL[serializer.add_file] SERIAL --> PAYLOAD[optional pakem payload transforms] PAYLOAD --> ENDREP[end_repository] ENDREP --> TOTALS[update totals] TOTALS --> WRITE[serializer.write_to] WRITE --> SAVE[state save if configured] SAVE --> DONE[exit code 0] ``` ## 数据流与控制流 ### pack 命令数据契约 | 阶段 | 输入 | 输出 | 不变量 | |---|---|---|---| | 参数解析 | CLI 选项 | `Namespace` | 子命令为 `pack`、`diff`、`restore`、`archive-diff`、`explore`、`setup-precommit` 之一 | | 输出路径解析 | `--out`、`--format` | 具体文件路径或云 URI | 如果 `--out` 没有后缀,则根据格式推断后缀 | | 文件遍历 | 根目录 + 忽略规则 | `FileEntry` 流 | 相对路径规范化为 `/` | | 文本分析 | 文件路径 | `FileMetadata` + 内容行 | 跳过二进制文件 | | 状态更新 | 先前状态 + 文件哈希 | 当前状态 | 每个处理过的文本文件都会获得确定性的状态条目 | | 序列化 | 元数据 + 行 | 格式制品 | 仓库总计在末尾更新 | ### restore 命令数据契约 | 阶段 | 输入 | 输出 | 不变量 | |---|---|---|---| | 制品读取 | `.pakem` 或分割部分 | bytes | Header 必须以 `PAKM` 开头 | | Header 解析 | 制品字节 | 元数据 JSON + payload 字节 | 版本字节必须受协商元数据支持 | | 块重建 | payload 流 + 每个文件的长度 | 文件字节 | 转换逆转是转换顺序的逆操作 | | 写入阶段 | `target_dir` + 相对路径 | 恢复的文件 | 拒绝目标之外的路径遍历 | ## 安装与运行环境 ### 最小化安装 ``` pip install pakem ``` ### 开发安装 ``` git clone https://github.com/YaronKoresh/pakem.git cd pakem pip install -e ".[dev]" ``` ### 可选附加项 根据需要安装可选附加项: ``` pip install -e ".[extra]" ``` 当前包含的附加项: | 包 | 启用功能 | |---|---| | `pathspec` | 高级 gitignore 风格模式匹配 | | `tiktoken` | 感知模型的 token 计数 | | `protobuf` | Proto 序列化器支持 | | `dulwich` | Git 原生跟踪文件和元数据丰富 | | `zstandard` | zstd 压缩配置 | | `lz4` | lz4 压缩配置 | | `fsspec` + 云 FS 插件(`s3fs`、`gcsfs`、`adlfs`) | 制品和报告的云 URI 读写 | | `langchain` | LangChain 加载器适配器 | | `llama-index` | LlamaIndex 读取器适配器 | ### 运行时要求 | 要求 | 值 | |---|---| | Python | `>=3.10` | | 项目版本 | `2.0.0` | | 入口点 | `pakem = pakem.cli:main` | ## CLI 参考 ## 全局调用形式 ``` pakem [options] python -m pakem [options] ``` 如果未提供子命令,则隐式使用 `pack`。 ## `pack` 命令 ``` pakem pack [--path PATH] [--out OUT] [--format {xml,json,proto,pakem,llm-prompt}] ``` ### `pack` 选项表 | 选项 | 类型 | 默认值 | 描述 | |---|---|---|---| | `--path` | string | `.` | 要处理的根目录 | | `--out` | string | `repo` | 输出路径或基础名称 | | `--ignore` | list[string] | 无 | 额外的忽略模式 | | `--include` | list[string] | 无 | 允许列表模式;仅考虑匹配的路径 | | `--tracked-files` | flag | `false` | 仅包含 git 索引中跟踪的文件 | | `--git-metadata` | flag | `false` | 使用提交哈希/作者/日期丰富文件元数据 | | `--semantic-chunking` | flag | `false` | 在渲染文件内容时保留类/函数边界 | | `--summary-mode` | enum | `off` | 可选的低优先级摘要模式 | | `--plugin` | list[string] | 无 | 执行前加载的可选插件模块路径 | | `--cache-mode` | enum | `off` | 分析缓存模式 | | `--dedup-chunks` | flag | `false` | 为 pakem payload 启用块级去重 | | `--distributed-shards` | int | 无 | 分布式打包的分片总数 | | `--distributed-index` | int | 无 | 本次运行的从零开始的分片索引 | | `--ignore-file` | string | 无 | 额外忽略文件的路径 | | `--state` | string | 无 | JSON 状态文件路径 | | `--delta` | flag | `false` | 仅包含更改的文件 | | `--max-file-size` | size | 无 | 跳过大于此阈值的文件(`512KB`、`10MB`、`1GB`) | | `--max-total-tokens` | int | 无 | 限制所选文件的打包 token 总数 | | `--dry-run` | flag | `false` | 分析并报告,而不写入包/状态/报告文件 | | `--focus-ranking` | enum | `basic` | token 预算受限时使用的排名策略 | | `--list-ignored` | flag | `false` | 打印被忽略的条目并退出 | | `--model` | string | 无 | 分词模型提示 | | `--workers` | int | auto | 分析工作线程数(正整数) | | `--format` | enum | `xml` | 输出格式 | | `--emit-schema` | string | 无 | Schema 输出路径 | | `--schema-format` | enum | `xml` | Schema 格式 | | `--compress` | enum | `none` | pakem payload 压缩 | | `--encrypt-key` | string | 无 | pakem 可逆密钥 | | `--cipher` | enum | `aes-gcm` | 用于 pakem payload 加密的加密配置 | | `--sign-key` | string | 无 | 可选的来源签名密钥(`hmac-sha256`) | | `--split-size` | size | 无 | pakem 分割阈值(`1MB`、`512KB`、`2GB`) | | `--sensitive-data-policy` | enum | `off` | 敏感数据处理模式 | | `--secret-scanner` | enum | `builtin` | 密钥扫描器集成模式(`builtin`/`gitleaks`/`trufflehog`/`auto`/`off`) | | `--sensitive-report-out` | string | 无 | 针对敏感数据发现的可选 JSON 报告输出 | | `--selection-report-out` | string | 无 | 包含已选和已跳过路径的可选 JSON 报告 | ### `pack` 示例 ``` # 在当前目录中默认打包(隐式 .xml 后缀) pakem pack # 显式格式及自动扩展名 pakem pack --path ./repo --format json --out snapshot # 使用 state file 的 Delta pack pakem pack --path ./repo --state .pakem-state.json --delta --out delta-report # 带有 include allowlist 和 token budget 的定向打包 pakem pack --path ./repo --include "src/**" --max-total-tokens 20000 --focus-ranking basic --out focused # 仅执行 Analysis-only pass,不写入 artifact pakem pack --path ./repo --dry-run --max-file-size 1048576 # 带有 payload transforms 和 splitting 的 pakem archive pakem pack --path ./repo --format pakem --compress zlib --encrypt-key key123 --split-size 1048576 --out archive # 带有 semantic chunking 的 LLM prompt profile pakem pack --path ./repo --format llm-prompt --semantic-chunking --summary-mode basic --out prompt ``` ## `diff` 命令 ``` pakem diff --state STATE [--path PATH] [--out OUT] [--diff-out FILE] ``` ### `diff` 选项表 | 选项 | 类型 | 必需 | 描述 | |---|---|---:|---| | `--state` | string | 是 | 要进行比较的现有状态文件 | | `--path` | string | 否 | 根目录(默认 `.`) | | `--out` | string | 否 | 制品输出基础名称/路径 | | `--diff-out` | string | 否 | JSON diff 清单输出路径 | | `--html-diff-out` | string | 否 | HTML diff 报告输出路径 | | `--ignore` | list[string] | 否 额外的忽略模式 | | `--include` | list[string] | 否 | 允许列表模式;仅考虑匹配的路径 | | `--tracked-files` | flag | 否 | 仅包含 git 索引中跟踪的文件 | | `--git-metadata` | flag | 否 | 使用提交哈希/作者/日期丰富文件元数据 | | `--semantic-chunking` | flag | 否 | 在渲染文件内容时保留类/函数边界 | | `--summary-mode` | enum | 否 | 可选的低优先级摘要模式 | | `--plugin` | list[string] | 否 | 执行前加载的可选插件模块路径 | | `--cache-mode` | enum | 否 | 分析缓存模式 | | `--dedup-chunks` | flag | 否 | 为 pakem payload 启用块级去重 | | `--distributed-shards` | int | 否 | 分布式打包的分片总数 | | `--distributed-index` | int | 否 | 本次运行的从零开始的分片索引 | | `--ignore-file` | string | 否 | 额外的忽略文件 | | `--format` | enum | 否 | 输出格式 | | `--max-file-size` | size | 否 | 跳过大于此阈值的文件(`512KB`、`10MB`、`1GB`) | | `--max-total-tokens` | int | 否 | 限制所选文件的打包 token 总数 | | `--dry-run` | flag | 否 | 仅分析,不写入包或 diff 输出文件 | | `--focus-ranking` | enum | 否 | token 预算受限时使用的排名策略 | | `--selection-report-out` | string | 否 | 包含已选和已跳过路径的可选 JSON 报告 | | `--secret-scanner` | enum | 否 | 密钥扫描器集成模式(`builtin`/`gitleaks`/`trufflehog`/`auto`/`off`) | 约束语义: - `--max-file-size` 和 `--max-total-tokens` 定义了所选范围。 - 所选范围一致地用于制品内容、持久化状态条目和 `diff` 输出。 - 运行时统计信息包含针对超出 max-file-size 和 token-budget 的跳过计数器。 - `--selection-report-out` 为自动化和审计发出已选路径和跳过原因。 - 大小参数接受不区分大小写的后缀:`B`、`KB`、`MB`、`GB`、`TB`。 状态后端语义: - 文件后端(默认):向 `--state` 传递普通路径。 - 内存后端:`--state memory://`。 - SQLite 后端:`--state sqlite:///path/to/state.db?key=`。 归档协商与来源: - pakem 归档包含 `min_reader_version` 和 `max_reader_version` 元数据。 - 可选签名在 pack 期间使用 `--sign-key`,在 restore 期间使用 `--verify-signature-key`。 - 恢复操作将拒绝签名不匹配及不兼容的协商范围。 Pack 选项兼容性: - `--compress`、`--encrypt-key` 和 `--split-size` 仅在与 `--format pakem` 一起使用时有效。 - `--cipher` 自定义仅在与 `--format pakem` 一起使用时有效。 - `--cipher none` 不能与 `--encrypt-key` 组合使用。 ### `diff` 输出 Schema 如果提供了 `--diff-out`,JSON 结构为: ``` { "added": ["..."], "modified": ["..."], "removed": ["..."] } ``` ## `restore` 命令 ``` pakem restore --in ARCHIVE --target TARGET [--format pakem] [--compress {none,zlib,zstd,lz4}] [--encrypt-key KEY] ``` ### `restore` 注意事项 - 支持 `.pakem` 制品和分割序列(`.pakem.part001`、`.part002`,...)。 - 使用元数据 `payload_length` 值重建文件 payload 边界。 - 拒绝解析到 `--target` 之外的写入。 ## `archive-diff` 命令 ``` pakem archive-diff --left OLD --right NEW [--left-format FMT] [--right-format FMT] [--out OUT] [--html-out REPORT.html] ``` 无需扫描活动仓库即可生成确定性的新增/修改/删除结果。 ## `explore` 命令 ``` pakem explore --in ARCHIVE [--tui] ``` 使用普通终端输出或基于 curses 的 TUI(`--tui`)检查归档条目。 ## `setup-precommit` 命令 ``` pakem setup-precommit [--path PATH] [--force] ``` 生成包含 `ruff`、`ruff-format` 和本地 `poe check` 钩子的 `.pre-commit-config.yaml`。 ## 输出格式与文件规范 ## 扩展名自动选择 当 `--out` 没有后缀时: | 格式 | 应用的后缀 | |---|---| | `xml` | `.xml` | | `json` | `.json` | | `proto` | `.pb` | | `pakem` | `.pakem` | | `llm-prompt` | `.prompt.md` | 如果 `--out` 已有后缀,则保留该后缀。 ## XML 和 JSON 两者都表示仓库元数据、目录记录和文件记录。XML 使用嵌套元素,JSON 使用结构化对象。 ## Protobuf Protobuf 使用在运行时通过 `pakem.proto` 描述符构建生成的动态消息。 ## pakem 二进制容器 ### 二进制布局 | 段 | 大小 | 描述 | |---|---:|---| | Magic | 4 bytes | ASCII `PAKM` | | Version | 1 byte | 当前值:`2` | | Header length | 4 bytes(大端序) | 元数据 JSON 的字节长度 | | Metadata | 可变 | 包含仓库/文件描述符的 UTF-8 JSON | | Payload | 可变 | 拼接的文件 payload 块 | ### 元数据核心键 | 键 | 类型 | 描述 | |---|---|---| | `repository` | object | 根元数据、总计、时间戳 | | `directories` | array | 可选的目录条目 | | `files` | array | 包含 `payload_length` 的文件描述符 | | `payload_size` | int | 总 payload 字节数 | ### 分割输出行为 如果最终 blob 大小超过 `--split-size`,写入器会发出: - `name.pakem.part001` - `name.pakem.part002` - ... 在分割模式下不会发出根 `.pakem` 文件。 ## 状态、差异与恢复语义 ## 状态模型 状态文件存储: | 字段 | 类型 | 描述 | |---|---|---| | `version` | int | Schema 版本,当前默认值为 `2` | | `files` | object map | `rel_path -> {mtime, size, sha256}` | 没有 `version` 的遗留状态将加载为版本 `1`。 ## 差异计算 `RepoState.diff_paths(new_state)` 返回以下项的排序列表: - `added`(新增) - `modified`(修改) - `removed`(删除) 在差异模式下: - 未更改的文件不会被序列化到输出 payload 中 - 序列化器仓库元数据可以包含 `delta` 块 ## 恢复语义 恢复需要 `pakem` 格式,并遵循以下逆操作逻辑: 1. 解析 header 和元数据。 2. 根据每个文件的 `payload_length` 切片 payload。 3. 反转加密(如果提供了密钥)。 4. 反转压缩(如果启用了 `zlib`)。 5. 验证目标路径安全性。 6. 写入文件字节。 ## 安全与信任模型 ## 当前安全控制 | 控制 | 状态 | 描述 | |---|---|---| | 路径遍历预防 | 已启用 | 恢复操作通过 realpath/commonpath 逻辑检查目标路径边界 | | 格式完整性检查 | 已启用 | `validate_pakem` 检查 magic/version/header 的一致性 | | 二进制检测 | 已启用 | 在源代码 pack 阶段跳过二进制文件 | ## 重要密码学说明 默认加密配置是认证加密(`aes-gcm` 和 `chacha20-poly1305`),带有与元数据绑定的身份验证。 遗留的可逆 xor 模式仅在显式遗留模式下可用,用于提供恢复兼容性路径。 ## 性能与可扩展性调优 ## Worker 策略 默认情况下,worker 数量派生自 CPU 计数(`cpu_count * 4`,最小为 1)。 指南: | 仓库概况 | 建议的 `--workers` | |---|---:| | 小型(<5k 个文件) | auto | | 中型(5k-50k 个文件) | 8-16 | | 大型 monorepo | 16-32(验证宿主机 IO 限制) | ## 吞吐量注意事项 | 因素 | 影响 | |---|---| | 二进制文件流行度 | 更多的二进制文件意味着由于跳过行为,总运行时间更快 | | 分词器后端 | `tiktoken` 可以提高模型一致性;正则回退可避免依赖 | | 状态可用性 | 现有状态可以减少昂贵的哈希重新计算路径 | | 分析缓存模式 | `local` 和 `memory` 缓存减少重复的分析工作 | | mmap 哈希 | 大文件哈希在可用时使用 mmap,以减少内存 churn | | Pakem 转换 | 压缩和加密会增加 CPU 负载 | ## 流程图:性能路径 ``` flowchart TD A[File discovered] --> B{binary?} B -->|yes| C[skip] B -->|no| D[analyze + hash] D --> E{delta + unchanged?} E -->|yes| F[exclude from artifact] E -->|no| G[serialize] G --> H{format pakem?} H -->|no| I[write structured output] H -->|yes| J[compress/encrypt/split] ``` ## 验证与质量门禁 ## 内置验证器 | 验证器 | 目标 | |---|---| | `validate_xml(path)` | XML 制品 | | `validate_json(path)` | JSON 制品 | | `validate_proto(path)` | Proto 制品 | | `validate_pakem(path)` | pakem 二进制制品 | | `validate(path, format=None)` | 格式推断 + 分发 | ## 项目质量命令 | 目标 | 命令 | |---|---| | 运行测试 | `pytest -q` | | 运行 Autobot 脚本测试 | `node --test tests/autobot_scripts.test.js` | | 运行 linter | `ruff check .` | | 编译检查 | `python -m compileall -q .` | | 所有检查 | `poe check` | ## Python API 用法 ## 基础 Pack ``` from pakem import IgnoreRules, RepoPacker from pakem.fs import FileWalker root = "/path/to/repo" out = "repo.xml" rules = IgnoreRules.from_defaults(root, extra_patterns=["*.tmp"]) walker = FileWalker(root, rules, output_path=out) packer = RepoPacker( root_dir=root, output_file=out, ignore_rules=rules, walker=walker, output_format="xml", ) exit_code = packer.pack() print(exit_code) ``` ## 高级 Pack(pakem) ``` from pakem import IgnoreRules, RepoPacker from pakem.fs import FileWalker root = "/path/to/repo" out = "archive.pakem" rules = IgnoreRules.from_defaults(root) walker = FileWalker(root, rules, output_path=out) packer = RepoPacker( root_dir=root, output_file=out, ignore_rules=rules, walker=walker, state_path=".pakem-state.json", delta=True, output_format="pakem", compression="zlib", encryption_key="demo-key", split_size=2_000_000, ) packer.pack() ``` ## 通过 API 恢复 ``` from pakem import IgnoreRules, RepoPacker from pakem.fs import FileWalker target = "./restored" rules = IgnoreRules.from_defaults(target) packer = RepoPacker( root_dir=target, output_file="archive.pakem", ignore_rules=rules, walker=FileWalker(target, rules), output_format="pakem", compression="zlib", encryption_key="demo-key", ) packer.restore("archive.pakem", target) ``` ## 运维手册 ## 手册 A:每日增量快照 ``` flowchart LR A[Load previous state] --> B[Run pack --delta] B --> C[Publish artifact] C --> D[Store new state] D --> E[Run validate] ``` 步骤: 1. 为每个仓库保留一个持久化的状态文件。 2. 运行 `pakem pack --state state.json --delta`。 3. 将生成的制品和更新后的状态文件存储在一起。 4. 可选运行 `pakem diff --state state.json --diff-out diff.json` 以生成变更报告。 ## 手册 B:作为分割二进制文件传输 1. `pakem pack --format pakem --split-size 1048576 --out archive` 2. 传输所有 `.partNNN` 文件。 3. 使用以下命令恢复: `pakem restore --in archive.pakem --target ./target` ## 手册 C:忽略规则调试会话 1. 通过 `--ignore` 或 `--ignore-file` 添加新模式。 2. 执行 `pakem pack --list-ignored --path ...`。 3. 验证预期路径是否出现在输出列表中。 ## 故障排除 | 症状 | 可能原因 | 纠正措施 | |---|---|---| | `restore` 返回 `1` 且没有文件 | 格式错误或 magic/header 无效 | 验证归档是否以 `PAKM` 开头,运行 `validate_pakem` | | 输出中缺少预期文件 | 忽略规则将它们过滤掉了 | 使用 `--list-ignored` 并调整模式 | | 输出扩展名与预期不符 | `--out` 具有显式后缀 | 从 `--out` 中删除后缀以使用自动扩展名 | | Token 计数看起来很通用 | 未安装 `tiktoken` 或模型不受支持 | 安装附加项并传递 `--model` | | 差异输出过大 | 状态文件丢失或过时 | 保持状态持久化并限定在每个仓库范围内 | | 分割归档未恢复 | 部分文件丢失/顺序混乱 | 确保存在连续的 `.partNNN` 文件 | ### 诊断命令 ``` # 检查 lints 和 imports ruff check . # 验证 runtime behavior pytest -q # 验证 artifact(Python snippet) python -c "from pakem.validation import validate; validate('archive.pakem', 'pakem')" ``` ## 模块内部原理 | 模块 | 职责 | 关键类型/函数 | |---|---|---| | `pakem/cli.py` | 参数解析和子命令路由 | `main`、`resolve_output_path` | | `pakem/commands.py` | 命令执行适配器 | `PackCommand`、`DiffCommand`、`RestoreCommand`、`ArchiveDiffCommand`、`ExploreCommand`、`SetupPrecommitCommand` | | `pakem/packer.py` | 核心编排 pipeline | `RepoPacker.pack`、`RepoPacker.diff`、`RepoPacker.restore` | | `pak/fs.py` | 确定性文件遍历 | `FileWalker`、`FileEntry` | | `pakem/ignore.py` | 忽略模式加载和匹配 | `IgnoreRules` | | `pakem/analyze.py` | 元数据提取和 token/行计数 | `FileMetadata`、`analyze_text` | | `pakem/tokenizer.py` | Token 计数后端 | `RegexTokenCounter`、`TiktokenTokenCounter` | | `pakem/state.py` | 增量文件状态和差异 | `RepoState`、`FileState`、`diff_paths` | | `pakem/serialize.py` | XML/JSON/Proto/Pakem 序列化器 | `XmlSerializer`、`JsonSerializer`、`ProtoSerializer`、`PakemSerializer` | | `pakem/cloud_io.py` | 本地/云读写抽象 | `read_bytes`、`write_text`、`write_bytes` | | `pakem/cache.py` | 分析缓存后端 | `AnalysisCache`、`create_cache` | | `pakem/plugins.py` | 运行时插件加载 | `load_plugins`、`register_analyzer` | | `pakem/reports.py` | HTML 报告 | `render_html_diff_report` | | `pakem/loaders.py` | 生态系统数据加载器 | `PakemLangChainLoader`、`PakemLlamaIndexReader` | | `pakem/tui.py` | 归档探索 UI | `explore_archive` | | `pakem/validation.py` | 制品验证和路径安全 | `validate`、`validate_pakem`、`is_path_safe` | | `pakem/proto.py` | 动态 protobuf schema 描述符 | `get_repository_message_class` | ## 贡献与发布工作流 ## 开发工作流 ``` pip install -e ".[dev,extra]" ruff check . pytest -q node --test tests/autobot_scripts.test.js ``` ## 建议的 Pull Request 检查清单 | 检查项 | 状态 | |---|---| | 测试覆盖了新行为 | 必需 | | Lint 通过(`ruff check .`) | 必需 | | 针对 CLI/API 变更更新了 README | 必需 | | 考虑了向后兼容性 | 推荐 | | 记录了状态/格式迁移 | 推荐 | ## 打包任务 | 任务 | 命令 | |---|---| | 构建 source + wheel | `poe build` | | 仅构建 wheel | `poe build-wheel` | | 安装 pre-commit 钩子 | `poe hook` | ## 术语表 | 术语 | 含义 | |---|---| | Artifact(制品) | 运行产生的最终输出文件 | | Delta mode(差异模式) | 仅序列化相对于先前状态已更改的文件 | | State file(状态文件) | 文件路径到 mtime/size/hash 的 JSON 映射,用于增量处理 | | Payload length | pakem payload 流中单个文件序列化字节的字节长度 | | Split archive(分割归档) | 当 blob 超过 `--split-size` 时生成的多部分输出 | ## 许可证 该项目根据 GNU General Public License v3.0 或更高版本进行许可。 完整条款请参见 [LICENSE](LICENSE)。
标签:Linux安全, Python, SOC Prime, 代码分析, 凭证管理, 大语言模型预处理, 开发工具, 归档备份, 无后门, 逆向工具