@mintlify/cli 4.0.1813 → 4.1.2
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.
- package/dist/assets/export-scripts/README.classic.md +15 -0
- package/dist/assets/export-scripts/README.md +14 -0
- package/dist/assets/export-scripts/serve.js +114 -0
- package/dist/assets/export-scripts/start-docs.bat +10 -0
- package/dist/assets/export-scripts/start-docs.sh +9 -0
- package/dist/assets/og/Inter-Bold.ttf +0 -0
- package/dist/assets/og/Inter-Medium.ttf +0 -0
- package/dist/assets/og/Inter-Regular.ttf +0 -0
- package/dist/assets/og/Inter-SemiBold.ttf +0 -0
- package/dist/assets/og/PaperMono-Regular.ttf +0 -0
- package/dist/assets/og/index_bg.wasm +0 -0
- package/dist/assets/openChrome.applescript +94 -0
- package/dist/assets/socket.io/socket.io.esm.min.js +7 -0
- package/dist/assets/socket.io/socket.io.esm.min.js.map +1 -0
- package/dist/assets/socket.io/socket.io.js +4907 -0
- package/dist/assets/socket.io/socket.io.js.map +1 -0
- package/dist/assets/socket.io/socket.io.min.js +7 -0
- package/dist/assets/socket.io/socket.io.min.js.map +1 -0
- package/dist/assets/socket.io/socket.io.msgpack.min.js +7 -0
- package/dist/assets/socket.io/socket.io.msgpack.min.js.map +1 -0
- package/dist/assets/xdg-open +1066 -0
- package/dist/assets/yargs-locales/be.json +46 -0
- package/dist/assets/yargs-locales/cs.json +51 -0
- package/dist/assets/yargs-locales/de.json +46 -0
- package/dist/assets/yargs-locales/en.json +55 -0
- package/dist/assets/yargs-locales/es.json +46 -0
- package/dist/assets/yargs-locales/fi.json +49 -0
- package/dist/assets/yargs-locales/fr.json +53 -0
- package/dist/assets/yargs-locales/hi.json +49 -0
- package/dist/assets/yargs-locales/hu.json +46 -0
- package/dist/assets/yargs-locales/id.json +50 -0
- package/dist/assets/yargs-locales/it.json +46 -0
- package/dist/assets/yargs-locales/ja.json +51 -0
- package/dist/assets/yargs-locales/ko.json +49 -0
- package/dist/assets/yargs-locales/nb.json +44 -0
- package/dist/assets/yargs-locales/nl.json +49 -0
- package/dist/assets/yargs-locales/nn.json +44 -0
- package/dist/assets/yargs-locales/pirate.json +13 -0
- package/dist/assets/yargs-locales/pl.json +49 -0
- package/dist/assets/yargs-locales/pt.json +45 -0
- package/dist/assets/yargs-locales/pt_BR.json +48 -0
- package/dist/assets/yargs-locales/ru.json +51 -0
- package/dist/assets/yargs-locales/th.json +46 -0
- package/dist/assets/yargs-locales/tr.json +48 -0
- package/dist/assets/yargs-locales/uk_UA.json +51 -0
- package/dist/assets/yargs-locales/uz.json +52 -0
- package/dist/assets/yargs-locales/zh_CN.json +48 -0
- package/dist/assets/yargs-locales/zh_TW.json +51 -0
- package/dist/converter-d8O3xkdU.js +102 -0
- package/dist/devtools-CGNZQKFV.js +24 -0
- package/dist/index.js +8 -0
- package/dist/rolldown-runtime-CEAe2Uac.js +7 -0
- package/dist/schemas-CBsmCNpK.js +372 -0
- package/dist/start.js +2310 -0
- package/package.json +38 -31
- package/.oxlintrc.json +0 -5
- package/.prettierignore +0 -2
- package/.turbo/turbo-build.log +0 -1
- package/CONTRIBUTING.md +0 -45
- package/__test__/agent-auth.test.ts +0 -114
- package/__test__/agent-claim.test.ts +0 -164
- package/__test__/agent-credentials.test.ts +0 -149
- package/__test__/agent-deployment.test.ts +0 -106
- package/__test__/agent-setup-config.test.ts +0 -324
- package/__test__/agent-setup.test.ts +0 -207
- package/__test__/agent.test.ts +0 -64
- package/__test__/analytics/client.test.ts +0 -180
- package/__test__/analytics/dates.test.ts +0 -12
- package/__test__/analytics/filters.test.ts +0 -116
- package/__test__/analytics/format.test.ts +0 -137
- package/__test__/authenticatedFetch.test.ts +0 -182
- package/__test__/brokenLinks.test.ts +0 -283
- package/__test__/checkPort.test.ts +0 -92
- package/__test__/deploy-github-actions.test.ts +0 -202
- package/__test__/deploy-github-setup.test.ts +0 -240
- package/__test__/deploy-instructions.test.ts +0 -155
- package/__test__/deploy.test.ts +0 -202
- package/__test__/feedback.test.ts +0 -34
- package/__test__/foreignSyntax.test.ts +0 -73
- package/__test__/format.test.ts +0 -72
- package/__test__/helpers.test.ts +0 -52
- package/__test__/init.test.ts +0 -119
- package/__test__/instructions.test.ts +0 -53
- package/__test__/keyring.test.ts +0 -82
- package/__test__/mdxAccessibility.test.ts +0 -81
- package/__test__/migrate.test.ts +0 -186
- package/__test__/openApiCheck.test.ts +0 -185
- package/__test__/pathValidation.test.ts +0 -25
- package/__test__/resolveFiles.test.ts +0 -70
- package/__test__/sessionId.test.ts +0 -46
- package/__test__/signup.test.ts +0 -36
- package/__test__/update.test.ts +0 -117
- package/__test__/utils.ts +0 -25
- package/__test__/validateCommand.test.ts +0 -647
- package/__test__/validateEngine.test.ts +0 -245
- package/__test__/validateRules.test.ts +0 -1275
- package/__test__/welcome.test.ts +0 -15
- package/__test__/workflows/client.test.ts +0 -126
- package/bin/accessibility.js +0 -111
- package/bin/accessibilityCheck.js +0 -82
- package/bin/addDomain.js +0 -130
- package/bin/agent-auth.js +0 -104
- package/bin/agent-claim.js +0 -97
- package/bin/agent-credentials.js +0 -124
- package/bin/agent-deployment.js +0 -96
- package/bin/agent-http.js +0 -45
- package/bin/agent-setup-config.js +0 -141
- package/bin/agent-setup.js +0 -146
- package/bin/agent.js +0 -42
- package/bin/analytics/client.js +0 -60
- package/bin/analytics/dates.js +0 -6
- package/bin/analytics/filters.js +0 -27
- package/bin/analytics/format.js +0 -13
- package/bin/analytics/index.js +0 -496
- package/bin/analytics/output.js +0 -75
- package/bin/analytics/types.js +0 -1
- package/bin/authenticatedFetch.js +0 -46
- package/bin/brokenLinks.js +0 -122
- package/bin/callbackServer.js +0 -65
- package/bin/cli.js +0 -813
- package/bin/comingSoon.js +0 -26
- package/bin/config.js +0 -78
- package/bin/constants.js +0 -16
- package/bin/deploy-base.js +0 -20
- package/bin/deploy-github-actions.js +0 -102
- package/bin/deploy-github-setup.js +0 -165
- package/bin/deploy-instructions.js +0 -71
- package/bin/deploy.js +0 -123
- package/bin/feedback.js +0 -36
- package/bin/format.js +0 -121
- package/bin/helpers.js +0 -238
- package/bin/idToken.js +0 -14
- package/bin/index.js +0 -102
- package/bin/init.js +0 -182
- package/bin/instructions.js +0 -101
- package/bin/keyring.js +0 -78
- package/bin/login.js +0 -123
- package/bin/logout.js +0 -18
- package/bin/mdxAccessibility.js +0 -113
- package/bin/mdxLinter.js +0 -55
- package/bin/middlewares/subdomainMiddleware.js +0 -28
- package/bin/middlewares/telemetryMiddleware.js +0 -61
- package/bin/migrate.js +0 -54
- package/bin/og.js +0 -145
- package/bin/openApiCheck.js +0 -99
- package/bin/resolveFiles.js +0 -114
- package/bin/score/client.js +0 -40
- package/bin/score/index.js +0 -211
- package/bin/score/types.js +0 -1
- package/bin/signup.js +0 -118
- package/bin/start.js +0 -36
- package/bin/status.js +0 -106
- package/bin/telemetry/client.js +0 -53
- package/bin/telemetry/distinctId.js +0 -68
- package/bin/telemetry/sessionId.js +0 -36
- package/bin/telemetry/track.js +0 -149
- package/bin/templates.js +0 -127
- package/bin/tokenRefresh.js +0 -50
- package/bin/tsconfig.build.tsbuildinfo +0 -1
- package/bin/update.js +0 -65
- package/bin/validate/command.js +0 -127
- package/bin/validate/engine.js +0 -154
- package/bin/validate/files.js +0 -163
- package/bin/validate/mdx.js +0 -238
- package/bin/validate/output.js +0 -44
- package/bin/validate/report.js +0 -11
- package/bin/validate/rules/build.js +0 -102
- package/bin/validate/rules/content/duplicateH1.js +0 -57
- package/bin/validate/rules/content/foreignSyntax.js +0 -120
- package/bin/validate/rules/content/katex.js +0 -34
- package/bin/validate/rules/content/missingSnippet.js +0 -34
- package/bin/validate/rules/content/undefinedVariable.js +0 -13
- package/bin/validate/rules/content/unknownComponent.js +0 -121
- package/bin/validate/rules/content/voidTags.js +0 -38
- package/bin/validate/rules/index.js +0 -21
- package/bin/validate/rules/openapi.js +0 -50
- package/bin/validate/rules/parseError.js +0 -7
- package/bin/validate/site.js +0 -57
- package/bin/validate/types.js +0 -1
- package/bin/vendor/converter.js +0 -30882
- package/bin/welcome.js +0 -108
- package/bin/workflows/client.js +0 -34
- package/bin/workflows/index.js +0 -269
- package/bin/workflows/types.js +0 -11
- package/scripts/bundle-converter.mjs +0 -26
- package/scripts/generate-logo.mjs +0 -79
- package/src/accessibility.ts +0 -180
- package/src/accessibilityCheck.tsx +0 -150
- package/src/addDomain.tsx +0 -206
- package/src/agent-auth.ts +0 -119
- package/src/agent-claim.ts +0 -124
- package/src/agent-credentials.ts +0 -104
- package/src/agent-deployment.ts +0 -116
- package/src/agent-http.ts +0 -34
- package/src/agent-setup-config.ts +0 -144
- package/src/agent-setup.ts +0 -165
- package/src/agent.ts +0 -56
- package/src/analytics/client.ts +0 -153
- package/src/analytics/dates.ts +0 -6
- package/src/analytics/filters.ts +0 -50
- package/src/analytics/format.ts +0 -13
- package/src/analytics/index.tsx +0 -599
- package/src/analytics/output.ts +0 -99
- package/src/analytics/types.ts +0 -145
- package/src/authenticatedFetch.ts +0 -42
- package/src/brokenLinks.tsx +0 -152
- package/src/callbackServer.ts +0 -64
- package/src/cli.tsx +0 -1105
- package/src/comingSoon.tsx +0 -29
- package/src/config.ts +0 -75
- package/src/constants.ts +0 -28
- package/src/deploy-base.ts +0 -18
- package/src/deploy-github-actions.ts +0 -139
- package/src/deploy-github-setup.ts +0 -189
- package/src/deploy-instructions.ts +0 -76
- package/src/deploy.ts +0 -165
- package/src/feedback.tsx +0 -31
- package/src/format.tsx +0 -82
- package/src/helpers.tsx +0 -279
- package/src/idToken.ts +0 -17
- package/src/index.ts +0 -109
- package/src/init.tsx +0 -237
- package/src/instructions.ts +0 -99
- package/src/keyring.ts +0 -65
- package/src/login.tsx +0 -166
- package/src/logout.tsx +0 -8
- package/src/mdxAccessibility.ts +0 -134
- package/src/mdxLinter.tsx +0 -88
- package/src/middlewares/subdomainMiddleware.ts +0 -20
- package/src/middlewares/telemetryMiddleware.ts +0 -55
- package/src/migrate.ts +0 -76
- package/src/og.tsx +0 -185
- package/src/openApiCheck.tsx +0 -125
- package/src/resolveFiles.ts +0 -101
- package/src/score/client.ts +0 -36
- package/src/score/index.tsx +0 -205
- package/src/score/types.ts +0 -15
- package/src/signup.tsx +0 -172
- package/src/start.ts +0 -27
- package/src/status.tsx +0 -129
- package/src/telemetry/client.ts +0 -46
- package/src/telemetry/distinctId.ts +0 -70
- package/src/telemetry/sessionId.ts +0 -40
- package/src/telemetry/track.ts +0 -163
- package/src/templates.tsx +0 -143
- package/src/tokenRefresh.ts +0 -53
- package/src/update.tsx +0 -89
- package/src/validate/command.tsx +0 -135
- package/src/validate/engine.ts +0 -210
- package/src/validate/files.ts +0 -249
- package/src/validate/mdx.ts +0 -290
- package/src/validate/output.tsx +0 -76
- package/src/validate/report.ts +0 -40
- package/src/validate/rules/build.ts +0 -146
- package/src/validate/rules/content/duplicateH1.ts +0 -78
- package/src/validate/rules/content/foreignSyntax.ts +0 -144
- package/src/validate/rules/content/katex.ts +0 -33
- package/src/validate/rules/content/missingSnippet.ts +0 -36
- package/src/validate/rules/content/undefinedVariable.ts +0 -20
- package/src/validate/rules/content/unknownComponent.ts +0 -130
- package/src/validate/rules/content/voidTags.ts +0 -43
- package/src/validate/rules/index.ts +0 -23
- package/src/validate/rules/openapi.ts +0 -59
- package/src/validate/rules/parseError.ts +0 -9
- package/src/validate/site.ts +0 -53
- package/src/validate/types.ts +0 -102
- package/src/vendor/converter.ts +0 -1
- package/src/welcome.ts +0 -154
- package/src/workflows/client.ts +0 -39
- package/src/workflows/index.tsx +0 -287
- package/src/workflows/types.ts +0 -73
- package/tsconfig.build.json +0 -4
- package/tsconfig.json +0 -10
- 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
|
-
};
|
package/src/instructions.ts
DELETED
|
@@ -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