gitxelectron 1.1.7 → 1.1.9
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 +286 -17
- package/out/preload/index.js +4 -0
- package/out/renderer/assets/index-BHcqstpr.css +193 -0
- package/out/renderer/assets/{index-i67_EinM.js → index-j4GZkdPL.js} +1098 -314
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/out/renderer/assets/index-D22RH28n.css +0 -193
package/out/main/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
const electron = require("electron");
|
|
3
3
|
const path = require("path");
|
|
4
|
-
const simpleGit = require("simple-git");
|
|
5
4
|
const fs = require("fs/promises");
|
|
5
|
+
const simpleGit = require("simple-git");
|
|
6
6
|
const crypto = require("crypto");
|
|
7
7
|
const generativeAi = require("@google/generative-ai");
|
|
8
8
|
const OpenAI = require("openai");
|
|
@@ -58,15 +58,23 @@ function cleanupSession(sessionId) {
|
|
|
58
58
|
activeSessions.delete(sessionId);
|
|
59
59
|
}
|
|
60
60
|
function getToken(sessionId) {
|
|
61
|
-
|
|
61
|
+
let accountId = activeSessions.get(sessionId);
|
|
62
|
+
if (!accountId && accounts.length > 0) {
|
|
63
|
+
accountId = accounts[0].id;
|
|
64
|
+
activeSessions.set(sessionId, accountId);
|
|
65
|
+
}
|
|
62
66
|
if (!accountId) return null;
|
|
63
67
|
const acc = accounts.find((a) => a.id === accountId);
|
|
64
|
-
return acc ? acc.token : null;
|
|
68
|
+
return acc ? acc.token : accounts.length > 0 ? accounts[0].token : null;
|
|
65
69
|
}
|
|
66
70
|
function getActiveAccount(sessionId) {
|
|
67
|
-
|
|
71
|
+
let accountId = activeSessions.get(sessionId);
|
|
72
|
+
if (!accountId && accounts.length > 0) {
|
|
73
|
+
accountId = accounts[0].id;
|
|
74
|
+
activeSessions.set(sessionId, accountId);
|
|
75
|
+
}
|
|
68
76
|
if (!accountId) return null;
|
|
69
|
-
return accounts.find((a) => a.id === accountId) || null;
|
|
77
|
+
return accounts.find((a) => a.id === accountId) || (accounts.length > 0 ? accounts[0] : null);
|
|
70
78
|
}
|
|
71
79
|
async function getAccounts(sessionId) {
|
|
72
80
|
return {
|
|
@@ -288,6 +296,68 @@ async function getUserRepositories(sessionId) {
|
|
|
288
296
|
}
|
|
289
297
|
return await res.json();
|
|
290
298
|
}
|
|
299
|
+
async function getCollaboratedRepos(sessionId) {
|
|
300
|
+
const token = getToken(sessionId);
|
|
301
|
+
if (!token) throw new Error("Not authenticated in this session");
|
|
302
|
+
const headers = {
|
|
303
|
+
Authorization: `Bearer ${token}`,
|
|
304
|
+
Accept: "application/vnd.github.v3+json",
|
|
305
|
+
"User-Agent": "gitelectron-App"
|
|
306
|
+
};
|
|
307
|
+
const res = await fetch(
|
|
308
|
+
"https://api.github.com/user/repos?affiliation=owner,collaborator,organization_member&per_page=100&sort=updated",
|
|
309
|
+
{ headers }
|
|
310
|
+
);
|
|
311
|
+
if (!res.ok) {
|
|
312
|
+
const errorData = await res.json().catch(() => ({}));
|
|
313
|
+
throw new Error(errorData.message || "Failed to fetch collaborated repositories");
|
|
314
|
+
}
|
|
315
|
+
const allRepos = await res.json();
|
|
316
|
+
const account = getActiveAccount(sessionId);
|
|
317
|
+
const currentUsername = account?.username?.toLowerCase() || "";
|
|
318
|
+
const externalCollabRepos = [];
|
|
319
|
+
const ownedRepos = [];
|
|
320
|
+
for (const repo of allRepos) {
|
|
321
|
+
const ownerLogin = repo.owner?.login?.toLowerCase() || "";
|
|
322
|
+
if (ownerLogin !== currentUsername) {
|
|
323
|
+
externalCollabRepos.push(repo);
|
|
324
|
+
} else {
|
|
325
|
+
ownedRepos.push(repo);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
const ownedCollabChecks = await Promise.allSettled(
|
|
329
|
+
ownedRepos.map(async (repo) => {
|
|
330
|
+
try {
|
|
331
|
+
const [collabRes, invRes] = await Promise.all([
|
|
332
|
+
fetch(`https://api.github.com/repos/${repo.owner.login}/${repo.name}/collaborators`, { headers }),
|
|
333
|
+
fetch(`https://api.github.com/repos/${repo.owner.login}/${repo.name}/invitations`, { headers })
|
|
334
|
+
]);
|
|
335
|
+
const collabs = collabRes.ok ? await collabRes.json() : [];
|
|
336
|
+
const invs = invRes.ok ? await invRes.json() : [];
|
|
337
|
+
const hasOtherCollabs = Array.isArray(collabs) && collabs.some(
|
|
338
|
+
(c) => c.login && c.login.toLowerCase() !== currentUsername
|
|
339
|
+
);
|
|
340
|
+
const hasPendingInvs = Array.isArray(invs) && invs.length > 0;
|
|
341
|
+
if (hasOtherCollabs || hasPendingInvs) {
|
|
342
|
+
return {
|
|
343
|
+
...repo,
|
|
344
|
+
collaboratorsList: collabs,
|
|
345
|
+
hasPendingInvitations: hasPendingInvs
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
} catch (err) {
|
|
349
|
+
}
|
|
350
|
+
return null;
|
|
351
|
+
})
|
|
352
|
+
);
|
|
353
|
+
const ownedCollabRepos = [];
|
|
354
|
+
for (const result of ownedCollabChecks) {
|
|
355
|
+
if (result.status === "fulfilled" && result.value) {
|
|
356
|
+
ownedCollabRepos.push(result.value);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
return [...externalCollabRepos, ...ownedCollabRepos];
|
|
360
|
+
}
|
|
291
361
|
async function createGitHubRepository(sessionId, name, description, isPrivate, autoInit = false, gitignoreTemplate = "", licenseTemplate = "") {
|
|
292
362
|
const token = getToken(sessionId);
|
|
293
363
|
if (!token) throw new Error("Not authenticated in this session");
|
|
@@ -390,7 +460,9 @@ async function removeCollaborator(sessionId, remoteUrl, usernameOrId, isInvitati
|
|
|
390
460
|
async function searchGitHubUser(sessionId, username) {
|
|
391
461
|
const token = getToken(sessionId);
|
|
392
462
|
if (!token) throw new Error("Not authenticated");
|
|
393
|
-
const
|
|
463
|
+
const trimmed = username.trim();
|
|
464
|
+
if (!trimmed) return null;
|
|
465
|
+
const res = await fetch(`https://api.github.com/users/${encodeURIComponent(trimmed)}`, {
|
|
394
466
|
headers: {
|
|
395
467
|
Authorization: `Bearer ${token}`,
|
|
396
468
|
Accept: "application/vnd.github.v3+json",
|
|
@@ -407,17 +479,32 @@ async function searchGitHubUser(sessionId, username) {
|
|
|
407
479
|
async function searchGitHubUsers(sessionId, query) {
|
|
408
480
|
const token = getToken(sessionId);
|
|
409
481
|
if (!token) throw new Error("Not authenticated");
|
|
410
|
-
|
|
411
|
-
|
|
482
|
+
const trimmed = query.trim();
|
|
483
|
+
if (!trimmed) return [];
|
|
484
|
+
const searchPromise = fetch(
|
|
485
|
+
`https://api.github.com/search/users?q=${encodeURIComponent(trimmed)}+type:user&per_page=15`,
|
|
486
|
+
{
|
|
487
|
+
headers: {
|
|
488
|
+
Authorization: `Bearer ${token}`,
|
|
489
|
+
Accept: "application/vnd.github.v3+json",
|
|
490
|
+
"User-Agent": "gitelectron-App"
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
).then((r) => r.ok ? r.json() : { items: [] }).catch(() => ({ items: [] }));
|
|
494
|
+
const exactPromise = /^[a-zA-Z0-9-]+$/.test(trimmed) ? fetch(`https://api.github.com/users/${encodeURIComponent(trimmed)}`, {
|
|
412
495
|
headers: {
|
|
413
496
|
Authorization: `Bearer ${token}`,
|
|
414
497
|
Accept: "application/vnd.github.v3+json",
|
|
415
498
|
"User-Agent": "gitelectron-App"
|
|
416
499
|
}
|
|
417
|
-
});
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
500
|
+
}).then((r) => r.ok ? r.json() : null).catch(() => null) : Promise.resolve(null);
|
|
501
|
+
const [searchData, exactUser] = await Promise.all([searchPromise, exactPromise]);
|
|
502
|
+
let items = searchData.items || [];
|
|
503
|
+
if (exactUser && exactUser.login) {
|
|
504
|
+
items = items.filter((u) => u.login.toLowerCase() !== exactUser.login.toLowerCase());
|
|
505
|
+
items.unshift(exactUser);
|
|
506
|
+
}
|
|
507
|
+
return items;
|
|
421
508
|
}
|
|
422
509
|
async function getRepositoryBranches(sessionId, owner, repo) {
|
|
423
510
|
const token = getToken(sessionId);
|
|
@@ -499,6 +586,22 @@ function initGit(sessionId, baseDir) {
|
|
|
499
586
|
});
|
|
500
587
|
gitSessions.set(sessionId, { git, repoPath: baseDir });
|
|
501
588
|
}
|
|
589
|
+
function createSafeGit(baseDir) {
|
|
590
|
+
const options = {
|
|
591
|
+
binary: "git",
|
|
592
|
+
maxConcurrentProcesses: 6,
|
|
593
|
+
unsafe: { allowUnsafeEditor: true, allowUnsafeAskPass: true, allowUnsafeCredentialHelper: true }
|
|
594
|
+
};
|
|
595
|
+
if (baseDir) {
|
|
596
|
+
options.baseDir = baseDir;
|
|
597
|
+
}
|
|
598
|
+
return simpleGit.simpleGit(options).env({
|
|
599
|
+
...process.env,
|
|
600
|
+
GCM_INTERACTIVE: "false",
|
|
601
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
602
|
+
GIT_ASKPASS: "echo"
|
|
603
|
+
});
|
|
604
|
+
}
|
|
502
605
|
function cleanupGitSession(sessionId) {
|
|
503
606
|
gitSessions.delete(sessionId);
|
|
504
607
|
}
|
|
@@ -630,10 +733,20 @@ async function commitChanges(sessionId, message) {
|
|
|
630
733
|
function injectAuthToken(sessionId, remoteUrl) {
|
|
631
734
|
const token = getToken(sessionId);
|
|
632
735
|
if (!token) return remoteUrl;
|
|
633
|
-
|
|
634
|
-
let cleanUrl = remoteUrl.
|
|
635
|
-
if (cleanUrl.startsWith("
|
|
636
|
-
|
|
736
|
+
try {
|
|
737
|
+
let cleanUrl = remoteUrl.trim();
|
|
738
|
+
if (cleanUrl.startsWith("git@github.com:")) {
|
|
739
|
+
cleanUrl = cleanUrl.replace("git@github.com:", "https://github.com/");
|
|
740
|
+
}
|
|
741
|
+
if (cleanUrl.includes("github.com")) {
|
|
742
|
+
const parsed = new URL(cleanUrl);
|
|
743
|
+
parsed.username = "x-access-token";
|
|
744
|
+
parsed.password = token;
|
|
745
|
+
return parsed.toString();
|
|
746
|
+
}
|
|
747
|
+
} catch (e) {
|
|
748
|
+
if (remoteUrl.includes("github.com")) {
|
|
749
|
+
return remoteUrl.replace(/https:\/\/(?:[^@]+@)?github\.com\//, `https://x-access-token:${token}@github.com/`);
|
|
637
750
|
}
|
|
638
751
|
}
|
|
639
752
|
return remoteUrl;
|
|
@@ -1009,6 +1122,97 @@ async function executeRawCommand(sessionId, args) {
|
|
|
1009
1122
|
const { git } = getGitSession(sessionId);
|
|
1010
1123
|
return await git.raw(args);
|
|
1011
1124
|
}
|
|
1125
|
+
async function cloneRepository(sessionId, remoteUrl, destPath) {
|
|
1126
|
+
let normalizedUrl = remoteUrl.trim();
|
|
1127
|
+
if (!normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") && !normalizedUrl.startsWith("git@")) {
|
|
1128
|
+
normalizedUrl = "https://github.com/" + normalizedUrl;
|
|
1129
|
+
}
|
|
1130
|
+
if (normalizedUrl.startsWith("git@github.com:")) {
|
|
1131
|
+
normalizedUrl = normalizedUrl.replace("git@github.com:", "https://github.com/");
|
|
1132
|
+
}
|
|
1133
|
+
if (!normalizedUrl.endsWith(".git") && normalizedUrl.startsWith("http")) {
|
|
1134
|
+
normalizedUrl += ".git";
|
|
1135
|
+
}
|
|
1136
|
+
const authUrl = injectAuthToken(sessionId, normalizedUrl);
|
|
1137
|
+
await fs__namespace.mkdir(path__namespace.dirname(destPath), { recursive: true });
|
|
1138
|
+
let destExists = false;
|
|
1139
|
+
let destIsEmpty = false;
|
|
1140
|
+
let destHasGit = false;
|
|
1141
|
+
try {
|
|
1142
|
+
const stats = await fs__namespace.stat(destPath);
|
|
1143
|
+
if (stats.isDirectory()) {
|
|
1144
|
+
destExists = true;
|
|
1145
|
+
const files = await fs__namespace.readdir(destPath);
|
|
1146
|
+
const realFiles = files.filter(
|
|
1147
|
+
(f) => ![".ds_store", "desktop.ini", "thumbs.db"].includes(f.toLowerCase())
|
|
1148
|
+
);
|
|
1149
|
+
destIsEmpty = realFiles.length === 0;
|
|
1150
|
+
destHasGit = files.includes(".git");
|
|
1151
|
+
}
|
|
1152
|
+
} catch {
|
|
1153
|
+
destExists = false;
|
|
1154
|
+
}
|
|
1155
|
+
try {
|
|
1156
|
+
if (destExists && destHasGit) {
|
|
1157
|
+
const existingGit = createSafeGit(destPath);
|
|
1158
|
+
try {
|
|
1159
|
+
await existingGit.raw(["config", "--global", "--add", "safe.directory", destPath]);
|
|
1160
|
+
const remotes = await existingGit.getRemotes();
|
|
1161
|
+
if (remotes.some((r) => r.name === "origin")) {
|
|
1162
|
+
await existingGit.raw(["remote", "set-url", "origin", authUrl]);
|
|
1163
|
+
} else {
|
|
1164
|
+
await existingGit.raw(["remote", "add", "origin", authUrl]);
|
|
1165
|
+
}
|
|
1166
|
+
await existingGit.raw(["-c", "credential.helper=", "fetch", "origin"]);
|
|
1167
|
+
const st = await existingGit.status();
|
|
1168
|
+
const branch = st.current || "main";
|
|
1169
|
+
try {
|
|
1170
|
+
await existingGit.raw(["-c", "credential.helper=", "pull", "origin", branch]);
|
|
1171
|
+
} catch (e) {
|
|
1172
|
+
}
|
|
1173
|
+
return destPath;
|
|
1174
|
+
} catch (err) {
|
|
1175
|
+
console.warn("Re-using existing repo failed, falling through to clone attempt:", err);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
if (destExists && destIsEmpty) {
|
|
1179
|
+
const emptyDirGit = createSafeGit(destPath);
|
|
1180
|
+
await emptyDirGit.raw(["-c", "credential.helper=", "clone", authUrl, "."]);
|
|
1181
|
+
try {
|
|
1182
|
+
await createSafeGit().raw(["config", "--global", "--add", "safe.directory", destPath]);
|
|
1183
|
+
} catch (e) {
|
|
1184
|
+
}
|
|
1185
|
+
return destPath;
|
|
1186
|
+
}
|
|
1187
|
+
if (destExists && !destIsEmpty && !destHasGit) {
|
|
1188
|
+
throw new Error(
|
|
1189
|
+
`The folder '${path__namespace.basename(destPath)}' already contains files. Please select an empty folder or a different location to clone.`
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
const baseDir = path__namespace.dirname(destPath);
|
|
1193
|
+
const targetDirName = path__namespace.basename(destPath);
|
|
1194
|
+
const parentGit = createSafeGit(baseDir);
|
|
1195
|
+
await parentGit.raw(["-c", "credential.helper=", "clone", authUrl, targetDirName]);
|
|
1196
|
+
try {
|
|
1197
|
+
await createSafeGit().raw(["config", "--global", "--add", "safe.directory", destPath]);
|
|
1198
|
+
} catch (e) {
|
|
1199
|
+
}
|
|
1200
|
+
return destPath;
|
|
1201
|
+
} catch (err) {
|
|
1202
|
+
const token = getToken(sessionId);
|
|
1203
|
+
let cleanMsg = err?.message || String(err);
|
|
1204
|
+
if (token) {
|
|
1205
|
+
cleanMsg = cleanMsg.split(token).join("***");
|
|
1206
|
+
}
|
|
1207
|
+
cleanMsg = cleanMsg.replace(/https:\/\/[^@]+@github\.com/g, "https://github.com");
|
|
1208
|
+
if (cleanMsg.includes("terminal prompts disabled") || cleanMsg.includes("Authentication failed") || cleanMsg.includes("could not read Username")) {
|
|
1209
|
+
throw new Error(
|
|
1210
|
+
`Authentication failed for GitHub repository. Please verify your account is logged in and has access to this repository.`
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
throw new Error(cleanMsg);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1012
1216
|
const SYSTEM_PROMPT = `You are an autonomous Git Healer Agent for the "GitElectron" app.
|
|
1013
1217
|
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.
|
|
1014
1218
|
You will receive the Git Status and the Raw Error Message.
|
|
@@ -1114,6 +1318,32 @@ ${errorMsg}
|
|
|
1114
1318
|
`AI Analysis failed after trying all provided keys. Last error: ${lastError?.message}`
|
|
1115
1319
|
);
|
|
1116
1320
|
}
|
|
1321
|
+
const getConfigPath = () => path__namespace.join(electron.app.getPath("userData"), "gitx-config.json");
|
|
1322
|
+
const saveLastWorkspace = async (workspacePath) => {
|
|
1323
|
+
try {
|
|
1324
|
+
const configPath = getConfigPath();
|
|
1325
|
+
let config = {};
|
|
1326
|
+
try {
|
|
1327
|
+
const data = await fs__namespace.readFile(configPath, "utf8");
|
|
1328
|
+
config = JSON.parse(data);
|
|
1329
|
+
} catch (e) {
|
|
1330
|
+
}
|
|
1331
|
+
config.lastWorkspace = workspacePath;
|
|
1332
|
+
await fs__namespace.writeFile(configPath, JSON.stringify(config, null, 2));
|
|
1333
|
+
} catch (e) {
|
|
1334
|
+
console.error("Failed to save workspace", e);
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
const getLastWorkspace = async () => {
|
|
1338
|
+
try {
|
|
1339
|
+
const configPath = getConfigPath();
|
|
1340
|
+
const data = await fs__namespace.readFile(configPath, "utf8");
|
|
1341
|
+
const config = JSON.parse(data);
|
|
1342
|
+
return config.lastWorkspace || null;
|
|
1343
|
+
} catch (e) {
|
|
1344
|
+
return null;
|
|
1345
|
+
}
|
|
1346
|
+
};
|
|
1117
1347
|
let currentWatcher = null;
|
|
1118
1348
|
let syncTimeout = null;
|
|
1119
1349
|
let isAutoSyncEnabled = false;
|
|
@@ -1288,6 +1518,7 @@ electron.app.whenReady().then(async () => {
|
|
|
1288
1518
|
if (isRepo) {
|
|
1289
1519
|
initGit(sessionId, path2);
|
|
1290
1520
|
}
|
|
1521
|
+
await saveLastWorkspace(path2);
|
|
1291
1522
|
return { path: path2, isRepo };
|
|
1292
1523
|
});
|
|
1293
1524
|
electron.ipcMain.handle("set-repo-path", async (event, path2) => {
|
|
@@ -1296,6 +1527,7 @@ electron.app.whenReady().then(async () => {
|
|
|
1296
1527
|
if (isRepo) {
|
|
1297
1528
|
initGit(sessionId, path2);
|
|
1298
1529
|
}
|
|
1530
|
+
await saveLastWorkspace(path2);
|
|
1299
1531
|
return { path: path2, isRepo };
|
|
1300
1532
|
});
|
|
1301
1533
|
electron.ipcMain.handle("init-repo", async (event, path2) => {
|
|
@@ -1378,6 +1610,9 @@ electron.app.whenReady().then(async () => {
|
|
|
1378
1610
|
electron.ipcMain.handle("get-user-repositories", async (event) => {
|
|
1379
1611
|
return await getUserRepositories(event.sender.id);
|
|
1380
1612
|
});
|
|
1613
|
+
electron.ipcMain.handle("get-collaborated-repos", async (event) => {
|
|
1614
|
+
return await getCollaboratedRepos(event.sender.id);
|
|
1615
|
+
});
|
|
1381
1616
|
electron.ipcMain.handle(
|
|
1382
1617
|
"create-github-repository",
|
|
1383
1618
|
async (event, name, description, isPrivate, autoInit, gitignoreTemplate, licenseTemplate) => {
|
|
@@ -1497,6 +1732,37 @@ electron.app.whenReady().then(async () => {
|
|
|
1497
1732
|
electron.ipcMain.handle("execute-raw-git", async (event, args) => {
|
|
1498
1733
|
return await executeRawCommand(event.sender.id, args);
|
|
1499
1734
|
});
|
|
1735
|
+
electron.ipcMain.handle("clone-repository", async (event, remoteUrl, destPath) => {
|
|
1736
|
+
return await cloneRepository(event.sender.id, remoteUrl, destPath);
|
|
1737
|
+
});
|
|
1738
|
+
electron.ipcMain.handle("check-path-exists", async (_event, targetPath) => {
|
|
1739
|
+
if (!targetPath) return false;
|
|
1740
|
+
try {
|
|
1741
|
+
const stats = await fs__namespace.stat(targetPath);
|
|
1742
|
+
return stats.isDirectory();
|
|
1743
|
+
} catch {
|
|
1744
|
+
return false;
|
|
1745
|
+
}
|
|
1746
|
+
});
|
|
1747
|
+
electron.ipcMain.handle("upload-files-to-repo", async (event, repoPath) => {
|
|
1748
|
+
const window = electron.BrowserWindow.fromWebContents(event.sender);
|
|
1749
|
+
if (!repoPath) throw new Error("No repository path specified");
|
|
1750
|
+
const result = await electron.dialog.showOpenDialog(window || void 0, {
|
|
1751
|
+
title: "Select Files to Upload to Repository",
|
|
1752
|
+
properties: ["openFile", "multiSelections"]
|
|
1753
|
+
});
|
|
1754
|
+
if (result.canceled || !result.filePaths.length) {
|
|
1755
|
+
return { success: false, count: 0, files: [] };
|
|
1756
|
+
}
|
|
1757
|
+
const copiedFiles = [];
|
|
1758
|
+
for (const filePath of result.filePaths) {
|
|
1759
|
+
const fileName = path__namespace.basename(filePath);
|
|
1760
|
+
const destPath = path__namespace.join(repoPath, fileName);
|
|
1761
|
+
await fs__namespace.copyFile(filePath, destPath);
|
|
1762
|
+
copiedFiles.push(fileName);
|
|
1763
|
+
}
|
|
1764
|
+
return { success: true, count: copiedFiles.length, files: copiedFiles };
|
|
1765
|
+
});
|
|
1500
1766
|
electron.ipcMain.on("toggle-auto-sync", (event, repoPath, enabled) => {
|
|
1501
1767
|
toggleAutoSync(event.sender.id, repoPath, enabled, (msg) => {
|
|
1502
1768
|
event.sender.send("auto-sync-log", msg);
|
|
@@ -1549,7 +1815,10 @@ electron.app.whenReady().then(async () => {
|
|
|
1549
1815
|
}, 500);
|
|
1550
1816
|
});
|
|
1551
1817
|
});
|
|
1552
|
-
|
|
1818
|
+
if (!initialRepo) {
|
|
1819
|
+
initialRepo = await getLastWorkspace();
|
|
1820
|
+
}
|
|
1821
|
+
createWindow(initialRepo || void 0);
|
|
1553
1822
|
electron.app.on("activate", function() {
|
|
1554
1823
|
if (electron.BrowserWindow.getAllWindows().length === 0) createWindow();
|
|
1555
1824
|
});
|
package/out/preload/index.js
CHANGED
|
@@ -40,6 +40,7 @@ const api = {
|
|
|
40
40
|
switchAccount: (accountId) => electron.ipcRenderer.invoke("switch-account", accountId),
|
|
41
41
|
removeAccount: (accountId) => electron.ipcRenderer.invoke("remove-account", accountId),
|
|
42
42
|
getUserRepositories: () => electron.ipcRenderer.invoke("get-user-repositories"),
|
|
43
|
+
getCollaboratedRepos: () => electron.ipcRenderer.invoke("get-collaborated-repos"),
|
|
43
44
|
createGitHubRepository: (name, description, isPrivate, autoInit = false, gitignoreTemplate = "", licenseTemplate = "") => electron.ipcRenderer.invoke(
|
|
44
45
|
"create-github-repository",
|
|
45
46
|
name,
|
|
@@ -68,6 +69,9 @@ const api = {
|
|
|
68
69
|
setupUniversalWorkspace: (remoteUrl, branch, baseBranch, dest) => electron.ipcRenderer.invoke("setup-universal-workspace", remoteUrl, branch, baseBranch, dest),
|
|
69
70
|
checkUniversalCollisions: (workspacePath, sourceFiles, dest) => electron.ipcRenderer.invoke("check-universal-collisions", workspacePath, sourceFiles, dest),
|
|
70
71
|
getUniversalDiff: (workspacePath, file) => electron.ipcRenderer.invoke("get-universal-diff", workspacePath, file),
|
|
72
|
+
cloneRepository: (remoteUrl, destPath) => electron.ipcRenderer.invoke("clone-repository", remoteUrl, destPath),
|
|
73
|
+
checkPathExists: (targetPath) => electron.ipcRenderer.invoke("check-path-exists", targetPath),
|
|
74
|
+
uploadFilesToRepo: (repoPath) => electron.ipcRenderer.invoke("upload-files-to-repo", repoPath),
|
|
71
75
|
commitUniversalWorkspace: (workspacePath, msg, branch) => electron.ipcRenderer.invoke("commit-universal-workspace", workspacePath, msg, branch),
|
|
72
76
|
cleanupUniversalWorkspace: (workspacePath) => electron.ipcRenderer.invoke("cleanup-universal-workspace", workspacePath),
|
|
73
77
|
toggleAutoSync: (repoPath, enabled) => electron.ipcRenderer.send("toggle-auto-sync", repoPath, enabled),
|