@termly-dev/cli-dev
Advanced tools
@@ -23,4 +23,9 @@ const { getAllTools, getToolVersion } = require('./registry'); | ||
| // On Windows, checkInstalled may return full path instead of true | ||
| // Use this full path as command if available (for .cmd/.bat files) | ||
| const toolCommand = (typeof isInstalled === 'string') ? isInstalled : tool.command; | ||
| installedTools.push({ | ||
| ...tool, | ||
| command: toolCommand, | ||
| version, | ||
@@ -30,3 +35,3 @@ installed: true | ||
| logger.debug(`Found: ${tool.displayName} v${version}`); | ||
| logger.debug(`Found: ${tool.displayName} v${version} (command: ${toolCommand})`); | ||
| } | ||
@@ -57,2 +62,7 @@ } catch (err) { | ||
| const version = await getToolVersion(tool); | ||
| // On Windows, checkInstalled may return full path instead of true | ||
| // Use this full path as command if available (for .cmd/.bat files) | ||
| const toolCommand = (typeof isInstalled === 'string') ? isInstalled : tool.command; | ||
| return { | ||
@@ -62,2 +72,3 @@ installed: true, | ||
| ...tool, | ||
| command: toolCommand, | ||
| version | ||
@@ -64,0 +75,0 @@ } |
@@ -10,3 +10,3 @@ const { exec } = require('child_process'); | ||
| command: 'claude', | ||
| args: ['code'], | ||
| args: [], | ||
| displayName: 'Claude Code', | ||
@@ -173,2 +173,4 @@ description: 'Anthropic\'s AI coding assistant', | ||
| // Check if command exists | ||
| // On Windows, returns full path to command (for reliable PTY execution) | ||
| // On Unix, returns true/false | ||
| async function commandExists(command) { | ||
@@ -178,3 +180,28 @@ try { | ||
| const checkCommand = isWindows ? `where ${command}` : `command -v ${command}`; | ||
| await execAsync(checkCommand); | ||
| const { stdout } = await execAsync(checkCommand); | ||
| // On Windows, always return full path | ||
| // PTY spawned via cmd.exe may have different PATH than parent PowerShell | ||
| // where.exe returns multiple lines if multiple matches exist, use first | ||
| if (isWindows && stdout.trim()) { | ||
| // Handle both \r\n (Windows) and \n line endings | ||
| const lines = stdout.trim().split(/\r?\n/); | ||
| let firstLine = lines[0].trim(); | ||
| if (firstLine && firstLine.length > 0) { | ||
| // where.exe may return path without extension | ||
| // If path doesn't end with .cmd/.bat/.exe, prefer .cmd version if it exists | ||
| const hasExtension = /\.(cmd|bat|exe)$/i.test(firstLine); | ||
| if (!hasExtension) { | ||
| // Check if .cmd file exists | ||
| const fs = require('fs'); | ||
| const cmdPath = `${firstLine}.cmd`; | ||
| if (fs.existsSync(cmdPath)) { | ||
| return cmdPath; | ||
| } | ||
| } | ||
| return firstLine; | ||
| } | ||
| } | ||
| return true; | ||
@@ -181,0 +208,0 @@ } catch { |
@@ -291,20 +291,2 @@ const WebSocket = require('ws'); | ||
| // Handle input from mobile | ||
| // Helper: escape special characters for logging | ||
| escapeSpecialChars(data) { | ||
| return data | ||
| .replace(/\r/g, '\\r') | ||
| .replace(/\n/g, '\\n') | ||
| .replace(/\t/g, '\\t') | ||
| .replace(/\x1b/g, '\\x1b') | ||
| .replace(/\x00/g, '\\x00'); | ||
| } | ||
| // Helper: convert to hex dump | ||
| toHexDump(data, maxLength = 200) { | ||
| const bytes = Buffer.from(data, 'utf8'); | ||
| const hex = bytes.toString('hex').match(/.{1,2}/g)?.join(' ') || ''; | ||
| const truncated = hex.length > maxLength ? hex.substring(0, maxLength) + '...' : hex; | ||
| return truncated; | ||
| } | ||
| handleInput(message) { | ||
@@ -319,9 +301,2 @@ if (!this.aesKey) { | ||
| // Log decrypted input for debugging | ||
| if (process.env.DEBUG === '1' || process.argv.includes('--debug')) { | ||
| logger.debug(`WS Input received (${decrypted.length} bytes):`); | ||
| logger.debug(` Text: ${this.escapeSpecialChars(decrypted.substring(0, 100))}`); | ||
| logger.debug(` Hex: ${this.toHexDump(decrypted)}`); | ||
| } | ||
| if (this.onInputCallback) { | ||
@@ -488,9 +463,2 @@ this.onInputCallback(decrypted); | ||
| try { | ||
| // Log output before encryption for debugging | ||
| if (process.env.DEBUG === '1' || process.argv.includes('--debug')) { | ||
| logger.debug(`WS Output sending (${data.length} bytes):`); | ||
| logger.debug(` Text: ${this.escapeSpecialChars(data.substring(0, 100))}`); | ||
| logger.debug(` Hex: ${this.toHexDump(data)}`); | ||
| } | ||
| const encrypted = encrypt(data, this.aesKey); | ||
@@ -497,0 +465,0 @@ |
@@ -46,5 +46,15 @@ const pty = require('node-pty'); | ||
| if (isWindows) { | ||
| // Use cmd.exe to spawn the command (handles .cmd/.bat files) | ||
| spawnCommand = 'cmd.exe'; | ||
| spawnArgs = ['/c', this.tool.command, ...args]; | ||
| // On Windows with full paths: spawn .cmd/.bat directly (node-pty supports this) | ||
| // Avoids cmd.exe quote escaping issues | ||
| const isFullPath = this.tool.command.includes('\\') || this.tool.command.includes('/'); | ||
| if (isFullPath) { | ||
| // Direct spawn - node-pty handles .cmd/.bat files automatically | ||
| spawnCommand = this.tool.command; | ||
| spawnArgs = args; | ||
| } else { | ||
| // For commands in PATH, use cmd.exe | ||
| spawnCommand = 'cmd.exe'; | ||
| spawnArgs = ['/c', this.tool.command, ...args]; | ||
| } | ||
| } | ||
@@ -51,0 +61,0 @@ |
+1
-1
| { | ||
| "name": "@termly-dev/cli-dev", | ||
| "version": "1.1.10", | ||
| "version": "1.2.7", | ||
| "description": "Mirror your AI coding sessions to mobile - control Claude, Aider, Copilot, and 17+ tools from your phone (Development version)", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Unpublished package
Supply chain riskPackage version was not found on the registry. It may exist on a different registry and need to be configured to pull from that registry.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Unpopular package
QualityThis package is not very popular.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
172292
0.45%4188
0.31%0
-100%27
-3.57%3
50%