Skip to content
Merged
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
4 changes: 2 additions & 2 deletions docs/integrations/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Integrations
description: Connect Cadence to Git platforms, AI providers, AI assistants, and automation workflows
order: 0
order: 3
---

# Integrations
## Integrations

Cadence provides four integration surfaces: a **webhook server** for continuous Git platform monitoring, **AI providers** (OpenAI and Anthropic) for enhanced detection, an **AI skills system** for embedding detection into agents and pipelines, and a **plugin API** for extending detection with custom strategies.

Expand Down
20 changes: 20 additions & 0 deletions src/components/landing/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export function Header() {
>
Playground
</a>
<a
href="/downloads"
className="text-sm text-white/50 hover:text-white transition-colors"
>
Downloads
</a>
<a
href="/changelog"
className="text-sm text-white/50 hover:text-white transition-colors"
Expand Down Expand Up @@ -122,6 +128,20 @@ export function Header() {
>
Examples
</a>
<a
href="/analysis"
className="px-3 py-2 text-sm text-white/50 hover:text-white rounded transition-colors"
onClick={() => setMobileMenuOpen(false)}
>
Playground
</a>
<a
href="/downloads"
className="px-3 py-2 text-sm text-white/50 hover:text-white rounded transition-colors"
onClick={() => setMobileMenuOpen(false)}
>
Downloads
</a>
<a
href="/changelog"
className="px-3 py-2 text-sm text-white/50 hover:text-white rounded transition-colors"
Expand Down
82 changes: 64 additions & 18 deletions src/lib/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,75 @@ interface DocMeta {
/**
* Parse markdown content, extracting frontmatter and returning the rendered
* markdown body along with title and description metadata.
*
* Frontmatter is expected to be YAML-like format between two lines of `---`:
* ---
* title: Some Title
* description: Some description
* ---
*
* This function strips the frontmatter and returns only the markdown body.
* If the markdown starts with an H1 matching the extracted title, it's removed
* to avoid duplication (since the title is rendered by the layout).
*/
export function parseMarkdown(content: string) {
const normalized = content.replace(/\r\n/g, "\n");
const frontmatterRegex = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
const match = normalized.match(frontmatterRegex);

if (match) {
const frontmatter = match[1];
const markdown = match[2];
const title =
frontmatter.match(/title:\s*(.+)/)?.[1]?.trim() ||
extractHeading(markdown) ||
"Documentation";
const description =
frontmatter.match(/description:\s*(.+)/)?.[1]?.trim() ||
extractDescription(markdown) ||
"";
return { markdown, title, description };

// Simple frontmatter extraction: look for --- at start and somewhere else
let markdown = "";
let title = "";
let description = "";

// Check if file starts with frontmatter
if (normalized.startsWith("---")) {
// Find the closing --- (must be on its own line)
const closingIndex = normalized.indexOf("\n---\n", 4); // Start search after opening ---\n

if (closingIndex !== -1) {
// Found closing ---, extract frontmatter
const frontmatterBlock = normalized.substring(4, closingIndex); // Skip "---\n"
markdown = normalized.substring(closingIndex + 5).trim(); // Skip "\n---\n"

// Parse frontmatter lines
for (const line of frontmatterBlock.split("\n")) {
const match = line.match(/^title:\s*(.+)$/);
if (match) {
title = match[1].trim();
}
const descMatch = line.match(/^description:\s*(.+)$/);
if (descMatch) {
description = descMatch[1].trim();
}
}
} else {
// No closing ---, treat entire file as markdown
markdown = normalized;
title = extractHeading(markdown) || "Documentation";
}
} else {
// No frontmatter
markdown = normalized;
title = extractHeading(markdown) || "Documentation";
}

// Fallback title/description extraction if not in frontmatter
if (!title) {
title = extractHeading(markdown) || "Documentation";
}
if (!description) {
description = extractDescription(markdown) || "";
}

// Remove duplicate H1 if markdown starts with it and it matches the title
const firstHeading = extractHeading(markdown);
if (
firstHeading &&
firstHeading.toLowerCase() === title.toLowerCase()
) {
markdown = markdown.replace(/^#+\s+.+\n+/, "");
}

const title = extractHeading(normalized) || "Documentation";
const description = extractDescription(normalized) || "";
return { markdown: content, title, description };
return { markdown, title, description };
}

function extractHeading(content: string): string | null {
Expand Down
21 changes: 21 additions & 0 deletions src/routeTree.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Route as rootRouteImport } from './routes/__root'
import { Route as MetaPreviewRouteImport } from './routes/meta-preview'
import { Route as FeaturesRouteImport } from './routes/features'
import { Route as ExamplesRouteImport } from './routes/examples'
import { Route as DownloadsRouteImport } from './routes/downloads'
import { Route as ChangelogRouteImport } from './routes/changelog'
import { Route as AnalysisRouteImport } from './routes/analysis'
import { Route as IndexRouteImport } from './routes/index'
Expand All @@ -33,6 +34,11 @@ const ExamplesRoute = ExamplesRouteImport.update({
path: '/examples',
getParentRoute: () => rootRouteImport,
} as any)
const DownloadsRoute = DownloadsRouteImport.update({
id: '/downloads',
path: '/downloads',
getParentRoute: () => rootRouteImport,
} as any)
const ChangelogRoute = ChangelogRouteImport.update({
id: '/changelog',
path: '/changelog',
Expand Down Expand Up @@ -63,6 +69,7 @@ export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/analysis': typeof AnalysisRoute
'/changelog': typeof ChangelogRoute
'/downloads': typeof DownloadsRoute
'/examples': typeof ExamplesRoute
'/features': typeof FeaturesRoute
'/meta-preview': typeof MetaPreviewRoute
Expand All @@ -73,6 +80,7 @@ export interface FileRoutesByTo {
'/': typeof IndexRoute
'/analysis': typeof AnalysisRoute
'/changelog': typeof ChangelogRoute
'/downloads': typeof DownloadsRoute
'/examples': typeof ExamplesRoute
'/features': typeof FeaturesRoute
'/meta-preview': typeof MetaPreviewRoute
Expand All @@ -84,6 +92,7 @@ export interface FileRoutesById {
'/': typeof IndexRoute
'/analysis': typeof AnalysisRoute
'/changelog': typeof ChangelogRoute
'/downloads': typeof DownloadsRoute
'/examples': typeof ExamplesRoute
'/features': typeof FeaturesRoute
'/meta-preview': typeof MetaPreviewRoute
Expand All @@ -96,6 +105,7 @@ export interface FileRouteTypes {
| '/'
| '/analysis'
| '/changelog'
| '/downloads'
| '/examples'
| '/features'
| '/meta-preview'
Expand All @@ -106,6 +116,7 @@ export interface FileRouteTypes {
| '/'
| '/analysis'
| '/changelog'
| '/downloads'
| '/examples'
| '/features'
| '/meta-preview'
Expand All @@ -116,6 +127,7 @@ export interface FileRouteTypes {
| '/'
| '/analysis'
| '/changelog'
| '/downloads'
| '/examples'
| '/features'
| '/meta-preview'
Expand All @@ -127,6 +139,7 @@ export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
AnalysisRoute: typeof AnalysisRoute
ChangelogRoute: typeof ChangelogRoute
DownloadsRoute: typeof DownloadsRoute
ExamplesRoute: typeof ExamplesRoute
FeaturesRoute: typeof FeaturesRoute
MetaPreviewRoute: typeof MetaPreviewRoute
Expand Down Expand Up @@ -157,6 +170,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ExamplesRouteImport
parentRoute: typeof rootRouteImport
}
'/downloads': {
id: '/downloads'
path: '/downloads'
fullPath: '/downloads'
preLoaderRoute: typeof DownloadsRouteImport
parentRoute: typeof rootRouteImport
}
'/changelog': {
id: '/changelog'
path: '/changelog'
Expand Down Expand Up @@ -199,6 +219,7 @@ const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
AnalysisRoute: AnalysisRoute,
ChangelogRoute: ChangelogRoute,
DownloadsRoute: DownloadsRoute,
ExamplesRoute: ExamplesRoute,
FeaturesRoute: FeaturesRoute,
MetaPreviewRoute: MetaPreviewRoute,
Expand Down
Loading
Loading