@tiramisu-docs/kit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +103 -0
  2. package/components.json +14 -0
  3. package/dist/bin/mcp.d.ts +2 -0
  4. package/dist/bin/mcp.js +4 -0
  5. package/dist/config.d.ts +99 -0
  6. package/dist/config.js +36 -0
  7. package/dist/highlight.d.ts +10 -0
  8. package/dist/highlight.js +93 -0
  9. package/dist/index.d.ts +6 -0
  10. package/dist/index.js +3 -0
  11. package/dist/lib/components/index.d.ts +16 -0
  12. package/dist/lib/components/index.js +18 -0
  13. package/dist/lib/components/tiramisu/lang-icons.d.ts +4 -0
  14. package/dist/lib/components/tiramisu/lang-icons.js +77 -0
  15. package/dist/lib/components/ui/alert/index.d.ts +5 -0
  16. package/dist/lib/components/ui/alert/index.js +6 -0
  17. package/dist/lib/components/ui/badge/index.d.ts +2 -0
  18. package/dist/lib/components/ui/badge/index.js +1 -0
  19. package/dist/lib/components/ui/button/index.d.ts +4 -0
  20. package/dist/lib/components/ui/button/index.js +2 -0
  21. package/dist/lib/components/ui/card/index.d.ts +8 -0
  22. package/dist/lib/components/ui/card/index.js +10 -0
  23. package/dist/lib/components/ui/collapsible/index.d.ts +1 -0
  24. package/dist/lib/components/ui/collapsible/index.js +1 -0
  25. package/dist/lib/components/ui/dropdown-menu/index.d.ts +18 -0
  26. package/dist/lib/components/ui/dropdown-menu/index.js +18 -0
  27. package/dist/lib/components/ui/scroll-area/index.d.ts +1 -0
  28. package/dist/lib/components/ui/scroll-area/index.js +1 -0
  29. package/dist/lib/components/ui/separator/index.d.ts +1 -0
  30. package/dist/lib/components/ui/separator/index.js +1 -0
  31. package/dist/lib/components/ui/sheet/index.d.ts +3 -0
  32. package/dist/lib/components/ui/sheet/index.js +3 -0
  33. package/dist/lib/components/ui/tabs/index.d.ts +5 -0
  34. package/dist/lib/components/ui/tabs/index.js +7 -0
  35. package/dist/lib/open-links.d.ts +22 -0
  36. package/dist/lib/open-links.js +33 -0
  37. package/dist/lib/routes/docs/[...slug]/+page.d.ts +25 -0
  38. package/dist/lib/routes/docs/[...slug]/+page.js +109 -0
  39. package/dist/lib/utils.d.ts +5 -0
  40. package/dist/lib/utils.js +5 -0
  41. package/dist/mcp.d.ts +24 -0
  42. package/dist/mcp.js +155 -0
  43. package/dist/scan.d.ts +15 -0
  44. package/dist/scan.js +72 -0
  45. package/dist/seo.d.ts +63 -0
  46. package/dist/seo.js +160 -0
  47. package/dist/tiramisu-grammar.d.ts +2 -0
  48. package/dist/tiramisu-grammar.js +77 -0
  49. package/dist/types.d.ts +66 -0
  50. package/dist/types.js +1 -0
  51. package/dist/vite.d.ts +33 -0
  52. package/dist/vite.js +406 -0
  53. package/package.json +74 -0
  54. package/src/config.ts +133 -0
  55. package/src/highlight.ts +110 -0
  56. package/src/index.ts +6 -0
  57. package/src/lib/components/DocPage.svelte +430 -0
  58. package/src/lib/components/DocsLayout.svelte +145 -0
  59. package/src/lib/components/Footer.svelte +26 -0
  60. package/src/lib/components/Navbar.svelte +117 -0
  61. package/src/lib/components/PageFooter.svelte +63 -0
  62. package/src/lib/components/PrevNextNav.svelte +83 -0
  63. package/src/lib/components/SearchDialog.svelte +130 -0
  64. package/src/lib/components/Sidebar.svelte +237 -0
  65. package/src/lib/components/TableOfContents.svelte +50 -0
  66. package/src/lib/components/TopBar.svelte +407 -0
  67. package/src/lib/components/index.ts +19 -0
  68. package/src/lib/components/tiramisu/Accordion.svelte +16 -0
  69. package/src/lib/components/tiramisu/Badge.svelte +16 -0
  70. package/src/lib/components/tiramisu/Callout.svelte +26 -0
  71. package/src/lib/components/tiramisu/CodeBlock.svelte +56 -0
  72. package/src/lib/components/tiramisu/CodeTabs.svelte +123 -0
  73. package/src/lib/components/tiramisu/Demo.svelte +15 -0
  74. package/src/lib/components/tiramisu/FileTree.svelte +67 -0
  75. package/src/lib/components/tiramisu/MathBlock.svelte +26 -0
  76. package/src/lib/components/tiramisu/Mermaid.svelte +30 -0
  77. package/src/lib/components/tiramisu/NavCard.svelte +49 -0
  78. package/src/lib/components/tiramisu/Steps.svelte +60 -0
  79. package/src/lib/components/tiramisu/Tabs.svelte +87 -0
  80. package/src/lib/components/tiramisu/ZoomImage.svelte +114 -0
  81. package/src/lib/components/tiramisu/lang-icons.ts +81 -0
  82. package/src/lib/open-links.ts +50 -0
  83. package/src/lib/routes/docs/[...slug]/+page.svelte +26 -0
  84. package/src/lib/routes/docs/[...slug]/+page.ts +117 -0
  85. package/src/lib/styles/theme.css +222 -0
  86. package/src/lib/utils.ts +10 -0
  87. package/src/mcp.ts +180 -0
  88. package/src/scan.ts +92 -0
  89. package/src/seo.ts +193 -0
  90. package/src/tiramisu-grammar.ts +80 -0
  91. package/src/types.ts +71 -0
  92. package/src/virtual.d.ts +11 -0
  93. package/src/vite.ts +478 -0
  94. package/tests/config.test.ts +60 -0
  95. package/tests/mcp.test.ts +116 -0
  96. package/tests/scan.test.ts +48 -0
  97. package/tests/seo.test.ts +174 -0
  98. package/tests/vite.test.ts +283 -0
  99. package/tsconfig.json +19 -0
