create-githat-app 1.0.11 → 1.0.14

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/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.11";
14
+ var VERSION = "1.0.14";
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"];
@@ -21,7 +21,8 @@ var DEPS = {
21
21
  next: "^16.0.0",
22
22
  react: "^19.0.0",
23
23
  "react-dom": "^19.0.0",
24
- "@githat/nextjs": "^0.5.0"
24
+ "@githat/nextjs": "^0.5.0",
25
+ "@githat/ui": "^1.0.0"
25
26
  },
26
27
  devDependencies: {
27
28
  typescript: "^5.9.0",
@@ -35,7 +36,8 @@ var DEPS = {
35
36
  react: "^19.0.0",
36
37
  "react-dom": "^19.0.0",
37
38
  "react-router-dom": "^7.0.0",
38
- "@githat/nextjs": "^0.5.0"
39
+ "@githat/nextjs": "^0.5.0",
40
+ "@githat/ui": "^1.0.0"
39
41
  },
40
42
  devDependencies: {
41
43
  vite: "^7.0.0",
@@ -328,7 +330,8 @@ function getInstallCommand(pm) {
328
330
  async function promptFramework(typescriptOverride, isFullstack) {
329
331
  const packageManager = detectPackageManager();
330
332
  const frameworkOptions = isFullstack ? [{ value: "nextjs", label: "Next.js 16", hint: "App Router \xB7 SSR \xB7 middleware auth" }] : [
331
- { value: "nextjs", label: "Next.js 16", hint: "App Router \xB7 SSR \xB7 middleware auth" },
333
+ { value: "plain", label: "Plain (recommended for first time)", hint: "Just auth + one homepage. Build whatever on top." },
334
+ { value: "nextjs", label: "Next.js 16 \u2014 full kit", hint: "Dashboard \xB7 orgs \xB7 agents \xB7 MCP scaffolding" },
332
335
  { value: "react-vite", label: "React 19 + Vite 7", hint: "SPA \xB7 client-side routing" }
333
336
  ];
334
337
  const answers = await p3.group(
@@ -581,33 +584,34 @@ async function promptFinalize() {
581
584
  function toDisplayName(projectName) {
582
585
  return projectName.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
583
586
  }
584
- function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework) {
587
+ function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework, plain) {
585
588
  const displayName = toDisplayName(projectName);
586
589
  const projectType = fullstack ? "fullstack" : "frontend";
590
+ const framework = plain ? "plain" : "nextjs";
587
591
  return {
588
592
  projectName,
589
593
  businessName: displayName,
590
594
  description: `${displayName} \u2014 Built with GitHat`,
591
595
  projectType,
592
596
  backendFramework: fullstack ? backendFramework || "hono" : void 0,
593
- framework: "nextjs",
597
+ framework,
594
598
  typescript: typescript ?? true,
595
599
  packageManager: detectPackageManager(),
596
600
  publishableKey: publishableKey || "",
597
601
  apiUrl: DEFAULT_API_URL,
598
- authFeatures: ["forgot-password"],
602
+ authFeatures: plain ? [] : ["forgot-password"],
599
603
  databaseChoice: "none",
600
604
  useTailwind: true,
601
- includeDashboard: true,
602
- includeGithatFolder: projectType === "frontend",
605
+ includeDashboard: !plain,
606
+ includeGithatFolder: !plain && projectType === "frontend",
603
607
  initGit: true,
604
608
  installDeps: true
605
609
  };
606
610
  }
607
611
  async function runPrompts(args) {
608
612
  if (args.yes && args.initialName) {
609
- p8.log.info("Using defaults (--yes flag)");
610
- return getDefaults(args.initialName, args.publishableKey, args.typescript, args.fullstack, args.backendFramework);
613
+ p8.log.info(args.plain ? "Using plain defaults (--yes --plain)" : "Using defaults (--yes flag)");
614
+ return getDefaults(args.initialName, args.publishableKey, args.typescript, args.fullstack, args.backendFramework, args.plain);
611
615
  }
612
616
  p8.intro("Let's set up your GitHat app");
613
617
  sectionHeader("Project");
@@ -674,6 +678,9 @@ var TEMPLATES_ROOT = path.resolve(__dirname2, "..", "templates");
674
678
  Handlebars.registerHelper("ifEquals", function(a, b, options) {
675
679
  return a === b ? options.fn(this) : options.inverse(this);
676
680
  });
681
+ Handlebars.registerHelper("ifNext", function(framework, options) {
682
+ return framework === "nextjs" || framework === "plain" ? options.fn(this) : options.inverse(this);
683
+ });
677
684
  function getTemplatesRoot() {
678
685
  return TEMPLATES_ROOT;
679
686
  }
@@ -721,14 +728,17 @@ function writeJson(root, relativePath, data) {
721
728
 
722
729
  // src/scaffold/package-builder.ts
723
730
  function buildPackageJson(ctx) {
724
- const isNext = ctx.framework === "nextjs";
731
+ const isNext = ctx.framework === "nextjs" || ctx.framework === "plain";
725
732
  const deps = {
726
733
  ...isNext ? DEPS.nextjs.dependencies : DEPS["react-vite"].dependencies
727
734
  };
728
735
  const devDeps = {
729
736
  ...isNext ? DEPS.nextjs.devDependencies : DEPS["react-vite"].devDependencies
730
737
  };
731
- if (ctx.useTailwind) {
738
+ if (ctx.framework === "plain") {
739
+ delete deps["@githat/ui"];
740
+ }
741
+ if (ctx.useTailwind || ctx.framework === "plain") {
732
742
  if (isNext) {
733
743
  Object.assign(devDeps, DEPS.tailwind.devDependencies);
734
744
  } else {
@@ -922,7 +932,7 @@ async function scaffold(context, options) {
922
932
  writeJson(root, "package.json", pkg);
923
933
  }, "package.json generated");
924
934
  }
925
- if (!isFullstack && context.framework === "nextjs") {
935
+ if (!isFullstack && (context.framework === "nextjs" || context.framework === "plain")) {
926
936
  await registerApp(context.projectName, root);
927
937
  }
928
938
  if (options.initGit) {
@@ -1577,9 +1587,27 @@ skillsCommand.action(() => {
1577
1587
  // src/cli.ts
1578
1588
  var program = new Command7();
1579
1589
  program.name("githat").description("GitHat CLI - Scaffold apps and manage skills").version(VERSION);
1580
- program.command("create [project-name]", { isDefault: true }).description("Scaffold a new GitHat app").option("--key <key>", "GitHat publishable key (pk_live_...)").option("--ts", "Use TypeScript (default)").option("--js", "Use JavaScript").option("--fullstack", "Create fullstack project (Turborepo)").option("--backend <framework>", "Backend framework (hono, express, fastify)").option("-y, --yes", "Skip prompts and use defaults").action(async (projectName, opts) => {
1590
+ program.command("create [project-name]", { isDefault: true }).description("Scaffold a new GitHat app").option("--key <key>", "GitHat publishable key (pk_live_...)").option("--ts", "Use TypeScript (default)").option("--js", "Use JavaScript").option("--plain", "Smallest scaffold: auth + a homepage. No dashboard, no orgs.").option("--fullstack", "Create fullstack project (Turborepo)").option("--backend <framework>", "Backend framework (hono, express, fastify)").option("-y, --yes", "Skip prompts and use defaults").action(async (projectName, opts) => {
1581
1591
  try {
1582
1592
  displayBanner();
1593
+ if (!opts.yes && !opts.key) {
1594
+ p12.note(
1595
+ [
1596
+ chalk10.bold("Two ways to connect this app to GitHat:"),
1597
+ "",
1598
+ ` ${chalk10.cyan("1.")} ${chalk10.bold("Already signed up?")} Pass your key:`,
1599
+ ` ${chalk10.dim("npx create-githat-app my-app --key pk_live_...")}`,
1600
+ ` Get the key at ${chalk10.cyan("https://githat.io/dashboard/apps")}`,
1601
+ "",
1602
+ ` ${chalk10.cyan("2.")} ${chalk10.bold("Don't have an account yet?")} Press Enter`,
1603
+ ` below \u2014 we'll open a browser, you sign up in 30s,`,
1604
+ ` and the key is stitched in for you.`,
1605
+ "",
1606
+ chalk10.dim("Either path lands you in the same place.")
1607
+ ].join("\n"),
1608
+ "First time with GitHat?"
1609
+ );
1610
+ }
1583
1611
  const typescript = opts.js ? false : opts.ts ? true : void 0;
1584
1612
  if (opts.yes && !projectName) {
1585
1613
  p12.cancel(chalk10.red("Project name is required when using --yes flag"));
@@ -1590,6 +1618,7 @@ program.command("create [project-name]", { isDefault: true }).description("Scaff
1590
1618
  publishableKey: opts.key,
1591
1619
  typescript,
1592
1620
  yes: opts.yes,
1621
+ plain: opts.plain,
1593
1622
  fullstack: opts.fullstack,
1594
1623
  backendFramework: opts.backend
1595
1624
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-githat-app",
3
- "version": "1.0.11",
3
+ "version": "1.0.14",
4
4
  "description": "GitHat CLI — scaffold apps and manage the skills marketplace",
5
5
  "type": "module",
6
6
  "bin": {
@@ -62,6 +62,6 @@
62
62
  "url": "git+https://github.com/GitHat-IO/create-githat-app.git"
63
63
  },
64
64
  "engines": {
65
- "node": ">=18"
65
+ "node": ">=20.10"
66
66
  }
67
67
  }
@@ -1,11 +1,11 @@
1
1
  # GitHat Identity
2
- {{#ifEquals framework "nextjs"}}
2
+ {{#ifNext framework}}
3
3
  NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY=pk_test_your_key_here
4
4
  NEXT_PUBLIC_GITHAT_API_URL={{apiUrl}}
5
5
  {{else}}
6
6
  VITE_GITHAT_PUBLISHABLE_KEY=pk_test_your_key_here
7
7
  VITE_GITHAT_API_URL={{apiUrl}}
8
- {{/ifEquals}}
8
+ {{/ifNext}}
9
9
  {{#if useDatabase}}
10
10
 
11
11
  # Database
@@ -1,4 +1,4 @@
1
- {{#ifEquals framework "nextjs"}}
1
+ {{#ifNext framework}}
2
2
  # GitHat — publishable key for this app.
3
3
  # Get yours at https://githat.io/dashboard/apps
4
4
  NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY=pk_live_your_key_here
@@ -12,7 +12,7 @@ VITE_GITHAT_PUBLISHABLE_KEY=pk_live_your_key_here
12
12
 
13
13
  # GitHat API base URL (leave as-is unless using a self-hosted deployment)
14
14
  VITE_GITHAT_API_URL={{apiUrl}}
15
- {{/ifEquals}}
15
+ {{/ifNext}}
16
16
  {{#if useDatabase}}
17
17
 
18
18
  # Database
@@ -1,10 +1,10 @@
1
- {{#ifEquals framework "nextjs"}}
1
+ {{#ifNext framework}}
2
2
  NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY={{publishableKey}}
3
3
  NEXT_PUBLIC_GITHAT_API_URL={{apiUrl}}
4
4
  {{else}}
5
5
  VITE_GITHAT_PUBLISHABLE_KEY={{publishableKey}}
6
6
  VITE_GITHAT_API_URL={{apiUrl}}
7
- {{/ifEquals}}
7
+ {{/ifNext}}
8
8
  {{#if useDatabase}}
9
9
  DATABASE_URL="postgresql://user:password@localhost:5432/{{projectName}}"
10
10
  {{/if}}
@@ -1,3 +1,4 @@
1
+ @import "@githat/ui/tokens.css";
1
2
  {{#if useTailwind}}
2
3
  @import "tailwindcss";
3
4
  {{/if}}
@@ -9,9 +10,9 @@
9
10
  }
10
11
 
11
12
  body {
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
- background: #09090b;
14
- color: #fafafa;
13
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
14
+ background: var(--bg, #09090b);
15
+ color: var(--fg, #fafafa);
15
16
  }
16
17
 
17
18
  a {
@@ -1,4 +1,5 @@
1
1
  import { GitHatProvider } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
  import '@githat/nextjs/styles';
3
4
  import './globals.css';
4
5
 
@@ -18,13 +19,11 @@ export default function RootLayout({ children }{{#if typescript}}: { children: R
18
19
  afterSignInUrl: '/dashboard',
19
20
  afterSignOutUrl: '/',
20
21
  }}>
21
- {children}
22
+ <header style=\{{ padding: 'var(--space-4, 1rem) var(--space-6, 1.5rem)', borderBottom: '1px solid var(--border, #e5e7eb)' }}>
23
+ <Wordmark name="{{businessName}}" size="md" href="/" />
24
+ </header>
25
+ <main>{children}</main>
22
26
  </GitHatProvider>
23
- <footer style=\{{ textAlign: 'center', padding: '1rem 0', fontSize: '0.75rem', color: '#52525b' }}>
24
- <a href="https://githat.io" target="_blank" rel="noopener noreferrer" style=\{{ color: '#7c3aed', textDecoration: 'none' }}>
25
- Powered by GitHat
26
- </a>
27
- </footer>
28
27
  </body>
29
28
  </html>
30
29
  );
@@ -1,11 +1,10 @@
1
1
  import { SignInButton, SignUpButton } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
 
3
4
  export default function Home() {
4
5
  return (
5
6
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-6 bg-[#09090b] text-[#fafafa]"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '1.5rem', background: '#09090b', color: '#fafafa' }}{{/if}}>
6
- <h1 {{#if useTailwind}}className="text-4xl font-bold"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700 }}{{/if}}>
7
- Welcome to {{businessName}}
8
- </h1>
7
+ <Wordmark name="{{businessName}}" size="xl" />
9
8
  <p {{#if useTailwind}}className="text-zinc-400 max-w-lg text-center"{{else}}style=\{{ color: '#a1a1aa', maxWidth: '32rem', textAlign: 'center' }}{{/if}}>
10
9
  {{description}}
11
10
  </p>
@@ -11,6 +11,7 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@githat/nextjs": "^0.2.6",
14
+ "@githat/ui": "^1.0.0",
14
15
  "next": "^16.0.0",
15
16
  "react": "^19.0.0",
16
17
  "react-dom": "^19.0.0"
@@ -1,3 +1,4 @@
1
+ @import "@githat/ui/tokens.css";
1
2
  {{#if useTailwind}}
2
3
  @import "tailwindcss";
3
4
  {{/if}}
@@ -9,9 +10,9 @@
9
10
  }
10
11
 
11
12
  body {
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
- background: #09090b;
14
- color: #fafafa;
13
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
14
+ background: var(--bg, #09090b);
15
+ color: var(--fg, #fafafa);
15
16
  }
16
17
 
17
18
  a {
@@ -1,4 +1,5 @@
1
1
  import { GitHatProvider } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
  import '@githat/nextjs/styles';
3
4
  import './globals.css';
4
5
  {{#if includeGithatFolder}}
@@ -25,13 +26,11 @@ export default function RootLayout({ children }{{#if typescript}}: { children: R
25
26
  afterSignOutUrl: '/',
26
27
  {{/if}}
27
28
  }}>
28
- {children}
29
+ <header style=\{{ padding: 'var(--space-4, 1rem) var(--space-6, 1.5rem)', borderBottom: '1px solid var(--border, #e5e7eb)' }}>
30
+ <Wordmark name="{{businessName}}" size="md" href="/" />
31
+ </header>
32
+ <main>{children}</main>
29
33
  </GitHatProvider>
30
- <footer style=\{{ textAlign: 'center', padding: '1rem 0', fontSize: '0.75rem', color: '#52525b' }}>
31
- <a href="https://githat.io" target="_blank" rel="noopener noreferrer" style=\{{ color: '#7c3aed', textDecoration: 'none' }}>
32
- Powered by GitHat
33
- </a>
34
- </footer>
35
34
  </body>
36
35
  </html>
37
36
  );
@@ -1,4 +1,5 @@
1
1
  import { SignInButton, SignUpButton } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
 
3
4
  const hasKey = !!process.env.NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY;
4
5
 
@@ -6,9 +7,7 @@ function SetupGuide() {
6
7
  return (
7
8
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-8 bg-[#09090b] text-[#fafafa] px-6"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '2rem', background: '#09090b', color: '#fafafa', padding: '0 1.5rem' }}{{/if}}>
8
9
  <div {{#if useTailwind}}className="text-center"{{else}}style=\{{ textAlign: 'center' }}{{/if}}>
9
- <h1 {{#if useTailwind}}className="text-4xl font-bold mb-2"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700, marginBottom: '0.5rem' }}{{/if}}>
10
- {{businessName}}
11
- </h1>
10
+ <Wordmark name="{{businessName}}" size="xl" />
12
11
  <p {{#if useTailwind}}className="text-zinc-400"{{else}}style=\{{ color: '#a1a1aa' }}{{/if}}>
13
12
  Get started in 3 steps
14
13
  </p>
@@ -58,9 +57,7 @@ export default function Home() {
58
57
 
59
58
  return (
60
59
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-6 bg-[#09090b] text-[#fafafa]"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '1.5rem', background: '#09090b', color: '#fafafa' }}{{/if}}>
61
- <h1 {{#if useTailwind}}className="text-4xl font-bold"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700 }}{{/if}}>
62
- Welcome to {{businessName}}
63
- </h1>
60
+ <Wordmark name="{{businessName}}" size="xl" />
64
61
  <p {{#if useTailwind}}className="text-zinc-400 max-w-lg text-center"{{else}}style=\{{ color: '#a1a1aa', maxWidth: '32rem', textAlign: 'center' }}{{/if}}>
65
62
  {{description}}
66
63
  </p>
@@ -0,0 +1,9 @@
1
+ import { SignInForm } from '@githat/nextjs';
2
+
3
+ export default function SignInPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignInForm signUpUrl="/sign-up" {{#if includeForgotPassword}}forgotPasswordUrl="/forgot-password"{{/if}} />
7
+ </main>
8
+ );
9
+ }
@@ -0,0 +1,9 @@
1
+ import { SignUpForm } from '@githat/nextjs';
2
+
3
+ export default function SignUpPage() {
4
+ return (
5
+ <main {{#if useTailwind}}className="flex items-center justify-center min-h-screen bg-[#09090b]"{{else}}style=\{{ display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', background: '#09090b' }}{{/if}}>
6
+ <SignUpForm signInUrl="/sign-in" />
7
+ </main>
8
+ );
9
+ }
@@ -0,0 +1,87 @@
1
+ /*
2
+ * Tailwind v4 — required because @githat/nextjs/styles is processed
3
+ * through @tailwindcss/postcss. Plain doesn't ship utility classes,
4
+ * but the import is needed for the auth pages to render styled.
5
+ */
6
+ @import "tailwindcss";
7
+
8
+ /*
9
+ * Plain template — self-contained globals.
10
+ *
11
+ * Defines the minimum CSS variables a GitHat app uses for layout and
12
+ * the auth-page styling that ships with @githat/nextjs/styles.
13
+ * Override these in your own files when you want a real theme.
14
+ *
15
+ * Light theme by default; flip --bg/--fg for dark.
16
+ */
17
+
18
+ :root {
19
+ /* Surface */
20
+ --bg: #ffffff;
21
+ --surface: #fafafa;
22
+ --surface-sub: #f4f4f5;
23
+
24
+ /* Borders */
25
+ --border: #e5e7eb;
26
+
27
+ /* Foreground */
28
+ --fg: #0a0a0a;
29
+ --fg-muted: #525252;
30
+ --fg-subtle: #737373;
31
+
32
+ /* Brand — change these two to re-skin the whole auth flow */
33
+ --primary: #6366f1;
34
+ --accent: #f59e0b;
35
+
36
+ /* Semantic */
37
+ --success: #16a34a;
38
+ --warn: #d97706;
39
+ --danger: #dc2626;
40
+
41
+ /* Spacing — used by @githat/nextjs/styles */
42
+ --space-1: 0.25rem;
43
+ --space-2: 0.5rem;
44
+ --space-3: 0.75rem;
45
+ --space-4: 1rem;
46
+ --space-6: 1.5rem;
47
+ --space-8: 2rem;
48
+
49
+ /* Radius */
50
+ --radius: 0.5rem;
51
+ --radius-md: 0.5rem;
52
+ --radius-lg: 0.75rem;
53
+
54
+ /* Fonts */
55
+ --font-sans: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
56
+ --font-wordmark: 'Instrument Serif', Georgia, serif;
57
+ }
58
+
59
+ @media (prefers-color-scheme: dark) {
60
+ :root {
61
+ --bg: #0a0a0a;
62
+ --surface: #18181b;
63
+ --surface-sub: #27272a;
64
+ --border: #3f3f46;
65
+ --fg: #fafafa;
66
+ --fg-muted: #a1a1aa;
67
+ --fg-subtle: #71717a;
68
+ }
69
+ }
70
+
71
+ * {
72
+ box-sizing: border-box;
73
+ margin: 0;
74
+ padding: 0;
75
+ }
76
+
77
+ body {
78
+ font-family: var(--font-sans);
79
+ background: var(--bg);
80
+ color: var(--fg);
81
+ line-height: 1.5;
82
+ }
83
+
84
+ a {
85
+ color: inherit;
86
+ text-decoration: none;
87
+ }
@@ -0,0 +1,41 @@
1
+ import { GitHatProvider } from '@githat/nextjs';
2
+ import '@githat/nextjs/styles';
3
+ import './globals.css';
4
+
5
+ export const metadata = {
6
+ title: '{{businessName}}',
7
+ description: '{{description}}',
8
+ };
9
+
10
+ export default function RootLayout({ children }{{#if typescript}}: { children: React.ReactNode }{{/if}}) {
11
+ return (
12
+ <html lang="en">
13
+ <body>
14
+ {/*
15
+ Plain template: no @githat/ui dep, no Wordmark. The
16
+ full-kit (`nextjs`) template uses @githat/ui for the
17
+ shared design system; the plain scaffold is the smallest
18
+ working app, so we avoid extra deps.
19
+ */}
20
+ <GitHatProvider config=\{{
21
+ publishableKey: process.env.NEXT_PUBLIC_GITHAT_PUBLISHABLE_KEY || '',
22
+ signInUrl: '/sign-in',
23
+ signUpUrl: '/sign-up',
24
+ afterSignInUrl: '/',
25
+ afterSignOutUrl: '/',
26
+ }}>
27
+ <header style=\{{
28
+ padding: '1rem 1.5rem',
29
+ borderBottom: '1px solid var(--border, #e5e7eb)',
30
+ fontFamily: 'system-ui, -apple-system, sans-serif',
31
+ }}>
32
+ <a href="/" style=\{{ textDecoration: 'none', color: 'inherit', fontWeight: 600 }}>
33
+ {{businessName}}
34
+ </a>
35
+ </header>
36
+ <main>{children}</main>
37
+ </GitHatProvider>
38
+ </body>
39
+ </html>
40
+ );
41
+ }
@@ -0,0 +1,123 @@
1
+ 'use client';
2
+
3
+ import { SignInButton, SignUpButton, UserButton, useAuth } from '@githat/nextjs';
4
+
5
+ /**
6
+ * Plain GitHat homepage.
7
+ *
8
+ * No dashboard, no orgs, no agents — just one page that flips between
9
+ * "signed out" and "signed in." The smallest possible example of "I
10
+ * have GitHat wired up." Replace this file with whatever your app
11
+ * actually does — auth keeps working.
12
+ */
13
+ export default function Home() {
14
+ const { isSignedIn, isLoading, user } = useAuth();
15
+
16
+ if (isLoading) {
17
+ return (
18
+ <div
19
+ style=\{{
20
+ display: 'flex',
21
+ minHeight: 'calc(100vh - 64px)',
22
+ alignItems: 'center',
23
+ justifyContent: 'center',
24
+ color: 'var(--fg-muted)',
25
+ }}
26
+ >
27
+ Loading…
28
+ </div>
29
+ );
30
+ }
31
+
32
+ return (
33
+ <div
34
+ style=\{{
35
+ display: 'flex',
36
+ minHeight: 'calc(100vh - 64px)',
37
+ alignItems: 'center',
38
+ justifyContent: 'center',
39
+ padding: 'var(--space-8) var(--space-4)',
40
+ background: 'var(--bg)',
41
+ }}
42
+ >
43
+ <main
44
+ style=\{{
45
+ width: '100%',
46
+ maxWidth: '32rem',
47
+ textAlign: 'center',
48
+ color: 'var(--fg)',
49
+ }}
50
+ >
51
+ {!isSignedIn ? (
52
+ <>
53
+ <h1
54
+ style=\{{
55
+ fontFamily: 'var(--font-wordmark)',
56
+ fontSize: '2.5rem',
57
+ lineHeight: 1.1,
58
+ marginBottom: 'var(--space-3)',
59
+ }}
60
+ >
61
+ Welcome to {{businessName}}
62
+ </h1>
63
+ <p
64
+ style=\{{
65
+ color: 'var(--fg-muted)',
66
+ marginBottom: 'var(--space-6)',
67
+ lineHeight: 1.6,
68
+ }}
69
+ >
70
+ Sign in to continue, or create an account in 30 seconds.
71
+ We use GitHat for identity — your password never touches
72
+ this app.
73
+ </p>
74
+ <div
75
+ style=\{{
76
+ display: 'flex',
77
+ gap: 'var(--space-3)',
78
+ justifyContent: 'center',
79
+ flexWrap: 'wrap',
80
+ }}
81
+ >
82
+ <SignInButton />
83
+ <SignUpButton />
84
+ </div>
85
+ </>
86
+ ) : (
87
+ <>
88
+ <div
89
+ style=\{{
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ justifyContent: 'center',
93
+ gap: 'var(--space-4)',
94
+ marginBottom: 'var(--space-6)',
95
+ }}
96
+ >
97
+ <UserButton />
98
+ <h1
99
+ style=\{{
100
+ fontFamily: 'var(--font-wordmark)',
101
+ fontSize: '2rem',
102
+ margin: 0,
103
+ }}
104
+ >
105
+ Hello{user?.name ? `, ${user.name}` : ''}.
106
+ </h1>
107
+ </div>
108
+ <p
109
+ style=\{{
110
+ color: 'var(--fg-muted)',
111
+ lineHeight: 1.6,
112
+ }}
113
+ >
114
+ That's it. The plain template doesn't ship a dashboard or
115
+ any other route — replace this page with whatever your
116
+ app actually does. Authentication will keep working.
117
+ </p>
118
+ </>
119
+ )}
120
+ </main>
121
+ </div>
122
+ );
123
+ }
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from 'next';
2
+
3
+ const nextConfig: NextConfig = {
4
+ output: 'standalone',
5
+ };
6
+
7
+ export default nextConfig;
@@ -0,0 +1,14 @@
1
+ /*
2
+ * Plain template — Tailwind v4 PostCSS plugin is required even though
3
+ * the plain scaffold doesn't use Tailwind utility classes. The auth
4
+ * page CSS shipped by `@githat/nextjs/styles` is processed through
5
+ * @tailwindcss/postcss at build time. Drop this config and the
6
+ * auth pages render unstyled.
7
+ */
8
+ const config = {
9
+ plugins: {
10
+ '@tailwindcss/postcss': {},
11
+ },
12
+ };
13
+
14
+ export default config;
@@ -0,0 +1,10 @@
1
+ import { authProxy } from '@githat/nextjs/proxy';
2
+
3
+ export const proxy = authProxy({
4
+ publicRoutes: ['/', '/sign-in', '/sign-up'{{#if includeForgotPassword}}, '/forgot-password', '/reset-password'{{/if}}{{#if includeEmailVerification}}, '/verify-email'{{/if}}],
5
+ signInUrl: '/sign-in',
6
+ });
7
+
8
+ export const config = {
9
+ matcher: ['/((?!_next|api|.*\\..*).*)'],
10
+ };
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "preserve",
15
+ "incremental": true,
16
+ "plugins": [{ "name": "next" }],
17
+ "paths": { "@/*": ["./*"] }
18
+ },
19
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
20
+ "exclude": ["node_modules"]
21
+ }
@@ -43,11 +43,6 @@ export default function App() {
43
43
  {{/if}}
44
44
  <Route path="*" element={<NotFound />} />
45
45
  </Routes>
46
- <footer style=\{{ textAlign: 'center', padding: '1rem 0', fontSize: '0.75rem', color: '#52525b' }}>
47
- <a href="https://githat.io" target="_blank" rel="noopener noreferrer" style=\{{ color: '#7c3aed', textDecoration: 'none' }}>
48
- Powered by GitHat
49
- </a>
50
- </footer>
51
46
  </>
52
47
  );
53
48
  }
@@ -1,3 +1,4 @@
1
+ @import "@githat/ui/tokens.css";
1
2
  {{#if useTailwind}}
2
3
  @import "tailwindcss";
3
4
  {{/if}}
@@ -9,9 +10,9 @@
9
10
  }
10
11
 
11
12
  body {
12
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
- background: #09090b;
14
- color: #fafafa;
13
+ font-family: var(--font-sans, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
14
+ background: var(--bg, #09090b);
15
+ color: var(--fg, #fafafa);
15
16
  }
16
17
 
17
18
  a {
@@ -1,4 +1,5 @@
1
1
  import { SignInButton, SignUpButton } from '@githat/nextjs';
2
+ import { Wordmark } from '@githat/ui';
2
3
 
3
4
  const hasKey = !!import.meta.env.VITE_GITHAT_PUBLISHABLE_KEY;
4
5
 
@@ -6,9 +7,7 @@ function SetupGuide() {
6
7
  return (
7
8
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-8 bg-[#09090b] text-[#fafafa] px-6"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '2rem', background: '#09090b', color: '#fafafa', padding: '0 1.5rem' }}{{/if}}>
8
9
  <div {{#if useTailwind}}className="text-center"{{else}}style=\{{ textAlign: 'center' }}{{/if}}>
9
- <h1 {{#if useTailwind}}className="text-4xl font-bold mb-2"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700, marginBottom: '0.5rem' }}{{/if}}>
10
- {{businessName}}
11
- </h1>
10
+ <Wordmark name="{{businessName}}" size="xl" />
12
11
  <p {{#if useTailwind}}className="text-zinc-400"{{else}}style=\{{ color: '#a1a1aa' }}{{/if}}>
13
12
  Get started in 3 steps
14
13
  </p>
@@ -58,9 +57,7 @@ export default function Home() {
58
57
 
59
58
  return (
60
59
  <main {{#if useTailwind}}className="flex flex-col items-center justify-center min-h-screen gap-6 bg-[#09090b] text-[#fafafa]"{{else}}style=\{{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', minHeight: '100vh', gap: '1.5rem', background: '#09090b', color: '#fafafa' }}{{/if}}>
61
- <h1 {{#if useTailwind}}className="text-4xl font-bold"{{else}}style=\{{ fontSize: '2.5rem', fontWeight: 700 }}{{/if}}>
62
- Welcome to {{businessName}}
63
- </h1>
60
+ <Wordmark name="{{businessName}}" size="xl" />
64
61
  <p {{#if useTailwind}}className="text-zinc-400 max-w-lg text-center"{{else}}style=\{{ color: '#a1a1aa', maxWidth: '32rem', textAlign: 'center' }}{{/if}}>
65
62
  {{description}}
66
63
  </p>