Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
28 changes: 28 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ on:
- plugin-particles
- plugin-vue
- plugin-svelte
- website
- npm
- vsce
- all
Expand Down Expand Up @@ -108,3 +109,30 @@ jobs:

- name: Publish VSIX target
run: pnpm run release:publish vsce

release-website-check:
if: ${{ inputs.target == 'all' || inputs.target == 'website' }}
name: Release website check
runs-on: ubuntu-latest
timeout-minutes: 15

steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup pnpm
uses: pnpm/action-setup@v6.0.8
with:
version: 10.32.0

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22.22.0
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build website
run: pnpm --filter @codegraphy/web run build
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ dist/
.vscode/settings.json
/coverage/
*.log
*.tsbuildinfo
.DS_Store
dist-e2e/
/artifacts/
Expand All @@ -18,6 +19,8 @@ packages/extension/tests/playwright-vscode/generated/
packages/extension/tests/playwright-vscode/generated-ir/
.superpowers/
.turbo/
.next/
out/
reports/
.stryker-tmp/
.pnpm-store/
Expand Down
1 change: 1 addition & 0 deletions apps/web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
next-env.d.ts
78 changes: 78 additions & 0 deletions apps/web/app/_components/agents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { CodeBlock } from '@/components/code-block';
import { Link } from '@/components/link';
import { SectionHeader } from '@/components/section-header';
import { Card, CardContent } from '@/components/ui/card';
import { npmPackageRootHref } from '@/content/links';

const agentSkillHref = 'https://github.com/codegraphy/skills';
const corePackageHref = `${npmPackageRootHref}/@codegraphy-dev/core`;

const agentCapabilities: string[] = [
'Index the CodeGraphy Workspace',
'List Nodes, Edges, and symbols',
'Trace paths between files',
'Explain Relationships from the Graph Cache',
];

