@myassis/gateway 1.0.107 → 1.0.109
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/dist/.env +6 -0
- package/dist/config/index.js +3 -3
- package/dist/middleware/auth.js +1 -1
- package/dist/middleware/broadcast.js +1 -1
- package/dist/routes/agent.js +6 -6
- package/dist/routes/upload.js +3 -3
- package/dist/services/TaskSchedulerService.js +1 -1
- package/dist/services/TaskService.js +1 -1
- package/dist/services/agent/AgentManager.js +2 -2
- package/dist/services/llm/LLMClient.js +15 -29
- package/dist/services/memory/ContextBuilder.js +1 -1
- package/dist/services/memory/MemoryManager.js +2 -2
- package/dist/services/session/Session.js +8 -12
- package/dist/services/session/SessionManager.js +1 -1
- package/dist/services/systemPrompt.js +1 -1
- package/dist/services/tools/model.js +1 -1
- package/dist/services/tools/skill.js +1 -1
- package/package.json +1 -1
- package/scripts/pkg-build-win.js +64 -64
package/dist/.env
ADDED
package/dist/config/index.js
CHANGED
|
@@ -100,7 +100,7 @@ exports.appConfig = {
|
|
|
100
100
|
/** 摘要后保留的原始历史消息条数 */
|
|
101
101
|
historyKeep: parseInt(process.env.HISTORY_KEEP || '4', 10),
|
|
102
102
|
/** 保留完整输出的最近工具调用轮数 */
|
|
103
|
-
toolPairKeep: parseInt(process.env.TOOL_PAIR_KEEP || '
|
|
103
|
+
toolPairKeep: parseInt(process.env.TOOL_PAIR_KEEP || '4', 10),
|
|
104
104
|
/** 极端裁剪时至少保留的工具调用轮数 */
|
|
105
105
|
minToolPairKeep: 2,
|
|
106
106
|
/** 单次请求上下文字符预算(LLMClient 硬上限为 200000,此处留出余量) */
|
|
@@ -121,7 +121,7 @@ exports.appConfig = {
|
|
|
121
121
|
/** 模型上下文窗口的可用百分比(折算为字符预算,对齐 Codex 的 90%) */
|
|
122
122
|
turnCompactTriggerPercent: parseInt(process.env.TURN_COMPACT_TRIGGER_PERCENT || '90', 10),
|
|
123
123
|
/** 轮内压缩时保留原文的最近工具调用轮数 */
|
|
124
|
-
turnCompactKeepPairs: parseInt(process.env.TURN_COMPACT_KEEP_PAIRS || '
|
|
124
|
+
turnCompactKeepPairs: parseInt(process.env.TURN_COMPACT_KEEP_PAIRS || '4', 10),
|
|
125
125
|
/** 单轮请求内最多做几次轮内压缩,防止摘要模型被反复调用 */
|
|
126
126
|
maxInTurnCompactions: parseInt(process.env.MAX_IN_TURN_COMPACTIONS || '4', 10),
|
|
127
127
|
/** 模型瞬时故障(空回复 / 超时 / 网络抖动)的自动重试次数 */
|
|
@@ -146,7 +146,7 @@ exports.appConfig = {
|
|
|
146
146
|
* 必定压缩,与内容多少无关 —— 这是「没聊几句就压缩」最直接的原因。
|
|
147
147
|
* 条数只作为体积估算失真时的兜底,阈值应远高于正常对话轮数。
|
|
148
148
|
*/
|
|
149
|
-
summaryThreshold: parseInt(process.env.SUMMARY_THRESHOLD || '
|
|
149
|
+
summaryThreshold: parseInt(process.env.SUMMARY_THRESHOLD || '10', 10),
|
|
150
150
|
appName: '我的助手'
|
|
151
151
|
};
|
|
152
152
|
/**
|
package/dist/middleware/auth.js
CHANGED
|
@@ -9,7 +9,7 @@ exports.requireAuth = void 0;
|
|
|
9
9
|
* 注:Gateway 不自行验证 JWT 签名,而是比对 authStore 中由 Server 下发并本地持久化的 token。
|
|
10
10
|
* 因此无需也不应持有 JWT_SECRET,避免密钥在末端多处散落。
|
|
11
11
|
*/
|
|
12
|
-
const authStore_js_1 = require("
|
|
12
|
+
const authStore_js_1 = require("../stores/authStore.js");
|
|
13
13
|
const shared_1 = require("@myassis/shared");
|
|
14
14
|
const logger = (0, shared_1.getLogger)('middleware/auth');
|
|
15
15
|
/**
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
19
|
exports.broadcastDataChanges = void 0;
|
|
20
20
|
const shared_1 = require("@myassis/shared");
|
|
21
|
-
const WebSocketService_js_1 = require("
|
|
21
|
+
const WebSocketService_js_1 = require("../services/WebSocketService.js");
|
|
22
22
|
const logger = (0, shared_1.getLogger)('middleware/broadcast');
|
|
23
23
|
/**
|
|
24
24
|
* 路由前缀 -> 资源类型。
|
package/dist/routes/agent.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const express_1 = require("express");
|
|
4
|
-
const auth_js_1 = require("
|
|
5
|
-
const index_js_1 = require("
|
|
6
|
-
const index_js_2 = require("
|
|
7
|
-
const AgentManager_js_1 = require("
|
|
8
|
-
const AgentStore_js_1 = require("
|
|
4
|
+
const auth_js_1 = require("../middleware/auth.js");
|
|
5
|
+
const index_js_1 = require("../api/index.js");
|
|
6
|
+
const index_js_2 = require("../services/session/index.js");
|
|
7
|
+
const AgentManager_js_1 = require("../services/agent/AgentManager.js");
|
|
8
|
+
const AgentStore_js_1 = require("../services/agent/AgentStore.js");
|
|
9
9
|
const shared_1 = require("@myassis/shared");
|
|
10
10
|
const logger = (0, shared_1.getLogger)('AgentRoutes');
|
|
11
|
-
const SessionStore_js_1 = require("
|
|
11
|
+
const SessionStore_js_1 = require("../services/session/SessionStore.js");
|
|
12
12
|
const router = (0, express_1.Router)();
|
|
13
13
|
// 所有路由需要认证
|
|
14
14
|
router.use(auth_js_1.requireAuth, (req, _res, next) => {
|
package/dist/routes/upload.js
CHANGED
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.deleteFile = void 0;
|
|
7
7
|
const express_1 = require("express");
|
|
8
8
|
const multer_1 = __importDefault(require("multer"));
|
|
9
|
-
const index_js_1 = require("
|
|
10
|
-
const auth_js_1 = require("
|
|
11
|
-
const index_js_2 = require("
|
|
9
|
+
const index_js_1 = require("../config/index.js");
|
|
10
|
+
const auth_js_1 = require("../middleware/auth.js");
|
|
11
|
+
const index_js_2 = require("../api/index.js");
|
|
12
12
|
const shared_1 = require("@myassis/shared");
|
|
13
13
|
const logger = (0, shared_1.getLogger)('UploadRoutes');
|
|
14
14
|
const router = (0, express_1.Router)();
|
|
@@ -11,7 +11,7 @@ const WebSocketService_js_1 = require("./WebSocketService.js");
|
|
|
11
11
|
const index_js_1 = require("./session/index.js");
|
|
12
12
|
const shared_1 = require("@myassis/shared");
|
|
13
13
|
const dataService_js_1 = require("./dataService.js");
|
|
14
|
-
const authStore_js_1 = require("
|
|
14
|
+
const authStore_js_1 = require("../stores/authStore.js");
|
|
15
15
|
const logger = (0, shared_1.getLogger)('TaskSchedulerService');
|
|
16
16
|
const EXPIRED_THRESHOLD = 60 * 60 * 1000; // 1小时
|
|
17
17
|
const CHECK_INTERVAL = 60 * 1000; // 1分钟
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.taskService = void 0;
|
|
13
|
-
const index_js_1 = require("
|
|
13
|
+
const index_js_1 = require("../stores/index.js");
|
|
14
14
|
const index_js_2 = require("../api/index.js");
|
|
15
15
|
const LocalTaskService_js_1 = require("./LocalTaskService.js");
|
|
16
16
|
const shared_1 = require("@myassis/shared");
|
|
@@ -7,9 +7,9 @@ exports.initAgentManager = exports.agentManagerMap = exports.AgentManager = void
|
|
|
7
7
|
const uuid_1 = require("uuid");
|
|
8
8
|
const Agent_js_1 = require("./Agent.js");
|
|
9
9
|
const SessionManager_js_1 = require("../session/SessionManager.js");
|
|
10
|
-
const authStore_js_1 = require("
|
|
10
|
+
const authStore_js_1 = require("../../stores/authStore.js");
|
|
11
11
|
const shared_1 = require("@myassis/shared");
|
|
12
|
-
const index_js_1 = __importDefault(require("
|
|
12
|
+
const index_js_1 = __importDefault(require("../../config/index.js"));
|
|
13
13
|
const logger = (0, shared_1.getLogger)('AgentManager');
|
|
14
14
|
/**
|
|
15
15
|
* AgentManager - Business logic layer
|
|
@@ -4,15 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getGlobalModelSelector = exports.parseAruments = exports.LLMClient = void 0;
|
|
7
|
-
const index_js_1 = require("
|
|
7
|
+
const index_js_1 = require("../../stores/index.js");
|
|
8
8
|
const shared_1 = require("@myassis/shared");
|
|
9
9
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
10
|
-
const index_js_2 = require("
|
|
10
|
+
const index_js_2 = require("../../config/index.js");
|
|
11
11
|
const logger = (0, shared_1.getLogger)('LLMClient');
|
|
12
12
|
/** 历史工具输出在上下文中的最大保留长度 */
|
|
13
13
|
const HISTORY_TOOL_OUTPUT_LIMIT = index_js_2.appConfig.oldToolContentLimit;
|
|
14
14
|
/** 请求体字符硬上限,超过则视为上下文超限 */
|
|
15
|
-
const HARD_MAX_CHARS =
|
|
15
|
+
const HARD_MAX_CHARS = index_js_2.appConfig.contextMaxChars;
|
|
16
16
|
/**
|
|
17
17
|
* 规范化工具调用参数。
|
|
18
18
|
*
|
|
@@ -371,30 +371,16 @@ class LLMClient {
|
|
|
371
371
|
*/
|
|
372
372
|
async buildRequest(stream, model) {
|
|
373
373
|
// 系统模式:转发到 Server LLM 代理
|
|
374
|
-
if (this.systemMode) {
|
|
375
|
-
const { mapped } = this.mapMessages(this.messages);
|
|
376
|
-
return {
|
|
377
|
-
url: `${this.serverUrl}/api/v1/llm/${stream ? 'chat' : 'invoke'}`,
|
|
378
|
-
headers: {
|
|
379
|
-
'Content-Type': 'application/json',
|
|
380
|
-
'Authorization': `Bearer ${this.authToken}`,
|
|
381
|
-
},
|
|
382
|
-
body: {
|
|
383
|
-
modelId: model.modelId,
|
|
384
|
-
messages: mapped,
|
|
385
|
-
temperature: 0.7,
|
|
386
|
-
tools: this.tools,
|
|
387
|
-
},
|
|
388
|
-
isSystemMode: true,
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
374
|
// 自定义模式:直接调用 LLM API
|
|
392
375
|
if (!model) {
|
|
393
376
|
throw new Error('No available model');
|
|
394
377
|
}
|
|
395
|
-
|
|
396
|
-
if (!
|
|
397
|
-
|
|
378
|
+
var apiKey;
|
|
379
|
+
if (!this.systemMode) {
|
|
380
|
+
apiKey = index_js_1.persistStore.getModelApiKey(model.id);
|
|
381
|
+
if (!apiKey) {
|
|
382
|
+
throw new Error('No API Key');
|
|
383
|
+
}
|
|
398
384
|
}
|
|
399
385
|
// 使用统一的消息映射
|
|
400
386
|
const { mapped: mappedMessages, existAttachments, existScreenShot } = this.mapMessages(this.messages);
|
|
@@ -410,17 +396,17 @@ class LLMClient {
|
|
|
410
396
|
const bodyChars = JSON.stringify(body).length;
|
|
411
397
|
logger.debug('context chars', bodyChars);
|
|
412
398
|
// 附件/截图场景 base64 体积大但不可裁剪,跳过硬上限检查
|
|
413
|
-
if (bodyChars > HARD_MAX_CHARS && !existAttachments && !existScreenShot) {
|
|
414
|
-
|
|
415
|
-
}
|
|
399
|
+
// if (bodyChars > HARD_MAX_CHARS && !existAttachments && !existScreenShot) {
|
|
400
|
+
// throw Error('exceed max message tokens')
|
|
401
|
+
// }
|
|
416
402
|
return {
|
|
417
|
-
url: `${model.baseUrl}/chat/completions`,
|
|
403
|
+
url: this.systemMode ? `${this.serverUrl}/api/v1/llm/${stream ? 'chat' : 'invoke'}` : `${model.baseUrl}/chat/completions`,
|
|
418
404
|
headers: {
|
|
419
405
|
'Content-Type': 'application/json',
|
|
420
|
-
'Authorization': `Bearer ${apiKey}`,
|
|
406
|
+
'Authorization': `Bearer ${this.systemMode ? this.authToken : apiKey}`,
|
|
421
407
|
},
|
|
422
408
|
body,
|
|
423
|
-
isSystemMode:
|
|
409
|
+
isSystemMode: this.systemMode,
|
|
424
410
|
};
|
|
425
411
|
}
|
|
426
412
|
/**
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.nextTrimLevel = exports.planTurnCompaction = exports.buildContext = exports.estimateTokens = exports.estimateChars = exports.TrimLevel = exports.CHARS_PER_TOKEN = void 0;
|
|
4
4
|
const shared_1 = require("@myassis/shared");
|
|
5
|
-
const index_js_1 = require("
|
|
5
|
+
const index_js_1 = require("../../config/index.js");
|
|
6
6
|
const ToolLedger_js_1 = require("./ToolLedger.js");
|
|
7
7
|
const ToolCallArchive_js_1 = require("./ToolCallArchive.js");
|
|
8
8
|
const logger = (0, shared_1.getLogger)('ContextBuilder');
|
|
@@ -28,9 +28,9 @@ const shared_1 = require("@myassis/shared");
|
|
|
28
28
|
const logger = (0, shared_1.getLogger)('MemoryManager');
|
|
29
29
|
const models_js_1 = require("../models.js");
|
|
30
30
|
const dataService_js_1 = require("../dataService.js");
|
|
31
|
-
const index_js_1 = require("
|
|
31
|
+
const index_js_1 = require("../../stores/index.js");
|
|
32
32
|
const LLMClient_js_1 = require("../llm/LLMClient.js");
|
|
33
|
-
const index_js_2 = require("
|
|
33
|
+
const index_js_2 = require("../../config/index.js");
|
|
34
34
|
const ToolLedger_js_1 = require("./ToolLedger.js");
|
|
35
35
|
const DEFAULT_CONFIG = {
|
|
36
36
|
summaryThreshold: index_js_2.appConfig.summaryThreshold,
|
|
@@ -27,15 +27,15 @@ exports.Session = exports.handleApprovalResponse = exports.registerApprovalWaite
|
|
|
27
27
|
const uuid_1 = require("uuid");
|
|
28
28
|
const shared_1 = require("@myassis/shared");
|
|
29
29
|
const SessionStore_js_1 = require("./SessionStore.js");
|
|
30
|
-
const AgentStore_js_1 = require("
|
|
31
|
-
const authStore_js_1 = require("
|
|
32
|
-
const models_js_1 = require("
|
|
33
|
-
const index_js_1 = require("
|
|
30
|
+
const AgentStore_js_1 = require("../../services/agent/AgentStore.js");
|
|
31
|
+
const authStore_js_1 = require("../../stores/authStore.js");
|
|
32
|
+
const models_js_1 = require("../../services/models.js");
|
|
33
|
+
const index_js_1 = require("../../services/tools/index.js");
|
|
34
34
|
const systemPrompt_js_1 = require("../systemPrompt.js");
|
|
35
35
|
const LLMClient_js_1 = require("../llm/LLMClient.js");
|
|
36
|
-
const dataService_js_1 = require("
|
|
36
|
+
const dataService_js_1 = require("../../services/dataService.js");
|
|
37
37
|
const MemoryManager_js_1 = require("../memory/MemoryManager.js");
|
|
38
|
-
const index_js_2 = require("
|
|
38
|
+
const index_js_2 = require("../../config/index.js");
|
|
39
39
|
const ContextBuilder_js_1 = require("../memory/ContextBuilder.js");
|
|
40
40
|
const SessionManager_js_1 = require("./SessionManager.js");
|
|
41
41
|
const SessionNotificationService_js_1 = require("../SessionNotificationService.js");
|
|
@@ -898,6 +898,7 @@ class Session {
|
|
|
898
898
|
}
|
|
899
899
|
}
|
|
900
900
|
systemPrompt = await (0, systemPrompt_js_1.getSystemPromptAsync)(agent, systemPrompt);
|
|
901
|
+
systemPrompt += '\n【防重复规则】1.不要重复执行已经成功完成的工具调用。若工具结果被截断(标记为内容过长已截断或完整结果请调阅detailTool),必须先用detailTool获取完整内容,切勿重新执行原工具。2.完成阶段性目标后(如编辑验证通过、提交代码后)直接总结结果回复用户,不要重新检查已解决的问题。';
|
|
901
902
|
if (messages.some(x => x.role === 'system')) {
|
|
902
903
|
messages = messages.map(m => m.role == 'system' ? { ...m, content: systemPrompt + '\n以下为之前对话内容摘要:\n' + m.content } : m);
|
|
903
904
|
}
|
|
@@ -1030,6 +1031,7 @@ class Session {
|
|
|
1030
1031
|
if (built.trimmed) {
|
|
1031
1032
|
logger.debug(`上下文裁剪: level=${built.level} chars=${built.chars}`);
|
|
1032
1033
|
}
|
|
1034
|
+
logger.debug(`调用模型${this.selectModelId},messages:`, built.messages);
|
|
1033
1035
|
// 收尾阶段不再下发工具定义:只要工具还在,模型大概率继续调用而不收尾
|
|
1034
1036
|
const llmClient = new LLMClient_js_1.LLMClient(models, built.messages, this.abortController.signal, forceFinalize ? [] : tools);
|
|
1035
1037
|
llmClient.setPreferredModel(this.selectModelId);
|
|
@@ -1369,12 +1371,6 @@ class Session {
|
|
|
1369
1371
|
};
|
|
1370
1372
|
await Promise.all(llmResult.toolCalls.map(x => startToolCall(x)));
|
|
1371
1373
|
toolCalls.push(toolCall);
|
|
1372
|
-
// 重置 toolCall:下一轮工具调用必须开启新的分组。
|
|
1373
|
-
// 否则模型连续多轮只返回工具调用(无正文)时,所有轮次的结果会
|
|
1374
|
-
// 累积进同一个 toolCall 对象,并被重复 push 到 toolCalls 数组,
|
|
1375
|
-
// 导致持久化消息出现重复的工具调用组,历史回放时模型看到重复
|
|
1376
|
-
// 的 tool_calls/tool 结果对,进而重复执行工具。
|
|
1377
|
-
toolCall = null;
|
|
1378
1374
|
// 本轮工具已执行完,增量落库一次。工具轮次可能很多且每轮都耗时,
|
|
1379
1375
|
// 这里保存能让崩溃后仍保留已完成的工具调用记录。
|
|
1380
1376
|
if (!childAgent) {
|
|
@@ -5,7 +5,7 @@ const uuid_1 = require("uuid");
|
|
|
5
5
|
const shared_1 = require("@myassis/shared");
|
|
6
6
|
const logger = (0, shared_1.getLogger)('SessionManager');
|
|
7
7
|
const SessionStore_js_1 = require("./SessionStore.js");
|
|
8
|
-
const authStore_js_1 = require("
|
|
8
|
+
const authStore_js_1 = require("../../stores/authStore.js");
|
|
9
9
|
const Session_js_1 = require("./Session.js");
|
|
10
10
|
const ToolCallArchive_js_1 = require("../memory/ToolCallArchive.js");
|
|
11
11
|
/**
|
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getSystemPromptAsync = exports.LANGUAGES = exports.CHAT_STYLE_TEMPLATES = void 0;
|
|
7
|
-
const index_js_1 = require("
|
|
7
|
+
const index_js_1 = require("../stores/index.js");
|
|
8
8
|
const os_1 = __importDefault(require("os"));
|
|
9
9
|
const dataService_js_1 = require("./dataService.js");
|
|
10
10
|
const shared_1 = require("@myassis/shared");
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.modelTool = void 0;
|
|
4
4
|
const dataService_js_1 = require("../dataService.js");
|
|
5
|
-
const index_js_1 = require("
|
|
5
|
+
const index_js_1 = require("../../stores/index.js");
|
|
6
6
|
exports.modelTool = {
|
|
7
7
|
name: 'model',
|
|
8
8
|
description: '模型管理工具',
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.skillTool = void 0;
|
|
4
4
|
const dataService_js_1 = require("../dataService.js");
|
|
5
|
-
const index_js_1 = require("
|
|
5
|
+
const index_js_1 = require("../../stores/index.js");
|
|
6
6
|
const shared_1 = require("@myassis/shared");
|
|
7
7
|
const logger = (0, shared_1.getLogger)('skill');
|
|
8
8
|
exports.skillTool = {
|
package/package.json
CHANGED
package/scripts/pkg-build-win.js
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
// pkg-build-win.js - Windows pkg build using PKG_CACHE_PATH
|
|
3
|
-
// Points to ~/.pkg-cache which contains the correct v3.6 patched binary (40.6 MB, hash matches)
|
|
4
|
-
'use strict';
|
|
5
|
-
const { spawn } = require('child_process');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const os = require('os');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
|
|
10
|
-
const TARGET = process.argv[2] || 'node18-win-x64';
|
|
11
|
-
const OUTPUT = process.argv[3] || 'myassis-gateway-win.exe';
|
|
12
|
-
|
|
13
|
-
const CACHE_DIR = path.join(os.homedir(), '.pkg-cache');
|
|
14
|
-
const PKG_BIN = path.resolve(__dirname, '../node_modules/@yao-pkg/pkg/lib-es5/bin.js');
|
|
15
|
-
|
|
16
|
-
function log(msg) { console.error('[pkg-build] ' + msg); }
|
|
17
|
-
|
|
18
|
-
/** 根据 target (如 node24-win-x64) 在缓存目录中找到匹配的二进制 */
|
|
19
|
-
function findCachedBinary(target) {
|
|
20
|
-
const m = target.match(/^node(\d+)-(.+)$/);
|
|
21
|
-
if (!m) return null;
|
|
22
|
-
const [, major, plat] = m;
|
|
23
|
-
const v36dir = path.join(CACHE_DIR, 'v3.6');
|
|
24
|
-
if (!fs.existsSync(v36dir)) return null;
|
|
25
|
-
const candidates = fs.readdirSync(v36dir)
|
|
26
|
-
.filter(f => new RegExp(`^fetched-v${major}\\.\\d+\\.\\d+-${plat}$`).test(f))
|
|
27
|
-
.sort()
|
|
28
|
-
.reverse();
|
|
29
|
-
return candidates.length > 0 ? path.join(v36dir, candidates[0]) : null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function main() {
|
|
33
|
-
log(`Building for ${TARGET}`);
|
|
34
|
-
log(`Output: ${OUTPUT}`);
|
|
35
|
-
|
|
36
|
-
// Verify cached binary exists (dynamically match by target)
|
|
37
|
-
const cachedBinary = findCachedBinary(TARGET);
|
|
38
|
-
if (!cachedBinary) {
|
|
39
|
-
log(`ERROR: No cached binary found for target ${TARGET} in ${CACHE_DIR}`);
|
|
40
|
-
log(`Please run: node node_modules/@yao-pkg/pkg/lib-es5/bin.js --targets ${TARGET} first`);
|
|
41
|
-
process.exit(1);
|
|
42
|
-
}
|
|
43
|
-
const size = (fs.statSync(cachedBinary).size / 1024 / 1024).toFixed(1);
|
|
44
|
-
log(`Using cached binary: ${cachedBinary} (${size} MB)`);
|
|
45
|
-
|
|
46
|
-
// Use PKG_CACHE_PATH so pkg-fetch finds the correct v3.6 binary by hash
|
|
47
|
-
const env = { ...process.env };
|
|
48
|
-
delete env.PKG_NODE_PATH; // MUST NOT use PKG_NODE_PATH - it bypasses placeholders check
|
|
49
|
-
env.PKG_CACHE_PATH = CACHE_DIR;
|
|
50
|
-
log(`PKG_CACHE_PATH=${CACHE_DIR}`);
|
|
51
|
-
|
|
52
|
-
log('Starting pkg...');
|
|
53
|
-
return new Promise((resolve) => {
|
|
54
|
-
const child = spawn(process.execPath, [PKG_BIN, '.', '--targets', TARGET, '--output', OUTPUT], {
|
|
55
|
-
cwd: path.resolve(__dirname, '..'),
|
|
56
|
-
env,
|
|
57
|
-
stdio: 'inherit'
|
|
58
|
-
});
|
|
59
|
-
child.on('exit', (code) => process.exit(code || 0));
|
|
60
|
-
child.on('error', (e) => { log('Spawn error: ' + e.message); process.exit(1); });
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
main().catch(e => { console.error('[pkg-build] Fatal:', e.message); process.exit(1); });
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// pkg-build-win.js - Windows pkg build using PKG_CACHE_PATH
|
|
3
|
+
// Points to ~/.pkg-cache which contains the correct v3.6 patched binary (40.6 MB, hash matches)
|
|
4
|
+
'use strict';
|
|
5
|
+
const { spawn } = require('child_process');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const os = require('os');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
|
|
10
|
+
const TARGET = process.argv[2] || 'node18-win-x64';
|
|
11
|
+
const OUTPUT = process.argv[3] || 'myassis-gateway-win.exe';
|
|
12
|
+
|
|
13
|
+
const CACHE_DIR = path.join(os.homedir(), '.pkg-cache');
|
|
14
|
+
const PKG_BIN = path.resolve(__dirname, '../node_modules/@yao-pkg/pkg/lib-es5/bin.js');
|
|
15
|
+
|
|
16
|
+
function log(msg) { console.error('[pkg-build] ' + msg); }
|
|
17
|
+
|
|
18
|
+
/** 根据 target (如 node24-win-x64) 在缓存目录中找到匹配的二进制 */
|
|
19
|
+
function findCachedBinary(target) {
|
|
20
|
+
const m = target.match(/^node(\d+)-(.+)$/);
|
|
21
|
+
if (!m) return null;
|
|
22
|
+
const [, major, plat] = m;
|
|
23
|
+
const v36dir = path.join(CACHE_DIR, 'v3.6');
|
|
24
|
+
if (!fs.existsSync(v36dir)) return null;
|
|
25
|
+
const candidates = fs.readdirSync(v36dir)
|
|
26
|
+
.filter(f => new RegExp(`^fetched-v${major}\\.\\d+\\.\\d+-${plat}$`).test(f))
|
|
27
|
+
.sort()
|
|
28
|
+
.reverse();
|
|
29
|
+
return candidates.length > 0 ? path.join(v36dir, candidates[0]) : null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
log(`Building for ${TARGET}`);
|
|
34
|
+
log(`Output: ${OUTPUT}`);
|
|
35
|
+
|
|
36
|
+
// Verify cached binary exists (dynamically match by target)
|
|
37
|
+
const cachedBinary = findCachedBinary(TARGET);
|
|
38
|
+
if (!cachedBinary) {
|
|
39
|
+
log(`ERROR: No cached binary found for target ${TARGET} in ${CACHE_DIR}`);
|
|
40
|
+
log(`Please run: node node_modules/@yao-pkg/pkg/lib-es5/bin.js --targets ${TARGET} first`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
const size = (fs.statSync(cachedBinary).size / 1024 / 1024).toFixed(1);
|
|
44
|
+
log(`Using cached binary: ${cachedBinary} (${size} MB)`);
|
|
45
|
+
|
|
46
|
+
// Use PKG_CACHE_PATH so pkg-fetch finds the correct v3.6 binary by hash
|
|
47
|
+
const env = { ...process.env };
|
|
48
|
+
delete env.PKG_NODE_PATH; // MUST NOT use PKG_NODE_PATH - it bypasses placeholders check
|
|
49
|
+
env.PKG_CACHE_PATH = CACHE_DIR;
|
|
50
|
+
log(`PKG_CACHE_PATH=${CACHE_DIR}`);
|
|
51
|
+
|
|
52
|
+
log('Starting pkg...');
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
const child = spawn(process.execPath, [PKG_BIN, '.', '--targets', TARGET, '--output', OUTPUT], {
|
|
55
|
+
cwd: path.resolve(__dirname, '..'),
|
|
56
|
+
env,
|
|
57
|
+
stdio: 'inherit'
|
|
58
|
+
});
|
|
59
|
+
child.on('exit', (code) => process.exit(code || 0));
|
|
60
|
+
child.on('error', (e) => { log('Spawn error: ' + e.message); process.exit(1); });
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main().catch(e => { console.error('[pkg-build] Fatal:', e.message); process.exit(1); });
|