create-egregore 0.19.2 → 0.19.3

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/bin/cli.js CHANGED
@@ -36,6 +36,7 @@ const {
36
36
  registerInstance,
37
37
  installLauncherBinary,
38
38
  normalizeRuntime,
39
+ redactToken,
39
40
  } = require("../lib/setup");
40
41
  const { detectContext, isWritable, isSystemDir } = require("../lib/context");
41
42
 
@@ -888,6 +889,8 @@ async function joinFlow(api, githubToken, choice, ctx) {
888
889
  }
889
890
 
890
891
  main().catch((err) => {
891
- ui.error(err.message);
892
+ // Last-resort net: never let a credential reach the terminal via an
893
+ // unhandled error message (cloneRepo already redacts at the source).
894
+ ui.error(redactToken(err && err.message));
892
895
  process.exit(1);
893
896
  });
package/lib/local.js CHANGED
@@ -25,6 +25,7 @@ const {
25
25
  installLauncherBinary,
26
26
  launchOrInstruct,
27
27
  embedToken,
28
+ redactToken,
28
29
  configureGitCredentials,
29
30
  gitCloneEnv,
30
31
  initMemoryDirs,
@@ -342,12 +343,20 @@ function cloneRepo(url, dir, token, ui, label) {
342
343
  ui.warn(`${path.basename(dir)}/ already exists — pulling latest`);
343
344
  run("git pull", { cwd: dir });
344
345
  } else {
345
- execFileSync("git", ["clone", embedToken(url, token), dir], {
346
- stdio: "pipe",
347
- encoding: "utf-8",
348
- timeout: 60000,
349
- env: gitCloneEnv(),
350
- });
346
+ try {
347
+ execFileSync("git", ["clone", embedToken(url, token), dir], {
348
+ stdio: "pipe",
349
+ encoding: "utf-8",
350
+ timeout: 60000,
351
+ env: gitCloneEnv(),
352
+ });
353
+ } catch (err) {
354
+ // execFileSync puts the full command — including the embedded token — in
355
+ // err.message. Rethrow a redacted error that keeps git's stderr (the
356
+ // useful "remote: ..." lines) but never the credential.
357
+ const detail = [err.message, err.stderr].filter(Boolean).join("\n");
358
+ throw new Error(redactToken(detail, token));
359
+ }
351
360
  try {
352
361
  run(`git remote set-url origin ${url}`, { cwd: dir });
353
362
  } catch {}
package/lib/setup.js CHANGED
@@ -596,6 +596,20 @@ function embedToken(url, token) {
596
596
  }
597
597
  }
598
598
 
599
+ // Strip credentials from any text before it reaches the terminal. execFileSync
600
+ // bakes the full argv into its thrown error message, so an authenticated
601
+ // `git clone https://x-access-token:<pat>@github.com/...` leaks the token
602
+ // verbatim if that error is printed. Redacts the known token, any userinfo in
603
+ // an https URL, and bare GitHub token shapes as a backstop.
604
+ function redactToken(text, token) {
605
+ let s = text == null ? "" : String(text);
606
+ if (token) s = s.split(token).join("***");
607
+ s = s.replace(/(https:\/\/)[^@/\s]+@/g, "$1***@"); // https://user:secret@host → https://***@host
608
+ s = s.replace(/gh[posru]_[A-Za-z0-9_]+/g, "***"); // ghp_/gho_/ghs_/ghu_/ghr_
609
+ s = s.replace(/github_pat_[A-Za-z0-9_]+/g, "***");
610
+ return s;
611
+ }
612
+
599
613
  function toSSH(url) {
600
614
  const m = url.match(/https:\/\/github\.com\/(.+?)(?:\.git)?$/);
601
615
  return m ? `git@github.com:${m[1]}.git` : null;
@@ -1255,6 +1269,7 @@ module.exports = {
1255
1269
  ensurePersonOnboardingWitness,
1256
1270
  ensureInstallerMemberRole,
1257
1271
  embedToken,
1272
+ redactToken,
1258
1273
  configureGitCredentials,
1259
1274
  gitCloneEnv,
1260
1275
  assistantInstallCommand,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-egregore",
3
- "version": "0.19.2",
3
+ "version": "0.19.3",
4
4
  "description": "Set up Egregore for your team in one command — installs the egregore launcher and your choice of Claude Code or Codex.",
5
5
  "license": "MIT",
6
6
  "bin": {