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
26 changes: 15 additions & 11 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions packages/chronicle/build-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ const result = await Bun.build({
outdir: 'dist/cli',
target: 'node',
format: 'esm',
define: {
PACKAGE_ROOT: JSON.stringify(path.resolve(import.meta.dir)),
},
})

if (!result.success) {
Expand Down
4 changes: 3 additions & 1 deletion packages/chronicle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@
"@codemirror/view": "^6.39.14",
"@heroicons/react": "^2.2.0",
"@raystack/apsara": "^0.56.0",
"@types/unist": "^3.0.3",
"chalk": "^5.6.2",
"class-variance-authority": "^0.7.1",
"codemirror": "^6.0.2",
"commander": "^14.0.2",
"fumadocs-core": "^16.4.9",
"fumadocs-core": "16.6.15",
"fumadocs-mdx": "^14.2.6",
"lodash": "^4.17.23",
"mermaid": "^11.13.0",
Expand All @@ -53,6 +54,7 @@
"remark-attr": "^0.11.1",
"remark-directive": "^4.0.0",
"slugify": "^1.6.6",
"unified": "^11.0.5",
"unist-util-visit": "^5.1.0",
"yaml": "^2.8.2",
"zod": "^4.3.6"
Expand Down
9 changes: 8 additions & 1 deletion packages/chronicle/source.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineDocs, defineConfig } from 'fumadocs-mdx/config'
import { defineDocs, defineConfig, frontmatterSchema } from 'fumadocs-mdx/config'
import { z } from 'zod'
import remarkDirective from 'remark-directive'
import { remarkDirectiveAdmonition, remarkMdxMermaid } from 'fumadocs-core/mdx-plugins'
import remarkUnusedDirectives from './src/lib/remark-unused-directives'
Expand All @@ -8,6 +9,12 @@ const contentDir = process.env.CHRONICLE_CONTENT_DIR || './content'
export const docs = defineDocs({
dir: contentDir,
docs: {
schema: frontmatterSchema.extend({
order: z.number().optional(),
}),
postprocess: {
includeProcessedMarkdown: true,
},
files: ['**/*.mdx', '**/*.md', '!**/node_modules/**'],
},
})
Expand Down
18 changes: 18 additions & 0 deletions packages/chronicle/src/app/llms-full.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { source } from '@/lib/source'
import { loadConfig } from '@/lib/config'
import { getLLMText } from '@/lib/get-llm-text'

export const revalidate = false

export async function GET() {
const config = loadConfig()

if (!config.llms?.enabled) {
return new Response('Not Found', { status: 404 })
}

const scan = source.getPages().map(getLLMText)
const scanned = await Promise.all(scan)

return new Response(scanned.join('\n\n'))
}
15 changes: 15 additions & 0 deletions packages/chronicle/src/app/llms.txt/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { source } from '@/lib/source'
import { loadConfig } from '@/lib/config'
import { llms } from 'fumadocs-core/source'

export const revalidate = false

export function GET() {
const config = loadConfig()

if (!config.llms?.enabled) {
return new Response('Not Found', { status: 404 })
}

return new Response(llms(source).index())
}
4 changes: 2 additions & 2 deletions packages/chronicle/src/cli/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Command } from 'commander'
import { spawn } from 'child_process'
import path from 'path'
import { fileURLToPath } from 'url'
import chalk from 'chalk'
import { resolveContentDir, loadCLIConfig, attachLifecycleHandlers } from '@/cli/utils'

declare const PACKAGE_ROOT: string

const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
const nextBin = path.join(PACKAGE_ROOT, 'node_modules', '.bin', process.platform === 'win32' ? 'next.cmd' : 'next')

export const buildCommand = new Command('build')
Expand Down
4 changes: 2 additions & 2 deletions packages/chronicle/src/cli/commands/dev.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Command } from 'commander'
import { spawn } from 'child_process'
import path from 'path'
import { fileURLToPath } from 'url'
import chalk from 'chalk'
import { resolveContentDir, loadCLIConfig, attachLifecycleHandlers } from '@/cli/utils'

declare const PACKAGE_ROOT: string

const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
const nextBin = path.join(PACKAGE_ROOT, 'node_modules', '.bin', process.platform === 'win32' ? 'next.cmd' : 'next')

