# 压缩、Git 与远程仓库

## 生成结构概览

```sh
moon-repomix ./project --compress --style json -o structure.json
```

`--compress` 在原始文件通过安全扫描后提取语法骨架。支持 MoonBit `.mbt/.mbti`、JavaScript `.js/.jsx/.mjs/.cjs`、TypeScript `.ts/.mts/.cts/.tsx`、Python `.py/.pyi`，以及 Go `.go`、Rust `.rs`、Java `.java`；解析器版本见 [第三方来源](../LICENSES/tree-sitter-sources.md)。解析器编译进原生程序，构建和运行无需安装 Node 或语法生成器。

MoonBit 保留导入、属性、文档注释、常量、struct/enum/trait/type、derive、impl 和函数的完整参数、默认值、返回/错误类型。函数及测试的实现正文按语法树边界省略，内部命名函数和类型仍保留；外部函数的符号/模块链接字符串保持完整，多行内联实现可以省略。矩阵函数分支属于实现。`.mbti` 通常已经是结构接口，正确解析后按 `not-smaller` 保持原文。固定 grammar 的本地补丁支持 tuple `for`、`..<=` 范围模式和 `errdefer`，原始 CRLF 和源行位置保持不变。

Go 保留 package/import、构建注释、泛型、receiver、struct/interface/type 和完整参数/返回类型，按函数、方法及函数字面量的 AST body 边界省略实现。Rust 保留 use/mod、属性、struct/enum/trait/impl、生命周期、where 约束及完整签名；嵌套声明仍保留，宏、extern、常量及未知结构保持原片段。这两种语言不做初始化值折叠或展示空白压缩，宏密集文件可能仅有少量收益。

Java 保留类/接口/枚举/record、字段和 schema、annotations、泛型、继承关系、完整参数/返回/throws、嵌套及匿名类 API，按 AST 删除已知方法、构造、lambda 和初始化实现区。未知节点及声明值保持保守；输出用于理解结构，不承诺可重新编译。升级注意事项见 [迁移指南](migration.md)。

JS/TS/Python 提取导入、类型、类、函数签名和从属结构。仅含实现的分支和循环整体省略，围住嵌套声明或成员 API 的控制结构保留；CommonJS 的静态 `require`、导出别名及回调安装的方法也保留。部分私有索引数据表可整表折叠，导出、别名、类型查询、返回/序列化、枚举键或写入等使用会保护相应结构。较短的初始化片段保留原文，避免替换成更长的省略标记。

JS/TS/Python 的相邻删除区合并，AST 容器子节点之间的展示空白压缩；字面量、模板字符串和保留注释的内部换行保持原样。整表折叠时，其内部分类注释随表省略。MoonBit 使用独立的 AST 正文选择，保留其余原始片段。

每份压缩记录包含 `path`、`language`、`applied`、`reason`、`ranges`、`originalTokens` 和 `outputTokens`。`ranges` 是 `[startLine,endLine]` 数组，从 1 开始、包含两端，回指原文件而非输出行号。相邻或重叠的行区间合并，区间表示保留片段覆盖到的行，不表示整行均被保留；压缩包 API 仍提供逐片段范围。不支持、解析失败或正文 token 数没有减少时保留原文，并记录原因。骨架适合先了解结构；需要实现细节时可用 `--include` 选定路径，再关闭压缩。

### 按路径保留原文

```sh
moon-repomix ./project --compress --keep-full 'src/core/**,README.md' --style markdown -o review.md
```

`--keep-full` 为已选文件设置原文例外，其余文件仍按语言提取骨架。模式相对输入根，沿用 include 的花括号、字符类和目录后代匹配；它只控制压缩方式，文件选择与扫描保持同一流程。库入口使用 `options(..., compress=true, keep_full_patterns=["src/core/**"])`，配置使用 `output.keepFull`。

主动保留的完整记录为 `applied: false`、`reason: "kept-full"`、空行区间，原始/输出正文计数相同；`language` 为 null，表示未调用解析器。概览以 `keptFull` 单独计数。关闭全局压缩时全部文件保留原文。

终端的 `File-body tokens` 对比接受文件的原始正文与处理后正文，文件排名和目录统计使用后者。处理后计数位于显示行号和格式转义之前；最终文档计数还包含显示路径、行号、目录树、格式包装、来源、压缩记录及 Git 章节，预算以这个完整计数为准。

## 添加头部和指令

```sh
moon-repomix ./project --header-text '请关注接口与错误处理。' --instruction-file-path review-instructions.md --style markdown -o review.md
```

先准备本地 `review-instructions.md`，路径相对进程 cwd。头部和指令在获取远程仓库及压缩前读入、扫描，随后进入同一份 `Document`，四种格式均可呈现。头部文字和指令文件各最多 1 MiB；文件使用严格 UTF-8，去除开头 BOM并保留其余 CRLF。最终链接、非普通文件、过大或无效编码均报 `ContextTextError`。扫描开启且任一模板命中时报 `ContextSecurityError`，只显示字段名。

配置字段为 `output.headerText` / `output.instructionFilePath`，空字符串清除继承值；库入口接受 `header_text` / `instruction_file_path`。模板参与完整文档的计数和预算，文件及 Git 章节仍按原选择规则处理。远程仓库不会自动提供指令文件。

