create-githat-app 1.0.13 → 1.0.15

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 (71) hide show
  1. package/dist/cli.js +85 -14
  2. package/package.json +2 -2
  3. package/templates/agent/TODO.md +9 -0
  4. package/templates/agent/app/(auth)/sign-in/page.tsx.hbs +9 -0
  5. package/templates/agent/app/(auth)/sign-up/page.tsx.hbs +9 -0
  6. package/templates/agent/app/globals.css.hbs +87 -0
  7. package/templates/agent/app/layout.tsx.hbs +41 -0
  8. package/templates/agent/app/page.tsx.hbs +123 -0
  9. package/templates/agent/next.config.ts.hbs +7 -0
  10. package/templates/agent/postcss.config.mjs.hbs +14 -0
  11. package/templates/agent/proxy.ts.hbs +10 -0
  12. package/templates/agent/tsconfig.json.hbs +21 -0
  13. package/templates/base/.env.example.hbs +2 -2
  14. package/templates/base/.env.local.example.hbs +2 -2
  15. package/templates/base/.env.local.hbs +2 -2
  16. package/templates/content/TODO.md +9 -0
  17. package/templates/content/app/(auth)/sign-in/page.tsx.hbs +9 -0
  18. package/templates/content/app/(auth)/sign-up/page.tsx.hbs +9 -0
  19. package/templates/content/app/globals.css.hbs +87 -0
  20. package/templates/content/app/layout.tsx.hbs +41 -0
  21. package/templates/content/app/page.tsx.hbs +123 -0
  22. package/templates/content/next.config.ts.hbs +7 -0
  23. package/templates/content/postcss.config.mjs.hbs +14 -0
  24. package/templates/content/proxy.ts.hbs +10 -0
  25. package/templates/content/tsconfig.json.hbs +21 -0
  26. package/templates/dashboard/TODO.md +9 -0
  27. package/templates/dashboard/app/(auth)/sign-in/page.tsx.hbs +9 -0
  28. package/templates/dashboard/app/(auth)/sign-up/page.tsx.hbs +9 -0
  29. package/templates/dashboard/app/globals.css.hbs +87 -0
  30. package/templates/dashboard/app/layout.tsx.hbs +41 -0
  31. package/templates/dashboard/app/page.tsx.hbs +123 -0
  32. package/templates/dashboard/next.config.ts.hbs +7 -0
  33. package/templates/dashboard/postcss.config.mjs.hbs +14 -0
  34. package/templates/dashboard/proxy.ts.hbs +10 -0
  35. package/templates/dashboard/tsconfig.json.hbs +21 -0
  36. package/templates/marketplace/CULTURE.md +74 -0
  37. package/templates/marketplace/app/(auth)/sign-in/page.tsx.hbs +9 -0
  38. package/templates/marketplace/app/(auth)/sign-up/page.tsx.hbs +9 -0
  39. package/templates/marketplace/app/(shop)/[slug]/p/[productId]/page.tsx.hbs +99 -0
  40. package/templates/marketplace/app/(shop)/[slug]/page.tsx.hbs +90 -0
  41. package/templates/marketplace/app/admin/page.tsx.hbs +95 -0
  42. package/templates/marketplace/app/cart/page.tsx.hbs +157 -0
  43. package/templates/marketplace/app/globals.css.hbs +87 -0
  44. package/templates/marketplace/app/layout.tsx.hbs +77 -0
  45. package/templates/marketplace/app/page.tsx.hbs +178 -0
  46. package/templates/marketplace/app/sell/page.tsx.hbs +78 -0
  47. package/templates/marketplace/next.config.ts.hbs +7 -0
  48. package/templates/marketplace/postcss.config.mjs.hbs +14 -0
  49. package/templates/marketplace/proxy.ts.hbs +10 -0
  50. package/templates/marketplace/src/lib/anon-session.ts.hbs +117 -0
  51. package/templates/marketplace/src/lib/categories.ts.hbs +35 -0
  52. package/templates/marketplace/tsconfig.json.hbs +21 -0
  53. package/templates/plain/app/(auth)/sign-in/page.tsx.hbs +9 -0
  54. package/templates/plain/app/(auth)/sign-up/page.tsx.hbs +9 -0
  55. package/templates/plain/app/globals.css.hbs +87 -0
  56. package/templates/plain/app/layout.tsx.hbs +41 -0
  57. package/templates/plain/app/page.tsx.hbs +123 -0
  58. package/templates/plain/next.config.ts.hbs +7 -0
  59. package/templates/plain/postcss.config.mjs.hbs +14 -0
  60. package/templates/plain/proxy.ts.hbs +10 -0
  61. package/templates/plain/tsconfig.json.hbs +21 -0
  62. package/templates/saas/TODO.md +9 -0
  63. package/templates/saas/app/(auth)/sign-in/page.tsx.hbs +9 -0
  64. package/templates/saas/app/(auth)/sign-up/page.tsx.hbs +9 -0
  65. package/templates/saas/app/globals.css.hbs +87 -0
  66. package/templates/saas/app/layout.tsx.hbs +41 -0
  67. package/templates/saas/app/page.tsx.hbs +123 -0
  68. package/templates/saas/next.config.ts.hbs +7 -0
  69. package/templates/saas/postcss.config.mjs.hbs +14 -0
  70. package/templates/saas/proxy.ts.hbs +10 -0
  71. package/templates/saas/tsconfig.json.hbs +21 -0
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.13";
14
+ var VERSION = "1.0.15";
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"];
@@ -330,8 +330,14 @@ function getInstallCommand(pm) {
330
330
  async function promptFramework(typescriptOverride, isFullstack) {
331
331
  const packageManager = detectPackageManager();
332
332
  const frameworkOptions = isFullstack ? [{ value: "nextjs", label: "Next.js 16", hint: "App Router \xB7 SSR \xB7 middleware auth" }] : [
333
- { value: "nextjs", label: "Next.js 16", hint: "App Router \xB7 SSR \xB7 middleware auth" },
334
- { value: "react-vite", label: "React 19 + Vite 7", hint: "SPA \xB7 client-side routing" }
333
+ { value: "plain", label: "Plain", hint: "Auth + a homepage. Smallest possible GitHat app." },
334
+ { value: "saas", label: "SaaS", hint: "Orgs, teams, RBAC, subscription billing. Replaces Clerk + Stripe." },
335
+ { value: "marketplace", label: "Marketplace", hint: "Multi-vendor commerce. Anonymous-first browsing, Sebastn Connect." },
336
+ { value: "agent", label: "AI Agent", hint: "Web4 wallet-bound agent + MCP server. Public verification." },
337
+ { value: "content", label: "Content", hint: "Paywalled posts, newsletter, one-time purchases. Replaces Substack." },
338
+ { value: "dashboard", label: "Dashboard", hint: "Auth-gated admin UI over your existing database." },
339
+ { value: "nextjs", label: "Next.js (full kit)", hint: "Legacy: dashboard + orgs + agents + MCP scaffolding." },
340
+ { value: "react-vite", label: "React + Vite", hint: "SPA \xB7 client-side routing." }
335
341
  ];
336
342
  const answers = await p3.group(
337
343
  {
@@ -583,33 +589,37 @@ async function promptFinalize() {
583
589
  function toDisplayName(projectName) {
584
590
  return projectName.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
585
591
  }
586
- function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework) {
592
+ function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework, template) {
587
593
  const displayName = toDisplayName(projectName);
588
594
  const projectType = fullstack ? "fullstack" : "frontend";
595
+ const framework = template ?? "nextjs";
596
+ const isMinimal = template !== void 0;
589
597
  return {
590
598
  projectName,
591
599
  businessName: displayName,
592
600
  description: `${displayName} \u2014 Built with GitHat`,
593
601
  projectType,
594
602
  backendFramework: fullstack ? backendFramework || "hono" : void 0,
595
- framework: "nextjs",
603
+ framework,
596
604
  typescript: typescript ?? true,
597
605
  packageManager: detectPackageManager(),
598
606
  publishableKey: publishableKey || "",
599
607
  apiUrl: DEFAULT_API_URL,
600
- authFeatures: ["forgot-password"],
608
+ authFeatures: isMinimal ? [] : ["forgot-password"],
601
609
  databaseChoice: "none",
602
610
  useTailwind: true,
603
- includeDashboard: true,
604
- includeGithatFolder: projectType === "frontend",
611
+ includeDashboard: !isMinimal,
612
+ includeGithatFolder: !isMinimal && projectType === "frontend",
605
613
  initGit: true,
606
614
  installDeps: true
607
615
  };
608
616
  }
609
617
  async function runPrompts(args) {
610
618
  if (args.yes && args.initialName) {
611
- p8.log.info("Using defaults (--yes flag)");
612
- return getDefaults(args.initialName, args.publishableKey, args.typescript, args.fullstack, args.backendFramework);
619
+ p8.log.info(
620
+ args.template ? `Using ${args.template} defaults (--yes --${args.template})` : "Using defaults (--yes flag)"
621
+ );
622
+ return getDefaults(args.initialName, args.publishableKey, args.typescript, args.fullstack, args.backendFramework, args.template);
613
623
  }
614
624
  p8.intro("Let's set up your GitHat app");
615
625
  sectionHeader("Project");
@@ -676,6 +686,18 @@ var TEMPLATES_ROOT = path.resolve(__dirname2, "..", "templates");
676
686
  Handlebars.registerHelper("ifEquals", function(a, b, options) {
677
687
  return a === b ? options.fn(this) : options.inverse(this);
678
688
  });
689
+ var NEXT_LIKE = /* @__PURE__ */ new Set([
690
+ "nextjs",
691
+ "plain",
692
+ "saas",
693
+ "marketplace",
694
+ "agent",
695
+ "content",
696
+ "dashboard"
697
+ ]);
698
+ Handlebars.registerHelper("ifNext", function(framework, options) {
699
+ return NEXT_LIKE.has(framework) ? options.fn(this) : options.inverse(this);
700
+ });
679
701
  function getTemplatesRoot() {
680
702
  return TEMPLATES_ROOT;
681
703
  }
@@ -722,15 +744,35 @@ function writeJson(root, relativePath, data) {
722
744
  }
723
745
 
724
746
  // src/scaffold/package-builder.ts
747
+ var NEXT_LIKE2 = /* @__PURE__ */ new Set([
748
+ "nextjs",
749
+ "plain",
750
+ "saas",
751
+ "marketplace",
752
+ "agent",
753
+ "content",
754
+ "dashboard"
755
+ ]);
756
+ var MINIMAL = /* @__PURE__ */ new Set([
757
+ "plain",
758
+ "saas",
759
+ "marketplace",
760
+ "agent",
761
+ "content",
762
+ "dashboard"
763
+ ]);
725
764
  function buildPackageJson(ctx) {
726
- const isNext = ctx.framework === "nextjs";
765
+ const isNext = NEXT_LIKE2.has(ctx.framework);
727
766
  const deps = {
728
767
  ...isNext ? DEPS.nextjs.dependencies : DEPS["react-vite"].dependencies
729
768
  };
730
769
  const devDeps = {
731
770
  ...isNext ? DEPS.nextjs.devDependencies : DEPS["react-vite"].devDependencies
732
771
  };
733
- if (ctx.useTailwind) {
772
+ if (MINIMAL.has(ctx.framework)) {
773
+ delete deps["@githat/ui"];
774
+ }
775
+ if (ctx.useTailwind || MINIMAL.has(ctx.framework)) {
734
776
  if (isNext) {
735
777
  Object.assign(devDeps, DEPS.tailwind.devDependencies);
736
778
  } else {
@@ -924,7 +966,16 @@ async function scaffold(context, options) {
924
966
  writeJson(root, "package.json", pkg);
925
967
  }, "package.json generated");
926
968
  }
927
- if (!isFullstack && context.framework === "nextjs") {
969
+ const NEXT_LIKE3 = /* @__PURE__ */ new Set([
970
+ "nextjs",
971
+ "plain",
972
+ "saas",
973
+ "marketplace",
974
+ "agent",
975
+ "content",
976
+ "dashboard"
977
+ ]);
978
+ if (!isFullstack && NEXT_LIKE3.has(context.framework)) {
928
979
  await registerApp(context.projectName, root);
929
980
  }
930
981
  if (options.initGit) {
@@ -1579,19 +1630,39 @@ skillsCommand.action(() => {
1579
1630
  // src/cli.ts
1580
1631
  var program = new Command7();
1581
1632
  program.name("githat").description("GitHat CLI - Scaffold apps and manage skills").version(VERSION);
1582
- 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) => {
1633
+ 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.").option("--saas", "B2B starter: orgs, teams, RBAC, subscription billing.").option("--marketplace", "Multi-vendor commerce: anonymous-first browsing, Sebastn Connect.").option("--agent", "Web4 wallet-bound autonomous agent + MCP server registration.").option("--content", "Paywalled posts, newsletter, one-time purchases via Sebastn.").option("--dashboard", "Admin UI over your existing database, auth-gated.").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) => {
1583
1634
  try {
1584
1635
  displayBanner();
1636
+ if (!opts.yes && !opts.key) {
1637
+ p12.note(
1638
+ [
1639
+ chalk10.bold("Two ways to connect this app to GitHat:"),
1640
+ "",
1641
+ ` ${chalk10.cyan("1.")} ${chalk10.bold("Already signed up?")} Pass your key:`,
1642
+ ` ${chalk10.dim("npx create-githat-app my-app --key pk_live_...")}`,
1643
+ ` Get the key at ${chalk10.cyan("https://githat.io/dashboard/apps")}`,
1644
+ "",
1645
+ ` ${chalk10.cyan("2.")} ${chalk10.bold("Don't have an account yet?")} Press Enter`,
1646
+ ` below \u2014 we'll open a browser, you sign up in 30s,`,
1647
+ ` and the key is stitched in for you.`,
1648
+ "",
1649
+ chalk10.dim("Either path lands you in the same place.")
1650
+ ].join("\n"),
1651
+ "First time with GitHat?"
1652
+ );
1653
+ }
1585
1654
  const typescript = opts.js ? false : opts.ts ? true : void 0;
1586
1655
  if (opts.yes && !projectName) {
1587
1656
  p12.cancel(chalk10.red("Project name is required when using --yes flag"));
1588
1657
  process.exit(1);
1589
1658
  }
1659
+ const template = opts.marketplace ? "marketplace" : opts.agent ? "agent" : opts.saas ? "saas" : opts.content ? "content" : opts.dashboard ? "dashboard" : opts.plain ? "plain" : void 0;
1590
1660
  const answers = await runPrompts({
1591
1661
  initialName: projectName,
1592
1662
  publishableKey: opts.key,
1593
1663
  typescript,
1594
1664
  yes: opts.yes,
1665
+ template,
1595
1666
  fullstack: opts.fullstack,
1596
1667
  backendFramework: opts.backend
1597
1668
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-githat-app",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
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
  }
@@ -0,0 +1,9 @@
1
+ # agent template — placeholder
2
+
3
+ This template currently mirrors `plain`. The dedicated agent scaffold is
4
+ queued. See `../../TEMPLATES.md` for the full lineup and the
5
+ `saas` / `content` / `dashboard` / `ai-agent` rows for what each
6
+ should ultimately ship.
7
+
8
+ For now, `npx create-githat-app my-thing --agent` lays down the plain
9
+ template — auth + a homepage. Wire your agent-specific routes on top.
@@ -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
+ }
@@ -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}}
@@ -0,0 +1,9 @@
1
+ # content template — placeholder
2
+
3
+ This template currently mirrors `plain`. The dedicated content scaffold is
4
+ queued. See `../../TEMPLATES.md` for the full lineup and the
5
+ `saas` / `content` / `dashboard` / `ai-agent` rows for what each
6
+ should ultimately ship.
7
+
8
+ For now, `npx create-githat-app my-thing --content` lays down the plain
9
+ template — auth + a homepage. Wire your content-specific routes on top.
@@ -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
+ }