create-macostack 0.6.3 → 0.6.4

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.
@@ -6,6 +6,7 @@ import {
6
6
  multiselect,
7
7
  note,
8
8
  outro,
9
+ password,
9
10
  select,
10
11
  spinner,
11
12
  text,
@@ -134,6 +135,7 @@ Flags:
134
135
  Auth (templates are private):
135
136
  export GITHUB_TOKEN=github_pat_… or gh auth login
136
137
  (fine-grained token, Contents: Read-only is enough)
138
+ No token configured? I'll ask for one when it's needed.
137
139
  `);
138
140
  process.exit(0);
139
141
  }
@@ -158,9 +160,40 @@ const answered = <T>(value: T | symbol): T => {
158
160
  const githubToken = (): string | null => {
159
161
  const fromEnv = Bun.env.GITHUB_TOKEN ?? Bun.env.GH_TOKEN;
160
162
  if (fromEnv) return fromEnv;
161
- const gh = Bun.spawnSync(["gh", "auth", "token"], { stdout: "pipe", stderr: "pipe" });
162
- const token = gh.exitCode === 0 ? gh.stdout.toString().trim() : "";
163
- return token || null;
163
+ try {
164
+ const gh = Bun.spawnSync(["gh", "auth", "token"], { stdout: "pipe", stderr: "pipe" });
165
+ const token = gh.exitCode === 0 ? gh.stdout.toString().trim() : "";
166
+ return token || null;
167
+ } catch {
168
+ return null; // gh isn't installed
169
+ }
170
+ };
171
+
172
+ // Resolve a GitHub token, or ask for one when nothing is configured. In --yes
173
+ // mode there's nobody to ask, so it bails with instructions instead.
174
+ const requireGithubToken = async (purpose: string): Promise<string> => {
175
+ const found = githubToken();
176
+ if (found) return found;
177
+ if (flags.yes) {
178
+ bail(
179
+ `I need GitHub access to ${purpose} (the repos are private).\n` +
180
+ " Easiest: gh auth login\n" +
181
+ " Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
182
+ );
183
+ }
184
+ note(
185
+ `I need GitHub access to ${purpose} (the repos are private).\n` +
186
+ "A fine-grained token with Contents: Read-only is enough.\n" +
187
+ "Tip: gh auth login (or export GITHUB_TOKEN=…) skips this question next time.",
188
+ "GitHub access",
189
+ );
190
+ const typed = answered(
191
+ await password({
192
+ message: "Paste your GitHub token (input is hidden)",
193
+ validate: (v) => (v?.trim() ? undefined : "I need a token to continue"),
194
+ }),
195
+ );
196
+ return typed.trim();
164
197
  };
165
198
 
166
199
  const isEmptyDir = (dir: string) =>
@@ -500,29 +533,13 @@ if (present.length > 0) {
500
533
  process.exit(0);
501
534
  }
502
535
  if (action === "docs-update") {
503
- const syncToken = githubToken();
504
- if (!syncToken) {
505
- bail(
506
- "I need GitHub access to fetch the docs system (the repo is private).\n" +
507
- " Easiest: gh auth login\n" +
508
- " Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
509
- );
510
- throw ""; // unreachable
511
- }
536
+ const syncToken = await requireGithubToken("fetch the docs system");
512
537
  await updateDocs(syncToken, targetRoot);
513
538
  outro(`${appName} is up to date ✨`);
514
539
  process.exit(0);
515
540
  }
516
541
  if (action === "docs") {
517
- const docsToken = githubToken();
518
- if (!docsToken) {
519
- bail(
520
- "I need GitHub access to download the docs system (the repo is private).\n" +
521
- " Easiest: gh auth login\n" +
522
- " Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
523
- );
524
- throw ""; // unreachable
525
- }
542
+ const docsToken = await requireGithubToken("download the docs system");
526
543
  const ok = await scaffoldDocs(docsToken, targetRoot, appName, null);
527
544
  if (ok) {
528
545
  note(
@@ -571,15 +588,7 @@ if (!selected) {
571
588
  // 3. GitHub access — checked before anything is created.
572
589
  const owner = flags.owner ?? DEFAULT_OWNER;
573
590
  const ref = flags.ref ?? DEFAULT_REF;
574
- const token = githubToken();
575
- if (!token) {
576
- bail(
577
- "I need GitHub access to download the templates (they're private).\n" +
578
- " Easiest: gh auth login\n" +
579
- " Or: export GITHUB_TOKEN=github_pat_… (Contents: Read-only)",
580
- );
581
- throw ""; // unreachable
582
- }
591
+ const token = await requireGithubToken("download the templates");
583
592
  for (const p of selected) {
584
593
  p.repo = (p.id === "server" ? flags["server-repo"] : flags["client-repo"]) ?? p.repo;
585
594
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-macostack",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "Scaffold a production-ready full-stack app from the macostack templates: Bun + Hono + Postgres backend and TanStack web app, each as its own git repo.",
5
5
  "license": "MIT",
6
6
  "repository": {