diff --git a/bin/gen-claude-skill b/bin/gen-claude-skill new file mode 100755 index 0000000000000..4a332ee0f93f5 --- /dev/null +++ b/bin/gen-claude-skill @@ -0,0 +1,64 @@ +#!/usr/bin/env bash + +# Copyright Materialize, Inc. and contributors. All rights reserved. +# +# Use of this software is governed by the Business Source License +# included in the LICENSE file at the root of this repository. +# +# As of the Change Date specified in that file, in accordance with +# the Business Source License, use of this software will be governed +# by the Apache License, Version 2.0. +# +# gen-claude-skill -- Generate a Claude Code skill bundle from the documentation. +# +# Usage: +# bin/gen-claude-skill [OUTPUT_DIR] +# +# Arguments: +# OUTPUT_DIR Directory to output the skill files (default: .claude/skills/materialize-docs) +# +# Examples: +# bin/gen-claude-skill # Generate to default location +# bin/gen-claude-skill /path/to/output # Generate to custom location + +set -euo pipefail + +cd "$(dirname "$0")/.." + +OUTPUT_DIR="${1:-.claude/skills/materialize-docs}" + +# Ensure output directory exists +mkdir -p "$OUTPUT_DIR" + +echo "Generating Claude skill from documentation..." +echo "Output directory: $OUTPUT_DIR" + +# Build documentation with skill output format +cd doc/user +hugo --config config.toml,config.skill.toml \ + --destination "../../$OUTPUT_DIR" \ + --gc \ + --quiet + +cd ../.. + +# Rename the home page to SKILL.md (Claude skill convention) +if [[ -f "$OUTPUT_DIR/index.md" ]]; then + mv "$OUTPUT_DIR/index.md" "$OUTPUT_DIR/SKILL.md" +fi + +# Clean up files not needed for the skill +rm -f "$OUTPUT_DIR/sitemap.xml" 2>/dev/null +rm -rf "$OUTPUT_DIR/images" 2>/dev/null +rm -f "$OUTPUT_DIR/materialize-openapi.yml" 2>/dev/null +rm -rf "$OUTPUT_DIR/releases" 2>/dev/null +rm -rf "$OUTPUT_DIR/self-managed" 2>/dev/null +rm -rf "$OUTPUT_DIR/stylesheet" 2>/dev/null +rm -rf "$OUTPUT_DIR/about" 2>/dev/null +rm -rf "$OUTPUT_DIR/get-started" 2>/dev/null + +# Count generated files +FILE_COUNT=$(find "$OUTPUT_DIR" -name "*.md" | wc -l | tr -d ' ') + +echo "Done! Generated $FILE_COUNT markdown files." +echo "Skill entry point: $OUTPUT_DIR/SKILL.md" diff --git a/doc/user/config.skill.toml b/doc/user/config.skill.toml new file mode 100644 index 0000000000000..ab16a34b84b6e --- /dev/null +++ b/doc/user/config.skill.toml @@ -0,0 +1,22 @@ +# Copyright Materialize, Inc. and contributors. All rights reserved. +# +# Use of this software is governed by the Business Source License +# included in the LICENSE file at the root of this repository. +# +# As of the Change Date specified in that file, in accordance with +# the Business Source License, use of this software will be governed +# by the Apache License, Version 2.0. +# +# config.skill.toml - Configuration overlay for generating Claude skill output. +# Use with: hugo --config config.toml,config.skill.toml + +# Output only the skill format (markdown), not HTML +[outputs] + home = ["skill"] + section = ["skill"] + page = ["skill"] + +# Skill-specific parameters +[params] + # Sections to exclude from skill generation + excludeFromSkill = ["releases", "self-managed"] diff --git a/doc/user/config.toml b/doc/user/config.toml index ba031962e0a5e..b25cfe867ace6 100644 --- a/doc/user/config.toml +++ b/doc/user/config.toml @@ -101,6 +101,15 @@ parent = "about" url = "https://materialize.com/securitydisclosure" weight = 55 +# +# Custom output format for Claude skill generation +# +[outputFormats.skill] + mediaType = "text/markdown" + baseName = "index" + isPlainText = true + notAlternative = true + [markup.goldmark.renderer] # allow , the old syntax no longer works unsafe = true diff --git a/doc/user/layouts/_default/list.skill.md b/doc/user/layouts/_default/list.skill.md new file mode 100644 index 0000000000000..c027c610f60e3 --- /dev/null +++ b/doc/user/layouts/_default/list.skill.md @@ -0,0 +1,17 @@ +{{- /* List/section template for Claude skill output */ -}} +# {{ .Title }} +{{ if .Description }} +{{ .Description }} +{{ end }} + +{{ .RawContent }} + +{{ range .Pages }} +{{ if not (in (slice "releases" "self-managed") .Section) }} +--- + +## {{ .Title }} + +{{ .RawContent }} +{{ end }} +{{ end }} diff --git a/doc/user/layouts/_default/single.skill.md b/doc/user/layouts/_default/single.skill.md new file mode 100644 index 0000000000000..5463be28233de --- /dev/null +++ b/doc/user/layouts/_default/single.skill.md @@ -0,0 +1,7 @@ +{{- /* Single page template for Claude skill output */ -}} +# {{ .Title }} +{{ if .Description }} +{{ .Description }} +{{ end }} + +{{ .RawContent }} diff --git a/doc/user/layouts/index.skill.md b/doc/user/layouts/index.skill.md new file mode 100644 index 0000000000000..5f0cae4ce6ab6 --- /dev/null +++ b/doc/user/layouts/index.skill.md @@ -0,0 +1,56 @@ +{{- /* Home page template - generates SKILL.md for Claude */ -}} +--- +name: materialize-docs +description: Materialize documentation for SQL syntax, data ingestion, concepts, and best practices. Use when users ask about Materialize queries, sources, sinks, views, or clusters. +--- + +# Materialize Documentation + +This skill provides comprehensive documentation for Materialize, a streaming database for real-time analytics. + +## How to Use This Skill + +When a user asks about Materialize: + +1. **For SQL syntax/commands**: Read files in the `sql/` directory +2. **For core concepts**: Read files in the `concepts/` directory +3. **For data ingestion**: Read files in the `ingest-data/` directory +4. **For transformations**: Read files in the `transform-data/` directory + +## Documentation Sections +{{- range .Site.Sections }} +{{- $sectionName := .Section }} +{{- if not (in (slice "releases" "self-managed" "about" "get-started") $sectionName) }} + +### {{ .Title }} +{{- with .Description }} +{{ . }} +{{- end }} +{{ range .Pages | first 10 }} +- **{{ .Title }}**: `{{ strings.TrimPrefix "/" .RelPermalink }}` +{{- end }} +{{- if gt (len .Pages) 10 }} +- _(and {{ sub (len .Pages) 10 }} more files in this section)_ +{{- end }} +{{- end }} +{{- end }} + +## Quick Reference + +### Common SQL Commands + +| Command | Description | +|---------|-------------| +| `CREATE SOURCE` | Connect to external data sources (Kafka, PostgreSQL, MySQL) | +| `CREATE MATERIALIZED VIEW` | Create incrementally maintained views | +| `CREATE INDEX` | Create indexes on views for faster queries | +| `CREATE SINK` | Export data to external systems | +| `SELECT` | Query data from sources, views, and tables | + +### Key Concepts + +- **Sources**: Connections to external data systems that stream data into Materialize +- **Materialized Views**: Views that are incrementally maintained as source data changes +- **Indexes**: Arrangements of data in memory for fast point lookups +- **Clusters**: Isolated compute resources for running dataflows +- **Sinks**: Connections that export data from Materialize to external systems diff --git a/doc/user/layouts/shortcodes/callout.skill.md b/doc/user/layouts/shortcodes/callout.skill.md new file mode 100644 index 0000000000000..1c5ab84bdca66 --- /dev/null +++ b/doc/user/layouts/shortcodes/callout.skill.md @@ -0,0 +1,9 @@ +{{- /* Skill output: render callout as markdown blockquote */ -}} +> {{ .Inner | replaceRE "^\\s+" "" | replaceRE "\\n" "\n> " }} +{{ if and ($.Params) (isset $.Params "primary_text") }} +> +> **{{ .Get "primary_text" }}**: {{ .Get "primary_url" }} +{{ end }} +{{ if and ($.Params) (isset $.Params "secondary_text") }} +> **{{ .Get "secondary_text" }}**: {{ .Get "secondary_url" }} +{{ end }} diff --git a/doc/user/layouts/shortcodes/diagram.skill.md b/doc/user/layouts/shortcodes/diagram.skill.md new file mode 100644 index 0000000000000..33ce07ed4dc28 --- /dev/null +++ b/doc/user/layouts/shortcodes/diagram.skill.md @@ -0,0 +1,3 @@ +{{- /* Skill output: diagrams are visual, describe or omit */ -}} +{{- $diagramName := .Get 0 | replaceRE "\\.svg$" "" -}} +_See syntax diagram: {{ $diagramName }}_ diff --git a/doc/user/layouts/shortcodes/important.skill.md b/doc/user/layouts/shortcodes/important.skill.md new file mode 100644 index 0000000000000..2e2ef3bed38cb --- /dev/null +++ b/doc/user/layouts/shortcodes/important.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: render important as markdown blockquote */ -}} +> **Important:** {{ .Inner | replaceRE "^\\s+" "" | replaceRE "\\n" "\n> " }} diff --git a/doc/user/layouts/shortcodes/include-md.skill.md b/doc/user/layouts/shortcodes/include-md.skill.md new file mode 100644 index 0000000000000..2a3b6320344da --- /dev/null +++ b/doc/user/layouts/shortcodes/include-md.skill.md @@ -0,0 +1,3 @@ +{{- /* Skill output: inline the included markdown content */ -}} +{{- $path := .Get "file" -}} +{{- readFile $path -}} diff --git a/doc/user/layouts/shortcodes/note.skill.md b/doc/user/layouts/shortcodes/note.skill.md new file mode 100644 index 0000000000000..ec0aff7c3f531 --- /dev/null +++ b/doc/user/layouts/shortcodes/note.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: render note as markdown blockquote */ -}} +> **Note:** {{ .Inner | replaceRE "^\\s+" "" | replaceRE "\\n" "\n> " }} diff --git a/doc/user/layouts/shortcodes/private-preview.skill.md b/doc/user/layouts/shortcodes/private-preview.skill.md new file mode 100644 index 0000000000000..850f9b3590cf6 --- /dev/null +++ b/doc/user/layouts/shortcodes/private-preview.skill.md @@ -0,0 +1 @@ +{{- /* Skill output: omit private preview marker */ -}} diff --git a/doc/user/layouts/shortcodes/public-preview.skill.md b/doc/user/layouts/shortcodes/public-preview.skill.md new file mode 100644 index 0000000000000..9298735aa0f64 --- /dev/null +++ b/doc/user/layouts/shortcodes/public-preview.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: show public preview note */ -}} +> **Public Preview:** This feature is in public preview. diff --git a/doc/user/layouts/shortcodes/tab.skill.md b/doc/user/layouts/shortcodes/tab.skill.md new file mode 100644 index 0000000000000..ea0b8f629efec --- /dev/null +++ b/doc/user/layouts/shortcodes/tab.skill.md @@ -0,0 +1,5 @@ +{{- /* Skill output: render tab with heading */ -}} +{{ $title := .Get 0 }} +**{{ $title }}:** + +{{ .Inner }} diff --git a/doc/user/layouts/shortcodes/tabs.skill.md b/doc/user/layouts/shortcodes/tabs.skill.md new file mode 100644 index 0000000000000..3337139e58df7 --- /dev/null +++ b/doc/user/layouts/shortcodes/tabs.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: render tabs content sequentially */ -}} +{{ .Inner }} diff --git a/doc/user/layouts/shortcodes/tip.skill.md b/doc/user/layouts/shortcodes/tip.skill.md new file mode 100644 index 0000000000000..7bb774c572df1 --- /dev/null +++ b/doc/user/layouts/shortcodes/tip.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: render tip as markdown blockquote */ -}} +> **Tip:** {{ .Inner | replaceRE "^\\s+" "" | replaceRE "\\n" "\n> " }} diff --git a/doc/user/layouts/shortcodes/warning.skill.md b/doc/user/layouts/shortcodes/warning.skill.md new file mode 100644 index 0000000000000..82c10771d9a53 --- /dev/null +++ b/doc/user/layouts/shortcodes/warning.skill.md @@ -0,0 +1,2 @@ +{{- /* Skill output: render warning as markdown blockquote */ -}} +> **Warning:** {{ .Inner | replaceRE "^\\s+" "" | replaceRE "\\n" "\n> " }}