create-githat-app 1.0.5 → 1.0.6

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/dist/cli.js +89 -13
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import gradient from "gradient-string";
11
11
  import chalk from "chalk";
12
12
 
13
13
  // src/constants.ts
14
- var VERSION = "1.0.5";
14
+ var VERSION = "1.0.6";
15
15
  var DEFAULT_API_URL = "https://api.githat.io";
16
16
  var DASHBOARD_URL = "https://githat.io/dashboard/apps";
17
17
  var BRAND_COLORS = ["#7c3aed", "#6366f1", "#8b5cf6"];
@@ -397,7 +397,77 @@ async function promptBackend() {
397
397
  }
398
398
 
399
399
  // src/prompts/githat.ts
400
+ import { execSync } from "child_process";
400
401
  import * as p5 from "@clack/prompts";
402
+ function openBrowser(url) {
403
+ try {
404
+ const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
405
+ execSync(`${cmd} "${url}"`, { stdio: "ignore" });
406
+ } catch {
407
+ }
408
+ }
409
+ function sleep(ms) {
410
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
411
+ }
412
+ async function deviceAuthFlow() {
413
+ const spinner2 = p5.spinner();
414
+ try {
415
+ spinner2.start("Requesting device code...");
416
+ const codeRes = await fetch(`${DEFAULT_API_URL}/auth/device/code`, {
417
+ method: "POST",
418
+ headers: { "Content-Type": "application/json" },
419
+ body: JSON.stringify({ client_name: "create-githat-app" })
420
+ });
421
+ if (!codeRes.ok) {
422
+ spinner2.stop("Failed to get device code");
423
+ return null;
424
+ }
425
+ const codeData = await codeRes.json();
426
+ spinner2.stop("Device code generated");
427
+ p5.note(
428
+ `Code: ${codeData.user_code}
429
+
430
+ Opening browser to complete sign-in...
431
+ If it doesn't open, visit: ${codeData.verification_uri_complete}`,
432
+ "Authorize Device"
433
+ );
434
+ openBrowser(codeData.verification_uri_complete);
435
+ spinner2.start("Waiting for browser authorization...");
436
+ const expiresAt = Date.now() + codeData.expires_in * 1e3;
437
+ const pollInterval = (codeData.interval || 5) * 1e3;
438
+ while (Date.now() < expiresAt) {
439
+ await sleep(pollInterval);
440
+ const tokenRes = await fetch(`${DEFAULT_API_URL}/auth/device/token`, {
441
+ method: "POST",
442
+ headers: { "Content-Type": "application/json" },
443
+ body: JSON.stringify({ device_code: codeData.device_code })
444
+ });
445
+ const tokenData = await tokenRes.json();
446
+ if (tokenData.error === "authorization_pending") {
447
+ continue;
448
+ }
449
+ if (tokenData.error === "expired_token") {
450
+ spinner2.stop("Device code expired");
451
+ p5.log.error("Authorization timed out. Please try again.");
452
+ return null;
453
+ }
454
+ if (tokenData.publishable_key) {
455
+ spinner2.stop("Authorized!");
456
+ p5.log.success(`Connected to ${tokenData.app_name || "your app"} (${tokenData.org_name || "your org"})`);
457
+ return tokenData.publishable_key;
458
+ }
459
+ spinner2.stop("Authorization failed");
460
+ return null;
461
+ }
462
+ spinner2.stop("Timed out");
463
+ p5.log.error("Authorization timed out. Please try again.");
464
+ return null;
465
+ } catch (err) {
466
+ spinner2.stop("Connection error");
467
+ p5.log.error("Failed to connect to GitHat API. Check your internet connection.");
468
+ return null;
469
+ }
470
+ }
401
471
  async function promptGitHat(existingKey) {
402
472
  let publishableKey = existingKey || "";
403
473
  if (!publishableKey) {
@@ -405,6 +475,7 @@ async function promptGitHat(existingKey) {
405
475
  message: "Connect to GitHat",
406
476
  options: [
407
477
  { value: "skip", label: "Skip for now", hint: "auth works on localhost \u2014 add key later" },
478
+ { value: "browser", label: "Sign in with browser", hint: "opens githat.io to authorize" },
408
479
  { value: "paste", label: "I have a key", hint: "paste your pk_live_... key" }
409
480
  ]
410
481
  });
@@ -412,7 +483,12 @@ async function promptGitHat(existingKey) {
412
483
  p5.cancel("Setup cancelled.");
413
484
  process.exit(0);
414
485
  }
415
- if (connectChoice === "paste") {
486
+ if (connectChoice === "browser") {
487
+ const key = await deviceAuthFlow();
488
+ if (key) {
489
+ publishableKey = key;
490
+ }
491
+ } else if (connectChoice === "paste") {
416
492
  const pastedKey = await p5.text({
417
493
  message: "Publishable key",
418
494
  placeholder: `pk_live_... (get one at ${DASHBOARD_URL})`,
@@ -579,7 +655,7 @@ function answersToContext(answers) {
579
655
  // src/scaffold/index.ts
580
656
  import fs3 from "fs-extra";
581
657
  import path3 from "path";
582
- import { execSync as execSync2 } from "child_process";
658
+ import { execSync as execSync3 } from "child_process";
583
659
  import * as p9 from "@clack/prompts";
584
660
  import chalk2 from "chalk";
585
661
 
@@ -701,25 +777,25 @@ function createSpinner(text4) {
701
777
  return ora({ text: text4, color: "magenta" });
702
778
  }
703
779
  async function withSpinner(text4, fn, successText) {
704
- const spinner = createSpinner(text4);
705
- spinner.start();
780
+ const spinner2 = createSpinner(text4);
781
+ spinner2.start();
706
782
  try {
707
783
  const result = await fn();
708
- spinner.succeed(successText || text4);
784
+ spinner2.succeed(successText || text4);
709
785
  return result;
710
786
  } catch (err) {
711
- spinner.fail(text4);
787
+ spinner2.fail(text4);
712
788
  throw err;
713
789
  }
714
790
  }
715
791
 
716
792
  // src/utils/git.ts
717
- import { execSync } from "child_process";
793
+ import { execSync as execSync2 } from "child_process";
718
794
  function initGit(cwd) {
719
795
  try {
720
- execSync("git init", { cwd, stdio: "ignore" });
721
- execSync("git add -A", { cwd, stdio: "ignore" });
722
- execSync('git commit -m "Initial commit from create-githat-app"', {
796
+ execSync2("git init", { cwd, stdio: "ignore" });
797
+ execSync2("git add -A", { cwd, stdio: "ignore" });
798
+ execSync2('git commit -m "Initial commit from create-githat-app"', {
723
799
  cwd,
724
800
  stdio: "ignore"
725
801
  });
@@ -776,7 +852,7 @@ async function scaffold(context, options) {
776
852
  `Installing dependencies with ${context.packageManager}...`,
777
853
  async () => {
778
854
  try {
779
- execSync2(installCmd, { cwd: root, stdio: "ignore", timeout: 12e4 });
855
+ execSync3(installCmd, { cwd: root, stdio: "ignore", timeout: 12e4 });
780
856
  } catch (err) {
781
857
  const msg = err.message || "";
782
858
  if (msg.includes("TIMEOUT")) {
@@ -799,7 +875,7 @@ async function scaffold(context, options) {
799
875
  if (!p9.isCancel(starPrompt) && starPrompt) {
800
876
  try {
801
877
  const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
802
- execSync2(`${cmd} "https://github.com/GitHat-IO/githat"`, { stdio: "ignore" });
878
+ execSync3(`${cmd} "https://github.com/GitHat-IO/githat"`, { stdio: "ignore" });
803
879
  } catch {
804
880
  p9.log.info("Visit https://github.com/GitHat-IO/githat to star us!");
805
881
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-githat-app",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "GitHat CLI — scaffold apps and manage the skills marketplace",
5
5
  "type": "module",
6
6
  "bin": {