@sstar/embedlink_agent 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.
Files changed (53) hide show
  1. package/README.md +107 -0
  2. package/dist/.platform +1 -0
  3. package/dist/board/docs.js +59 -0
  4. package/dist/board/notes.js +11 -0
  5. package/dist/board_uart/history.js +81 -0
  6. package/dist/board_uart/index.js +66 -0
  7. package/dist/board_uart/manager.js +313 -0
  8. package/dist/board_uart/resource.js +578 -0
  9. package/dist/board_uart/sessions.js +559 -0
  10. package/dist/config/index.js +341 -0
  11. package/dist/core/activity.js +7 -0
  12. package/dist/core/errors.js +45 -0
  13. package/dist/core/log_stream.js +26 -0
  14. package/dist/files/__tests__/files_manager.test.js +209 -0
  15. package/dist/files/artifact_manager.js +68 -0
  16. package/dist/files/file_operation_logger.js +271 -0
  17. package/dist/files/files_manager.js +511 -0
  18. package/dist/files/index.js +87 -0
  19. package/dist/files/types.js +5 -0
  20. package/dist/firmware/burn_recover.js +733 -0
  21. package/dist/firmware/prepare_images.js +184 -0
  22. package/dist/firmware/user_guide.js +43 -0
  23. package/dist/index.js +449 -0
  24. package/dist/logger.js +245 -0
  25. package/dist/macro/index.js +241 -0
  26. package/dist/macro/runner.js +168 -0
  27. package/dist/nfs/index.js +105 -0
  28. package/dist/plugins/loader.js +30 -0
  29. package/dist/proto/agent.proto +473 -0
  30. package/dist/resources/docs/board-interaction.md +115 -0
  31. package/dist/resources/docs/firmware-upgrade.md +404 -0
  32. package/dist/resources/docs/nfs-mount-guide.md +78 -0
  33. package/dist/resources/docs/tftp-transfer-guide.md +81 -0
  34. package/dist/secrets/index.js +9 -0
  35. package/dist/server/grpc.js +1069 -0
  36. package/dist/server/web.js +2284 -0
  37. package/dist/ssh/adapter.js +126 -0
  38. package/dist/ssh/candidates.js +85 -0
  39. package/dist/ssh/index.js +3 -0
  40. package/dist/ssh/paircheck.js +35 -0
  41. package/dist/ssh/tunnel.js +111 -0
  42. package/dist/tftp/client.js +345 -0
  43. package/dist/tftp/index.js +284 -0
  44. package/dist/tftp/server.js +731 -0
  45. package/dist/uboot/index.js +45 -0
  46. package/dist/ui/assets/index-BlnLVmbt.js +374 -0
  47. package/dist/ui/assets/index-xMbarYXA.css +32 -0
  48. package/dist/ui/index.html +21 -0
  49. package/dist/utils/network.js +150 -0
  50. package/dist/utils/platform.js +83 -0
  51. package/dist/utils/port-check.js +153 -0
  52. package/dist/utils/user-prompt.js +139 -0
  53. package/package.json +64 -0
