Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
933ef25
feat(#354 | create-hypergraph-app): move hypergraph-app-template into…
cmwhited Jul 22, 2025
506177e
feat(#354 | create-hypergraph-app): remove scripts until ready
cmwhited Jul 22, 2025
4798e01
feat(#354 | create-hypergraph-app): add missing mapping.ts and main.t…
cmwhited Jul 22, 2025
5a4c193
feat(#351 | create-hypergraph-app): working on building create-hyperg…
cmwhited Jul 22, 2025
37f05ab
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 22, 2025
a004e4f
feat(#351 | create-hypergraph-app): use prompts instead of options
cmwhited Jul 22, 2025
6003c65
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 22, 2025
8ea798f
feat(#351 | create-hypergraph-app): bump @types/node to latest
cmwhited Jul 22, 2025
64d196d
feat(#351 | create-hypergraph-app): buildout ability scaffold app, in…
cmwhited Jul 22, 2025
63fa01e
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 22, 2025
68a79db
feat(#351 | create-hypergraph-app): rebase main. sort order import
cmwhited Jul 22, 2025
39beee4
feat(#351 | create-hypergraph-app): fixes. updates from testing
cmwhited Jul 23, 2025
deee18d
feat(#351 | create-hypergraph-app): add create-hypergraph-app tests t…
cmwhited Jul 23, 2025
bd88912
feat(#351 | create-hypergraph-app): handle sigint of user killing cli…
cmwhited Jul 23, 2025
447cdb4
feat(#351 | create-hypergraph): rename to create-hypergraph (drop app)
cmwhited Jul 23, 2025
ba47d53
feat(#351 | create-hypergraph): rename package.json bin to create-hyp…
cmwhited Jul 23, 2025
f40426b
feat(#351 | create-hypergraph): fix typo
cmwhited Jul 23, 2025
4446ffe
feat(#351 | create-hypergraph): resolve inputs from passed in options…
cmwhited Jul 23, 2025
f54e72a
feat(#351 | create-hypergraph): create llms.txt for create-hypergraph…
cmwhited Jul 23, 2025
97894a1
feat(#351 | create-hypergraph): test suite for Cli tool
cmwhited Jul 23, 2025
2d3814e
feat(#351 | create-hypergraph): better check for access to template d…
cmwhited Jul 23, 2025
2c9ac16
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 23, 2025
2e62f8b
feat(#351 | create-hypergraph): create CHANGELOG and publish to npm
cmwhited Jul 23, 2025
559aec1
feat(#351 | create-hypergraph): configure git to run create-hypergrap…
cmwhited Jul 23, 2025
20340b9
feat(#365 | nextjs-template): add nextjs template to create-hypergraph
cmwhited Jul 24, 2025
0bddb72
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 24, 2025
87c2c32
feat(#365 | nextjs-template): rebase on main. fixes from updated hype…
cmwhited Jul 24, 2025
dbaa6bc
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 24, 2025
64723ca
Merge branch 'main' of github.com:graphprotocol/hypergraph into chris…
cmwhited Jul 25, 2025
fadccd2
feat(#365 | nextjs template): fixes to nextjs template for functional…
cmwhited Jul 25, 2025
89e556c
feat(#365 | nextjs template): changeset and publish
cmwhited Jul 25, 2025
862688a
feat(#365 | nextjs template): add nextjs template to README for bette…
cmwhited Jul 25, 2025
be6c647
feat(#365 | nextjs template): publish create-hypergraph 0.3.1
cmwhited Jul 25, 2025
91eb4fb
feat(#365 | nextjs template): update llms.txt with additional nextjs …
cmwhited Jul 25, 2025
4ec2c07
feat(#365 | nextjs template): publish 0.3.2
cmwhited Jul 25, 2025
c5822d5
feat(#365 | nextjs template): use default syncServerUri instead of lo…
cmwhited Jul 25, 2025
4eaaf9f
feat(#365 | nextjs template): publish 0.3.3
cmwhited Jul 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .changeset/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["events", "next-example", "docs", "hypergraph-vite-react-template"],
"ignore": ["events", "next-example", "docs", "hypergraph-vite-react-template", "hypergraph-template-nextjs"],
"prettier": false
}
13 changes: 13 additions & 0 deletions apps/create-hypergraph/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Include .gitignore files in templates
!template-*/.gitignore
!dist/template-*/.gitignore

# Exclude source files
src/
scripts/
test/
*.ts
!*.d.ts
tsconfig*.json
vitest.config.ts
tsdown.config.ts
26 changes: 26 additions & 0 deletions apps/create-hypergraph/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
# create-hypergraph

## 0.3.3
### Patch Changes

- c5822d5: Remove localhost syncServerUri from HypergraphAppProvider. uses default instead

## 0.3.2
### Patch Changes

- 91eb4fb: Update llms.txt to include nextjs template for visibility to AI agents

## 0.3.1
### Patch Changes

- 862688a: Update available create hypergraph templates in README to include nextjs for better visibility

## 0.3.0
### Minor Changes

- fadccd2: Include a nextjs template for selection with the create-hypergraph command.

Example usage:

```bash
pnpm create hypergraph@latest --template nextjs
```

## 0.2.0
### Minor Changes

Expand Down
4 changes: 3 additions & 1 deletion apps/create-hypergraph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Then follow the given prompts.
- `--template` -> if provided, uses the provided template
- options:
- vite-react
- nextjs
- `--package-manager` -> if provided, uses the provided package manager
- options:
- pnpm
Expand All @@ -59,7 +60,8 @@ pnpm create hypergraph@latest --template vite-react --package-manager pnpm my-hy

### Currently Supported Templates

- vite + react
- [vite + react](./template-vite-react/README.md)
- [nextjs](./template-nextjs/README.md)

## References

Expand Down
12 changes: 10 additions & 2 deletions apps/create-hypergraph/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ create-hypergraph is a CLI tool that scaffolds new Hypergraph-enabled applicatio
### Options

- `--template, -t` (optional): Template to scaffold
- Available values: `vite-react`
- Available values: `vite-react`, `nextjs`
- Default: prompts user to select
- Currently only supports `vite-react` which scaffolds a Vite + React app using @tanstack/react-router
- `vite-react`: Scaffolds a Vite + React app using @tanstack/react-router
- `nextjs`: Scaffolds a Next.js app with App Router and Hypergraph integration

- `--package-manager, -p` (optional): The package manager to use for installing dependencies
- Available values: `pnpm`, `bun`, `yarn`, `npm`
Expand Down Expand Up @@ -109,6 +110,13 @@ pnpm create hypergraph my-app --skip-install-deps --skip-initialize-git
- TypeScript enabled
- Development server with HMR

### nextjs
- Next.js application with App Router
- Server and Client Components support
- Hypergraph integration with client-side providers
- TypeScript enabled
- Built-in optimizations and best practices

## Error Handling

The tool will fail gracefully if:
Expand Down
4 changes: 2 additions & 2 deletions apps/create-hypergraph/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-hypergraph",
"version": "0.2.0",
"version": "0.3.3",
"description": "CLI toolchain to scaffold a Hypergraph-enabled application with a given template.",
"type": "module",
"bin": {
Expand Down Expand Up @@ -43,7 +43,7 @@
"Web3",
"Knowledge Graph",
"Hypergraph",
"TypeSyncs"
"TypeSync"
],
"license": "MIT",
"engines": {
Expand Down
7 changes: 6 additions & 1 deletion apps/create-hypergraph/src/Cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const createHypergraphApp = Command.make('create-hypergraph-app', {

export const run = Command.run(createHypergraphApp, {
name: 'create-hypergraph-app',
version: '0.2.0',
version: '0.3.3',
});

// ========================
Expand Down Expand Up @@ -294,6 +294,11 @@ function resolveTemplate(config: Readonly<RawConfig>) {
value: 'vite-react',
description: 'Scaffolds a vite + react app using @tanstack/react-router',
},
{
title: 'Nextjs',
value: 'nextjs',
description: 'Scaffolds a nextjs app',
},
],
}).pipe(Effect.map((selected) => selected));
},
Expand Down
6 changes: 5 additions & 1 deletion apps/create-hypergraph/src/Domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as Schema from 'effect/Schema';

export const ALWAYS_SKIP_DIRECTORIES = ['node_modules', '.git'];

export const AvailableFrameworkKey = Schema.Union(Schema.Literal('vite-react'));
export const AvailableFrameworkKey = Schema.Union(Schema.Literal('vite-react'), Schema.Literal('nextjs'));
export type AvailableFrameworkKey = typeof AvailableFrameworkKey.Type;
export const Framework = Schema.Record({
key: AvailableFrameworkKey,
Expand All @@ -18,6 +18,10 @@ export const availableFrameworks = {
directory: 'template-vite-react',
skipDirectories: new Set([...ALWAYS_SKIP_DIRECTORIES, '.tanstack', 'dist']),
},
nextjs: {
directory: 'template-nextjs',
skipDirectories: new Set([...ALWAYS_SKIP_DIRECTORIES, '.next', 'dist']),
},
} as const satisfies Framework;
export const availableFrameworkKeys = Object.keys(availableFrameworks) as ReadonlyArray<AvailableFrameworkKey>;

Expand Down
4 changes: 4 additions & 0 deletions apps/create-hypergraph/template-nextjs/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Ignore artifacts:
build
dist
.next
4 changes: 4 additions & 0 deletions apps/create-hypergraph/template-nextjs/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"printWidth": 120
}
111 changes: 111 additions & 0 deletions apps/create-hypergraph/template-nextjs/Components/Layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
'use client';

import { useHypergraphApp, useHypergraphAuth } from '@graphprotocol/hypergraph-react';
import { usePathname, useRouter } from 'next/navigation';
import { useLayoutEffect } from 'react';

import { SpacesMenu } from './SpacesMenu';
import { Button } from './ui/button';
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
} from './ui/NavigationMenu';

export function Layout({ children }: Readonly<{ children: React.ReactNode }>) {
const navigation = useRouter();
const pathname = usePathname();

const { authenticated } = useHypergraphAuth();
const { redirectToConnect, logout } = useHypergraphApp();

useLayoutEffect(() => {
if (pathname.startsWith('/login') || pathname.startsWith('/authenticate-success') || pathname === '/') {
return;
}

// Only redirect to login if not authenticated and not already on login page
if (!authenticated) {
void navigation.push('/login');
}
}, [authenticated, pathname, navigation]);

const handleSignIn = () => {
redirectToConnect({
storage: localStorage,
connectUrl: 'https://hypergraph-connect.vercel.app/',
successUrl: `${window.location.origin}/authenticate-success`,
redirectFn: (url: URL) => {
window.location.href = url.toString();
},
});
};
const handleLogout = () => {
logout();
navigation.push('/login');
};

return (
<div className="min-h-full flex flex-col">
<nav className="border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 relative z-[9998]">
<div className="container mx-auto px-4">
<div className="flex h-16 items-center justify-between">
<NavigationMenu viewport={false}>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuLink
href="/"
className="group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1"
>
Home
</NavigationMenuLink>
</NavigationMenuItem>

<NavigationMenuItem>
<NavigationMenuLink
href="/explore-public-knowledge"
className="group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=open]:hover:bg-accent data-[state=open]:text-accent-foreground data-[state=open]:focus:bg-accent data-[state=open]:bg-accent/50 focus-visible:ring-ring/50 outline-none transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1"
>
Explore Public Knowledge
</NavigationMenuLink>
</NavigationMenuItem>

<NavigationMenuItem>
<NavigationMenuTrigger>My Spaces</NavigationMenuTrigger>
{authenticated ? (
<SpacesMenu />
) : (
<NavigationMenuContent>
<div className="w-[240px] py-4 text-center text-muted-foreground">
<p>
Sign in to access your
<br />
private and public spaces
</p>
</div>
</NavigationMenuContent>
)}
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenu>

{/* Auth Button */}
<div className="flex items-center space-x-4">
{authenticated ? (
<Button onClick={handleLogout} variant="outline">
Logout
</Button>
) : (
<Button onClick={handleSignIn}>Sign in with Geo Connect</Button>
)}
</div>
</div>
</div>
</nav>
<main className="flex-1 container mx-auto px-4 py-6">{children}</main>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import { useHypergraphApp } from '@graphprotocol/hypergraph-react';
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';

export type AuthCallbackProps = {
ciphertext: string;
nonce: string;
};
export function AuthCallback({ ciphertext, nonce }: Readonly<AuthCallbackProps>) {
const router = useRouter();
const { processConnectAuthSuccess } = useHypergraphApp();

useEffect(() => {
processConnectAuthSuccess({ storage: localStorage, ciphertext, nonce });
router.replace('/');
}, [ciphertext, nonce, processConnectAuthSuccess, router]);

return <div>Authenticating …</div>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client';

import { useHypergraphApp } from '@graphprotocol/hypergraph-react';

import { Button } from '../ui/button';

export function LoginButton() {
const { redirectToConnect } = useHypergraphApp();

const handleSignIn = () => {
redirectToConnect({
storage: localStorage,
connectUrl: 'https://hypergraph-connect.vercel.app/',
successUrl: `${window.location.origin}/authenticate-success`,
redirectFn: (url: URL) => {
window.location.href = url.toString();
},
});
};

return (
<Button type="button" onClick={handleSignIn} className="w-full bg-primary hover:bg-primary/90">
Sign in with Geo Connect
</Button>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
'use client';

import { useHypergraphApp } from '@graphprotocol/hypergraph-react';

export function LoginForm() {
const { redirectToConnect } = useHypergraphApp();

return (
<div className="flex items-center justify-center">
<div className="flex flex-col items-center gap-6 p-8 text-center">
<p className="text-muted-foreground text-lg">Sign in to access your spaces and start building.</p>
<button
type="button"
className="px-8 py-4 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium text-base cursor-pointer"
onClick={() => {
redirectToConnect({
storage: localStorage,
connectUrl: 'https://hypergraph-connect.vercel.app/',
successUrl: `${window.location.origin}/authenticate-success`,
redirectFn: (url: URL) => {
window.location.href = url.toString();
},
});
}}
>
Sign in with Geo Connect
</button>
</div>
</div>
);
}
Loading
Loading