base_parts_ai 1.0.49 → 1.0.50
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/lib/ai_utils.js +117 -101
- package/package.json +1 -1
- package/test_home/.claude/settings.json +1 -1
- package/test_home/.codex/AGENTS.md +1 -1
package/lib/ai_utils.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
var fs = require('fs');
|
|
9
9
|
var path = require('path');
|
|
10
|
-
var http = require('http');
|
|
11
10
|
var { execSync, spawnSync } = require('child_process');
|
|
12
11
|
|
|
13
12
|
// ============================================================
|
|
@@ -24,6 +23,26 @@ var noticeList = [];
|
|
|
24
23
|
// jcc.json 中保存最后一次手动输入 Token 的内部字段名
|
|
25
24
|
var LAST_MANUAL_AUTH_TOKEN_KEY = '__lastManualAuthToken';
|
|
26
25
|
|
|
26
|
+
/**
|
|
27
|
+
* 使用 Node.js 18 内置 fetch 读取远程文本,并提供超时控制
|
|
28
|
+
* @param {string} url 请求地址
|
|
29
|
+
* @param {number} timeoutMs 超时时间(毫秒)
|
|
30
|
+
* @returns {Promise<{ ok: boolean, status: number, text: string }>}
|
|
31
|
+
*/
|
|
32
|
+
async function fetchRemoteText(url, timeoutMs) {
|
|
33
|
+
var controller = new AbortController();
|
|
34
|
+
var timer = setTimeout(function () {
|
|
35
|
+
controller.abort();
|
|
36
|
+
}, timeoutMs);
|
|
37
|
+
try {
|
|
38
|
+
var res = await fetch(url, { signal: controller.signal });
|
|
39
|
+
var text = await res.text();
|
|
40
|
+
return { ok: res.ok, status: res.status, text: text };
|
|
41
|
+
} finally {
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
27
46
|
/**
|
|
28
47
|
* 从当前入口文件名推断正在运行的 CLI 命令名
|
|
29
48
|
* @returns {string} jcc、jcx 或空字符串
|
|
@@ -74,95 +93,91 @@ function rerunCurrentCli() {
|
|
|
74
93
|
* @param {object} buildCfg getBuildCfg 返回的配置对象
|
|
75
94
|
* @returns {Promise<void>}
|
|
76
95
|
*/
|
|
77
|
-
function fetchConfig(buildCfg) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
} else {
|
|
146
|
-
console.log('[fetchConfig] 已跳过升级,继续使用当前版本');
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
} else {
|
|
150
|
-
console.warn('[fetchConfig] 服务端返回异常:', result.msg || JSON.stringify(result));
|
|
96
|
+
async function fetchConfig(buildCfg) {
|
|
97
|
+
var url = 'https://jai.jaskle.cn/hm/hm_pub/ai_cc_cfg?r=' + Math.random();
|
|
98
|
+
try {
|
|
99
|
+
var response = await fetchRemoteText(url, 8000);
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
console.warn('[fetchConfig] 请求失败: HTTP ' + response.status);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
var result = JSON.parse(response.text);
|
|
106
|
+
if (result.code === 0 && result.data) {
|
|
107
|
+
// 将服务端返回的渠道列表填充到 API_CHANNELS
|
|
108
|
+
if (Array.isArray(result.data.channels)) {
|
|
109
|
+
API_CHANNELS.length = 0;
|
|
110
|
+
result.data.channels.forEach(function (ch) {
|
|
111
|
+
API_CHANNELS.push(ch);
|
|
112
|
+
});
|
|
113
|
+
console.log('[fetchConfig] 已拉取 ' + API_CHANNELS.length + ' 个渠道');
|
|
114
|
+
}
|
|
115
|
+
// 将服务端返回的 Codex 渠道列表填充到 CX_CHANNELS
|
|
116
|
+
if (Array.isArray(result.data.cxChannels)) {
|
|
117
|
+
CX_CHANNELS.length = 0;
|
|
118
|
+
result.data.cxChannels.forEach(function (ch) {
|
|
119
|
+
CX_CHANNELS.push(ch);
|
|
120
|
+
});
|
|
121
|
+
console.log('[fetchConfig] 已拉取 ' + CX_CHANNELS.length + ' 个 Codex 渠道');
|
|
122
|
+
}
|
|
123
|
+
// 解析公告列表
|
|
124
|
+
if (Array.isArray(result.data.noticeList)) {
|
|
125
|
+
noticeList.length = 0;
|
|
126
|
+
result.data.noticeList.forEach(function (item) {
|
|
127
|
+
noticeList.push(item);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
// 检查 jcc 自身版本,若需要升级则询问用户确认后安装
|
|
131
|
+
var currentVer = '';
|
|
132
|
+
try { currentVer = require('../package.json').version; } catch (e) { }
|
|
133
|
+
var newVer = result.data.newVer || '';
|
|
134
|
+
// 比较语义化版本号,仅当服务端版本大于当前版本时才升级
|
|
135
|
+
function semverGt(a, b) {
|
|
136
|
+
var pa = a.split('.').map(Number);
|
|
137
|
+
var pb = b.split('.').map(Number);
|
|
138
|
+
for (var i = 0; i < 3; i++) {
|
|
139
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return true;
|
|
140
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return false;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (newVer && process.env.BASE_PARTS_AI_SKIP_SELF_UPDATE !== '1' && semverGt(newVer, currentVer)) {
|
|
145
|
+
console.log('[fetchConfig] 检测到新版本: ' + newVer + '(当前 ' + currentVer + ')');
|
|
146
|
+
var confirmed = "yes"
|
|
147
|
+
// confirmed = await select({
|
|
148
|
+
// message: '是否立即升级?',
|
|
149
|
+
// default: 'yes',
|
|
150
|
+
// choices: [
|
|
151
|
+
// { name: '立即升级', value: 'yes' },
|
|
152
|
+
// { name: '跳过', value: 'no' },
|
|
153
|
+
// ],
|
|
154
|
+
// });
|
|
155
|
+
if (confirmed === 'yes') {
|
|
156
|
+
console.log('[fetchConfig] 正在升级...');
|
|
157
|
+
// 用 select 上下选,默认高亮"立即升级"
|
|
158
|
+
try {
|
|
159
|
+
var tgzUrl = 'https://jdwfiles.oss-cn-hangzhou.aliyuncs.com/npm_pkg/base_parts_ai-' + newVer + '.tgz';
|
|
160
|
+
execSync('npm install -g ' + tgzUrl + ' --force --registry=https://registry.npmmirror.com', { stdio: 'inherit' });
|
|
161
|
+
rerunCurrentCli();
|
|
162
|
+
} catch (e) {
|
|
163
|
+
console.warn('[fetchConfig] 自动升级失败:', e.message);
|
|
151
164
|
}
|
|
152
|
-
}
|
|
153
|
-
console.
|
|
165
|
+
} else {
|
|
166
|
+
console.log('[fetchConfig] 已跳过升级,继续使用当前版本');
|
|
154
167
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
168
|
+
}
|
|
169
|
+
} else {
|
|
170
|
+
console.warn('[fetchConfig] 服务端返回异常:', result.msg || JSON.stringify(result));
|
|
171
|
+
}
|
|
172
|
+
} catch (e) {
|
|
173
|
+
if (e && e.name === 'AbortError') {
|
|
161
174
|
console.warn('[fetchConfig] 请求超时');
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
175
|
+
} else if (e instanceof SyntaxError) {
|
|
176
|
+
console.warn('[fetchConfig] 解析响应失败:', e.message);
|
|
177
|
+
} else {
|
|
178
|
+
console.warn('[fetchConfig] 请求失败:', e.message);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
166
181
|
}
|
|
167
182
|
|
|
168
183
|
/**
|
|
@@ -251,21 +266,22 @@ function buildAiTipUrl(cli) {
|
|
|
251
266
|
* @param {string} url 请求地址
|
|
252
267
|
* @returns {Promise<string>}
|
|
253
268
|
*/
|
|
254
|
-
function fetchText(url) {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
269
|
+
async function fetchText(url) {
|
|
270
|
+
try {
|
|
271
|
+
var response = await fetchRemoteText(url, 8000);
|
|
272
|
+
if (!response.ok) {
|
|
273
|
+
console.warn('[fetchText] 请求失败: HTTP ' + response.status);
|
|
274
|
+
return '';
|
|
275
|
+
}
|
|
276
|
+
return response.text;
|
|
277
|
+
} catch (e) {
|
|
278
|
+
if (e && e.name === 'AbortError') {
|
|
264
279
|
console.warn('[fetchText] 请求超时');
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
|
|
280
|
+
} else {
|
|
281
|
+
console.warn('[fetchText] 请求失败:', e.message);
|
|
282
|
+
}
|
|
283
|
+
return '';
|
|
284
|
+
}
|
|
269
285
|
}
|
|
270
286
|
|
|
271
287
|
/**
|
package/package.json
CHANGED