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.
- package/dist/cli.js +85 -14
- package/package.json +2 -2
- package/templates/agent/TODO.md +9 -0
- package/templates/agent/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/agent/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/agent/app/globals.css.hbs +87 -0
- package/templates/agent/app/layout.tsx.hbs +41 -0
- package/templates/agent/app/page.tsx.hbs +123 -0
- package/templates/agent/next.config.ts.hbs +7 -0
- package/templates/agent/postcss.config.mjs.hbs +14 -0
- package/templates/agent/proxy.ts.hbs +10 -0
- package/templates/agent/tsconfig.json.hbs +21 -0
- package/templates/base/.env.example.hbs +2 -2
- package/templates/base/.env.local.example.hbs +2 -2
- package/templates/base/.env.local.hbs +2 -2
- package/templates/content/TODO.md +9 -0
- package/templates/content/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/content/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/content/app/globals.css.hbs +87 -0
- package/templates/content/app/layout.tsx.hbs +41 -0
- package/templates/content/app/page.tsx.hbs +123 -0
- package/templates/content/next.config.ts.hbs +7 -0
- package/templates/content/postcss.config.mjs.hbs +14 -0
- package/templates/content/proxy.ts.hbs +10 -0
- package/templates/content/tsconfig.json.hbs +21 -0
- package/templates/dashboard/TODO.md +9 -0
- package/templates/dashboard/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/dashboard/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/dashboard/app/globals.css.hbs +87 -0
- package/templates/dashboard/app/layout.tsx.hbs +41 -0
- package/templates/dashboard/app/page.tsx.hbs +123 -0
- package/templates/dashboard/next.config.ts.hbs +7 -0
- package/templates/dashboard/postcss.config.mjs.hbs +14 -0
- package/templates/dashboard/proxy.ts.hbs +10 -0
- package/templates/dashboard/tsconfig.json.hbs +21 -0
- package/templates/marketplace/CULTURE.md +74 -0
- package/templates/marketplace/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/marketplace/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/marketplace/app/(shop)/[slug]/p/[productId]/page.tsx.hbs +99 -0
- package/templates/marketplace/app/(shop)/[slug]/page.tsx.hbs +90 -0
- package/templates/marketplace/app/admin/page.tsx.hbs +95 -0
- package/templates/marketplace/app/cart/page.tsx.hbs +157 -0
- package/templates/marketplace/app/globals.css.hbs +87 -0
- package/templates/marketplace/app/layout.tsx.hbs +77 -0
- package/templates/marketplace/app/page.tsx.hbs +178 -0
- package/templates/marketplace/app/sell/page.tsx.hbs +78 -0
- package/templates/marketplace/next.config.ts.hbs +7 -0
- package/templates/marketplace/postcss.config.mjs.hbs +14 -0
- package/templates/marketplace/proxy.ts.hbs +10 -0
- package/templates/marketplace/src/lib/anon-session.ts.hbs +117 -0
- package/templates/marketplace/src/lib/categories.ts.hbs +35 -0
- package/templates/marketplace/tsconfig.json.hbs +21 -0
- package/templates/plain/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/plain/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/plain/app/globals.css.hbs +87 -0
- package/templates/plain/app/layout.tsx.hbs +41 -0
- package/templates/plain/app/page.tsx.hbs +123 -0
- package/templates/plain/next.config.ts.hbs +7 -0
- package/templates/plain/postcss.config.mjs.hbs +14 -0
- package/templates/plain/proxy.ts.hbs +10 -0
- package/templates/plain/tsconfig.json.hbs +21 -0
- package/templates/saas/TODO.md +9 -0
- package/templates/saas/app/(auth)/sign-in/page.tsx.hbs +9 -0
- package/templates/saas/app/(auth)/sign-up/page.tsx.hbs +9 -0
- package/templates/saas/app/globals.css.hbs +87 -0
- package/templates/saas/app/layout.tsx.hbs +41 -0
- package/templates/saas/app/page.tsx.hbs +123 -0
- package/templates/saas/next.config.ts.hbs +7 -0
- package/templates/saas/postcss.config.mjs.hbs +14 -0
- package/templates/saas/proxy.ts.hbs +10 -0
- 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.
|
|
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: "
|
|
334
|
-
{ value: "
|
|
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
|
|
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:
|
|
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(
|
|
612
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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": ">=
|
|
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,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
|
-
{{#
|
|
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
|
-
{{/
|
|
8
|
+
{{/ifNext}}
|
|
9
9
|
{{#if useDatabase}}
|
|
10
10
|
|
|
11
11
|
# Database
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
{{#
|
|
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
|
-
{{/
|
|
15
|
+
{{/ifNext}}
|
|
16
16
|
{{#if useDatabase}}
|
|
17
17
|
|
|
18
18
|
# Database
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{{#
|
|
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
|
-
{{/
|
|
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
|
+
}
|