@mintlify/cli 4.0.1812 → 4.1.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.
Files changed (274) hide show
  1. package/dist/assets/export-scripts/README.classic.md +15 -0
  2. package/dist/assets/export-scripts/README.md +14 -0
  3. package/dist/assets/export-scripts/serve.js +114 -0
  4. package/dist/assets/export-scripts/start-docs.bat +10 -0
  5. package/dist/assets/export-scripts/start-docs.sh +9 -0
  6. package/dist/assets/og/Inter-Bold.ttf +0 -0
  7. package/dist/assets/og/Inter-Medium.ttf +0 -0
  8. package/dist/assets/og/Inter-Regular.ttf +0 -0
  9. package/dist/assets/og/Inter-SemiBold.ttf +0 -0
  10. package/dist/assets/og/PaperMono-Regular.ttf +0 -0
  11. package/dist/assets/og/index_bg.wasm +0 -0
  12. package/dist/assets/openChrome.applescript +94 -0
  13. package/dist/assets/socket.io/socket.io.esm.min.js +7 -0
  14. package/dist/assets/socket.io/socket.io.esm.min.js.map +1 -0
  15. package/dist/assets/socket.io/socket.io.js +4907 -0
  16. package/dist/assets/socket.io/socket.io.js.map +1 -0
  17. package/dist/assets/socket.io/socket.io.min.js +7 -0
  18. package/dist/assets/socket.io/socket.io.min.js.map +1 -0
  19. package/dist/assets/socket.io/socket.io.msgpack.min.js +7 -0
  20. package/dist/assets/socket.io/socket.io.msgpack.min.js.map +1 -0
  21. package/dist/assets/xdg-open +1066 -0
  22. package/dist/assets/yargs-locales/be.json +46 -0
  23. package/dist/assets/yargs-locales/cs.json +51 -0
  24. package/dist/assets/yargs-locales/de.json +46 -0
  25. package/dist/assets/yargs-locales/en.json +55 -0
  26. package/dist/assets/yargs-locales/es.json +46 -0
  27. package/dist/assets/yargs-locales/fi.json +49 -0
  28. package/dist/assets/yargs-locales/fr.json +53 -0
  29. package/dist/assets/yargs-locales/hi.json +49 -0
  30. package/dist/assets/yargs-locales/hu.json +46 -0
  31. package/dist/assets/yargs-locales/id.json +50 -0
  32. package/dist/assets/yargs-locales/it.json +46 -0
  33. package/dist/assets/yargs-locales/ja.json +51 -0
  34. package/dist/assets/yargs-locales/ko.json +49 -0
  35. package/dist/assets/yargs-locales/nb.json +44 -0
  36. package/dist/assets/yargs-locales/nl.json +49 -0
  37. package/dist/assets/yargs-locales/nn.json +44 -0
  38. package/dist/assets/yargs-locales/pirate.json +13 -0
  39. package/dist/assets/yargs-locales/pl.json +49 -0
  40. package/dist/assets/yargs-locales/pt.json +45 -0
  41. package/dist/assets/yargs-locales/pt_BR.json +48 -0
  42. package/dist/assets/yargs-locales/ru.json +51 -0
  43. package/dist/assets/yargs-locales/th.json +46 -0
  44. package/dist/assets/yargs-locales/tr.json +48 -0
  45. package/dist/assets/yargs-locales/uk_UA.json +51 -0
  46. package/dist/assets/yargs-locales/uz.json +52 -0
  47. package/dist/assets/yargs-locales/zh_CN.json +48 -0
  48. package/dist/assets/yargs-locales/zh_TW.json +51 -0
  49. package/dist/converter-d8O3xkdU.js +102 -0
  50. package/dist/devtools-CGNZQKFV.js +24 -0
  51. package/dist/index.js +8 -0
  52. package/dist/rolldown-runtime-CEAe2Uac.js +7 -0
  53. package/dist/schemas-CBsmCNpK.js +372 -0
  54. package/dist/start.js +2310 -0
  55. package/package.json +43 -36
  56. package/.oxlintrc.json +0 -5
  57. package/.prettierignore +0 -2
  58. package/.turbo/turbo-build.log +0 -1
  59. package/CONTRIBUTING.md +0 -45
  60. package/__test__/agent-auth.test.ts +0 -114
  61. package/__test__/agent-claim.test.ts +0 -164
  62. package/__test__/agent-credentials.test.ts +0 -149
  63. package/__test__/agent-deployment.test.ts +0 -106
  64. package/__test__/agent-setup-config.test.ts +0 -324
  65. package/__test__/agent-setup.test.ts +0 -207
  66. package/__test__/agent.test.ts +0 -64
  67. package/__test__/analytics/client.test.ts +0 -180
  68. package/__test__/analytics/dates.test.ts +0 -12
  69. package/__test__/analytics/filters.test.ts +0 -116
  70. package/__test__/analytics/format.test.ts +0 -137
  71. package/__test__/authenticatedFetch.test.ts +0 -182
  72. package/__test__/brokenLinks.test.ts +0 -283
  73. package/__test__/checkPort.test.ts +0 -92
  74. package/__test__/deploy-github-actions.test.ts +0 -202
  75. package/__test__/deploy-github-setup.test.ts +0 -240
  76. package/__test__/deploy-instructions.test.ts +0 -155
  77. package/__test__/deploy.test.ts +0 -202
  78. package/__test__/feedback.test.ts +0 -34
  79. package/__test__/foreignSyntax.test.ts +0 -73
  80. package/__test__/format.test.ts +0 -72
  81. package/__test__/helpers.test.ts +0 -52
  82. package/__test__/init.test.ts +0 -119
  83. package/__test__/instructions.test.ts +0 -53
  84. package/__test__/keyring.test.ts +0 -82
  85. package/__test__/mdxAccessibility.test.ts +0 -81
  86. package/__test__/migrate.test.ts +0 -186
  87. package/__test__/openApiCheck.test.ts +0 -185
  88. package/__test__/pathValidation.test.ts +0 -25
  89. package/__test__/resolveFiles.test.ts +0 -70
  90. package/__test__/sessionId.test.ts +0 -46
  91. package/__test__/signup.test.ts +0 -36
  92. package/__test__/update.test.ts +0 -117
  93. package/__test__/utils.ts +0 -25
  94. package/__test__/validateCommand.test.ts +0 -647
  95. package/__test__/validateEngine.test.ts +0 -245
  96. package/__test__/validateRules.test.ts +0 -1275
  97. package/__test__/welcome.test.ts +0 -15
  98. package/__test__/workflows/client.test.ts +0 -126
  99. package/bin/accessibility.js +0 -111
  100. package/bin/accessibilityCheck.js +0 -82
  101. package/bin/addDomain.js +0 -130
  102. package/bin/agent-auth.js +0 -104
  103. package/bin/agent-claim.js +0 -97
  104. package/bin/agent-credentials.js +0 -124
  105. package/bin/agent-deployment.js +0 -96
  106. package/bin/agent-http.js +0 -45
  107. package/bin/agent-setup-config.js +0 -141
  108. package/bin/agent-setup.js +0 -146
  109. package/bin/agent.js +0 -42
  110. package/bin/analytics/client.js +0 -60
  111. package/bin/analytics/dates.js +0 -6
  112. package/bin/analytics/filters.js +0 -27
  113. package/bin/analytics/format.js +0 -13
  114. package/bin/analytics/index.js +0 -496
  115. package/bin/analytics/output.js +0 -75
  116. package/bin/analytics/types.js +0 -1
  117. package/bin/authenticatedFetch.js +0 -46
  118. package/bin/brokenLinks.js +0 -122
  119. package/bin/callbackServer.js +0 -65
  120. package/bin/cli.js +0 -813
  121. package/bin/comingSoon.js +0 -26
  122. package/bin/config.js +0 -78
  123. package/bin/constants.js +0 -16
  124. package/bin/deploy-base.js +0 -20
  125. package/bin/deploy-github-actions.js +0 -102
  126. package/bin/deploy-github-setup.js +0 -165
  127. package/bin/deploy-instructions.js +0 -71
  128. package/bin/deploy.js +0 -123
  129. package/bin/feedback.js +0 -36
  130. package/bin/format.js +0 -121
  131. package/bin/helpers.js +0 -238
  132. package/bin/idToken.js +0 -14
  133. package/bin/index.js +0 -102
  134. package/bin/init.js +0 -182
  135. package/bin/instructions.js +0 -101
  136. package/bin/keyring.js +0 -78
  137. package/bin/login.js +0 -123
  138. package/bin/logout.js +0 -18
  139. package/bin/mdxAccessibility.js +0 -113
  140. package/bin/mdxLinter.js +0 -55
  141. package/bin/middlewares/subdomainMiddleware.js +0 -28
  142. package/bin/middlewares/telemetryMiddleware.js +0 -61
  143. package/bin/migrate.js +0 -54
  144. package/bin/og.js +0 -145
  145. package/bin/openApiCheck.js +0 -99
  146. package/bin/resolveFiles.js +0 -114
  147. package/bin/score/client.js +0 -40
  148. package/bin/score/index.js +0 -211
  149. package/bin/score/types.js +0 -1
  150. package/bin/signup.js +0 -118
  151. package/bin/start.js +0 -36
  152. package/bin/status.js +0 -106
  153. package/bin/telemetry/client.js +0 -53
  154. package/bin/telemetry/distinctId.js +0 -68
  155. package/bin/telemetry/sessionId.js +0 -36
  156. package/bin/telemetry/track.js +0 -149
  157. package/bin/templates.js +0 -127
  158. package/bin/tokenRefresh.js +0 -50
  159. package/bin/tsconfig.build.tsbuildinfo +0 -1
  160. package/bin/update.js +0 -65
  161. package/bin/validate/command.js +0 -127
  162. package/bin/validate/engine.js +0 -154
  163. package/bin/validate/files.js +0 -163
  164. package/bin/validate/mdx.js +0 -238
  165. package/bin/validate/output.js +0 -44
  166. package/bin/validate/report.js +0 -11
  167. package/bin/validate/rules/build.js +0 -102
  168. package/bin/validate/rules/content/duplicateH1.js +0 -57
  169. package/bin/validate/rules/content/foreignSyntax.js +0 -120
  170. package/bin/validate/rules/content/katex.js +0 -34
  171. package/bin/validate/rules/content/missingSnippet.js +0 -34
  172. package/bin/validate/rules/content/undefinedVariable.js +0 -13
  173. package/bin/validate/rules/content/unknownComponent.js +0 -121
  174. package/bin/validate/rules/content/voidTags.js +0 -38
  175. package/bin/validate/rules/index.js +0 -21
  176. package/bin/validate/rules/openapi.js +0 -50
  177. package/bin/validate/rules/parseError.js +0 -7
  178. package/bin/validate/site.js +0 -57
  179. package/bin/validate/types.js +0 -1
  180. package/bin/vendor/converter.js +0 -30882
  181. package/bin/welcome.js +0 -108
  182. package/bin/workflows/client.js +0 -34
  183. package/bin/workflows/index.js +0 -269
  184. package/bin/workflows/types.js +0 -11
  185. package/scripts/bundle-converter.mjs +0 -26
  186. package/scripts/generate-logo.mjs +0 -79
  187. package/src/accessibility.ts +0 -180
  188. package/src/accessibilityCheck.tsx +0 -150
  189. package/src/addDomain.tsx +0 -206
  190. package/src/agent-auth.ts +0 -119
  191. package/src/agent-claim.ts +0 -124
  192. package/src/agent-credentials.ts +0 -104
  193. package/src/agent-deployment.ts +0 -116
  194. package/src/agent-http.ts +0 -34
  195. package/src/agent-setup-config.ts +0 -144
  196. package/src/agent-setup.ts +0 -165
  197. package/src/agent.ts +0 -56
  198. package/src/analytics/client.ts +0 -153
  199. package/src/analytics/dates.ts +0 -6
  200. package/src/analytics/filters.ts +0 -50
  201. package/src/analytics/format.ts +0 -13
  202. package/src/analytics/index.tsx +0 -599
  203. package/src/analytics/output.ts +0 -99
  204. package/src/analytics/types.ts +0 -145
  205. package/src/authenticatedFetch.ts +0 -42
  206. package/src/brokenLinks.tsx +0 -152
  207. package/src/callbackServer.ts +0 -64
  208. package/src/cli.tsx +0 -1105
  209. package/src/comingSoon.tsx +0 -29
  210. package/src/config.ts +0 -75
  211. package/src/constants.ts +0 -28
  212. package/src/deploy-base.ts +0 -18
  213. package/src/deploy-github-actions.ts +0 -139
  214. package/src/deploy-github-setup.ts +0 -189
  215. package/src/deploy-instructions.ts +0 -76
  216. package/src/deploy.ts +0 -165
  217. package/src/feedback.tsx +0 -31
  218. package/src/format.tsx +0 -82
  219. package/src/helpers.tsx +0 -279
  220. package/src/idToken.ts +0 -17
  221. package/src/index.ts +0 -109
  222. package/src/init.tsx +0 -237
  223. package/src/instructions.ts +0 -99
  224. package/src/keyring.ts +0 -65
  225. package/src/login.tsx +0 -166
  226. package/src/logout.tsx +0 -8
  227. package/src/mdxAccessibility.ts +0 -134
  228. package/src/mdxLinter.tsx +0 -88
  229. package/src/middlewares/subdomainMiddleware.ts +0 -20
  230. package/src/middlewares/telemetryMiddleware.ts +0 -55
  231. package/src/migrate.ts +0 -76
  232. package/src/og.tsx +0 -185
  233. package/src/openApiCheck.tsx +0 -125
  234. package/src/resolveFiles.ts +0 -101
  235. package/src/score/client.ts +0 -36
  236. package/src/score/index.tsx +0 -205
  237. package/src/score/types.ts +0 -15
  238. package/src/signup.tsx +0 -172
  239. package/src/start.ts +0 -27
  240. package/src/status.tsx +0 -129
  241. package/src/telemetry/client.ts +0 -46
  242. package/src/telemetry/distinctId.ts +0 -70
  243. package/src/telemetry/sessionId.ts +0 -40
  244. package/src/telemetry/track.ts +0 -163
  245. package/src/templates.tsx +0 -143
  246. package/src/tokenRefresh.ts +0 -53
  247. package/src/update.tsx +0 -89
  248. package/src/validate/command.tsx +0 -135
  249. package/src/validate/engine.ts +0 -210
  250. package/src/validate/files.ts +0 -249
  251. package/src/validate/mdx.ts +0 -290
  252. package/src/validate/output.tsx +0 -76
  253. package/src/validate/report.ts +0 -40
  254. package/src/validate/rules/build.ts +0 -146
  255. package/src/validate/rules/content/duplicateH1.ts +0 -78
  256. package/src/validate/rules/content/foreignSyntax.ts +0 -144
  257. package/src/validate/rules/content/katex.ts +0 -33
  258. package/src/validate/rules/content/missingSnippet.ts +0 -36
  259. package/src/validate/rules/content/undefinedVariable.ts +0 -20
  260. package/src/validate/rules/content/unknownComponent.ts +0 -130
  261. package/src/validate/rules/content/voidTags.ts +0 -43
  262. package/src/validate/rules/index.ts +0 -23
  263. package/src/validate/rules/openapi.ts +0 -59
  264. package/src/validate/rules/parseError.ts +0 -9
  265. package/src/validate/site.ts +0 -53
  266. package/src/validate/types.ts +0 -102
  267. package/src/vendor/converter.ts +0 -1
  268. package/src/welcome.ts +0 -154
  269. package/src/workflows/client.ts +0 -39
  270. package/src/workflows/index.tsx +0 -287
  271. package/src/workflows/types.ts +0 -73
  272. package/tsconfig.build.json +0 -4
  273. package/tsconfig.json +0 -10
  274. package/vitest.config.ts +0 -9
