@mintlify/cli 4.0.1763 → 4.0.1765
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/__test__/migrate.test.ts +186 -0
- package/__test__/validateRules.test.ts +36 -0
- package/bin/cli.js +35 -0
- package/bin/migrate.js +54 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/bin/validate/files.js +16 -4
- package/bin/validate/mdx.js +1 -1
- package/migrate/index.md +56 -0
- package/migrate/sources/confluence.md +120 -0
- package/migrate/sources/docsify.md +128 -0
- package/migrate/sources/document360.md +117 -0
- package/migrate/sources/docus.md +136 -0
- package/migrate/sources/docusaurus.md +143 -0
- package/migrate/sources/fern.md +130 -0
- package/migrate/sources/fumadocs.md +141 -0
- package/migrate/sources/gitbook.md +120 -0
- package/migrate/sources/github-wiki.md +90 -0
- package/migrate/sources/jekyll.md +104 -0
- package/migrate/sources/mdbook.md +98 -0
- package/migrate/sources/mkdocs.md +113 -0
- package/migrate/sources/nextra.md +144 -0
- package/migrate/sources/notion.md +99 -0
- package/migrate/sources/nuxt.md +113 -0
- package/migrate/sources/pdf.md +99 -0
- package/migrate/sources/readme.md +118 -0
- package/migrate/sources/redocly.md +114 -0
- package/migrate/sources/starlight.md +136 -0
- package/migrate/sources/vitepress.md +143 -0
- package/migrate/sources/vuepress.md +153 -0
- package/migrate/topics/api.md +76 -0
- package/migrate/topics/changelog.md +47 -0
- package/migrate/topics/conversion.md +194 -0
- package/migrate/topics/discovery.md +93 -0
- package/migrate/topics/navigation.md +82 -0
- package/migrate/topics/verify.md +58 -0
- package/package.json +10 -10
- package/src/cli.tsx +47 -0
- package/src/migrate.ts +76 -0
- package/src/validate/files.ts +23 -3
- package/src/validate/mdx.ts +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# API reference
|
|
2
|
+
|
|
3
|
+
Only when the source has API or endpoint docs. Skip this for pure content sites.
|
|
4
|
+
|
|
5
|
+
## Find or build the spec
|
|
6
|
+
|
|
7
|
+
1. **Use the source's spec.** Look for an OpenAPI file in the repo, a download link on the reference pages, or common paths (`/openapi.json`, `/swagger.json`, `/api-docs`). A spec in the repo or export is the source of truth for operations (`mint migrate --topic discovery`, Get the source); never edit it to match the old site's rendered output. Platforms that render a playground usually embed the spec or a fragment per operation in the page source; extract and merge them (dedupe `components.schemas`, union `tags`).
|
|
8
|
+
2. **Only if no spec exists**, and the user agrees, build one from the reference pages. Every path, parameter, field, type and example must come from the source. Mark the result in the report as reconstructed.
|
|
9
|
+
|
|
10
|
+
One spec per product, stored at `openapi/<product>.json` or `.yaml`. Do not merge unrelated APIs or split one API across files. A usable spec has `info`, `servers` with the real base URL, `security` with matching `components.securitySchemes`, `tags` with descriptions, and per operation: `operationId`, `summary`, parameters, request body and at least one success response with an example.
|
|
11
|
+
|
|
12
|
+
If the platform changed the spec at build time (decorators, overrides, overlays), bake those changes into the spec or port them to an OpenAPI Overlay referenced as `"openapi": { "source": "...", "overlays": ["..."] }`. Otherwise readers lose them.
|
|
13
|
+
|
|
14
|
+
Reference: https://www.mintlify.com/docs/api-playground/openapi-setup.md
|
|
15
|
+
|
|
16
|
+
## Choose how pages render
|
|
17
|
+
|
|
18
|
+
- **Source has generated reference pages** (one page per operation, little extra prose): add a group with the spec and let Mintlify generate the pages.
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{ "group": "API reference", "openapi": "openapi/core.json" }
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- **Source has hand-written page per endpoint with real prose** (common on hosted platforms): migrate each page as normal and add the operation to its frontmatter, so the page keeps its prose and gains the playground at its original URL.
|
|
25
|
+
|
|
26
|
+
```mdx
|
|
27
|
+
---
|
|
28
|
+
title: 'List loads'
|
|
29
|
+
openapi: 'GET /v1/loads'
|
|
30
|
+
---
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
With several specs, qualify it: `openapi: "openapi/core.json GET /v1/loads"`. Method and path must match the spec exactly.
|
|
34
|
+
|
|
35
|
+
Never do both for the same operations. That publishes every endpoint at two URLs.
|
|
36
|
+
|
|
37
|
+
Add root-level `api` config so the playground and code samples render:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
"api": {
|
|
41
|
+
"playground": { "display": "interactive" },
|
|
42
|
+
"examples": { "languages": ["curl", "python", "javascript"] }
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Only enable `interactive` if the source's API accepts browser requests the user is happy to expose; otherwise use `"simple"`.
|
|
47
|
+
|
|
48
|
+
Reference: https://www.mintlify.com/docs/organize/settings-api.md
|
|
49
|
+
|
|
50
|
+
## Code samples
|
|
51
|
+
|
|
52
|
+
When the source shows per-language samples for an operation, add them to that operation in the spec as `x-codeSamples` entries so they render in the request panel. Use a snippet in the endpoint page only when a sample needs surrounding prose or repeats across many endpoints. Never invent samples.
|
|
53
|
+
|
|
54
|
+
Reference: https://www.mintlify.com/docs/api-playground/adding-sdk-examples.md
|
|
55
|
+
|
|
56
|
+
## Generated URLs
|
|
57
|
+
|
|
58
|
+
Never predict generated page paths. Run `mint dev`, read each generated endpoint page's path from its sidebar link or URL, and use those for links and redirect destinations. Then run `mint broken-links` to catch any link or redirect that points at a page that does not exist. Paths come from the tag name and operation `summary`, lowercased with spaces turned into `-` and only `{}(),.'/` removed, so a tag like `[Integrations] AWS` becomes `[integrations]-aws`.
|
|
59
|
+
|
|
60
|
+
If the source URLs differ from the generated ones, set `x-mint: { href: "<old path>" }` on each operation to keep its old URL, or add `redirects` from each old endpoint URL (from the old sitemap). If tag names produce ugly slugs, tell the user rather than renaming tags silently, since tags may be shared with their SDK tooling.
|
|
61
|
+
|
|
62
|
+
## Pages that dump spec JSON
|
|
63
|
+
|
|
64
|
+
Some exports render each operation as a heading plus a large `openapi` JSON block. Once the spec is wired in, replace those blocks with a `<CardGroup cols={2}>` of cards linking to the generated pages (title from `summary`, body `` `METHOD /path` ``). Keep the page's intro prose.
|
|
65
|
+
|
|
66
|
+
## Supporting pages
|
|
67
|
+
|
|
68
|
+
Migrate overview, authentication, errors, rate limits, pagination, webhooks and SDK pages as normal content pages and list them in the API section of navigation.
|
|
69
|
+
|
|
70
|
+
Never write SDK or CLI reference content from memory. Every method, field and signature must come from the source docs or the SDK's code.
|
|
71
|
+
|
|
72
|
+
## Check
|
|
73
|
+
|
|
74
|
+
- Each spec is referenced from `docs.json`, and every `openapi` frontmatter value resolves to an operation. `mint validate` reports both.
|
|
75
|
+
- Open one generated or overlaid page per spec in `mint dev` and confirm method, path, auth and a code sample render.
|
|
76
|
+
- No spec file in `openapi/` is unreferenced.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Only when the source has a changelog, release notes or "What's new" section.
|
|
4
|
+
|
|
5
|
+
## Shape
|
|
6
|
+
|
|
7
|
+
If the source keeps each entry at its own URL, consolidate into one page of `<Update>` blocks, newest first. Do not create one `.mdx` per entry. If the source already has a single changelog page, convert it in place.
|
|
8
|
+
|
|
9
|
+
```mdx
|
|
10
|
+
---
|
|
11
|
+
title: 'Changelog'
|
|
12
|
+
rss: true
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
<Update
|
|
16
|
+
label="September 8, 2025"
|
|
17
|
+
description="New endpoints for company locations"
|
|
18
|
+
tags={['Added', 'API']}
|
|
19
|
+
>
|
|
20
|
+
Entry body, converted like any other page.
|
|
21
|
+
</Update>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
- `title` and `description` on the page follow the normal frontmatter rules.
|
|
25
|
+
- `label` is the date, `description` is the entry title, `tags` are the entry's type and categories as shown on the source. Do not invent tags.
|
|
26
|
+
- Every `label` must be unique on the page. When two entries share a date, add the time to both (`September 8, 2025 · 4:28 PM`); if no time is available, ask the user. Never put slugs or IDs in labels.
|
|
27
|
+
- Record each entry's source URL in the manifest.
|
|
28
|
+
|
|
29
|
+
Reference: https://www.mintlify.com/docs/create/changelogs.md
|
|
30
|
+
|
|
31
|
+
Past about 15 entries, generate the page with a script from the mirrored entries, and make sure the main transformer does not also emit per-entry pages.
|
|
32
|
+
|
|
33
|
+
## Dates
|
|
34
|
+
|
|
35
|
+
Use the publish date shown on, or embedded in, each entry page. Never use sitemap `<lastmod>`: hosted platforms rewrite it on every re-index, so it clusters many entries into a few recent dates. If no publish date is available, ask the user and report it.
|
|
36
|
+
|
|
37
|
+
Sanity check: the oldest and newest labels match the oldest and newest entries on the source. If more than about a third of entries share one week, you have re-index dates; go back and find real ones.
|
|
38
|
+
|
|
39
|
+
## URLs
|
|
40
|
+
|
|
41
|
+
Add a redirect from every per-entry URL to the consolidated page (with an anchor if you can match it):
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{ "source": "/changelog/new-company-location-endpoints", "destination": "/changelog" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Point in-repo links at the consolidated page directly. The source's changelog listing page has no separate counterpart; mark it `done` against the consolidated page.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Conversion
|
|
2
|
+
|
|
3
|
+
Turn each mirrored page into a Mintlify `.mdx` file. Preserve every heading, paragraph, list, table, code block and image. Do not summarize or reword.
|
|
4
|
+
|
|
5
|
+
Past about 50 pages, write a deterministic transformer script that reads the source (the repo, export or `mirror/`) and writes `.mdx`. When output is wrong, fix the rule and re-run the script; do not hand-patch generated files. Keep scripts outside the Mintlify project or list them in `.mintignore` (https://www.mintlify.com/docs/organize/mintignore.md).
|
|
6
|
+
|
|
7
|
+
Before writing the transformer, list every distinct custom tag, macro, directive, component, class and link scheme across the source and map each one. Unmapped constructs otherwise vanish or leak as raw text.
|
|
8
|
+
|
|
9
|
+
## Files
|
|
10
|
+
|
|
11
|
+
- Every page becomes an `.mdx` file.
|
|
12
|
+
- Mintlify never treats a file named `README.md` as a page, and serves `<dir>/index.mdx` at `/<dir>`. Rename a `README.md` that served its folder to `index.mdx`, and point links to `README.md` or `README` at the folder path.
|
|
13
|
+
- Partials and include targets are not pages; see Reusable content.
|
|
14
|
+
|
|
15
|
+
## Frontmatter
|
|
16
|
+
|
|
17
|
+
Every frontmatter field renders visibly: `title` is the page H1 and browser tab, `sidebarTitle` is the sidebar label, `description` is a subtitle under the H1, `icon` sits next to the sidebar entry. Copy from the source or omit. Never generate.
|
|
18
|
+
|
|
19
|
+
- `title`: the page's H1. Remove that H1 from the body so it does not render twice. If there is no H1, use the source's page title.
|
|
20
|
+
- `sidebarTitle`: only when the source nav label differs from the H1. If the nav label is longer than the H1, you extracted the wrong label (page `<title>`, breadcrumb, `og:title`); fix extraction.
|
|
21
|
+
- `description`: only when the source shows a subtitle or lead line directly under the title. Copy it verbatim, stripped of markdown and HTML. Never fall back to the first paragraph or a paraphrase of the title. No subtitle means no `description`. Many platforms use a frontmatter `description` only for meta tags, or derive one from the first paragraph; drop it unless the page showed it.
|
|
22
|
+
- `icon`: only when the source nav shows an icon for that page.
|
|
23
|
+
- Quote string values; if a value contains that quote character, use the other quote style. Never put JSX or HTML in frontmatter.
|
|
24
|
+
- Carry over other source frontmatter only when Mintlify has the same field with the same meaning; report the rest.
|
|
25
|
+
|
|
26
|
+
Reference: https://www.mintlify.com/docs/organize/pages.md
|
|
27
|
+
|
|
28
|
+
## Components
|
|
29
|
+
|
|
30
|
+
Map source patterns to Mintlify components only when the meaning matches:
|
|
31
|
+
|
|
32
|
+
| Source | Mintlify |
|
|
33
|
+
| ------------------------------------------ | ------------------------------------------------------------------------ |
|
|
34
|
+
| Note / info / tip / warning / danger boxes | `<Note>`, `<Info>`, `<Tip>`, `<Warning>`, `<Danger>` |
|
|
35
|
+
| Numbered procedures rendered as steps | `<Steps>` / `<Step title="...">` |
|
|
36
|
+
| Tabbed content | `<Tabs>` / `<Tab title="...">` |
|
|
37
|
+
| Same snippet in several languages | `<CodeGroup>` |
|
|
38
|
+
| Collapsible sections, FAQs | `<Accordion>` / `<AccordionGroup>` |
|
|
39
|
+
| Link tiles, feature grids | `<Card>` inside `<CardGroup cols={2}>` or `<Columns>` |
|
|
40
|
+
| API parameter and response lists | `<ParamField>` / `<ResponseField>` |
|
|
41
|
+
| Inline definitions | `<Tooltip>` |
|
|
42
|
+
| Code blocks | fenced blocks with a language, plus `filename` when the source shows one |
|
|
43
|
+
|
|
44
|
+
Typed callouts (`<Note>`, `<Tip>`, `<Info>`, `<Warning>`, `<Danger>`, `<Check>`) take no `title` prop. Put a source callout title as a bold first line inside the callout; drop a title that only restates the type.
|
|
45
|
+
|
|
46
|
+
If the structure is ambiguous, leave it as plain markdown. A broken component is worse than a plain paragraph. Source components with no equivalent (interactive widgets, custom React or Vue, embeds) become a component snippet (Reusable content) or the closest static rendering of their content, and go in the report. Delete imports of the platform's component libraries once their usages are converted. Framework image and link components (`next/image`, `next/link`, `astro:assets` `<Image>`) become markdown images and links.
|
|
47
|
+
|
|
48
|
+
Reference: https://www.mintlify.com/docs/components/index.md
|
|
49
|
+
|
|
50
|
+
## Common source syntax
|
|
51
|
+
|
|
52
|
+
Several platforms share these. Source guides list their exceptions.
|
|
53
|
+
|
|
54
|
+
**Admonitions.** `:::type`, `!!! type` and similar blocks map by type:
|
|
55
|
+
|
|
56
|
+
| Type | Mintlify |
|
|
57
|
+
| ------------------------------------------- | ----------- |
|
|
58
|
+
| `note`, `example` | `<Note>` |
|
|
59
|
+
| `info`, `important`, `abstract`, `question` | `<Info>` |
|
|
60
|
+
| `tip` | `<Tip>` |
|
|
61
|
+
| `success` | `<Check>` |
|
|
62
|
+
| `warning`, `caution` | `<Warning>` |
|
|
63
|
+
| `danger`, `failure`, `bug` | `<Danger>` |
|
|
64
|
+
| `quote` | blockquote |
|
|
65
|
+
| unknown | `<Note>` |
|
|
66
|
+
|
|
67
|
+
For `:::` containers, pair openers and closers before converting: a closing fence closes the nearest open container whose opening fence is no longer than it, so nested containers use a longer outer fence (`::::`). Text after the type on the opening line, or a `[Title]` label, is the title. An unclosed container runs to the end of its parent; a stray closer renders as text. If the old site already showed literal `:::`, report it rather than guessing the meaning.
|
|
68
|
+
|
|
69
|
+
**GitHub alerts.** `> [!NOTE]` → `<Note>`, `[!TIP]` → `<Tip>`, `[!IMPORTANT]` → `<Info>`, `[!WARNING]` → `<Warning>`, `[!CAUTION]` → `<Danger>`. Remove the marker line and the `> ` prefix from every line, including lazy-continuation lines. Text after the marker is the title. Convert them only where the platform rendered them as alerts; elsewhere they were plain quotes.
|
|
70
|
+
|
|
71
|
+
**Package-manager tabs.** Fences that the platform expanded into one tab per package manager (`npm2yarn`, ` ```npm ` and similar) become one `<CodeGroup>` with one fence per manager the live page showed, each titled with the manager name and holding the command as the live page translated it.
|
|
72
|
+
|
|
73
|
+
**Heading IDs.** Custom ids in any source syntax (`[#id]`, `{/* #id */}`, `{ #id }`, `:id=id`) become `## Heading {#id}`. Each platform slugifies headings differently from Mintlify: diff the old build's heading ids against `mint dev` and pin every anchor that content or inbound links target with `{#old-id}`.
|
|
74
|
+
|
|
75
|
+
**Code imports.** Directives that pull a source file into a fence (whole file, line range, region or anchor) become a fenced block holding exactly the selected lines, with the language, title and highlight meta carried over. Report each as a copy that will no longer track the file, or keep a prebuild script that regenerates it and say so. Fence options: https://www.mintlify.com/docs/create/code.md
|
|
76
|
+
|
|
77
|
+
**Template tags.** Never leave `{%` in MDX. Mintlify reads `{{name}}` as a `docs.json` `variables` entry (https://www.mintlify.com/docs/organize/settings-structure.md).
|
|
78
|
+
|
|
79
|
+
- Site-wide values: a `variables` entry used as `{{name}}`. Rename any name the schema rejects and record the mapping in the report. Take each value from the source config or a rendered page; never guess one.
|
|
80
|
+
- Page values (`page.x`, `$frontmatter.x`): inline the literal value.
|
|
81
|
+
- Logic (`if`, `for`, `assign`, `capture`, macro calls): replace with the output the production site showed; report each.
|
|
82
|
+
- `raw` wrappers: remove, keeping the content.
|
|
83
|
+
|
|
84
|
+
## Reusable content
|
|
85
|
+
|
|
86
|
+
Includes, partials and reusable blocks become snippets. An imported `.md` or `.mdx` file is a snippet, not a page, wherever it lives; files under `snippets/` always are, and any `.jsx` or `.tsx` file is a component snippet. Imports resolve against the importing file (`./x.mdx`, `../shared/x.mdx`) or the project root (`/shared/x.mdx`). Render with `import X from "./x.mdx"` and `<X />`; include parameters become props, read as `{param}` inside the snippet. Snippets never appear in navigation.
|
|
87
|
+
|
|
88
|
+
- **Source keeps its partials** (repo, or an export that ships them): each partial becomes exactly one snippet, imported wherever the source included it. Never paste copies. Keep the source's file layout and relative imports where they still resolve instead of moving everything into `/snippets/`.
|
|
89
|
+
- **Reuse already expanded** (most exports, live site): consolidate copies into one snippet only where they are identical.
|
|
90
|
+
- **Unused partials.** A partial nothing imports would publish as an orphan page. Do not copy it, or list it in `.mintignore`, and record it as `excluded` in the manifest.
|
|
91
|
+
- **Components.** Carry self-contained `.jsx`/`.tsx` components over as snippets, within the constraints at https://www.mintlify.com/docs/customize/react-components.md. Rename `.js` component files to `.jsx`: Mintlify loads every `.js` file as a site-wide script. One that imports an npm package other than `react` needs third-party libraries (https://www.mintlify.com/docs/customize/third-party-libraries.md); ask the user before relying on it. Components bound to the source framework (theme hooks, `next/*`, `@docusaurus/*`, Astro, Vue) map to Mintlify components or go in the report.
|
|
92
|
+
- **Single values** (product name, version) are `variables`, not snippets (Template tags above).
|
|
93
|
+
|
|
94
|
+
Reference: https://www.mintlify.com/docs/create/reusable-snippets.md
|
|
95
|
+
|
|
96
|
+
## MDX safety
|
|
97
|
+
|
|
98
|
+
MDX parses everything outside code fences as JSX. Normalize:
|
|
99
|
+
|
|
100
|
+
- `<https://example.com>` autolinks: use the bare URL.
|
|
101
|
+
- A bare `<` in prose (`<= v1.2`, `use < for less than`): `<`.
|
|
102
|
+
- Placeholders like `<bucket-name>` in prose: wrap in backticks. Do not add backticks inside an existing inline code span.
|
|
103
|
+
- `{` and `}` in prose, tables and HTML cells: escape as `\{` `\}`.
|
|
104
|
+
- HTML: self-close void elements (`<br />`, `<img />`), use `className` not `class`, and `style={{ ... }}` objects, not strings.
|
|
105
|
+
- Component tags and fences go on their own lines with a blank line around them. `1. Do this. <Info>` becomes a list item, blank line, `<Info>`.
|
|
106
|
+
- Keep every component and fence balanced. Never emit a closing tag with no opener.
|
|
107
|
+
- Attribute values containing double quotes: use single quotes (`<Step title='Click "Save"'>`), not backslash escapes.
|
|
108
|
+
- Strip leftover wrapper `<div>`s from the source platform after converting their contents.
|
|
109
|
+
|
|
110
|
+
## Links
|
|
111
|
+
|
|
112
|
+
Rewrite internal links to root-absolute paths:
|
|
113
|
+
|
|
114
|
+
1. Find markdown links (not images) and `<a href>`.
|
|
115
|
+
2. Skip `http(s):`, `mailto:`, `tel:`, `#` and targets already starting with `/`.
|
|
116
|
+
3. Split off `#fragment` and `?query` and keep them.
|
|
117
|
+
4. Strip `.md`, `.mdx` and `.html`.
|
|
118
|
+
5. Resolve against the current file's directory. If the result escapes the repo root, leave the link alone and report it.
|
|
119
|
+
6. Prefix `/`.
|
|
120
|
+
|
|
121
|
+
Absolute links to the old docs domain become root-absolute paths too.
|
|
122
|
+
|
|
123
|
+
When the source links pages by id or title, build an id/title → path index from the whole inventory first, then rewrite links in a second pass. Links into content you did not migrate stay absolute and go in the report.
|
|
124
|
+
|
|
125
|
+
## Images and files
|
|
126
|
+
|
|
127
|
+
Download every image and linked file into the repo (for example `images/<page-path>/`) and point to it with a root-absolute path. Folders the platform served at the site root (`public/`, `static/`) are copied to the same paths at the Mintlify project root, so root-absolute URLs keep working without rewrites.
|
|
128
|
+
|
|
129
|
+
Exports and scraped pages often reference images by hosted URL without shipping the files. Collect every hosted asset URL from page bodies and embedded JSON blocks, download the original file (not a resized proxy), and rewrite the references. Keep alt text. If an image URL contains parentheses or spaces, use `<img src="/images/a (1).png" alt="..." />` instead of `![]()`, which breaks on them. macOS screenshot filenames put U+202F (narrow no-break space) before `AM`/`PM`, which the link checker does not match to a regular space: replace it with a space in both the filename and every reference (find them with `rg -l $'\u202f'`). Report any asset you could not download.
|
|
130
|
+
|
|
131
|
+
Reference: https://www.mintlify.com/docs/create/image-embeds.md
|
|
132
|
+
|
|
133
|
+
## Port artifacts
|
|
134
|
+
|
|
135
|
+
Scraping composed widgets (cards, steps, tiles) to markdown leaves patterns that parse cleanly but render broken. Detect and fix them in the transformer before writing MDX.
|
|
136
|
+
|
|
137
|
+
- **A. Card link smash.** `[💬\n\n#### Title\n\nBody](/path)` becomes `<Card title="Title" icon="comments" href="/path">Body</Card>`.
|
|
138
|
+
- **B. Inline emoji card.** `[📋Sample apps](/path)` becomes `<Card title="Sample apps" icon="clipboard" href="/path" />`.
|
|
139
|
+
- **C. Link-wrapped steps.** `[1\n\n### Title\n\nBody](/path)` repeated becomes `<Steps>` with one `<Step title="Title">` each; the link goes at the end of the step body.
|
|
140
|
+
- **D. Orphan card.** An emoji line, a blank line, `#### Title`, then body, with no link around it. Consecutive triples become one `<CardGroup cols={2}>`. There are no brackets to search for, so test the detector on a known example.
|
|
141
|
+
- **E. `prism-code` fences.** Replace with the real language, detected from content (`import` python, `SELECT` sql, `{` json, `$ ` bash).
|
|
142
|
+
- **F. Admonition in frontmatter.** `description: ":::warning ..."` means the body admonition leaked. Remove the description (it was never a subtitle) and convert the body admonition.
|
|
143
|
+
- **G. Escaped placeholders.** `<name>` in prose renders literally; raw `<name>` breaks parsing. Both become `` `<name>` ``.
|
|
144
|
+
- **H. Stacked rules.** Consecutive `---` with nothing between them collapse into one or none.
|
|
145
|
+
- **I. Whole-page link.** An index page whose body is one giant `[...](...)`. Rebuild as a `<CardGroup>` with one card per entry. Find these by reading index and overview pages.
|
|
146
|
+
- **J. Chrome leakage.** "Copy page", "Edit on GitHub", "Was this helpful?", breadcrumbs, "On this page", prev/next footers. Strip during extraction.
|
|
147
|
+
- **K. Empty table header.** A header row of empty cells (`| | |`) renders as a blank strip. Rebuild real headers from the source, or drop the empty row so the first body row becomes the header.
|
|
148
|
+
- **L. Inlined generated data.** Machine-generated reference pages (field explorers, catalogs) scrape as huge inlined JSON. Write a dedicated converter that emits tables or `<ResponseField>` from that data.
|
|
149
|
+
|
|
150
|
+
Detector. Save it outside the docs folder, run `python3 detect.py mirror/` to plan transformer rules (ignore G on HTML mirrors), and `python3 detect.py .` on the converted repo until it prints nothing:
|
|
151
|
+
|
|
152
|
+
````python
|
|
153
|
+
import re, sys, pathlib
|
|
154
|
+
E = '[\U0001F000-\U0001FFFF☀-➿]'
|
|
155
|
+
P = {
|
|
156
|
+
'A': rf'\[\s*{E}[^\]]*?####[^\]]*?\]\([^)]+\)',
|
|
157
|
+
'B': rf'\[{E}+[A-Z][^\]]+\]\([^)]+\)',
|
|
158
|
+
'C': r'\[\s*\d+\s*\n\s*\n\s*###[^\]]+\]\([^)]+\)',
|
|
159
|
+
'D': rf'(?m)^{E}\s*\n\s*\n####\s',
|
|
160
|
+
'E': r'```prism-code',
|
|
161
|
+
'F': r'(?m)^description:\s*"?:::',
|
|
162
|
+
'G': r'<[A-Za-z0-9_-]+>',
|
|
163
|
+
'H': r'(?m)^---\s*\n\s*\n---\s*$',
|
|
164
|
+
'J': r'(?m)^(Copy page|Edit on GitHub|Edit this page|Was this (page )?helpful)',
|
|
165
|
+
'K': r'(?m)^\|(\s*\|)+\s*$',
|
|
166
|
+
}
|
|
167
|
+
for f in pathlib.Path(sys.argv[1]).rglob('*'):
|
|
168
|
+
if f.is_file() and f.suffix in ('.md', '.mdx', '.json', '.html'):
|
|
169
|
+
t = f.read_text(errors='ignore')
|
|
170
|
+
hits = [k for k, p in P.items() if re.search(p, t, re.S)]
|
|
171
|
+
if hits:
|
|
172
|
+
print(f, ' '.join(hits))
|
|
173
|
+
````
|
|
174
|
+
|
|
175
|
+
## Icons
|
|
176
|
+
|
|
177
|
+
Mintlify icons default to Font Awesome (https://www.mintlify.com/docs/components/icons.md). Unknown names render as a blank slot, so never guess. Iconify names (`i-lucide-*`, `i-heroicons-*`, `i-simple-icons-*`) do not resolve: map each to an icon in the configured `icons.library` only on a clear match, otherwise drop it and report it.
|
|
178
|
+
|
|
179
|
+
Emoji used as icons:
|
|
180
|
+
|
|
181
|
+
| Emoji | Icon | Emoji | Icon |
|
|
182
|
+
| ----- | ------------------ | ----- | ----------------- |
|
|
183
|
+
| 💬 | `comments` | 🔗 | `link` |
|
|
184
|
+
| 🤖 | `robot` | 🛡️ | `shield-halved` |
|
|
185
|
+
| 🔍 | `magnifying-glass` | 🧠 | `brain` |
|
|
186
|
+
| 📊 | `chart-column` | ⚡ | `bolt` |
|
|
187
|
+
| 🧪 | `flask` | 🌐 | `globe` |
|
|
188
|
+
| 📝 | `note-sticky` | 🚀 | `rocket` |
|
|
189
|
+
| 📄 | `file-lines` | 🔌 | `plug` |
|
|
190
|
+
| 📋 | `clipboard` | 🔧 | `wrench` |
|
|
191
|
+
| ⚙️ | `gear` | ❓ | `circle-question` |
|
|
192
|
+
| 🤝 | `handshake` | | |
|
|
193
|
+
|
|
194
|
+
For anything else, pick the closest free icon from https://fontawesome.com/search?o=r&m=free.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Discovery
|
|
2
|
+
|
|
3
|
+
Build a complete inventory of source pages before writing any MDX. Most migration gaps come from pages nobody found.
|
|
4
|
+
|
|
5
|
+
## Get the source
|
|
6
|
+
|
|
7
|
+
There are three ways in. Prefer them in this order: repo, export, live site. If it is unclear which the user has, ask. Each source guide (`mint migrate --from <name>`) lists that platform's specifics under the same three headings.
|
|
8
|
+
|
|
9
|
+
**Source of truth.** With the platform's source (a repo, or an export that includes its config and nav files), the code is the source of truth: navigation, labels, order, nesting, tabs, URLs and the OpenAPI spec are exactly what it declares. Use the live site only to fill gaps the code does not cover. Only when scraping (the live-site route, or an export without nav data) do you reconstruct structure, and only then does cleanup judgment apply.
|
|
10
|
+
|
|
11
|
+
Wherever the source comes from, never modify or delete it. Write the Mintlify project to a separate directory: ask the user where if it is not obvious, otherwise create a new folder. Never overwrite existing content.
|
|
12
|
+
|
|
13
|
+
### From the repo
|
|
14
|
+
|
|
15
|
+
- Docs are often a subfolder of a larger product repo or monorepo. Find the docs root and the platform config before inventorying.
|
|
16
|
+
- Convert from the repo files directly; the `mirror/` download step does not apply.
|
|
17
|
+
- If the repo builds, build the old site once with the tool and plugins its CI pins, into a folder outside both projects. Its output is the old URL list (`sitemap.xml` or the emitted `.html` files) and the record of what includes, macros and plugins actually rendered. Convert from source; check output against the build.
|
|
18
|
+
- If the user wants the Mintlify project inside the source repo instead, add the platform's config, theme source, `node_modules/` and build output to `.mintignore`. Mintlify loads every `.js` and `.css` file in the content directory on every page.
|
|
19
|
+
|
|
20
|
+
Reference: https://www.mintlify.com/docs/organize/mintignore.md
|
|
21
|
+
|
|
22
|
+
### From an export
|
|
23
|
+
|
|
24
|
+
- Unzip each export into its own folder and treat it as read-only source, like a repo.
|
|
25
|
+
- Inspect its layout (folder structure and a few files of each type) before assuming one. Layouts vary by platform, editor and version.
|
|
26
|
+
- An export covers only what its options and the exporting user's access included. Reconcile it against the live site's page list and report anything missing.
|
|
27
|
+
|
|
28
|
+
### From the live site
|
|
29
|
+
|
|
30
|
+
Mirror the raw source (below), then convert from the mirror. Find pages with:
|
|
31
|
+
|
|
32
|
+
- **Sitemap.** Fetch `/sitemap.xml`. If the root element is `<sitemapindex>`, fetch every child `<sitemap><loc>` and merge their `<url><loc>` entries, recursing through nested indexes. The index itself is not the URL list.
|
|
33
|
+
- **Machine-readable indexes.** `llms.txt`, `llms-full.txt`, search index JSON, route manifests, framework payloads.
|
|
34
|
+
- **Raw endpoints.** `<url>.md` or a JSON content payload per page, where the platform serves one. Rendered HTML only as a fallback.
|
|
35
|
+
|
|
36
|
+
## Find every page
|
|
37
|
+
|
|
38
|
+
Combine every source the route offers, then dedupe:
|
|
39
|
+
|
|
40
|
+
- **Navigation.** Header tabs, every sidebar (each tab can have its own), footer links, "next/previous" and related-page links.
|
|
41
|
+
- **In-page links.** Follow internal docs links recursively. Stop only after two consecutive passes find zero new in-scope pages.
|
|
42
|
+
- **Variants.** Versions and languages, if present. Ask the user which versions and languages to migrate; record the rest as `excluded` with a reason.
|
|
43
|
+
|
|
44
|
+
For a repo or export, the file tree plus the platform's nav config (sidebar file, `SUMMARY.md`, `mkdocs.yml` and so on) is the inventory. Still check for pages the config references but the tree lacks, and files the config never references.
|
|
45
|
+
|
|
46
|
+
Normalize every URL: drop `#fragments`, pick one trailing-slash form and use it everywhere, and dedupe query-only variants unless they serve different content.
|
|
47
|
+
|
|
48
|
+
## Manifest
|
|
49
|
+
|
|
50
|
+
Keep `migration-manifest.json` at the root of the Mintlify project, one entry per discovered page:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"source_url": "https://docs.example.com/guides/setup",
|
|
55
|
+
"source_title": "Setting up your workspace",
|
|
56
|
+
"source_sidebar_label": "Setup",
|
|
57
|
+
"nav_section": "Guides > Getting started",
|
|
58
|
+
"converted_file": "guides/setup.mdx",
|
|
59
|
+
"status": "todo",
|
|
60
|
+
"notes": ""
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
`status` is one of `todo`, `done`, `excluded`, `blocked`. `excluded` and `blocked` need a concrete reason in `notes`; `blocked` also needs the next step (for example "private section; needs an export that includes it").
|
|
65
|
+
|
|
66
|
+
If the source links pages by id or title, record each page's id and title here too; link rewriting needs them (`mint migrate --topic conversion`, Links).
|
|
67
|
+
|
|
68
|
+
## Mirror the raw source
|
|
69
|
+
|
|
70
|
+
Live-site route only. Download every page into `mirror/`, one file per URL, before converting. Prefer the most structured endpoint the platform offers: raw markdown, a JSON content payload, then rendered HTML. Add `mirror/`, transformer scripts and the manifest to `.mintignore`.
|
|
71
|
+
|
|
72
|
+
Fetch in parallel for large sites:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
xargs -P 20 -I {} sh -c 'curl -sSL --max-time 30 -o "mirror/$(echo {} | sed "s#https://docs.example.com/##; s#/#__#g").md" "{}.md"' < urls.txt
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Validate the mirror before converting:
|
|
79
|
+
|
|
80
|
+
- A file starting with `<!DOCTYPE html>` or `<html` is a failed fetch: the endpoint served rendered HTML. Try another endpoint or scrape that page.
|
|
81
|
+
- Site and section roots do not always answer on `<root>.md` the way leaf pages do. Spot-check each with `curl -sS <url>.md | head -3`; the source guide names the working pattern.
|
|
82
|
+
- Platform `.md` endpoints add text that is not page content: a header line or block, generated frontmatter, and footer sections. The source guide lists them. Strip them before converting.
|
|
83
|
+
|
|
84
|
+
## Missing pages
|
|
85
|
+
|
|
86
|
+
When a URL fails, tell two cases apart:
|
|
87
|
+
|
|
88
|
+
- **Wrong endpoint.** The page exists but the raw endpoint does not resolve for it. Try the alternatives above, then the rendered page.
|
|
89
|
+
- **Stale sitemap entry.** The URL 404s on every endpoint, including the rendered page. Sitemaps often keep removed pages. Mark it `excluded` with `notes: "404 on all endpoints"` and leave it out of navigation.
|
|
90
|
+
|
|
91
|
+
## Gated content
|
|
92
|
+
|
|
93
|
+
If pages sit behind a login, paywall or private visibility, do not guess their content and never ask for credentials. Mark them `blocked` and ask the user for an export that includes them.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Navigation and docs.json
|
|
2
|
+
|
|
3
|
+
`docs.json` should reproduce the source site's structure and chrome, nothing more. Look up the current schema at https://www.mintlify.com/docs/organize/settings.md before writing it.
|
|
4
|
+
|
|
5
|
+
## Build navigation from the source's nav data
|
|
6
|
+
|
|
7
|
+
Most platforms publish their sidebar as data (a sidebar file, `SUMMARY.md`, a nav key in the config, a JSON payload). Use it instead of inferring structure from folders. The source guide names it (`mint migrate --from <name>`); for anything else, use the rendered sidebar of each section.
|
|
8
|
+
|
|
9
|
+
Walk that tree and emit Mintlify's shape, keeping group order, labels and nesting depth verbatim. Leaf URLs become repo-relative paths without `.mdx`. Generate `docs.json` with a script past about 50 pages.
|
|
10
|
+
|
|
11
|
+
Reference: https://www.mintlify.com/docs/organize/navigation.md
|
|
12
|
+
|
|
13
|
+
Only when the source has no nav data and no readable sidebar, fall back to the directory tree: one group per directory, the directory's index or overview page first, titles from the source.
|
|
14
|
+
|
|
15
|
+
Fetch sidebars as raw HTML (`curl`) and parse the list structure. Text-only page summaries flatten nested groups and lose the hierarchy.
|
|
16
|
+
|
|
17
|
+
## Structure rules
|
|
18
|
+
|
|
19
|
+
- **Nesting.** A sidebar entry with children is a nested group: `{ "group": "Parent", "pages": ["parent/index", "parent/child"] }`. The parent page goes first and gets `sidebarTitle: "Overview"` only if the source labels it that way; otherwise keep its source label. Never flatten children into siblings.
|
|
20
|
+
- **Per-tab sidebars.** Each top-level section with its own sidebar becomes a tab (or product) with its own `groups`, mirroring that section's sidebar. Pages not in a section's source sidebar do not go in that tab. Never dump leftovers into a catch-all "Reference" or "Misc" group.
|
|
21
|
+
- **Surfaces.** Use root `groups`, `tabs`, `products` and `versions` the way the source presents its sections. From source code, use exactly what the code declares.
|
|
22
|
+
- **No invented icons.** Add `icon` to tabs, groups or pages only where the source shows an icon.
|
|
23
|
+
- **External links in the top row** stay in the same surface as the rest of the row: `{ "tab": "Status", "href": "https://..." }`.
|
|
24
|
+
- **Orphans.** Every converted page appears in navigation exactly once. If the source had pages reachable only by link, ask the user where they belong or put them in `"hidden": true` groups, and report it.
|
|
25
|
+
- **Versions and languages** map to `navigation.versions` / `navigation.languages` only if the user chose to migrate them.
|
|
26
|
+
- **Untranslated locale pages.** If the source served default-language content at `/<locale>/page` for pages with no translation, do not create duplicate pages: redirect each such URL to the default-language page and report the list.
|
|
27
|
+
|
|
28
|
+
Hidden pages: https://www.mintlify.com/docs/organize/hidden-pages.md
|
|
29
|
+
|
|
30
|
+
## Reconstructed navigation
|
|
31
|
+
|
|
32
|
+
Only when scraping, where no code declares the navigation (`mint migrate --topic discovery`, Get the source):
|
|
33
|
+
|
|
34
|
+
- Put each section's landing or overview page first in its group.
|
|
35
|
+
- Keep the site root `index` out of sidebar groups unless the source shows a Home row.
|
|
36
|
+
- Flatten a single-page group whose label duplicates the page's title.
|
|
37
|
+
- Put icons on top-level sections only.
|
|
38
|
+
- Set `expanded: false` only on nested groups, and only when the source's sections were collapsible.
|
|
39
|
+
- Do not add tabs or switchers just to fill the header.
|
|
40
|
+
|
|
41
|
+
With source code, never apply these where they would change what the code declares. If the declared navigation looks broken, report it instead of restructuring.
|
|
42
|
+
|
|
43
|
+
## Chrome
|
|
44
|
+
|
|
45
|
+
Default is remove. Add each element only after confirming it on the source:
|
|
46
|
+
|
|
47
|
+
- `name`, `logo` (light and dark), `favicon`, `colors.primary`: from the source site. Download the files.
|
|
48
|
+
- `navbar.links`: only the right-hand utility links the source shows.
|
|
49
|
+
- `navbar.primary`: only if the source has a CTA button.
|
|
50
|
+
- `navigation.global.anchors`: only if the source has a persistent anchor list at the top of the sidebar.
|
|
51
|
+
- `footer.socials` and `footer.links`: only what the source footer shows.
|
|
52
|
+
- `seo.metatags`: mirror the source's meta tags where Mintlify supports them.
|
|
53
|
+
|
|
54
|
+
`mint init` and templates add starter defaults (example anchors, social links, CTA buttons, placeholder colors). Remove every default the source does not have. Each chrome item lives in exactly one surface; nothing appears in both `navigation.tabs` and `navbar.links`.
|
|
55
|
+
|
|
56
|
+
Analytics, search, feedback widgets, custom scripts and custom CSS do not migrate automatically. List them in the report with what Mintlify offers instead.
|
|
57
|
+
|
|
58
|
+
Mintlify loads every `.css` and `.js` file in the content directory on every page; scripts run everywhere except the editor's live preview. Selectors and scripts written for the old theme's DOM match nothing: port only real brand rules. Delete MathJax, KaTeX and Mermaid loaders; Mintlify renders math and Mermaid natively.
|
|
59
|
+
|
|
60
|
+
Reference: https://www.mintlify.com/docs/organize/settings-structure.md, https://www.mintlify.com/docs/customize/custom-scripts.md
|
|
61
|
+
|
|
62
|
+
## Redirects
|
|
63
|
+
|
|
64
|
+
Every source URL must keep working. Write redirects to `redirects.json` at the project root and reference it from `docs.json` with `"redirects": { "$ref": "./redirects.json" }`. If `docs.json` already has inline `redirects`, move them into the file. For each page whose path changes, add an entry:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
[{ "source": "/old/path", "destination": "/new/path" }]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Include old trailing-slash forms if the source served them, removed sections the user wants to point somewhere, and per-entry changelog URLs. Do not redirect a path to itself, and do not chain redirects. A redirect source can be `/`.
|
|
71
|
+
|
|
72
|
+
- **Wildcards.** Nothing matches a suffix and there is no regex.
|
|
73
|
+
- **`.html` URLs.** When the old site served `/a/b.html`, add one exact redirect per page from `/a/b.html` to `/a/b`, generated from the old build output or sitemap. Skip index URLs that still resolve.
|
|
74
|
+
- **Base path.** If every old URL sat under a prefix (`baseUrl`, `basePath`, `base`, `routeBasePath`) that the Mintlify site drops, add one `/<prefix>/:slug*` → `/:slug*` redirect.
|
|
75
|
+
- **Existing redirect config.** Port the source's own redirects: static pairs and trailing `:name*` patterns carry over; temporary redirects get `"permanent": false`. A single-segment `:name` (no `*`) is matched literally, so expand it, and entries using regex, query or header conditions, into exact paths, or report them.
|
|
76
|
+
- **Hash and query URLs.** Fragments and query strings never reach the server, so no redirect can match them. Pin heading ids instead (`mint migrate --topic conversion`, Heading IDs) and report the rest.
|
|
77
|
+
|
|
78
|
+
Reference: https://www.mintlify.com/docs/create/redirects.md, https://www.mintlify.com/docs/organize/settings.md
|
|
79
|
+
|
|
80
|
+
## Check the file
|
|
81
|
+
|
|
82
|
+
After every structural edit run `mint validate`. Then compare navigation against disk, on any route: every `.mdx` is listed exactly once, with no missing pages, dangling paths or duplicates. Collect page strings recursively from `tabs`, `products`, `versions`, `groups` and `pages`; never count `group` or `tab` labels as page paths.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Verify
|
|
2
|
+
|
|
3
|
+
A migration is done when the checks below are clean. Never fix a finding by deleting or emptying a page, removing a section, or dropping a page from navigation. Fix the conversion rule and re-run it.
|
|
4
|
+
|
|
5
|
+
## 1. Parse and validate
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
mint validate
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Run it after every conversion batch. Fix every error, starting with parse errors; they hide the rest. Common ones:
|
|
12
|
+
|
|
13
|
+
- `Could not parse expression with acorn`: unescaped `{`, `}` or `<` in prose. See `mint migrate --topic conversion`, MDX safety.
|
|
14
|
+
- `Expected a closing tag for <Warning>` / `Unexpected closing tag`: an unbalanced component, often a tag on the same line as prose or a source `</div>` left behind.
|
|
15
|
+
- `Unexpected character` in an attribute name: backslash-escaped quotes inside an attribute.
|
|
16
|
+
|
|
17
|
+
Open the exact file and line reported. If one file in a batch fails, fix that file's rule before converting more.
|
|
18
|
+
|
|
19
|
+
Flags for `mint validate` and `mint broken-links`: https://www.mintlify.com/docs/cli/commands.md
|
|
20
|
+
|
|
21
|
+
## 2. Links
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
mint broken-links
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Every internal link must resolve. A broken link usually means a missed rewrite (relative path, `.md` extension, old domain), a page converted to a different path than its links expect, or a page that was never converted. Fix the link or convert the page. Do not delete the link.
|
|
28
|
+
|
|
29
|
+
## 3. Content sweeps
|
|
30
|
+
|
|
31
|
+
`mint validate` passes content that renders broken. Run the port-artifact detector from `mint migrate --topic conversion` on the repo; it must print nothing. Then also check:
|
|
32
|
+
|
|
33
|
+
- Files ending in ` 2.mdx` or folders ending in ` 2` (copy artifacts): delete them.
|
|
34
|
+
- Pages with an empty body or only a heading.
|
|
35
|
+
- Leftover source syntax: `:::`, `{% `, `{{< `, `.. directive::`, raw `<div class=`.
|
|
36
|
+
- Images that 404: every `src` under `/images/` (or wherever you put assets) exists on disk.
|
|
37
|
+
- Read 10 to 20 pages against the source, including index pages, the longest page, and pages with tabs, steps or tables. Every section, list item, table row and code block should be present.
|
|
38
|
+
|
|
39
|
+
## 4. Structure
|
|
40
|
+
|
|
41
|
+
Pick 5 to 10 pages at random, plus every index and overview page, and compare each against its source: section order, heading text, and the number of cards, steps, tabs, code blocks and tables. A mismatch means a transformer rule is wrong: fix the rule and regenerate, never hand-patch.
|
|
42
|
+
|
|
43
|
+
## 5. Parity
|
|
44
|
+
|
|
45
|
+
Reconcile `migration-manifest.json`:
|
|
46
|
+
|
|
47
|
+
- Every entry is `done`, `excluded` or `blocked`. Nothing is `todo`.
|
|
48
|
+
- `excluded` and `blocked` entries have a concrete reason; `blocked` entries have a next step.
|
|
49
|
+
- Count manifest rows by status: discovered = done + excluded + blocked. Several `done` rows may share one output file (changelog entries merged into one page).
|
|
50
|
+
- Every `done` row's file exists and is in `docs.json` navigation. Every navigation page maps back to at least one row, except pages the user asked you to add.
|
|
51
|
+
- Every source URL resolves on `mint dev`, directly or through a redirect. Spot-check with `curl -sI http://localhost:3000/<old-path>`.
|
|
52
|
+
- Re-crawl the converted site's links once. Any in-scope source page it reaches that is not in the manifest was missed in discovery.
|
|
53
|
+
|
|
54
|
+
## 6. Preview
|
|
55
|
+
|
|
56
|
+
Run `mint dev` and click through each tab: the sidebar matches the source's sidebar for that section, the home page renders, and an API page shows its playground if there is one.
|
|
57
|
+
|
|
58
|
+
Report to the user only after `mint validate` and `mint broken-links` are clean and the parity counts match.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1765",
|
|
4
4
|
"description": "The Mintlify CLI",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@inquirer/prompts": "7.9.0",
|
|
48
|
-
"@mintlify/common": "1.0.
|
|
49
|
-
"@mintlify/link-rot": "3.0.
|
|
50
|
-
"@mintlify/models": "0.0.
|
|
51
|
-
"@mintlify/og": "0.0.
|
|
52
|
-
"@mintlify/prebuild": "1.0.
|
|
53
|
-
"@mintlify/previewing": "4.0.
|
|
54
|
-
"@mintlify/validation": "0.1.
|
|
48
|
+
"@mintlify/common": "1.0.1320",
|
|
49
|
+
"@mintlify/link-rot": "3.0.1557",
|
|
50
|
+
"@mintlify/models": "0.0.381",
|
|
51
|
+
"@mintlify/og": "0.0.119",
|
|
52
|
+
"@mintlify/prebuild": "1.0.1492",
|
|
53
|
+
"@mintlify/previewing": "4.0.1575",
|
|
54
|
+
"@mintlify/validation": "0.1.951",
|
|
55
55
|
"adm-zip": "0.6.0",
|
|
56
56
|
"chalk": "5.2.0",
|
|
57
57
|
"color": "4.2.3",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"keytar": "7.9.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@mintlify/editor": "0.0.
|
|
90
|
+
"@mintlify/editor": "0.0.593",
|
|
91
91
|
"@mintlify/ts-config": "2.0.2",
|
|
92
92
|
"@tsconfig/recommended": "1.0.2",
|
|
93
93
|
"@types/detect-port": "1.3.2",
|
|
@@ -106,5 +106,5 @@
|
|
|
106
106
|
"vitest": "2.1.9",
|
|
107
107
|
"vitest-mock-process": "1.0.4"
|
|
108
108
|
},
|
|
109
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "8cbfe9508ed4441f6c6aad9afd306f097cf1ad91"
|
|
110
110
|
}
|