pi-git-commit 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/index.ts +36 -7
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -5,8 +5,8 @@ Keeps mutative git operations out of the agent's bash and provides a safe, revie
|
|
|
5
5
|
## What you get
|
|
6
6
|
|
|
7
7
|
- **Bash git guard.** Mutative git commands are blocked in the agent's bash tool — `add`, `stage`, `commit`, `push`, `pull`, `merge`, `rebase`, `reset`, `clean`, `rm`, `restore`, `switch`, `cherry-pick`, `revert`, `mv`, `init`, `clone`, index/object plumbing (`read-tree`, `checkout-index`, `merge-file`, `prune-packed`), plus mutative forms of `branch` (including creation, `-u`, `-f`, `-c`/`-C`/`--copy`, `-D`/`-M`, `--force`, `-t`/`--track`), `tag` (including creation), `checkout` (including whole-tree restores like `checkout -- .`), `stash`, `submodule`, `worktree`, `config`, `remote`, `apply`, `notes`, `update-ref`, `gc` and more. Read-only commands (`status`, `diff`, `log`, `fetch`, `branch`, `tag`, `stash list`, ...) stay allowed.
|
|
8
|
-
- **`git_commit` tool.** The agent stages everything and commits with a `FIX` / `IMPROVE` / `NEW` type prefix. Inactive by default: `/commit` activates it for the commit flow and it is disabled again after
|
|
9
|
-
- **`/commit` command.** Waits for queued messages to finish, stages all changes, shows the staged diff, activates the `git_commit` tool, and asks the agent to review
|
|
8
|
+
- **`git_commit` tool.** The agent stages everything and commits with a `FIX` / `IMPROVE` / `NEW` type prefix. Inactive by default: `/commit` activates it for the commit flow and it is disabled again after a successful commit, so the agent cannot commit on its own at other times.
|
|
9
|
+
- **`/commit` command.** Waits for queued messages to finish, stages all changes, shows a collapsed summary of the staged diff (a `git diff --stat` line; press `ctrl+o` to expand the full diff), activates the `git_commit` tool, and asks the agent to review the changes and commit via `git_commit` — never via bash. Run `/stop-commit` at any point to abort the flow.
|
|
10
10
|
- **`/stop-commit` command.** Aborts a pending commit flow: deactivates the `git_commit` tool and cancels a `/commit` that is still waiting for queued messages, so no commit is made.
|
|
11
11
|
- **`/toggle-allow-git` command.** Temporarily allows mutative git commands in bash for the current session. The guard re-arms on the next session.
|
|
12
12
|
|
|
@@ -18,7 +18,7 @@ Keeps mutative git operations out of the agent's bash and provides a safe, revie
|
|
|
18
18
|
/commit
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
2. The extension stages the working tree and
|
|
21
|
+
2. The extension stages the working tree and shows a collapsed summary of the staged diff — press `ctrl+o` to expand it. The full diff is handed to the agent with instructions to review it.
|
|
22
22
|
|
|
23
23
|
3. The agent commits using the `git_commit` tool:
|
|
24
24
|
|
|
@@ -56,7 +56,7 @@ pi install /path/to/pi-git-commit
|
|
|
56
56
|
| `type` | `FIX` (bug fix), `IMPROVE` (improvement), or `NEW` (new feature). |
|
|
57
57
|
| `message` | Commit message in imperative mood, without the type prefix (it is added automatically). A leading type word matching the chosen type is stripped (with `:`, whitespace, or `-`/`—` separators, any casing, repeats included) so the type is never duplicated. Multi-line allowed for detailed changes. |
|
|
58
58
|
|
|
59
|
-
The tool runs `git add .` followed by `git commit -m "<TYPE>: <message>"` and reports staging or commit failures as tool errors. A leading type word in the message is stripped whenever it repeats the chosen type — with `:`, whitespace, or `-`/`—` separators, at any casing, repeated prefixes included — so the type never ends up duplicated: `FIX: Fix: ...`, `FIX: Fix ...`, and `fix - ...` all become `FIX: ...`. The tool is inactive by default and only becomes available when you run `/commit`; it is deactivated again after a
|
|
59
|
+
The tool runs `git add .` followed by `git commit -m "<TYPE>: <message>"` and reports staging or commit failures as tool errors. A leading type word in the message is stripped whenever it repeats the chosen type — with `:`, whitespace, or `-`/`—` separators, at any casing, repeated prefixes included — so the type never ends up duplicated: `FIX: Fix: ...`, `FIX: Fix ...`, and `fix - ...` all become `FIX: ...`. The tool is inactive by default and only becomes available when you run `/commit`; it is deactivated again after a successful commit, so the agent cannot commit at arbitrary points in the conversation. If a commit fails, the tool stays active and the agent can retry immediately without re-running `/commit`.
|
|
60
60
|
|
|
61
61
|
## The bash guard
|
|
62
62
|
|
package/index.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { keyHint, renderDiff, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Box, Text } from "@earendil-works/pi-tui";
|
|
2
3
|
import { Type } from "typebox";
|
|
3
4
|
|
|
4
5
|
const COMMIT_TYPES = ["FIX", "IMPROVE", "NEW"] as const;
|
|
6
|
+
const DIFF_CUSTOM_TYPE = "git-commit-diff";
|
|
5
7
|
|
|
6
8
|
export default function (pi: ExtensionAPI) {
|
|
7
9
|
let gitBlocked = true;
|
|
@@ -250,6 +252,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
250
252
|
}),
|
|
251
253
|
}),
|
|
252
254
|
async execute(_toolCallId, params, signal, _onUpdate, _ctx) {
|
|
255
|
+
let committed = false;
|
|
253
256
|
try {
|
|
254
257
|
const { type, message } = params;
|
|
255
258
|
const description = stripLeadingCommitType(type, message);
|
|
@@ -266,15 +269,17 @@ export default function (pi: ExtensionAPI) {
|
|
|
266
269
|
if (result.code !== 0) {
|
|
267
270
|
return { content: [{ type: "text", text: `Commit failed: ${result.stderr}` }], details: {}, isError: true };
|
|
268
271
|
}
|
|
269
|
-
|
|
272
|
+
committed = true;
|
|
270
273
|
pi.sendMessage(
|
|
271
|
-
{ customType: "git-commit-
|
|
274
|
+
{ customType: "git-commit-flow-complete", content: "The commit flow is complete.", display: false },
|
|
272
275
|
{ deliverAs: "steer" },
|
|
273
276
|
);
|
|
274
277
|
return { content: [{ type: "text", text: `✓ Committed: ${fullMessage}` }], details: {} };
|
|
275
278
|
} finally {
|
|
276
|
-
|
|
277
|
-
|
|
279
|
+
if (committed) {
|
|
280
|
+
commitFlowActive = false;
|
|
281
|
+
deactivateGitCommit();
|
|
282
|
+
}
|
|
278
283
|
}
|
|
279
284
|
},
|
|
280
285
|
});
|
|
@@ -285,6 +290,23 @@ export default function (pi: ExtensionAPI) {
|
|
|
285
290
|
deactivateGitCommit();
|
|
286
291
|
});
|
|
287
292
|
|
|
293
|
+
pi.registerMessageRenderer(DIFF_CUSTOM_TYPE, (message, { expanded, outputPad }, theme) => {
|
|
294
|
+
const details = message.details as { diff?: string; stat?: string } | undefined;
|
|
295
|
+
const box = new Box(outputPad, 1, (text) => theme.bg("customMessageBg", text));
|
|
296
|
+
box.addChild(new Text(theme.fg("accent", "Staged changes"), 0, 0));
|
|
297
|
+
if (expanded) {
|
|
298
|
+
if (details?.diff) {
|
|
299
|
+
box.addChild(new Text(renderDiff(details.diff), 0, 0));
|
|
300
|
+
}
|
|
301
|
+
} else {
|
|
302
|
+
if (details?.stat) {
|
|
303
|
+
box.addChild(new Text(details.stat, 0, 0));
|
|
304
|
+
}
|
|
305
|
+
box.addChild(new Text(theme.fg("dim", `(${keyHint("app.tools.expand", "to expand")})`), 0, 0));
|
|
306
|
+
}
|
|
307
|
+
return box;
|
|
308
|
+
});
|
|
309
|
+
|
|
288
310
|
pi.registerCommand("commit", {
|
|
289
311
|
description: "Stage files and show diff for commit",
|
|
290
312
|
handler: async (_args, ctx) => {
|
|
@@ -323,10 +345,17 @@ export default function (pi: ExtensionAPI) {
|
|
|
323
345
|
|
|
324
346
|
const diff = diffResult.stdout || "(no changes staged)";
|
|
325
347
|
|
|
348
|
+
const statResult = await pi.exec("git", ["diff", "--staged", "--stat"]);
|
|
349
|
+
if (!commitFlowActive) return;
|
|
350
|
+
const stat = statResult.code === 0 ? statResult.stdout.trim().split("\n").pop() ?? "" : "";
|
|
351
|
+
|
|
326
352
|
const prompt = `DO NOT use bash for git. Use ONLY the \`git_commit\` tool.\n\nReview staged changes:\n\`\`\`diff\n${diff}\`\`\`\n\nUse \`git_commit\` tool with:\n- type: FIX, IMPROVE, or NEW\n- message: brief description (imperative mood)`;
|
|
327
353
|
if (!commitFlowActive) return;
|
|
328
354
|
activateGitCommit();
|
|
329
|
-
pi.
|
|
355
|
+
pi.sendMessage(
|
|
356
|
+
{ customType: DIFF_CUSTOM_TYPE, content: prompt, display: true, details: { diff, stat } },
|
|
357
|
+
{ deliverAs: "followUp", triggerTurn: true },
|
|
358
|
+
);
|
|
330
359
|
} finally {
|
|
331
360
|
ctx.ui.setWorkingMessage();
|
|
332
361
|
}
|
|
@@ -346,7 +375,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
346
375
|
deactivateGitCommit();
|
|
347
376
|
if (toolWasActive) {
|
|
348
377
|
pi.sendMessage(
|
|
349
|
-
{ customType: "git-commit-stopped", content: "The user stopped the commit flow with /stop-commit. Do not attempt to commit.
|
|
378
|
+
{ customType: "git-commit-stopped", content: "The user stopped the commit flow with /stop-commit. Do not attempt to commit.", display: false },
|
|
350
379
|
{ deliverAs: "steer" },
|
|
351
380
|
);
|
|
352
381
|
ctx.ui.notify("Commit flow stopped. The git_commit tool is deactivated.", "info");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-git-commit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Pi extension: block mutative git commands in bash and provide a git_commit tool plus /commit, /stop-commit and /toggle-allow-git commands",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@earendil-works/pi-coding-agent": "*",
|
|
34
|
+
"@earendil-works/pi-tui": "*",
|
|
34
35
|
"typebox": "*"
|
|
35
36
|
},
|
|
36
37
|
"engines": {
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
45
|
"@earendil-works/pi-coding-agent": "^0.84.0",
|
|
46
|
+
"@earendil-works/pi-tui": "^0.84.1",
|
|
45
47
|
"@types/node": "^24.0.0",
|
|
46
48
|
"typescript": "~5.9.3",
|
|
47
49
|
"vitest": "^4.1.9",
|