Skip to content

Commit 580e11a

Browse files
committed
feat(mintlify): add Mintlify integration
Adds all 18 documented Mintlify REST API endpoints across deployment, automation, agent jobs, prose detection, docs search/assistant, and analytics export.
1 parent 9883543 commit 580e11a

35 files changed

Lines changed: 4593 additions & 3 deletions

apps/docs/components/icons.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,6 +2494,25 @@ export function DocumentIcon(props: SVGProps<SVGSVGElement>) {
24942494
)
24952495
}
24962496

2497+
export function MintlifyIcon(props: SVGProps<SVGSVGElement>) {
2498+
return (
2499+
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 19 19' fill='none'>
2500+
<path
2501+
d='M18.367 7.28888V1.59755C18.367 0.986819 17.8715 0.5 17.2699 0.5H11.5812C10.6877 0.5 9.80295 0.677018 8.98017 1.01336C8.15738 1.35856 7.40539 1.85424 6.77724 2.49152L6.733 2.53578C5.90137 3.37664 5.30862 4.42108 5.00781 5.57174C5.54749 5.43012 6.10483 5.35931 6.6622 5.35046C8.14852 5.33276 9.60831 5.81073 10.7938 6.7047C11.8643 7.50131 12.6783 8.59885 13.1206 9.86458C13.5807 11.148 13.6337 12.5465 13.2887 13.8653C14.43 13.5644 15.4828 12.9714 16.3233 12.1393L16.3675 12.0951C16.9957 11.4667 17.4999 10.7143 17.845 9.89114C18.19 9.06797 18.3581 8.18285 18.3581 7.28888H18.367Z'
2502+
fill='#18E299'
2503+
/>
2504+
<path
2505+
d='M4.83793 7.193C4.84674 5.44706 5.54303 3.77167 6.76814 2.51953L2.03511 7.25472C2.01749 7.27236 1.99985 7.28117 1.98222 7.29881C0.827615 8.44513 0.131342 9.97945 0.0167623 11.6019C-0.0890033 13.1186 0.307609 14.6176 1.15373 15.8698C1.23444 15.9892 1.45343 16.0285 1.57682 15.9139L4.47656 13.0216C5.38438 12.1134 5.66643 10.7642 5.23455 9.55618C4.96132 8.80666 4.82912 8.00424 4.83793 7.193Z'
2506+
fill='#0C8C5E'
2507+
/>
2508+
<path
2509+
d='M16.341 12.0938C15.4332 12.9844 14.2962 13.6016 13.0623 13.875C11.8195 14.1483 10.5327 14.0689 9.33405 13.6457C9.33405 13.6457 9.32522 13.6457 9.31641 13.6457C8.10892 13.2136 6.76042 13.4958 5.8526 14.3952L2.95282 17.2875C2.82943 17.4109 2.84706 17.6137 2.99689 17.7107C4.24845 18.5484 5.74683 18.954 7.26281 18.8482C8.88455 18.7336 10.4093 18.037 11.5639 16.8818L11.608 16.8378L16.341 12.1026V12.0938Z'
2510+
fill='#0C8C5E'
2511+
/>
2512+
</svg>
2513+
)
2514+
}
2515+
24972516
export function MistralIcon(props: SVGProps<SVGSVGElement>) {
24982517
const id = useId()
24992518
const clipId = `mistral_clip_${id}`

apps/docs/components/ui/icon-mapping.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ import {
149149
MicrosoftSharepointIcon,
150150
MicrosoftTeamsIcon,
151151
MillionVerifierIcon,
152+
MintlifyIcon,
152153
MistralIcon,
153154
MondayIcon,
154155
MongoDBIcon,
@@ -428,6 +429,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
428429
microsoft_teams: MicrosoftTeamsIcon,
429430
'microsoft-teams': MicrosoftTeamsIcon,
430431
millionverifier: MillionVerifierIcon,
432+
mintlify: MintlifyIcon,
431433
mistral_parse: MistralIcon,
432434
mistral_parse_v2: MistralIcon,
433435
mistral_parse_v3: MistralIcon,

apps/docs/content/docs/en/integrations/meta.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@
157157
"microsoft_planner",
158158
"microsoft_teams",
159159
"millionverifier",
160+
"mintlify",
160161
"mistral_parse",
161162
"monday",
162163
"monday-service-account",

apps/docs/content/docs/en/integrations/mintlify.mdx

Lines changed: 654 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { describe, expect, it } from 'vitest'
5+
import { MintlifyBlock } from './mintlify'
6+
7+
/**
8+
* The executor merges `tools.config.params` on top of the raw inputs, so every
9+
* assertion runs against the merged result rather than the transform's return
10+
* value alone.
11+
*/
12+
function resolveParams(inputs: Record<string, unknown>) {
13+
return { ...inputs, ...MintlifyBlock.tools.config.params!(inputs) }
14+
}
15+
16+
describe('MintlifyBlock', () => {
17+
describe('tool selection', () => {
18+
it('maps every operation option to a registered tool ID', () => {
19+
const operationSubBlock = MintlifyBlock.subBlocks.find((block) => block.id === 'operation')
20+
const operations = operationSubBlock?.options as { id: string }[]
21+
22+
expect(operations.length).toBeGreaterThan(0)
23+
for (const { id } of operations) {
24+
const toolId = MintlifyBlock.tools.config!.tool!({ operation: id })
25+
expect(MintlifyBlock.tools.access).toContain(toolId)
26+
}
27+
})
28+
29+
it('exposes one operation option per accessible tool', () => {
30+
const operationSubBlock = MintlifyBlock.subBlocks.find((block) => block.id === 'operation')
31+
const operations = operationSubBlock?.options as { id: string }[]
32+
expect(operations).toHaveLength(MintlifyBlock.tools.access!.length)
33+
})
34+
})
35+
36+
describe('operation scoping', () => {
37+
it('clears advanced values retained from another operation', () => {
38+
const result = resolveParams({
39+
operation: 'get_feedback',
40+
projectId: 'proj_1',
41+
// Retained from a prior Get Page Views selection, whose limit ceiling is 250.
42+
offset: '100',
43+
limit: '200',
44+
})
45+
46+
expect(result.offset).toBeUndefined()
47+
expect(result.limit).toBe(200)
48+
})
49+
50+
it('clears a retained search filter when an analytics operation runs', () => {
51+
const result = resolveParams({
52+
operation: 'get_views',
53+
projectId: 'proj_1',
54+
query: 'stale query',
55+
groups: '["internal"]',
56+
tag: 'api-reference',
57+
})
58+
59+
expect(result.query).toBeUndefined()
60+
expect(result.groups).toBeUndefined()
61+
expect(result.tag).toBeUndefined()
62+
})
63+
64+
it('leaves the model arguments untouched on the agent-tool path', () => {
65+
const agentArgs = { projectId: 'proj_1', limit: 25 }
66+
expect(resolveParams(agentArgs)).toEqual(agentArgs)
67+
})
68+
})
69+
70+
describe('param aliasing', () => {
71+
it('forwards the prose-check path under the tool param name', () => {
72+
const result = resolveParams({
73+
operation: 'detect_ai_prose',
74+
projectId: 'proj_1',
75+
deslopPath: 'guides/quickstart.mdx',
76+
content: '# Quickstart',
77+
})
78+
79+
expect(result.path).toBe('guides/quickstart.mdx')
80+
})
81+
82+
it('forwards the page-content path under the tool param name', () => {
83+
const result = resolveParams({
84+
operation: 'get_page_content',
85+
domain: 'acme',
86+
pagePath: 'guides/quickstart',
87+
})
88+
89+
expect(result.path).toBe('guides/quickstart')
90+
})
91+
92+
it('forwards the feedback filters under their tool param names', () => {
93+
const result = resolveParams({
94+
operation: 'get_feedback',
95+
projectId: 'proj_1',
96+
feedbackSource: 'contextual',
97+
feedbackStatus: 'pending,resolved',
98+
})
99+
100+
expect(result.source).toBe('contextual')
101+
expect(result.status).toBe('pending,resolved')
102+
})
103+
})
104+
105+
describe('numeric coercion', () => {
106+
it('coerces numeric inputs delivered as strings', () => {
107+
const result = resolveParams({
108+
operation: 'search',
109+
domain: 'acme',
110+
query: 'custom domains',
111+
pageSize: '25',
112+
scoreThreshold: '0.4',
113+
})
114+
115+
expect(result.pageSize).toBe(25)
116+
expect(result.scoreThreshold).toBe(0.4)
117+
})
118+
119+
it('drops a numeric input that cannot be parsed', () => {
120+
const result = resolveParams({
121+
operation: 'get_views',
122+
projectId: 'proj_1',
123+
limit: 'not-a-number',
124+
})
125+
126+
expect(result.limit).toBeUndefined()
127+
})
128+
129+
it('drops empty optional values', () => {
130+
const result = resolveParams({
131+
operation: 'get_searches',
132+
projectId: 'proj_1',
133+
dateFrom: '',
134+
cursor: '',
135+
})
136+
137+
expect(result.dateFrom).toBeUndefined()
138+
expect(result.cursor).toBeUndefined()
139+
})
140+
})
141+
})

0 commit comments

Comments
 (0)