create-githat-app 1.0.13 → 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.13";
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"];
@@ -330,7 +330,8 @@ 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" },
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" },
334
335
  { value: "react-vite", label: "React 19 + Vite 7", hint: "SPA \xB7 client-side routing" }
335
336
  ];
336
337
  const answers = await p3.group(
@@ -583,33 +584,34 @@ async function promptFinalize() {
583
584
  function toDisplayName(projectName) {
584
585
  return projectName.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
585
586
  }
586
- function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework) {
587
+ function getDefaults(projectName, publishableKey, typescript, fullstack, backendFramework, plain) {
587
588
  const displayName = toDisplayName(projectName);
588
589
  const projectType = fullstack ? "fullstack" : "frontend";
590
+ const framework = plain ? "plain" : "nextjs";
589
591
  return {
590
592
  projectName,
591
593
  businessName: displayName,
592
594
  description: `${displayName} \u2014 Built with GitHat`,
593
595
  projectType,
594
596
  backendFramework: fullstack ? backendFramework || "hono" : void 0,
595
- framework: "nextjs",
597
+ framework,
596
598
  typescript: typescript ?? true,
597
599
  packageManager: detectPackageManager(),
598
600
  publishableKey: publishableKey || "",
599
601
  apiUrl: DEFAULT_API_URL,
600
- authFeatures: ["forgot-password"],
602
+ authFeatures: plain ? [] : ["forgot-password"],
601
603
  databaseChoice: "none",
602
604
  useTailwind: true,
603
- includeDashboard: true,
604
- includeGithatFolder: projectType === "frontend",
605
+ includeDashboard: !plain,
606
+ includeGithatFolder: !plain && projectType === "frontend",
605
607
  initGit: true,
606
608
  installDeps: true
607
609
  };
608
610
  }
609
611
  async function runPrompts(args) {
610
612
  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);
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);
613
615
  }
614
616
  p8.intro("Let's set up your GitHat app");
615
617
  sectionHeader("Project");
@@ -676,6 +678,9 @@ var TEMPLATES_ROOT = path.resolve(__dirname2, "..", "templates");
676
678
  Handlebars.registerHelper("ifEquals", function(a, b, options) {
677
679
  return a === b ? options.fn(this) : options.inverse(this);
678
680
  });
681
+ Handlebars.registerHelper("ifNext", function(framework, options) {
682
+ return framework === "nextjs" || framework === "plain" ? options.fn(this) : options.inverse(this);
683
+ });
679
684
  function getTemplatesRoot() {
680
685
  return TEMPLATES_ROOT;
681
686
  }
@@ -723,14 +728,17 @@ function writeJson(root, relativePath, data) {
723
728
 
724
729
  // src/scaffold/package-builder.ts
725
730
  function buildPackageJson(ctx) {
726
- const isNext = ctx.framework === "nextjs";
731
+ const isNext = ctx.framework === "nextjs" || ctx.framework === "plain";
727
732
  const deps = {
728
733
  ...isNext ? DEPS.nextjs.dependencies : DEPS["react-vite"].dependencies
729
734
  };
730
735
  const devDeps = {
731
736
  ...isNext ? DEPS.nextjs.devDependencies : DEPS["react-vite"].devDependencies
732
737
  };
733
- if (ctx.useTailwind) {
738
+ if (ctx.framework === "plain") {
739
+ delete deps["@githat/ui"];
740
+ }
741
+ if (ctx.useTailwind || ctx.framework === "plain") {
734
742
  if (isNext) {
735
743
  Object.assign(devDeps, DEPS.tailwind.devDependencies);
736
744
  } else {
@@ -924,7 +932,7 @@ async function scaffold(context, options) {
924
932
  writeJson(root, "package.json", pkg);
925
933
  }, "package.json generated");
926
934
  }
927
- if (!isFullstack && context.framework === "nextjs") {
935
+ if (!isFullstack && (context.framework === "nextjs" || context.framework === "plain")) {
928
936
  await registerApp(context.projectName, root);
929
937
  }
930
938
  if (options.initGit) {
@@ -1579,9 +1587,27 @@ skillsCommand.action(() => {
1579
1587
  // src/cli.ts
1580
1588
  var program = new Command7();
1581
1589
  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) => {
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) => {
1583
1591
  try {
1584
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
+ }
1585
1611
  const typescript = opts.js ? false : opts.ts ? true : void 0;
1586
1612
  if (opts.yes && !projectName) {
1587
1613
  p12.cancel(chalk10.red("Project name is required when using --yes flag"));
@@ -1592,6 +1618,7 @@ program.command("create [project-name]", { isDefault: true }).description("Scaff
1592
1618
  publishableKey: opts.key,
1593
1619
  typescript,
1594
1620
  yes: opts.yes,
1621
+ plain: opts.plain,
1595
1622
  fullstack: opts.fullstack,
1596
1623
  backendFramework: opts.backend
1597
1624
  });
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.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}}
@@ -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
+ }