export function Agents(): React.ReactElement {
return (
<section className="mx-auto grid w-full max-w-7xl gap-10 px-6 sm:px-8 lg:grid-cols-[0.9fr_1fr] lg:items-center lg:px-12">
<div className="max-w-xl">
<SectionHeader
title="Let agents read the Relationship Graph."
description="The CodeGraphy Agent Skill teaches coding agents to query the same local Graph Cache that powers the VS Code extension. One CLI answers focused questions about Nodes, Edges, dependencies, dependents, and paths."
/>
<p className="mt-4 text-base leading-7 text-muted-foreground">
Index the CodeGraphy Workspace once, then use your agent for targeted Relationship
questions instead of broad file-by-file exploration.
</p>
<div className="mt-6 flex flex-wrap gap-4">
<Link href={agentSkillHref} icon="github" variant="text">
CodeGraphy Agent Skill
</Link>
<Link href={corePackageHref} variant="text">
@codegraphy-dev/core
</Link>
</div>
</div>

<Card className="overflow-hidden">
<CardContent className="grid gap-5 p-5">
<div>
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-muted-foreground">
Install
</p>
<CodeBlock className="mt-2 text-xs leading-5">
npx skills@latest add codegraphy/skills
</CodeBlock>
</div>

<div>
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-muted-foreground">
Ask your agent
</p>
<blockquote className="mt-2 rounded-md bg-secondary/60 px-3 py-2.5 text-sm leading-6 text-foreground">
codegraphy search SettingsPanel
</blockquote>
</div>

<div>
<p className="font-mono text-xs font-semibold uppercase tracking-widest text-muted-foreground">
What it unlocks
</p>
<ul className="mt-2 grid gap-2 sm:grid-cols-2">
{agentCapabilities.map((capability) => (
<li
className="rounded-md bg-muted px-3 py-2 text-sm font-medium text-muted-foreground"
key={capability}
>
{capability}
</li>
))}
</ul>
</div>
</CardContent>
</Card>
</section>
);
}
160 changes: 160 additions & 0 deletions apps/web/app/_components/features.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import {
Code,
Extension,
Hub,
Layers,
Tune,
type MaterialSymbolsComponent,
} from '@material-symbols-svg/react/rounded';
import { MediaImage, type Media } from '@/components/media-image';
import { SectionHeader } from '@/components/section-header';
import { Card, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { cn } from '@/lib/utils';

type FeatureLayout = 'square' | 'wide';

interface Feature {
icon: MaterialSymbolsComponent;
layout: FeatureLayout;
media: Media;
summary: string;
title: string;
}

const features: Feature[] = [
{
icon: Hub,
layout: 'square',
media: gifMedia(
'force-graph',
'Animation of a force-directed Relationship Graph being explored inside CodeGraphy',
),
title: 'Force-directed Relationship Graph',
summary: 'Folders, files, symbols, imports, references, inheritance, and Plugin data rendered as one explorable Relationship Graph.',
},
{
icon: Extension,
layout: 'square',
media: gifMedia(
'plugin-graph-scope',
'Animation of a Godot CodeGraphy Workspace with Plugin-owned Node Types and Edge Types toggled in Graph Scope',
),
title: 'Extensible with Plugins',
summary: 'Add languages, frameworks, documents, and custom Relationship Graph semantics through the typed Plugin API.',
},
{
icon: Tune,
layout: 'wide',
media: imageMedia(
'search-filter-panel',
'Search and Filter controls with persistent workspace Filters enabled',
),
title: 'Search, filter, and scope',
summary: 'Search the Visible Graph in the moment, then save persistent Filters that keep tests, generated files, and other noise out of view.',
},
{
icon: Code,
layout: 'square',
media: gifMedia(
'symbol-nodes',
'Animation of a graph expanding from file nodes into function, class, and type symbol nodes',
),
title: 'Symbol-level detail',
summary: 'Expand any file into its functions, classes, interfaces, and types with built-in Tree-sitter analysis.',
},
{
icon: Layers,
layout: 'square',
media: gifMedia(
'force-graph',
'Animation of CodeGraphy rendering and laying out a Relationship Graph',
),
title: 'Our own graph renderer',
summary: 'A custom @codegraphy-dev/graph-renderer package draws with WebGPU while deterministic WebAssembly physics keeps large graphs responsive.',
},
];

function gifMedia(name: string, alt: string): Media {
return {
alt,
src: `/media/features/${name}-light.gif`,
posterSrc: `/media/features/posters/${name}-light.png`,
darkSrc: `/media/features/${name}-dark.gif`,
darkPosterSrc: `/media/features/posters/${name}-dark.png`,
};
}

function imageMedia(name: string, alt: string): Media {
return {
alt,
src: `/media/features/${name}-light.png`,
darkSrc: `/media/features/${name}-dark.png`,
};
}

export function Features(): React.ReactElement {
return (
<section className="mx-auto grid w-full max-w-7xl gap-6 px-6 sm:px-8 lg:px-12" id="features">
<SectionHeader
title="Features"
description="Explore the Relationship Graph, narrow it to the code you care about, and reuse the same local Graph Cache from the editor, CLI, Agent Skill, and Plugins."
/>
<div className="grid gap-5 md:grid-cols-2 lg:grid-cols-6">
{features.map((feature) => (
<FeatureCard feature={feature} key={feature.title} />
))}
</div>
</section>
);
}

function FeatureCard({ feature }: { feature: Feature }): React.ReactElement {
return (
<Card
as="article"
className={cn(
'flex min-w-0 flex-col overflow-hidden',
feature.layout === 'wide' ? 'md:col-span-2 lg:col-span-6' : 'lg:col-span-3',
)}
interactive
>
<FeatureMedia layout={feature.layout} media={feature.media} />
<CardHeader className="shrink-0">
<div className="flex items-start gap-3">
<span className="flex size-9 shrink-0 items-center justify-center rounded-lg bg-secondary text-primary">
<feature.icon aria-hidden="true" className="size-4" />
</span>
<div className="min-w-0">
<CardTitle className="text-base text-foreground">{feature.title}</CardTitle>
<CardDescription className="mt-1">{feature.summary}</CardDescription>
</div>
</div>
</CardHeader>
</Card>
);
}

function FeatureMedia({
layout,
media,
}: {
layout: FeatureLayout;
media: Media;
}): React.ReactElement {
return (
<MediaImage
className={cn(
'min-h-0 border-b border-border bg-graph-surface',
layout === 'wide' ? 'aspect-[20/7]' : 'aspect-square',
)}
fill
imageClassName="bg-graph-surface object-contain object-center"
media={media}
sizes={
layout === 'wide'
? '(min-width: 1024px) 100vw, 100vw'
: '(min-width: 1024px) 50vw, (min-width: 768px) 50vw, 100vw'
}
/>
);
}
Loading