@model-go/docs-core 0.1.0
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/README.md +77 -0
- package/assets/images/agents/cc-switch/claude-add.webp +0 -0
- package/assets/images/agents/cc-switch/config-cn.webp +0 -0
- package/assets/images/agents/cc-switch/config-global.webp +0 -0
- package/assets/images/agents/cc-switch/overview.webp +0 -0
- package/assets/images/agents/cc-switch/provider-cn.webp +0 -0
- package/assets/images/agents/cc-switch/provider-global.webp +0 -0
- package/assets/images/agents/cc-switch/use-cn.webp +0 -0
- package/assets/images/agents/cc-switch/use-global.webp +0 -0
- package/assets/images/agents/cherry-studio/add-provider.webp +0 -0
- package/assets/images/agents/cherry-studio/custom-provider-global.webp +0 -0
- package/assets/images/agents/cherry-studio/custom-provider.webp +0 -0
- package/assets/images/agents/cherry-studio/fetch-models-global.webp +0 -0
- package/assets/images/agents/cherry-studio/fetch-models.webp +0 -0
- package/assets/images/agents/cherry-studio/model-list-global.webp +0 -0
- package/assets/images/agents/cherry-studio/model-list.webp +0 -0
- package/assets/images/agents/cherry-studio/model-picker.webp +0 -0
- package/assets/images/agents/cline/cline-chat.webp +0 -0
- package/assets/images/agents/cline/cline-config-cn.webp +0 -0
- package/assets/images/agents/cline/cline-config-global.webp +0 -0
- package/assets/images/agents/cline/cline-market.webp +0 -0
- package/assets/images/agents/codex/codex-chat.webp +0 -0
- package/assets/images/agents/codex/codex-skip.webp +0 -0
- package/assets/images/agents/codex/codex-start.webp +0 -0
- package/assets/images/agents/cursor/add-model.webp +0 -0
- package/assets/images/agents/cursor/chat.webp +0 -0
- package/assets/images/agents/cursor/config-cn.webp +0 -0
- package/assets/images/agents/cursor/config-global.webp +0 -0
- package/assets/images/agents/cursor/install.webp +0 -0
- package/assets/images/agents/cursor/model-list.webp +0 -0
- package/assets/images/agents/cursor/settings.webp +0 -0
- package/assets/images/agents/deepseek-harness/install.webp +0 -0
- package/assets/images/agents/deepseek-harness/model-picker.webp +0 -0
- package/assets/images/agents/deepseek-harness/provider-config.webp +0 -0
- package/assets/images/agents/deepseek-harness/session.webp +0 -0
- package/assets/images/agents/deepseek-harness/settings.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-byok.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-config-cn.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-config-global.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-market.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-panel.webp +0 -0
- package/assets/images/agents/kilo-code/jetbrains-start.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-byok.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-config-cn.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-config-global.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-market.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-panel.webp +0 -0
- package/assets/images/agents/kilo-code/vscode-start.webp +0 -0
- package/assets/images/agents/opencode/chat.webp +0 -0
- package/assets/images/agents/opencode/model-search.webp +0 -0
- package/assets/images/agents/opencode/provider-filter.webp +0 -0
- package/assets/images/agents/opencode/provider-name.webp +0 -0
- package/assets/images/agents/zcode/chat.webp +0 -0
- package/assets/images/agents/zcode/install.webp +0 -0
- package/assets/images/agents/zcode/provider-fields.webp +0 -0
- package/assets/images/agents/zcode/provider-saved-global.webp +0 -0
- package/assets/images/agents/zcode/provider-saved.webp +0 -0
- package/assets/images/agents/zcode/setup.webp +0 -0
- package/dist/code-highlight.d.ts +1 -0
- package/dist/code-highlight.js +50 -0
- package/dist/content.generated.d.ts +2 -0
- package/dist/content.generated.js +4 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +625 -0
- package/package.json +39 -0
- package/styles/docs-content.css +928 -0
- package/styles/docs-responsive.css +113 -0
- package/styles/docs-tokens.css +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# @model-go/docs-core
|
|
2
|
+
|
|
3
|
+
ModelGo 文档的**单一真源**:文档内容 + 纯渲染器 + 正文样式。
|
|
4
|
+
|
|
5
|
+
## 为什么存在
|
|
6
|
+
|
|
7
|
+
文档原来只有 `modelgo-doc-web` 一个消费方,内容和渲染器都长在它的 VitePress 主题里
|
|
8
|
+
(`import.meta.glob('?raw')` 把 markdown 打进浏览器包,运行期在浏览器渲染)。
|
|
9
|
+
现在官网也要读文档(`modelgo.ai/docs`),而 Google 要的是**服务端渲染的真 HTML**——
|
|
10
|
+
如果两个站点各抄一份渲染逻辑,早晚漂移。
|
|
11
|
+
|
|
12
|
+
所以把「内容 + 渲染器」抽成这个包:内容只有一个真源,渲染只有一个实现,
|
|
13
|
+
两个消费方只是传入不同的挂载前缀:
|
|
14
|
+
|
|
15
|
+
| 消费方 | 站点 | linkBase | assetBase |
|
|
16
|
+
|--------|------|----------|-----------|
|
|
17
|
+
| `modelgo-doc-web` | `docs.modelgo.com` | `''` | `''` |
|
|
18
|
+
| `modelgo-global-web` | `modelgo.ai/docs` | `/docs`(en)、`/zh/docs`(zh) | `/docs` |
|
|
19
|
+
|
|
20
|
+
## 用法
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { getDocsNav, getDocsPage, getDocSlugs } from '@model-go/docs-core'
|
|
24
|
+
|
|
25
|
+
const nav = await getDocsNav('en', 'global')
|
|
26
|
+
const page = await getDocsPage('quickstart/overview', 'en', 'global', {
|
|
27
|
+
linkBase: '/docs',
|
|
28
|
+
assetBase: '/docs',
|
|
29
|
+
})
|
|
30
|
+
// page.html 是服务端渲染好的正文 HTML,page.toc 是目录
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
样式:
|
|
34
|
+
|
|
35
|
+
```css
|
|
36
|
+
@import '@model-go/docs-core/styles/docs-tokens.css'; /* --docs-* ← --mg-*,需先加载 modelgo-design-tokens */
|
|
37
|
+
@import '@model-go/docs-core/styles/docs-content.css'; /* 正文排版 */
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
图片:`assets/images/**`,消费方自行复制到自己的静态目录(官网复制到 `/docs/images`)。
|
|
41
|
+
|
|
42
|
+
## 约束
|
|
43
|
+
|
|
44
|
+
- 渲染器**不得引入任何浏览器 API**(`location` / `navigator` / `storage` / DOM)。
|
|
45
|
+
站点/语言由调用方显式传入 `profile`、`lang`,包内不做任何运行期探测——
|
|
46
|
+
这是官网能把它跑在服务端的前提。
|
|
47
|
+
- `tsconfig.json` 的 `lib` 只有 `ES2022`(不含 DOM),用来在编译期卡住上面的约束。
|
|
48
|
+
|
|
49
|
+
## 发版
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npm publish # prepublishOnly 会自动跑:sync:assets → build → 发版门禁
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`prepublishOnly` 串了四步,`npm publish` 无论本地发还是 CI 发都必然走到:
|
|
56
|
+
|
|
57
|
+
1. `sync:assets` —— 把正文实际引用到的图片从 `../../public/images` 同步进 `assets/`
|
|
58
|
+
2. `build` —— `tsc` + 生成 `dist/content.generated.js`
|
|
59
|
+
3. `prepublish-gate` —— 产物完整性(入口字段/pack 清单/CHANGELOG/运行期载荷变化)
|
|
60
|
+
4. `readme-gate` —— 首屏包装。**本包显式 `README_GATE=off`**:`open_source_project_baseline`
|
|
61
|
+
要求的是「GitHub 开源项目」首屏(banner/立体徽章/双语),而本包是**内部包**——
|
|
62
|
+
源码在自建 GitLab、消费方只有 ModelGo 自己的两个站点、不做社区推广。
|
|
63
|
+
逃生舱会打印一行跳过提示,不是静默通过;哪天要对外推广,删掉这个前缀即可。
|
|
64
|
+
|
|
65
|
+
两个门禁的真源在 `CortexOS/scripts/release-gate/`,`scripts/` 下的是拷贝。
|
|
66
|
+
**改真源,别改拷贝** —— 拷贝漂移会让各仓的拦截口径不一致。
|
|
67
|
+
|
|
68
|
+
### 图片格式
|
|
69
|
+
|
|
70
|
+
截图一律用 **WebP**,不用 PNG。2026-09-28 实测:58 张 UI 截图原为 PNG 共 27.6 MB
|
|
71
|
+
(单张最大 2.2 MB),转 WebP q85 后 2.3 MB,**省 91.5%**,PSNR 36–42 dB,
|
|
72
|
+
小字号代码文字仍清晰可读。PNG 存 UI 截图压缩率极低,是纯浪费。
|
|
73
|
+
|
|
74
|
+
- 新增图片后跑 `python3 ../scripts/optimize-images.py` 转换
|
|
75
|
+
- 正文引用写 `.webp`;`scripts/switch-refs-to-webp.py` 可批量改引用
|
|
76
|
+
- 原始 PNG 保留在 `../../public/images`(已对外发布过的 URL 不能 404),
|
|
77
|
+
但不会被同步进包 —— 只有正文引用到的文件才进包
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderCodeBlock(code: string, lang?: string): string;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
const KEYWORDS = new Set([
|
|
2
|
+
'async',
|
|
3
|
+
'await',
|
|
4
|
+
'body',
|
|
5
|
+
'const',
|
|
6
|
+
'curl',
|
|
7
|
+
'fetch',
|
|
8
|
+
'GET',
|
|
9
|
+
'headers',
|
|
10
|
+
'JSON',
|
|
11
|
+
'method',
|
|
12
|
+
'POST',
|
|
13
|
+
'return',
|
|
14
|
+
'stringify',
|
|
15
|
+
]);
|
|
16
|
+
const LITERALS = new Set(['false', 'null', 'true']);
|
|
17
|
+
const TOKEN_RE = /("[^&]*(?:&(?!quot;)[^&]*)*"|'[^&]*(?:&(?!#39;)[^&]*)*'|\b[A-Za-z_][\w-]*\b|\b\d+(?:\.\d+)?\b|[{}[\]():,])/g;
|
|
18
|
+
function escapeHtml(value) {
|
|
19
|
+
return value
|
|
20
|
+
.replaceAll('&', '&')
|
|
21
|
+
.replaceAll('<', '<')
|
|
22
|
+
.replaceAll('>', '>')
|
|
23
|
+
.replaceAll('"', '"')
|
|
24
|
+
.replaceAll("'", ''');
|
|
25
|
+
}
|
|
26
|
+
function classNameForToken(token) {
|
|
27
|
+
if (token.startsWith('"') || token.startsWith('''))
|
|
28
|
+
return 'code-string';
|
|
29
|
+
if (KEYWORDS.has(token))
|
|
30
|
+
return 'code-keyword';
|
|
31
|
+
if (LITERALS.has(token))
|
|
32
|
+
return 'code-literal';
|
|
33
|
+
if (/^\d/.test(token))
|
|
34
|
+
return 'code-number';
|
|
35
|
+
if (/^[{}[\]():,]$/.test(token))
|
|
36
|
+
return 'code-punctuation';
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
export function renderCodeBlock(code, lang = '') {
|
|
40
|
+
const highlighted = escapeHtml(code).replace(TOKEN_RE, (token) => {
|
|
41
|
+
const className = classNameForToken(token);
|
|
42
|
+
return className ? `<span class="${className}">${token}</span>` : token;
|
|
43
|
+
});
|
|
44
|
+
const languageClass = lang ? ` language-${escapeHtml(lang.toLowerCase())}` : '';
|
|
45
|
+
const langLabel = lang ? escapeHtml(lang.toLowerCase()) : '';
|
|
46
|
+
const langTag = langLabel
|
|
47
|
+
? `<span class="code-header-lang">${langLabel}</span>`
|
|
48
|
+
: '';
|
|
49
|
+
return `<div class="code-window${languageClass}"><div class="code-header"><span class="code-header-dots"><i></i><i></i><i></i></span>${langTag}<button class="code-copy-btn" type="button" title="Copy" aria-label="Copy code"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button></div><pre class="code-block"><code>${highlighted}</code></pre></div>`;
|
|
50
|
+
}
|