czon 0.6.8 → 0.7.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  ![Logo of CZON](logo.png)
2
2
 
3
+ <div style="text-align: center; margin-bottom: 20px; font-size: 2em; font-weight: bold;">
4
+ <a href="https://czon.zccz14.com/">
5
+ 🌐 View Website of CZON 🚀
6
+ </a>
7
+ </div>
8
+
3
9
  # CZON - AI-Native Markdown 内容引擎
4
10
 
5
11
  - **C**: **C**ontent oriented | 内容为王,专注内容
@@ -7,8 +13,6 @@
7
13
  - **O**: **O**rganic AI-Native | 有机的 AI 原生,深度集成 AI
8
14
  - **N**: **N**-shaped Energy Curve | N 型能量曲线,介入创作-分发-反馈的各个环节
9
15
 
10
- [> Website Demo](https://czon.zccz14.com/)
11
-
12
16
  AI 时代下,作为网站内容创作者,我们可以有更智能的内容创作引擎。
13
17
 
14
18
  **回归内容:最小化打扰,专注写作**
@@ -23,55 +27,77 @@ AI 时代下,作为网站内容创作者,我们可以有更智能的内容
23
27
 
24
28
  人生苦短,我懒得翻译。人在使用母语时,才是最能发挥自身思考深度的。但同时与世界保持连接又是必要的,我不想放弃多语言的交流。于是我希望有一个工具,能让我用母语写作,同时又能让更多人看到我的内容。现在的 i18n 需要自己翻译不说,还得自己维护内容更新,太麻烦了。我选择使用 LLM 来帮我做翻译,省下了我很多时间,并且可以一键完成多国语言翻译。
25
29
 
26
- ## 基本功能
27
-
28
- 1. 🌍 **自动多语言翻译**:使用 AI 进行增量翻译,让用户使用母语编写 Markdown,但是用户可以是多语言的。
29
- 2. 💭 **自动摘要提取**:使用 AI 对原始文本进行内容分析和提取。
30
- 3. 🏷️ **自动标签分类**:使用 AI 对内容进行标签和分类的提取和管理。
31
- 4. 🧭 **智能分类导航**:使用 AI 生成站点地图和导航,源文件的位置不敏感。
32
-
33
- ## 静态站点生成 (SSG)
34
-
35
- CZON 内置了一个 SSG 方案,可以将任意一个包含 Markdown 的 git 文件夹构建成一个静态 HTML 站点。
30
+ ## ✨ 核心功能
36
31
 
37
- ⚠️ 请注意,CZON 不是专业的静态站点生成器(SSG),而是一个 AI 驱动的 Markdown 内容引擎,专注于内容创作和管理。
32
+ 1. 🌍 **AI 多语言翻译**:使用 AI 进行增量翻译,让用户使用母语编写 Markdown,但是用户可以是多语言的。
33
+ 2. 📊 **AI 元数据提取**:自动提取标题、描述、摘要、关键词、目标读者、URL 友好别名等。
34
+ 3. 🏷️ **AI 标签分类**:使用 AI 对内容进行标签和分类的提取和管理。
35
+ 4. 🧭 **AI 分类导航**:使用 AI 生成站点地图和导航,源文件的位置不敏感。
36
+ 5. 🤖 **AI 全站摘要**:可使用多种风格生成全站摘要。
38
37
 
39
- CZON 旨在简化内容创作和发布的流程,让用户能够专注于写作本身,而不是被复杂的配置和工具所困扰。
38
+ 以及一些非 AI 功能点:
40
39
 
41
- CZON 不会提供复杂的主题定制和插件生态,而是专注于通过 AI 提升内容的质量和可访问性。
40
+ 1. ⚙️ **零配置**:所有配置和缓存隐藏在 `.czon` 目录,项目结构保持整洁。
41
+ 2. 🔄 **增量构建**:基于内容哈希检测更改,仅处理变更文件。
42
+ 3. 📚 **Markdown 扩展支持**:原生支持 KaTeX 数学公式、Mermaid 图表、Embla 轮播图、脚注等。
43
+ 4. 🚀 **静态站点生成**:内置 React-based SSG,生成多语言静态站点。
44
+ 5. 🌐 **自动根据访问者语言路由**:根据访问者的语言自动路由到对应的语言版本。
42
45
 
43
- 🔔 但是,CZON 仍然可以生成静态站点,如果有必要的话,可以将 CZON 作为预处理器,集成其他 SSG 方案生成个性化的、美观的站点。
46
+ ## 📦 快速开始
44
47
 
45
- ## 快速开始
48
+ ### 前提条件
46
49
 
47
- 前提:
48
-
49
- - 已安装 [Node.js](https://nodejs.org/)(建议版本 18 及以上,需要有 npx 命令)
50
+ - 已安装 [Node.js](https://nodejs.org/)(建议使用 LTS 版本 24,或者版本 18 及以上,需要有 npx 命令)
50
51
  - 已获取 [OpenAI API Key](https://platform.openai.com/account/api-keys),或者 OPENAI 兼容的 API Key
51
52
  - 已安装 Git(用于从 Git 列出 Markdown 文件,忽略 .gitignore 规则过滤的文件)
52
53
 
53
- 首先,工作在一个已经被 git 管理的文件夹中:
54
-
55
- 配置环境变量
54
+ ### 环境变量配置
56
55
 
57
56
  ```bash
58
57
  export OPENAI_API_KEY="sk-xxxxxx" # 必须:请替换为您的 OpenAI API Key
59
58
  export OPENAI_BASE_URL="https://api.openai.com/v1" # 可选,默认使用 OpenAI 官方 API
60
59
  export OPENAI_MODEL="gpt-3.5-turbo" # 可选,默认使用 gpt-3.5-turbo 模型
61
60
  export OPENAI_MAX_TOKENS="4096" # 可选,设置最大 token 数量限制 (忽略则使用模型的默认值,对于长文本翻译建议设置更高的值,例如 8192,具体取决于所使用的模型支持的最大 token 数量)
61
+
62
+ # 如果需要使用 HTTP 代理访问 OpenAI API,可以设置以下变量
63
+ export HTTPS_PROXY="http://your-proxy.com:8080" # 可选,设置 HTTPS 代理
64
+ export HTTP_PROXY="http://your-proxy.com:8080" # 可选,设置 HTTP 代理
62
65
  ```
63
66
 
64
- 构建站点,支持多语言翻译。使用当前目录作为源目录,输出到 `.czon/dist` 目录。
67
+ ### 构建多语言站点
65
68
 
66
- - 可以通过多次使用 `--lang` 参数指定需要生成的语言版本(例如 `--lang zh-Hans --lang en-US`)。
67
- - 不需要配置源语言,CZON 会自动检测。
69
+ 在任意 Git 管理的文件夹中运行:
68
70
 
69
71
  ```bash
70
72
  npx czon@latest build --lang zh-Hans --lang en-US
71
73
  ```
72
74
 
73
- **查看更多参数或帮助**:
75
+ 由于语言代码后续会用作静态站点生成中许多功能的一部分,请确保使用 BCP 47 标准的语言代码。例如,`zh-Hans` 代表简体中文,`en-US` 代表美国英语。您可以根据需要添加更多语言,例如 `es-ES` (西班牙语) `ja-JP`(日语)、`ko-KR`(韩语)等。
76
+ 标准语言代码列表请参考 [IETF language tag - Wikipedia](https://en.wikipedia.org/wiki/IETF_language_tag#List_of_common_primary_language_subtags)。
74
77
 
75
- ```bash
76
- npx czon@latest
77
- ```
78
+ 输出目录:`.czon/dist`,后续需要部署该目录下的内容到静态站点托管平台。
79
+
80
+ 详细用法请运行 `npx czon@latest --help`。
81
+
82
+ ## 🔗 与其他工具的比较
83
+
84
+ | 特性 | CZON | Docusaurus | VuePress | Astro |
85
+ | ------------------ | ------------------------ | --------------- | --------------- | --------------- |
86
+ | **AI 原生** | ✅ 深度集成 | ❌ | ❌ | ❌ |
87
+ | **零配置** | ✅ 隐藏配置 | ❌ 需要配置文件 | ❌ 需要配置文件 | ❌ 需要配置文件 |
88
+ | **多语言 AI 翻译** | ✅ 自动增量翻译 | ❌ 手动翻译 | ❌ 手动翻译 | ❌ 手动翻译 |
89
+ | **自动分类/标签** | ✅ AI 提取 | ❌ 手动配置 | ❌ 手动配置 | ❌ 手动配置 |
90
+ | **Markdown 扩展** | ✅ KaTeX, Mermaid, Embla | ✅ 通过插件 | ✅ 通过插件 | ✅ 通过插件 |
91
+ | **主题定制** | ❌ 有限 | ✅ 丰富 | ✅ 丰富 | ✅ 丰富 |
92
+
93
+ CZON 定位为 **AI 增强的内容引擎**,而非全功能 SSG。它专注于通过 AI 提升内容创作效率,适合注重内容质量、希望减少配置负担的创作者。实际上,CZON 可以与 Docusaurus、VuePress、Astro 等 SSG 工具结合使用,作为内容生成和管理的前端引擎。
94
+
95
+ ## 📞 支持
96
+
97
+ - 项目主页: [https://github.com/zccz14/CZON](https://github.com/zccz14/CZON)
98
+ - GitHub Issues: [https://github.com/zccz14/CZON/issues](https://github.com/zccz14/CZON/issues)
99
+ - Discord 讨论区: [https://discord.gg/h3QrCmz24n](https://discord.gg/h3QrCmz24n)
100
+
101
+ ---
102
+
103
+ _让写作回归宁静,让内容自然生长。_
@@ -32,9 +32,13 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
35
38
  Object.defineProperty(exports, "__esModule", { value: true });
36
39
  exports.downloadCDNResources = exports.spiderStaticSiteGenerator = void 0;
37
40
  const fs = __importStar(require("fs/promises"));
41
+ const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
38
42
  const path = __importStar(require("path"));
39
43
  const sitemap_1 = require("../build/sitemap");
40
44
  const metadata_1 = require("../metadata");
@@ -147,7 +151,7 @@ const downloadCDNResources = async () => {
147
151
  for (const resource of resourceMap_1.EXTERNAL_RESOURCES) {
148
152
  const targetFilePath = path.join(paths_1.CZON_DIST_DIR, 'assets', resource.name);
149
153
  console.info(`⬇️ Downloading resource: ${resource.url} -> ${targetFilePath}`);
150
- const response = await fetch(resource.url);
154
+ const response = await (0, make_fetch_happen_1.default)(resource.url);
151
155
  if (!response.ok) {
152
156
  console.error(`❌ Failed to download resource: ${resource.url}, status: ${response.status}`);
153
157
  throw new Error(`Failed to download resource: ${resource.url}`);
@@ -1,6 +1,11 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.completeMessages = void 0;
7
+ // 使用 make-fetch-happen 以支持代理选项 (支持环境变量 HTTP_PROXY, HTTPS_PROXY, PROXY, NO_PROXY)
8
+ const make_fetch_happen_1 = __importDefault(require("make-fetch-happen"));
4
9
  const startTime = Date.now();
5
10
  let totalContentGenerated = 0;
6
11
  const processingTaskIds = new Set();
@@ -70,7 +75,7 @@ const completeMessages = async (messages, options) => {
70
75
  // for (const msg of messages) {
71
76
  // console.info(`💬 [${msg.role}] ${msg.content}`);
72
77
  // }
73
- const response = await fetch(`${baseUrl}/chat/completions`, {
78
+ const response = await (0, make_fetch_happen_1.default)(`${baseUrl}/chat/completions`, {
74
79
  method: 'POST',
75
80
  headers: {
76
81
  'Content-Type': 'application/json',
@@ -83,17 +88,10 @@ const completeMessages = async (messages, options) => {
83
88
  throw new Error(`OpenAI API error (${response.status}): ${errorText}`);
84
89
  }
85
90
  // 处理流式响应
86
- const reader = response.body?.getReader();
87
- if (!reader) {
88
- throw new Error('No response body reader available');
89
- }
90
91
  const decoder = new TextDecoder();
91
92
  let buffer = '';
92
93
  let content = '';
93
- while (true) {
94
- const { done, value } = await reader.read();
95
- if (done)
96
- break;
94
+ const handleData = (value) => {
97
95
  buffer += decoder.decode(value, { stream: true });
98
96
  const lines = buffer.split('\n');
99
97
  buffer = lines.pop() || ''; // 保留未完成的行
@@ -134,7 +132,13 @@ const completeMessages = async (messages, options) => {
134
132
  }
135
133
  }
136
134
  }
137
- }
135
+ };
136
+ //
137
+ await new Promise((resolve, reject) => {
138
+ response.body.on('data', handleData);
139
+ response.body.on('end', () => resolve());
140
+ response.body.on('error', err => reject(err));
141
+ });
138
142
  // 确保所有剩余数据被解码
139
143
  if (buffer) {
140
144
  buffer += decoder.decode();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "czon",
3
- "version": "0.6.8",
4
- "description": "CZone - AI enhanced Markdown content engine",
3
+ "version": "0.7.0",
4
+ "description": "CZON - AI enhanced Markdown content engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "bin": "dist/cli.js",
@@ -40,8 +40,8 @@
40
40
  ]
41
41
  },
42
42
  "devDependencies": {
43
- "@types/chokidar": "^1.7.5",
44
43
  "@types/express": "^5.0.6",
44
+ "@types/make-fetch-happen": "^10.0.4",
45
45
  "@types/node": "^25.0.3",
46
46
  "@types/yaml": "^1.9.6",
47
47
  "husky": "^9.1.7",
@@ -54,11 +54,10 @@
54
54
  "@opencode-ai/sdk": "^1.1.34",
55
55
  "@types/react": "^19.2.7",
56
56
  "@types/react-dom": "^19.2.3",
57
- "chokidar": "^5.0.0",
58
57
  "clipanion": "^4.0.0-rc.4",
59
58
  "dotenv": "^16.4.7",
60
- "express": "^4.21.2",
61
59
  "highlight.js": "^11.11.1",
60
+ "make-fetch-happen": "^15.0.3",
62
61
  "marked": "^17.0.1",
63
62
  "marked-footnote": "^1.4.0",
64
63
  "marked-katex-extension": "^5.1.6",