@veluai/velu 0.2.13 → 0.2.15

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 (109) hide show
  1. package/README.md +80 -80
  2. package/dist/cli.js +37 -37
  3. package/package.json +64 -64
  4. package/runtime/velu-ui/base.css +320 -320
  5. package/runtime/velu-ui/components/Accordion.jsx +64 -64
  6. package/runtime/velu-ui/components/ApiClient.jsx +207 -207
  7. package/runtime/velu-ui/components/ApiField.jsx +87 -87
  8. package/runtime/velu-ui/components/ApiPath.jsx +63 -63
  9. package/runtime/velu-ui/components/ApiReferencePage.jsx +384 -384
  10. package/runtime/velu-ui/components/ApiSamples.jsx +36 -36
  11. package/runtime/velu-ui/components/ApiSidebar.jsx +122 -122
  12. package/runtime/velu-ui/components/AskBar.jsx +71 -71
  13. package/runtime/velu-ui/components/Callout.jsx +114 -114
  14. package/runtime/velu-ui/components/Card.jsx +131 -131
  15. package/runtime/velu-ui/components/Chatbot.jsx +885 -885
  16. package/runtime/velu-ui/components/CodeBlock.jsx +375 -375
  17. package/runtime/velu-ui/components/Columns.jsx +56 -56
  18. package/runtime/velu-ui/components/ContextMenu.jsx +298 -273
  19. package/runtime/velu-ui/components/ErrorCard.jsx +138 -138
  20. package/runtime/velu-ui/components/Field.jsx +81 -81
  21. package/runtime/velu-ui/components/Image.jsx +163 -163
  22. package/runtime/velu-ui/components/Logo.jsx +31 -31
  23. package/runtime/velu-ui/components/MethodBadge.jsx +31 -31
  24. package/runtime/velu-ui/components/NavSelect.jsx +108 -108
  25. package/runtime/velu-ui/components/NotFound.jsx +63 -63
  26. package/runtime/velu-ui/components/PageFeedback.jsx +219 -219
  27. package/runtime/velu-ui/components/PageFooter.jsx +145 -145
  28. package/runtime/velu-ui/components/PageHeader.jsx +422 -422
  29. package/runtime/velu-ui/components/PageNav.jsx +77 -77
  30. package/runtime/velu-ui/components/PoweredBy.jsx +51 -51
  31. package/runtime/velu-ui/components/Prompt.jsx +115 -115
  32. package/runtime/velu-ui/components/Search.jsx +460 -460
  33. package/runtime/velu-ui/components/Sidebar.jsx +254 -254
  34. package/runtime/velu-ui/components/SocialLinks.jsx +90 -90
  35. package/runtime/velu-ui/components/Steps.jsx +65 -65
  36. package/runtime/velu-ui/components/ThemeToggle.jsx +48 -48
  37. package/runtime/velu-ui/components/Toc.jsx +537 -537
  38. package/runtime/velu-ui/components/TocBar.jsx +195 -195
  39. package/runtime/velu-ui/components/Tree.jsx +87 -87
  40. package/runtime/velu-ui/components/TryItBar.jsx +102 -102
  41. package/runtime/velu-ui/components/accordion.css +92 -92
  42. package/runtime/velu-ui/components/api-page.css +208 -208
  43. package/runtime/velu-ui/components/api.css +635 -635
  44. package/runtime/velu-ui/components/ask-bar.css +94 -94
  45. package/runtime/velu-ui/components/card.css +105 -105
  46. package/runtime/velu-ui/components/chatbot.css +622 -622
  47. package/runtime/velu-ui/components/code-block.css +263 -263
  48. package/runtime/velu-ui/components/context-menu.css +173 -173
  49. package/runtime/velu-ui/components/docs-layout.css +822 -822
  50. package/runtime/velu-ui/components/field.css +82 -82
  51. package/runtime/velu-ui/components/image.css +237 -237
  52. package/runtime/velu-ui/components/nav-select.css +157 -157
  53. package/runtime/velu-ui/components/not-found.css +94 -94
  54. package/runtime/velu-ui/components/page-feedback.css +241 -241
  55. package/runtime/velu-ui/components/page-footer.css +130 -130
  56. package/runtime/velu-ui/components/page-header.css +558 -558
  57. package/runtime/velu-ui/components/page-nav.css +50 -50
  58. package/runtime/velu-ui/components/powered-by.css +92 -92
  59. package/runtime/velu-ui/components/prompt.css +99 -99
  60. package/runtime/velu-ui/components/search.css +307 -307
  61. package/runtime/velu-ui/components/sidebar.css +205 -205
  62. package/runtime/velu-ui/components/steps.css +77 -77
  63. package/runtime/velu-ui/components/theme-toggle.css +102 -102
  64. package/runtime/velu-ui/components/toc-bar.css +234 -234
  65. package/runtime/velu-ui/components/tree.css +49 -49
  66. package/runtime/velu-ui/index.js +54 -54
  67. package/runtime/velu-ui/lib/api-send.js +92 -92
  68. package/runtime/velu-ui/lib/brand-icons.jsx +103 -103
  69. package/runtime/velu-ui/lib/component-schemas.js +100 -100
  70. package/runtime/velu-ui/lib/copyText.js +64 -64
  71. package/runtime/velu-ui/lib/docs-assistant.js +250 -250
  72. package/runtime/velu-ui/lib/lang-icons.jsx +147 -147
  73. package/runtime/velu-ui/lib/pagefind.js +113 -113
  74. package/runtime/velu-ui/lib/prism-langs.js +957 -957
  75. package/runtime/velu-ui/lib/prism-loader.js +74 -74
  76. package/runtime/velu-ui/lib/resolveIcon.jsx +29 -29
  77. package/runtime/velu-ui/lib/scrollIntoNearestView.js +66 -66
  78. package/runtime/velu-ui/mdx-components.jsx +105 -105
  79. package/runtime/velu-ui/primitives/Cluster.jsx +49 -49
  80. package/runtime/velu-ui/primitives/Stack.jsx +63 -63
  81. package/runtime/velu-ui/primitives/Switcher.jsx +57 -57
  82. package/runtime/velu-ui/primitives/stack.css +3 -3
  83. package/runtime/velu-ui/primitives/switcher.css +25 -25
  84. package/runtime/velu-ui/styles.css +46 -46
  85. package/runtime/velu-ui/tokens.css +4 -4
  86. package/schema/velu.schema.json +423 -423
  87. package/src/lib/extract-mdx-error.js +170 -170
  88. package/src/lib/issues.js +159 -159
  89. package/src/lib/known-components.js +34 -34
  90. package/src/navigation.js +443 -443
  91. package/src/runtime/App.jsx +1669 -1668
  92. package/src/runtime/ErrorBoundary.jsx +54 -54
  93. package/src/runtime/client-entry.jsx +22 -22
  94. package/src/runtime/server-entry.jsx +16 -16
  95. package/src/template.html +48 -48
  96. package/templates/starter/ai-tools/claude-code.mdx +26 -26
  97. package/templates/starter/ai-tools/cursor.mdx +17 -17
  98. package/templates/starter/api-reference/introduction.mdx +43 -43
  99. package/templates/starter/development.mdx +19 -19
  100. package/templates/starter/essentials/code.mdx +29 -29
  101. package/templates/starter/essentials/images.mdx +29 -29
  102. package/templates/starter/essentials/markdown.mdx +25 -25
  103. package/templates/starter/essentials/navigation.mdx +39 -39
  104. package/templates/starter/essentials/settings.mdx +30 -30
  105. package/templates/starter/favicon.svg +6 -6
  106. package/templates/starter/index.mdx +31 -31
  107. package/templates/starter/openapi.json +160 -160
  108. package/templates/starter/quickstart.mdx +31 -31
  109. package/templates/starter/velu.json +41 -41
