Patchloom

io.github.patchloom由 GitHub 帳號 patchloom 發布v0.37.7更新於 Nov 6, 2026

Agent-safe structured edits: JSON/YAML/TOML/md/AST, dry-run, batch/tx. Not a filesystem MCP.

已驗證STDIO僅桌面檔案與儲存開發者工具

概覽

AI 產生的概覽

本機 MCP 伺服器,為 AI 助理提供結構化且安全的檔案編輯:解析器驅動的 JSON/YAML/TOML 與 Markdown 編輯、AST 程式碼操作,以及原子化的多檔案批次修改。

可以做什麼
  • 讀取、搜尋、列出、建立、移動、附加、前置與刪除檔案,並支援空白整理與復原
  • 依選擇器路徑設定、讀取、合併、移動、查詢與刪除 JSON、YAML、TOML、env、ini、properties 中的值,並保留註解
  • 依標題編輯 Markdown:取代章節、插入或更新項目、附加表格列、移動章節、檢查格式
  • 約 20 種語言的 AST 程式碼操作:列出、讀取、重新命名、取代、刪除、插入、移動、拆分、包裹符號,以及引用查找、影響分析、相依性擷取、結構差異與語法驗證
  • 套用統一 diff、Codex 修補文件、Aider 搜尋取代區塊與帶錨點的片段,並支援僅檢查不寫入
  • 以原子方式執行多操作計畫,支援回復、格式化與驗證步驟,並可在套用前說明計畫
適用情境
適合需要修改設定檔、文件與原始碼,並要求輸出合法、保留註解、減少往返次數的編碼助理。多檔案或結構化編輯最能發揮價值;README 也說明單一檔案讀取、簡單搜尋與純文字取代用原生工具更快。
執行需求
以本機程序透過 stdio 執行,可透過 cargo、npm/npx、Homebrew、Scoop 或預先編譯的執行檔安裝。未宣告帳號、API 金鑰或請求標頭。選用環境變數 PATCHLOOM_MCP_SURFACE 可啟用更精簡的核心工具集。僅限桌面端,無網頁版。
安裝前請注意
工具預設會寫入、移動與刪除檔案,但 apply=false 可只做檢查預覽,undo 可還原備份。交易計畫被視為可信輸入:其中的 format 與 validate 指令會透過主機 shell 執行,因此只執行可信的計畫。MCP 模式下路徑限制會拒絕工作區以外的存取。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Patchloom,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。

其他 MCP 客戶端

參照 儲存庫 中的啟動說明。

README

[Patchloom logo]

Patchloom

[CI] [Security] [crates.io] [Release] [License]

[Tests] [Coverage] [OpenSSF Best Practices] [OpenSSF Scorecard] [FOSSA Status]

[Docs] [VS Code Marketplace] [crates.io downloads]

One binary. Every platform. Structured file edits for AI agents.

Patchloom is a single-binary CLI that gives AI coding agents safe, structured file editing on any operating system. It edits JSON, YAML, and TOML by selector (not regex), preserves comments, understands code structure across 20 languages, batches multiple file edits into one tool call, and works identically on Linux, macOS, and Windows.

Not a generic filesystem MCP. Default MCP filesystem servers read/write files as text. Patchloom adds dry-run previews, parser-backed config and markdown edits, AST ops, multi-file batch/tx with undo, and stable error_kind peels for hosts. Full coding agents (Claude Code, Codex, Cursor) own the loop; Patchloom is the tool layer they (or a Rust embedder) call.

[Patchloom demo: 6 edits across 4 files in JSON, YAML, and TOML: one command, comments preserved]

bash
# Edit a YAML value by selector without breaking comments or formattingpatchloom doc set config.yaml database.port 5432 --apply
# Batch 6 file edits into a single tool callpatchloom batch --apply <<'EOF'doc.set package.json version "2.0.0"doc.set config.yaml app.version "2.0.0"doc.set config.toml project.version "2.0.0"replace README.md "1.0.0" "2.0.0"replace CHANGELOG.md "1.0.0" "2.0.0"file.create VERSION "2.0.0"EOF

Why Patchloom? | Install | Quick start | Commands | Comparison | When to use what | Architecture | Status


Why Patchloom?

The problem

AI agents edit files through tool calls. Each call is a round-trip back to the LLM. When a task touches config files, that process has three failure modes:

  1. Syntax corruption. The agent uses text replacement on JSON, YAML, or TOML and produces invalid output (mismatched braces, broken indentation, lost comments).
  2. Round-trip tax. Editing 6 files means 6 separate tool calls. Each one waits for the LLM to generate, execute, read the result, and plan the next call.
  3. Platform fragmentation. On Linux the agent uses sed, jq, grep. On Windows, none of those exist. The agent falls back to verbose PowerShell or makes errors with unfamiliar syntax.

How patchloom solves each one

ProblemHow patchloom solves it
Syntax corruptiondoc commands parse the file, change the value by selector path, and write valid output. Comments and formatting are preserved. No regex needed.
Round-trip taxbatch and tx combine N operations into 1 tool call. Six file edits become one command with atomic rollback on failure.
Platform fragmentationSingle static binary with zero dependencies. Same commands, same flags, same behavior on Linux, macOS, and Windows.

What changes with patchloom

Without patchloom (6 tool calls)

Agent: edit file 1  ─── tool call ───▶  15sAgent: edit file 2  ─── tool call ───▶  15sAgent: edit file 3  ─── tool call ───▶  15sAgent: edit file 4  ─── tool call ───▶  15sAgent: edit file 5  ─── tool call ───▶  15sAgent: edit file 6  ─── tool call ───▶  15s                                    Total: ~90s

With patchloom batch (1 tool call)

Agent: batch with  all 6 edits     ─── tool call ───▶  25s


                  5 round-trips saved                                    Total: ~25s

Key capabilities

CapabilityWhat it doesExample
Parser-backed editsEdit JSON/YAML/TOML by selector, preserving comments and formattingdoc set config.yaml db.port 5432 --apply
Batch N files in 1 callbatch and tx combine operations into one tool call with rollbackbatch --apply < ops.txt
Comment preservationYAML/TOML comments survive all edits, including array resizingdoc append config.yaml tags '"v2"' --apply
Heading-aware markdownEdit sections, tables, and bullets by heading, not line numbermd table-append README.md --heading "API" --row "| new | row |" --apply
AST-aware code opsList, rename, replace, and analyze symbols across 20 languagesast rename src/ --old old_name --new new_name --apply
Atomic rollbackstrict: true reverts every file if format or validate steps failtx plan.json --apply
MCP serverExpose all operations as structured MCP tool callspatchloom mcp-server
Optional CLI sandboxReject ../ / absolute path escapes from --cwd on reads and writes (off by default; MCP always on)patchloom --cwd <ws> --contain search … / create … --apply
Cross-platformIdentical behavior on Linux, macOS, Windows. No sed, jq, grep required.Same binary everywhere

