{"_id":"@caesarloo/simple-svn-client","_rev":"5-9d4983080647e7557a012a2e8a13c65a","name":"@caesarloo/simple-svn-client","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@caesarloo/simple-svn-client","version":"0.1.0","keywords":["svn","subversion","wrapper","child-process","gbk","encoding"],"license":"MIT","_id":"@caesarloo/simple-svn-client@0.1.0","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"homepage":"https://github.com/caesarloo/simple-svn-client","bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"dist":{"shasum":"690734e87c617290df07b2a5eb68c52c24d071c7","tarball":"https://registry.npmjs.org/@caesarloo/simple-svn-client/-/simple-svn-client-0.1.0.tgz","fileCount":18,"integrity":"sha512-XOfgCnwLQ09sWZRCSZ4UNcUILEELiO1SmHh/HZ/kbr/m1ERKkBhOJCuhrVBairnaadl6DGloclYUolYdwzs2ng==","signatures":[{"sig":"MEYCIQCIHT7qBU0gzL1iV4FW9tVu95PPsTzHbQmtUqCg2XewdwIhAMPjXJzNObfvGUcVtwF6VpQ0VdlZT6DTFjVMyUSz0CwG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131280},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16"},"gitHead":"42587eb9a40c4f8297e458da51d63f4420f4e79e","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"npm run build","typecheck":"tsc --noEmit","test:watch":"jest --watch"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"_npmVersion":"11.16.0","description":"SVN CLI wrapper for Node.js — wraps the system svn executable with Windows GBK-safe decoding, binary discovery and error reporting","directories":{},"_nodeVersion":"24.14.0","dependencies":{"iconv-lite":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.6","typescript":"^5.7.3","@types/jest":"^30.0.0","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/simple-svn-client_0.1.0_1787556974914_0.3737812519553061","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@caesarloo/simple-svn-client","version":"0.1.1","keywords":["svn","subversion","wrapper","child-process","gbk","encoding"],"license":"MIT","_id":"@caesarloo/simple-svn-client@0.1.1","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"homepage":"https://github.com/caesarloo/simple-svn-client","bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"dist":{"shasum":"23b6c7f789983aac1bcc181992b54c37f7e0951c","tarball":"https://registry.npmjs.org/@caesarloo/simple-svn-client/-/simple-svn-client-0.1.1.tgz","fileCount":18,"integrity":"sha512-SzVWIAZqr2SHoP1h36yyNEslLnDDqGFtMxYKIg7oqDwGjhj/n+yCI4FdlZ1D8Zm5xxE4OhXKCeHlm9qq+Ypo1A==","signatures":[{"sig":"MEUCICn7LE0i8yqt09nMm9D91Ty38IiwydICoJsVCtPohEdeAiEAhhewtw9hR35Ji7rcs7Sc2eVUoMFRequ76S3gnElQif0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":132356},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16"},"gitHead":"c47718936519010791714748b9d9eddce2f3676a","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"npm run build","typecheck":"tsc --noEmit","test:watch":"jest --watch"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"_npmVersion":"11.16.0","description":"SVN CLI wrapper for Node.js — wraps the system svn executable with Windows GBK-safe decoding, binary discovery and error reporting","directories":{},"_nodeVersion":"24.14.0","dependencies":{"iconv-lite":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.6","typescript":"^5.7.3","@types/jest":"^30.0.0","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/simple-svn-client_0.1.1_1787571997165_0.2095051020576788","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@caesarloo/simple-svn-client","version":"0.1.2","keywords":["svn","subversion","wrapper","child-process","gbk","encoding"],"license":"MIT","_id":"@caesarloo/simple-svn-client@0.1.2","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"homepage":"https://github.com/caesarloo/simple-svn-client","bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"dist":{"shasum":"0a3df61b24e27f80974bad659b3e65ec86c5d957","tarball":"https://registry.npmjs.org/@caesarloo/simple-svn-client/-/simple-svn-client-0.1.2.tgz","fileCount":18,"integrity":"sha512-Sh6/ldkLPL+PeVbU8VW+jrAARWP1glj4R5+8vxwXN2UFeD5zH75/gpNwmsFO/Bm/kRz5rkIcvx3UEh2E61k/WA==","signatures":[{"sig":"MEUCIQC7gjwxReJ7nkgUPcBIz8WPEpyvVBMaucLf4lCeFrlN/AIga9mV2UEsvQJ8NfziPgsoOeFWKNABFx9J5i3GO0S6fNk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":133431},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16"},"gitHead":"97d7192d5d8858b00a376688c8838bd61926aa5c","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"npm run build","typecheck":"tsc --noEmit","test:watch":"jest --watch"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"_npmVersion":"11.16.0","description":"SVN CLI wrapper for Node.js — wraps the system svn executable with Windows GBK-safe decoding, binary discovery and error reporting","directories":{},"_nodeVersion":"24.14.0","dependencies":{"iconv-lite":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.6","typescript":"^5.7.3","@types/jest":"^30.0.0","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/simple-svn-client_0.1.2_1787739861249_0.04926634790355289","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@caesarloo/simple-svn-client","version":"0.1.3","keywords":["svn","subversion","wrapper","child-process","gbk","encoding"],"license":"MIT","_id":"@caesarloo/simple-svn-client@0.1.3","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"homepage":"https://github.com/caesarloo/simple-svn-client","bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"dist":{"shasum":"3b5c560fa53c880a4f50eb9f82b6bbd2df338f4b","tarball":"https://registry.npmjs.org/@caesarloo/simple-svn-client/-/simple-svn-client-0.1.3.tgz","fileCount":18,"integrity":"sha512-2bSB7JgKPNNc75GuNmDwdBwd0jusLdOZXhnWy4htPQgo4FmhRNP9pv1QuXbUczscbbo6KZ70c3tLxrcfsPDHkw==","signatures":[{"sig":"MEUCIQDyn+fCZGfmcW2lgEMT/XM5I2P+YooY0AY8Rjm+b0RAlQIgGzuWyN6ESCH57KOmsc0usO34Ef0IS3rleMOFYETaHzw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":136795},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=16"},"gitHead":"2ba5c3131b0d68f3e495924ac2e315a93b18c7d6","scripts":{"test":"jest","build":"tsc -p tsconfig.build.json","prepare":"npm run build","typecheck":"tsc --noEmit","test:watch":"jest --watch"},"_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"_npmVersion":"11.16.0","description":"SVN CLI wrapper for Node.js — wraps the system svn executable with Windows GBK-safe decoding, binary discovery and error reporting","directories":{},"_nodeVersion":"24.14.0","dependencies":{"iconv-lite":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.6","typescript":"^5.7.3","@types/jest":"^30.0.0","@types/node":"^22.10.2"},"_npmOperationalInternal":{"tmp":"tmp/simple-svn-client_0.1.3_1787744643357_0.6016398858539538","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"_id":"@caesarloo/simple-svn-client@0.2.0","bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"dist":{"shasum":"97e6d55716de8707f709bbe224ba70499dc31085","tarball":"https://registry.npmjs.org/@caesarloo/simple-svn-client/-/simple-svn-client-0.2.0.tgz","fileCount":31,"integrity":"sha512-NAn+/VkDtrMFi1g/re4fwCLapCR8ReJcZfpB6DqyhTr+7lG6100DMlkLBrsfUI0Gjd4D+PafknhYxzQjAguWMg==","signatures":[{"sig":"MEUCIE+9jxFMJiEuOSbSAyZptnfEHQk88R6Hy5qEyGJDNO8CAiEArKpmNWyMkcGxYdCvWHzZjEUJYueGjUboSDccjY6K/3E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCXGfxYj8kw4Sf+7I1213WBalB5ApQX3tMHablw7uCvPQIhAMxrLX9JRVNFdTENgUGtCcBSw6ihBhmjnlSCyf59z+pS"}],"unpackedSize":303027},"main":"dist/index.js","name":"@caesarloo/simple-svn-client","types":"dist/index.d.ts","engines":{"node":">=16"},"gitHead":"f2099cdaa634f0872f412eb553b394768d2eb63f","license":"MIT","scripts":{"test":"jest","build":"npm run clean && tsc -p tsconfig.build.json","clean":"node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"","prepare":"npm run build","typecheck":"tsc --noEmit","test:watch":"jest --watch","prepublishOnly":"npm run typecheck && npm test"},"version":"0.2.0","_npmUser":{"name":"caesarloo","email":"qizhen.lu@hotmail.com"},"homepage":"https://github.com/caesarloo/simple-svn-client","keywords":["svn","subversion","wrapper","child-process","gbk","encoding","conflict"],"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"_npmVersion":"11.16.0","description":"SVN CLI wrapper for Node.js — Windows-safe decoding, typed parsing of status/update/diff/log, conflict guards, no fs dependency","directories":{},"maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"_nodeVersion":"24.14.0","dependencies":{"iconv-lite":"^0.7.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^30.2.0","ts-jest":"^29.4.6","typescript":"^5.7.3","@types/jest":"^30.0.0","@types/node":"^22.10.2"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/simple-svn-client_0.2.0_1790677487131_0.20565432851616428"}}},"time":{"created":"2026-08-24T07:36:14.588Z","modified":"2026-09-29T10:24:47.449Z","0.1.0":"2026-08-24T07:36:15.057Z","0.1.1":"2026-08-24T11:46:37.306Z","0.1.2":"2026-08-26T10:24:21.380Z","0.1.3":"2026-08-26T11:44:03.504Z","0.2.0":"2026-09-29T10:24:47.275Z"},"bugs":{"url":"https://github.com/caesarloo/simple-svn-client/issues"},"license":"MIT","homepage":"https://github.com/caesarloo/simple-svn-client","keywords":["svn","subversion","wrapper","child-process","gbk","encoding","conflict"],"repository":{"url":"git+https://github.com/caesarloo/simple-svn-client.git","type":"git"},"description":"SVN CLI wrapper for Node.js — Windows-safe decoding, typed parsing of status/update/diff/log, conflict guards, no fs dependency","maintainers":[{"name":"caesarloo","email":"qizhen.lu@hotmail.com"}],"readme":"# @caesarloo/simple-svn-client\n\n[English](#english) | [中文](#中文)\n\n---\n\n## English\n\nA pure-Node SVN client: wraps the system `svn` executable with Windows-safe output decoding, strict\nXML parsing, conflict guards and a typed domain layer. Shared by the\n[vault-svn](https://github.com/caesarloo/obsidian-svn) and `ai-pm-tool` Obsidian plugins, but usable\nin any Node.js project.\n\n### What it does\n\n- Wraps the system `svn` executable (no bundled binary), with automatic discovery of common install\n  locations and a cached candidate list.\n- Decodes Windows output safely: lossless UTF-8 first, GBK fallback, explicit override when needed —\n  Chinese file paths, commit messages and error text survive round-trips.\n- Parses `status` / `update` / `diff` / `log` output into typed structures, including the update\n  columns most wrappers drop: property updates, tree conflicts, and `C`/`G`/`R`/`E` statuses.\n- Detects unresolved conflicts **before** committing, from both `svn status` and the conflict markers\n  inside file content.\n- Reports failures as a typed `SvnError` with a `kind` (timeout / output limit / not-found / conflict /\n  auth …) instead of a single opaque exit code.\n\n### Install\n\n```bash\nnpm install @caesarloo/simple-svn-client\n```\n\nThe `svn` command line client must be installed and on `PATH` (or pointed to via `svnBinaryPath`).\nOn Windows, TortoiseSVN works if \"command line client tools\" is selected during installation;\nSlikSvn or VisualSVN Server binaries work too.\n\nVerify:\n\n```bash\nnode -e \"require('@caesarloo/simple-svn-client').execSvn(['--version'], process.cwd()).then(r => console.log(r.code, r.stdout.trim()))\"\n```\n\n### Usage\n\n```ts\nimport { SvnClient, runSync } from \"@caesarloo/simple-svn-client\";\n\nconst client = new SvnClient(\"<path-to-working-copy>\", {\n  // Optional: read file content yourself (keeps this package free of `fs`)\n  fileContentReader: async (relativePath) => myVaultAdapter.readBinary(relativePath),\n});\n\nif (await client.isAvailable()) {\n  const entries = await client.status();          // typed entries, sorted\n  const update = await client.update();           // includes `conflicts`\n  const diff = await client.diff(\"notes/a.md\");   // normalized line numbers\n}\n\n// Full sync: availability → base revision → update → collect changes\nconst sync = await runSync(\"<path-to-working-copy>\", \"requirements\");\nconsole.log(sync.ok, sync.message, sync.snapshot);\n\n// Conflict guard: refuse to commit while anything is unresolved\nawait client.assertNoConflicts(paths);            // throws SvnError(kind: \"conflict\")\nawait client.commit(paths, \"message\", { autoAdd: true, assertNoConflicts: true });\n```\n\nCommon operations: `status`, `update`, `diff`, `diffSummarize`, `log`, `logRange`, `cat`, `add`,\n`delete`, `revert`, `resolve`, `commit`, `diffFrontmatterFields`, `collectChanges`, `runSync`.\n\n### Configuration\n\n`new SvnClient(workingCopyPath, options?)` — every option is optional; the defaults suit Obsidian-style\nvaults.\n\n| Key | Default | Meaning |\n| --- | --- | --- |\n| `svnBinaryPath` | `\"\"` | Explicit `svn` path; empty means auto-discovery (configured path → bare `svn` → common install paths → `PATH`) |\n| `enableDebugLog` | `false` | Use `console` as the logger |\n| `logger` | `null` | Injectable logger (`debug`/`warn`/`error`); `null` keeps the client silent |\n| `timeoutMs` | `60000` | Per-command timeout; `0` disables the timeout |\n| `maxBufferBytes` | `64 MiB` | Output buffer limit per command |\n| `outputEncoding` | `\"auto\"` | `auto` \\| `utf8` \\| `gbk` \\| `gb18030` \\| `latin1`; set explicitly for cygwin/WSL svn builds |\n| `fileContentReader` | `null` | `(relativePath) => Promise<Buffer \\| null>`; used for unversioned-file previews and conflict-marker scans |\n| `signal` | – | `AbortSignal` to cancel running commands |\n| `normalizeDiff` | `false` | When `true`, collapses whitespace-only changes and Markdown separator edits (the 0.1.x default) |\n| `legacyStatusMapping` | `false` | Restores the 0.1.x status mapping (`external` → `added`, dropping rare statuses) |\n| `assertNoConflictsOnCommit` | `false` | Check conflicts before every `commit` |\n\n### Error handling\n\nWrite operations throw; read helpers (`cat`, `getRevision`, `getWorkingCopyRoot`, `isWorkingCopy`,\n`isAvailable`) return `null`/`false`. `execSvn` never throws — check the returned `code`\n(`127` = executable missing). Every thrown `SvnError` carries `stderr`, `code` and `kind`\n(`notFound` \\| `notWorkingCopy` \\| `conflict` \\| `auth` \\| `timeout` \\| `outputLimit` \\| `aborted` \\| `unknown`).\n\n### Boundaries\n\n- Does **not** bundle or download `svn`; the system client must be present.\n- Does **not** implement the Subversion protocol — it is a CLI wrapper, not a library binding.\n- Does **not** resolve conflicts automatically. `resolve()` defaults to `--accept working`, which\n  *keeps* the conflict markers in the file; only use it when you intend to keep the working version.\n- Does **not** read or write files by itself — the caller injects `fileContentReader`\n  (this is what keeps the package free of Node's `fs`, as required for Obsidian community review).\n- Does **not** merge revisions or rewrite history; it only exposes what `svn` reports.\n\n### License\n\nMIT\n\n---\n\n## 中文\n\n纯 Node 的 SVN 客户端：封装系统 `svn` 可执行文件，附带 Windows 安全解码、严格 XML 解析、冲突守卫\n与类型化领域层。由 [vault-svn](https://github.com/caesarloo/obsidian-svn) 与 `ai-pm-tool` 两个\nObsidian 插件共用，也可用于任意 Node.js 项目。\n\n### 它做什么\n\n- 封装系统 `svn` 可执行文件（不打包二进制），自动探测常见安装位置并缓存候选列表。\n- 安全解码 Windows 输出：无损 UTF-8 优先、GBK 回退、必要时可显式指定 —— 中文路径、提交信息与\n  报错文本都不会被改写。\n- 把 `status` / `update` / `diff` / `log` 的输出解析成类型化结构，并覆盖多数封装会丢掉的 update\n  状态列：属性更新、树冲突，以及 `C`/`G`/`R`/`E` 等状态。\n- 提交前检查未解决的冲突：同时查 `svn status` 与文件内容里的冲突标记（两重保险）。\n- 失败以类型化 `SvnError` 抛出，带 `kind`（超时 / 输出超限 / 未安装 / 冲突 / 认证 …），而不是\n  一个无法分诊的退出码。\n\n### 安装\n\n```bash\nnpm install @caesarloo/simple-svn-client\n```\n\n需要已安装 `svn` 命令行客户端并位于 `PATH`（或用 `svnBinaryPath` 指定）。Windows 上装 TortoiseSVN\n时需勾选 \"command line client tools\"，也可用 SlikSvn / VisualSVN Server 的二进制。\n\n验证：\n\n```bash\nnode -e \"require('@caesarloo/simple-svn-client').execSvn(['--version'], process.cwd()).then(r => console.log(r.code, r.stdout.trim()))\"\n```\n\n### 使用\n\n```ts\nimport { SvnClient, runSync } from \"@caesarloo/simple-svn-client\";\n\nconst client = new SvnClient(\"<工作副本路径>\", {\n  // 可选：由调用方读文件内容（本包因此不依赖 fs）\n  fileContentReader: async (relativePath) => myVaultAdapter.readBinary(relativePath),\n});\n\nif (await client.isAvailable()) {\n  const entries = await client.status();          // 类型化条目，已排序\n  const update = await client.update();           // 含 conflicts\n  const diff = await client.diff(\"notes/a.md\");   // 行号已对齐\n}\n\n// 完整同步：检测可用 → 取基线版本 → update → 收集变更\nconst sync = await runSync(\"<工作副本路径>\", \"产品需求\");\nconsole.log(sync.ok, sync.message, sync.snapshot);\n\n// 冲突守卫：有未解决冲突时拒绝提交\nawait client.assertNoConflicts(paths);            // 抛 SvnError(kind: \"conflict\")\nawait client.commit(paths, \"提交备注\", { autoAdd: true, assertNoConflicts: true });\n```\n\n常用操作：`status`、`update`、`diff`、`diffSummarize`、`log`、`logRange`、`cat`、`add`、`delete`、\n`revert`、`resolve`、`commit`、`diffFrontmatterFields`、`collectChanges`、`runSync`。\n\n### 配置\n\n`new SvnClient(workingCopyPath, options?)` —— 全部选项可选，缺省值适配 Obsidian 式 vault。\n\n| 键 | 缺省 | 含义 |\n| --- | --- | --- |\n| `svnBinaryPath` | `\"\"` | 显式指定 `svn` 路径；留空则自动探测（配置路径 → 裸名 `svn` → 常见安装路径 → `PATH`） |\n| `enableDebugLog` | `false` | 把 `console` 作为日志器 |\n| `logger` | `null` | 可注入日志器（`debug`/`warn`/`error`）；`null` 表示静默 |\n| `timeoutMs` | `60000` | 单条命令超时；`0` 表示不设超时 |\n| `maxBufferBytes` | `64 MiB` | 单条命令输出缓冲上限 |\n| `outputEncoding` | `\"auto\"` | `auto` \\| `utf8` \\| `gbk` \\| `gb18030` \\| `latin1`；cygwin/WSL 版 svn 建议显式指定 |\n| `fileContentReader` | `null` | `(relativePath) => Promise<Buffer \\| null>`；用于未版本化文件预览与冲突标记扫描 |\n| `signal` | – | `AbortSignal`，用于取消正在执行的命令 |\n| `normalizeDiff` | `false` | 设为 `true` 时归并「仅空白不同」与 Markdown 分隔线改动（0.1.x 的默认行为） |\n| `legacyStatusMapping` | `false` | 恢复 0.1.x 的状态映射（`external` → `added`，丢弃冷门状态） |\n| `assertNoConflictsOnCommit` | `false` | 每次 `commit` 前自动检查冲突 |\n\n### 错误处理\n\n写操作抛错；读取类方法（`cat`、`getRevision`、`getWorkingCopyRoot`、`isWorkingCopy`、`isAvailable`）\n返回 `null`/`false`。`execSvn` 从不抛错 —— 检查返回的 `code`（`127` = 可执行文件缺失）。\n抛出的 `SvnError` 带 `stderr`、`code` 与 `kind`\n（`notFound` \\| `notWorkingCopy` \\| `conflict` \\| `auth` \\| `timeout` \\| `outputLimit` \\| `aborted` \\| `unknown`）。\n\n### 边界（明确不做）\n\n- **不**打包或下载 `svn`；必须由系统提供命令行客户端。\n- **不**实现 Subversion 协议 —— 它是 CLI 封装，不是库级绑定。\n- **不**自动解决冲突。`resolve()` 默认 `--accept working`，会把冲突标记**留在文件里**；\n  只有确实打算保留工作区版本时才用它。\n- **不**自行读写文件 —— 由调用方注入 `fileContentReader`（这也是本包完全不依赖 Node `fs`、\n  满足 Obsidian 社区审核要求的原因）。\n- **不**做版本合并或历史改写；只如实反映 `svn` 报告的内容。\n\n### License\n\nMIT\n","readmeFilename":"README.md"}