@myassis/gateway 1.0.6 → 1.0.7
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/index.js +1 -0
- package/dist/middleware/auth.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 +1 -1
- package/dist/services/memory/MemoryManager.js +2 -2
- package/dist/services/session/Session.js +6 -6
- package/dist/services/session/SessionManager.js +1 -1
- package/dist/services/systemPrompt.js +1 -1
- package/dist/services/tools/keyboard.js +61 -63
- package/dist/services/tools/model.js +1 -1
- package/dist/services/tools/mouse.js +45 -67
- package/dist/services/tools/skill.js +1 -1
- package/package.json +2 -2
- package/scripts/add-shebang.js +19 -0
package/dist/index.js
CHANGED
package/dist/middleware/auth.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* 从请求头 Authorization: Bearer <token> 解码 JWT,提取 userId
|
|
4
4
|
* 同时保留原始 token 供路由转发给 Server
|
|
5
5
|
*/
|
|
6
|
-
import { authStore } from '
|
|
6
|
+
import { authStore } from '../stores';
|
|
7
7
|
import { getLogger } from '@myassis/shared';
|
|
8
8
|
const logger = getLogger('middleware/auth');
|
|
9
9
|
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-in-production';
|
package/dist/routes/agent.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
|
-
import { requireAuth } from '
|
|
3
|
-
import { runWithToken } from '
|
|
4
|
-
import { getSessionManager } from '
|
|
5
|
-
import { initAgentManager, agentManagerMap } from '
|
|
6
|
-
import { AgentStore } from '
|
|
2
|
+
import { requireAuth } from '../middleware/auth.js';
|
|
3
|
+
import { runWithToken } from '../api/index.js';
|
|
4
|
+
import { getSessionManager } from '../services/session';
|
|
5
|
+
import { initAgentManager, agentManagerMap } from '../services/agent/AgentManager';
|
|
6
|
+
import { AgentStore } from '../services/agent/AgentStore';
|
|
7
7
|
import { getLogger } from '@myassis/shared';
|
|
8
8
|
const logger = getLogger('AgentRoutes');
|
|
9
|
-
import { sessionStore } from '
|
|
9
|
+
import { sessionStore } from '../services/session/SessionStore';
|
|
10
10
|
const router = Router();
|
|
11
11
|
// 所有路由需要认证
|
|
12
12
|
router.use(requireAuth, (req, _res, next) => {
|
package/dist/routes/upload.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Router } from 'express';
|
|
2
2
|
import multer from 'multer';
|
|
3
|
-
import { appConfig } from '
|
|
4
|
-
import { requireAuth } from '
|
|
5
|
-
import { runWithToken } from '
|
|
3
|
+
import { appConfig } from '../config/index.js';
|
|
4
|
+
import { requireAuth } from '../middleware/auth.js';
|
|
5
|
+
import { runWithToken } from '../api/index.js';
|
|
6
6
|
import { getLogger } from '@myassis/shared';
|
|
7
7
|
const logger = getLogger('UploadRoutes');
|
|
8
8
|
const router = Router();
|
|
@@ -8,7 +8,7 @@ import { webSocketService } from './WebSocketService';
|
|
|
8
8
|
import { getSessionManager } from './session';
|
|
9
9
|
import { getLogger, getUTCTimeKey, formatUTCForLog, holidayService } from '@myassis/shared';
|
|
10
10
|
import { tasksService } from './dataService';
|
|
11
|
-
import { authStore } from '
|
|
11
|
+
import { authStore } from '../stores';
|
|
12
12
|
const logger = getLogger('TaskSchedulerService');
|
|
13
13
|
const EXPIRED_THRESHOLD = 60 * 60 * 1000; // 1小时
|
|
14
14
|
const CHECK_INTERVAL = 60 * 1000; // 1分钟
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - platformApply === currentPlatform → 本地 SQLite 存储(localTaskService)
|
|
8
8
|
* - platformApply !== currentPlatform → 服务器 API(tasksApi)
|
|
9
9
|
*/
|
|
10
|
-
import { authStore } from '
|
|
10
|
+
import { authStore } from '../stores';
|
|
11
11
|
import { tasksApi } from '../api';
|
|
12
12
|
import { localTaskService } from './LocalTaskService';
|
|
13
13
|
import { getLogger } from '@myassis/shared';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
2
|
import { Agent } from './Agent';
|
|
3
3
|
import { getSessionManager } from '../session/SessionManager';
|
|
4
|
-
import { authStore } from '
|
|
4
|
+
import { authStore } from '../../stores/authStore';
|
|
5
5
|
import { getLogger } from '@myassis/shared';
|
|
6
|
-
import appConfig from '
|
|
6
|
+
import appConfig from '../../config';
|
|
7
7
|
const logger = getLogger('AgentManager');
|
|
8
8
|
/**
|
|
9
9
|
* AgentManager - Business logic layer
|
|
@@ -2,9 +2,9 @@ import { getLogger } from '@myassis/shared';
|
|
|
2
2
|
const logger = getLogger('MemoryManager');
|
|
3
3
|
import { toModel } from '../models';
|
|
4
4
|
import { modelsService } from '../dataService';
|
|
5
|
-
import { authStore } from '
|
|
5
|
+
import { authStore } from '../../stores';
|
|
6
6
|
import { LLMClient } from '../llm/LLMClient';
|
|
7
|
-
import { appConfig } from '
|
|
7
|
+
import { appConfig } from '../../config';
|
|
8
8
|
const DEFAULT_CONFIG = {
|
|
9
9
|
summaryThreshold: 10,
|
|
10
10
|
enabled: true,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { v4 as uuidv4 } from 'uuid';
|
|
2
2
|
import { getLogger } from '@myassis/shared';
|
|
3
3
|
import { SessionStore } from './SessionStore';
|
|
4
|
-
import { AgentStore } from '
|
|
5
|
-
import { authStore } from '
|
|
6
|
-
import { toModel } from '
|
|
7
|
-
import { executeTool, getToolDefinitions } from '
|
|
4
|
+
import { AgentStore } from '../../services/agent/AgentStore';
|
|
5
|
+
import { authStore } from '../../stores/authStore';
|
|
6
|
+
import { toModel } from '../../services/models';
|
|
7
|
+
import { executeTool, getToolDefinitions } from '../../services/tools';
|
|
8
8
|
import { getSystemPromptAsync } from '../systemPrompt';
|
|
9
9
|
import { LLMClient, parseAruments } from '../llm/LLMClient';
|
|
10
|
-
import { modelsService, settingsService } from '
|
|
10
|
+
import { modelsService, settingsService } from '../../services/dataService';
|
|
11
11
|
import { MemoryManager } from '../memory/MemoryManager';
|
|
12
|
-
import { appConfig } from '
|
|
12
|
+
import { appConfig } from '../../config';
|
|
13
13
|
import { getSessionManager } from './SessionManager';
|
|
14
14
|
const logger = getLogger('Session');
|
|
15
15
|
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
|
|
@@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
|
|
|
2
2
|
import { getLogger } from '@myassis/shared';
|
|
3
3
|
const logger = getLogger('SessionManager');
|
|
4
4
|
import { sessionStore } from './SessionStore';
|
|
5
|
-
import { authStore } from '
|
|
5
|
+
import { authStore } from '../../stores/authStore';
|
|
6
6
|
import { Session } from './Session';
|
|
7
7
|
/**
|
|
8
8
|
* SessionManager - Business logic layer
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { keyboard, Key } from '@nut-tree
|
|
2
|
-
//
|
|
1
|
+
import { keyboard, Key } from '@nut-tree/nut-js';
|
|
2
|
+
// 可打印 ASCII 字符范围(空格到 ~)
|
|
3
3
|
const PRINTABLE_ASCII_START = 32;
|
|
4
4
|
const PRINTABLE_ASCII_END = 126;
|
|
5
|
-
//
|
|
5
|
+
// 校验文本中的所有字符是否都是键盘可输入的字符
|
|
6
6
|
function validateText(text) {
|
|
7
7
|
for (let i = 0; i < text.length; i++) {
|
|
8
8
|
const charCode = text.charCodeAt(i);
|
|
9
|
-
//
|
|
9
|
+
// 检查是否在可打印 ASCII 范围内
|
|
10
10
|
if (charCode < PRINTABLE_ASCII_START || charCode > PRINTABLE_ASCII_END) {
|
|
11
11
|
return { valid: false, invalidChar: text[i], charCode };
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
return { valid: true };
|
|
15
15
|
}
|
|
16
|
-
//
|
|
16
|
+
// 按键名称到 nut-js Key 的映射
|
|
17
17
|
const keyMap = {
|
|
18
|
-
//
|
|
18
|
+
// 常用键
|
|
19
19
|
enter: Key.Enter,
|
|
20
20
|
return: Key.Enter,
|
|
21
21
|
escape: Key.Escape,
|
|
@@ -25,12 +25,12 @@ const keyMap = {
|
|
|
25
25
|
backspace: Key.Backspace,
|
|
26
26
|
delete: Key.Delete,
|
|
27
27
|
del: Key.Delete,
|
|
28
|
-
//
|
|
28
|
+
// 方向键
|
|
29
29
|
up: Key.Up,
|
|
30
30
|
down: Key.Down,
|
|
31
31
|
left: Key.Left,
|
|
32
32
|
right: Key.Right,
|
|
33
|
-
//
|
|
33
|
+
// 功能键
|
|
34
34
|
f1: Key.F1,
|
|
35
35
|
f2: Key.F2,
|
|
36
36
|
f3: Key.F3,
|
|
@@ -43,7 +43,7 @@ const keyMap = {
|
|
|
43
43
|
f10: Key.F10,
|
|
44
44
|
f11: Key.F11,
|
|
45
45
|
f12: Key.F12,
|
|
46
|
-
//
|
|
46
|
+
// 修饰键
|
|
47
47
|
ctrl: Key.LeftControl,
|
|
48
48
|
control: Key.LeftControl,
|
|
49
49
|
alt: Key.LeftAlt,
|
|
@@ -53,7 +53,7 @@ const keyMap = {
|
|
|
53
53
|
cmd: Key.LeftSuper,
|
|
54
54
|
command: Key.LeftSuper,
|
|
55
55
|
};
|
|
56
|
-
//
|
|
56
|
+
// 解析组合键,如 "Ctrl+C" 或 "Alt+Shift+F4"
|
|
57
57
|
function parseHotkey(keysStr) {
|
|
58
58
|
const parts = keysStr.split(/[+\-]/).map(s => s.trim().toLowerCase());
|
|
59
59
|
const keys = [];
|
|
@@ -63,7 +63,7 @@ function parseHotkey(keysStr) {
|
|
|
63
63
|
keys.push(mappedKey);
|
|
64
64
|
}
|
|
65
65
|
else {
|
|
66
|
-
//
|
|
66
|
+
// 处理单个字符
|
|
67
67
|
if (part.length === 1) {
|
|
68
68
|
keys.push(part);
|
|
69
69
|
}
|
|
@@ -71,77 +71,75 @@ function parseHotkey(keysStr) {
|
|
|
71
71
|
}
|
|
72
72
|
return keys;
|
|
73
73
|
}
|
|
74
|
-
//
|
|
74
|
+
// 解析单个按键
|
|
75
75
|
function parseKey(keyStr) {
|
|
76
76
|
const lowerKey = keyStr.toLowerCase();
|
|
77
77
|
if (keyMap[lowerKey]) {
|
|
78
78
|
return keyMap[lowerKey];
|
|
79
79
|
}
|
|
80
|
-
//
|
|
80
|
+
// 单个字符直接返回
|
|
81
81
|
if (keyStr.length === 1) {
|
|
82
82
|
return keyStr;
|
|
83
83
|
}
|
|
84
|
-
throw new Error(
|
|
84
|
+
throw new Error(`未知按键: ${keyStr}`);
|
|
85
85
|
}
|
|
86
86
|
export const keyboardTool = {
|
|
87
87
|
name: 'keyboard',
|
|
88
|
-
description: '
|
|
88
|
+
description: '控制键盘输入和按键操作',
|
|
89
89
|
parameters: {
|
|
90
90
|
type: 'object',
|
|
91
91
|
properties: {
|
|
92
92
|
action: {
|
|
93
93
|
type: 'string',
|
|
94
|
-
description: '
|
|
94
|
+
description: '操作类型:type(输入文本)、press(按压键)、hotkey(组合键)',
|
|
95
95
|
enum: ['type', 'press', 'hotkey'],
|
|
96
96
|
},
|
|
97
|
-
text: { type: 'string', description: '
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
},
|
|
97
|
+
text: { type: 'string', description: '要输入的文本(type 必填)' },
|
|
98
|
+
key: { type: 'string', description: '按键名称(press 必填),如 Enter、Escape、Tab' },
|
|
99
|
+
keys: {
|
|
100
|
+
type: 'string',
|
|
101
|
+
description: '组合键,如 Ctrl+C、Alt+F4(hotkey 必填)',
|
|
103
102
|
},
|
|
104
|
-
required: ['action'],
|
|
105
103
|
},
|
|
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
|
-
catch (error) {
|
|
143
|
-
return { success: false, errorMessage: `閿洏鎿嶄綔澶辫触: ${error?.message || error}` };
|
|
104
|
+
required: ['action'],
|
|
105
|
+
},
|
|
106
|
+
handler: async (args) => {
|
|
107
|
+
try {
|
|
108
|
+
const { action, text, key, keys } = args;
|
|
109
|
+
switch (action) {
|
|
110
|
+
case 'type':
|
|
111
|
+
if (typeof text !== 'string') {
|
|
112
|
+
return { success: false, errorMessage: 'type 操作需要 text 参数' };
|
|
113
|
+
}
|
|
114
|
+
const validation = validateText(text);
|
|
115
|
+
if (!validation.valid) {
|
|
116
|
+
return { success: false, errorMessage: `文本包含不可输入字符: "${validation.invalidChar}" (字符码: ${validation.charCode})` };
|
|
117
|
+
}
|
|
118
|
+
await keyboard.type(text);
|
|
119
|
+
return { success: true, output: `已输入文本: "${text}"` };
|
|
120
|
+
case 'press':
|
|
121
|
+
if (typeof key !== 'string') {
|
|
122
|
+
return { success: false, errorMessage: 'press 操作需要 key 参数' };
|
|
123
|
+
}
|
|
124
|
+
const parsedKey = parseKey(key);
|
|
125
|
+
await keyboard.pressKey(parsedKey);
|
|
126
|
+
return { success: true, output: `已按下按键: ${key}` };
|
|
127
|
+
case 'hotkey':
|
|
128
|
+
if (typeof keys !== 'string') {
|
|
129
|
+
return { success: false, errorMessage: 'hotkey 操作需要 keys 参数' };
|
|
130
|
+
}
|
|
131
|
+
const hotkeys = parseHotkey(keys);
|
|
132
|
+
if (hotkeys.length === 0) {
|
|
133
|
+
return { success: false, errorMessage: '无法解析组合键' };
|
|
134
|
+
}
|
|
135
|
+
await keyboard.pressKey(...hotkeys);
|
|
136
|
+
return { success: true, output: `已执行组合键: ${keys}` };
|
|
137
|
+
default:
|
|
138
|
+
return { success: false, errorMessage: `未知的键盘操作: ${action}` };
|
|
144
139
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
return { success: false, errorMessage: `键盘操作失败: ${error?.message || error}` };
|
|
143
|
+
}
|
|
144
|
+
},
|
|
147
145
|
};
|
|
@@ -1,77 +1,55 @@
|
|
|
1
|
-
import { mouse, Button } from '@nut-tree
|
|
1
|
+
import { mouse, Button } from '@nut-tree/nut-js';
|
|
2
2
|
export const mouseTool = {
|
|
3
3
|
name: 'mouse',
|
|
4
|
-
description: '
|
|
4
|
+
description: '控制鼠标移动、点击和滚轮操作',
|
|
5
5
|
parameters: {
|
|
6
6
|
type: 'object',
|
|
7
7
|
properties: {
|
|
8
8
|
action: {
|
|
9
9
|
type: 'string',
|
|
10
|
-
description: '
|
|
10
|
+
description: '鼠标操作类型:move、click、rightClick、doubleClick、scroll、position',
|
|
11
11
|
},
|
|
12
|
-
x: { type: 'number', description: '
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
default:
|
|
52
|
-
return { success: false, errorMessage: `;
|
|
53
|
-
鏈;
|
|
54
|
-
煡鐨勯紶鏍囨搷浣 ? $ : ;
|
|
55
|
-
{
|
|
56
|
-
action;
|
|
57
|
-
}
|
|
58
|
-
` };
|
|
59
|
-
}
|
|
60
|
-
} catch (error: any) {
|
|
61
|
-
return { success: false, errorMessage: `;
|
|
62
|
-
榧犳爣鎿嶄綔澶辫触: $;
|
|
63
|
-
{
|
|
64
|
-
error?.message || error;
|
|
65
|
-
}
|
|
66
|
-
` };
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
finally { }
|
|
74
|
-
} } }
|
|
12
|
+
x: { type: 'number', description: '目标 X 坐标(move 必填)' },
|
|
13
|
+
y: { type: 'number', description: '目标 Y 坐标(move 必填)' },
|
|
14
|
+
button: { type: 'string', description: '鼠标按钮:left、right、middle,默认 left', default: 'left' },
|
|
15
|
+
scrollX: { type: 'number', description: '水平滚动量', default: 0 },
|
|
16
|
+
scrollY: { type: 'number', description: '垂直滚动量', default: 0 },
|
|
17
|
+
},
|
|
18
|
+
required: ['action'],
|
|
19
|
+
},
|
|
20
|
+
handler: async (args) => {
|
|
21
|
+
try {
|
|
22
|
+
const { action, x, y, button = 'left', scrollX = 0, scrollY = 0 } = args;
|
|
23
|
+
switch (action) {
|
|
24
|
+
case 'move':
|
|
25
|
+
if (typeof x !== 'number' || typeof y !== 'number') {
|
|
26
|
+
return { success: false, errorMessage: 'move 操作需要 x 和 y 坐标' };
|
|
27
|
+
}
|
|
28
|
+
await mouse.setPosition({ x, y });
|
|
29
|
+
return { success: true, output: `鼠标移动到 (${x}, ${y})` };
|
|
30
|
+
case 'click':
|
|
31
|
+
case 'rightClick':
|
|
32
|
+
case 'doubleClick':
|
|
33
|
+
if (action === 'doubleClick') {
|
|
34
|
+
await mouse.click(Button.LEFT);
|
|
35
|
+
await new Promise(r => setTimeout(r, 100));
|
|
36
|
+
}
|
|
37
|
+
const btn = button === 'right' ? Button.RIGHT : button === 'middle' ? Button.MIDDLE : Button.LEFT;
|
|
38
|
+
await mouse.click(btn);
|
|
39
|
+
return { success: true, output: `${button} 键${action === 'doubleClick' ? '双' : ''}击成功` };
|
|
40
|
+
case 'scroll':
|
|
41
|
+
await mouse.scrollDown(scrollY);
|
|
42
|
+
await mouse.scrollRight(scrollX);
|
|
43
|
+
return { success: true, output: `滚动 (${scrollX}, ${scrollY})` };
|
|
44
|
+
case 'position':
|
|
45
|
+
const pos = await mouse.getPosition();
|
|
46
|
+
return { success: true, output: `当前鼠标位置 (${pos.x}, ${pos.y})` };
|
|
47
|
+
default:
|
|
48
|
+
return { success: false, errorMessage: `未知的鼠标操作: ${action}` };
|
|
49
|
+
}
|
|
75
50
|
}
|
|
76
|
-
|
|
51
|
+
catch (error) {
|
|
52
|
+
return { success: false, errorMessage: `鼠标操作失败: ${error?.message || error}` };
|
|
53
|
+
}
|
|
54
|
+
},
|
|
77
55
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { skillsService, skillHubService } from '../dataService';
|
|
2
|
-
import { authStore, persistStore } from '
|
|
2
|
+
import { authStore, persistStore } from '../../stores';
|
|
3
3
|
import { getLogger } from '@myassis/shared';
|
|
4
4
|
const logger = getLogger('skill');
|
|
5
5
|
export const skillTool = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@myassis/gateway",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "我的助手 Gateway Service - 本地 AI 网关服务,支持认证、WebSocket 实时通信和任务调度",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"dev": "tsx watch src/index.ts",
|
|
25
25
|
"start": "node dist/index.js",
|
|
26
26
|
"build": "tsc --skipLibCheck",
|
|
27
|
-
"postbuild": "node -
|
|
27
|
+
"postbuild": "node scripts/add-shebang.js && npx tsc-alias",
|
|
28
28
|
"pkg:win": "pkg . --targets node18-win-x64 --output myassis-gateway-win.exe",
|
|
29
29
|
"pkg:linux": "pkg . --targets node18-linux-x64 --output myassis-gateway-linux",
|
|
30
30
|
"pkg:all": "npm run pkg:win && npm run pkg:linux",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
const filePath = path.join(__dirname, '..', 'dist', 'index.js');
|
|
10
|
+
|
|
11
|
+
// 检查并添加 shebang
|
|
12
|
+
let content = fs.readFileSync(filePath, 'utf8');
|
|
13
|
+
if (!content.startsWith('#!')) {
|
|
14
|
+
content = '#!/usr/bin/env node\n' + content;
|
|
15
|
+
fs.writeFileSync(filePath, content, 'utf8');
|
|
16
|
+
console.log('✅ Added shebang to dist/index.js');
|
|
17
|
+
} else {
|
|
18
|
+
console.log('ℹ️ Shebang already exists in dist/index.js');
|
|
19
|
+
}
|