gitxelectron 1.2.6 → 1.2.8
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/out/main/index.js +259 -23
- package/out/preload/index.js +5 -0
- package/out/renderer/assets/{index-C-5ryxXi.js → index-Cn2WMJc6.js} +499 -4
- package/out/renderer/assets/index-DOm7Sn2B.css +1365 -0
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/out/renderer/assets/index-ByoEJy2t.css +0 -1365
package/out/main/index.js
CHANGED
|
@@ -4,6 +4,8 @@ const path = require("path");
|
|
|
4
4
|
const fs = require("fs/promises");
|
|
5
5
|
const simpleGit = require("simple-git");
|
|
6
6
|
const crypto = require("crypto");
|
|
7
|
+
const child_process = require("child_process");
|
|
8
|
+
const readline = require("readline");
|
|
7
9
|
const generativeAi = require("@google/generative-ai");
|
|
8
10
|
const OpenAI = require("openai");
|
|
9
11
|
const chokidar = require("chokidar");
|
|
@@ -26,6 +28,7 @@ function _interopNamespaceDefault(e) {
|
|
|
26
28
|
}
|
|
27
29
|
const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path);
|
|
28
30
|
const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
|
|
31
|
+
const readline__namespace = /* @__PURE__ */ _interopNamespaceDefault(readline);
|
|
29
32
|
const GITHUB_CLIENT_ID = "Ov23livWfiaPADGiwSXq";
|
|
30
33
|
let accounts = [];
|
|
31
34
|
const activeSessions = /* @__PURE__ */ new Map();
|
|
@@ -690,9 +693,56 @@ async function initializeRepo(sessionId, dir) {
|
|
|
690
693
|
}
|
|
691
694
|
}
|
|
692
695
|
async function getStatus(sessionId) {
|
|
693
|
-
const { git } = getGitSession(sessionId);
|
|
694
|
-
|
|
695
|
-
|
|
696
|
+
const { git, repoPath } = getGitSession(sessionId);
|
|
697
|
+
return new Promise((resolve, reject) => {
|
|
698
|
+
const child = child_process.spawn("git", ["status", "--porcelain"], { cwd: repoPath });
|
|
699
|
+
let count = 0;
|
|
700
|
+
let isMassive = false;
|
|
701
|
+
child.stdout.on("data", (chunk) => {
|
|
702
|
+
for (let i = 0; i < chunk.length; ++i) {
|
|
703
|
+
if (chunk[i] === 10) {
|
|
704
|
+
count++;
|
|
705
|
+
if (count > 1e4) {
|
|
706
|
+
isMassive = true;
|
|
707
|
+
child.kill();
|
|
708
|
+
break;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
child.on("close", async () => {
|
|
714
|
+
if (isMassive) {
|
|
715
|
+
resolve({
|
|
716
|
+
not_added: [],
|
|
717
|
+
created: [],
|
|
718
|
+
deleted: [],
|
|
719
|
+
modified: [],
|
|
720
|
+
conflicted: [],
|
|
721
|
+
renamed: [],
|
|
722
|
+
staged: [],
|
|
723
|
+
files: [],
|
|
724
|
+
current: "main",
|
|
725
|
+
ahead: 0,
|
|
726
|
+
behind: 0,
|
|
727
|
+
tracking: null,
|
|
728
|
+
isMassive: true,
|
|
729
|
+
totalChanges: count
|
|
730
|
+
});
|
|
731
|
+
} else {
|
|
732
|
+
try {
|
|
733
|
+
const status = await git.status();
|
|
734
|
+
const result = JSON.parse(JSON.stringify(status));
|
|
735
|
+
result.isMassive = false;
|
|
736
|
+
result.totalChanges = count;
|
|
737
|
+
if (!result.staged) result.staged = [];
|
|
738
|
+
resolve(result);
|
|
739
|
+
} catch (e) {
|
|
740
|
+
reject(e);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
});
|
|
744
|
+
child.on("error", reject);
|
|
745
|
+
});
|
|
696
746
|
}
|
|
697
747
|
async function stageFiles(sessionId, files) {
|
|
698
748
|
const { git, repoPath } = getGitSession(sessionId);
|
|
@@ -727,7 +777,15 @@ async function stageFiles(sessionId, files) {
|
|
|
727
777
|
const chunkSize = 50;
|
|
728
778
|
for (let i = 0; i < fileArray.length; i += chunkSize) {
|
|
729
779
|
const chunk = fileArray.slice(i, i + chunkSize);
|
|
730
|
-
|
|
780
|
+
try {
|
|
781
|
+
await git.raw(["-c", "core.safecrlf=false", "-c", "core.autocrlf=false", "add", "--force", ...chunk]);
|
|
782
|
+
} catch (e) {
|
|
783
|
+
if (e.message && e.message.includes("LF will be replaced by CRLF") && !e.message.includes("fatal:")) {
|
|
784
|
+
console.warn("Ignored CRLF warning during stage");
|
|
785
|
+
} else {
|
|
786
|
+
throw e;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
731
789
|
}
|
|
732
790
|
return true;
|
|
733
791
|
}
|
|
@@ -779,6 +837,123 @@ function injectAuthToken(sessionId, remoteUrl) {
|
|
|
779
837
|
}
|
|
780
838
|
return remoteUrl;
|
|
781
839
|
}
|
|
840
|
+
async function pushMassiveRepository(sessionId, remote, branch, chunkSize = 5e3, onProgress, onDetailedProgress) {
|
|
841
|
+
const { repoPath } = getGitSession(sessionId);
|
|
842
|
+
if (onProgress) onProgress("Starting rapid file count to prepare massive chunking...");
|
|
843
|
+
const totalFiles = await new Promise((resolve) => {
|
|
844
|
+
const child2 = child_process.spawn("git", ["status", "--porcelain"], { cwd: repoPath });
|
|
845
|
+
let count = 0;
|
|
846
|
+
child2.stdout.on("data", (chunk) => {
|
|
847
|
+
for (let i = 0; i < chunk.length; ++i) {
|
|
848
|
+
if (chunk[i] === 10) count++;
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
child2.on("close", () => resolve(count));
|
|
852
|
+
child2.on("error", () => resolve(0));
|
|
853
|
+
});
|
|
854
|
+
if (totalFiles === 0) {
|
|
855
|
+
if (onProgress) onProgress("No files to push.");
|
|
856
|
+
return true;
|
|
857
|
+
}
|
|
858
|
+
if (onProgress) onProgress(`Total files to push: ${totalFiles}. Starting chunked upload...`);
|
|
859
|
+
const { git } = getGitSession(sessionId);
|
|
860
|
+
const remotes = await getRemotes(sessionId);
|
|
861
|
+
const remoteObj = remotes.find((r) => r.name === remote);
|
|
862
|
+
if (onProgress) onProgress("Starting massive repository push...");
|
|
863
|
+
await git.addConfig("http.postBuffer", "1048576000");
|
|
864
|
+
await git.addConfig("core.safecrlf", "false");
|
|
865
|
+
await git.addConfig("core.autocrlf", "false");
|
|
866
|
+
let authUrl = remote;
|
|
867
|
+
if (remoteObj && remoteObj.refs.push) {
|
|
868
|
+
authUrl = injectAuthToken(sessionId, remoteObj.refs.push);
|
|
869
|
+
}
|
|
870
|
+
const child = child_process.spawn("git", ["status", "--porcelain"], { cwd: repoPath });
|
|
871
|
+
const rl = readline__namespace.createInterface({
|
|
872
|
+
input: child.stdout,
|
|
873
|
+
crlfDelay: Infinity
|
|
874
|
+
});
|
|
875
|
+
let currentChunk = [];
|
|
876
|
+
let chunkCount = 0;
|
|
877
|
+
let processedFiles = 0;
|
|
878
|
+
const startTime = Date.now();
|
|
879
|
+
const processChunk = async (chunk) => {
|
|
880
|
+
chunkCount++;
|
|
881
|
+
processedFiles += chunk.length;
|
|
882
|
+
const percentage = Math.min(100, processedFiles / totalFiles * 100);
|
|
883
|
+
const elapsedMs = Date.now() - startTime;
|
|
884
|
+
const msPerFile = elapsedMs / processedFiles;
|
|
885
|
+
const remainingFiles = totalFiles - processedFiles;
|
|
886
|
+
const etaMs = msPerFile * remainingFiles;
|
|
887
|
+
const formatEta = (ms) => {
|
|
888
|
+
if (!isFinite(ms) || ms < 0) return "calculating...";
|
|
889
|
+
const totalSec = Math.floor(ms / 1e3);
|
|
890
|
+
const min = Math.floor(totalSec / 60);
|
|
891
|
+
const sec = totalSec % 60;
|
|
892
|
+
if (min > 0) return `${min}m ${sec}s left`;
|
|
893
|
+
return `${sec}s left`;
|
|
894
|
+
};
|
|
895
|
+
const etaStr = formatEta(etaMs);
|
|
896
|
+
if (onProgress) onProgress(`Processing chunk ${chunkCount} (${chunk.length} files)... ETA: ${etaStr}`);
|
|
897
|
+
if (onDetailedProgress) {
|
|
898
|
+
onDetailedProgress({
|
|
899
|
+
processed: processedFiles,
|
|
900
|
+
total: totalFiles,
|
|
901
|
+
percentage,
|
|
902
|
+
eta: etaStr
|
|
903
|
+
});
|
|
904
|
+
}
|
|
905
|
+
const tempFile = path__namespace.join(repoPath, ".git", "massive_chunk.txt");
|
|
906
|
+
await fs__namespace.writeFile(tempFile, chunk.join("\n"), "utf-8");
|
|
907
|
+
try {
|
|
908
|
+
await git.raw(["-c", "core.safecrlf=false", "add", "--force", "--pathspec-from-file=" + tempFile]);
|
|
909
|
+
} catch (e) {
|
|
910
|
+
if (e.message && e.message.includes("fatal:")) {
|
|
911
|
+
throw e;
|
|
912
|
+
}
|
|
913
|
+
} finally {
|
|
914
|
+
try {
|
|
915
|
+
await fs__namespace.unlink(tempFile);
|
|
916
|
+
} catch (e) {
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
try {
|
|
920
|
+
await git.commit(`Auto-sync chunk ${chunkCount} (Massive Push)`);
|
|
921
|
+
} catch (e) {
|
|
922
|
+
}
|
|
923
|
+
try {
|
|
924
|
+
await git.raw(["-c", "credential.helper=", "push", authUrl, branch]);
|
|
925
|
+
} catch (err) {
|
|
926
|
+
if (err.message && (err.message.includes("non-fast-forward") || err.message.includes("fetch first") || err.message.includes("branch is behind"))) {
|
|
927
|
+
await git.pull(authUrl, branch, { "--rebase": null, "--autostash": null });
|
|
928
|
+
await git.raw(["-c", "credential.helper=", "push", authUrl, branch]);
|
|
929
|
+
} else {
|
|
930
|
+
if (err.message && !err.message.includes("nothing to commit")) {
|
|
931
|
+
throw err;
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
for await (const line of rl) {
|
|
937
|
+
if (line.length < 3) continue;
|
|
938
|
+
let file = line.substring(3).trim();
|
|
939
|
+
if (file.startsWith('"') && file.endsWith('"')) {
|
|
940
|
+
file = file.substring(1, file.length - 1);
|
|
941
|
+
}
|
|
942
|
+
if (!file) continue;
|
|
943
|
+
currentChunk.push(file);
|
|
944
|
+
if (currentChunk.length >= chunkSize) {
|
|
945
|
+
rl.pause();
|
|
946
|
+
await processChunk(currentChunk);
|
|
947
|
+
currentChunk = [];
|
|
948
|
+
rl.resume();
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
if (currentChunk.length > 0) {
|
|
952
|
+
await processChunk(currentChunk);
|
|
953
|
+
}
|
|
954
|
+
if (onProgress) onProgress("✅ Massive push completed successfully!");
|
|
955
|
+
return true;
|
|
956
|
+
}
|
|
782
957
|
async function pushToRemote(sessionId, remote, branch) {
|
|
783
958
|
const remotes = await getRemotes(sessionId);
|
|
784
959
|
const remoteObj = remotes.find((r) => r.name === remote);
|
|
@@ -1127,7 +1302,15 @@ async function commitUniversalWorkspace(workspacePath, message, branch) {
|
|
|
1127
1302
|
GIT_TERMINAL_PROMPT: "0",
|
|
1128
1303
|
GIT_ASKPASS: "echo"
|
|
1129
1304
|
});
|
|
1130
|
-
|
|
1305
|
+
try {
|
|
1306
|
+
await git.raw(["-c", "core.safecrlf=false", "-c", "core.autocrlf=false", "add", "--sparse", "."]);
|
|
1307
|
+
} catch (e) {
|
|
1308
|
+
if (e.message && e.message.includes("LF will be replaced by CRLF") && !e.message.includes("fatal:")) {
|
|
1309
|
+
console.warn("Ignored CRLF warning in universal workspace");
|
|
1310
|
+
} else {
|
|
1311
|
+
throw e;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1131
1314
|
await git.commit(message);
|
|
1132
1315
|
try {
|
|
1133
1316
|
await git.raw(["-c", "credential.helper=", "push", "origin", branch]);
|
|
@@ -1193,11 +1376,11 @@ async function cloneRepository(sessionId, remoteUrl, destPath) {
|
|
|
1193
1376
|
} else {
|
|
1194
1377
|
await existingGit.raw(["remote", "add", "origin", authUrl]);
|
|
1195
1378
|
}
|
|
1196
|
-
await existingGit.raw(["-c", "credential.helper=", "fetch", "origin"]);
|
|
1379
|
+
await existingGit.raw(["-c", "credential.helper=", "fetch", "--progress", "origin"]);
|
|
1197
1380
|
const st = await existingGit.status();
|
|
1198
1381
|
const branch = st.current || "main";
|
|
1199
1382
|
try {
|
|
1200
|
-
await existingGit.raw(["-c", "credential.helper=", "pull", "origin", branch]);
|
|
1383
|
+
await existingGit.raw(["-c", "credential.helper=", "pull", "--progress", "origin", branch]);
|
|
1201
1384
|
} catch (e) {
|
|
1202
1385
|
}
|
|
1203
1386
|
return destPath;
|
|
@@ -1207,7 +1390,7 @@ async function cloneRepository(sessionId, remoteUrl, destPath) {
|
|
|
1207
1390
|
}
|
|
1208
1391
|
if (destExists && destIsEmpty) {
|
|
1209
1392
|
const emptyDirGit = createSafeGit(destPath, sessionId);
|
|
1210
|
-
await emptyDirGit.raw(["-c", "credential.helper=", "clone", authUrl, "."]);
|
|
1393
|
+
await emptyDirGit.raw(["-c", "credential.helper=", "clone", "--progress", authUrl, "."]);
|
|
1211
1394
|
try {
|
|
1212
1395
|
await createSafeGit(void 0, sessionId).raw(["config", "--global", "--add", "safe.directory", destPath]);
|
|
1213
1396
|
} catch (e) {
|
|
@@ -1222,7 +1405,7 @@ async function cloneRepository(sessionId, remoteUrl, destPath) {
|
|
|
1222
1405
|
const baseDir = path__namespace.dirname(destPath);
|
|
1223
1406
|
const targetDirName = path__namespace.basename(destPath);
|
|
1224
1407
|
const parentGit = createSafeGit(baseDir, sessionId);
|
|
1225
|
-
await parentGit.raw(["-c", "credential.helper=", "clone", authUrl, targetDirName]);
|
|
1408
|
+
await parentGit.raw(["-c", "credential.helper=", "clone", "--progress", authUrl, targetDirName]);
|
|
1226
1409
|
try {
|
|
1227
1410
|
await createSafeGit(void 0, sessionId).raw(["config", "--global", "--add", "safe.directory", destPath]);
|
|
1228
1411
|
} catch (e) {
|
|
@@ -1243,6 +1426,16 @@ async function cloneRepository(sessionId, remoteUrl, destPath) {
|
|
|
1243
1426
|
throw new Error(cleanMsg);
|
|
1244
1427
|
}
|
|
1245
1428
|
}
|
|
1429
|
+
async function removeGitMetadata(_sessionId, repoPath) {
|
|
1430
|
+
try {
|
|
1431
|
+
const gitDir = path__namespace.join(repoPath, ".git");
|
|
1432
|
+
await fs__namespace.rm(gitDir, { recursive: true, force: true });
|
|
1433
|
+
return true;
|
|
1434
|
+
} catch (e) {
|
|
1435
|
+
console.error("Failed to remove git metadata:", e);
|
|
1436
|
+
return false;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1246
1439
|
const SYSTEM_PROMPT = `You are an autonomous Git Healer Agent for the "GitElectron" app.
|
|
1247
1440
|
The user has encountered a Git error during a push, pull, or merge operation and you are executing as a background process to silently fix it.
|
|
1248
1441
|
You will receive the Git Status and the Raw Error Message.
|
|
@@ -1517,13 +1710,15 @@ let isResolving = false;
|
|
|
1517
1710
|
let globalOnLog = null;
|
|
1518
1711
|
let globalOnErrorApproval = null;
|
|
1519
1712
|
let globalOnResolveComplete = null;
|
|
1713
|
+
let globalOnMassiveProgress = null;
|
|
1520
1714
|
const DEBOUNCE_MS = 3e3;
|
|
1521
1715
|
const changedFiles = /* @__PURE__ */ new Set();
|
|
1522
|
-
function toggleAutoSync(sessionId, repoPath, enabled, onLog, onErrorApproval, onResolveComplete) {
|
|
1716
|
+
function toggleAutoSync(sessionId, repoPath, enabled, onLog, onErrorApproval, onResolveComplete, onMassiveProgress) {
|
|
1523
1717
|
isAutoSyncEnabled = enabled;
|
|
1524
1718
|
globalOnLog = onLog;
|
|
1525
1719
|
if (onErrorApproval) globalOnErrorApproval = onErrorApproval;
|
|
1526
1720
|
if (onResolveComplete) globalOnResolveComplete = onResolveComplete;
|
|
1721
|
+
if (onMassiveProgress) globalOnMassiveProgress = onMassiveProgress;
|
|
1527
1722
|
if (currentWatcher) {
|
|
1528
1723
|
currentWatcher.close();
|
|
1529
1724
|
currentWatcher = null;
|
|
@@ -1553,7 +1748,11 @@ function toggleAutoSync(sessionId, repoPath, enabled, onLog, onErrorApproval, on
|
|
|
1553
1748
|
currentWatcher.on("all", (_event, filePath) => {
|
|
1554
1749
|
if (!isAutoSyncEnabled || isResolving) return;
|
|
1555
1750
|
const relativePath = path__namespace.relative(repoPath, filePath).replace(/\\/g, "/");
|
|
1556
|
-
changedFiles.
|
|
1751
|
+
if (changedFiles.size < 1e4) {
|
|
1752
|
+
changedFiles.add(relativePath);
|
|
1753
|
+
} else if (!changedFiles.has("__MASSIVE__")) {
|
|
1754
|
+
changedFiles.add("__MASSIVE__");
|
|
1755
|
+
}
|
|
1557
1756
|
if (syncTimeout) {
|
|
1558
1757
|
clearTimeout(syncTimeout);
|
|
1559
1758
|
}
|
|
@@ -1574,9 +1773,29 @@ async function triggerSyncSequence(sessionId, _repoPath, onLog) {
|
|
|
1574
1773
|
onLog("No valid files to sync (temp files filtered).");
|
|
1575
1774
|
return;
|
|
1576
1775
|
}
|
|
1577
|
-
|
|
1776
|
+
if (changedFiles.has("__MASSIVE__")) {
|
|
1777
|
+
onLog("Massive file changes detected in watcher. Checking status...");
|
|
1778
|
+
}
|
|
1578
1779
|
const status = await getStatus(sessionId);
|
|
1579
|
-
|
|
1780
|
+
if (status.isMassive) {
|
|
1781
|
+
onLog(`🚨 Massive repository change detected! Engaging chunked sync mode...`);
|
|
1782
|
+
const branch2 = status.current || "main";
|
|
1783
|
+
const success = await pushMassiveRepository(
|
|
1784
|
+
sessionId,
|
|
1785
|
+
"origin",
|
|
1786
|
+
branch2,
|
|
1787
|
+
5e3,
|
|
1788
|
+
onLog,
|
|
1789
|
+
globalOnMassiveProgress || void 0
|
|
1790
|
+
);
|
|
1791
|
+
if (success) {
|
|
1792
|
+
onLog(`✅ Successfully pushed massive repository sync!`);
|
|
1793
|
+
}
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
await stageFiles(sessionId, existingFiles);
|
|
1797
|
+
const finalStatus = await getStatus(sessionId);
|
|
1798
|
+
const branch = finalStatus.current || "main";
|
|
1580
1799
|
onLog("Generating AI commit message...");
|
|
1581
1800
|
let commitMsg = `Auto-sync: update ${filesToSync.length > 1 ? filesToSync.length + " files" : filesToSync[0]}`;
|
|
1582
1801
|
try {
|
|
@@ -1688,7 +1907,15 @@ async function applyAiFixAndResume(sessionId, resolvedCode) {
|
|
|
1688
1907
|
if (resolvedCode) {
|
|
1689
1908
|
for (const [file, content] of Object.entries(resolvedCode)) {
|
|
1690
1909
|
await fs__namespace.writeFile(path__namespace.join(repoPath, file), content, "utf-8");
|
|
1691
|
-
|
|
1910
|
+
try {
|
|
1911
|
+
await git.raw(["-c", "core.safecrlf=false", "-c", "core.autocrlf=false", "add", "--force", file]);
|
|
1912
|
+
} catch (e) {
|
|
1913
|
+
if (e.message && e.message.includes("LF will be replaced by CRLF") && !e.message.includes("fatal:")) {
|
|
1914
|
+
console.warn("Ignored CRLF warning during AI fix apply");
|
|
1915
|
+
} else {
|
|
1916
|
+
throw e;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1692
1919
|
}
|
|
1693
1920
|
}
|
|
1694
1921
|
try {
|
|
@@ -1851,6 +2078,17 @@ electron.app.whenReady().then(async () => {
|
|
|
1851
2078
|
return await commitChanges(event.sender.id, message);
|
|
1852
2079
|
});
|
|
1853
2080
|
electron.ipcMain.handle("push-to-remote", async (event, remote, branch) => {
|
|
2081
|
+
const status = await getStatus(event.sender.id);
|
|
2082
|
+
if (status.isMassive) {
|
|
2083
|
+
return await pushMassiveRepository(
|
|
2084
|
+
event.sender.id,
|
|
2085
|
+
remote,
|
|
2086
|
+
branch,
|
|
2087
|
+
5e3,
|
|
2088
|
+
void 0,
|
|
2089
|
+
(data) => event.sender.send("massive-push-progress", data)
|
|
2090
|
+
);
|
|
2091
|
+
}
|
|
1854
2092
|
return await pushToRemote(event.sender.id, remote, branch);
|
|
1855
2093
|
});
|
|
1856
2094
|
electron.ipcMain.handle("pull-from-remote", async (event, remote, branch) => {
|
|
@@ -2040,6 +2278,9 @@ electron.app.whenReady().then(async () => {
|
|
|
2040
2278
|
electron.ipcMain.handle("clone-repository", async (event, remoteUrl, destPath) => {
|
|
2041
2279
|
return await cloneRepository(event.sender.id, remoteUrl, destPath);
|
|
2042
2280
|
});
|
|
2281
|
+
electron.ipcMain.handle("remove-git-metadata", async (event, repoPath) => {
|
|
2282
|
+
return await removeGitMetadata(event.sender.id, repoPath);
|
|
2283
|
+
});
|
|
2043
2284
|
electron.ipcMain.handle("check-path-exists", async (_event, targetPath) => {
|
|
2044
2285
|
if (!targetPath) return false;
|
|
2045
2286
|
try {
|
|
@@ -2073,15 +2314,10 @@ electron.app.whenReady().then(async () => {
|
|
|
2073
2314
|
event.sender.id,
|
|
2074
2315
|
repoPath,
|
|
2075
2316
|
enabled,
|
|
2076
|
-
(msg) =>
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
(
|
|
2080
|
-
event.sender.send("auto-sync-error-approval", payload);
|
|
2081
|
-
},
|
|
2082
|
-
() => {
|
|
2083
|
-
event.sender.send("auto-sync-resolved");
|
|
2084
|
-
}
|
|
2317
|
+
(msg) => event.sender.send("auto-sync-log", msg),
|
|
2318
|
+
(payload) => event.sender.send("auto-sync-error-approval", payload),
|
|
2319
|
+
() => event.sender.send("auto-sync-resolved"),
|
|
2320
|
+
(data) => event.sender.send("massive-push-progress", data)
|
|
2085
2321
|
);
|
|
2086
2322
|
});
|
|
2087
2323
|
electron.ipcMain.handle("approve-ai-fix", async (event, resolvedCode) => {
|
package/out/preload/index.js
CHANGED
|
@@ -13,6 +13,7 @@ const api = {
|
|
|
13
13
|
selectDirectory: () => electron.ipcRenderer.invoke("select-directory"),
|
|
14
14
|
setRepoPath: (path) => electron.ipcRenderer.invoke("set-repo-path", path),
|
|
15
15
|
initRepo: (path) => electron.ipcRenderer.invoke("init-repo", path),
|
|
16
|
+
removeGitMetadata: (repoPath) => electron.ipcRenderer.invoke("remove-git-metadata", repoPath),
|
|
16
17
|
getStatus: () => electron.ipcRenderer.invoke("get-status"),
|
|
17
18
|
stageFiles: (files) => electron.ipcRenderer.invoke("stage-files", files),
|
|
18
19
|
unstageFiles: (files) => electron.ipcRenderer.invoke("unstage-files", files),
|
|
@@ -93,6 +94,10 @@ const api = {
|
|
|
93
94
|
electron.ipcRenderer.removeAllListeners("auto-sync-resolved");
|
|
94
95
|
electron.ipcRenderer.on("auto-sync-resolved", () => callback());
|
|
95
96
|
},
|
|
97
|
+
onMassivePushProgress: (callback) => {
|
|
98
|
+
electron.ipcRenderer.removeAllListeners("massive-push-progress");
|
|
99
|
+
electron.ipcRenderer.on("massive-push-progress", (_event, data) => callback(data));
|
|
100
|
+
},
|
|
96
101
|
getAppVersion: () => electron.ipcRenderer.invoke("get-app-version"),
|
|
97
102
|
// AI Fixer API
|
|
98
103
|
askAi: (provider, apiKey, errorMsg, gitStatus, repoPath) => electron.ipcRenderer.invoke("ask-ai", provider, apiKey, errorMsg, gitStatus, repoPath),
|