create-egregore 0.11.1 → 0.12.1
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/lib/auth.js +3 -3
- package/lib/local.js +36 -22
- package/package.json +1 -1
package/lib/auth.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
const https = require("node:https");
|
|
7
7
|
|
|
8
|
-
const CLIENT_ID = "
|
|
9
|
-
const SCOPE = "
|
|
8
|
+
const CLIENT_ID = "Iv23li2obNsAjakoK2RE";
|
|
9
|
+
const SCOPE = ""; // GitHub App — permissions managed via installation, not OAuth scope
|
|
10
10
|
|
|
11
11
|
function post(url, body) {
|
|
12
12
|
return new Promise((resolve, reject) => {
|
|
@@ -135,4 +135,4 @@ async function deviceFlow(ui) {
|
|
|
135
135
|
throw new Error("Timed out waiting for authorization (5 minutes)");
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
module.exports = { deviceFlow };
|
|
138
|
+
module.exports = { deviceFlow, openBrowser };
|
package/lib/local.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
const fs = require("node:fs");
|
|
7
7
|
const path = require("node:path");
|
|
8
8
|
const { execFileSync } = require("node:child_process");
|
|
9
|
-
const { deviceFlow } = require("./auth");
|
|
9
|
+
const { deviceFlow, openBrowser } = require("./auth");
|
|
10
10
|
const {
|
|
11
11
|
ghApi,
|
|
12
12
|
acceptPendingInvitations,
|
|
@@ -80,6 +80,17 @@ async function waitForRepo(token, owner, repo, timeoutMs = 30000) {
|
|
|
80
80
|
return false;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
async function findEgregoreRepo(token, orgLogin, explicitRepo) {
|
|
84
|
+
if (explicitRepo) {
|
|
85
|
+
if (await repoExists(token, orgLogin, explicitRepo)) return explicitRepo;
|
|
86
|
+
} else {
|
|
87
|
+
for (const candidate of ["egregore", "egregore-core"]) {
|
|
88
|
+
if (await repoExists(token, orgLogin, candidate)) return candidate;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
async function getFileContent(token, owner, repo, filePath) {
|
|
84
95
|
const { status, data } = await ghApi("GET", `/repos/${owner}/${repo}/contents/${filePath}`, token);
|
|
85
96
|
if (status !== 200 || !data.content) return null;
|
|
@@ -561,40 +572,43 @@ async function localJoinFlow(orgArg, ui) {
|
|
|
561
572
|
// 2. Get user info
|
|
562
573
|
const user = await getUser(githubToken);
|
|
563
574
|
|
|
564
|
-
// 3. Accept pending invitations
|
|
575
|
+
// 3. Accept pending invitations (may silently fail with GitHub App tokens)
|
|
565
576
|
console.log("");
|
|
566
577
|
const s1 = ui.spinner("Checking for invitations...");
|
|
567
578
|
await acceptPendingInvitations(githubToken, orgLogin, ui);
|
|
568
579
|
s1.stop("Checked invitations");
|
|
569
580
|
|
|
570
581
|
// 4. Find egregore repo
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
}
|
|
582
|
+
let repoName = await findEgregoreRepo(githubToken, orgLogin, explicitRepo);
|
|
583
|
+
|
|
584
|
+
// 4b. If repo not found, the user likely has a pending invitation that couldn't
|
|
585
|
+
// be accepted automatically. Open the repo page so they can accept with one click.
|
|
586
|
+
if (!repoName && explicitRepo) {
|
|
587
|
+
console.log("");
|
|
588
|
+
ui.info("Accept the repo invitation in your browser.");
|
|
589
|
+
openBrowser(`https://github.com/${orgLogin}/${explicitRepo}`);
|
|
590
|
+
await ui.prompt("Press Enter after accepting...");
|
|
591
|
+
|
|
592
|
+
const s2 = ui.spinner("Retrying...");
|
|
593
|
+
repoName = await findEgregoreRepo(githubToken, orgLogin, explicitRepo);
|
|
594
|
+
if (!repoName) {
|
|
595
|
+
s2.fail(`Still can't access ${orgLogin}/${explicitRepo}`);
|
|
596
|
+
ui.error("Make sure the org admin has set up Egregore and invited you.");
|
|
597
|
+
process.exit(1);
|
|
585
598
|
}
|
|
586
|
-
|
|
587
|
-
if (!repoName) {
|
|
588
|
-
|
|
599
|
+
s2.stop("Access confirmed");
|
|
600
|
+
} else if (!repoName) {
|
|
601
|
+
ui.error(`No egregore repo found in ${orgLogin}`);
|
|
589
602
|
ui.error("Make sure the org admin has set up Egregore and invited you.");
|
|
590
603
|
ui.info("If the repo has a custom name, use: npx create-egregore join <org>/<repo>");
|
|
591
604
|
process.exit(1);
|
|
592
605
|
}
|
|
593
606
|
|
|
594
607
|
// 5. Read egregore.json from remote
|
|
608
|
+
const s3 = ui.spinner(`Reading config from ${orgLogin}/${repoName}...`);
|
|
595
609
|
const configRaw = await getFileContent(githubToken, orgLogin, repoName, "egregore.json");
|
|
596
610
|
if (!configRaw) {
|
|
597
|
-
|
|
611
|
+
s3.fail("Could not read egregore.json");
|
|
598
612
|
ui.error("The egregore repo exists but has no egregore.json. Ask the admin to set up first.");
|
|
599
613
|
process.exit(1);
|
|
600
614
|
}
|
|
@@ -602,10 +616,10 @@ async function localJoinFlow(orgArg, ui) {
|
|
|
602
616
|
try {
|
|
603
617
|
config = JSON.parse(configRaw);
|
|
604
618
|
} catch {
|
|
605
|
-
|
|
619
|
+
s3.fail("Invalid egregore.json");
|
|
606
620
|
process.exit(1);
|
|
607
621
|
}
|
|
608
|
-
|
|
622
|
+
s3.stop(`Found ${ui.bold(config.org_name || orgLogin)}`);
|
|
609
623
|
|
|
610
624
|
const orgName = config.org_name || orgLogin;
|
|
611
625
|
const memoryRepoName = config.memory_repo
|