shellx-ai 1.0.0 → 1.0.2

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/shellx.js CHANGED
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
36
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
37
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -18,6 +51,7 @@ exports.createHelpers = createShellX;
18
51
  exports.createShellXWithShellMonitoring = createShellXWithShellMonitoring;
19
52
  exports.createHelpersWithShellMonitoring = createShellXWithShellMonitoring;
20
53
  const index_1 = __importDefault(require("./index"));
54
+ const uuid_1 = require("uuid");
21
55
  /**
22
56
  * ShellX automation utilities for common patterns
23
57
  */
@@ -45,7 +79,7 @@ class ShellX {
45
79
  * 处理 shell 输出数据
46
80
  */
47
81
  handleShellOutput(chunks) {
48
- const [sid, sessionId, dataArrays] = chunks;
82
+ const [sessionId, len, dataArrays] = chunks;
49
83
  try {
50
84
  // 将 Uint8Array 数组转换为字符串
51
85
  let output = '';
@@ -66,9 +100,10 @@ class ShellX {
66
100
  // 更新总输出
67
101
  commandPromise.output = this.combineSessionOutputs(commandPromise.sessionOutputs);
68
102
  console.log(`📊 [Shell] 命令 ${commandKey} 累积输出长度: ${commandPromise.output.length}`);
69
- // 调用输出回调
103
+ // 调用输出回调(传递清理后的输出)
70
104
  if (commandPromise.options.onOutput) {
71
- commandPromise.options.onOutput(output);
105
+ const cleanOutput = this.cleanCommandOutput(output, commandPromise.command);
106
+ commandPromise.options.onOutput(cleanOutput);
72
107
  }
73
108
  // 检查是否满足完成条件
74
109
  this.checkCommandCompletion(commandKey, commandPromise, output);
@@ -87,10 +122,6 @@ class ShellX {
87
122
  if (output.includes(command)) {
88
123
  return true;
89
124
  }
90
- // 如果输出包含提示符,说明是命令完成
91
- if (this.containsPrompt(output)) {
92
- return true;
93
- }
94
125
  // 如果有多个命令在等待,按时间顺序分配
95
126
  const waitingCommands = Array.from(this.shellCommandPromises.keys());
96
127
  if (waitingCommands.length === 1) {
@@ -99,6 +130,41 @@ class ShellX {
99
130
  // 多个命令时,根据 sessionId 和命令创建时间进行启发式匹配
100
131
  return true; // 暂时返回 true,让所有命令都接收输出
101
132
  }
133
+ /**
134
+ * 清理命令输出,去除输入的命令内容
135
+ */
136
+ cleanCommandOutput(output, command) {
137
+ if (!output || !command) {
138
+ return output;
139
+ }
140
+ let cleanOutput = output;
141
+ // 去除命令回显(命令本身)
142
+ cleanOutput = cleanOutput.replace(new RegExp(this.escapeRegExp(command), 'g'), '');
143
+ // 去除可能的命令提示符前缀和后缀
144
+ const promptPatterns = [
145
+ /^\s*[^$#>\s]*[#$>]\s*/, // 匹配提示符前缀
146
+ /^\s*[^$#>\s]*@[^$#>\s]*[#$>]\s*/, // 匹配 user@host 格式
147
+ /^\s*[^$#>\s]*:\s*[^$#>\s]*[#$>]\s*/, // 匹配 path: 格式
148
+ /\s*[^$#>\s]*[#$>]\s*$/, // 匹配提示符后缀
149
+ /\s*[^$#>\s]*@[^$#>\s]*[#$>]\s*$/, // 匹配 user@host 后缀
150
+ /\s*[^$#>\s]*:\s*[^$#>\s]*[#$>]\s*$/, // 匹配 path: 后缀
151
+ /\s*\d+\|[^$#>\s]*[#$>]\s*$/, // 匹配 Android 格式后缀
152
+ ];
153
+ for (const pattern of promptPatterns) {
154
+ cleanOutput = cleanOutput.replace(pattern, '');
155
+ }
156
+ // 去除多余的空行和空格
157
+ cleanOutput = cleanOutput.replace(/^\s+|\s+$/g, ''); // 去除首尾空白
158
+ cleanOutput = cleanOutput.replace(/\n\s*\n/g, '\n'); // 去除多余空行
159
+ // 如果清理后为空,返回空字符串
160
+ if (cleanOutput.trim().length === 0) {
161
+ return '';
162
+ }
163
+ console.log(`🧹 [Shell] 清理命令输出:`);
164
+ console.log(` 原始: "${output.trim()}"`);
165
+ console.log(` 清理后: "${cleanOutput.trim()}"`);
166
+ return cleanOutput;
167
+ }
102
168
  /**
103
169
  * 合并多个 session 的输出
104
170
  */
@@ -112,20 +178,10 @@ class ShellX {
112
178
  return combined;
113
179
  }
114
180
  /**
115
- * 检查输出是否包含提示符
181
+ * 转义正则表达式特殊字符
116
182
  */
117
- containsPrompt(output) {
118
- const promptPatterns = [
119
- /\$ $/,
120
- /# $/,
121
- /> $/,
122
- /\w+@\w+.*\$ $/,
123
- /shell@.*:.*\$ $/,
124
- /houji:\/.*\$ $/,
125
- /\d+\|\w+:\/.*\$ $/, // Android pattern like "127|bluejay:/ $"
126
- /\w+:\/.*\$ $/ // Android pattern like "bluejay:/ $"
127
- ];
128
- return promptPatterns.some(pattern => pattern.test(output));
183
+ escapeRegExp(string) {
184
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
129
185
  }
130
186
  /**
131
187
  * 检查命令是否完成
@@ -133,41 +189,6 @@ class ShellX {
133
189
  checkCommandCompletion(commandKey, commandPromise, newOutput) {
134
190
  const { resolve, startTime, options, output, command } = commandPromise;
135
191
  console.log(`🔍 [Shell] 检查命令 "${command}" 完成条件,当前输出长度: ${output.length}`);
136
- // 检查成功模式
137
- if (options.successPattern) {
138
- const pattern = options.successPattern;
139
- const isMatch = typeof pattern === 'string'
140
- ? output.includes(pattern)
141
- : pattern.test(output);
142
- if (isMatch) {
143
- console.log(`✅ [Shell] 命令 "${command}" 成功完成 (匹配成功模式)`);
144
- this.resolveCommand(commandKey, {
145
- success: true,
146
- output: output.trim(),
147
- duration: Date.now() - startTime
148
- });
149
- return;
150
- }
151
- }
152
- // 检查错误模式
153
- if (options.errorPattern) {
154
- const pattern = options.errorPattern;
155
- const isMatch = typeof pattern === 'string'
156
- ? output.includes(pattern)
157
- : pattern.test(output);
158
- if (isMatch) {
159
- console.log(`❌ [Shell] 命令 "${command}" 执行失败 (匹配错误模式)`);
160
- this.resolveCommand(commandKey, {
161
- success: false,
162
- output: output.trim(),
163
- error: 'Command failed with error pattern',
164
- duration: Date.now() - startTime
165
- });
166
- return;
167
- }
168
- }
169
- // 检查通用完成模式(如命令提示符)
170
- // 这是最主要的完成检测逻辑,包括对没有输出的命令的支持
171
192
  if (this.isCommandComplete(output, command)) {
172
193
  console.log(`✅ [Shell] 命令 "${command}" 执行完成 (检测到提示符)`);
173
194
  this.resolveCommand(commandKey, {
@@ -177,26 +198,6 @@ class ShellX {
177
198
  });
178
199
  return;
179
200
  }
180
- // 额外的完成检测:仅当有输出时才进行的检查
181
- if (output.trim().length > 0) {
182
- // 检查是否有错误指示器
183
- if (this.hasErrorIndicators(output)) {
184
- console.log(`❌ [Shell] 命令 "${command}" 可能执行失败 (检测到错误指示器)`);
185
- // 不立即失败,继续等待完整的提示符
186
- return;
187
- }
188
- // 检查是否包含命令和结果(备用检测方式)
189
- if (output.includes(command) && this.containsPrompt(output)) {
190
- console.log(`✅ [Shell] 命令 "${command}" 执行完成 (命令+提示符备用检测)`);
191
- this.resolveCommand(commandKey, {
192
- success: true,
193
- output: output.trim(),
194
- duration: Date.now() - startTime
195
- });
196
- return;
197
- }
198
- }
199
- // 如果没有检测到完成条件,继续等待
200
201
  console.log(`⏳ [Shell] 命令 "${command}" 继续等待完成...`);
201
202
  }
202
203
  /**
@@ -215,50 +216,12 @@ class ShellX {
215
216
  return errorPatterns.some(pattern => pattern.test(output));
216
217
  }
217
218
  /**
218
- * 判断命令是否完成(基于常见的提示符模式)
219
+ * 判断命令是否完成(基于时间)
219
220
  */
220
221
  isCommandComplete(output, command) {
221
- // 常见的命令提示符模式
222
- const promptPatterns = [
223
- /\$ $/, // Unix shell prompt
224
- /# $/, // Root shell prompt
225
- /> $/, // Windows command prompt
226
- /~\$ $/, // Home directory prompt
227
- /\w+@\w+.*\$ $/, // User@host prompt
228
- /shell@.*:.*\$ $/, // Android shell prompt
229
- /houji:\/.*\$ $/, // Specific Android shell prompt
230
- /\d+\|\w+:\/.*\$ $/, // Android pattern like "127|bluejay:/ $"
231
- /\w+:\/.*\$ $/, // Android pattern like "bluejay:/ $"
232
- /\[.*\]\$ $/, // Bracketed prompt
233
- /\w+:\w+\$ $/, // Simple path prompt
234
- /\w+> $/, // Simple greater-than prompt
235
- /.*:\w+\$ $/, // Path-based prompt
236
- /\w+@\w+:.* $/, // User@host with path
237
- /\d+\|.*\$ $/, // Numbered prompt with pipe
238
- /.*#\s*$/, // Hash prompt with optional space
239
- /.*\$\s*$/ // Dollar prompt with optional space
240
- ];
241
- // 分割输出为行,检查最后几行
242
- const lines = output.split(/\r?\n/).filter(line => line.trim().length > 0);
243
- const lastLine = lines[lines.length - 1] || '';
244
- // 清理最后一行的控制字符
245
- const cleanLastLine = lastLine.replace(/\r/g, '').trim();
246
- console.log(`🔍 [Shell] 检查命令 "${command}" 最后一行提示符: "${cleanLastLine}"`);
247
- const hasPrompt = promptPatterns.some(pattern => {
248
- const matches = pattern.test(cleanLastLine);
249
- if (matches) {
250
- console.log(`✅ [Shell] 命令 "${command}" 匹配到提示符模式: ${pattern}`);
251
- }
252
- return matches;
253
- });
254
- // 如果检测到提示符,则认为命令完成
255
- // 不再要求输出必须包含命令本身,因为有些命令可能没有输出
256
- if (hasPrompt) {
257
- return true;
258
- }
259
- // 如果没有检测到提示符,但输出包含命令本身,可能命令还在执行中
260
- // 这种情况下返回false,继续等待
261
- return false;
222
+ // 简化逻辑:只基于时间判断,不依赖提示符检测
223
+ // 命令完成由超时机制控制
224
+ return false; // 让超时机制处理命令完成
262
225
  }
263
226
  /**
264
227
  * 解析命令 Promise
@@ -267,7 +230,9 @@ class ShellX {
267
230
  const commandPromise = this.shellCommandPromises.get(commandKey);
268
231
  if (commandPromise) {
269
232
  console.log(`✅ [Shell] 解析命令 Promise: ${commandKey}`);
270
- commandPromise.resolve(result);
233
+ // 清理最终输出结果
234
+ const cleanResult = Object.assign(Object.assign({}, result), { output: this.cleanCommandOutput(result.output, commandPromise.command) });
235
+ commandPromise.resolve(cleanResult);
271
236
  this.shellCommandPromises.delete(commandKey);
272
237
  }
273
238
  else {
@@ -610,7 +575,7 @@ class ShellX {
610
575
  console.log(`🔨 [Shell] ${title}`);
611
576
  console.log(`⏱️ 超时时间: ${timeout}ms`);
612
577
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
613
- const commandKey = this.generateCommandKey(command);
578
+ const commandKey = (0, uuid_1.v4)();
614
579
  console.log(`🔑 [Shell] 生成命令键: ${commandKey}`);
615
580
  // 注册命令 Promise
616
581
  this.shellCommandPromises.set(commandKey, {
@@ -627,21 +592,21 @@ class ShellX {
627
592
  const timeoutId = setTimeout(() => {
628
593
  if (this.shellCommandPromises.has(commandKey)) {
629
594
  const commandPromise = this.shellCommandPromises.get(commandKey);
630
- console.log(`⏰ [Shell] 命令超时: ${command}`);
631
- // 即使超时,如果有输出也返回输出
595
+ this.shellCommandPromises.delete(commandKey);
632
596
  if (commandPromise && commandPromise.output.trim().length > 0) {
633
- console.log(`📤 [Shell] 超时但有输出,返回部分结果`);
634
- this.shellCommandPromises.delete(commandKey);
635
597
  resolve({
636
- success: false,
598
+ success: true,
637
599
  output: commandPromise.output.trim(),
638
- error: `Command timeout after ${timeout}ms, but got partial output`,
639
600
  duration: Date.now() - startTime
640
601
  });
641
602
  }
642
603
  else {
643
- this.shellCommandPromises.delete(commandKey);
644
- reject(new Error(`Command timeout after ${timeout}ms`));
604
+ resolve({
605
+ success: true,
606
+ output: "",
607
+ error: `Command timeout after ${timeout}ms, but got partial output`,
608
+ duration: Date.now() - startTime
609
+ });
645
610
  }
646
611
  }
647
612
  }, timeout);
@@ -659,10 +624,8 @@ class ShellX {
659
624
  }
660
625
  };
661
626
  // 发送命令
662
- yield this.client.executeAction(shellAction);
663
- console.log(`📤 [Shell] 命令已发送: ${command}`);
664
- // 等待命令完成(通过 chunks 数据流)
665
- // Promise 将由 handleShellOutput 解析
627
+ yield this.client.executeAction(shellAction, commandKey);
628
+ console.log(`📤 [Shell] 命令已发送: ${commandKey}`);
666
629
  }
667
630
  catch (error) {
668
631
  clearTimeout(timeoutId);
@@ -754,7 +717,6 @@ class ShellX {
754
717
  onError: options === null || options === void 0 ? void 0 : options.onError,
755
718
  expectedOutput: options === null || options === void 0 ? void 0 : options.expectedOutput,
756
719
  successPattern: options === null || options === void 0 ? void 0 : options.successPattern,
757
- errorPattern: options === null || options === void 0 ? void 0 : options.errorPattern
758
720
  });
759
721
  });
760
722
  }
@@ -793,6 +755,74 @@ exports.AutomationHelpers = ShellX;
793
755
  function createShellX(client) {
794
756
  return new ShellX(client);
795
757
  }
758
+ /**
759
+ * 获取ofetch实例
760
+ */
761
+ function getfetch() {
762
+ return __awaiter(this, void 0, void 0, function* () {
763
+ try {
764
+ // @ts-ignore - Dynamic import may not have types
765
+ const { ofetch } = yield Promise.resolve().then(() => __importStar(require('ofetch')));
766
+ // 创建配置好的ofetch实例
767
+ const fetchInstance = ofetch.create({
768
+ timeout: 10000,
769
+ retry: 1,
770
+ retryDelay: 1000,
771
+ headers: {
772
+ 'User-Agent': 'ShellX/1.0.1'
773
+ },
774
+ onRequest({ request, options }) {
775
+ console.log(`🌐 [Fetch] 请求: ${options.method || 'GET'} ${request}`);
776
+ },
777
+ onResponse({ response }) {
778
+ console.log(`📡 [Fetch] 响应: ${response.status} ${response.statusText}`);
779
+ },
780
+ onRequestError({ error }) {
781
+ console.error('❌ [Fetch] 请求错误:', error.message);
782
+ },
783
+ onResponseError({ response }) {
784
+ console.error(`❌ [Fetch] 响应错误: ${response.status} ${response.statusText}`);
785
+ }
786
+ });
787
+ return fetchInstance;
788
+ }
789
+ catch (error) {
790
+ console.warn('⚠️ [Auth] ofetch不可用,使用降级方案');
791
+ return createFallbackFetch();
792
+ }
793
+ });
794
+ }
795
+ /**
796
+ * 降级fetch实现
797
+ */
798
+ function createFallbackFetch() {
799
+ return (url, options) => __awaiter(this, void 0, void 0, function* () {
800
+ // 尝试使用全局fetch
801
+ if (typeof globalThis.fetch !== 'undefined') {
802
+ console.log(`🌐 [Fetch] 请求: ${(options === null || options === void 0 ? void 0 : options.method) || 'GET'} ${url}`);
803
+ const response = yield globalThis.fetch(url, options);
804
+ console.log(`📡 [Fetch] 响应: ${response.status} ${response.statusText}`);
805
+ if (!response.ok) {
806
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
807
+ }
808
+ return response.json();
809
+ }
810
+ // Node.js环境降级
811
+ try {
812
+ const { default: fetch } = yield Promise.resolve().then(() => __importStar(require('node-fetch')));
813
+ console.log(`🌐 [Fetch] 请求: ${(options === null || options === void 0 ? void 0 : options.method) || 'GET'} ${url}`);
814
+ const response = yield fetch(url, options);
815
+ console.log(`📡 [Fetch] 响应: ${response.status} ${response.statusText}`);
816
+ if (!response.ok) {
817
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
818
+ }
819
+ return response.json();
820
+ }
821
+ catch (fetchError) {
822
+ throw new Error(`Fetch not available: ${fetchError.message}`);
823
+ }
824
+ });
825
+ }
796
826
  /**
797
827
  * 从ShellX.ai服务认证并获取WebSocket连接信息
798
828
  */
@@ -804,45 +834,45 @@ function authenticateDevice() {
804
834
  }
805
835
  try {
806
836
  console.log('🔑 [Auth] 正在认证设备...');
807
- const response = yield fetch(`https://shellx.ai/api/device/${authKey}`, {
837
+ // 获取ofetch实例
838
+ const fetchFn = yield getfetch();
839
+ // ofetch自动处理JSON解析和错误处理
840
+ const data = yield fetchFn(`https://shellx.ai/api/device/${authKey}`, {
808
841
  method: 'GET',
809
842
  headers: {
810
843
  'Content-Type': 'application/json',
811
844
  }
812
845
  });
813
- if (!response.ok) {
814
- throw new Error(`Authentication failed: ${response.status} ${response.statusText}`);
815
- }
816
- const data = yield response.json();
817
- if (data.status !== 'success') {
818
- throw new Error(`Authentication failed: ${data.message}`);
819
- }
820
- console.log('✅ [Auth] 设备认证成功');
821
- console.log(`📡 [Auth] 连接信息: ${data.machine}`);
822
- return data.machine;
846
+ const jsonData = JSON.parse(data);
847
+ console.log('✅ [Auth] ShellX.ai设备认证成功');
848
+ console.log(`📡 [Auth] 设备ID: ${jsonData.authenticate}`);
849
+ console.log(`📡 [Auth] ShellX.ai服务地址: ${jsonData.machine}`);
850
+ console.log(`📡 [Auth] 注册时间: ${jsonData.registered_at}`);
851
+ console.log(`📡 [Auth] 最后更新: ${jsonData.last_updated}`);
852
+ return jsonData.machine;
823
853
  }
824
854
  catch (error) {
825
855
  const errorMessage = error instanceof Error ? error.message : String(error);
826
- console.warn('⚠️ [Auth] 在线认证失败,使用本地默认连接:', errorMessage);
827
- // 认证失败时使用默认的本地WebSocket URL
856
+ console.warn('⚠️ [Auth] ShellX.ai在线认证失败,使用本地服务:', errorMessage);
857
+ // 认证失败时使用默认的本地ShellX服务
828
858
  const fallbackUrl = `ws://127.0.0.1:9091/api/s/${authKey}`;
829
- console.log(`🔄 [Auth] 使用默认连接: ${fallbackUrl}`);
859
+ console.log(`🔄 [Auth] 使用本地ShellX服务: ${fallbackUrl}`);
830
860
  return fallbackUrl;
831
861
  }
832
862
  });
833
863
  }
834
864
  /**
835
865
  * Create ShellX instance with automatic authentication and shell output monitoring
836
- * 自动处理认证和连接,无需外部提供WebSocket URL
866
+ * 自动处理ShellX.ai认证和连接,无需外部提供连接地址
837
867
  */
838
868
  function createShellXWithShellMonitoring() {
839
869
  return __awaiter(this, arguments, void 0, function* (config = {}) {
840
870
  try {
841
- // 认证并获取WebSocket URL
871
+ // 认证并获取ShellX.ai服务地址
842
872
  const wsUrl = yield authenticateDevice();
843
873
  // 先创建 shellx 实例,但不绑定客户端
844
874
  const shellx = new ShellX(null);
845
- // 创建客户端时设置消息监听器
875
+ // 创建ShellX客户端并设置消息监听器
846
876
  const client = new index_1.default(wsUrl, Object.assign(Object.assign({}, config), { onMessage: (message) => {
847
877
  // 处理 chunks 数据(pty 终端输出)
848
878
  if (message.chunks) {
@@ -852,10 +882,20 @@ function createShellXWithShellMonitoring() {
852
882
  if (config.onMessage) {
853
883
  config.onMessage(message);
854
884
  }
885
+ }, onOpen: () => {
886
+ // 调用原始的onOpen处理器
887
+ if (config.onOpen) {
888
+ config.onOpen();
889
+ }
855
890
  } }));
891
+ // 等待ShellX.ai服务连接完成
892
+ console.log('⏳ [ShellX] 等待ShellX.ai服务连接...');
893
+ yield client.waitForInitialization();
856
894
  // 绑定客户端到 shellx
857
895
  shellx.client = client;
858
- console.log('🚀 [ShellX] 初始化完成,可以开始使用自动化功能');
896
+ // shellx 实例关联到客户端
897
+ client.setShellX(shellx);
898
+ console.log('🚀 [ShellX] 初始化完成,等待ShellX.ai服务响应...');
859
899
  return { client, shellx };
860
900
  }
861
901
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellx-ai",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "shellx is a powerful WebSocket-based client for controlling shell commands and UI automation on remote devices.",
5
5
  "repository": {
6
6
  "url": "git+https://github.com/10cl/shellx.git",
@@ -23,7 +23,15 @@
23
23
  "test:shellx-ai": "ts-node -r dotenv/config examples/shellx.ai/index.ts",
24
24
  "test:shell-commands": "ts-node -r dotenv/config examples/shell-commands-demo.ts",
25
25
  "test:no-output": "ts-node -r dotenv/config examples/no-output-command-test.ts",
26
- "test:find-elements": "ts-node -r dotenv/config examples/find-elements-demo.ts"
26
+ "test:find-elements": "ts-node -r dotenv/config examples/find-elements-demo.ts",
27
+ "test:api": "ts-node test-shellx.ts",
28
+ "test:auth": "ts-node test-auth.ts",
29
+ "test:ofetch": "ts-node test-ofetch.ts",
30
+ "test:paytm-connection": "ts-node -r dotenv/config test-paytm-connection.ts",
31
+ "test:prompt-detection": "ts-node -r dotenv/config test-shell-prompt-integration.ts",
32
+ "test:simplified": "ts-node -r dotenv/config test-simplified-shell.ts",
33
+ "install-deps": "node install-deps.js",
34
+ "postinstall": "node install-deps.js"
27
35
  },
28
36
  "keywords": [
29
37
  "websocket",
@@ -42,6 +50,10 @@
42
50
  "dotenv": "^16.4.5",
43
51
  "uuid": "^11.1.0"
44
52
  },
53
+ "optionalDependencies": {
54
+ "node-fetch": "^3.3.2",
55
+ "ws": "^8.14.2"
56
+ },
45
57
  "devDependencies": {
46
58
  "@types/jest": "^30.0.0",
47
59
  "@types/node": "^24.0.13",