@mintlify/cli 4.0.1713 → 4.0.1715

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/bin/welcome.js CHANGED
@@ -36,6 +36,7 @@ const GROUPS = [
36
36
  title: 'Account',
37
37
  commands: [
38
38
  { name: 'login', description: 'Authenticate with Mintlify' },
39
+ { name: 'claim', description: 'Claim a site created with mint deploy' },
39
40
  { name: 'logout', description: 'Sign out on this device' },
40
41
  { name: 'status', description: 'View authentication status' },
41
42
  ],
@@ -51,6 +52,11 @@ const GROUPS = [
51
52
  const EXAMPLES = [
52
53
  { name: 'dev', description: 'Start a local preview of your site' },
53
54
  { name: 'new docs', description: 'Scaffold a new site in ./docs' },
55
+ {
56
+ name: 'claim --email you@example.com',
57
+ description: 'Get a claim link; use the deployment directory',
58
+ },
59
+ { name: 'claim --code <code>', description: 'Finish the claim in the same directory' },
54
60
  { name: 'validate', description: 'Validate your site before shipping' },
55
61
  { name: 'broken-links', description: 'Find broken links across your site' },
56
62
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mintlify/cli",
3
- "version": "4.0.1713",
3
+ "version": "4.0.1715",
4
4
  "description": "The Mintlify CLI",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -45,12 +45,12 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@inquirer/prompts": "7.9.0",
48
- "@mintlify/common": "1.0.1295",
49
- "@mintlify/link-rot": "3.0.1520",
48
+ "@mintlify/common": "1.0.1296",
49
+ "@mintlify/link-rot": "3.0.1521",
50
50
  "@mintlify/models": "0.0.378",
51
- "@mintlify/og": "0.0.94",
52
- "@mintlify/prebuild": "1.0.1460",
53
- "@mintlify/previewing": "4.0.1538",
51
+ "@mintlify/og": "0.0.95",
52
+ "@mintlify/prebuild": "1.0.1461",
53
+ "@mintlify/previewing": "4.0.1539",
54
54
  "@mintlify/validation": "0.1.940",
55
55
  "adm-zip": "0.6.0",
56
56
  "chalk": "5.2.0",
@@ -82,7 +82,7 @@
82
82
  "keytar": "7.9.0"
83
83
  },
84
84
  "devDependencies": {
85
- "@mintlify/editor": "0.0.562",
85
+ "@mintlify/editor": "0.0.563",
86
86
  "@mintlify/ts-config": "2.0.2",
87
87
  "@tsconfig/recommended": "1.0.2",
88
88
  "@types/detect-port": "1.3.2",
@@ -101,5 +101,5 @@
101
101
  "vitest": "2.1.9",
102
102
  "vitest-mock-process": "1.0.4"
103
103
  },
104
- "gitHead": "c2289baf20353b9ed7e11ed8ec20b8e644b63a8c"
104
+ "gitHead": "597cd230e480b7026623253191c869f82964b334"
105
105
  }
package/src/agent-auth.ts CHANGED
@@ -13,9 +13,10 @@ const discoverySchema = z.object({
13
13
  identity_types_supported: z.array(z.string()),
14
14
  }),
15
15
  });
16
+ export const agentIdentityAssertionSchema = z.object({ assertion: z.string().min(1) });
16
17
  const registrationSchema = z.object({
17
18
  id: z.string().min(1),
18
- identity: z.object({ assertion: z.string().min(1) }),
19
+ identity: agentIdentityAssertionSchema,
19
20
  claim: z.object({ token: z.string().min(1) }),
20
21
  });
