zuplo 6.68.0 → 6.68.1

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.
@@ -0,0 +1,169 @@
1
+ ---
2
+ title: Set up your Zuplo project for AI coding agents
3
+ sidebar_label: AI Coding Agents
4
+ ---
5
+
6
+ Zuplo ships version-matched documentation inside the `zuplo` npm package,
7
+ allowing AI coding agents to reference accurate, up-to-date APIs and patterns.
8
+ An `AGENTS.md` file at the root of your project directs agents to these bundled
9
+ docs instead of their training data.
10
+
11
+ ## How it works
12
+
13
+ When you install `zuplo`, the full Zuplo documentation is bundled at
14
+ `node_modules/zuplo/docs/`. The bundled docs cover policies, handlers, concepts,
15
+ guides, CLI reference, and more:
16
+
17
+ ```txt
18
+ node_modules/zuplo/docs/
19
+ ├── concepts/ # Core concepts (request lifecycle, project structure)
20
+ ├── policies/ # Policy catalog, per-policy docs and JSON schemas
21
+ ├── handlers/ # Handler docs (URL forward, custom handler, etc.)
22
+ ├── articles/ # Guides (CORS, env vars, auth, deployment, etc.)
23
+ ├── cli/ # CLI reference
24
+ ├── dev-portal/ # Developer portal / Zudoku docs
25
+ ├── guides/ # Step-by-step guides
26
+ └── programmable-api/ # Programmable API reference
27
+ ```
28
+
29
+ This means agents always have access to docs that match your installed version
30
+ with no network request or external lookup required.
31
+
32
+ The `AGENTS.md` file at the root of your project tells agents to read these
33
+ bundled docs before writing any code. Most AI coding agents — including Claude
34
+ Code, Cursor, GitHub Copilot, Windsurf, and others — automatically read
35
+ `AGENTS.md` when they start a session.
36
+
37
+ ## Getting started
38
+
39
+ ### New projects
40
+
41
+ When you create a new project with `create-zuplo-api`, the `AGENTS.md` and
42
+ `CLAUDE.md` files are generated automatically. No additional setup is needed:
43
+
44
+ ```bash
45
+ npx create-zuplo-api@latest
46
+ ```
47
+
48
+ ### Existing projects
49
+
50
+ Ensure you are on `zuplo` version `0.66.0` or later, then add the following
51
+ files to the root of your project.
52
+
53
+ `AGENTS.md` contains the instructions that agents read:
54
+
55
+ ```md title="AGENTS.md"
56
+ # Zuplo: ALWAYS read docs before coding
57
+
58
+ Before any Zuplo work, find and read the relevant doc in
59
+ `node_modules/zuplo/docs/`. Your training data may be outdated — the bundled
60
+ docs are the source of truth.
61
+ ```
62
+
63
+ `CLAUDE.md` uses the `@` import syntax to include `AGENTS.md`, so
64
+ [Claude Code](https://docs.anthropic.com/en/docs/claude-code) users get the same
65
+ instructions without duplicating content:
66
+
67
+ ```md title="CLAUDE.md"
68
+ @AGENTS.md
69
+ ```
70
+
71
+ ## Understanding AGENTS.md
72
+
73
+ The default `AGENTS.md` contains a single, focused instruction: **read the
74
+ bundled docs before writing code**. This is intentionally minimal — the goal is
75
+ to redirect agents from stale training data to the accurate, version-matched
76
+ documentation in `node_modules/zuplo/docs/`.
77
+
78
+ The bundled docs include guides, API references, policy schemas, and handler
79
+ documentation. When an agent encounters a task involving routing, policies,
80
+ authentication, rate limiting, or any other Zuplo feature, it can look up the
81
+ correct configuration in the bundled docs rather than relying on potentially
82
+ outdated training data.
83
+
84
+ You can add your own project-specific instructions to `AGENTS.md` or `CLAUDE.md`
85
+ alongside the Zuplo defaults.
86
+
87
+ ## Install official skills
88
+
89
+ For a richer experience, install the official
90
+ [Zuplo agent skills](https://github.com/zuplo/tools). Skills provide
91
+ specialized, task-specific guidance that goes beyond general documentation
92
+ lookup — they teach agents how to set up projects, configure policies, write
93
+ handlers, set up monetization, and more.
94
+
95
+ ### What are agent skills?
96
+
97
+ [Agent skills](https://agentskills.io) are structured instruction files that AI
98
+ coding agents load automatically. Each skill focuses on a specific domain and
99
+ includes step-by-step guidance, code patterns, and references to documentation.
100
+
101
+ ### Available skills
102
+
103
+ | Skill | Description |
104
+ | ----------------------- | -------------------------------------------------------------------------------------------------------------------- |
105
+ | **zuplo-guide** | Comprehensive gateway guide — documentation lookup, request pipeline, route/policy configuration, custom handlers. |
106
+ | **zuplo-project-setup** | Step-by-step new project setup — scaffolding, routes, auth, rate limiting, CORS, env vars, deployment. |
107
+ | **zuplo-policies** | Policy configuration — built-in policy catalog, custom code policies, wiring policies to routes. |
108
+ | **zuplo-handlers** | Request handlers — URL forwarding/rewriting, redirects, custom TypeScript handlers, Lambda, WebSockets, MCP servers. |
109
+ | **zuplo-monetization** | API monetization — meters, plans, Stripe billing, subscriptions, usage tracking. |
110
+ | **zuplo-cli** | CLI reference — local dev, deployment, env vars, tunnels, OpenAPI tools, project management. |
111
+ | **zudoku-guide** | Comprehensive Zudoku framework guide — setup, configuration, OpenAPI integration, plugins, auth, theming. |
112
+
113
+ ### Install skills
114
+
115
+ Install the skills from GitHub:
116
+
117
+ ```bash
118
+ npx skills add zuplo/tools
119
+ ```
120
+
121
+ Or via `.well-known` discovery:
122
+
123
+ ```bash
124
+ npx skills add https://zuplo.com/
125
+ ```
126
+
127
+ After installation, agents automatically load the relevant skills when working
128
+ in your project.
129
+
130
+ ## Optional: Add the MCP server
131
+
132
+ For search and Q&A across all Zuplo documentation, you can also add the Zuplo
133
+ MCP server. This gives agents the ability to search docs and ask questions in
134
+ real-time.
135
+
136
+ For **Claude Code**, add to `.claude/settings.json`:
137
+
138
+ ```json title=".claude/settings.json"
139
+ {
140
+ "mcpServers": {
141
+ "zuplo-docs": {
142
+ "type": "http",
143
+ "url": "https://dev.zuplo.com/mcp/docs"
144
+ }
145
+ }
146
+ }
147
+ ```
148
+
149
+ :::tip
150
+
151
+ The MCP server is optional. The bundled docs in `node_modules/zuplo/docs/`
152
+ provide complete, version-matched documentation without any network requests.
153
+ The MCP server is useful for broader search and Q&A across all Zuplo
154
+ documentation.
155
+
156
+ :::
157
+
158
+ ## Summary
159
+
160
+ There are three ways to give AI coding agents access to Zuplo documentation,
161
+ listed in priority order:
162
+
163
+ 1. **Bundled docs** (recommended) — always available at
164
+ `node_modules/zuplo/docs/`, version-matched, no setup required beyond
165
+ `AGENTS.md`
166
+ 2. **Agent skills** — install from [zuplo/tools](https://github.com/zuplo/tools)
167
+ for task-specific guidance on project setup, policies, handlers,
168
+ monetization, and more
169
+ 3. **MCP server** — add the Zuplo docs MCP server for real-time search and Q&A
@@ -11,7 +11,8 @@ import { Book, Code, FileText } from "zudoku/icons";
11
11
 
12
12
  Dev Portal uses a single `navigation` array to control both the top navigation tabs and the sidebar.
13
13
  Items at the root of this array appear as tabs, and nested items build the sidebar tree. Navigation
14
- entries can be links, document references, categories or custom pages.
14
+ entries can be links, document references, categories, custom pages, separators, sections, or
15
+ filters.
15
16
 
16
17
  ## Basic configuration
17
18
 
@@ -45,7 +46,6 @@ one of several types. At the simplest level you may only have links and categori
45
46
  "to": "/api",
46
47
  "label": "API Reference",
47
48
  "icon": "code",
48
- "description": "Complete API documentation",
49
49
  "badge": {
50
50
  "label": "v2.0",
51
51
  "color": "blue"
@@ -58,13 +58,18 @@ one of several types. At the simplest level you may only have links and categori
58
58
 
59
59
  ## Navigation Items
60
60
 
61
- Navigation items can be of these types: `category`, `doc`, `link`, or `custom-page`.
61
+ Navigation items can be of these types: `category`, `doc`, `link`, `custom-page`, `separator`,
62
+ `section`, or `filter`.
62
63
 
63
64
  - `link`: A direct link to a page or external URL.
64
65
  - `category`: A group of links that can be expanded or collapsed.
65
- - `doc`: A reference to a document by it's file path: `file`.
66
- - `custom-pages`: A custom page that is made of a React component, see
66
+ - `doc`: A reference to a document by its file path: `file`.
67
+ - `custom-page`: A custom page that is made of a React component, see
67
68
  [Custom Pages](../guides/custom-pages.md)
69
+ - `separator`: A horizontal line to visually divide sidebar items.
70
+ - `section`: A non-interactive heading label to group sidebar items.
71
+ - `filter`: An inline search input that filters navigation items. Multiple filter inputs share the
72
+ same search query.
68
73
 
69
74
  ### `type: link`
70
75
 
@@ -87,10 +92,10 @@ type NavigationLink = {
87
92
  to: string;
88
93
  label: string;
89
94
  icon?: string; // Lucide icon name
90
- description?: string;
91
95
  badge?: {
92
96
  label: string;
93
97
  color: "green" | "blue" | "yellow" | "red" | "purple" | "indigo" | "gray" | "outline";
98
+ invert?: boolean;
94
99
  };
95
100
  display?:
96
101
  | "auth"
@@ -106,7 +111,8 @@ type NavigationLink = {
106
111
  ### `type: category`
107
112
 
108
113
  The `category` type groups related items under a collapsible section. The `label` is the displayed
109
- text, and the `items` array contains `id`s of documents, links, or other categories.
114
+ text, and the `items` array can contain any navigation item type (documents, links, categories,
115
+ custom pages, separators, sections, and filters).
110
116
 
111
117
  ```json
112
118
  {
@@ -131,11 +137,11 @@ text, and the `items` array contains `id`s of documents, links, or other categor
131
137
  type NavigationCategory = {
132
138
  type: "category";
133
139
  icon?: string; // Lucide icon name
134
- items: Array<NavigationDoc | NavigationLink | NavigationCategory | NavigationCustomPage>;
140
+ items: Array<NavigationItem>; // any navigation item type, including string shorthands for docs
135
141
  label: string;
136
142
  collapsible?: boolean;
137
143
  collapsed?: boolean;
138
- link?: string | { type: "doc"; file: string; label?: string };
144
+ link?: string | { type: "doc"; file: string; label?: string; path?: string };
139
145
  display?:
140
146
  | "auth"
141
147
  | "anon"
@@ -147,6 +153,50 @@ type NavigationCategory = {
147
153
 
148
154
  </details>
149
155
 
156
+ #### Category links
157
+
158
+ A category can have a `link` property that makes the category label itself clickable, navigating to
159
+ a document. This is useful when you want a category that acts as both a group and a landing page.
160
+
161
+ The `link` can be a simple string pointing to a file path, or an object for more control:
162
+
163
+ ```tsx title="String shorthand"
164
+ {
165
+ type: "category",
166
+ label: "Configuration",
167
+ link: "docs/configuration/overview",
168
+ items: [
169
+ "docs/configuration/navigation",
170
+ "docs/configuration/site",
171
+ ],
172
+ }
173
+ ```
174
+
175
+ ```tsx title="Object form with custom path"
176
+ {
177
+ type: "category",
178
+ label: "Documentation",
179
+ link: {
180
+ type: "doc",
181
+ file: "home.md",
182
+ path: "/",
183
+ },
184
+ items: [
185
+ "guides/getting-started",
186
+ "guides/advanced",
187
+ ],
188
+ }
189
+ ```
190
+
191
+ The object form supports these properties:
192
+
193
+ | Property | Type | Description |
194
+ | -------- | -------- | -------------------------------------------------------- |
195
+ | `type` | `"doc"` | Must be `"doc"` |
196
+ | `file` | `string` | Path to the markdown file |
197
+ | `label` | `string` | Override the label (defaults to the document title) |
198
+ | `path` | `string` | Custom URL path (overrides the default file-based route) |
199
+
150
200
  ### `type: doc`
151
201
 
152
202
  Doc is used to reference markdown files. The `label` is the text that will be displayed, and the
@@ -173,6 +223,7 @@ type NavigationDoc = {
173
223
  badge?: {
174
224
  label: string;
175
225
  color: "green" | "blue" | "yellow" | "red" | "purple" | "indigo" | "gray" | "outline";
226
+ invert?: boolean;
176
227
  };
177
228
  display?:
178
229
  | "auth"
@@ -223,6 +274,37 @@ Learn more in the [Markdown documentation](/dev-portal/zudoku/markdown/overview)
223
274
  The `path` property allows you to customize the URL path for a document. By default, Dev Portal uses the
224
275
  file path to generate the URL, but you can override this behavior by specifying a custom path.
225
276
 
277
+ ```tsx title="Serving a doc at the root URL"
278
+ {
279
+ type: "doc",
280
+ file: "home.md",
281
+ path: "/",
282
+ label: "Home",
283
+ }
284
+ ```
285
+
286
+ ```tsx title="Custom slug"
287
+ {
288
+ type: "doc",
289
+ file: "guides/getting-started.md",
290
+ path: "/start-here",
291
+ label: "Start Here",
292
+ }
293
+ ```
294
+
295
+ When a file has a custom path, it will only be accessible at that custom path, not at its original
296
+ file-based path. See [Documentation - Custom Paths](/dev-portal/zudoku/configuration/docs#custom-paths) for more
297
+ details.
298
+
299
+ :::note
300
+
301
+ Avoid naming files `index.md` or `index.mdx` and relying on their default path. Some hosting
302
+ providers (e.g. Vercel) automatically strip `/index` from URLs with a redirect, which can cause
303
+ routing issues. Instead, give files descriptive names and use the `path` property to serve them at
304
+ the desired URL.
305
+
306
+ :::
307
+
226
308
  ### `type: custom-page`
227
309
 
228
310
  Custom pages allow you to create standalone pages that are not tied to a Markdown document. This is
@@ -247,6 +329,7 @@ type NavigationCustomPage = {
247
329
  label?: string;
248
330
  element: any;
249
331
  icon?: string; // Lucide icon name
332
+ layout?: "default" | "none";
250
333
  badge?: {
251
334
  label: string;
252
335
  color: "green" | "blue" | "yellow" | "red" | "purple" | "indigo" | "gray" | "outline";
@@ -263,6 +346,120 @@ type NavigationCustomPage = {
263
346
 
264
347
  </details>
265
348
 
349
+ Set `layout: "none"` to render the page without the default Dev Portal layout (header, sidebar, footer).
350
+ This is useful for fully custom landing pages.
351
+
352
+ ### `type: separator`
353
+
354
+ A visual divider line in the sidebar. Use separators to create visual breaks between groups of
355
+ items.
356
+
357
+ ```tsx
358
+ {
359
+ type: "category",
360
+ label: "Documentation",
361
+ items: [
362
+ "guides/getting-started",
363
+ "guides/installation",
364
+ { type: "separator" },
365
+ "guides/advanced",
366
+ "guides/troubleshooting",
367
+ ],
368
+ }
369
+ ```
370
+
371
+ <details>
372
+ <summary>**TypeScript type declaration**</summary>
373
+
374
+ ```ts
375
+ type NavigationSeparator = {
376
+ type: "separator";
377
+ display?:
378
+ | "auth"
379
+ | "anon"
380
+ | "always"
381
+ | "hide"
382
+ | ((params: { context: ZudokuContext; auth: UseAuthReturn }) => boolean);
383
+ };
384
+ ```
385
+
386
+ </details>
387
+
388
+ ### `type: section`
389
+
390
+ A non-interactive heading label in the sidebar. Sections are rendered as small uppercase text and
391
+ are useful for labeling groups of items without adding a collapsible wrapper.
392
+
393
+ ```tsx
394
+ {
395
+ type: "category",
396
+ label: "Documentation",
397
+ items: [
398
+ { type: "section", label: "Getting Started" },
399
+ "guides/quickstart",
400
+ "guides/installation",
401
+ { type: "section", label: "Advanced" },
402
+ "guides/plugins",
403
+ "guides/deployment",
404
+ ],
405
+ }
406
+ ```
407
+
408
+ <details>
409
+ <summary>**TypeScript type declaration**</summary>
410
+
411
+ ```ts
412
+ type NavigationSection = {
413
+ type: "section";
414
+ label: string;
415
+ display?:
416
+ | "auth"
417
+ | "anon"
418
+ | "always"
419
+ | "hide"
420
+ | ((params: { context: ZudokuContext; auth: UseAuthReturn }) => boolean);
421
+ };
422
+ ```
423
+
424
+ </details>
425
+
426
+ ### `type: filter`
427
+
428
+ An inline search input that updates the shared navigation filter. When the user types, the query is
429
+ applied across the sidebar so that only matching items remain visible.
430
+
431
+ ```tsx
432
+ {
433
+ type: "category",
434
+ label: "Documentation",
435
+ items: [
436
+ { type: "filter", placeholder: "Filter documentation" },
437
+ "guides/getting-started",
438
+ "guides/installation",
439
+ "guides/authentication",
440
+ "guides/deployment",
441
+ ],
442
+ }
443
+ ```
444
+
445
+ <details>
446
+ <summary>**TypeScript type declaration**</summary>
447
+
448
+ ```ts
449
+ type NavigationFilter = {
450
+ type: "filter";
451
+ placeholder?: string;
452
+ display?:
453
+ | "auth"
454
+ | "anon"
455
+ | "always"
456
+ | "hide"
457
+ | ((params: { context: ZudokuContext; auth: UseAuthReturn }) => boolean);
458
+ };
459
+ ```
460
+
461
+ </details>
462
+
266
463
  ## Display Control
267
464
 
268
465
  All navigation items support a `display` property that controls when the item should be visible:
@@ -363,6 +560,94 @@ sidebar_label: Short Title
363
560
  In this example, the document's title remains "My Long Title," but the sidebar displays "Short
364
561
  Title."
365
562
 
563
+ For the complete list of supported frontmatter properties, see
564
+ [Frontmatter](/dev-portal/zudoku/markdown/frontmatter).
565
+
566
+ ## Common Patterns
567
+
568
+ ### Serving a document at the root URL
569
+
570
+ To make a markdown document accessible at `/`, use the `path` property to override the default
571
+ file-based route:
572
+
573
+ ```tsx title="Standalone root doc"
574
+ navigation: [
575
+ {
576
+ type: "doc",
577
+ file: "home.md",
578
+ path: "/",
579
+ label: "Home",
580
+ },
581
+ ],
582
+ ```
583
+
584
+ ```tsx title="Category with root landing page"
585
+ navigation: [
586
+ {
587
+ type: "category",
588
+ label: "Documentation",
589
+ link: {
590
+ type: "doc",
591
+ file: "home.md",
592
+ path: "/",
593
+ },
594
+ items: [
595
+ "guides/getting-started",
596
+ "guides/installation",
597
+ ],
598
+ },
599
+ ],
600
+ ```
601
+
602
+ ### Landing page with hidden tab
603
+
604
+ Use a `custom-page` with `display: "hide"` and `layout: "none"` to create a full-page landing
605
+ experience that doesn't appear in the navigation tabs:
606
+
607
+ ```tsx
608
+ navigation: [
609
+ {
610
+ type: "custom-page",
611
+ path: "/",
612
+ display: "hide",
613
+ layout: "none",
614
+ element: <LandingPage />,
615
+ },
616
+ {
617
+ type: "category",
618
+ label: "Documentation",
619
+ items: ["docs/quickstart", "docs/installation"],
620
+ },
621
+ ],
622
+ ```
623
+
624
+ ### Organized sidebar with sections and separators
625
+
626
+ Combine `section`, `separator`, and `filter` items to create a well-structured sidebar:
627
+
628
+ ```tsx
629
+ navigation: [
630
+ {
631
+ type: "category",
632
+ label: "Documentation",
633
+ items: [
634
+ { type: "filter", placeholder: "Filter documentation" },
635
+ { type: "section", label: "Getting Started" },
636
+ "guides/quickstart",
637
+ "guides/installation",
638
+ { type: "separator" },
639
+ { type: "section", label: "Advanced" },
640
+ {
641
+ type: "category",
642
+ label: "Plugins",
643
+ icon: "blocks",
644
+ items: ["plugins/overview", "plugins/custom"],
645
+ },
646
+ ],
647
+ },
648
+ ],
649
+ ```
650
+
366
651
  ## Navigation Rules
367
652
 
368
653
  Plugins generate sidebar navigation automatically (e.g. from OpenAPI tags). Navigation rules let you
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuplo",
3
- "version": "6.68.0",
3
+ "version": "6.68.1",
4
4
  "type": "module",
5
5
  "description": "The programmable API Gateway",
6
6
  "author": "Zuplo, Inc.",
@@ -19,9 +19,9 @@
19
19
  "zuplo": "zuplo.js"
20
20
  },
21
21
  "dependencies": {
22
- "@zuplo/cli": "6.68.0",
23
- "@zuplo/core": "6.68.0",
24
- "@zuplo/runtime": "6.68.0",
22
+ "@zuplo/cli": "6.68.1",
23
+ "@zuplo/core": "6.68.1",
24
+ "@zuplo/runtime": "6.68.1",
25
25
  "@zuplo/test": "1.4.0"
26
26
  }
27
27
  }