@335g/pi-git 0.0.2 → 0.0.4
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.ja.md +3 -30
- package/README.md +3 -30
- package/dist/commands/agg-commit.d.ts.map +1 -1
- package/dist/commands/agg-commit.js +27 -38
- package/dist/commands/agg-commit.js.map +1 -1
- package/dist/commands/auto-agg-commit.d.ts.map +1 -1
- package/dist/commands/auto-agg-commit.js +11 -68
- package/dist/commands/auto-agg-commit.js.map +1 -1
- package/dist/commands/config.d.ts +1 -1
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +55 -70
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/diagnostics.d.ts +12 -0
- package/dist/commands/diagnostics.d.ts.map +1 -0
- package/dist/commands/diagnostics.js +59 -0
- package/dist/commands/diagnostics.js.map +1 -0
- package/dist/core/auto-commit-message.d.ts +2 -2
- package/dist/core/auto-commit-message.d.ts.map +1 -1
- package/dist/core/auto-commit-message.js +239 -58
- package/dist/core/auto-commit-message.js.map +1 -1
- package/dist/core/auto-commit.d.ts.map +1 -1
- package/dist/core/auto-commit.js +4 -8
- package/dist/core/auto-commit.js.map +1 -1
- package/dist/core/commit-message.d.ts.map +1 -1
- package/dist/core/commit-message.js +3 -0
- package/dist/core/commit-message.js.map +1 -1
- package/dist/core/diff-analyzer.d.ts +1 -9
- package/dist/core/diff-analyzer.d.ts.map +1 -1
- package/dist/core/diff-analyzer.js +75 -75
- package/dist/core/diff-analyzer.js.map +1 -1
- package/dist/core/git.d.ts +5 -28
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +19 -68
- package/dist/core/git.js.map +1 -1
- package/dist/i18n/messages.d.ts +107 -0
- package/dist/i18n/messages.d.ts.map +1 -0
- package/dist/i18n/messages.js +135 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -22
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/diagnostics.d.ts +33 -0
- package/dist/utils/diagnostics.d.ts.map +1 -0
- package/dist/utils/diagnostics.js +32 -0
- package/dist/utils/diagnostics.js.map +1 -0
- package/dist/utils/footer-manager.d.ts.map +1 -1
- package/dist/utils/footer-manager.js +6 -9
- package/dist/utils/footer-manager.js.map +1 -1
- package/dist/utils/lang.d.ts +13 -7
- package/dist/utils/lang.d.ts.map +1 -1
- package/dist/utils/lang.js +21 -10
- package/dist/utils/lang.js.map +1 -1
- package/dist/utils/settings.d.ts +13 -5
- package/dist/utils/settings.d.ts.map +1 -1
- package/dist/utils/settings.js +65 -13
- package/dist/utils/settings.js.map +1 -1
- package/package.json +6 -2
- package/dist/commands/branch.d.ts +0 -8
- package/dist/commands/branch.d.ts.map +0 -1
- package/dist/commands/branch.js +0 -197
- package/dist/commands/branch.js.map +0 -1
- package/dist/commands/git-diff.d.ts +0 -10
- package/dist/commands/git-diff.d.ts.map +0 -1
- package/dist/commands/git-diff.js +0 -228
- package/dist/commands/git-diff.js.map +0 -1
- package/dist/commands/git-log.d.ts +0 -8
- package/dist/commands/git-log.d.ts.map +0 -1
- package/dist/commands/git-log.js +0 -100
- package/dist/commands/git-log.js.map +0 -1
- package/dist/tui/hunk-review.d.ts +0 -51
- package/dist/tui/hunk-review.d.ts.map +0 -1
- package/dist/tui/hunk-review.js +0 -296
- package/dist/tui/hunk-review.js.map +0 -1
package/dist/utils/settings.js
CHANGED
|
@@ -3,33 +3,31 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Settings are stored in:
|
|
5
5
|
* - Global: ~/.config/pi-git/settings.json
|
|
6
|
-
* - Local: <git-root
|
|
6
|
+
* - Local: <git-root>/pi-git.toml (takes precedence)
|
|
7
7
|
*/
|
|
8
8
|
import { execSync } from "node:child_process";
|
|
9
9
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { homedir } from "node:os";
|
|
11
11
|
import { dirname, join } from "node:path";
|
|
12
|
+
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
12
13
|
/** Metadata for all valid configuration keys */
|
|
13
14
|
export const VALID_KEYS_META = [
|
|
14
15
|
{
|
|
15
16
|
key: "lang",
|
|
16
17
|
type: "string",
|
|
17
|
-
|
|
18
|
-
description_en: "Display and commit message language",
|
|
18
|
+
messageKey: "config.keyDesc.lang",
|
|
19
19
|
valid_values: '"en" or "ja"',
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
key: "auto_agg_commit",
|
|
23
23
|
type: "boolean",
|
|
24
|
-
|
|
25
|
-
description_en: "Whether to automatically run git-agg-commit after assistant response",
|
|
24
|
+
messageKey: "config.keyDesc.auto_agg_commit",
|
|
26
25
|
valid_values: "true or false",
|
|
27
26
|
},
|
|
28
27
|
{
|
|
29
28
|
key: "analysis_model",
|
|
30
29
|
type: "string",
|
|
31
|
-
|
|
32
|
-
description_en: "AI model to use for diff analysis (format: provider/model-id)",
|
|
30
|
+
messageKey: "config.keyDesc.analysis_model",
|
|
33
31
|
valid_values: "e.g., anthropic/claude-3-5-sonnet-20241022",
|
|
34
32
|
},
|
|
35
33
|
];
|
|
@@ -40,8 +38,8 @@ export const DEFAULT_SETTINGS = {
|
|
|
40
38
|
};
|
|
41
39
|
export const GLOBAL_CONFIG_DIR = join(homedir(), ".config", "pi-git");
|
|
42
40
|
export const GLOBAL_SETTINGS_FILE = join(GLOBAL_CONFIG_DIR, "settings.json");
|
|
43
|
-
const
|
|
44
|
-
const
|
|
41
|
+
const LOCAL_SETTINGS_FILE = "pi-git.toml";
|
|
42
|
+
const LEGACY_LOCAL_PATH = join(".pi-git", "settings.json");
|
|
45
43
|
// ───────────────────────────────────────────────
|
|
46
44
|
// File I/O helpers
|
|
47
45
|
// ───────────────────────────────────────────────
|
|
@@ -68,7 +66,21 @@ export function getLocalSettingsPath(cwd) {
|
|
|
68
66
|
}).trim();
|
|
69
67
|
if (!repoRoot)
|
|
70
68
|
return null;
|
|
71
|
-
return join(repoRoot,
|
|
69
|
+
return join(repoRoot, LOCAL_SETTINGS_FILE);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function loadToml(path) {
|
|
76
|
+
if (!existsSync(path))
|
|
77
|
+
return null;
|
|
78
|
+
try {
|
|
79
|
+
const raw = readFileSync(path, "utf-8");
|
|
80
|
+
const parsed = parseToml(raw);
|
|
81
|
+
if (typeof parsed !== "object" || parsed === null)
|
|
82
|
+
return null;
|
|
83
|
+
return parsed;
|
|
72
84
|
}
|
|
73
85
|
catch {
|
|
74
86
|
return null;
|
|
@@ -77,7 +89,28 @@ export function getLocalSettingsPath(cwd) {
|
|
|
77
89
|
function loadRaw(cwd) {
|
|
78
90
|
const global = loadJson(GLOBAL_SETTINGS_FILE) ?? {};
|
|
79
91
|
const localPath = getLocalSettingsPath(cwd);
|
|
80
|
-
const local = localPath ?
|
|
92
|
+
const local = localPath ? loadToml(localPath) : null;
|
|
93
|
+
// Detect legacy settings file and warn if found
|
|
94
|
+
if (!local && localPath) {
|
|
95
|
+
try {
|
|
96
|
+
const repoRoot = execSync("git rev-parse --show-toplevel", {
|
|
97
|
+
cwd,
|
|
98
|
+
encoding: "utf-8",
|
|
99
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
100
|
+
}).trim();
|
|
101
|
+
if (repoRoot) {
|
|
102
|
+
const legacyPath = join(repoRoot, LEGACY_LOCAL_PATH);
|
|
103
|
+
if (existsSync(legacyPath)) {
|
|
104
|
+
console.warn("[pi-git] Found legacy .pi-git/settings.json. " +
|
|
105
|
+
"Settings are now read from pi-git.toml. " +
|
|
106
|
+
"Please migrate your settings manually or create pi-git.toml via /git-config.");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// ignore
|
|
112
|
+
}
|
|
113
|
+
}
|
|
81
114
|
return { global, local };
|
|
82
115
|
}
|
|
83
116
|
function merge(global, local) {
|
|
@@ -137,15 +170,34 @@ export function saveGlobalSettings(settings) {
|
|
|
137
170
|
writeFileSync(GLOBAL_SETTINGS_FILE, `${JSON.stringify(updated, null, 2)}\n`, "utf-8");
|
|
138
171
|
cache.clear();
|
|
139
172
|
}
|
|
173
|
+
/**
|
|
174
|
+
* Create (or overwrite) pi-git.toml with DEFAULT_SETTINGS at the repo root.
|
|
175
|
+
*
|
|
176
|
+
* @param cwdOrPath - Working directory (to resolve git root) or an already-resolved
|
|
177
|
+
* local settings path. If a path ending in "pi-git.toml" is passed, it is used directly
|
|
178
|
+
* without re-running git rev-parse.
|
|
179
|
+
* @returns The written path, or null if not inside a git repo.
|
|
180
|
+
*/
|
|
181
|
+
export function initLocalSettings(cwdOrPath) {
|
|
182
|
+
const localPath = cwdOrPath?.endsWith("pi-git.toml")
|
|
183
|
+
? cwdOrPath
|
|
184
|
+
: getLocalSettingsPath(cwdOrPath);
|
|
185
|
+
if (!localPath)
|
|
186
|
+
return null;
|
|
187
|
+
mkdirSync(dirname(localPath), { recursive: true });
|
|
188
|
+
writeFileSync(localPath, stringifyToml(DEFAULT_SETTINGS), "utf-8");
|
|
189
|
+
cache.clear();
|
|
190
|
+
return localPath;
|
|
191
|
+
}
|
|
140
192
|
export function saveLocalSettings(settings, cwd) {
|
|
141
193
|
const localPath = getLocalSettingsPath(cwd);
|
|
142
194
|
if (!localPath) {
|
|
143
195
|
throw new Error("Not inside a git repository");
|
|
144
196
|
}
|
|
145
197
|
mkdirSync(dirname(localPath), { recursive: true });
|
|
146
|
-
const current =
|
|
198
|
+
const current = loadToml(localPath) ?? {};
|
|
147
199
|
const updated = { ...current, ...settings };
|
|
148
|
-
writeFileSync(localPath,
|
|
200
|
+
writeFileSync(localPath, stringifyToml(updated), "utf-8");
|
|
149
201
|
cache.clear();
|
|
150
202
|
}
|
|
151
203
|
//# sourceMappingURL=settings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/utils/settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/utils/settings.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@335g/pi-git",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Git utilities extension for pi-coding-agent",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -45,7 +45,8 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@earendil-works/pi-tui": "^0.78.0",
|
|
47
47
|
"@types/node": "^25.9.1",
|
|
48
|
-
"typescript": "^5.9.0"
|
|
48
|
+
"typescript": "^5.9.0",
|
|
49
|
+
"typescript-language-server": "^5.3.0"
|
|
49
50
|
},
|
|
50
51
|
"peerDependencies": {
|
|
51
52
|
"@earendil-works/pi-ai": "*",
|
|
@@ -56,5 +57,8 @@
|
|
|
56
57
|
"@earendil-works/pi-tui": {
|
|
57
58
|
"optional": true
|
|
58
59
|
}
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"smol-toml": "^1.6.1"
|
|
59
63
|
}
|
|
60
64
|
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /git-branch command
|
|
3
|
-
*
|
|
4
|
-
* Manage git branches: list, switch, create, and delete.
|
|
5
|
-
*/
|
|
6
|
-
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
7
|
-
export declare function handleBranch(pi: ExtensionAPI, ctx: ExtensionCommandContext, args: string): Promise<void>;
|
|
8
|
-
//# sourceMappingURL=branch.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/commands/branch.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,uBAAuB,EACxB,MAAM,iCAAiC,CAAC;AAYzC,wBAAsB,YAAY,CAChC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAuHf"}
|
package/dist/commands/branch.js
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /git-branch command
|
|
3
|
-
*
|
|
4
|
-
* Manage git branches: list, switch, create, and delete.
|
|
5
|
-
*/
|
|
6
|
-
import { createAndSwitchBranch, deleteBranch, getBranches, getCurrentBranch, isGitRepository, switchBranch, } from "../core/git.js";
|
|
7
|
-
import { isJapanese } from "../utils/lang.js";
|
|
8
|
-
import { getSettings } from "../utils/settings.js";
|
|
9
|
-
export async function handleBranch(pi, ctx, args) {
|
|
10
|
-
if (!ctx.hasUI) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
const lang = getSettings(ctx.cwd).lang ?? "en";
|
|
14
|
-
const ja = isJapanese(lang);
|
|
15
|
-
if (!(await isGitRepository(pi, ctx.cwd))) {
|
|
16
|
-
ctx.ui.notify(ja ? "Gitリポジトリではありません" : "Not a git repository", "warning");
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const tokens = args.trim().split(/\s+/).filter(Boolean);
|
|
20
|
-
// Parse flags
|
|
21
|
-
let createNew = false;
|
|
22
|
-
let deleteFlag = false;
|
|
23
|
-
let listOnly = false;
|
|
24
|
-
let help = false;
|
|
25
|
-
const positional = [];
|
|
26
|
-
for (const token of tokens) {
|
|
27
|
-
if (token === "-c" || token === "--create")
|
|
28
|
-
createNew = true;
|
|
29
|
-
else if (token === "-d" || token === "--delete")
|
|
30
|
-
deleteFlag = true;
|
|
31
|
-
else if (token === "--list" || token === "-l")
|
|
32
|
-
listOnly = true;
|
|
33
|
-
else if (token === "--help" || token === "-h")
|
|
34
|
-
help = true;
|
|
35
|
-
else
|
|
36
|
-
positional.push(token);
|
|
37
|
-
}
|
|
38
|
-
if (help) {
|
|
39
|
-
const lines = ja
|
|
40
|
-
? [
|
|
41
|
-
"/git-branch [<branch>] [-c|--create] [-d|--delete] [--list] [--help]",
|
|
42
|
-
"",
|
|
43
|
-
"ブランチを管理します。",
|
|
44
|
-
"",
|
|
45
|
-
"引数:",
|
|
46
|
-
" <branch> 切り替えるブランチ名",
|
|
47
|
-
"",
|
|
48
|
-
"フラグ:",
|
|
49
|
-
" -c, --create 新しいブランチを作成して切り替え",
|
|
50
|
-
" -d, --delete ブランチを削除(マージ済みのみ)",
|
|
51
|
-
" --list, -l ブランチ一覧を表示",
|
|
52
|
-
" --help, -h このヘルプを表示",
|
|
53
|
-
"",
|
|
54
|
-
"引数を省略すると、ブランチ一覧を表示します。",
|
|
55
|
-
]
|
|
56
|
-
: [
|
|
57
|
-
"/git-branch [<branch>] [-c|--create] [-d|--delete] [--list] [--help]",
|
|
58
|
-
"",
|
|
59
|
-
"Manage git branches.",
|
|
60
|
-
"",
|
|
61
|
-
"Arguments:",
|
|
62
|
-
" <branch> Branch name to switch to",
|
|
63
|
-
"",
|
|
64
|
-
"Flags:",
|
|
65
|
-
" -c, --create Create a new branch and switch to it",
|
|
66
|
-
" -d, --delete Delete a branch (merged only)",
|
|
67
|
-
" --list, -l List all branches",
|
|
68
|
-
" --help, -h Show this help message",
|
|
69
|
-
"",
|
|
70
|
-
"Without arguments, lists all branches.",
|
|
71
|
-
];
|
|
72
|
-
ctx.ui.notify(lines.join("\n"), "info");
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// List branches if no branch specified or --list flag
|
|
76
|
-
if (listOnly || (positional.length === 0 && !createNew && !deleteFlag)) {
|
|
77
|
-
await listBranches(pi, ctx, ja);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const branchName = positional[0];
|
|
81
|
-
if (deleteFlag) {
|
|
82
|
-
// Delete branch
|
|
83
|
-
await handleDeleteBranch(pi, ctx, branchName, ja);
|
|
84
|
-
}
|
|
85
|
-
else if (createNew) {
|
|
86
|
-
// Create and switch to new branch
|
|
87
|
-
const result = await createAndSwitchBranch(pi, branchName, ctx.cwd);
|
|
88
|
-
if (result.success) {
|
|
89
|
-
ctx.ui.notify(ja
|
|
90
|
-
? `新しいブランチ '${branchName}' を作成して切り替えました`
|
|
91
|
-
: `Created and switched to new branch '${branchName}'`, "info");
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
ctx.ui.notify(ja
|
|
95
|
-
? `ブランチの作成に失敗しました: ${result.message}`
|
|
96
|
-
: `Failed to create branch: ${result.message}`, "error");
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
// Switch to existing branch
|
|
101
|
-
const result = await switchBranch(pi, branchName, ctx.cwd);
|
|
102
|
-
if (result.success) {
|
|
103
|
-
ctx.ui.notify(ja
|
|
104
|
-
? `ブランチ '${branchName}' に切り替えました`
|
|
105
|
-
: `Switched to branch '${branchName}'`, "info");
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
ctx.ui.notify(ja
|
|
109
|
-
? `ブランチの切り替えに失敗しました: ${result.message}`
|
|
110
|
-
: `Failed to switch branch: ${result.message}`, "error");
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
async function handleDeleteBranch(pi, ctx, branchName, ja) {
|
|
115
|
-
// Check if trying to delete current branch
|
|
116
|
-
try {
|
|
117
|
-
const currentBranch = await getCurrentBranch(pi, ctx.cwd);
|
|
118
|
-
if (currentBranch === branchName) {
|
|
119
|
-
ctx.ui.notify(ja
|
|
120
|
-
? `現在のブランチ '${branchName}' は削除できません。まず他のブランチに切り替えてください`
|
|
121
|
-
: `Cannot delete the current branch '${branchName}'. Please switch to another branch first`, "warning");
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
ctx.ui.notify(ja
|
|
127
|
-
? `現在のブランチの取得に失敗しました: ${error instanceof Error ? error.message : String(error)}`
|
|
128
|
-
: `Failed to get current branch: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
// Confirm deletion
|
|
132
|
-
const confirmTitle = ja ? "ブランチ削除の確認" : "Confirm Branch Deletion";
|
|
133
|
-
const confirmMessage = ja
|
|
134
|
-
? `ブランチ '${branchName}' を削除してもよろしいですか?`
|
|
135
|
-
: `Are you sure you want to delete branch '${branchName}'?`;
|
|
136
|
-
const confirmed = await ctx.ui.confirm(confirmTitle, confirmMessage);
|
|
137
|
-
if (!confirmed) {
|
|
138
|
-
ctx.ui.notify(ja ? "削除をキャンセルしました" : "Deletion cancelled", "info");
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
// Delete branch
|
|
142
|
-
const result = await deleteBranch(pi, branchName, ctx.cwd);
|
|
143
|
-
if (result.success) {
|
|
144
|
-
ctx.ui.notify(ja
|
|
145
|
-
? `ブランチ '${branchName}' を削除しました`
|
|
146
|
-
: `Deleted branch '${branchName}'`, "info");
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
ctx.ui.notify(ja
|
|
150
|
-
? `ブランチの削除に失敗しました: ${result.message}`
|
|
151
|
-
: `Failed to delete branch: ${result.message}`, "error");
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async function listBranches(pi, ctx, ja) {
|
|
155
|
-
try {
|
|
156
|
-
const currentBranch = await getCurrentBranch(pi, ctx.cwd);
|
|
157
|
-
const branches = await getBranches(pi, ctx.cwd);
|
|
158
|
-
const localBranches = branches.filter((b) => !b.isRemote);
|
|
159
|
-
const remoteBranches = branches.filter((b) => b.isRemote);
|
|
160
|
-
const lines = [];
|
|
161
|
-
if (ja) {
|
|
162
|
-
lines.push("ローカルブランチ:");
|
|
163
|
-
for (const branch of localBranches) {
|
|
164
|
-
const marker = branch.name === currentBranch ? "* " : " ";
|
|
165
|
-
lines.push(`${marker}${branch.name}`);
|
|
166
|
-
}
|
|
167
|
-
if (remoteBranches.length > 0) {
|
|
168
|
-
lines.push("");
|
|
169
|
-
lines.push("リモートブランチ:");
|
|
170
|
-
for (const branch of remoteBranches) {
|
|
171
|
-
lines.push(` ${branch.name}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
lines.push("Local branches:");
|
|
177
|
-
for (const branch of localBranches) {
|
|
178
|
-
const marker = branch.name === currentBranch ? "* " : " ";
|
|
179
|
-
lines.push(`${marker}${branch.name}`);
|
|
180
|
-
}
|
|
181
|
-
if (remoteBranches.length > 0) {
|
|
182
|
-
lines.push("");
|
|
183
|
-
lines.push("Remote branches:");
|
|
184
|
-
for (const branch of remoteBranches) {
|
|
185
|
-
lines.push(` ${branch.name}`);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
ctx.ui.notify(lines.join("\n"), "info");
|
|
190
|
-
}
|
|
191
|
-
catch (error) {
|
|
192
|
-
ctx.ui.notify(ja
|
|
193
|
-
? `ブランチ一覧の取得に失敗しました: ${error instanceof Error ? error.message : String(error)}`
|
|
194
|
-
: `Failed to list branches: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
//# sourceMappingURL=branch.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"branch.js","sourceRoot":"","sources":["../../src/commands/branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /git-diff command
|
|
3
|
-
*
|
|
4
|
-
* Interactive diff review with sequential hunk approval.
|
|
5
|
-
* Allows reviewing AI-generated hunks, viewing diffs, editing messages,
|
|
6
|
-
* and committing approved hunks one at a time.
|
|
7
|
-
*/
|
|
8
|
-
import type { ExtensionAPI, ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
9
|
-
export declare function handleGitDiff(pi: ExtensionAPI, ctx: ExtensionCommandContext, args: string): Promise<void>;
|
|
10
|
-
//# sourceMappingURL=git-diff.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"git-diff.d.ts","sourceRoot":"","sources":["../../src/commands/git-diff.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,uBAAuB,EACxB,MAAM,iCAAiC,CAAC;AAoDzC,wBAAsB,aAAa,CACjC,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,uBAAuB,EAC5B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CA+Qf"}
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* /git-diff command
|
|
3
|
-
*
|
|
4
|
-
* Interactive diff review with sequential hunk approval.
|
|
5
|
-
* Allows reviewing AI-generated hunks, viewing diffs, editing messages,
|
|
6
|
-
* and committing approved hunks one at a time.
|
|
7
|
-
*/
|
|
8
|
-
import { analyzeDiff, parseDiffStats, processHunks, splitDiffByFile, } from "../core/diff-analyzer.js";
|
|
9
|
-
import { collectDiff, ensureReadyToCommit, resetStaging, stageFiles, } from "../core/git.js";
|
|
10
|
-
import { isJapanese } from "../utils/lang.js";
|
|
11
|
-
import { getLanguage } from "../utils/settings.js";
|
|
12
|
-
import { footerManager } from "../utils/footer-manager.js";
|
|
13
|
-
import { HunkReviewComponent, } from "../tui/hunk-review.js";
|
|
14
|
-
/**
|
|
15
|
-
* Review a single hunk using the TUI component
|
|
16
|
-
*/
|
|
17
|
-
async function reviewHunk(ctx, hunk, hunkIndex, totalHunks, fileStats, fileDiffs) {
|
|
18
|
-
if (!ctx.hasUI) {
|
|
19
|
-
return { type: "quit" };
|
|
20
|
-
}
|
|
21
|
-
return await ctx.ui.custom((tui, theme, _keybindings, done) => {
|
|
22
|
-
const component = new HunkReviewComponent(hunk, hunkIndex, totalHunks, fileStats, fileDiffs, tui, theme, done);
|
|
23
|
-
return component;
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
export async function handleGitDiff(pi, ctx, args) {
|
|
27
|
-
const lang = getLanguage(ctx.cwd);
|
|
28
|
-
const ja = isJapanese(lang);
|
|
29
|
-
if (/--help/.test(args)) {
|
|
30
|
-
const lines = ja
|
|
31
|
-
? [
|
|
32
|
-
"/git-diff [--help]",
|
|
33
|
-
"",
|
|
34
|
-
"AIが生成したhunkを対話的にレビューし、承認したものをコミットします。",
|
|
35
|
-
"",
|
|
36
|
-
"オプション:",
|
|
37
|
-
" --help このヘルプを表示",
|
|
38
|
-
"",
|
|
39
|
-
"操作:",
|
|
40
|
-
" ↑↓ ファイル間を移動",
|
|
41
|
-
" Enter 選択したファイルのdiffを表示",
|
|
42
|
-
" a hunkを承認してコミット",
|
|
43
|
-
" e コミットメッセージを編集",
|
|
44
|
-
" s hunkをスキップ",
|
|
45
|
-
" x 選択したファイルをhunkから除外",
|
|
46
|
-
" q 終了",
|
|
47
|
-
]
|
|
48
|
-
: [
|
|
49
|
-
"/git-diff [--help]",
|
|
50
|
-
"",
|
|
51
|
-
"Interactively review AI-generated hunks and commit approved ones.",
|
|
52
|
-
"",
|
|
53
|
-
"Options:",
|
|
54
|
-
" --help Show this help message",
|
|
55
|
-
"",
|
|
56
|
-
"Controls:",
|
|
57
|
-
" ↑↓ Navigate between files",
|
|
58
|
-
" Enter View diff for selected file",
|
|
59
|
-
" a Approve and commit hunk",
|
|
60
|
-
" e Edit commit message",
|
|
61
|
-
" s Skip hunk",
|
|
62
|
-
" x Exclude selected file from hunk",
|
|
63
|
-
" q Quit",
|
|
64
|
-
];
|
|
65
|
-
if (ctx.hasUI) {
|
|
66
|
-
ctx.ui.notify(lines.join("\n"), "info");
|
|
67
|
-
}
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
if (!ctx.hasUI) {
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
|
-
// Check if agg-commit is running
|
|
74
|
-
if (footerManager.isRunning()) {
|
|
75
|
-
ctx.ui.notify(ja
|
|
76
|
-
? "git-agg-commit 実行中です。完了してから再度実行してください。"
|
|
77
|
-
: "git-agg-commit is already running. Please wait for it to complete.", "warning");
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
await footerManager.setRunning("diff", "prepare");
|
|
81
|
-
try {
|
|
82
|
-
const preCheck = await ensureReadyToCommit(pi, ctx.cwd);
|
|
83
|
-
if (preCheck) {
|
|
84
|
-
await footerManager.clearRunning();
|
|
85
|
-
ctx.ui.notify(preCheck === "not_git_repo"
|
|
86
|
-
? ja ? "Gitリポジトリではありません" : "Not a git repository"
|
|
87
|
-
: ja ? "コミットする変更がありません" : "No changes to commit", preCheck === "not_git_repo" ? "warning" : "info");
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
// Collect diff via stash to freeze the working tree
|
|
91
|
-
await footerManager.setPhase("collectDiff");
|
|
92
|
-
const diff = await collectDiff(pi, ctx.cwd);
|
|
93
|
-
if (diff === null) {
|
|
94
|
-
await footerManager.clearRunning();
|
|
95
|
-
ctx.ui.notify(ja ? "変更のstashに失敗しました" : "Failed to stash changes", "warning");
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (!diff.trim()) {
|
|
99
|
-
await footerManager.clearRunning();
|
|
100
|
-
ctx.ui.notify(ja ? "コミットする変更がありません" : "No changes to commit", "info");
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
// Parse diff by file
|
|
104
|
-
const fileDiffs = splitDiffByFile(diff);
|
|
105
|
-
const fileStats = parseDiffStats(diff);
|
|
106
|
-
// Analyze diff into hunks
|
|
107
|
-
await footerManager.setPhase("analyze");
|
|
108
|
-
let hunks = await analyzeDiff(pi, ctx, diff, lang);
|
|
109
|
-
if (hunks.length === 0) {
|
|
110
|
-
await footerManager.clearRunning();
|
|
111
|
-
ctx.ui.notify(ja ? "コミット可能なhunkがありません" : "No hunks found to commit", "info");
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// Sanitize, deduplicate, and filter hunks
|
|
115
|
-
hunks = processHunks(hunks);
|
|
116
|
-
await footerManager.clearRunning();
|
|
117
|
-
// Review each hunk sequentially
|
|
118
|
-
const unassignedFiles = [];
|
|
119
|
-
let committedCount = 0;
|
|
120
|
-
let skippedCount = 0;
|
|
121
|
-
let quitRequested = false;
|
|
122
|
-
for (let i = 0; i < hunks.length; i++) {
|
|
123
|
-
const hunk = hunks[i];
|
|
124
|
-
let currentMessage = hunk.message;
|
|
125
|
-
// Review loop (for message editing)
|
|
126
|
-
while (true) {
|
|
127
|
-
const action = await reviewHunk(ctx, { ...hunk, message: currentMessage }, i, hunks.length, fileStats, fileDiffs);
|
|
128
|
-
if (action.type === "quit") {
|
|
129
|
-
// Add current and remaining hunks' files to unassigned
|
|
130
|
-
for (let j = i; j < hunks.length; j++) {
|
|
131
|
-
unassignedFiles.push(...hunks[j].files);
|
|
132
|
-
}
|
|
133
|
-
quitRequested = true;
|
|
134
|
-
break;
|
|
135
|
-
}
|
|
136
|
-
if (action.type === "edit_message") {
|
|
137
|
-
// Edit message using pi's built-in input dialog (IME-supported)
|
|
138
|
-
const newMessage = await ctx.ui.input(ja ? "コミットメッセージを編集:" : "Edit commit message:", action.currentMessage);
|
|
139
|
-
if (newMessage && newMessage.trim()) {
|
|
140
|
-
currentMessage = newMessage.trim();
|
|
141
|
-
}
|
|
142
|
-
// Continue loop to re-show the hunk with updated message
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
|
-
if (action.type === "skip") {
|
|
146
|
-
// Add non-excluded files to unassigned
|
|
147
|
-
const files = hunk.files.filter((f) => !action.excludedFiles.includes(f));
|
|
148
|
-
unassignedFiles.push(...files, ...action.excludedFiles);
|
|
149
|
-
skippedCount++;
|
|
150
|
-
break;
|
|
151
|
-
}
|
|
152
|
-
if (action.type === "approve") {
|
|
153
|
-
// Stage and commit non-excluded files
|
|
154
|
-
const files = hunk.files.filter((f) => !action.excludedFiles.includes(f));
|
|
155
|
-
if (files.length === 0) {
|
|
156
|
-
ctx.ui.notify(ja
|
|
157
|
-
? "コミットするファイルがありません"
|
|
158
|
-
: "No files to commit", "warning");
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
await stageFiles(pi, files, ctx.cwd);
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
ctx.ui.notify(ja
|
|
166
|
-
? `ファイルのステージに失敗しました: ${error instanceof Error ? error.message : String(error)}`
|
|
167
|
-
: `Failed to stage files: ${error instanceof Error ? error.message : String(error)}`, "error");
|
|
168
|
-
break;
|
|
169
|
-
}
|
|
170
|
-
const { code: exitCode, stderr } = await pi.exec("git", ["commit", "-m", action.message], { cwd: ctx.cwd });
|
|
171
|
-
if (exitCode !== 0) {
|
|
172
|
-
try {
|
|
173
|
-
await resetStaging(pi, ctx.cwd);
|
|
174
|
-
}
|
|
175
|
-
catch {
|
|
176
|
-
// Ignore reset errors
|
|
177
|
-
}
|
|
178
|
-
const detail = stderr.trim() ? ` — ${stderr.trim()}` : "";
|
|
179
|
-
ctx.ui.notify(ja
|
|
180
|
-
? `コミットに失敗しました: "${action.message}" (exit code ${exitCode})${detail}。ステージをリセットしました。`
|
|
181
|
-
: `Commit failed for "${action.message}" (exit code ${exitCode}).${detail} Staging has been reset.`, "warning");
|
|
182
|
-
break;
|
|
183
|
-
}
|
|
184
|
-
committedCount++;
|
|
185
|
-
// Add excluded files to unassigned
|
|
186
|
-
unassignedFiles.push(...action.excludedFiles);
|
|
187
|
-
break;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (quitRequested)
|
|
191
|
-
break;
|
|
192
|
-
}
|
|
193
|
-
// Show summary
|
|
194
|
-
const parts = [];
|
|
195
|
-
if (committedCount > 0) {
|
|
196
|
-
parts.push(ja
|
|
197
|
-
? `${committedCount}個のhunkをコミットしました`
|
|
198
|
-
: `Committed ${committedCount} hunk${committedCount > 1 ? "s" : ""}`);
|
|
199
|
-
}
|
|
200
|
-
if (skippedCount > 0) {
|
|
201
|
-
parts.push(ja
|
|
202
|
-
? `${skippedCount}個のhunkをスキップしました`
|
|
203
|
-
: `Skipped ${skippedCount} hunk${skippedCount > 1 ? "s" : ""}`);
|
|
204
|
-
}
|
|
205
|
-
if (parts.length > 0) {
|
|
206
|
-
ctx.ui.notify(parts.join(", "), "info");
|
|
207
|
-
}
|
|
208
|
-
// Show unassigned files
|
|
209
|
-
if (unassignedFiles.length > 0) {
|
|
210
|
-
const lines = ja
|
|
211
|
-
? [
|
|
212
|
-
"",
|
|
213
|
-
`⚠ ${unassignedFiles.length}個のファイルが未割り当てです:`,
|
|
214
|
-
...unassignedFiles.map((f) => ` ${f}`),
|
|
215
|
-
]
|
|
216
|
-
: [
|
|
217
|
-
"",
|
|
218
|
-
`⚠ ${unassignedFiles.length} file${unassignedFiles.length > 1 ? "s" : ""} remain unassigned:`,
|
|
219
|
-
...unassignedFiles.map((f) => ` ${f}`),
|
|
220
|
-
];
|
|
221
|
-
ctx.ui.notify(lines.join("\n"), "info");
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
finally {
|
|
225
|
-
await footerManager.clearRunning();
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
//# sourceMappingURL=git-diff.js.map
|