package/src/init.tsx DELETED
@@ -1,237 +0,0 @@
1
- import { select, input } from '@inquirer/prompts';
2
- import { addLogs, addLog, SpinnerLog, removeLastLog } from '@mintlify/previewing';
3
- import { docsConfigSchema, validatePathWithinCwd } from '@mintlify/validation';
4
- import AdmZip from 'adm-zip';
5
- import fse from 'fs-extra';
6
- import { Box, Text } from 'ink';
7
-
8
- import { isAI } from './helpers.js';
9
- import {
10
- fetchAvailableTemplates,
11
- installFromTemplate,
12
- promptForTemplate,
13
- validateTemplateName,
14
- } from './templates.js';
15
-
16
- const sendOnboardingMessage = (installDir: string) => {
17
- addLogs(
18
- <Text bold>Documentation Setup!</Text>,
19
- <Text>To see your docs run</Text>,
20
- <Box>
21
- <Text color="blue">cd</Text>
22
- <Text> {installDir}</Text>
23
- </Box>,
24
- <Text color="blue">mint dev</Text>
25
- );
26
- if (isAI()) {
27
- addLog(
28
- <Text>
29
- When the docs are ready, run `mint validate` in {installDir} to check the build and get
30
- publish steps.
31
- </Text>
32
- );
33
- }
34
- };
35
-
36
- const sendUsageMessageForAI = (
37
- directory: string,
38
- contentsOccupied: boolean,
39
- themes: string[],
40
- templateNames?: string[]
41
- ) => {
42
- const templateInfo =
43
- templateNames === undefined
44
- ? 'Unable to fetch templates — use --template flag if you know the name'
45
- : templateNames.length > 0
46
- ? `Templates: ${JSON.stringify(templateNames)}`
47
- : 'No templates are currently available';
48
-
49
- addLogs(
50
- <Text>Agent Detected - sending AI friendly prompt</Text>,
51
- <Text>{'<system-message>'}</Text>,
52
- <Text>
53
- Help the user set up a Mintlify docs site with `mint new`. Ask each step one at a time unless
54
- the user asks you to skip questions or use your best judgment.
55
- </Text>,
56
- <Text>
57
- {[
58
- `- [ ] Pick a theme or clone a template? (${templateInfo})`,
59
- `- [ ] If template: which one? If theme: which one? (Themes: ${JSON.stringify(themes)})`,
60
- '- [ ] Project name?',
61
- `- [ ] Directory? (default: "${directory}", auto-created if needed)${contentsOccupied ? ` ⚠️ "${directory}" is occupied — subdirectory, overwrite (--force), or different path?` : ''}`,
62
- ].join('\n')}
63
- </Text>,
64
- <Text>
65
- Command: `mint new [dir] --theme [theme] --name [name]` or `mint new [dir] --template
66
- [template] --name [name]`. --theme optionally overrides a template default. --force overwrites
67
- non-empty dirs. Use AskQuestion to present choices.
68
- </Text>,
69
- <Text>{'</system-message>'}</Text>
70
- );
71
- };
72
-
73
- async function sendAIUsageMessage(directory: string, contentsOccupied: boolean, themes: string[]) {
74
- const templateNames = await fetchAvailableTemplates().catch(() => undefined);
75
- sendUsageMessageForAI(directory, contentsOccupied, themes, templateNames);
76
- }
77
-
78
- async function resolveInstallDir(
79
- installDir: string,
80
- force: boolean,
81
- contentsOccupied: boolean
82
- ): Promise<string | undefined> {
83
- if (!contentsOccupied) return installDir;
84
-
85
- if (isAI()) {
86
- if (force) return installDir;
87
- return undefined;
88
- }
89
-
90
- const choice = await select({
91
- message: `Directory ${installDir} is not empty. What would you like to do?`,
92
- choices: [
93
- { name: 'Create in a subdirectory', value: 'subdir' as const },
94
- { name: 'Overwrite current directory (may lose contents)', value: 'overwrite' as const },
95
- { name: 'Cancel', value: 'cancel' as const },
96
- ],
97
- });
98
-
99
- if (choice === 'cancel') return undefined;
100
-
101
- if (choice === 'subdir') {
102
- const subdir = await input({
103
- message: 'Subdirectory name:',
104
- default: 'docs',
105
- });
106
- if (!subdir || subdir.trim() === '') {
107
- throw new Error('Subdirectory name cannot be empty');
108
- }
109
- const resolved = installDir === '.' ? subdir : `${installDir}/${subdir}`;
110
- validatePathWithinCwd(resolved, process.cwd());
111
- return resolved;
112
- }
113
-
114
- return installDir;
115
- }
116
-
117
- async function promptForProjectName(installDir: string, currentName?: string): Promise<string> {
118
- if (currentName) return currentName;
119
- const defaultProject = installDir === '.' ? 'Mintlify' : installDir;
120
- return input({ message: 'Project Name', default: defaultProject });
121
- }
122
-
123
- async function promptForApproach(): Promise<string | undefined> {
124
- const approach = await select({
125
- message: 'How would you like to set up your docs?',
126
- choices: [
127
- { name: 'Pick a theme', value: 'theme' as const },
128
- { name: 'Clone a template', value: 'template' as const },
129
- ],
130
- });
131
-
132
- if (approach === 'template') return promptForTemplate();
133
- return undefined;
134
- }
135
-
136
- export async function init(
137
- installDir: string,
138
- force: boolean,
139
- theme?: string,
140
- name?: string,
141
- template?: string
142
- ): Promise<void> {
143
- validatePathWithinCwd(installDir);
144
-
145
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
146
- const themes: string[] = docsConfigSchema.options.map((option: any) => {
147
- return option.shape.theme._def.value as string;
148
- });
149
-
150
- const dirContents = await fse.readdir(installDir).catch(() => [] as string[]);
151
- const contentsOccupied = dirContents.length > 0;
152
-
153
- if (isAI() && (!name || (!template && !theme))) {
154
- await sendAIUsageMessage(installDir, contentsOccupied, themes);
155
- return;
156
- }
157
-
158
- if (isAI() && contentsOccupied && !force) {
159
- await sendAIUsageMessage(installDir, contentsOccupied, themes);
160
- return;
161
- }
162
-
163
- const selectedTemplate = template
164
- ? await validateTemplateName(template).then(() => template)
165
- : !isAI() && !theme
166
- ? await promptForApproach()
167
- : undefined;
168
-
169
- if (selectedTemplate) {
170
- const resolved = await resolveInstallDir(installDir, force, contentsOccupied);
171
- if (resolved === undefined) {
172
- if (isAI()) await sendAIUsageMessage(installDir, contentsOccupied, themes);
173
- return;
174
- }
175
-
176
- const projectName = await promptForProjectName(resolved, name);
177
- await fse.ensureDir(resolved);
178
- await installFromTemplate(resolved, selectedTemplate, projectName, theme);
179
- sendOnboardingMessage(resolved);
180
- return;
181
- }
182
-
183
- // Standard theme-based path
184
- const resolved = await resolveInstallDir(installDir, force, contentsOccupied);
185
- if (resolved === undefined) {
186
- if (isAI()) await sendAIUsageMessage(installDir, contentsOccupied, themes);
187
- return;
188
- }
189
-
190
- let projectName = name;
191
- let selectedTheme = theme;
192
-
193
- if (!isAI() && (!selectedTheme || !projectName)) {
194
- projectName = await promptForProjectName(resolved, projectName);
195
-
196
- if (!selectedTheme) {
197
- selectedTheme = await select({
198
- message: 'Theme',
199
- choices: themes.map((t) => ({ name: t, value: t })),
200
- });
201
- }
202
- }
203
-
204
- if (projectName === undefined || selectedTheme === undefined) {
205
- await sendAIUsageMessage(resolved, contentsOccupied, themes);
206
- return;
207
- }
208
-
209
- await fse.ensureDir(resolved);
210
- await install(resolved, projectName, selectedTheme);
211
- sendOnboardingMessage(resolved);
212
- }
213
-
214
- const install = async (installDir: string, projectName: string, theme: string) => {
215
- addLog(<SpinnerLog message="downloading starter template..." />);
216
- const response = await fetch('https://github.com/mintlify/starter/archive/refs/heads/main.zip');
217
- const buffer = await response.arrayBuffer();
218
- await fse.writeFile(installDir + '/starter.zip', Buffer.from(buffer));
219
- removeLastLog();
220
-
221
- addLog(<SpinnerLog message="extracting..." />);
222
- new AdmZip(installDir + '/starter.zip').extractAllTo(installDir, true);
223
- removeLastLog();
224
-
225
- await fse.copy(installDir + '/starter-main', installDir, {
226
- overwrite: true,
227
- filter: (src) => !src.includes('starter-main/starter-main'),
228
- });
229
- await fse.remove(installDir + '/starter.zip');
230
- await fse.remove(installDir + '/starter-main');
231
-
232
- const docsJsonPath = installDir + '/docs.json';
233
- const docsConfig = await fse.readJson(docsJsonPath);
234
- docsConfig.theme = theme;
235
- docsConfig.name = projectName;
236
- await fse.writeJson(docsJsonPath, docsConfig, { spaces: 2 });
237
- };
@@ -1,99 +0,0 @@
1
- export const INSTRUCTIONS_URL = 'https://www.mintlify.com/docs/mint-instructions';
2
-
3
- export const TOPICS: { name: string; when: string }[] = [
4
- {
5
- name: 'overview',
6
- when: 'Start here: how Mintlify works and facts agents most often get wrong',
7
- },
8
- {
9
- name: 'new-site',
10
- when: 'New docs site, first publish, no account, claim a site, login, no docs.json yet',
11
- },
12
- {
13
- name: 'write',
14
- when: 'Before creating a page or writing more than a sentence or two; changelogs',
15
- },
16
- {
17
- name: 'write components',
18
- when: 'Adding or changing components: callouts, cards, steps, tabs, accordions, fields',
19
- },
20
- { name: 'configure', when: 'Changing docs.json: theme, colors, logo, favicon, required fields' },
21
- {
22
- name: 'configure navigation',
23
- when: 'Changing navigation: groups, tabs, anchors, dropdowns, products, versions, languages',
24
- },
25
- {
26
- name: 'configure settings',
27
- when: 'navbar, footer, banner, SEO, search, integrations, contextual menu, redirects, 404',
28
- },
29
- {
30
- name: 'configure customization',
31
- when: 'Themes, fonts, CSS, JavaScript, or React snippets',
32
- },
33
- { name: 'api-docs', when: 'API documentation: OpenAPI, AsyncAPI, GraphQL, playground' },
34
- {
35
- name: 'api-docs sdk',
36
- when: 'SDK reference pages, x-codeSamples, oneOf/anyOf, multiple responses, hiding endpoints',
37
- },
38
- {
39
- name: 'publish',
40
- when: 'Deploying, "is it live", previews, rollbacks, MCP, llms.txt, skill.md, Markdown export',
41
- },
42
- {
43
- name: 'publish domain',
44
- when: 'Custom domain (mint add-domain), /docs subpath, reverse proxy, CSP',
45
- },
46
- {
47
- name: 'publish repo',
48
- when: 'Monorepo, multi-repo, GitHub/GitLab/Bitbucket, offline export, self-host',
49
- },
50
- {
51
- name: 'publish analytics',
52
- when: 'mint analytics, feedback, search data, analytics integrations',
53
- },
54
- {
55
- name: 'publish assistant',
56
- when: 'AI assistant, widget, Assistant.md, skills, narration, own model',
57
- },
58
- { name: 'access', when: 'Private docs, reader login, user groups, personalization' },
59
- { name: 'access team', when: 'Team members, roles, SSO, SCIM, audit logs, session security' },
60
- {
61
- name: 'automate',
62
- when: 'Keep docs in sync with code: agent, Autopilot, automations, Slack, CI',
63
- },
64
- {
65
- name: 'migrate',
66
- when: 'Moving docs from Docusaurus, GitBook, ReadMe, Fern, Document360, Confluence, Markdown',
67
- },
68
- { name: 'troubleshoot', when: 'An error, a failed build or deploy, or the site looks wrong' },
69
- ];
70
-
71
- export const formatTopics = (): string => {
72
- const width = Math.max(...TOPICS.map(({ name }) => name.length)) + 2;
73
- return [
74
- 'Usage: mint instructions <topic> [subtopic]',
75
- '',
76
- ...TOPICS.map(({ name, when }) => ` ${name.padEnd(width)}${when}`),
77
- '',
78
- ].join('\n');
79
- };
80
-
81
- export const instructionsUrl = (topics: string[]): string =>
82
- `${INSTRUCTIONS_URL}/${topics.map(encodeURIComponent).join('/')}.md`;
83
-
84
- export const stripDocsPreamble = (markdown: string): string =>
85
- markdown.replace(/^(?:>.*\n|\s*\n)*/, '');
86
-
87
- export async function fetchInstructions(topics: string[]): Promise<string> {
88
- const url = instructionsUrl(topics);
89
- const response = await fetch(url);
90
- if (response.status === 404) {
91
- throw new Error(
92
- `no instructions for "${topics.join(' ')}". Run \`mint instructions\` to list topics.`
93
- );
94
- }
95
- if (!response.ok) {
96
- throw new Error(`failed to fetch ${url}: ${response.status} ${response.statusText}`);
97
- }
98
- return stripDocsPreamble(await response.text());
99
- }
package/src/keyring.ts DELETED
@@ -1,65 +0,0 @@
1
- const SERVICE = 'mintlify';
2
- const ACCESS_TOKEN_ACCOUNT = 'access_token';
3
- const REFRESH_TOKEN_ACCOUNT = 'refresh_token';
4
- const USER_EMAIL_ACCOUNT = 'user_email';
5
-
6
- export async function getKeytar(): Promise<typeof import('keytar')> {
7
- try {
8
- const mod = await import('keytar');
9
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- ESM wraps CJS in { default: ... } at runtime despite types
10
- return mod.default ?? mod;
11
- } catch {
12
- throw new Error(
13
- 'keytar is required for credential storage but is not installed. Install it with: npm install keytar'
14
- );
15
- }
16
- }
17
-
18
- export async function storeCredentials(
19
- accessToken: string,
20
- refreshToken: string,
21
- userEmail?: string | null
22
- ): Promise<void> {
23
- const keytar = await getKeytar();
24
- await Promise.all([
25
- keytar.setPassword(SERVICE, ACCESS_TOKEN_ACCOUNT, accessToken),
26
- keytar.setPassword(SERVICE, REFRESH_TOKEN_ACCOUNT, refreshToken),
27
- ]);
28
-
29
- try {
30
- if (userEmail === null) {
31
- await keytar.deletePassword(SERVICE, USER_EMAIL_ACCOUNT);
32
- } else if (userEmail !== undefined) {
33
- await keytar.setPassword(SERVICE, USER_EMAIL_ACCOUNT, userEmail);
34
- }
35
- } catch {}
36
- }
37
-
38
- export async function getAccessToken(): Promise<string | null> {
39
- const keytar = await getKeytar();
40
- return keytar.getPassword(SERVICE, ACCESS_TOKEN_ACCOUNT);
41
- }
42
-
43
- export async function getRefreshToken(): Promise<string | null> {
44
- const keytar = await getKeytar();
45
- return keytar.getPassword(SERVICE, REFRESH_TOKEN_ACCOUNT);
46
- }
47
-
48
- export async function getUserEmail(): Promise<string | null> {
49
- const keytar = await getKeytar();
50
- return keytar.getPassword(SERVICE, USER_EMAIL_ACCOUNT);
51
- }
52
-
53
- export async function storeUserEmail(userEmail: string): Promise<void> {
54
- const keytar = await getKeytar();
55
- await keytar.setPassword(SERVICE, USER_EMAIL_ACCOUNT, userEmail);
56
- }
57
-
58
- export async function clearCredentials(): Promise<void> {
59
- const keytar = await getKeytar();
60
- await Promise.all([
61
- keytar.deletePassword(SERVICE, ACCESS_TOKEN_ACCOUNT),
62
- keytar.deletePassword(SERVICE, REFRESH_TOKEN_ACCOUNT),
63
- keytar.deletePassword(SERVICE, USER_EMAIL_ACCOUNT).catch(() => false),
64
- ]);
65
- }
package/src/login.tsx DELETED
@@ -1,166 +0,0 @@
1
- import { input, search } from '@inquirer/prompts';
2
- import { addLog, ErrorLog, InfoLog, SuccessLog } from '@mintlify/previewing';
3
- import chalk from 'chalk';
4
- import { Box, Text } from 'ink';
5
- import open from 'open';
6
- import {
7
- calculatePKCECodeChallenge,
8
- randomNonce,
9
- randomPKCECodeVerifier,
10
- randomState,
11
- } from 'openid-client';
12
-
13
- import { startCallbackServer } from './callbackServer.js';
14
- import { setConfigValue } from './config.js';
15
- import { DASHBOARD_URL, TOKEN_ENDPOINT } from './constants.js';
16
- import { getEmailFromIdToken } from './idToken.js';
17
- import { storeCredentials } from './keyring.js';
18
- import { getCliSubdomains } from './status.js';
19
- import { trackLoginAttempt, trackLoginFailed, trackLoginSuccess } from './telemetry/track.js';
20
-
21
- export interface TokenResponse {
22
- access_token: string;
23
- id_token: string;
24
- refresh_token: string;
25
- token_type: 'bearer';
26
- expires_in: number;
27
- request_id: string;
28
- status_code: number;
29
- }
30
-
31
- export async function login(): Promise<void> {
32
- const codeVerifier = randomPKCECodeVerifier();
33
- const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);
34
- const nonce = randomNonce();
35
- const clientState = randomState();
36
-
37
- const state = Buffer.from(JSON.stringify({ nonce, clientState })).toString('base64url');
38
-
39
- const authorizeUrl = new URL('/api/cli/oauth/authorize', DASHBOARD_URL);
40
- authorizeUrl.searchParams.set('state', state);
41
- authorizeUrl.searchParams.set('code_challenge', codeChallenge);
42
- const url = authorizeUrl.toString();
43
-
44
- void trackLoginAttempt();
45
-
46
- const { codePromise, close: closeServer } = await startCallbackServer();
47
-
48
- addLog(
49
- <Box flexDirection="column" gap={1} paddingY={1}>
50
- <Text bold>
51
- <Text color="green">◆ </Text>A browser window will open for Mintlify authentication
52
- </Text>
53
- <Box flexDirection="column" paddingLeft={3} gap={1}>
54
- <Text dimColor>If your browser doesn't open automatically, copy this URL:</Text>
55
- <Text dimColor>{url}</Text>
56
- </Box>
57
- </Box>
58
- );
59
-
60
- open(url).catch(() => {});
61
-
62
- addLog(
63
- <Box flexDirection="column" paddingLeft={1} marginTop={1}>
64
- <Text dimColor>╭─ Paste the authorization code from your browser</Text>
65
- <Text dimColor>│</Text>
66
- </Box>
67
- );
68
-
69
- // Let ink finish rendering before inquirer takes over stdout
70
- await new Promise((resolve) => setTimeout(resolve, 50));
71
-
72
- const inputPromise = input({
73
- message: '█',
74
- theme: {
75
- prefix: chalk.dim(' │'),
76
- style: {
77
- answer: (text: string) => chalk.cyan(text),
78
- },
79
- },
80
- });
81
-
82
- let code: string;
83
- try {
84
- code = await Promise.race([codePromise, inputPromise]);
85
- } catch {
86
- closeServer();
87
- inputPromise.cancel();
88
- addLog(<ErrorLog message="login cancelled" />);
89
- return;
90
- }
91
-
92
- closeServer();
93
- inputPromise.cancel();
94
-
95
- const res = await fetch(TOKEN_ENDPOINT, {
96
- method: 'POST',
97
- headers: { 'Content-Type': 'application/json' },
98
- body: JSON.stringify({
99
- grant_type: 'authorization_code',
100
- code,
101
- code_verifier: codeVerifier,
102
- }),
103
- });
104
-
105
- const body = await res.json().catch(() => ({}));
106
-
107
- if (!res.ok) {
108
- const reason = body.error_message ?? body.error ?? 'unknown error';
109
- void trackLoginFailed(reason);
110
- addLog(<ErrorLog message={`login failed: ${reason}`} />);
111
- return;
112
- }
113
-
114
- const token = body as TokenResponse;
115
- await storeCredentials(
116
- token.access_token,
117
- token.refresh_token,
118
- getEmailFromIdToken(token.id_token) ?? null
119
- );
120
- void trackLoginSuccess();
121
- addLog(<SuccessLog message="logged in successfully" />);
122
- await promptSubdomainSelection(token.access_token);
123
- }
124
-
125
- function isPromptCancellationError(error: unknown): boolean {
126
- return error instanceof Error && error.name === 'ExitPromptError';
127
- }
128
-
129
- async function promptSubdomainSelection(accessToken: string): Promise<void> {
130
- const subdomains = await getCliSubdomains(accessToken);
131
- if (subdomains.length === 0) return;
132
-
133
- if (subdomains.length === 1) {
134
- await setConfigValue('subdomain', subdomains[0]!);
135
- addLog(<InfoLog message={`default project set to ${subdomains[0]}`} />);
136
- return;
137
- }
138
-
139
- await new Promise((resolve) => setTimeout(resolve, 50));
140
-
141
- let chosen: string;
142
- try {
143
- chosen = await search<string>({
144
- message: 'Select a default project',
145
- source: (term) => {
146
- const results = term
147
- ? subdomains.filter((s) => s.toLowerCase().includes(term.toLowerCase()))
148
- : subdomains;
149
- return results.map((s) => ({ name: s, value: s }));
150
- },
151
- });
152
- } catch (error) {
153
- if (isPromptCancellationError(error)) {
154
- addLog(
155
- <InfoLog
156
- message={`No project set. To set a default project, run ${chalk.bold('mintlify config set subdomain <subdomain>')}`}
157
- />
158
- );
159
- return;
160
- }
161
- throw error;
162
- }
163
-
164
- await setConfigValue('subdomain', chosen);
165
- addLog(<InfoLog message={`default project set to ${chosen}`} />);
166
- }
package/src/logout.tsx DELETED
@@ -1,8 +0,0 @@
1
- import { addLog, SuccessLog } from '@mintlify/previewing';
2
-
3
- import { clearCredentials } from './keyring.js';
4
-
5
- export async function logout(): Promise<void> {
6
- await clearCredentials();
7
- addLog(<SuccessLog message="logged out successfully" />);
8
- }