When to use patchloom vs native tools

Patchloom is not a replacement for all file operations. Its instructions tell agents exactly when to use it and when native tools are faster:

TaskUse patchloom?Why
Edit a JSON/YAML/TOML value by selectorYesParser guarantees valid output, preserves comments
Edit 3+ files in one taskYesbatch/tx eliminates round-trips
Append a row to a markdown tableYesHeading-aware, no line number guessing
Read a single fileNoNative read_file is faster
Simple text searchNoNative grep is faster
Single-file text replacementNoNative search_replace is faster

Correctness over speed

Patchloom is not faster than native tools for simple, single-file edits. Use native tools for those. But native text replacement cannot safely edit structured files: a sed on YAML can corrupt indentation, strip comments, or produce invalid syntax. doc set parses the file, changes the value by selector, and writes valid output. That guarantee is the point.

Where patchloom is faster is multi-file batching. Six file edits via native tools means six round-trips to the LLM. One batch call does the same work in a single round-trip.

Benchmark details (Claude Opus 4 via Grok Build, 11 tasks)
Task                    PL-CLI    MCP    Native──────────────────────  ──────  ──────  ──────search                   18.5s   12.7s   13.9s  ◀ ~samereplace                  36.1s   26.6s   26.1s  ◀ ~samedoc_set                  30.9s   16.9s   13.7s  ◀ native fastestmd_table                 15.5s   13.5s   15.3s  ◀ MCP fastesttx_multi_file            41.4s   28.5s   22.9s  ◀ native fastestbatch_6_files            50.6s   46.6s   30.3s  ◀ native fastestbatch_mixed_ops          24.7s   13.6s   20.9s  ◀ MCP fastestyaml_comment_preserve    18.1s   11.6s   16.1s  ◀ MCP fastestmd_insert                15.0s   11.7s   15.7s  ◀ MCP fastestfile_ops                 26.0s   16.6s   17.2s  ◀ ~sametidy                     45.0s   30.3s   41.7s  ◀ MCP fastest──────────────────────  ──────  ──────  ──────TOTAL                   321.9s  228.5s  233.8s

MCP mode wins overall (228.5s vs 233.8s native) because structured tool calls skip shell syntax construction entirely. MCP wins 5/11 tasks; native wins 3/11; 3 are ties. CLI mode is always slowest due to shell construction overhead.


Install

Prefer channels that track each GitHub Release (Homebrew, Scoop, crates, npm, Releases). On Windows, Scoop is recommended. winget (Patchloom.Patchloom) is published per release and is usually current after Microsoft's publish pipeline (winget source update if search is stale). Chocolatey often lags while community moderation runs.

bash
# Homebrew (macOS/Linux)brew install patchloom/tap/patchloom
# crates.io (requires Rust 1.95+, includes MCP server)cargo install patchloom
# npm / npx (downloads the platform binary from GitHub Releases)npx patchloom --version# or: npm install -g patchloom
powershell
# Scoop (Windows; recommended Windows channel)scoop bucket add patchloom https://github.com/patchloom/scoop-bucketscoop install patchloom/patchloom

Pre-built binaries for Linux, macOS, and Windows are on the Releases page. See Installation for shell installer scripts, source builds, shell completions, and winget / Chocolatey notes.

  • MCP Registry name: mcp-name: io.github.patchloom/patchloom

Editor extension

Install the companion extension for VS Code, Cursor, Windsurf, or VSCodium:

The extension auto-discovers the CLI (or installs it for you), generates AGENTS.md, configures MCP servers, and adds Quick Actions to the command palette. See the Editor Extension guide for details.

Quick start

1. Set up your project

bash
patchloom init

This creates AGENTS.md in a new project or appends the rules to an existing agent instructions file, offers shell completions, and detects MCP configuration opportunities. Pass -y to skip confirmation prompts.

If you only want the rules text:

bash
patchloom agent-rules >> AGENTS.md
# Or tailor the output:patchloom agent-rules --mode mcp >> AGENTS.md            # MCP-only (no CLI examples)patchloom agent-rules --platform windows >> AGENTS.md    # Windows-only syntax

If .vscode/ or .cursor/ exists, init also prints ready-to-copy .vscode/mcp.json or .cursor/mcp.json snippets.

Your AI agent reads AGENTS.md and learns when to use patchloom vs native tools.

2. Edit a config file safely

bash
# Parser-backed: changes the value, preserves comments and formattingpatchloom doc set config.yaml database.port 5432 --apply

3. Batch multiple edits into one call

bash
patchloom batch --apply <<'EOF'doc.set config.json version '"2.0.0"'md.upsert_bullet AGENTS.md "Rules" "- Always test"replace src/main.rs "v1" "v2"EOF

Values are JSON-first: unquoted 2.0 becomes a number. Force a string with nested quotes as above (Unix shells).

On Windows PowerShell (no bash heredoc), write ops to a file:

powershell
@'doc.set config.json version "\"2.0.0\""md.upsert_bullet AGENTS.md "Rules" "- Always test"replace src/main.rs "v1" "v2"'@ | Set-Content ops.txt -Encoding utf8patchloom batch --apply ops.txt

Or use a JSON plan with format and validate lifecycle:

json
{  "version": 1,  "operations": [    { "op": "doc.set", "path": "config.json", "selector": "version", "value": "2.0.0" },    { "op": "md.upsert_bullet", "path": "AGENTS.md", "heading": "Rules", "bullet": "- Always test" },    { "op": "replace", "path": "src/main.rs", "old": "v1", "new": "v2" }  ],  "format": [{ "cmd": "cargo fmt --all" }],  "validate": [{ "cmd": "cargo test", "required": true }]}
bash
patchloom tx plan.json --apply

tx plans are trusted input. format and validate run their cmd fields through the host shell (sh -c on Unix, cmd /C on Windows), so only run plans you trust.