@@ -0,0 +1,139 @@
1
+ import readline from 'node:readline';
2
+ /**
3
+ * 提示用户处理端口冲突
4
+ */
5
+ export async function promptUserForPortConflict(port, conflictInfo) {
6
+ // 检查是否在TTY环境中
7
+ if (!process.stdin.isTTY) {
8
+ // 非交互模式,自动选择备用端口
9
+ return {
10
+ action: 'change_port',
11
+ newPort: port + 1,
12
+ };
13
+ }
14
+ const rl = readline.createInterface({
15
+ input: process.stdin,
16
+ output: process.stdout,
17
+ });
18
+ try {
19
+ console.log(`\n❌ 端口 ${port} 被占用:`);
20
+ if (conflictInfo?.process?.command) {
21
+ console.log(` 占用进程: ${conflictInfo.process.command}`);
22
+ }
23
+ console.log(` 端口69是TFTP协议的标准端口`);
24
+ console.log(` 如果这是其他TFTP服务器,建议使用外部服务器模式`);
25
+ console.log('\n请选择处理方式:');
26
+ console.log('1. 使用备用端口启动内置TFTP服务器 (如70)');
27
+ console.log('2. 配置外部TFTP服务器 (指定其他TFTP服务器地址)');
28
+ console.log('3. 停止占用端口的进程后重试 (需要手动操作)');
29
+ console.log('4. 禁用TFTP服务器 (仅保留文件管理功能)');
30
+ const answer = await new Promise((resolve) => {
31
+ rl.question('\n请输入选择 (1-4): ', resolve);
32
+ });
33
+ switch (answer.trim()) {
34
+ case '1':
35
+ const newPort = await askForPort(rl, port + 1, '备用端口');
36
+ return { action: 'change_port', newPort };
37
+ case '2':
38
+ const externalHost = await askForString(rl, '外部TFTP服务器地址', '127.0.0.1');
39
+ const externalPort = await askForPort(rl, 69, '外部TFTP服务器端口');
40
+ return { action: 'use_external', externalHost, externalPort };
41
+ case '3':
42
+ console.log('\n请手动停止占用端口的进程后重新启动Agent:');
43
+ if (conflictInfo?.process?.pid) {
44
+ console.log(` 停止进程: kill -9 ${conflictInfo.process.pid}`);
45
+ }
46
+ else {
47
+ console.log(' 查找进程: lsof -i :' + port + ' (Linux/macOS)');
48
+ console.log(' 查找进程: netstat -aon | findstr :' + port + ' (Windows)');
49
+ }
50
+ console.log('\nAgent即将退出...');
51
+ await new Promise((resolve) => setTimeout(resolve, 2000));
52
+ process.exit(1);
53
+ case '4':
54
+ return { action: 'disable' };
55
+ default:
56
+ console.log('\n❌ 无效选择,将使用备用端口启动');
57
+ const fallbackPort = port + 1;
58
+ return { action: 'change_port', newPort: fallbackPort };
59
+ }
60
+ }
61
+ finally {
62
+ rl.close();
63
+ }
64
+ }
65
+ /**
66
+ * 询问端口号
67
+ */
68
+ async function askForPort(rl, defaultPort, label) {
69
+ while (true) {
70
+ const answer = await new Promise((resolve) => {
71
+ rl.question(`${label} (默认 ${defaultPort}): `, resolve);
72
+ });
73
+ const input = answer.trim();
74
+ if (input === '') {
75
+ return defaultPort;
76
+ }
77
+ const port = parseInt(input);
78
+ if (isNaN(port) || port < 1 || port > 65535) {
79
+ console.log('❌ 无效的端口号,请输入1-65535之间的数字');
80
+ continue;
81
+ }
82
+ return port;
83
+ }
84
+ }
85
+ /**
86
+ * 询问字符串
87
+ */
88
+ async function askForString(rl, prompt, defaultValue) {
89
+ const answer = await new Promise((resolve) => {
90
+ rl.question(`${prompt} (默认 ${defaultValue}): `, resolve);
91
+ });
92
+ return answer.trim() || defaultValue;
93
+ }
94
+ /**
95
+ * 询问用户确认 (y/n)
96
+ */
97
+ export async function askForConfirmation(message, defaultValue = true) {
98
+ if (!process.stdin.isTTY) {
99
+ return defaultValue;
100
+ }
101
+ const rl = readline.createInterface({
102
+ input: process.stdin,
103
+ output: process.stdout,
104
+ });
105
+ try {
106
+ const defaultStr = defaultValue ? 'Y/n' : 'y/N';
107
+ const answer = await new Promise((resolve) => {
108
+ rl.question(`${message} (${defaultStr}): `, resolve);
109
+ });
110
+ const input = answer.trim().toLowerCase();
111
+ if (input === '') {
112
+ return defaultValue;
113
+ }
114
+ return input === 'y' || input === 'yes';
115
+ }
116
+ finally {
117
+ rl.close();
118
+ }
119
+ }
120
+ /**
121
+ * 显示提示信息并等待用户按回车继续
122
+ */
123
+ export async function waitForEnter(message = '\n按回车键继续...') {
124
+ if (!process.stdin.isTTY) {
125
+ return;
126
+ }
127
+ const rl = readline.createInterface({
128
+ input: process.stdin,
129
+ output: process.stdout,
130
+ });
131
+ try {
132
+ await new Promise((resolve) => {
133
+ rl.question(message, () => resolve());
134
+ });
135
+ }
136
+ finally {
137
+ rl.close();
138
+ }
139
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@sstar/embedlink_agent",
3
+ "version": "0.1.0",
4
+ "description": "EmbedLink Agent - Board hardware access service for embedded development",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "embedlink": "dist/index.js"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "files": [
14
+ "dist/**",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc -p tsconfig.json",
20
+ "postbuild": "node scripts/inject-proto.mjs",
21
+ "prepack": "npm run build",
22
+ "start": "node dist/index.js"
23
+ },
24
+ "engines": {
25
+ "node": ">=18.0.0"
26
+ },
27
+ "keywords": [
28
+ "embedded",
29
+ "hardware",
30
+ "uart",
31
+ "serial",
32
+ "grpc",
33
+ "mcp",
34
+ "firmware",
35
+ "board"
36
+ ],
37
+ "author": "SStar",
38
+ "license": "MIT",
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/sstar/embed_link.git",
42
+ "directory": "packages/agent"
43
+ },
44
+ "dependencies": {
45
+ "@grpc/grpc-js": "^1.10.7",
46
+ "@grpc/proto-loader": "^0.7.13",
47
+ "@homebridge/node-pty-prebuilt-multiarch": "0.13.1",
48
+ "@toon-format/toon": "^2.1.0",
49
+ "express": "^4.19.2",
50
+ "serialport": "^12.0.0",
51
+ "ssh2": "^1.15.0",
52
+ "ws": "^8.18.0",
53
+ "yaml": "^2.5.0"
54
+ },
55
+ "files": [
56
+ "dist/**"
57
+ ],
58
+ "devDependencies": {
59
+ "@types/express": "^5.0.5",
60
+ "@types/ssh2": "^1.15.5",
61
+ "@types/ws": "^8.18.1",
62
+ "typescript": "^5.6.3"
63
+ }
64
+ }