## 导出变更和历史

```sh
moon-repomix ./project --include-diffs --include-logs --include-logs-count 20 -o review.xml
moon-repomix ./project/src --include-diffs --include 'api/**' --style markdown -o api-review.md
```

`--include-diffs` 分别导出 staged、unstaged 的逐文件补丁。`--include-logs` 先读取所选目录最近 N 个提交，再筛选其文件列表，因此接受的提交数可能小于 N。输出包含标识、日期、完整消息和文件列表；数量默认 50，可设为 `1..10000`。仅设置数量不会自动开启日志。

路径相对于所选目录，应用当前工作树的 include、ignore、父目录剪枝、链接和输出自身排除规则。已删除文件仍可导出；重命名任一端被排除时，整个补丁排除。历史提交只保留允许的文件列表，列表为空时排除该提交。这里使用当前 ignore 文件，不逐个恢复历史版本的规则。

提交消息保持原意，可能提及文件列表之外的名称，不会因此提取那些文件。原始补丁（包括删除行）和提交消息都扫描；命中时排除对应整个补丁或提交并记录诊断。XML 无法表示的章节也会排除。

Git 调用通过参数数组执行，禁用外部 diff、textconv、签名显示、fsmonitor、hooks 和交互凭据扩展，并限制输出与执行时间。`--max-git-bytes` 控制一次收集的 Git 文本总量，默认 8 MiB；超过上限会报错，而不是输出不完整的补丁。显式请求 Git 功能但目录不适用、Git 不存在或命令失败时，打包停止并保留旧输出。

## 从公开仓库获取

```sh
moon-repomix --remote https://github.com/octocat/Hello-World.git --include-logs --style json -o remote.json
moon-repomix --remote https://github.com/octocat/Hello-World.git --remote-branch master --include 'README*' -o readme.xml
```

首版接受公开 HTTPS URL，支持默认分支及显式 branch/tag/revision，拒绝嵌入凭据和其他协议。使用 `--include` 选择仓库内路径；远程输入与另一个本地目录参数互斥。

仓库进入独立临时目录，随后复用文件选择、扫描、压缩、格式与计数流程。成功、失败和取消均清理目录。开启日志时获取所选 ref 的完整祖先历史，再导出最近 N 条；大型历史可能受到每命令 30 秒限制。输出记录公开 URL 和实际 commit；干净 checkout 通常没有 staged/unstaged 差异。

远程模式只加载 `--config` 显式指定的本地配置，不自动采用启动目录或远程仓库中的 `repomix.config.json`。使用 JSON 的 `remote.url` 时同样需要显式 `--config`；自动发现的配置不能发起远程获取。仓库里的 ignore 文件仍作为路径规则读取。Git 子模块不递归获取，私有仓库与交互鉴权不在当前范围内。

## 结构化输出与库调用

`Document` 包含 `files`、`sections`、`metadata`、`header_text` 和 `instruction_text`；`PackResult.document` 暴露同一份模型，元数据始终完整。完整记录的结构为：

- `metadata.source`：`kind`、可选 URL 和实际 revision；普通本地压缩未请求 Git 时 revision 为 null。
- `metadata.compression`：逐文件骨架与回退记录。
- `metadata.git`：接受的 diff 路径、提交标识与文件列表。
- `sections`：`kind` 为 `git_diff` 或 `git_log`，并含 `title`、`text`。

四种输出格式默认展示简短概览：保留来源及 revision；`metadata.compression` 为对象，含 `files`、`applied`、`originalTokens`、`outputTokens`、`languages`、`fallbacks`；`metadata.git` 汇总接受的补丁与提交数。JSON 的 `files` 仍为路径到正文的对象，`sections` 与文件正文保持完整；XML 的 Git 内容位于 `sections/section`。概览只改变渲染后的元数据，原有未开启压缩、Git 或远程来源的输出结构保持原样。

需要逐文件状态和原始行区间时，使用 `--full-metadata`，或 JSON 配置 `output.fullMetadata: true`。此时 `metadata.compression` 恢复为逐文件数组，`metadata.git` 保留逐项记录。库入口 `options(..., full_metadata=true)` 和四种渲染函数的 `full_metadata=true` 参数提供同样的选择，也可直接读取完整的 `Document.metadata`。JSON 按其格式缩进，其他格式中的元数据使用紧凑 JSON。最终预算针对所选模式的实际完整输出计算。

```moonbit
let options = @repomix.options(
  ".", style=@repomix.Style::Json, compress=true,
  remote=Some("https://github.com/octocat/Hello-World.git"),
  include_logs=true, include_logs_count=10,
)
let result = @repomix.pack(options, runtime)
```

库入口负责远程获取与清理，返回的文本和结构化文档均可独立使用，不依赖临时目录继续存在。`FileStats.original_tokens` 是扫描后原始正文的计数，`tokens` 是实际渲染正文的计数。`PackError` 包含 `GitError`、`RemoteError`，以及模板读取/表示错误 `ContextTextError`、扫描命中 `ContextSecurityFinding`；安全扫描与预算仍使用原有状态。
