create-egregore 0.15.0 → 0.15.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.
Files changed (2) hide show
  1. package/lib/local.js +45 -11
  2. package/package.json +1 -1
package/lib/local.js CHANGED
@@ -168,6 +168,43 @@ function cloneRepo(url, dir, token, ui, label) {
168
168
  ui.success(`Cloned ${label}`);
169
169
  }
170
170
 
171
+ /**
172
+ * Convert HTTPS GitHub URL to SSH format.
173
+ * https://github.com/org/repo.git → git@github.com:org/repo.git
174
+ */
175
+ function toSSH(url) {
176
+ const m = url.match(/https:\/\/github\.com\/(.+?)(?:\.git)?$/);
177
+ return m ? `git@github.com:${m[1]}.git` : null;
178
+ }
179
+
180
+ /**
181
+ * Clone a repo, trying SSH first then HTTPS.
182
+ * GIT_TERMINAL_PROMPT=0 prevents the hanging username/password prompt.
183
+ */
184
+ function cloneWithFallback(httpsUrl, dir, timeout = 60000) {
185
+ const env = { ...process.env, GIT_TERMINAL_PROMPT: "0" };
186
+ const sshUrl = toSSH(httpsUrl);
187
+
188
+ // Try SSH first (most devs have SSH keys; GitHub no longer supports HTTPS password auth)
189
+ if (sshUrl) {
190
+ try {
191
+ execFileSync("git", ["clone", sshUrl, dir], { stdio: "pipe", encoding: "utf-8", timeout, env });
192
+ return true;
193
+ } catch {
194
+ // Clean up partial clone so HTTPS fallback can use the same dir
195
+ try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
196
+ }
197
+ }
198
+
199
+ // Fall back to HTTPS (works if user has gh CLI or a credential helper configured)
200
+ try {
201
+ execFileSync("git", ["clone", httpsUrl, dir], { stdio: "pipe", encoding: "utf-8", timeout, env });
202
+ return true;
203
+ } catch {}
204
+
205
+ return false;
206
+ }
207
+
171
208
  function setGitIdentity(dir, user) {
172
209
  try {
173
210
  run(`git config user.name "${user.name}"`, { cwd: dir });
@@ -602,10 +639,9 @@ async function localJoinFlow(orgArg, ui) {
602
639
 
603
640
  console.log("");
604
641
  const s2 = ui.spinner(`Cloning ${orgLogin}/${repoName}...`);
605
- try {
606
- execFileSync("git", ["clone", `https://github.com/${orgLogin}/${repoName}.git`, egregoreDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
642
+ if (cloneWithFallback(`https://github.com/${orgLogin}/${repoName}.git`, egregoreDir)) {
607
643
  s2.stop(`Cloned ${repoName}`);
608
- } catch (err) {
644
+ } else {
609
645
  s2.fail(`Could not clone ${orgLogin}/${repoName}`);
610
646
  ui.error("Make sure you have git credentials set up (SSH keys or gh auth login).");
611
647
  ui.error("Also verify the org admin has set up Egregore and invited you.");
@@ -642,12 +678,11 @@ async function localJoinFlow(orgArg, ui) {
642
678
  // Store the invite token for later use (invitation acceptance, not cloning)
643
679
  const inviteToken = githubToken;
644
680
 
645
- // Clone memory using git credentials (same as main repo — no token in URL)
681
+ // Clone memory using SSH-first fallback (same as main repo)
646
682
  ui.step(1, totalSteps, "Cloning shared memory...");
647
- try {
648
- execFileSync("git", ["clone", memoryUrl, memoryDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
683
+ if (cloneWithFallback(memoryUrl, memoryDir)) {
649
684
  ui.success("Cloned memory");
650
- } catch {
685
+ } else {
651
686
  ui.warn("Could not clone memory repo — you may not have access yet.");
652
687
  }
653
688
  setGitIdentity(memoryDir, user);
@@ -683,16 +718,15 @@ async function localJoinFlow(orgArg, ui) {
683
718
  registerInstance(repoName, orgName, egregoreDir);
684
719
  const alias = await installShellAlias(egregoreDir, ui);
685
720
 
686
- // Clone managed repos using git credentials
721
+ // Clone managed repos using SSH-first fallback
687
722
  for (let i = 0; i < managedRepos.length; i++) {
688
723
  const mr = managedRepos[i];
689
724
  ui.step(5 + i, totalSteps, `Cloning ${mr}...`);
690
725
  const repoDir = path.join(base, mr);
691
- try {
692
- execFileSync("git", ["clone", `https://github.com/${orgLogin}/${mr}.git`, repoDir], { stdio: "pipe", encoding: "utf-8", timeout: 60000 });
726
+ if (cloneWithFallback(`https://github.com/${orgLogin}/${mr}.git`, repoDir)) {
693
727
  setGitIdentity(repoDir, user);
694
728
  ui.success(`Cloned ${mr}`);
695
- } catch {
729
+ } else {
696
730
  ui.warn(`Could not clone ${mr} — you may not have access yet.`);
697
731
  }
698
732
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-egregore",
3
- "version": "0.15.0",
3
+ "version": "0.15.1",
4
4
  "description": "Set up Egregore for your team in one command",
5
5
  "license": "MIT",
6
6
  "bin": {