export const devCommand = new Command('dev')
Expand Down
4 changes: 2 additions & 2 deletions packages/chronicle/src/cli/commands/serve.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Command } from 'commander'
import { spawn } from 'child_process'
import path from 'path'
import { fileURLToPath } from 'url'
import chalk from 'chalk'
import { resolveContentDir, loadCLIConfig, attachLifecycleHandlers } from '@/cli/utils'

declare const PACKAGE_ROOT: string

const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
const nextBin = path.join(PACKAGE_ROOT, 'node_modules', '.bin', process.platform === 'win32' ? 'next.cmd' : 'next')

export const serveCommand = new Command('serve')
Expand Down
4 changes: 2 additions & 2 deletions packages/chronicle/src/cli/commands/start.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Command } from 'commander'
import { spawn } from 'child_process'
import path from 'path'
import { fileURLToPath } from 'url'
import chalk from 'chalk'
import { resolveContentDir, loadCLIConfig, attachLifecycleHandlers } from '@/cli/utils'

declare const PACKAGE_ROOT: string

const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..')
const nextBin = path.join(PACKAGE_ROOT, 'node_modules', '.bin', process.platform === 'win32' ? 'next.cmd' : 'next')

export const startCommand = new Command('start')
Expand Down
1 change: 1 addition & 0 deletions packages/chronicle/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ export function loadConfig(): ChronicleConfig {
search: { ...defaultConfig.search, ...userConfig.search },
footer: userConfig.footer,
api: userConfig.api,
llms: { enabled: false, ...userConfig.llms },
}
}
10 changes: 10 additions & 0 deletions packages/chronicle/src/lib/get-llm-text.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { source } from '@/lib/source'
import type { InferPageType } from 'fumadocs-core/source'

export async function getLLMText(page: InferPageType<typeof source>) {
const processed = await page.data.getText('processed')

return `# ${page.data.title} (${page.url})

${processed}`
}
31 changes: 15 additions & 16 deletions packages/chronicle/src/lib/remark-unused-directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,25 @@ import { visit } from 'unist-util-visit'
import type { Plugin } from 'unified'
import type { Node } from 'unist'

interface DirectiveNode extends Node {
name?: string
attributes?: Record<string, string>
children?: Node[]
data?: unknown
[key: string]: unknown
}

const remarkUnusedDirectives: Plugin = () => {
return (tree) => {
visit(tree, ['textDirective'], (node: DirectiveNode) => {
if (!node.data) {
const hasAttributes = node.attributes && Object.keys(node.attributes).length > 0
const hasChildren = node.children && node.children.length > 0
visit(tree, ['textDirective'], (node) => {
const directive = node as Node & {
name?: string
attributes?: Record<string, string>
children?: Node[]
value?: string
[key: string]: unknown
}
if (!directive.data) {
const hasAttributes = directive.attributes && Object.keys(directive.attributes).length > 0
const hasChildren = directive.children && directive.children.length > 0
if (!hasAttributes && !hasChildren) {
const name = node.name
const name = directive.name
if (!name) return
Object.keys(node).forEach((key) => delete node[key])
node.type = 'text'
node.value = `:${name}`
Object.keys(directive).forEach((key) => delete directive[key])
directive.type = 'text'
directive.value = `:${name}`
}
}
})
Expand Down
5 changes: 3 additions & 2 deletions packages/chronicle/src/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,12 @@ export function buildPageTree(): PageTree {
const folderItems: PageTreeItem[] = []
folders.forEach((items, folder) => {
const sorted = sortByOrder(items)
const indexPage = sorted[0]
const indexPage = items.find(item => item.url === `/${folder}`)
const folderOrder = indexPage?.order ?? sorted[0]?.order
folderItems.push({
type: 'folder',
name: folder.charAt(0).toUpperCase() + folder.slice(1),
order: indexPage?.order,
order: folderOrder,
children: sorted,
})
})
Expand Down
5 changes: 5 additions & 0 deletions packages/chronicle/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ export interface ChronicleConfig {
search?: SearchConfig
footer?: FooterConfig
api?: ApiConfig[]
llms?: LlmsConfig
}

export interface LlmsConfig {
enabled?: boolean
}

export interface ApiConfig {
Expand Down