Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ test/
managedLifecycle.test.ts Managed install with real file I/O (22 tests)
mcpConfig.test.ts MCP config with real temp directories (9 tests)
outputChannel.test.ts Output channel logging wrapper (10 tests)
patchloomCli.test.ts Patchloom CLI integration with real binary + managed install e2e MCP (34 tests incl. e2e)
patchloomCli.test.ts Patchloom CLI integration with real binary + managed install e2e MCP (35 tests incl. e2e)
propertyBased.test.ts Property-based tests with fast-check (13 tests)
quickActions.test.ts Quick action command building, path containment, patch merge (51 tests)
verifyMcp.test.ts MCP server verify and JSON-RPC response parsing (15 tests)
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ Or search for **Patchloom** in the Extensions view (`Ctrl+Shift+X` / `Cmd+Shift+
npm install -g patchloom # npm (Node.js)
curl -LsSf https://github.com/patchloom/patchloom/releases/latest/download/patchloom-installer.sh | sh # shell script
cargo install patchloom # from source
scoop install patchloom # Windows (Scoop; requires the official bucket)
scoop bucket add patchloom https://github.com/patchloom/scoop-bucket
scoop install patchloom # Windows (Scoop)
choco install patchloom # Windows (Chocolatey; first listing may wait on moderation)
```
2. Open a project and run **Patchloom: Setup Workspace**

Expand Down Expand Up @@ -89,8 +91,20 @@ Click it to see full diagnostics, including per-editor MCP configuration status
| **Append to file** | Append content to an existing file |
| **Prepend to file** | Prepend content to the start of an existing file (CLI 0.9+) |
| **Read structured value** | Read a JSON/YAML/TOML key and copy to clipboard |
| **Delete structured value** | Remove a key from JSON, YAML, or TOML with diff preview |
| **Merge into structured file** | Merge a partial JSON object into a config file |
| **Append to array** | Append a value to a JSON, YAML, or TOML array |
| **Prepend to array** | Prepend a value to a JSON, YAML, or TOML array |
| **Ensure structured value** | Idempotent set: write only if the key is missing |
| **Move/rename key** | Move or rename a selector path in JSON, YAML, or TOML |
| **Insert after heading** | Insert content immediately after a markdown heading line |
| **Insert after section** | Insert a sibling markdown section after a full section body (CLI 0.14+) |
| **Insert before heading** | Insert content immediately before a markdown heading line |
| **Append table row** | Append a row to a markdown table under a heading |
| **Upsert bullet** | Add a bullet under a heading if it is not already present |
| **Replace markdown section** | Replace content under a markdown heading |
| **Merge patch (three-way)** | Apply a stale patch using three-way merge (v0.2.0+) |
| **Undo last change** | Restore files from the latest Patchloom backup session |

Workspace Quick Actions and Batch Apply pass `--contain` so CLI paths stay inside the workspace root (CLI 0.10+). Containment is relative to the effective working directory (the workspace folder). Patch merge skips containment when the patch file may live outside the workspace.

Expand Down
31 changes: 31 additions & 0 deletions test/unit/patchloomCli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,37 @@ describe("patchloom CLI integration", async () => {
});
});

test("md insert-after-section inserts a sibling after the full section body", async () => {
await withTempDir(async (dir) => {
const file = path.join(dir, "notes.md");
await fs.writeFile(
file,
"# Title\n\n## Config\n\nsettings here\n\n## Other\n\nbody\n",
"utf8"
);

await execFileAsync(binaryPath, [
"md", "insert-after-section", file,
"--heading", "## Config",
"--content", "## FAQ\n\nCommon questions.\n",
"--apply"
], { timeout: 5000 });

const content = await fs.readFile(file, "utf8");
assert.ok(content.includes("## FAQ"), "sibling FAQ heading should be present");
assert.ok(content.includes("Common questions."), "FAQ body should be present");
assert.ok(content.includes("settings here"), "Config body should be preserved");
assert.ok(content.includes("## Other"), "following Other section should remain");

// Sibling placement: FAQ must come after the Config body, before Other.
const faqIdx = content.indexOf("## FAQ");
const settingsIdx = content.indexOf("settings here");
const otherIdx = content.indexOf("## Other");
assert.ok(settingsIdx >= 0 && faqIdx > settingsIdx, "FAQ should appear after Config body");
assert.ok(otherIdx > faqIdx, "FAQ should appear before the next original section");
});
});

// --- #116: undo CLI test ---

test("undo restores files after an apply", async () => {
Expand Down
8 changes: 8 additions & 0 deletions walkthrough/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ scoop bucket add patchloom https://github.com/patchloom/scoop-bucket
scoop install patchloom
```

## Chocolatey (Windows)

```bash
choco install patchloom
```

First listing on the community repository may wait on Chocolatey moderation.

## Cargo

```bash
Expand Down
Loading