package/src/seo.ts ADDED
@@ -0,0 +1,193 @@
1
+ export function generateSitemap(
2
+ docs: { slug: string }[],
3
+ options: { baseUrl: string; basePath?: string; locales?: { code: string }[]; defaultLocale?: string }
4
+ ): string {
5
+ const base = options.baseUrl.replace(/\/+$/, "")
6
+ const basePath = options.basePath ?? "/docs"
7
+ const buildDate = new Date().toISOString().split("T")[0]
8
+
9
+ const hasI18n = options.locales && options.locales.length > 0 && options.defaultLocale
10
+
11
+ let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`
12
+ if (hasI18n) {
13
+ xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/TR/xhtml11/xhtml11_schema.html">\n`
14
+ } else {
15
+ xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n`
16
+ }
17
+
18
+ for (const doc of docs) {
19
+ const slug = doc.slug === "index" ? "" : `/${doc.slug}`
20
+ const url = `${base}${basePath}${slug}`
21
+ xml += ` <url>\n`
22
+ xml += ` <loc>${escapeXml(url)}</loc>\n`
23
+ xml += ` <lastmod>${buildDate}</lastmod>\n`
24
+ if (hasI18n) {
25
+ for (const locale of options.locales!) {
26
+ const localeUrl = `${base}${basePath}/${locale.code}${slug}`
27
+ xml += ` <xhtml:link rel="alternate" hreflang="${locale.code}" href="${escapeXml(localeUrl)}" />\n`
28
+ }
29
+ }
30
+ xml += ` </url>\n`
31
+ }
32
+
33
+ xml += `</urlset>\n`
34
+ return xml
35
+ }
36
+
37
+ function escapeXml(str: string): string {
38
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;")
39
+ }
40
+
41
+ export function generateLlmsTxt(
42
+ docs: { slug: string; meta: { title?: string; description?: string; group?: string } }[],
43
+ options: { title: string; description: string; baseUrl: string; basePath?: string }
44
+ ): string {
45
+ const base = options.baseUrl.replace(/\/+$/, "")
46
+ const basePath = options.basePath ?? "/docs"
47
+
48
+ const lines: string[] = []
49
+ lines.push(`# ${options.title}`)
50
+ lines.push(`> ${options.description}`)
51
+ lines.push("")
52
+
53
+ const groups = new Map<string, typeof docs>()
54
+ for (const doc of docs) {
55
+ const group = doc.meta.group ?? "Docs"
56
+ if (!groups.has(group)) groups.set(group, [])
57
+ groups.get(group)!.push(doc)
58
+ }
59
+
60
+ for (const [group, groupDocs] of groups) {
61
+ lines.push(`## ${group}`)
62
+ for (const doc of groupDocs) {
63
+ const slug = doc.slug === "index" ? "" : `/${doc.slug}`
64
+ const url = `${base}${basePath}${slug}`
65
+ const title = doc.meta.title ?? doc.slug
66
+ const desc = doc.meta.description ? `: ${doc.meta.description}` : ""
67
+ lines.push(`- [${title}](${url})${desc}`)
68
+ }
69
+ lines.push("")
70
+ }
71
+
72
+ return lines.join("\n")
73
+ }
74
+
75
+ export function generateLlmsFullTxt(
76
+ searchIndex: { slug: string; title: string; group: string; text: string }[],
77
+ options: { title: string; description: string; baseUrl: string; basePath?: string }
78
+ ): string {
79
+ const base = options.baseUrl.replace(/\/+$/, "")
80
+ const basePath = options.basePath ?? "/docs"
81
+
82
+ const lines: string[] = []
83
+ lines.push(`# ${options.title}`)
84
+ lines.push(`> ${options.description}`)
85
+ lines.push("")
86
+
87
+ for (const entry of searchIndex) {
88
+ const slug = entry.slug === "index" ? "" : `/${entry.slug}`
89
+ const url = `${base}${basePath}${slug}`
90
+ lines.push(`---`)
91
+ lines.push(`## ${entry.title}`)
92
+ lines.push(`URL: ${url}`)
93
+ lines.push(`Group: ${entry.group}`)
94
+ lines.push("")
95
+ lines.push(entry.text)
96
+ lines.push("")
97
+ }
98
+
99
+ return lines.join("\n")
100
+ }
101
+
102
+ export function buildInstantOgUrl(pageUrl: string, options: { siteId: string; template?: string; theme?: "light" | "dark"; accentColor?: string; gradientBg?: boolean }): string {
103
+ const params = new URLSearchParams({ site: options.siteId, url: pageUrl })
104
+ if (options.template) params.set("template", options.template)
105
+ if (options.theme) params.set("theme", options.theme)
106
+ if (options.accentColor) params.set("accentColor", options.accentColor)
107
+ if (options.gradientBg) params.set("gradientBg", "true")
108
+ return `https://instantog.com/api/og?${params.toString()}`
109
+ }
110
+
111
+ export function buildCanonicalUrl(baseUrl: string, slug: string): string {
112
+ return `${baseUrl.replace(/\/+$/, "")}/docs/${slug}`
113
+ }
114
+
115
+ export function buildPageJsonLd(options: {
116
+ title: string
117
+ slug: string
118
+ baseUrl: string
119
+ description?: string
120
+ lastEdited?: string
121
+ siteName?: string
122
+ image?: string
123
+ author?: string
124
+ }): string {
125
+ const url = buildCanonicalUrl(options.baseUrl, options.slug)
126
+ const ld: Record<string, unknown> = {
127
+ "@context": "https://schema.org",
128
+ "@type": "TechArticle",
129
+ headline: options.title,
130
+ url,
131
+ mainEntityOfPage: { "@type": "WebPage", "@id": url },
132
+ isPartOf: { "@type": "WebSite", name: options.siteName ?? undefined, url: options.baseUrl.replace(/\/+$/, "") },
133
+ }
134
+ if (options.description) ld.description = options.description
135
+ if (options.lastEdited) ld.dateModified = options.lastEdited
136
+ if (options.image) ld.image = options.image
137
+ if (options.author) ld.author = { "@type": "Person", name: options.author }
138
+ return JSON.stringify(ld)
139
+ }
140
+
141
+ export function generateSkillMd(
142
+ docs: { slug: string; meta: { title?: string; description?: string; group?: string } }[],
143
+ options: { title: string; description: string }
144
+ ): string {
145
+ const lines: string[] = []
146
+ lines.push(`---`)
147
+ lines.push(`name: ${options.title.toLowerCase().replace(/\s+/g, "-")}-docs`)
148
+ lines.push(`description: ${options.description}`)
149
+ lines.push(`---`)
150
+ lines.push("")
151
+ lines.push(`# ${options.title} Documentation`)
152
+ lines.push("")
153
+ lines.push(options.description)
154
+ lines.push("")
155
+
156
+ // Structure by groups
157
+ const groups = new Map<string, typeof docs>()
158
+ for (const doc of docs) {
159
+ const group = doc.meta.group ?? "Docs"
160
+ if (!groups.has(group)) groups.set(group, [])
161
+ groups.get(group)!.push(doc)
162
+ }
163
+
164
+ lines.push(`## Sections`)
165
+ lines.push("")
166
+ for (const [group, groupDocs] of groups) {
167
+ lines.push(`- **${group}** (${groupDocs.length} pages)`)
168
+ }
169
+ lines.push("")
170
+
171
+ lines.push(`## Key Pages`)
172
+ lines.push("")
173
+ for (const [group, groupDocs] of groups) {
174
+ lines.push(`### ${group}`)
175
+ for (const doc of groupDocs) {
176
+ const title = doc.meta.title ?? doc.slug
177
+ const desc = doc.meta.description ? ` - ${doc.meta.description}` : ""
178
+ lines.push(`- **${title}** (\`${doc.slug}\`)${desc}`)
179
+ }
180
+ lines.push("")
181
+ }
182
+
183
+ lines.push(`## MCP Integration`)
184
+ lines.push("")
185
+ lines.push(`This documentation is available via MCP server. Tools:`)
186
+ lines.push(`- \`search_docs\`: Search documentation by keyword`)
187
+ lines.push(`- \`read_doc\`: Read a specific documentation page`)
188
+ lines.push(`- \`list_sections\`: List all documentation sections`)
189
+ lines.push(`- \`list_pages\`: List pages, optionally filtered by section`)
190
+ lines.push(`- \`get_table_of_contents\`: Get headings for a page`)
191
+
192
+ return lines.join("\n") + "\n"
193
+ }
@@ -0,0 +1,80 @@
1
+ import type { LanguageRegistration } from "shiki"
2
+
3
+ export const tiramisuGrammar: LanguageRegistration = {
4
+ name: "tiramisu",
5
+ scopeName: "source.tiramisu",
6
+ patterns: [
7
+ { include: "#string" },
8
+ { include: "#function-call" },
9
+ ],
10
+ repository: {
11
+ string: {
12
+ patterns: [
13
+ {
14
+ name: "string.quoted.triple.tiramisu",
15
+ begin: '"""',
16
+ end: '"""',
17
+ patterns: [{ include: "#string-escape" }],
18
+ },
19
+ {
20
+ name: "string.quoted.double-double.tiramisu",
21
+ begin: '""(?!")',
22
+ end: '""',
23
+ patterns: [{ include: "#string-escape" }],
24
+ },
25
+ {
26
+ name: "string.quoted.double.tiramisu",
27
+ begin: '"(?!")',
28
+ end: '"',
29
+ patterns: [{ include: "#string-escape" }],
30
+ },
31
+ ],
32
+ },
33
+ "string-escape": {
34
+ name: "constant.character.escape.tiramisu",
35
+ match: "\\\\[,{}\\[\\]\\\\]",
36
+ },
37
+ "function-call": {
38
+ patterns: [
39
+ {
40
+ // Known built-in functions
41
+ match:
42
+ "\\b(meta|h[1-6]|bold|italic|code|link|image|codeblock|list|table|callout|tabs|steps|badge|quote|tasklist|columns|col|accordion|cards|card|filetree|folder|file|math|mermaid)\\s*(?=\\{)",
43
+ captures: {
44
+ 1: { name: "support.function.builtin.tiramisu" },
45
+ },
46
+ },
47
+ {
48
+ // Custom/user functions
49
+ match: "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?=\\{)",
50
+ captures: {
51
+ 1: { name: "entity.name.function.tiramisu" },
52
+ },
53
+ },
54
+ {
55
+ // Named parameter keys
56
+ match: "\\b([a-zA-Z_][a-zA-Z0-9_]*)\\s*(?==)",
57
+ captures: {
58
+ 1: { name: "variable.parameter.tiramisu" },
59
+ },
60
+ },
61
+ {
62
+ name: "punctuation.section.braces.tiramisu",
63
+ match: "[{}]",
64
+ },
65
+ {
66
+ name: "punctuation.section.brackets.tiramisu",
67
+ match: "[\\[\\]]",
68
+ },
69
+ {
70
+ name: "punctuation.separator.comma.tiramisu",
71
+ match: ",",
72
+ },
73
+ {
74
+ name: "keyword.operator.assignment.tiramisu",
75
+ match: "=",
76
+ },
77
+ ],
78
+ },
79
+ },
80
+ }
package/src/types.ts ADDED
@@ -0,0 +1,71 @@
1
+ import type { DocMeta, Heading } from "@tiramisu-docs/core"
2
+ import type { SvelteComponent } from "svelte"
3
+
4
+ export interface SidebarItem {
5
+ type: "item"
6
+ title: string
7
+ slug: string
8
+ order: number
9
+ icon?: string
10
+ }
11
+
12
+ export interface SidebarSubgroup {
13
+ type: "subgroup"
14
+ key: string
15
+ label: string
16
+ slug?: string
17
+ items: SidebarEntry[]
18
+ order: number
19
+ icon?: string
20
+ }
21
+
22
+ export type SidebarEntry = SidebarItem | SidebarSubgroup
23
+
24
+ export interface SidebarGroup {
25
+ label: string
26
+ items: SidebarEntry[]
27
+ icon?: string
28
+ }
29
+
30
+ export interface VirtualDoc {
31
+ slug: string
32
+ meta: DocMeta
33
+ headings: Heading[]
34
+ lastEdited?: string
35
+ }
36
+
37
+ export interface SearchIndexEntry {
38
+ id: string
39
+ title: string
40
+ group: string
41
+ slug: string
42
+ headings: string
43
+ text: string
44
+ }
45
+
46
+ export interface ResolvedSection {
47
+ label: string
48
+ path?: string
49
+ href?: string
50
+ icon?: string
51
+ children?: ResolvedSection[]
52
+ sidebar?: SidebarGroup[]
53
+ }
54
+
55
+ export interface LocaleData {
56
+ sections?: ResolvedSection[]
57
+ sidebar: SidebarGroup[]
58
+ docs: VirtualDoc[]
59
+ searchIndex: SearchIndexEntry[]
60
+ docImports: Record<string, () => Promise<{ default: typeof SvelteComponent }>>
61
+ }
62
+
63
+ export interface VirtualModule {
64
+ docs: VirtualDoc[]
65
+ sidebar: SidebarGroup[]
66
+ sections?: ResolvedSection[]
67
+ docImports: Record<string, () => Promise<{ default: typeof SvelteComponent }>>
68
+ searchIndex: SearchIndexEntry[]
69
+ locales?: Record<string, LocaleData>
70
+ defaultLocale?: string
71
+ }
@@ -0,0 +1,11 @@
1
+ declare module "virtual:tiramisu-docs" {
2
+ import type { VirtualDoc, SidebarGroup, ResolvedSection, SearchIndexEntry, LocaleData } from "./types"
3
+
4
+ export const docs: VirtualDoc[]
5
+ export const sidebar: SidebarGroup[]
6
+ export const sections: ResolvedSection[] | undefined
7
+ export const docImports: Record<string, () => Promise<{ default: any }>>
8
+ export const searchIndex: SearchIndexEntry[]
9
+ export const locales: Record<string, LocaleData> | undefined
10
+ export const defaultLocale: string | undefined
11
+ }