21
22
  const tokenSchema = z.object({
@@ -1,7 +1,15 @@
1
1
  import { z } from 'zod';
2
2
 
3
- import { discoverAgentAuth } from './agent-auth.js';
4
- import type { AgentCredentials } from './agent-credentials.js';
3
+ import {
4
+ agentIdentityAssertionSchema,
5
+ discoverAgentAuth,
6
+ exchangeAgentToken,
7
+ } from './agent-auth.js';
8
+ import {
9
+ loadAgentCredentials,
10
+ saveAgentCredentials,
11
+ type AgentCredentials,
12
+ } from './agent-credentials.js';
5
13
  import { agentRequest, agentResponse } from './agent-http.js';
6
14
  import { DASHBOARD_URL } from './constants.js';
7
15
 
@@ -37,3 +45,76 @@ export async function createAgentClaimLink(
37
45
  claimUrl.searchParams.set('token', token);
38
46
  return claimUrl.toString();
39
47
  }
48
+
49
+ const completedClaimSchema = z.object({
50
+ identity: agentIdentityAssertionSchema,
51
+ });
52
+ const signupSchema = z.object({ orgId: z.string().min(1), claimed: z.literal(true) });
53
+
54
+ export async function claimDeployment(
55
+ options: { apiUrl: string; directory: string; code?: string; email?: string },
56
+ warn: (message: string) => void,
57
+ progress: (message: string) => void = () => {}
58
+ ): Promise<string> {
59
+ const { apiUrl, directory } = options;
60
+ const code = options.code?.trim();
61
+ const email = options.email?.trim();
62
+ if ((!code && !email) || (code && email)) {
63
+ throw new Error(
64
+ 'Provide either --email <email> for a claim link or --code <code> to finish the claim.'
65
+ );
66
+ }
67
+ let credentials = await loadAgentCredentials(apiUrl, directory);
68
+ if (!credentials)
69
+ throw new Error(
70
+ 'No saved agent registration. Run from the directory used for mint deploy, or pass --directory.'
71
+ );
72
+ if (email && !credentials.claimVerified) {
73
+ progress('Creating the claim link...');
74
+ const link = await createAgentClaimLink(apiUrl, credentials, email);
75
+ return `Claim link for the user: ${link}\nAsk the user to open it, sign in, and return the displayed code. Then run mint claim --code <code> from the same directory (or repeat --directory).`;
76
+ }
77
+ const discovery = await discoverAgentAuth(apiUrl);
78
+ if (new URL(discovery.issuer).origin !== new URL(credentials.issuer).origin) {
79
+ throw new Error('Saved agent credentials belong to another issuer.');
80
+ }
81
+ const save = async (value: AgentCredentials) => {
82
+ try {
83
+ await saveAgentCredentials(apiUrl, directory, value);
84
+ } catch {
85
+ warn(
86
+ 'Could not save claimed credentials to the keyring. Continuing for this run; a retry may not recover the completed claim.'
87
+ );
88
+ }
89
+ };
90
+ if (!credentials.claimVerified) {
91
+ progress('Completing the WorkOS claim...');
92
+ const completed = await agentResponse(
93
+ await agentRequest(`${discovery.agent_auth.claim_endpoint.replace(/\/$/, '')}/complete`, {
94
+ method: 'POST',
95
+ headers: { 'Content-Type': 'application/json' },
96
+ body: JSON.stringify({ claim_token: credentials.claimToken, user_code: code }),
97
+ }),
98
+ completedClaimSchema
99
+ );
100
+ credentials = {
101
+ ...credentials,
102
+ assertion: completed.identity.assertion,
103
+ claimVerified: true,
104
+ accessToken: undefined,
105
+ accessTokenExpiresAt: undefined,
106
+ };
107
+ await save(credentials);
108
+ }
109
+ progress('Finishing the site claim...');
110
+ const authenticated = await exchangeAgentToken(discovery, credentials);
111
+ await agentResponse(
112
+ await agentRequest(`${apiUrl}/api/agent/signup`, {
113
+ method: 'POST',
114
+ headers: { Authorization: `Bearer ${authenticated.accessToken}` },
115
+ }),
116
+ signupSchema
117
+ );
118
+ await save(authenticated);
119
+ return 'Site claimed successfully. The user can now manage it in the Mintlify dashboard.';
120
+ }
@@ -11,6 +11,7 @@ export const agentCredentialsSchema = z.object({
11
11
  issuer: z.url(),
12
12
  assertion: z.string().min(1),
13
13
  claimToken: z.string().min(1),
14
+ claimVerified: z.boolean().optional(),
14
15
  accessToken: z.string().min(1).optional(),
15
16
  accessTokenExpiresAt: z.number().optional(),
16
17
  });
package/src/cli.tsx CHANGED
@@ -17,7 +17,7 @@ import { hideBin } from 'yargs/helpers';
17
17
 
18
18
  import { accessibilityCheck } from './accessibilityCheck.js';
19
19
  import { addDomain } from './addDomain.js';
20
- import { createAgentClaimLink } from './agent-claim.js';
20
+ import { claimDeployment, createAgentClaimLink } from './agent-claim.js';
21
21
  import { analyticsBuilder } from './analytics/index.js';
22
22
  import { brokenLinksHandler } from './brokenLinks.js';
23
23
  import { comingSoon } from './comingSoon.js';
@@ -115,6 +115,42 @@ export const cli = ({ packageName = 'mint' }: { packageName?: string }) => {
115
115
  .middleware(checkNodeVersion)
116
116
  .middleware(suppressConsoleWarnings)
117
117
  .middleware(telemetryMiddleware)
118
+ .command(
119
+ 'claim',
120
+ 'Claim a site created with mint deploy',
121
+ (yargs) =>
122
+ yargs
123
+ .option('email', { type: 'string', description: 'User email for a claim link' })
124
+ .option('code', {
125
+ type: 'string',
126
+ description: 'Code returned by the user from the claim page',
127
+ })
128
+ .option('directory', {
129
+ type: 'string',
130
+ default: '.',
131
+ description: 'Original documentation directory used for mint deploy',
132
+ })
133
+ .conflicts('code', 'email')
134
+ .example('$0 claim --email you@example.com', 'Get a claim link for the current site')
135
+ .example('$0 claim --code ABCDEFGH', 'Finish the claim with the code from the user')
136
+ .epilog(
137
+ 'Run from the same directory as mint deploy, or pass --directory. Ask the user to open the claim link and return the code. The CLI reads saved credentials internally; do not read or print keychain secrets. Retry the same command if Mintlify signup fails.'
138
+ ),
139
+ async (argv) => {
140
+ try {
141
+ const message = await claimDeployment(
142
+ { apiUrl: API_URL, directory: argv.directory, code: argv.code, email: argv.email },
143
+ (message) => process.stderr.write(`Warning: ${message}\n`),
144
+ (message) => process.stderr.write(`${message}\n`)
145
+ );
146
+ process.stdout.write(`${message}\n`);
147
+ await terminate(0);
148
+ } catch (error) {
149
+ process.stderr.write(`${error instanceof Error ? error.message : 'Claim failed.'}\n`);
150
+ await terminate(1);
151
+ }
152
+ }
153
+ )
118
154
  .command(
119
155
  'deploy',
120
156
  'Provision an anonymous docs site and get Git push instructions',
@@ -1,4 +1,3 @@
1
- import { API_URL } from './constants.js';
2
1
  import type { DeployResult } from './deploy.js';
3
2
 
4
3
  export const DEPLOY_HELP = [
@@ -7,6 +6,7 @@ export const DEPLOY_HELP = [
7
6
  'Run again from the same documentation directory for the current anonymous site and a fresh write token. Use --new --subdomain <name> to create another site.',
8
7
  'Claimed sites are managed in the dashboard. Confirmed expired sites start a new anonymous registration.',
9
8
  'Pass --email to obtain a claim link for the user. If it is absent, ask the user for their email and rerun with --email from the same directory. Never invent an email address.',
9
+ 'To claim an existing site without provisioning, run mint claim --email <email>. Show the link to the user and ask them to return the displayed code. Then run mint claim --code <code>. Use the original documentation directory for both commands, or pass --directory.',
10
10
  'The output contains a short-lived write token. Do not paste it into public logs or save it in a Git remote.',
11
11
  ].join('\n\n');
12
12
 
@@ -31,7 +31,7 @@ export function deploymentInstructions(result: DeployResult, claimUrl?: string):
31
31
  ? [
32
32
  `Claim link for the user: ${claimUrl}`,
33
33
  'Show this link to the user. Ask them to open it, sign in, and return the displayed code. Do not sign in on their behalf.',
34
- `Follow the claim-completion instructions at ${API_URL}/api/agent/auth.md. This document includes the WorkOS steps and the authenticated Mintlify signup request.`,
34
+ 'After the user returns the code, run mint claim --code <code> from the same documentation directory (or repeat --directory). The CLI completes the claim using its saved credentials.',
35
35
  ]
36
36
  : [
37
37
  'Ask the user for the email address they want to use to claim this site. Never invent an email address.',
package/src/welcome.ts CHANGED
@@ -49,6 +49,7 @@ const GROUPS: CommandGroup[] = [
49
49
  title: 'Account',
50
50
  commands: [
51
51
  { name: 'login', description: 'Authenticate with Mintlify' },
52
+ { name: 'claim', description: 'Claim a site created with mint deploy' },
52
53
  { name: 'logout', description: 'Sign out on this device' },
53
54
  { name: 'status', description: 'View authentication status' },
54
55
  ],
@@ -65,6 +66,11 @@ const GROUPS: CommandGroup[] = [
65
66
  const EXAMPLES: CommandEntry[] = [
66
67
  { name: 'dev', description: 'Start a local preview of your site' },
67
68
  { name: 'new docs', description: 'Scaffold a new site in ./docs' },
69
+ {
70
+ name: 'claim --email you@example.com',
71
+ description: 'Get a claim link; use the deployment directory',
72
+ },
73
+ { name: 'claim --code <code>', description: 'Finish the claim in the same directory' },
68
74
  { name: 'validate', description: 'Validate your site before shipping' },
69
75
  { name: 'broken-links', description: 'Find broken links across your site' },
70
76
  ];