@@ -1,423 +1,423 @@
1
- {
2
- "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://veludocs.com/velu.schema.json",
4
- "title": "Velu project configuration",
5
- "description": "Configuration for a Velu documentation project (velu.json). This schema is defined internally during iteration; it will be hosted at the $id URL so editors can validate + autocomplete velu.json files.",
6
- "type": "object",
7
- "required": ["name"],
8
- "additionalProperties": false,
9
- "properties": {
10
- "$schema": {
11
- "type": "string",
12
- "description": "URL of this JSON Schema, enabling editor validation + autocomplete."
13
- },
14
- "name": {
15
- "type": "string",
16
- "description": "Project name; usually the folder name it's contained in.",
17
- "minLength": 1
18
- },
19
- "colors": {
20
- "type": "object",
21
- "description": "Accent colors. Maps onto the --accent-color token in base.css.",
22
- "additionalProperties": false,
23
- "required": ["primary"],
24
- "properties": {
25
- "primary": {
26
- "type": "string",
27
- "description": "The accent color used across the UI (--accent-color)."
28
- },
29
- "light": {
30
- "type": "string",
31
- "description": "Light-mode accent override. Defaults to `primary`."
32
- },
33
- "dark": {
34
- "type": "string",
35
- "description": "Dark-mode accent override. Defaults to `primary`."
36
- }
37
- }
38
- },
39
- "favicon": {
40
- "type": "string",
41
- "description": "Path to the favicon, relative to the project root."
42
- },
43
- "api": { "$ref": "#/$defs/api" },
44
- "logo": {
45
- "description": "Site logo shown in the header, replacing the name wordmark. A single path used in both themes, or per-theme light/dark images with an optional click-through href. Paths are relative to the project root.",
46
- "oneOf": [
47
- {
48
- "type": "string",
49
- "minLength": 1,
50
- "description": "Logo path used in both light and dark mode."
51
- },
52
- {
53
- "type": "object",
54
- "additionalProperties": false,
55
- "required": ["light", "dark"],
56
- "properties": {
57
- "light": {
58
- "type": "string",
59
- "minLength": 1,
60
- "description": "Logo shown in light mode."
61
- },
62
- "dark": {
63
- "type": "string",
64
- "minLength": 1,
65
- "description": "Logo shown in dark mode."
66
- },
67
- "href": {
68
- "type": "string",
69
- "description": "Where clicking the logo links. Defaults to the site root."
70
- }
71
- }
72
- }
73
- ]
74
- },
75
- "navbar": {
76
- "type": "object",
77
- "additionalProperties": false,
78
- "description": "The header's top-right area: secondary links plus a primary CTA button.",
79
- "properties": {
80
- "links": {
81
- "type": "array",
82
- "description": "Secondary header links (to the left of the primary CTA).",
83
- "items": {
84
- "type": "object",
85
- "additionalProperties": false,
86
- "required": ["href"],
87
- "properties": {
88
- "label": { "type": "string", "description": "Link text." },
89
- "href": { "type": "string", "description": "Link URL." },
90
- "icon": { "type": "string", "description": "lucide icon id." }
91
- }
92
- }
93
- },
94
- "primary": {
95
- "description": "The prominent CTA button at the far right.",
96
- "oneOf": [
97
- {
98
- "type": "object",
99
- "additionalProperties": false,
100
- "required": ["type", "label", "href"],
101
- "properties": {
102
- "type": { "const": "button" },
103
- "label": { "type": "string", "description": "Button text." },
104
- "href": { "type": "string", "description": "Button URL." }
105
- }
106
- },
107
- {
108
- "type": "object",
109
- "additionalProperties": false,
110
- "required": ["type", "href"],
111
- "properties": {
112
- "type": { "const": "github" },
113
- "href": { "type": "string", "description": "GitHub repository URL." },
114
- "label": { "type": "string", "description": "Button text (default \"GitHub\")." }
115
- }
116
- }
117
- ]
118
- }
119
- }
120
- },
121
- "footer": {
122
- "type": "object",
123
- "additionalProperties": false,
124
- "description": "Site footer. With `links`, a full footer section renders; with only `socials`, the icons sit next to the \"Powered by\" line instead.",
125
- "properties": {
126
- "socials": {
127
- "type": "object",
128
- "description": "Social links as platform → URL. Recognized icons: github, x (or twitter), youtube, linkedin.",
129
- "additionalProperties": { "type": "string" }
130
- },
131
- "links": {
132
- "type": "array",
133
- "description": "Footer link columns (max 4).",
134
- "maxItems": 4,
135
- "items": {
136
- "type": "object",
137
- "additionalProperties": false,
138
- "required": ["header", "items"],
139
- "properties": {
140
- "header": { "type": "string", "description": "Column heading." },
141
- "items": {
142
- "type": "array",
143
- "items": {
144
- "type": "object",
145
- "additionalProperties": false,
146
- "required": ["label", "href"],
147
- "properties": {
148
- "label": { "type": "string", "description": "Link text." },
149
- "href": { "type": "string", "description": "Link URL." }
150
- }
151
- }
152
- }
153
- }
154
- }
155
- }
156
- }
157
- },
158
- "font": {
159
- "type": "object",
160
- "description": "Typography. Maps onto the --font-sans token in base.css.",
161
- "additionalProperties": false,
162
- "required": ["family"],
163
- "properties": {
164
- "family": {
165
- "type": "string",
166
- "description": "Google Font family to use (--font-sans)."
167
- }
168
- }
169
- },
170
- "navigation": {
171
- "$ref": "#/$defs/navContainer",
172
- "description": "Site navigation. Mintlify-compatible: products > versions > languages > tabs > groups > pages. Switchable axes (product/version/language) become URL path prefixes; the default value of each is unprefixed. Dropdowns are intentionally unsupported."
173
- },
174
- "url": {
175
- "type": "string",
176
- "description": "Production site origin (e.g. \"https://docs.example.com\"), no trailing slash. Used by the static build for canonical URLs, og:url, and sitemap.xml, and by llms.txt for absolute links."
177
- },
178
- "thumbnails": {
179
- "type": "object",
180
- "additionalProperties": false,
181
- "description": "Auto-generated OG (social share) image options. Build-only.",
182
- "properties": {
183
- "background": {
184
- "type": "string",
185
- "description": "Project-relative path to a background image for the OG cards (e.g. \"/images/og-background.png\"). Defaults to a brand-color glow."
186
- }
187
- }
188
- },
189
- "seo": {
190
- "type": "object",
191
- "additionalProperties": false,
192
- "description": "Search-engine optimization. Build-only: meta tags and sitemap behaviour applied when the site is built (not in the dev preview).",
193
- "properties": {
194
- "metatags": {
195
- "type": "object",
196
- "description": "Extra meta tags injected on every page, as a flat key→value map (e.g. \"google-site-verification\", \"og:image\").",
197
- "additionalProperties": { "type": "string" }
198
- },
199
- "indexing": {
200
- "type": "string",
201
- "enum": ["navigable", "all"],
202
- "description": "\"navigable\" (default) indexes only pages in navigation; \"all\" also includes hidden pages."
203
- }
204
- }
205
- },
206
- "contextual": {
207
- "type": "object",
208
- "additionalProperties": false,
209
- "description": "Per-page context menu — the \"Copy Page\" split-button + dropdown of agent/IDE actions shown at the top of each page. Mintlify-compatible. Unset → copy, view, chatgpt, claude.",
210
- "required": ["options"],
211
- "properties": {
212
- "options": {
213
- "type": "array",
214
- "description": "Menu items, in order. Known string options, or custom { title, description, href } entries.",
215
- "items": {
216
- "oneOf": [
217
- {
218
- "type": "string",
219
- "enum": [
220
- "copy", "assistant", "view", "download-pdf", "download-spec",
221
- "chatgpt", "claude", "perplexity", "grok", "aistudio", "devin", "windsurf",
222
- "mcp", "add-mcp", "cursor", "vscode", "devin-mcp"
223
- ]
224
- },
225
- {
226
- "type": "object",
227
- "additionalProperties": false,
228
- "required": ["title", "href"],
229
- "properties": {
230
- "title": { "type": "string", "description": "Menu item label." },
231
- "description": { "type": "string", "description": "Secondary line under the label." },
232
- "href": { "type": "string", "description": "URL to open." },
233
- "icon": { "type": "string", "description": "Lucide icon id." }
234
- }
235
- }
236
- ]
237
- }
238
- },
239
- "display": {
240
- "type": "string",
241
- "enum": ["header", "toc"],
242
- "description": "Where the menu renders. Default \"header\"."
243
- }
244
- }
245
- },
246
- "assistant": {
247
- "type": "object",
248
- "additionalProperties": false,
249
- "description": "Docs-site \"Ask AI\" backend. When apiBase is set, the published build wires the chatbot to the public docs-AI-assistant API; absent → the chatbot shows a canned demo answer (also in the dev preview). On Velu-hosted sites apiBase (and, when unset, suggestions) are filled in at publish time.",
250
- "properties": {
251
- "apiBase": {
252
- "type": "string",
253
- "description": "Base URL of the Velu backend that serves /api/v1/public/ai-assistant/* (e.g. \"https://api.getvelu.com\"). Must be same-site with the docs (or send a SameSite=None visitor cookie) for the credentialed requests to work."
254
- },
255
- "host": {
256
- "type": "string",
257
- "description": "Override the tenant-resolution host sent as X-Velu-Site-Host. Defaults to the page's own host at runtime."
258
- },
259
- "suggestions": {
260
- "type": "array",
261
- "items": { "type": "string" },
262
- "maxItems": 6,
263
- "description": "Starter questions shown when the Ask-AI panel opens. Unset on a Velu-hosted site → generated from the site's content at publish time."
264
- }
265
- }
266
- }
267
- },
268
- "$defs": {
269
- "navContainer": {
270
- "type": "object",
271
- "additionalProperties": false,
272
- "description": "A navigation container. Higher-precedence keys nest the lower ones (products contain versions contain languages contain tabs contain groups/pages).",
273
- "properties": {
274
- "products": { "type": "array", "items": { "$ref": "#/$defs/product" } },
275
- "versions": { "type": "array", "items": { "$ref": "#/$defs/version" } },
276
- "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
277
- "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
278
- "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
279
- "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
280
- "pages": { "$ref": "#/$defs/pages" }
281
- }
282
- },
283
- "pages": {
284
- "type": "array",
285
- "description": "Ordered list of page paths (no extension, relative to the project root) and/or nested groups.",
286
- "items": {
287
- "oneOf": [
288
- { "type": "string" },
289
- { "$ref": "#/$defs/group" }
290
- ]
291
- }
292
- },
293
- "group": {
294
- "type": "object",
295
- "additionalProperties": false,
296
- "required": ["group"],
297
- "properties": {
298
- "group": { "type": "string", "description": "Sidebar section heading." },
299
- "icon": { "type": "string", "description": "lucide icon id." },
300
- "expanded": { "type": "boolean", "description": "Start expanded." },
301
- "root": { "type": "string", "description": "Landing page path for the group." },
302
- "openapi": { "$ref": "#/$defs/openapiRef" },
303
- "api": { "$ref": "#/$defs/api" },
304
- "pages": { "$ref": "#/$defs/pages" }
305
- }
306
- },
307
- "tab": {
308
- "type": "object",
309
- "additionalProperties": false,
310
- "required": ["tab"],
311
- "properties": {
312
- "tab": { "type": "string", "description": "Tab label (top nav)." },
313
- "icon": { "type": "string" },
314
- "href": { "type": "string", "description": "External/override link instead of in-site pages." },
315
- "openapi": { "$ref": "#/$defs/openapiRef" },
316
- "api": { "$ref": "#/$defs/api" },
317
- "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
318
- "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
319
- "pages": { "$ref": "#/$defs/pages" }
320
- }
321
- },
322
- "api": {
323
- "type": "object",
324
- "additionalProperties": false,
325
- "description": "API reference behaviour for OpenAPI-generated pages. Set at the root, or on a tab/group with `openapi` to override it for just that section.",
326
- "properties": {
327
- "server": {
328
- "type": "string",
329
- "description": "Base URL override for the playground + code samples (otherwise the spec's first server is used)."
330
- },
331
- "playground": {
332
- "type": "object",
333
- "additionalProperties": false,
334
- "properties": {
335
- "display": {
336
- "type": "string",
337
- "enum": ["interactive", "simple", "none"],
338
- "description": "Playground mode. \"none\" disables the proxy / live send."
339
- },
340
- "proxy": {
341
- "type": "boolean",
342
- "description": "Send Try-It requests through the dev proxy to avoid CORS (default true)."
343
- }
344
- }
345
- },
346
- "examples": {
347
- "type": "object",
348
- "additionalProperties": false,
349
- "properties": {
350
- "languages": {
351
- "type": "array",
352
- "items": { "type": "string", "enum": ["curl", "javascript", "python", "ruby"] },
353
- "description": "Which request-snippet languages to generate."
354
- }
355
- }
356
- }
357
- }
358
- },
359
- "openapiRef": {
360
- "description": "Path or URL to an OpenAPI spec (JSON/YAML), or an array of them. Auto-generates a page per operation, grouped by tag.",
361
- "oneOf": [
362
- { "type": "string" },
363
- { "type": "array", "items": { "type": "string" } }
364
- ]
365
- },
366
- "anchor": {
367
- "type": "object",
368
- "additionalProperties": false,
369
- "required": ["anchor", "href"],
370
- "properties": {
371
- "anchor": { "type": "string", "description": "Anchor label (pinned sidebar link)." },
372
- "icon": { "type": "string" },
373
- "href": { "type": "string" },
374
- "color": { "type": "string" }
375
- }
376
- },
377
- "product": {
378
- "type": "object",
379
- "additionalProperties": false,
380
- "required": ["product"],
381
- "properties": {
382
- "product": { "type": "string", "description": "Product id (used for the URL slug)." },
383
- "name": { "type": "string", "description": "Display name; defaults to `product`." },
384
- "icon": { "type": "string" },
385
- "color": { "type": "string" },
386
- "default": { "type": "boolean", "description": "The default product is unprefixed in URLs." },
387
- "versions": { "type": "array", "items": { "$ref": "#/$defs/version" } },
388
- "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
389
- "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
390
- "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
391
- "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
392
- "pages": { "$ref": "#/$defs/pages" }
393
- }
394
- },
395
- "version": {
396
- "type": "object",
397
- "additionalProperties": false,
398
- "required": ["version"],
399
- "properties": {
400
- "version": { "type": "string", "description": "Version label (used for the URL slug)." },
401
- "default": { "type": "boolean", "description": "The default version is unprefixed in URLs." },
402
- "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
403
- "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
404
- "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
405
- "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
406
- "pages": { "$ref": "#/$defs/pages" }
407
- }
408
- },
409
- "language": {
410
- "type": "object",
411
- "additionalProperties": false,
412
- "required": ["language"],
413
- "properties": {
414
- "language": { "type": "string", "description": "Language code (used for the URL slug)." },
415
- "default": { "type": "boolean", "description": "The default language is unprefixed in URLs." },
416
- "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
417
- "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
418
- "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
419
- "pages": { "$ref": "#/$defs/pages" }
420
- }
421
- }
422
- }
423
- }
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://veludocs.com/velu.schema.json",
4
+ "title": "Velu project configuration",
5
+ "description": "Configuration for a Velu documentation project (velu.json). This schema is defined internally during iteration; it will be hosted at the $id URL so editors can validate + autocomplete velu.json files.",
6
+ "type": "object",
7
+ "required": ["name"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+ "$schema": {
11
+ "type": "string",
12
+ "description": "URL of this JSON Schema, enabling editor validation + autocomplete."
13
+ },
14
+ "name": {
15
+ "type": "string",
16
+ "description": "Project name; usually the folder name it's contained in.",
17
+ "minLength": 1
18
+ },
19
+ "colors": {
20
+ "type": "object",
21
+ "description": "Accent colors. Maps onto the --accent-color token in base.css.",
22
+ "additionalProperties": false,
23
+ "required": ["primary"],
24
+ "properties": {
25
+ "primary": {
26
+ "type": "string",
27
+ "description": "The accent color used across the UI (--accent-color)."
28
+ },
29
+ "light": {
30
+ "type": "string",
31
+ "description": "Light-mode accent override. Defaults to `primary`."
32
+ },
33
+ "dark": {
34
+ "type": "string",
35
+ "description": "Dark-mode accent override. Defaults to `primary`."
36
+ }
37
+ }
38
+ },
39
+ "favicon": {
40
+ "type": "string",
41
+ "description": "Path to the favicon, relative to the project root."
42
+ },
43
+ "api": { "$ref": "#/$defs/api" },
44
+ "logo": {
45
+ "description": "Site logo shown in the header, replacing the name wordmark. A single path used in both themes, or per-theme light/dark images with an optional click-through href. Paths are relative to the project root.",
46
+ "oneOf": [
47
+ {
48
+ "type": "string",
49
+ "minLength": 1,
50
+ "description": "Logo path used in both light and dark mode."
51
+ },
52
+ {
53
+ "type": "object",
54
+ "additionalProperties": false,
55
+ "required": ["light", "dark"],
56
+ "properties": {
57
+ "light": {
58
+ "type": "string",
59
+ "minLength": 1,
60
+ "description": "Logo shown in light mode."
61
+ },
62
+ "dark": {
63
+ "type": "string",
64
+ "minLength": 1,
65
+ "description": "Logo shown in dark mode."
66
+ },
67
+ "href": {
68
+ "type": "string",
69
+ "description": "Where clicking the logo links. Defaults to the site root."
70
+ }
71
+ }
72
+ }
73
+ ]
74
+ },
75
+ "navbar": {
76
+ "type": "object",
77
+ "additionalProperties": false,
78
+ "description": "The header's top-right area: secondary links plus a primary CTA button.",
79
+ "properties": {
80
+ "links": {
81
+ "type": "array",
82
+ "description": "Secondary header links (to the left of the primary CTA).",
83
+ "items": {
84
+ "type": "object",
85
+ "additionalProperties": false,
86
+ "required": ["href"],
87
+ "properties": {
88
+ "label": { "type": "string", "description": "Link text." },
89
+ "href": { "type": "string", "description": "Link URL." },
90
+ "icon": { "type": "string", "description": "lucide icon id." }
91
+ }
92
+ }
93
+ },
94
+ "primary": {
95
+ "description": "The prominent CTA button at the far right.",
96
+ "oneOf": [
97
+ {
98
+ "type": "object",
99
+ "additionalProperties": false,
100
+ "required": ["type", "label", "href"],
101
+ "properties": {
102
+ "type": { "const": "button" },
103
+ "label": { "type": "string", "description": "Button text." },
104
+ "href": { "type": "string", "description": "Button URL." }
105
+ }
106
+ },
107
+ {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "required": ["type", "href"],
111
+ "properties": {
112
+ "type": { "const": "github" },
113
+ "href": { "type": "string", "description": "GitHub repository URL." },
114
+ "label": { "type": "string", "description": "Button text (default \"GitHub\")." }
115
+ }
116
+ }
117
+ ]
118
+ }
119
+ }
120
+ },
121
+ "footer": {
122
+ "type": "object",
123
+ "additionalProperties": false,
124
+ "description": "Site footer. With `links`, a full footer section renders; with only `socials`, the icons sit next to the \"Powered by\" line instead.",
125
+ "properties": {
126
+ "socials": {
127
+ "type": "object",
128
+ "description": "Social links as platform → URL. Recognized icons: github, x (or twitter), youtube, linkedin.",
129
+ "additionalProperties": { "type": "string" }
130
+ },
131
+ "links": {
132
+ "type": "array",
133
+ "description": "Footer link columns (max 4).",
134
+ "maxItems": 4,
135
+ "items": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "required": ["header", "items"],
139
+ "properties": {
140
+ "header": { "type": "string", "description": "Column heading." },
141
+ "items": {
142
+ "type": "array",
143
+ "items": {
144
+ "type": "object",
145
+ "additionalProperties": false,
146
+ "required": ["label", "href"],
147
+ "properties": {
148
+ "label": { "type": "string", "description": "Link text." },
149
+ "href": { "type": "string", "description": "Link URL." }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ },
158
+ "font": {
159
+ "type": "object",
160
+ "description": "Typography. Maps onto the --font-sans token in base.css.",
161
+ "additionalProperties": false,
162
+ "required": ["family"],
163
+ "properties": {
164
+ "family": {
165
+ "type": "string",
166
+ "description": "Google Font family to use (--font-sans)."
167
+ }
168
+ }
169
+ },
170
+ "navigation": {
171
+ "$ref": "#/$defs/navContainer",
172
+ "description": "Site navigation. Mintlify-compatible: products > versions > languages > tabs > groups > pages. Switchable axes (product/version/language) become URL path prefixes; the default value of each is unprefixed. Dropdowns are intentionally unsupported."
173
+ },
174
+ "url": {
175
+ "type": "string",
176
+ "description": "Production site origin (e.g. \"https://docs.example.com\"), no trailing slash. Used by the static build for canonical URLs, og:url, and sitemap.xml, and by llms.txt for absolute links."
177
+ },
178
+ "thumbnails": {
179
+ "type": "object",
180
+ "additionalProperties": false,
181
+ "description": "Auto-generated OG (social share) image options. Build-only.",
182
+ "properties": {
183
+ "background": {
184
+ "type": "string",
185
+ "description": "Project-relative path to a background image for the OG cards (e.g. \"/images/og-background.png\"). Defaults to a brand-color glow."
186
+ }
187
+ }
188
+ },
189
+ "seo": {
190
+ "type": "object",
191
+ "additionalProperties": false,
192
+ "description": "Search-engine optimization. Build-only: meta tags and sitemap behaviour applied when the site is built (not in the dev preview).",
193
+ "properties": {
194
+ "metatags": {
195
+ "type": "object",
196
+ "description": "Extra meta tags injected on every page, as a flat key→value map (e.g. \"google-site-verification\", \"og:image\").",
197
+ "additionalProperties": { "type": "string" }
198
+ },
199
+ "indexing": {
200
+ "type": "string",
201
+ "enum": ["navigable", "all"],
202
+ "description": "\"navigable\" (default) indexes only pages in navigation; \"all\" also includes hidden pages."
203
+ }
204
+ }
205
+ },
206
+ "contextual": {
207
+ "type": "object",
208
+ "additionalProperties": false,
209
+ "description": "Per-page context menu — the \"Copy Page\" split-button + dropdown of agent/IDE actions shown at the top of each page. Mintlify-compatible. Unset → copy, view, chatgpt, claude.",
210
+ "required": ["options"],
211
+ "properties": {
212
+ "options": {
213
+ "type": "array",
214
+ "description": "Menu items, in order. Known string options, or custom { title, description, href } entries.",
215
+ "items": {
216
+ "oneOf": [
217
+ {
218
+ "type": "string",
219
+ "enum": [
220
+ "copy", "assistant", "view", "download-pdf", "download-spec",
221
+ "chatgpt", "claude", "perplexity", "grok", "aistudio", "devin", "windsurf",
222
+ "mcp", "add-mcp", "cursor", "vscode", "devin-mcp"
223
+ ]
224
+ },
225
+ {
226
+ "type": "object",
227
+ "additionalProperties": false,
228
+ "required": ["title", "href"],
229
+ "properties": {
230
+ "title": { "type": "string", "description": "Menu item label." },
231
+ "description": { "type": "string", "description": "Secondary line under the label." },
232
+ "href": { "type": "string", "description": "URL to open." },
233
+ "icon": { "type": "string", "description": "Lucide icon id." }
234
+ }
235
+ }
236
+ ]
237
+ }
238
+ },
239
+ "display": {
240
+ "type": "string",
241
+ "enum": ["header", "toc"],
242
+ "description": "Where the menu renders. Default \"header\"."
243
+ }
244
+ }
245
+ },
246
+ "assistant": {
247
+ "type": "object",
248
+ "additionalProperties": false,
249
+ "description": "Docs-site \"Ask AI\" backend. When apiBase is set, the published build wires the chatbot to the public docs-AI-assistant API; absent → the chatbot shows a canned demo answer (also in the dev preview). On Velu-hosted sites apiBase (and, when unset, suggestions) are filled in at publish time.",
250
+ "properties": {
251
+ "apiBase": {
252
+ "type": "string",
253
+ "description": "Base URL of the Velu backend that serves /api/v1/public/ai-assistant/* (e.g. \"https://api.getvelu.com\"). Must be same-site with the docs (or send a SameSite=None visitor cookie) for the credentialed requests to work."
254
+ },
255
+ "host": {
256
+ "type": "string",
257
+ "description": "Override the tenant-resolution host sent as X-Velu-Site-Host. Defaults to the page's own host at runtime."
258
+ },
259
+ "suggestions": {
260
+ "type": "array",
261
+ "items": { "type": "string" },
262
+ "maxItems": 6,
263
+ "description": "Starter questions shown when the Ask-AI panel opens. Unset on a Velu-hosted site → generated from the site's content at publish time."
264
+ }
265
+ }
266
+ }
267
+ },
268
+ "$defs": {
269
+ "navContainer": {
270
+ "type": "object",
271
+ "additionalProperties": false,
272
+ "description": "A navigation container. Higher-precedence keys nest the lower ones (products contain versions contain languages contain tabs contain groups/pages).",
273
+ "properties": {
274
+ "products": { "type": "array", "items": { "$ref": "#/$defs/product" } },
275
+ "versions": { "type": "array", "items": { "$ref": "#/$defs/version" } },
276
+ "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
277
+ "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
278
+ "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
279
+ "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
280
+ "pages": { "$ref": "#/$defs/pages" }
281
+ }
282
+ },
283
+ "pages": {
284
+ "type": "array",
285
+ "description": "Ordered list of page paths (no extension, relative to the project root) and/or nested groups.",
286
+ "items": {
287
+ "oneOf": [
288
+ { "type": "string" },
289
+ { "$ref": "#/$defs/group" }
290
+ ]
291
+ }
292
+ },
293
+ "group": {
294
+ "type": "object",
295
+ "additionalProperties": false,
296
+ "required": ["group"],
297
+ "properties": {
298
+ "group": { "type": "string", "description": "Sidebar section heading." },
299
+ "icon": { "type": "string", "description": "lucide icon id." },
300
+ "expanded": { "type": "boolean", "description": "Start expanded." },
301
+ "root": { "type": "string", "description": "Landing page path for the group." },
302
+ "openapi": { "$ref": "#/$defs/openapiRef" },
303
+ "api": { "$ref": "#/$defs/api" },
304
+ "pages": { "$ref": "#/$defs/pages" }
305
+ }
306
+ },
307
+ "tab": {
308
+ "type": "object",
309
+ "additionalProperties": false,
310
+ "required": ["tab"],
311
+ "properties": {
312
+ "tab": { "type": "string", "description": "Tab label (top nav)." },
313
+ "icon": { "type": "string" },
314
+ "href": { "type": "string", "description": "External/override link instead of in-site pages." },
315
+ "openapi": { "$ref": "#/$defs/openapiRef" },
316
+ "api": { "$ref": "#/$defs/api" },
317
+ "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
318
+ "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
319
+ "pages": { "$ref": "#/$defs/pages" }
320
+ }
321
+ },
322
+ "api": {
323
+ "type": "object",
324
+ "additionalProperties": false,
325
+ "description": "API reference behaviour for OpenAPI-generated pages. Set at the root, or on a tab/group with `openapi` to override it for just that section.",
326
+ "properties": {
327
+ "server": {
328
+ "type": "string",
329
+ "description": "Base URL override for the playground + code samples (otherwise the spec's first server is used)."
330
+ },
331
+ "playground": {
332
+ "type": "object",
333
+ "additionalProperties": false,
334
+ "properties": {
335
+ "display": {
336
+ "type": "string",
337
+ "enum": ["interactive", "simple", "none"],
338
+ "description": "Playground mode. \"none\" disables the proxy / live send."
339
+ },
340
+ "proxy": {
341
+ "type": "boolean",
342
+ "description": "Send Try-It requests through the dev proxy to avoid CORS (default true)."
343
+ }
344
+ }
345
+ },
346
+ "examples": {
347
+ "type": "object",
348
+ "additionalProperties": false,
349
+ "properties": {
350
+ "languages": {
351
+ "type": "array",
352
+ "items": { "type": "string", "enum": ["curl", "javascript", "python", "ruby"] },
353
+ "description": "Which request-snippet languages to generate."
354
+ }
355
+ }
356
+ }
357
+ }
358
+ },
359
+ "openapiRef": {
360
+ "description": "Path or URL to an OpenAPI spec (JSON/YAML), or an array of them. Auto-generates a page per operation, grouped by tag.",
361
+ "oneOf": [
362
+ { "type": "string" },
363
+ { "type": "array", "items": { "type": "string" } }
364
+ ]
365
+ },
366
+ "anchor": {
367
+ "type": "object",
368
+ "additionalProperties": false,
369
+ "required": ["anchor", "href"],
370
+ "properties": {
371
+ "anchor": { "type": "string", "description": "Anchor label (pinned sidebar link)." },
372
+ "icon": { "type": "string" },
373
+ "href": { "type": "string" },
374
+ "color": { "type": "string" }
375
+ }
376
+ },
377
+ "product": {
378
+ "type": "object",
379
+ "additionalProperties": false,
380
+ "required": ["product"],
381
+ "properties": {
382
+ "product": { "type": "string", "description": "Product id (used for the URL slug)." },
383
+ "name": { "type": "string", "description": "Display name; defaults to `product`." },
384
+ "icon": { "type": "string" },
385
+ "color": { "type": "string" },
386
+ "default": { "type": "boolean", "description": "The default product is unprefixed in URLs." },
387
+ "versions": { "type": "array", "items": { "$ref": "#/$defs/version" } },
388
+ "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
389
+ "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
390
+ "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
391
+ "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
392
+ "pages": { "$ref": "#/$defs/pages" }
393
+ }
394
+ },
395
+ "version": {
396
+ "type": "object",
397
+ "additionalProperties": false,
398
+ "required": ["version"],
399
+ "properties": {
400
+ "version": { "type": "string", "description": "Version label (used for the URL slug)." },
401
+ "default": { "type": "boolean", "description": "The default version is unprefixed in URLs." },
402
+ "languages": { "type": "array", "items": { "$ref": "#/$defs/language" } },
403
+ "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
404
+ "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
405
+ "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
406
+ "pages": { "$ref": "#/$defs/pages" }
407
+ }
408
+ },
409
+ "language": {
410
+ "type": "object",
411
+ "additionalProperties": false,
412
+ "required": ["language"],
413
+ "properties": {
414
+ "language": { "type": "string", "description": "Language code (used for the URL slug)." },
415
+ "default": { "type": "boolean", "description": "The default language is unprefixed in URLs." },
416
+ "tabs": { "type": "array", "items": { "$ref": "#/$defs/tab" } },
417
+ "anchors": { "type": "array", "items": { "$ref": "#/$defs/anchor" } },
418
+ "groups": { "type": "array", "items": { "$ref": "#/$defs/group" } },
419
+ "pages": { "$ref": "#/$defs/pages" }
420
+ }
421
+ }
422
+ }
423
+ }