Skip to content

Commit 0629af9

Browse files
authored
feat: align with patchloom CLI v0.4.0 (#145)
feat: align extension with patchloom CLI v0.4.0 - Add Quick Action for append to file (new top-level CLI write operation) - Update batch template to demonstrate file.append - Update README requirements, troubleshooting, and quick actions table to recommend 0.4.0 and document new capabilities - Add unit tests covering the append builder and updated batch template - Refresh version references and comments to reflect current release Signed-off-by: Sebastien Tardif <sebtardif@ncf.ca>
1 parent 5e75ee3 commit 0629af9

5 files changed

Lines changed: 58 additions & 6 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ Click it to see full diagnostics, including per-editor MCP configuration status
8484
| **Set structured value** | Update a JSON, YAML, or TOML key with diff preview |
8585
| **Search text** | Find pattern matches across workspace files (results in output channel) |
8686
| **Create file** | Scaffold a new file and open it in the editor |
87+
| **Append to file** | Append content to an existing file |
8788
| **Read structured value** | Read a JSON/YAML/TOML key and copy to clipboard |
8889
| **Merge patch (three-way)** | Apply a stale patch using three-way merge (v0.2.0+) |
8990

@@ -147,7 +148,7 @@ The extension detects outdated CLI builds and warns with upgrade guidance. It re
147148
Set `patchloom.path` in settings, or add the CLI to your `PATH`.
148149

149150
**CLI compatibility warning**
150-
Run `Patchloom: Open Releases` to download the latest release. The extension requires 0.1.0 or newer; 0.2.0 is recommended.
151+
Run `Patchloom: Open Releases` to download the latest release. The extension requires 0.1.0 or newer; 0.4.0 is recommended.
151152

152153
**MCP config not injected**
153154
Run `Patchloom: Configure MCP` and select the target editor config.
@@ -182,7 +183,7 @@ File bugs and feature requests at [patchloom/patchloom-vscode/issues](https://gi
182183
## Requirements
183184

184185
- VS Code 1.90 or newer (or compatible editors: Cursor, Windsurf, VSCodium)
185-
- [Patchloom CLI](https://github.com/patchloom/patchloom) 0.1.0 or newer (0.2.0+ recommended for patch merge and strict transactions)
186+
- [Patchloom CLI](https://github.com/patchloom/patchloom) 0.1.0 or newer (0.4.0+ recommended for latest features including append, AST ops, and --confirm)
186187

187188
## Contributing
188189

src/commands/batchApply.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { activeWorkspaceFolder } from "../workspace/readiness.js";
88
export const BATCH_TEMPLATE = [
99
"replace src/example.ts \"old text\" \"new text\"",
1010
"doc.set package.json version \"2.0.0\"",
11+
"file.append src/example.ts \"new appended line\"",
1112
"tidy.fix src/example.ts",
1213
""
1314
].join("\n");

src/commands/quickActions.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,28 @@ export async function runQuickAction(): Promise<void> {
260260
await vscode.window.showInformationMessage(`Created ${relativePath.trim()}.`);
261261
}
262262
},
263+
{
264+
label: "Append to file",
265+
description: "Append content to an existing file",
266+
detail: "Builds `patchloom append <file> --content <text>`",
267+
run: async () => {
268+
const target = await pickWorkspaceFileTarget("Select a file to append to with Patchloom");
269+
if (!target) {
270+
return;
271+
}
272+
273+
const content = await vscode.window.showInputBox({
274+
prompt: "Content to append",
275+
placeHolder: "new line of text",
276+
validateInput: (value) => value.length > 0 ? undefined : "Content is required."
277+
});
278+
if (content === undefined) {
279+
return;
280+
}
281+
282+
await previewAndMaybeApply(binaryPath, target, buildAppendQuickAction(target.absolutePath, content));
283+
}
284+
},
263285
{
264286
label: "Read structured value",
265287
description: "Read a value from JSON, YAML, or TOML",
@@ -861,6 +883,15 @@ export function buildCreateQuickAction(filePath: string): PlannedQuickAction {
861883
};
862884
}
863885

886+
export function buildAppendQuickAction(targetPath: string, content: string): PlannedQuickAction {
887+
return {
888+
title: `Append to ${path.basename(targetPath)}`,
889+
targetPath,
890+
targetArgIndices: [1],
891+
args: ["append", targetPath, "--content", content]
892+
};
893+
}
894+
864895
export function buildDocGetQuickAction(targetPath: string, selector: string): PlannedQuickAction {
865896
return {
866897
title: `Get ${selector} from ${path.basename(targetPath)}`,

test/unit/batchApply.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ import assert from "node:assert/strict";
22
import test from "node:test";
33
import { buildBatchTemplate, parseBatchOperationCount } from "../../src/commands/batchApply.js";
44

5-
test("buildBatchTemplate returns line-oriented format with three operations", () => {
5+
test("buildBatchTemplate returns line-oriented format with four operations", () => {
66
const template = buildBatchTemplate();
77
const lines = template.split("\n").filter((line) => line.trim().length > 0);
88

9-
assert.equal(lines.length, 3);
9+
assert.equal(lines.length, 4);
1010
assert.ok(lines[0].startsWith("replace "), "first line should be a replace operation");
1111
assert.ok(lines[1].startsWith("doc.set "), "second line should be a doc.set operation");
12-
assert.ok(lines[2].startsWith("tidy.fix "), "third line should be a tidy.fix operation");
12+
assert.ok(lines[2].startsWith("file.append "), "third line should be a file.append operation");
13+
assert.ok(lines[3].startsWith("tidy.fix "), "fourth line should be a tidy.fix operation");
1314
});
1415

1516
test("buildBatchTemplate ends with a newline", () => {
@@ -65,3 +66,10 @@ test("buildBatchTemplate tidy.fix line has a file path", () => {
6566
assert.ok(tidyLine, "template should contain a tidy.fix line");
6667
assert.match(tidyLine, /tidy\.fix \S+/, "tidy.fix should have a file path");
6768
});
69+
70+
test("buildBatchTemplate file.append line has file and quoted content", () => {
71+
const lines = buildBatchTemplate().split("\n");
72+
const appendLine = lines.find((l) => l.startsWith("file.append "));
73+
assert.ok(appendLine, "template should contain a file.append line");
74+
assert.match(appendLine, /file\.append \S+ ".+"/, "file.append should have file and quoted content");
75+
});

test/unit/quickActions.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import assert from "node:assert/strict";
22
import test from "node:test";
33
import {
4+
buildAppendQuickAction,
45
buildCreateQuickAction,
56
buildDocAppendQuickAction,
67
buildDocDeleteQuickAction,
@@ -408,7 +409,7 @@ test("retargetQuickAction works with md commands", () => {
408409
assert.equal(retargeted.args[1], "table-append");
409410
});
410411

411-
// --- patch merge Quick Action (v0.2.0) ---
412+
// --- patch merge Quick Action (v0.2.0+) ---
412413

413414
test("buildPatchMergeQuickAction builds a patch merge command", () => {
414415
const action = buildPatchMergeQuickAction("/workspace/demo/changes.patch", false);
@@ -434,3 +435,13 @@ test("retargetQuickAction works with patch merge command", () => {
434435
assert.equal(retargeted.args[0], "patch");
435436
assert.equal(retargeted.args[1], "merge");
436437
});
438+
439+
// --- append Quick Action (reflecting patchloom 0.4.0+) ---
440+
441+
test("buildAppendQuickAction builds an append command", () => {
442+
const action = buildAppendQuickAction("/workspace/demo/log.txt", "new log entry");
443+
444+
assert.equal(action.title, "Append to log.txt");
445+
assert.deepEqual(action.targetArgIndices, [1]);
446+
assert.deepEqual(action.args, ["append", "/workspace/demo/log.txt", "--content", "new log entry"]);
447+
});

0 commit comments

Comments
 (0)