4. Or use MCP for structured tool calls (no shell syntax)

After installing with MCP support, start the server:

bash
PATCHLOOM_MCP_SURFACE=core patchloom mcp-server

MCP-capable agents call patchloom tools directly as structured JSON, with no shell quoting or command construction. The agent sends {"path": "config.json", "selector": "version", "value": "2.0"} instead of building patchloom doc set config.json version '"2.0"' --apply.

Coding agents: set PATCHLOOM_MCP_SURFACE=core for a 12-tool pack (list_files, search/read/replace, doc/md, execute_plan, operation_schema, server_info) so schemas stay small. Product default remains full inventory when the env is unset. Prefer Patchloom MCP alone for list+edit (no second filesystem MCP). See the MCP setup guide for Cursor / Claude / Codex paste configs and the full security model.

Using VS Code, Cursor, or Windsurf? The Patchloom extension handles setup automatically: it installs the binary, runs init, and configures your editor's MCP settings.

As a Rust library

Host teams embedding Patchloom instead of a private edit stack: see the embedder host case study (for_agent, peels, fuzzy refuse, apply_fragment, path-only ops).

Add patchloom as a dependency (omit CLI/MCP/AST with default-features = false):

toml
[dependencies]patchloom = { version = "0.37.7", default-features = false } <!-- x-release-please-version -->
rust
use patchloom::api::{self, ApplyMode, ReplaceOptions, edit_error_kind, EditErrorKind};use std::path::Path;
// Replace text (preview only, no disk write)let result = api::replace_text(    Path::new("src/config.rs"),    "old_value", "new_value",    &ReplaceOptions::default(),    ApplyMode::Preview,    None,)?;println!("{}", result.diff);
// Agent hosts: shared primary+fallback policy (unique, require_change, fuzzy @ 0.90)let opts = ReplaceOptions::for_agent();// Fail closed: zero matches become EditErrorKind::NoMatchmatch api::replace_in_content("body", "missing", "x", &opts) {    Ok(r) => println!("changed={}", r.changed),    Err(e) => assert_eq!(edit_error_kind(&e), Some(EditErrorKind::NoMatch)),}// for_agent auto-refuses over-wide fuzzy; custom options use api::fuzzy_span_suspicious// Buffer multi-op + host write: api::refuse_batch_if_suspicious_fuzzy after apply_content_edits// Invalid options and bad regex peel InvalidInput (CLI/tx typed errors included)match api::replace_in_content("body", "", "x", &ReplaceOptions::default()) {    Err(e) => assert_eq!(edit_error_kind(&e), Some(EditErrorKind::InvalidInput)),    Ok(_) => panic!("empty pattern must error"),}
// Set a value in a JSON fileapi::doc_set(    Path::new("config.json"),    "version",    serde_json::json!("2.0"),    ApplyMode::Apply,    None,)?;
// Multi-doc YAML: merge into document 0 (selector None = root only)api::doc_merge(    Path::new("stream.yaml"),    serde_json::json!({"env": "prod"}),    ApplyMode::Apply,    None,    Some("0"),)?;
// Sole-path text load: binary → EditErrorKind::Binary; invalid UTF-8 → InvalidEncodinglet _text = api::load_text(Path::new("notes.md"))?;

All API types are Send + Sync. Beyond the api module, utility modules are also public: containment (workspace path guarding), exec (shell command execution), files (file-walking, load_text_strict, binary detection), backup (restore_path_from_latest_backup for post-Apply validate/revert), and write (atomic file writes with policy transformations). Library users needing temp dirs (e.g. agents) can use PathGuard::builder(cwd).allow_temp_directory() (handles /tmp on macOS); see the containment and api module rustdocs. Multi-doc bare keys and wrong-root merges peel to EditErrorKind::TypeError via edit_error_kind. Create/rename dest-exists peels to EditErrorKind::AlreadyExists (or api::is_already_exists / api::error_kind_str for CLI-stable "already_exists" strings). Fine-grained kinds also have bool peels (is_not_found, is_conflicts, is_changes_detected, is_type_error, is_format_failed, is_guard_rejected, is_invalid_input, is_no_match, is_ambiguous) matching edit_error_kind.

