shellx-ai 1.0.1 → 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
@@ -51,6 +51,7 @@ exports.createHelpers = createShellX;
51
51
  exports.createShellXWithShellMonitoring = createShellXWithShellMonitoring;
52
52
  exports.createHelpersWithShellMonitoring = createShellXWithShellMonitoring;
53
53
  const index_1 = __importDefault(require("./index"));
54
+ const uuid_1 = require("uuid");
54
55
  /**
55
56
  * ShellX automation utilities for common patterns
56
57
  */
@@ -78,7 +79,7 @@ class ShellX {
78
79
  * 处理 shell 输出数据
79
80
  */
80
81
  handleShellOutput(chunks) {
81
- const [sid, sessionId, dataArrays] = chunks;
82
+ const [sessionId, len, dataArrays] = chunks;
82
83
  try {
83
84
  // 将 Uint8Array 数组转换为字符串
84
85
  let output = '';
@@ -99,9 +100,10 @@ class ShellX {
99
100
  // 更新总输出
100
101
  commandPromise.output = this.combineSessionOutputs(commandPromise.sessionOutputs);
101
102
  console.log(`📊 [Shell] 命令 ${commandKey} 累积输出长度: ${commandPromise.output.length}`);
102
- // 调用输出回调
103
+ // 调用输出回调(传递清理后的输出)
103
104
  if (commandPromise.options.onOutput) {
104
- commandPromise.options.onOutput(output);
105
+ const cleanOutput = this.cleanCommandOutput(output, commandPromise.command);
106
+ commandPromise.options.onOutput(cleanOutput);
105
107
  }
106
108
  // 检查是否满足完成条件
107
109
  this.checkCommandCompletion(commandKey, commandPromise, output);
@@ -120,10 +122,6 @@ class ShellX {
120
122
  if (output.includes(command)) {
121
123
  return true;
122
124
  }
123
- // 如果输出包含提示符,说明是命令完成
124
- if (this.containsPrompt(output)) {
125
- return true;
126
- }
127
125
  // 如果有多个命令在等待,按时间顺序分配
128
126
  const waitingCommands = Array.from(this.shellCommandPromises.keys());
129
127
  if (waitingCommands.length === 1) {
@@ -132,6 +130,41 @@ class ShellX {
132
130
  // 多个命令时,根据 sessionId 和命令创建时间进行启发式匹配
133
131
  return true; // 暂时返回 true,让所有命令都接收输出
134
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
+ }
135
168
  /**
136
169
  * 合并多个 session 的输出
137
170
  */
@@ -145,20 +178,10 @@ class ShellX {
145
178
  return combined;
146
179
  }
147
180
  /**
148
- * 检查输出是否包含提示符
181
+ * 转义正则表达式特殊字符
149
182
  */
150
- containsPrompt(output) {
151
- const promptPatterns = [
152
- /\$ $/,
153
- /# $/,
154
- /> $/,
155
- /\w+@\w+.*\$ $/,
156
- /shell@.*:.*\$ $/,
157
- /houji:\/.*\$ $/,
158
- /\d+\|\w+:\/.*\$ $/, // Android pattern like "127|bluejay:/ $"
159
- /\w+:\/.*\$ $/ // Android pattern like "bluejay:/ $"
160
- ];
161
- return promptPatterns.some(pattern => pattern.test(output));
183
+ escapeRegExp(string) {
184
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
162
185
  }
163
186
  /**
164
187
  * 检查命令是否完成
@@ -166,41 +189,6 @@ class ShellX {
166
189
  checkCommandCompletion(commandKey, commandPromise, newOutput) {
167
190
  const { resolve, startTime, options, output, command } = commandPromise;
168
191
  console.log(`🔍 [Shell] 检查命令 "${command}" 完成条件,当前输出长度: ${output.length}`);
169
- // 检查成功模式
170
- if (options.successPattern) {
171
- const pattern = options.successPattern;
172
- const isMatch = typeof pattern === 'string'
173
- ? output.includes(pattern)
174
- : pattern.test(output);
175
- if (isMatch) {
176
- console.log(`✅ [Shell] 命令 "${command}" 成功完成 (匹配成功模式)`);
177
- this.resolveCommand(commandKey, {
178
- success: true,
179
- output: output.trim(),
180
- duration: Date.now() - startTime
181
- });
182
- return;
183
- }
184
- }
185
- // 检查错误模式
186
- if (options.errorPattern) {
187
- const pattern = options.errorPattern;
188
- const isMatch = typeof pattern === 'string'
189
- ? output.includes(pattern)
190
- : pattern.test(output);
191
- if (isMatch) {
192
- console.log(`❌ [Shell] 命令 "${command}" 执行失败 (匹配错误模式)`);
193
- this.resolveCommand(commandKey, {
194
- success: false,
195
- output: output.trim(),
196
- error: 'Command failed with error pattern',
197
- duration: Date.now() - startTime
198
- });
199
- return;
200
- }
201
- }
202
- // 检查通用完成模式(如命令提示符)
203
- // 这是最主要的完成检测逻辑,包括对没有输出的命令的支持
204
192
  if (this.isCommandComplete(output, command)) {
205
193
  console.log(`✅ [Shell] 命令 "${command}" 执行完成 (检测到提示符)`);
206
194
  this.resolveCommand(commandKey, {
@@ -210,26 +198,6 @@ class ShellX {
210
198
  });
211
199
  return;
212
200
  }
213
- // 额外的完成检测:仅当有输出时才进行的检查
214
- if (output.trim().length > 0) {
215
- // 检查是否有错误指示器
216
- if (this.hasErrorIndicators(output)) {
217
- console.log(`❌ [Shell] 命令 "${command}" 可能执行失败 (检测到错误指示器)`);
218
- // 不立即失败,继续等待完整的提示符
219
- return;
220
- }
221
- // 检查是否包含命令和结果(备用检测方式)
222
- if (output.includes(command) && this.containsPrompt(output)) {
223
- console.log(`✅ [Shell] 命令 "${command}" 执行完成 (命令+提示符备用检测)`);
224
- this.resolveCommand(commandKey, {
225
- success: true,
226
- output: output.trim(),
227
- duration: Date.now() - startTime
228
- });
229
- return;
230
- }
231
- }
232
- // 如果没有检测到完成条件,继续等待
233
201
  console.log(`⏳ [Shell] 命令 "${command}" 继续等待完成...`);
234
202
  }
235
203
  /**
@@ -248,50 +216,12 @@ class ShellX {
248
216
  return errorPatterns.some(pattern => pattern.test(output));
249
217
  }
250
218
  /**
251
- * 判断命令是否完成(基于常见的提示符模式)
219
+ * 判断命令是否完成(基于时间)
252
220
  */
253
221
  isCommandComplete(output, command) {
254
- // 常见的命令提示符模式
255
- const promptPatterns = [
256
- /\$ $/, // Unix shell prompt
257
- /# $/, // Root shell prompt
258
- /> $/, // Windows command prompt
259
- /~\$ $/, // Home directory prompt
260
- /\w+@\w+.*\$ $/, // User@host prompt
261
- /shell@.*:.*\$ $/, // Android shell prompt
262
- /houji:\/.*\$ $/, // Specific Android shell prompt
263
- /\d+\|\w+:\/.*\$ $/, // Android pattern like "127|bluejay:/ $"
264
- /\w+:\/.*\$ $/, // Android pattern like "bluejay:/ $"
265
- /\[.*\]\$ $/, // Bracketed prompt
266
- /\w+:\w+\$ $/, // Simple path prompt
267
- /\w+> $/, // Simple greater-than prompt
268
- /.*:\w+\$ $/, // Path-based prompt
269
- /\w+@\w+:.* $/, // User@host with path
270
- /\d+\|.*\$ $/, // Numbered prompt with pipe
271
- /.*#\s*$/, // Hash prompt with optional space
272
- /.*\$\s*$/ // Dollar prompt with optional space
273
- ];
274
- // 分割输出为行,检查最后几行
275
- const lines = output.split(/\r?\n/).filter(line => line.trim().length > 0);
276
- const lastLine = lines[lines.length - 1] || '';
277
- // 清理最后一行的控制字符
278
- const cleanLastLine = lastLine.replace(/\r/g, '').trim();
279
- console.log(`🔍 [Shell] 检查命令 "${command}" 最后一行提示符: "${cleanLastLine}"`);
280
- const hasPrompt = promptPatterns.some(pattern => {
281
- const matches = pattern.test(cleanLastLine);
282
- if (matches) {
283
- console.log(`✅ [Shell] 命令 "${command}" 匹配到提示符模式: ${pattern}`);
284
- }
285
- return matches;
286
- });
287
- // 如果检测到提示符,则认为命令完成
288
- // 不再要求输出必须包含命令本身,因为有些命令可能没有输出
289
- if (hasPrompt) {
290
- return true;
291
- }
292
- // 如果没有检测到提示符,但输出包含命令本身,可能命令还在执行中
293
- // 这种情况下返回false,继续等待
294
- return false;
222
+ // 简化逻辑:只基于时间判断,不依赖提示符检测
223
+ // 命令完成由超时机制控制
224
+ return false; // 让超时机制处理命令完成
295
225
  }
296
226
  /**
297
227
  * 解析命令 Promise
@@ -300,7 +230,9 @@ class ShellX {
300
230
  const commandPromise = this.shellCommandPromises.get(commandKey);
301
231
  if (commandPromise) {
302
232
  console.log(`✅ [Shell] 解析命令 Promise: ${commandKey}`);
303
- commandPromise.resolve(result);
233
+ // 清理最终输出结果
234
+ const cleanResult = Object.assign(Object.assign({}, result), { output: this.cleanCommandOutput(result.output, commandPromise.command) });
235
+ commandPromise.resolve(cleanResult);
304
236
  this.shellCommandPromises.delete(commandKey);
305
237
  }
306
238
  else {
@@ -643,7 +575,7 @@ class ShellX {
643
575
  console.log(`🔨 [Shell] ${title}`);
644
576
  console.log(`⏱️ 超时时间: ${timeout}ms`);
645
577
  return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
646
- const commandKey = this.generateCommandKey(command);
578
+ const commandKey = (0, uuid_1.v4)();
647
579
  console.log(`🔑 [Shell] 生成命令键: ${commandKey}`);
648
580
  // 注册命令 Promise
649
581
  this.shellCommandPromises.set(commandKey, {
@@ -660,21 +592,21 @@ class ShellX {
660
592
  const timeoutId = setTimeout(() => {
661
593
  if (this.shellCommandPromises.has(commandKey)) {
662
594
  const commandPromise = this.shellCommandPromises.get(commandKey);
663
- console.log(`⏰ [Shell] 命令超时: ${command}`);
664
- // 即使超时,如果有输出也返回输出
595
+ this.shellCommandPromises.delete(commandKey);
665
596
  if (commandPromise && commandPromise.output.trim().length > 0) {
666
- console.log(`📤 [Shell] 超时但有输出,返回部分结果`);
667
- this.shellCommandPromises.delete(commandKey);
668
597
  resolve({
669
- success: false,
598
+ success: true,
670
599
  output: commandPromise.output.trim(),
671
- error: `Command timeout after ${timeout}ms, but got partial output`,
672
600
  duration: Date.now() - startTime
673
601
  });
674
602
  }
675
603
  else {
676
- this.shellCommandPromises.delete(commandKey);
677
- 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
+ });
678
610
  }
679
611
  }
680
612
  }, timeout);
@@ -692,10 +624,8 @@ class ShellX {
692
624
  }
693
625
  };
694
626
  // 发送命令
695
- yield this.client.executeAction(shellAction);
696
- console.log(`📤 [Shell] 命令已发送: ${command}`);
697
- // 等待命令完成(通过 chunks 数据流)
698
- // Promise 将由 handleShellOutput 解析
627
+ yield this.client.executeAction(shellAction, commandKey);
628
+ console.log(`📤 [Shell] 命令已发送: ${commandKey}`);
699
629
  }
700
630
  catch (error) {
701
631
  clearTimeout(timeoutId);
@@ -787,7 +717,6 @@ class ShellX {
787
717
  onError: options === null || options === void 0 ? void 0 : options.onError,
788
718
  expectedOutput: options === null || options === void 0 ? void 0 : options.expectedOutput,
789
719
  successPattern: options === null || options === void 0 ? void 0 : options.successPattern,
790
- errorPattern: options === null || options === void 0 ? void 0 : options.errorPattern
791
720
  });
792
721
  });
793
722
  }
@@ -827,62 +756,71 @@ function createShellX(client) {
827
756
  return new ShellX(client);
828
757
  }
829
758
  /**
830
- * 获取适合当前环境的fetch函数
759
+ * 获取ofetch实例
831
760
  */
832
- function getFetch() {
761
+ function getfetch() {
833
762
  return __awaiter(this, void 0, void 0, function* () {
834
- // 检查是否已有全局fetch(Node.js 18+或浏览器环境)
835
- if (typeof globalThis.fetch !== 'undefined') {
836
- return globalThis.fetch;
837
- }
838
- // Node.js环境下动态导入node-fetch
839
763
  try {
840
- const { default: fetch } = yield Promise.resolve().then(() => __importStar(require('node-fetch')));
841
- return fetch;
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;
842
788
  }
843
789
  catch (error) {
844
- // 如果node-fetch不可用,尝试使用内置的https模块
845
- console.warn('⚠️ [Auth] node-fetch不可用,使用内置https模块');
846
- return createNodeFetch();
790
+ console.warn('⚠️ [Auth] ofetch不可用,使用降级方案');
791
+ return createFallbackFetch();
847
792
  }
848
793
  });
849
794
  }
850
795
  /**
851
- * 使用Node.js内置模块创建fetch替代函数
796
+ * 降级fetch实现
852
797
  */
853
- function createNodeFetch() {
798
+ function createFallbackFetch() {
854
799
  return (url, options) => __awaiter(this, void 0, void 0, function* () {
855
- const https = yield Promise.resolve().then(() => __importStar(require('https')));
856
- const { URL } = yield Promise.resolve().then(() => __importStar(require('url')));
857
- return new Promise((resolve, reject) => {
858
- const parsedUrl = new URL(url);
859
- const requestOptions = {
860
- hostname: parsedUrl.hostname,
861
- port: parsedUrl.port || 443,
862
- path: parsedUrl.pathname + parsedUrl.search,
863
- method: (options === null || options === void 0 ? void 0 : options.method) || 'GET',
864
- headers: (options === null || options === void 0 ? void 0 : options.headers) || {}
865
- };
866
- const req = https.request(requestOptions, (res) => {
867
- let data = '';
868
- res.on('data', (chunk) => data += chunk);
869
- res.on('end', () => {
870
- const response = {
871
- ok: res.statusCode ? res.statusCode >= 200 && res.statusCode < 300 : false,
872
- status: res.statusCode || 0,
873
- statusText: res.statusMessage || '',
874
- json: () => __awaiter(this, void 0, void 0, function* () { return JSON.parse(data); }),
875
- text: () => __awaiter(this, void 0, void 0, function* () { return data; })
876
- };
877
- resolve(response);
878
- });
879
- });
880
- req.on('error', reject);
881
- if (options === null || options === void 0 ? void 0 : options.body) {
882
- req.write(options.body);
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}`);
883
807
  }
884
- req.end();
885
- });
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
+ }
886
824
  });
887
825
  }
888
826
  /**
@@ -896,47 +834,45 @@ function authenticateDevice() {
896
834
  }
897
835
  try {
898
836
  console.log('🔑 [Auth] 正在认证设备...');
899
- // 获取适合当前环境的fetch函数
900
- const fetchFn = yield getFetch();
901
- const response = yield fetchFn(`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}`, {
902
841
  method: 'GET',
903
842
  headers: {
904
843
  'Content-Type': 'application/json',
905
844
  }
906
845
  });
907
- if (!response.ok) {
908
- throw new Error(`Authentication failed: ${response.status} ${response.statusText}`);
909
- }
910
- const data = yield response.json();
911
- if (data.status !== 'success') {
912
- throw new Error(`Authentication failed: ${data.message}`);
913
- }
914
- console.log('✅ [Auth] 设备认证成功');
915
- console.log(`📡 [Auth] 连接信息: ${data.machine}`);
916
- 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;
917
853
  }
918
854
  catch (error) {
919
855
  const errorMessage = error instanceof Error ? error.message : String(error);
920
- console.warn('⚠️ [Auth] 在线认证失败,使用本地默认连接:', errorMessage);
921
- // 认证失败时使用默认的本地WebSocket URL
856
+ console.warn('⚠️ [Auth] ShellX.ai在线认证失败,使用本地服务:', errorMessage);
857
+ // 认证失败时使用默认的本地ShellX服务
922
858
  const fallbackUrl = `ws://127.0.0.1:9091/api/s/${authKey}`;
923
- console.log(`🔄 [Auth] 使用默认连接: ${fallbackUrl}`);
859
+ console.log(`🔄 [Auth] 使用本地ShellX服务: ${fallbackUrl}`);
924
860
  return fallbackUrl;
925
861
  }
926
862
  });
927
863
  }
928
864
  /**
929
865
  * Create ShellX instance with automatic authentication and shell output monitoring
930
- * 自动处理认证和连接,无需外部提供WebSocket URL
866
+ * 自动处理ShellX.ai认证和连接,无需外部提供连接地址
931
867
  */
932
868
  function createShellXWithShellMonitoring() {
933
869
  return __awaiter(this, arguments, void 0, function* (config = {}) {
934
870
  try {
935
- // 认证并获取WebSocket URL
871
+ // 认证并获取ShellX.ai服务地址
936
872
  const wsUrl = yield authenticateDevice();
937
873
  // 先创建 shellx 实例,但不绑定客户端
938
874
  const shellx = new ShellX(null);
939
- // 创建客户端时设置消息监听器
875
+ // 创建ShellX客户端并设置消息监听器
940
876
  const client = new index_1.default(wsUrl, Object.assign(Object.assign({}, config), { onMessage: (message) => {
941
877
  // 处理 chunks 数据(pty 终端输出)
942
878
  if (message.chunks) {
@@ -946,10 +882,20 @@ function createShellXWithShellMonitoring() {
946
882
  if (config.onMessage) {
947
883
  config.onMessage(message);
948
884
  }
885
+ }, onOpen: () => {
886
+ // 调用原始的onOpen处理器
887
+ if (config.onOpen) {
888
+ config.onOpen();
889
+ }
949
890
  } }));
891
+ // 等待ShellX.ai服务连接完成
892
+ console.log('⏳ [ShellX] 等待ShellX.ai服务连接...');
893
+ yield client.waitForInitialization();
950
894
  // 绑定客户端到 shellx
951
895
  shellx.client = client;
952
- console.log('🚀 [ShellX] 初始化完成,可以开始使用自动化功能');
896
+ // shellx 实例关联到客户端
897
+ client.setShellX(shellx);
898
+ console.log('🚀 [ShellX] 初始化完成,等待ShellX.ai服务响应...');
953
899
  return { client, shellx };
954
900
  }
955
901
  catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shellx-ai",
3
- "version": "1.0.1",
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",
@@ -24,7 +24,14 @@
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
26
  "test:find-elements": "ts-node -r dotenv/config examples/find-elements-demo.ts",
27
- "test:api": "ts-node test-shellx.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"
28
35
  },
29
36
  "keywords": [
30
37
  "websocket",
@@ -44,7 +51,8 @@
44
51
  "uuid": "^11.1.0"
45
52
  },
46
53
  "optionalDependencies": {
47
- "node-fetch": "^3.3.2"
54
+ "node-fetch": "^3.3.2",
55
+ "ws": "^8.14.2"
48
56
  },
49
57
  "devDependencies": {
50
58
  "@types/jest": "^30.0.0",