Replace fail-closed / shell-token options: CLI replace --require-change and --command-position (also plan/MCP fields and ReplaceOptions on the library). Agent hosts: ReplaceOptions::for_agent() on primary and fallback replace paths (auto span refuse); custom options still call api::fuzzy_span_suspicious / FuzzySpanPolicy after fuzzy Apply; buffer multi-op hosts call api::refuse_batch_if_suspicious_fuzzy after apply_content_edits (#2064). Library-only AST mutators: ast_rename / ast_replace_in_symbol / ast_rename_batch (feature ast + files), and FunctionSigEdit::parse_rust. Ordered host onboarding: Embedder host checklist (#2009). Full surface: docs.rs/patchloom.

Getting started

ResourceWhat you'll learn
InstallationInstall options and shell completions
Core conceptsWrite modes, transaction plans, exit codes
MCP setupConfigure patchloom as an MCP server for your agent
Editor extensionVS Code, Cursor, Windsurf, and VSCodium integration
Quickstart5-minute walkthrough
ReferenceEvery command, operation, and mode
ExamplesTransaction plan templates

Commands

Agent-optimized (these are faster or safer than native tools)

CommandWhat it doesWhen to use
batchLine-oriented multi-file edits in 1 callEditing 3+ files with simple syntax
txJSON plan with format/validate lifecycleComplex multi-file edits with rollback
docParser-backed JSON/YAML/TOML editsChanging config values without breaking syntax
mdHeading-aware markdown editsUpdating tables, sections, bullets in docs
astAST-aware symbol operations (20 languages)Renaming identifiers, listing symbols, impact analysis
patchApply unified diffs with stale detectionReplaying patches safely
tidyText-file whitespace and newline normalizationCI checks for text tidiness
mcp-serverMCP protocol serverMCP-capable agents (no shell syntax)

General-purpose (also useful in scripts and CI)

CommandDescription
searchFast literal or regex search across text files (supports --glob/--exclude/--ignore-file for layered custom ignore files, --max-results, -C context, etc.)
replaceMechanical string replacement across text files with diff preview
apply-fragmentFreeform fragment with required anchors (MorphLLM-style markers stripped; no cloud merge)
appendAppend content to an existing file
prependPrepend content to an existing file
createCreate a new file with content
deleteDelete a file
renameMove (rename) a file
readRead file contents with optional line range
statusShow which files have uncommitted changes
explainSummarize a tx plan in plain English
undoRestore files from a backup created by --apply
completionsGenerate shell completions (bash, zsh, fish, elvish)
initSet up patchloom in a project (agent rules, completions, MCP)
schemaExport operation schemas with tier filtering and system prompts
agent-rulesGenerate agent instructions for your project

How patchloom compares

ToolStrengthWhere patchloom differs
jqJSON query/transformpatchloom also handles YAML, TOML, env, ini, properties, and markdown; batches across files; preserves comments
yqYAML/JSON query/transformpatchloom preserves YAML comments via CST editing; also edits TOML, env, ini, properties, and markdown; adds batching and atomic transactions
daselMulti-format get/setpatchloom doc covers JSON, YAML, TOML, env, ini, and properties. It adds batching (N edits in 1 call), atomic rollback, and a format/validate lifecycle. XML, HCL, CSV, and KDL stay with dasel or yq
sdRegex find/replacepatchloom adds parser-backed structured edits; batching; never produces invalid JSON/YAML
combyStructural code patternspatchloom targets config files and agent workflows, not source code pattern matching

The key difference: patchloom is designed for AI agent workflows. One batch or tx call replaces N sequential tool calls, cutting round-trips and eliminating partial-failure states.

vs agent-native editing tools

The table above compares patchloom to human CLI tools. But agents already have built-in editing: Claude Code's edit_file, Cursor's apply, Grok Build's search_replace, Aider's /code blocks. Why add patchloom on top?

Agent-native tools use text matching. They find a block of text and replace it. This works for source code but fails on structured config files:

Agent uses search_replace on YAML

yaml
database:  # Production settings  host: db.prod.internal  port: 5432  # PostgreSQL default  pool_size: 10

The agent replaces port: 5432 with port: 5433. Result depends on implementation. Many agents lose the inline comment, break indentation, or fail to match because of surrounding context changes.

Agent uses patchloom doc set

bash
patchloom doc set config.yaml \  database.port 5433 --apply

The YAML parser changes the value at the selector path. Comments, indentation, key ordering, and all other formatting are preserved. The output is always valid YAML.

Limitation of agent-native toolsHow patchloom addresses it
Comment destructionCST-level YAML/TOML editing preserves all comments
One file per tool callbatch/tx edit N files in 1 call (6.7x faster in benchmarks)
No rollbacktx with strict: true reverts all files if validation fails
Platform-dependentSame binary and syntax on Linux, macOS, Windows
Stale context riskpatch apply uses fuzz matching to handle context drift

When to keep using native tools: Single-file reads, simple text search, single-file text replacement where comments don't matter. Patchloom's agent-rules tell agents exactly when to use each approach.

When to use what

NeedPreferPrefer something else
JSON, YAML, TOML, env, ini, or properties by pathPatchloom docGeneric filesystem MCP / blind text replace
Multi-doc YAML streamPatchloom selectors (0.key)Bare key on stream root
Structural code pattern searchast-grepText-only grep for shapes
Identifier rename in codePatchloom ast renameFuzzy text replace for symbols
Multi-file atomic apply + undoPatchloom batch / txN sequential shell edits
Freeform snippet with known anchor (after/before/old)Patchloom apply-fragment (strips Morph-style // ... existing code ... markers)Whole-file rewrite or guessing placement
Freeform snippet without anchors (cloud model merge)Morph Fast Apply or similarPatchloom (anchor-less Morph merge is a non-goal)
Full agent productClaude Code / Codex / CursorPatchloom alone

Longer write-ups: Comparisons · Embedder host checklist · MCP setup

Library hosts: Embedder host checklist: dual-path ReplaceOptions::for_agent() (primary + fallback, includes refuse_suspicious_fuzzy), peels via edit_error_kind / is_* / is_fuzzy_span_suspicious with #[non_exhaustive] _ arm, multi-op ContentEditsResult.op_honesty + refuse_batch_if_suspicious_fuzzy after buffer multi-op (#2064), plan/tx widest matched_text, optional apply_content_edits_to_file_with_span_policy. Custom options still use api::fuzzy_span_suspicious / FuzzySpanPolicy after fuzzy Apply.

Context budget: line-range read, search --count / --files-with-matches, one batch/tx, --jsonl for large streams.

How it works with your AI agent

Two integration modes, same capabilities:

mermaid
flowchart LR    subgraph CLI["CLI mode (any agent)"]        direction TB        A["patchloom agent-rules >> AGENTS.md"] --> B["Agent reads AGENTS.md"]        B --> C{"What kind of edit?"}        C -->|Simple edit| D["Native tool (faster)"]        C -->|Config edit| E["patchloom doc (safer)"]        C -->|Markdown edit| F["patchloom md (smarter)"]        C -->|Multi-file edit| G["patchloom batch (batched)"]    end
    subgraph MCP["MCP mode (MCP-capable agents)"]        direction TB        H["patchloom mcp-server"] --> I["Agent discovers tools via MCP"]        I --> J["Structured JSON tool calls"]        J --> K["No shell syntax needed"]    end

Status

5900+ tests across 25 commands. Tested with Grok 4.3, GPT-5.4, and Claude Opus 4.6.

ComponentStatus
CLIInstall from crates.io, Homebrew, Scoop, npm (npx patchloom), or GitHub Releases. Also on winget (Patchloom.Patchloom; usually current after Microsoft publish) and Chocolatey (community moderation often lags GitHub).
MCP serverOfficial MCP Registry name io.github.patchloom/patchloom (stdio; crates.io / npm packages; see server.json). Local MCPB for Smithery / desktop hosts: make pack-mcpb (mcpb/). Glama listing (glama.json; keep description aligned with server.json, see MCP setup)
Editor extensionPublished on VS Code Marketplace and Open VSX

Full command reference

Every command, flag, transaction operation, and exit code is documented in the Command Reference (also available at docs/reference/README.md).

License

Licensed under either of:

at your option.

Contributing

See CONTRIBUTING.md.

For local verification before opening a pull request, run make check. It covers the main Linux test and lint gate: formatting, clippy, unit tests (including feature-matrix jobs), integration tests, PTY tests, release-notes structure, test hygiene, generated-doc freshness (check-patchloom-md, check-readme), server-json-test, verify-homebrew-version-test, packaging-script unit tests (scoop-manifest-test, chocolatey-package-test, pack-mcpb-test, force-release-version-test), workflow-sanity-test, apply-release-notes-test, and dco-check-test. It is not every GitHub required check: audit, deny, and Windows stay in GitHub Actions. While iterating locally, make check-fast is the same except it skips only check-patchloom-md (it still runs check-readme, server-json-test, verify-homebrew-version-test, the packaging-script tests, workflow-sanity-test, apply-release-notes-test, and dco-check-test).

Pull request titles must use one Conventional Commits prefix (feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert; no commas or +). See CONTRIBUTING.md.

All commits must be signed off with git commit -s.

Agent integration tests

make agent-test runs 19 pytest scenarios that verify AI agents correctly use patchloom when given instructions. make bench-agent runs 3-way benchmarks (CLI vs MCP vs native) across 11 tasks. Use MODEL=X to switch models and RUNS=N for variance reduction. Requires an LLM API key. Not part of make check. See tests/agent/README.md for details.

Security

For current security reporting guidance, see SECURITY.md.

來源:README.md,提交 8d9fdbe

工具

66

append_file

Append content to an existing file. Inserts the file's line ending first when the file does not already end with one. Example: {"content":"#[test]\nfn new_test() {}\n","path":"tests/test.rs"}

輸入參數path必填content必填agent_presetexpected_sha256

apply_fragment

Constrained freeform fragment apply (#2018). Strips Morph-style // ... existing code ... marker lines from fragment, then inserts or replaces at a required unique anchor (exactly one of after, before, old). Fail-closed: no anchor-less Morph model merge. Prefer for lazy-snippet agent output when anchors are known; use replace/ast for precise edits. Morph-class freeform fragment with required placement (exactly one of after/before/old). Lazy // ... existing code ... lines are stripped; no model merge without anchors (#2018). Example: {"fragment":"// ... existing code ...\n bar();\n// ... existing code ...\n","path":"src/lib.rs","after":"fn foo() {"}

輸入參數oldpath必填afterbeforeuniquefragment必填instructionagent_presetexpected_sha256

apply_patch

Apply a unified diff, a Codex *** Begin Patch document, or an Aider SEARCH/REPLACE / DiffFenced document. Default apply=true writes (same as CLI patch apply --apply). Set apply=false for check-only preview (CLI patch check; disk is unchanged). The diff parameter is the full unified diff text, a *** Begin Patch ... *** End Patch envelope (Add/Update/Delete/Move), or <<<<<<< SEARCH / ======= / >>>>>>> REPLACE blocks (dest path above ------- after SEARCH). SEARCH/REPLACE is unique by default (multi-match is ambiguous, no write); set replace_all=true to update every exact match. Empty-hunk +++ /dev/null (git deleted file mode, no hunks) unlinks. A hunked delete applies minus lines first; leftover bytes rewrite the file (preview --diff). Stale minus lines are ambiguous and the file is not removed; regenerate minus lines or use file.delete for path-only unlink. Use on_stale=merge for three-way merge on stale unified-diff context; allow_conflicts=true writes conflict markers. Never commit files containing conflict markers. Example: {"diff": "--- a/file.txt\n+++ b/file.txt\n@@ -1 +1 @@\n-old\n+new", "on_stale": "fail"}

輸入參數diff必填applystricton_stalereplace_allallow_conflicts

ast_delete_symbol

Delete a whole symbol span, including leading doc comments and attributes, and collapse surrounding blank lines to one. Deletes the full symbol span (docs and attributes included) and collapses surrounding blank lines. Example: {"symbol":"unused_helper","path":"src/lib.rs"}

輸入參數langpath必填symbol必填agent_presetexpected_sha256

ast_deps

Extract import/dependency statements from source files. Supports Rust, Python, JS/TS, Go, Java, C/C++, Ruby, PHP. Use reverse=true to find what imports a file. Example: {"path": "src/main.rs"}

輸入參數langpath必填reverse

ast_diff

Structural diff between two versions of a file. Shows added, removed, and modified symbols (not line-level diff). Compares against git refs. Example: {"path": "src/lib.rs", "from": "HEAD~1"}

輸入參數tofromlangpath必填

ast_extract_to_file

Extract a symbol (module, function, struct) to a separate file. For modules with unwrap=true, content is un-indented. Example: {"source": "src/lib.rs", "symbol": "tests", "target": "src/lib_tests.rs", "replacement": "mod tests;", "prepend": "use super::*;"}

輸入參數langforcesource必填symbol必填target必填unwrapprependreplacementupdate_importsnew_module_pathold_module_path

ast_group

Group symbols into a named module within a file. Creates the module if it doesn't exist, or appends to it. Example: {"path": "src/tests.rs", "module": "line_endings", "symbols": ["test_crlf", "test_lf"], "preamble": "use super::*;"}

輸入參數langpath必填module必填symbols必填positionpreamble

ast_impact

Transitive impact analysis: what symbols are affected by changing a given symbol. Traces the reference graph to find all direct and indirect dependents. Example: {"symbol": "parse_config", "path": "src/", "depth": 3}

輸入參數path必填depthsymbol必填

ast_imports

Manage import/use statements: add (idempotent), remove, deduplicate. With no mutation args, lists existing imports. Example: {"path": "src/main.rs", "add": ["use std::collections::HashMap;"]}

輸入參數addlangpath必填deduperemove

ast_insert

Insert code at a structurally-aware position: inside a module/impl/struct (at start or end), or after/before a named symbol. Indentation is auto-detected. Example: {"path": "src/lib.rs", "content": "fn new_fn() {}", "after": "existing_fn"}

輸入參數langpath必填afterbeforeinsidecontent必填position

ast_list

List symbol definitions (functions, classes, structs, enums, methods, etc.) in a file or directory. Supports 20 languages. Example: {"path": "src/"} or {"path": "main.py", "kind": "function,class"}

輸入參數kindlangpath必填

ast_map

Generate a ranked repository map using PageRank over the symbol reference graph. Shows the most important symbols with token-budget-aware output. Example: {"path": "src/", "max_tokens": 2048}

輸入參數path必填boostfocusmax_tokens

ast_move

Move symbols between files. Removes from source, inserts into target (creating it if needed). Example: {"path": "src/big.rs", "target": "src/helpers.rs", "symbols": ["helper_fn"], "target_prepend": "use super::*;"}

輸入參數langpath必填target必填symbols必填positiontarget_prependupdate_importsnew_module_pathold_module_path

ast_read

Read a specific symbol's source code by name from a file. Uses AST parsing to find the exact definition. Example: {"path": "src/main.rs", "symbol": "run"}

輸入參數langpath必填symbol必填context

ast_refs

Find all references to a symbol across files using AST analysis. Distinguishes definitions from references. Example: {"symbol": "process_data", "path": "src/"}

輸入參數langpath必填symbol必填include_def

ast_rename

Rename identifiers across files using AST-aware renaming (skips strings and comments). Example: {"path": "src/", "old": "process_data", "new": "transform_data"}

輸入參數new必填old必填langpath必填

ast_reorder

Reorder symbols within a file or scope by name, kind, or custom order. Example: {"path": "src/lib.rs", "order": "alphabetical"} or {"path": "src/lib.rs", "order": ["Struct", "impl Struct", "helper"], "inside": "mod tests"}

輸入參數langpath必填order必填inside

ast_replace

Replace text only within a specific symbol's body using AST scoping. Precise: only changes code inside the named symbol, leaving everything else untouched. Example: {"path": "src/lib.rs", "symbol": "parse_config", "old": "unwrap()", "new": "expect(\"parse failed\")"}

輸入參數new必填old必填langpath必填regexsymbol必填

ast_replace_symbol

Replace a whole symbol span, including leading doc comments and attributes, with new source re-indented to the symbol column. Replaces the full symbol span (docs and attributes included). Example: {"content":"fn default_timeout() -> u64 { 60 }","path":"src/lib.rs","symbol":"default_timeout"}

輸入參數langpath必填symbol必填content必填agent_presetexpected_sha256

ast_rewrite_signature

Rewrite a function signature with structured fields (visibility, parameters, return_type) or a full new_signature string. Multi-language via tree-sitter. Example: {"path": "src/lib.rs", "old": "process", "parameters": "(x: i32)", "return_type": "-> String"}

輸入參數old必填langpath必填parametersvisibilityreturn_typenew_signature

ast_split

Split a file into multiple target files by distributing symbols. Atomic: all targets succeed or all roll back. Example: {"source": "src/big.rs", "targets": [{"path": "src/types.rs", "symbols": ["Config", "Mode"], "prepend": "use super::*;"}], "keep_in_source": ["main"], "source_suffix": "mod types;"}

輸入參數langsource必填targets必填source_prefixsource_suffixkeep_in_sourcerequire_exhaustive

ast_validate

Validate syntax of source files. Returns parse errors with line numbers. Supports 20 languages. Example: {"path": "src/main.rs"}

輸入參數langpath必填

ast_wrap

Wrap existing code in a structural block (module, impl, cfg, etc.). Specify symbols by name or a line range. Example: {"path": "src/lib.rs", "symbols": ["helper_fn", "HelperStruct"], "wrapper": "mod helpers"}

輸入參數langpath必填linessymbolswrapper必填preamble

batch_replace

Replace the same text across multiple files in one call. Engine staging is atomic for applied writes (all written files succeed or none change). Pattern misses are soft by default: matching files still apply and total misses appear in refused[]; set require_change=true to fail the whole batch if any file has no match. Canonical field is files (array); singular file is accepted as an alias for one path. Optional fuzzy enables similarity fallback; when exact old is absent, refuse by default unless allow_absent_old=true (#1758). JSON reports match_mode (exact/fuzzy/anchored), optional match_score, optional matched_text, match_count per change and aggregate (#1674). Example: {"files": ["Cargo.toml", "README.md"], "old": "0.1.0", "new": "0.2.0"}

輸入參數new必填old必填filefilesfuzzyregexstrictif_existsmultilineword_boundaryrequire_changemin_fuzzy_score另有 3 個

batch_tidy

Fix whitespace in multiple files in one call: trims trailing spaces and ensures final newline. Atomic: all files succeed or none change. Canonical field is files (array); singular file is accepted as an alias for one path. Example: {"files": ["src/main.rs", "src/lib.rs"]}

輸入參數filefilesstrict

create_file

Create a new file with specified content. Fails if the file exists unless force=true. Example: {"content":"{\"version\": \"1.0\"}","path":"config.json"}

輸入參數path必填forcecontent必填agent_presetexpected_sha256

delete_file

Delete a file. Default fails with not_found if the path is missing. Set if_exists=true to soft-skip a missing file (no write, success). Set if_exists=true to soft-skip when the file is missing. Example: {"path":"tmp/scratch.txt"}

輸入參數path必填if_existsagent_presetexpected_sha256

doc_append

Append a value to an array at a selector path. Example: {"value":"new_item","path":"data.json","selector":"items"}

輸入參數path必填value必填selector必填agent_presetexpected_sha256

doc_delete

Delete a value at a selector path in a JSON, YAML, or TOML file. CLI --json and MCP/tx success include changed and removed (0 on missing key; exit 0 / ok is idempotent). Example: {"selector":"deprecated_key","path":"config.json"}

輸入參數path必填selector必填agent_presetexpected_sha256

doc_delete_where

Delete array elements matching a key=value predicate via --predicate (CLI) or the predicate field (plans). For scalar arrays use .=x, _=x, or value=x. Different from doc.update, which filters inside the selector path. CLI --json and MCP/tx success include changed and removed (0 when no elements match; exit 0 / ok is idempotent). For object arrays: predicate='role=admin'. For simple arrays: predicate='_=value'. Nested paths: predicate='settings.theme=dark'. Example: {"predicate":"value=a","path":"config.toml","selector":"tags"}

輸入參數path必填selector必填predicate必填agent_presetexpected_sha256

doc_diff

Compare two structured files (JSON, YAML, or TOML) and show differences. Example: {"file_a": "old.json", "file_b": "new.json"}

輸入參數file_a必填file_b必填

doc_ensure

Set a value only if the selector path does not already exist. Example: {"value":30,"path":"config.json","selector":"timeout"}

輸入參數path必填value必填selector必填agent_presetexpected_sha256

doc_get

Read a value from a JSON, YAML, or TOML file by selector path. Example: {"path": "package.json", "selector": "version"}

輸入參數path必填selector必填

doc_merge

Deep-merge a JSON object into a document root, or into a selector path (e.g. multi-doc YAML `0` / `[0]`). Example: {"value":{"database":{"host":"localhost","port":5432}},"path":"config.yaml"}

輸入參數path必填value必填selectoragent_presetexpected_sha256

doc_move

Move a value from one selector path to another within the same file. Example: {"to":"new_key","path":"config.json","from":"old_key"}

輸入參數to必填from必填path必填agent_presetexpected_sha256

doc_prepend

Prepend a value to the beginning of an array at a selector path.

輸入參數path必填value必填selector必填agent_presetexpected_sha256

doc_query

Query a JSON, YAML, or TOML file. Actions: "has" (exists, true/false), "keys" (keys of one object; omit selector for `.`; e.g. database or items[0]), "len" (length of one object or array; omit selector for `.`; e.g. items or database), "select" (filter via selector predicates, e.g. users[role=admin]; no separate predicate field), "flatten" (leaf paths). keys need one object; len needs one object or array; items[*] is fail-closed ambiguous (use items[0] / items[1]). Example: {"action": "has", "path": "config.json", "selector": "database.host"}

輸入參數path必填action必填selector

doc_set

Set a value at a single concrete selector path in a JSON, JSONC, YAML, TOML, .env, .ini, or .properties file (keys and indexes such as server.port or items.0.v). Parser-backed; output is always valid. Not for predicates or wildcards (items[name=foo].v, items[*].v); use doc.update for multi-match writes. Default creates a missing key and fails with not_found if the file is missing. Set if_exists=true to soft-skip when the file is missing or the selector is not present (does not create the key). Single concrete path only (keys/indexes). For selector predicates or wildcards (items[name=foo].v, items[*].v) use doc_update / plan doc.update. Set if_exists=true to soft-skip a missing file or missing selector (does not create the key). Example: {"value":"2.0.0","path":"package.json","selector":"version"}

輸入參數path必填value必填strictselector必填if_existsagent_presetexpected_sha256

doc_update

Set a new value at every location matching a selector. Use wildcards (items[*].enabled) or selector predicates (items[name=foo].v). Not a separate --where flag; the filter is part of the selector string. Multi-match writes: use selector predicates or wildcards (items[name=foo].v, items[*].enabled). Prefer this over doc_set when filtering by field. Example: {"value":7,"path":"config.toml","selector":"items[name=a].v"}

輸入參數path必填value必填selector必填agent_presetexpected_sha256

execute_plan

Execute a multi-step transaction plan atomically (MCP equivalent of `patchloom tx`). Provide an inline plan object or a plan_path. plan requires version and operations (alias ops). Each operation requires string op. Other plan and op fields are allowed. Call operation_schema with the op name for that operation's fields. Optional plan.cwd must be a relative path under the server workspace. Absolute plan.cwd and ../ escapes are rejected. Do not set both plan.cwd and for_each. plan.format/validate are ignored on MCP. Example: {"plan": {"version": 1, "operations": [{"op": "doc.set", "path": "app.yaml", "selector": "name", "value": "x"}]}}

輸入參數planstrictplan_pathagent_preset

explain_plan

Explain a tx plan in structured JSON (same as CLI `patchloom explain --json`). Provide inline plan text (`plan`) or a plan file (`path`). Format hint optional (json/yaml/toml). Read-only: does not execute the plan. Example: {"plan": "{\"version\": 1, \"operations\": [{\"op\": \"file.create\", \"path\": \"a.txt\", \"content\": \"x\"}]}"}

輸入參數pathplanformat

fix_whitespace

Normalize whitespace in a file or directory. A directory path expands with the same ignore-aware walker as CLI tidy fix (one write per text file). When op fields are omitted, defaults match CLI tidy fix (trim trailing whitespace + ensure final newline; mixed line endings flatten to the dominant style; uniform CRLF/LF stays). Set normalize_eol to keep to opt out of flattening. Precedence: defaults → plan write_policy → op fields. Plan write_policy is not re-applied at commit for paths last written by tidy.fix so op fields stick (#1840, #1847). Defaults: trim trailing whitespace and ensure final newline when those fields are omitted. Example: {"trim_trailing_whitespace":true,"path":"src/main.rs","ensure_final_newline":true}

輸入參數path必填linesdedentindentagent_presetnormalize_eolcollapse_blanksexpected_sha256ensure_final_newlinetrim_trailing_whitespace

git_status

Show uncommitted file changes vs git HEAD. Returns lists of modified, created, and deleted files. Omits .patchloom/ backup paths from --apply undo sessions. No parameters required.

無需輸入參數。

list_files

List files under the workspace (or given roots) with the same ignore/exclude/glob rules as search. Use this instead of a generic filesystem MCP list_dir/tree. Caps results (default max_results=500) and reports truncated+total_matched when capped. max_depth prunes the walk at each root (does not enter deeper dirs). max_results still counts all in-depth matches then truncates (total_matched remains honest). Prefer relative paths. Example: {"path": "src/", "exclude_patterns": ["target/**"], "max_results": 100, "max_depth": 3}

輸入參數pathglobspathsmax_depthmax_resultsinclude_hiddenexclude_patternscustom_ignore_filenames

md_dedupe_headings

Remove later whole sections whose heading text+level already appeared (heading and body until next same-or-higher heading; unique second-section content is discarded). Removes later whole sections with the same heading level+text (body under the second heading is discarded, not merged).

輸入參數path必填agent_presetexpected_sha256

md_insert_after_heading

Insert content immediately after a markdown heading line (before any existing body). For a sibling section after the full body, use md.insert_after_section. Inserts immediately under the heading line (before existing body). For a sibling ## section after the full body, use md_insert_after_section.

輸入參數path必填content必填heading必填agent_presetexpected_sha256

md_insert_after_section

Insert content after the full section body (sibling placement). Use when adding a new ## section after this section's content. Prefer md.insert_after_heading for content under the heading line. Inserts after the full section body (sibling placement). Prefer md_insert_after_heading for content under the heading. Example: {"content":"## FAQ\n\nCommon questions.\n","path":"README.md","heading":"## Config"}

輸入參數path必填content必填heading必填agent_presetexpected_sha256

md_insert_before_heading

Insert content immediately before a markdown heading line.

輸入參數path必填content必填heading必填agent_presetexpected_sha256

md_lint

Lint a markdown rules file for duplicate headings, dangerous git commands, and missing final newline. Returns object envelope {ok, path, issue_count, issues} (CLI lint-agents --json parity; not a bare array). isError stays false when issues are present; branch on ok / issue_count. Example: {"path": "AGENTS.md"}

輸入參數path必填

md_move_section

Move a markdown heading section to a new position (same file reorder or cross-file). Exactly one of before or after is required. Omit to for same-file reorder. Example: {"path": "spec.md", "heading": "## Appendix", "to": "notes.md", "before": "## References"}

輸入參數topath必填afterbeforeheading必填

md_replace_section

Replace the body of a markdown section identified by heading (section ends at the next same-or-higher-level heading; nested lower-level headings are included). Section ends at the next same-or-higher-level heading; nested lower-level headings are included in the replaced range. Prefer peer-level headings when siblings must survive. Example: {"content":"Run `npm install`.\n","path":"README.md","heading":"## Installation"}

輸入參數path必填content必填heading必填agent_presetexpected_sha256

md_table_append

Append a row to a markdown table under a heading. Example: {"row":"| GET | /health | Health check |","path":"README.md","heading":"## API"}

輸入參數row必填path必填heading必填agent_presetexpected_sha256

md_upsert_bullet

Insert or update a bullet point under a markdown heading. Idempotent: skipped if the bullet is already present. Example: {"bullet":"- Added new feature","path":"CHANGELOG.md","heading":"## Changes"}

輸入參數path必填bullet必填heading必填agent_presetexpected_sha256

move_file

Rename (move) a file. Use force=true to overwrite an existing destination. Example: {"to":"new.txt","from":"old.txt"}

輸入參數to必填from必填forceagent_presetexpected_sha256

notebook_edit

Replace the source of one Jupyter notebook cell by its id. Pass the new cell body as one string. It is stored as an nbformat array of lines. Cell type, outputs, and the rest of the file stay put. A missing id is no_matches. A duplicate id is ambiguous. This does not run the cell. Address the cell by its id, not by index. source is the whole new cell body as one string. Does not run the cell. Example: {"source":"import pandas as pd\ndf.head()\n","path":"analysis.ipynb","cell_id":"load"}

輸入參數path必填source必填cell_id必填agent_presetexpected_sha256

operation_schema

Return the JSON schema for one plan operation. Pass op, for example doc.set. Use this for execute_plan field names. Does not run the operation. Example: {"op": "doc.set"}

輸入參數op必填

prepend_file

Prepend content to an existing file. Inserts the file's line ending after the new text when that text does not already end with one. Example: {"content":"// Copyright 2026\n","path":"src/main.rs"}

輸入參數path必填content必填agent_presetexpected_sha256

read_file

Read file contents with optional line range. Optional lines range uses start:end (1-based).

輸入參數path必填limitlinesoffsetend_linestart_line

replace_text

Replace text in a file. Literal by default; set regex=true for regex. Options: nth, insert_before, insert_after, case_insensitive, multiline, if_exists, whole_line, range, word_boundary, fuzzy, min_fuzzy_score, allow_absent_old. Set word_boundary=true to match only whole words (prevents 'SetupFile' matching inside 'BenchSetupFile'). Set whole_line=true to replace entire lines containing a match (use with new="" to delete lines). Fuzzy: when exact old is absent, refuse by default even if score ≥ min_fuzzy_score (#1758); set allow_absent_old=true only for deliberate approximate recovery. Prefer ast_rename for identifiers. Example: {"path": "README.md", "old": "1.0.0", "new": "2.0.0"}. Insert after anchor (mutually exclusive with new): {"path": "src/main.rs", "old": "use std::io;", "insert_after": "use std::fs;"}

輸入參數newnthold必填path必填fuzzyrangeregexstrictuniqueif_existsmultilinewhole_line另有 12 個

search_files

Search text files for a pattern (regex by default, use literal=true for exact match). Supports advanced layered ignores for LLM agents: globs (include), exclude_patterns, custom_ignore_filenames (e.g. .agentignore), max_results. Other options: files_with_matches, files_without_match, count, case_insensitive, multiline, invert_match, assert_count, before/after_context. Canonical multi-root field is paths (array); singular path is accepted as an alias for one root (same as paths:[path]). Example: {"pattern": "TODO", "paths": ["src/"], "literal": true, "custom_ignore_filenames": [".agentignore"], "exclude_patterns": ["target/**"], "max_results": 20}

輸入參數pathcountglobspathscontextliteralpattern必填multilinemax_resultsassert_countinvert_matchafter_context另有 6 個

server_info

Return server identity and workspace root: cwd, surface (full|core), tool_count, package version, MCP protocol_version from handshake, and optional recommendation (coding agents may prefer core). Prefer relative path parameters under cwd; absolute paths are allowed only when they resolve inside the workspace (AllowIfContained). Outside-workspace and ../ escapes are rejected.

無需輸入參數。

tidy_check

Scan files for missing final newline, mixed EOL, and trailing whitespace (CLI `tidy check`). Read-only: does not rewrite files. Canonical field is paths (array); singular path is accepted as an alias for one root. Empty issues is ok:true. Issues present still return a tool success with error_kind changes_detected. Example: {"path": "src/"}

輸入參數pathpaths

undo_list

List backup sessions created by --apply (including nested monorepo roots). Same as CLI `patchloom undo --list`. Returns items (timestamp, project_root, file_count, entries) plus warnings. Empty tree is error_kind no_matches. Example: {}

無需輸入參數。

undo_restore

Preview or restore files from a --apply backup session. Default is dry-run (applied:false, error_kind:changes_detected). Set apply=true to restore. Omit session to use the newest. Optional path[] restores only those session files (unknown path is no_matches). Paths stay inside the MCP workspace (AllowIfContained). Example: {"session": "<id-from-undo_list>", "apply": true}

輸入參數pathapplysession

版本歷史

12
  1. v0.37.7最新Nov 5, 2026
  2. v0.37.6Oct 25, 2026
  3. v0.37.5Oct 19, 2026
  4. v0.37.4Oct 19, 2026
  5. v0.37.3Oct 16, 2026
  6. v0.37.2Oct 12, 2026
  7. v0.37.1Oct 8, 2026
  8. v0.37.0Sep 26, 2026
  9. v0.36.0Sep 21, 2026
  10. v0.35.1Sep 19, 2026
  11. v0.35.0Sep 18, 2026
  12. v0.34.0Sep 16, 2026

評分

已滿足適用檢查項的 90%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通25 分
  • 已宣告認證方式10 分

    請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。

  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分