UNPKG

smartsh

Version:

Cross-shell command runner enabling Unix-style syntax on any OS.

1 lines 380 kB
{"version":3,"sources":["../src/tokenize.ts","../src/unixMappings.ts","../src/shellMappings.ts","../src/bidirectionalMappings.ts","../src/translate.ts"],"sourcesContent":["export interface TokenInfo {\n value: string;\n start: number;\n end: number; // exclusive\n /** Quote character that originally wrapped the token (' or \" ), or undefined for unquoted */\n quoteType?: \"'\" | '\"';\n}\n\nexport interface EnhancedToken extends TokenInfo {\n originalText: string; // The exact original substring\n reconstructedValue: string; // What it should be after reconstruction\n needsReconstruction: boolean; // Flag for special handling\n}\n\nexport type TokenRole = \"cmd\" | \"flag\" | \"arg\" | \"op\";\n\nexport interface RoleToken extends EnhancedToken {\n role: TokenRole;\n}\n\n/**\n * Custom tokenizer that preserves shell constructs instead of evaluating them.\n * This is the key difference from shell-quote which is designed for execution.\n */\nexport function tokenizeWithPos(cmd: string): TokenInfo[] {\n const tokens: TokenInfo[] = [];\n let i = 0;\n \n while (i < cmd.length) {\n // Skip whitespace\n while (i < cmd.length && /\\s/.test(cmd[i])) {\n i++;\n }\n if (i >= cmd.length) break;\n \n const start = i;\n let value = \"\";\n let quoteType: \"'\" | '\"' | undefined = undefined;\n \n // Handle quoted strings\n if (cmd[i] === \"'\" || cmd[i] === '\"') {\n quoteType = cmd[i] as \"'\" | '\"';\n const quoteChar = cmd[i];\n value = cmd[i]; // Include the opening quote\n i++; // Skip opening quote\n \n while (i < cmd.length && cmd[i] !== quoteChar) {\n value += cmd[i];\n i++;\n }\n \n if (i < cmd.length) {\n value += cmd[i]; // Include the closing quote\n i++; // Skip closing quote\n }\n }\n // Handle operators (but check for escaped operators first)\n else if (cmd[i] === '\\\\' && i + 1 < cmd.length && isOperatorStart(cmd[i + 1])) {\n // Escaped operator - treat as literal\n value = cmd[i] + cmd[i + 1];\n i += 2;\n }\n // Handle PowerShell backtick-escaped operators\n else if (cmd[i] === '`' && i + 1 < cmd.length && isOperatorStart(cmd[i + 1])) {\n // Check for double backtick-escaped operators like `&`&\n if (cmd[i + 1] === '&' && i + 2 < cmd.length && cmd[i + 2] === '`' && i + 3 < cmd.length && cmd[i + 3] === '&') {\n // `&`& - treat as single token\n value = cmd[i] + cmd[i + 1] + cmd[i + 2] + cmd[i + 3];\n i += 4;\n } else if (cmd[i + 1] === '|' && i + 2 < cmd.length && cmd[i + 2] === '`' && i + 3 < cmd.length && cmd[i + 3] === '|') {\n // `|`| - treat as single token\n value = cmd[i] + cmd[i + 1] + cmd[i + 2] + cmd[i + 3];\n i += 4;\n } else {\n // Single backtick-escaped operator\n value = cmd[i] + cmd[i + 1];\n i += 2;\n }\n }\n else if (isOperator(cmd, i)) {\n const op = extractOperator(cmd, i);\n value = op;\n i += op.length;\n }\n // Handle regular tokens\n else {\n while (i < cmd.length && !/\\s/.test(cmd[i]) && !isOperatorStart(cmd[i])) {\n value += cmd[i];\n i++;\n }\n }\n \n // Safety check: if we didn't process any characters, increment i to avoid infinite loop\n if (i === start) {\n value = cmd[i];\n i++;\n }\n \n if (value) {\n tokens.push({\n value,\n start,\n end: i,\n quoteType\n });\n }\n }\n \n return tokens;\n}\n\n/**\n * Check if we're at the start of an operator\n */\nfunction isOperatorStart(char: string): boolean {\n return ['<', '>', '|', '&', ';', '(', ')', '{', '}'].includes(char);\n}\n\n/**\n * Check if we're at an operator position\n */\nfunction isOperator(cmd: string, pos: number): boolean {\n const operators = ['&&', '||', '|&', '<<', '>>', '|', ';', '<', '>', '(', ')', '{', '}'];\n \n for (const op of operators) {\n if (cmd.substring(pos, pos + op.length) === op) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Extract the operator at the current position\n */\nfunction extractOperator(cmd: string, pos: number): string {\n const operators = ['&&', '||', '|&', '<<', '>>', '|', ';', '<', '>', '(', ')', '{', '}'];\n \n for (const op of operators) {\n if (cmd.substring(pos, pos + op.length) === op) {\n return op;\n }\n }\n \n return cmd[pos];\n}\n\n/**\n * Enhanced tokenization with preservation layer for complex shell constructs.\n * Maps parsed tokens back to original positions and reconstructs special constructs.\n */\nexport function tokenizeWithPosEnhanced(cmd: string): EnhancedToken[] {\n const basicTokens = tokenizeWithPos(cmd);\n const enhancedTokens = mapToOriginalPositions(basicTokens, cmd);\n return reconstructSpecialConstructs(enhancedTokens, cmd);\n}\n\n/**\n * Map basic tokens to enhanced tokens with original text preservation.\n */\nfunction mapToOriginalPositions(tokens: TokenInfo[], cmd: string): EnhancedToken[] {\n return tokens.map(token => ({\n ...token,\n originalText: cmd.substring(token.start, token.end),\n reconstructedValue: token.value,\n needsReconstruction: false\n }));\n}\n\n/**\n * Reconstruct special shell constructs from original text.\n */\nfunction reconstructSpecialConstructs(tokens: EnhancedToken[], cmd: string): EnhancedToken[] {\n let result = [...tokens];\n \n // Step 1: Reconstruct command substitution ($(...))\n result = reconstructCommandSubstitution(result);\n \n // Step 2: Reconstruct here-documents (<< 'EOF')\n result = reconstructHereDocs(result);\n \n // Step 3: Reconstruct process substitution (<(...))\n result = reconstructProcessSubs(result);\n \n // Step 4: Reconstruct function definitions (())\n result = reconstructFunctionDefs(result);\n \n // Step 5: Reconstruct environment variables (${...})\n result = reconstructEnvVars(result, cmd);\n \n // Step 6: Reconstruct redirection operators (2>, etc.)\n result = reconstructRedirections(result);\n \n // Step 7: Reconstruct escaped operators (\\&&, etc.)\n result = reconstructEscapedOperators(result);\n \n return result;\n}\n\n/**\n * Reconstruct command substitution: $(...)\n */\nfunction reconstructCommandSubstitution(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value === \"$\" && i + 1 < tokens.length && tokens[i + 1].value === \"(\") {\n // Found $(, find matching closing )\n let parenDepth = 1;\n let j = i + 2;\n \n while (j < tokens.length && parenDepth > 0) {\n if (tokens[j].value === \"(\") parenDepth++;\n if (tokens[j].value === \")\") parenDepth--;\n j++;\n }\n \n if (parenDepth === 0) {\n // Found complete $(...), merge all tokens\n const cmdSubToken: EnhancedToken = {\n value: \"$(\",\n start: tokens[i].start,\n end: tokens[j - 1].end,\n originalText: tokens.slice(i, j).map(t => t.originalText).join(\"\"),\n reconstructedValue: \"$(\",\n needsReconstruction: false\n };\n \n // Add the command inside\n for (let k = i + 2; k < j - 1; k++) {\n cmdSubToken.reconstructedValue += tokens[k].value + \" \";\n }\n cmdSubToken.reconstructedValue = cmdSubToken.reconstructedValue.trim() + \")\";\n \n result.push(cmdSubToken);\n i = j - 1; // Skip all processed tokens\n } else {\n result.push(tokens[i]);\n }\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct here-document syntax: << 'EOF'\n */\nfunction reconstructHereDocs(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value === \"<<\" && i + 1 < tokens.length) {\n // Found <<, merge with next token (delimiter)\n const hereDocToken: EnhancedToken = {\n value: \"<<\",\n start: tokens[i].start,\n end: tokens[i + 1].end,\n originalText: tokens[i].originalText + tokens[i + 1].originalText,\n reconstructedValue: \"<<\",\n needsReconstruction: false\n };\n \n // Include the delimiter (e.g., 'EOF') - NO SPACE\n hereDocToken.end = tokens[i + 1].end;\n hereDocToken.originalText += tokens[i + 1].originalText;\n hereDocToken.reconstructedValue += tokens[i + 1].value;\n i += 1; // Skip the next token\n \n result.push(hereDocToken);\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct process substitution: <(...)\n */\nfunction reconstructProcessSubs(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value === \"<\" && i + 1 < tokens.length && tokens[i + 1].value === \"(\") {\n // Found <(, find matching closing )\n let parenDepth = 1;\n let j = i + 2;\n \n while (j < tokens.length && parenDepth > 0) {\n if (tokens[j].value === \"(\") parenDepth++;\n if (tokens[j].value === \")\") parenDepth--;\n j++;\n }\n \n if (parenDepth === 0) {\n // Found complete <(...), merge all tokens\n const processSubToken: EnhancedToken = {\n value: \"<(\",\n start: tokens[i].start,\n end: tokens[j - 1].end,\n originalText: tokens.slice(i, j).map(t => t.originalText).join(\"\"),\n reconstructedValue: \"<(\",\n needsReconstruction: false\n };\n \n // Add the command inside\n for (let k = i + 2; k < j - 1; k++) {\n processSubToken.reconstructedValue += tokens[k].value + \" \";\n }\n processSubToken.reconstructedValue += \")\";\n \n result.push(processSubToken);\n i = j - 1; // Skip all processed tokens\n } else {\n result.push(tokens[i]);\n }\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct function definitions: ()\n */\nfunction reconstructFunctionDefs(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value === \"(\" && i + 1 < tokens.length && tokens[i + 1].value === \")\") {\n // Found (), merge them\n const funcDefToken: EnhancedToken = {\n value: \"()\",\n start: tokens[i].start,\n end: tokens[i + 1].end,\n originalText: tokens[i].originalText + tokens[i + 1].originalText,\n reconstructedValue: \"()\",\n needsReconstruction: false\n };\n \n result.push(funcDefToken);\n i += 1; // Skip the next token\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct environment variables from original text.\n */\nfunction reconstructEnvVars(tokens: EnhancedToken[], cmd: string): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value === \"$\" && i + 1 < tokens.length && tokens[i + 1].value === \"{\") {\n // Found ${, find matching closing }\n let braceDepth = 1;\n let j = i + 2;\n \n while (j < tokens.length && braceDepth > 0) {\n if (tokens[j].value === \"{\") braceDepth++;\n if (tokens[j].value === \"}\") braceDepth--;\n j++;\n }\n \n if (braceDepth === 0) {\n // Found complete ${...}, merge all tokens\n const envVarToken: EnhancedToken = {\n value: \"${\",\n start: tokens[i].start,\n end: tokens[j - 1].end,\n originalText: tokens.slice(i, j).map(t => t.originalText).join(\"\"),\n reconstructedValue: \"${\",\n needsReconstruction: false\n };\n \n // Add the variable name inside\n for (let k = i + 2; k < j - 1; k++) {\n envVarToken.reconstructedValue += tokens[k].value + \" \";\n }\n envVarToken.reconstructedValue = envVarToken.reconstructedValue.trim() + \"}\";\n \n result.push(envVarToken);\n i = j - 1; // Skip all processed tokens\n } else {\n result.push(tokens[i]);\n }\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct redirection operators (2>, etc.)\n */\nfunction reconstructRedirections(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n \n for (let i = 0; i < tokens.length; i++) {\n // Check for redirection patterns like \"2\" followed by \">\"\n if (tokens[i].value.match(/^\\d+$/) && i + 1 < tokens.length && \n (tokens[i + 1].value === \">\" || tokens[i + 1].value === \">>\" || tokens[i + 1].value === \"&\")) {\n // Found number followed by redirection operator\n const redirectionToken: EnhancedToken = {\n value: tokens[i].value + tokens[i + 1].value,\n start: tokens[i].start,\n end: tokens[i + 1].end,\n originalText: tokens[i].originalText + tokens[i + 1].originalText,\n reconstructedValue: tokens[i].value + tokens[i + 1].value,\n needsReconstruction: false\n };\n \n result.push(redirectionToken);\n i += 1; // Skip the next token\n } else if (isRedirectionToken(tokens[i].value)) {\n // Already a complete redirection token\n result.push(tokens[i]);\n } else {\n result.push(tokens[i]);\n }\n }\n \n return result;\n}\n\n/**\n * Reconstruct escaped operators (\\&&, etc.)\n */\nfunction reconstructEscapedOperators(tokens: EnhancedToken[]): EnhancedToken[] {\n const result: EnhancedToken[] = [];\n\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i].value.startsWith(\"\\\\\") && i + 1 < tokens.length && isOperatorStart(tokens[i + 1].value)) {\n // Found escaped operator like \\&&\n const escapedOpToken: EnhancedToken = {\n value: tokens[i].value + tokens[i + 1].value,\n start: tokens[i].start,\n end: tokens[i + 1].end,\n originalText: tokens[i].originalText + tokens[i + 1].originalText,\n reconstructedValue: tokens[i].value + tokens[i + 1].value,\n needsReconstruction: false\n };\n result.push(escapedOpToken);\n i += 1; // Skip the next token\n } else {\n result.push(tokens[i]);\n }\n }\n return result;\n}\n\nconst OPS = new Set([\"&&\", \"||\", \"|\", \";\", \"|&\"]);\n\n// Recognise > >> < 2> 2>> 2>&1 &> etc.\nfunction isRedirectionToken(val: string): boolean {\n return /^(\\d*>>?&?\\d*|[<>]{1,2}|&>?)$/.test(val);\n}\n\n/**\n * Classify each token with a coarse role: command, flag, argument or operator.\n * The heuristic is simple but works for most Unix one-liners.\n */\nexport function tagTokenRoles(tokens: TokenInfo[]): RoleToken[] {\n const out: RoleToken[] = [];\n let expectCmd = true; // start of command or after connector/semicolon/pipe\n\n for (const t of tokens) {\n const enhancedToken: EnhancedToken = {\n ...t,\n originalText: t.value,\n reconstructedValue: t.value,\n needsReconstruction: false\n };\n\n if (OPS.has(t.value)) {\n out.push({ ...enhancedToken, role: \"op\" });\n expectCmd = true;\n continue;\n }\n\n if (isRedirectionToken(t.value)) {\n out.push({ ...enhancedToken, role: \"arg\" });\n continue;\n }\n\n if (expectCmd) {\n out.push({ ...enhancedToken, role: \"cmd\" });\n expectCmd = false;\n continue;\n }\n\n if (t.value.startsWith(\"-\") && t.value.length > 1 && t.quoteType === undefined) {\n out.push({ ...enhancedToken, role: \"flag\" });\n } else {\n out.push({ ...enhancedToken, role: \"arg\" });\n }\n }\n return out;\n} \n\n/**\n * Enhanced tokenization with reconstruction and role tagging.\n */\nexport function tokenizeWithPosEnhancedAndRoles(cmd: string): RoleToken[] {\n const enhancedTokens = tokenizeWithPosEnhanced(cmd);\n return enhancedTokens.map(token => ({\n ...token,\n role: determineRole(token, enhancedTokens)\n }));\n}\n\n/**\n * Determine the role of a token based on context.\n */\nfunction determineRole(token: EnhancedToken, allTokens: EnhancedToken[]): TokenRole {\n // Use the reconstructed value for role determination\n const value = token.reconstructedValue;\n \n // Check if it's an operator\n if (OPS.has(value)) {\n return \"op\";\n }\n \n // Check if it's a redirection token\n if (isRedirectionToken(value)) {\n return \"arg\";\n }\n \n // Check if it's a flag (starts with - and not quoted)\n if (value.startsWith(\"-\") && value.length > 1 && token.quoteType === undefined) {\n return \"flag\";\n }\n \n // For the first token or after operators, it's likely a command\n const tokenIndex = allTokens.indexOf(token);\n if (tokenIndex === 0) {\n return \"cmd\";\n }\n \n // Check if the previous token was an operator\n for (let i = tokenIndex - 1; i >= 0; i--) {\n if (OPS.has(allTokens[i].reconstructedValue)) {\n return \"cmd\";\n }\n if (allTokens[i].reconstructedValue === \";\" || allTokens[i].reconstructedValue === \"|\") {\n return \"cmd\";\n }\n }\n \n // Default to argument\n return \"arg\";\n} ","import { tokenizeWithPos, tagTokenRoles } from \"./tokenize\";\n\nexport interface CommandMapping {\n unix: string;\n ps: string;\n flagMap: Record<string, string>; // maps a unix flag (or combo) to ps flags\n forceArgs?: boolean; // if true command requires at least one argument\n}\n\nconst RM_MAPPING: CommandMapping = {\n unix: \"rm\",\n ps: \"Remove-Item\",\n flagMap: {\n \"-rf\": \"-Recurse -Force\",\n \"-fr\": \"-Recurse -Force\",\n \"-r\": \"-Recurse\",\n \"-f\": \"-Force\",\n },\n forceArgs: true,\n};\n\nconst MKDIR_MAPPING: CommandMapping = {\n unix: \"mkdir\",\n ps: \"New-Item -ItemType Directory\",\n flagMap: {\n \"-p\": \"-Force\",\n \"-m\": \"-Mode\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: true,\n};\n\nconst LS_MAPPING: CommandMapping = {\n unix: \"ls\",\n ps: \"Get-ChildItem\",\n flagMap: {\n \"-la\": \"-Force\",\n \"-al\": \"-Force\",\n \"-a\": \"-Force\",\n \"-l\": \"\",\n },\n};\n\nconst CP_MAPPING: CommandMapping = {\n unix: \"cp\",\n ps: \"Copy-Item\",\n flagMap: {\n \"-r\": \"-Recurse\",\n \"-R\": \"-Recurse\",\n \"-f\": \"-Force\",\n \"-rf\": \"-Recurse -Force\",\n \"-fr\": \"-Recurse -Force\",\n },\n forceArgs: true,\n};\n\nconst MV_MAPPING: CommandMapping = {\n unix: \"mv\",\n ps: \"Move-Item\",\n flagMap: {},\n forceArgs: true,\n};\n\nconst TOUCH_MAPPING: CommandMapping = {\n unix: \"touch\",\n ps: \"New-Item -ItemType File\",\n flagMap: {\n \"-a\": \"-AccessTime\",\n \"-m\": \"-ModifyTime\",\n \"-c\": \"-NoCreate\",\n },\n forceArgs: true,\n};\n\nconst GREP_MAPPING: CommandMapping = {\n unix: \"grep\",\n ps: \"Select-String\",\n flagMap: {\n \"-i\": \"-CaseSensitive:$false\",\n \"-n\": \"-LineNumber\",\n \"-in\": \"-CaseSensitive:$false -LineNumber\",\n \"-ni\": \"-CaseSensitive:$false -LineNumber\",\n \"-v\": \"-NotMatch\",\n \"-iv\": \"-CaseSensitive:$false -NotMatch\",\n \"-vn\": \"-CaseSensitive:$false -LineNumber\",\n \"-vni\": \"-CaseSensitive:$false -NotMatch -LineNumber\",\n \"-q\": \"-Quiet\",\n \"-iq\": \"-CaseSensitive:$false -Quiet\",\n \"-qi\": \"-CaseSensitive:$false -Quiet\",\n \"-E\": \"\",\n \"-F\": \"-SimpleMatch\",\n },\n forceArgs: true,\n};\n\nconst CAT_MAPPING: CommandMapping = {\n unix: \"cat\",\n ps: \"Get-Content\",\n flagMap: {},\n forceArgs: true,\n};\n\nconst WHICH_MAPPING: CommandMapping = {\n unix: \"which\",\n ps: \"Get-Command\",\n flagMap: {},\n forceArgs: true,\n};\n\nconst SORT_MAPPING: CommandMapping = {\n unix: \"sort\",\n ps: \"Sort-Object\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst UNIQ_MAPPING: CommandMapping = {\n unix: \"uniq\",\n ps: \"Select-Object -Unique\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst FIND_MAPPING: CommandMapping = {\n unix: \"find\",\n ps: \"Get-ChildItem -Recurse\",\n flagMap: {\n \"-name\": \"-Filter\", // maps -name pattern\n \"-type\": \"\", // we ignore -type for now\n \"-delete\": \"\", // handled specially in translation logic\n },\n forceArgs: true,\n};\n\nconst PWD_MAPPING: CommandMapping = {\n unix: \"pwd\",\n ps: \"Get-Location\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst DATE_MAPPING: CommandMapping = {\n unix: \"date\",\n ps: \"Get-Date\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst CLEAR_MAPPING: CommandMapping = {\n unix: \"clear\",\n ps: \"Clear-Host\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst PS_MAPPING: CommandMapping = {\n unix: \"ps\",\n ps: \"Get-Process\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst KILL_MAPPING: CommandMapping = {\n unix: \"kill\",\n ps: \"Stop-Process\",\n flagMap: {\n \"-9\": \"-Force\",\n },\n forceArgs: true,\n};\n\nconst DF_MAPPING: CommandMapping = {\n unix: \"df\",\n ps: \"Get-PSDrive\",\n flagMap: {\n \"-h\": \"\", // human-readable not needed\n },\n forceArgs: false,\n};\n\nconst HOSTNAME_MAPPING: CommandMapping = {\n unix: \"hostname\",\n ps: \"$env:COMPUTERNAME\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst DIRNAME_MAPPING: CommandMapping = {\n unix: \"dirname\",\n ps: \"Split-Path -Parent\",\n flagMap: {},\n forceArgs: true,\n};\n\nconst BASENAME_MAPPING: CommandMapping = {\n unix: \"basename\",\n ps: \"Split-Path -Leaf\",\n flagMap: {},\n forceArgs: true,\n};\n\nconst TEE_MAPPING: CommandMapping = {\n unix: \"tee\",\n ps: \"Tee-Object -FilePath\",\n flagMap: {\n \"-a\": \"-Append\",\n },\n forceArgs: true,\n};\n\nconst TAR_MAPPING: CommandMapping = {\n unix: \"tar\",\n ps: \"tar\", // Use native tar if available, otherwise preserve\n flagMap: {\n \"-c\": \"-c\",\n \"-x\": \"-x\",\n \"-f\": \"-f\",\n \"-z\": \"-z\",\n \"-j\": \"-j\",\n \"-v\": \"-v\",\n \"-t\": \"-t\",\n },\n forceArgs: true,\n};\n\nconst CURL_MAPPING: CommandMapping = {\n unix: \"curl\",\n ps: \"Invoke-WebRequest\",\n flagMap: {\n \"-o\": \"-OutFile\",\n \"-O\": \"-OutFile\",\n \"-s\": \"-UseBasicParsing\",\n \"-L\": \"-MaximumRedirection\",\n \"-H\": \"-Headers\",\n \"-d\": \"-Body\",\n \"-X\": \"-Method\",\n \"-k\": \"-SkipCertificateCheck\",\n },\n forceArgs: true,\n};\n\nconst WGET_MAPPING: CommandMapping = {\n unix: \"wget\",\n ps: \"Invoke-WebRequest\",\n flagMap: {\n \"-O\": \"-OutFile\",\n \"-o\": \"-OutFile\",\n \"-q\": \"-UseBasicParsing\",\n \"-c\": \"-Resume\",\n \"-r\": \"-Recurse\",\n \"-np\": \"-NoParent\",\n \"-k\": \"-ConvertLinks\",\n },\n forceArgs: true,\n};\n\nconst DIFF_MAPPING: CommandMapping = {\n unix: \"diff\",\n ps: \"Compare-Object\",\n flagMap: {\n \"-u\": \"-Unified\",\n \"-r\": \"-Recurse\",\n \"-i\": \"-CaseInsensitive\",\n \"-w\": \"-IgnoreWhiteSpace\",\n \"-B\": \"-IgnoreBlankLines\",\n },\n forceArgs: true,\n};\n\nconst SPLIT_MAPPING: CommandMapping = {\n unix: \"split\",\n ps: \"Split-Content\",\n flagMap: {\n \"-l\": \"-LineCount\",\n \"-b\": \"-ByteCount\",\n \"-n\": \"-Number\",\n },\n forceArgs: true,\n};\n\nconst PASTE_MAPPING: CommandMapping = {\n unix: \"paste\",\n ps: \"Join-Object\",\n flagMap: {\n \"-d\": \"-Delimiter\",\n \"-s\": \"-Serial\",\n },\n forceArgs: true,\n};\n\nconst RSYNC_MAPPING: CommandMapping = {\n unix: \"rsync\",\n ps: \"Copy-Item\",\n flagMap: {\n \"-a\": \"-Recurse\", // archive mode (recursive + preserve attributes)\n \"-v\": \"-Verbose\", // verbose\n \"-r\": \"-Recurse\", // recursive\n \"-u\": \"-Force\", // update (skip newer files)\n \"-n\": \"-WhatIf\", // dry run\n \"-P\": \"-PassThru\", // progress + partial\n },\n forceArgs: true,\n};\n\nconst CHMOD_MAPPING: CommandMapping = {\n unix: \"chmod\",\n ps: \"icacls\",\n flagMap: {\n \"-R\": \"/T\", // recursive\n \"-v\": \"/Q\", // verbose (quiet in icacls)\n },\n forceArgs: true,\n};\n\nconst CHOWN_MAPPING: CommandMapping = {\n unix: \"chown\",\n ps: \"icacls\",\n flagMap: {\n \"-R\": \"/T\", // recursive\n \"-v\": \"/Q\", // verbose (quiet in icacls)\n },\n forceArgs: true,\n};\n\nconst LN_MAPPING: CommandMapping = {\n unix: \"ln\",\n ps: \"New-Item\",\n flagMap: {\n \"-s\": \"-ItemType SymbolicLink\", // symbolic link\n \"-f\": \"-Force\", // force\n \"-v\": \"-Verbose\", // verbose\n },\n forceArgs: true,\n};\n\nconst DU_MAPPING: CommandMapping = {\n unix: \"du\",\n ps: \"Get-ChildItem\",\n flagMap: {\n \"-h\": \"-Recurse\", // human readable (handled in translation)\n \"-s\": \"-Recurse\", // summarize\n \"-a\": \"-Recurse\", // all files\n \"-c\": \"-Recurse\", // total\n },\n forceArgs: true,\n};\n\nconst SYSTEMCTL_MAPPING: CommandMapping = {\n unix: \"systemctl\",\n ps: \"Get-Service\", // default fallback\n flagMap: {\n \"start\": \"Start-Service\",\n \"stop\": \"Stop-Service\", \n \"restart\": \"Restart-Service\",\n \"status\": \"Get-Service\",\n \"enable\": \"Set-Service -StartupType Automatic\",\n \"disable\": \"Set-Service -StartupType Disabled\",\n \"reload\": \"Restart-Service\",\n },\n forceArgs: true,\n};\n\nconst LESS_MAPPING: CommandMapping = {\n unix: \"less\",\n ps: \"Get-Content | Out-Host -Paging\",\n flagMap: {\n \"-N\": \"-LineNumber\",\n \"-M\": \"\", // show more info (handled in translation)\n \"-R\": \"\", // raw control chars (handled in translation)\n },\n forceArgs: false,\n};\n\nconst MORE_MAPPING: CommandMapping = {\n unix: \"more\",\n ps: \"Get-Content | Out-Host -Paging\",\n flagMap: {\n \"-N\": \"-LineNumber\",\n \"-c\": \"\", // clear screen (handled in translation)\n \"-p\": \"\", // pattern search (handled in translation)\n },\n forceArgs: false,\n};\n\nconst PING_MAPPING: CommandMapping = {\n unix: \"ping\",\n ps: \"Test-Connection\",\n flagMap: {\n \"-c\": \"-Count\",\n \"-i\": \"-Interval\",\n \"-t\": \"-TimeoutSeconds\",\n \"-W\": \"-TimeoutSeconds\",\n \"-s\": \"-BufferSize\",\n \"-l\": \"-BufferSize\",\n },\n forceArgs: true,\n};\n\nconst TOP_MAPPING: CommandMapping = {\n unix: \"top\",\n ps: \"Get-Process | Sort-Object CPU -Descending | Select-Object -First 20\",\n flagMap: {\n \"-n\": \"-First\",\n \"-p\": \"-Id\",\n \"-u\": \"-IncludeUserName\",\n },\n forceArgs: false,\n};\n\nconst RMDIR_MAPPING: CommandMapping = {\n unix: \"rmdir\",\n ps: \"Remove-Item -Directory\",\n flagMap: {\n \"-p\": \"-Recurse\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: true,\n};\n\nconst UPTIME_MAPPING: CommandMapping = {\n unix: \"uptime\",\n ps: \"(Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime\",\n flagMap: {\n \"-p\": \"-Pretty\",\n \"-s\": \"-Since\",\n },\n forceArgs: false,\n};\n\nconst FREE_MAPPING: CommandMapping = {\n unix: \"free\",\n ps: \"Get-Counter '\\\\Memory\\\\Available MBytes' | Select-Object -ExpandProperty CounterSamples\",\n flagMap: {\n \"-h\": \"-Human\",\n \"-m\": \"-MB\",\n \"-g\": \"-GB\",\n },\n forceArgs: false,\n};\n\nconst NL_MAPPING: CommandMapping = {\n unix: \"nl\",\n ps: \"Get-Content | ForEach-Object { $i++; \\\"$i`t$_\\\" }\",\n flagMap: {\n \"-b\": \"\", // body numbering (handled in translation)\n \"-n\": \"\", // number format (handled in translation)\n },\n forceArgs: false,\n};\n\nconst NETSTAT_MAPPING: CommandMapping = {\n unix: \"netstat\",\n ps: \"Get-NetTCPConnection\",\n flagMap: {\n \"-t\": \"-State Listen\",\n \"-u\": \"-State Listen\",\n \"-l\": \"-State Listen\",\n \"-n\": \"-State Listen\",\n \"-a\": \"-State Listen\",\n \"-p\": \"-State Listen\",\n },\n forceArgs: false,\n};\n\nconst SSH_MAPPING: CommandMapping = {\n unix: \"ssh\",\n ps: \"ssh\",\n flagMap: {\n \"-p\": \"-Port\",\n \"-i\": \"-IdentityFile\",\n \"-X\": \"-X11Forwarding\",\n },\n forceArgs: true,\n};\n\nconst GZIP_MAPPING: CommandMapping = {\n unix: \"gzip\",\n ps: \"Compress-Archive\",\n flagMap: {\n \"-d\": \"-DestinationPath\",\n \"-r\": \"-Recurse\",\n \"-f\": \"-Force\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: false,\n};\n\nconst GUNZIP_MAPPING: CommandMapping = {\n unix: \"gunzip\",\n ps: \"Expand-Archive\",\n flagMap: {\n \"-f\": \"-Force\",\n \"-v\": \"-Verbose\",\n \"-l\": \"-ListOnly\",\n },\n forceArgs: false,\n};\n\nconst JOBS_MAPPING: CommandMapping = {\n unix: \"jobs\",\n ps: \"Get-Job\",\n flagMap: {\n \"-l\": \"-IncludeChildJob\",\n \"-p\": \"-Id\",\n \"-r\": \"-State Running\",\n \"-s\": \"-State Stopped\",\n },\n forceArgs: false,\n};\n\nconst BG_MAPPING: CommandMapping = {\n unix: \"bg\",\n ps: \"Resume-Job\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst FG_MAPPING: CommandMapping = {\n unix: \"fg\",\n ps: \"Receive-Job\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst NICE_MAPPING: CommandMapping = {\n unix: \"nice\",\n ps: \"Start-Process\",\n flagMap: {\n \"-n\": \"-Priority\",\n },\n forceArgs: true,\n};\n\nconst NOHUP_MAPPING: CommandMapping = {\n unix: \"nohup\",\n ps: \"Start-Process\",\n flagMap: {\n \"-n\": \"-NoNewWindow\",\n },\n forceArgs: true,\n};\n\nconst CHGRP_MAPPING: CommandMapping = {\n unix: \"chgrp\",\n ps: \"icacls\",\n flagMap: {\n \"-R\": \"/T\",\n \"-v\": \"/Q\",\n },\n forceArgs: true,\n};\n\nconst UMASK_MAPPING: CommandMapping = {\n unix: \"umask\",\n ps: \"Get-ChildItem\",\n flagMap: {\n \"-S\": \"\",\n },\n forceArgs: false,\n};\n\nconst MKTEMP_MAPPING: CommandMapping = {\n unix: \"mktemp\",\n ps: \"New-TemporaryFile\",\n flagMap: {\n \"-d\": \"\",\n \"-u\": \"\",\n },\n forceArgs: false,\n};\n\nconst REALPATH_MAPPING: CommandMapping = {\n unix: \"realpath\",\n ps: \"Resolve-Path\",\n flagMap: {\n \"-q\": \"-Quiet\",\n \"-s\": \"-Relative\",\n },\n forceArgs: true,\n};\n\nconst JOIN_MAPPING: CommandMapping = {\n unix: \"join\",\n ps: \"Join-Object\",\n flagMap: {\n \"-1\": \"-JoinProperty\",\n \"-2\": \"-MergeProperty\",\n \"-t\": \"-Delimiter\",\n },\n forceArgs: true,\n};\n\nconst COMM_MAPPING: CommandMapping = {\n unix: \"comm\",\n ps: \"Compare-Object\",\n flagMap: {\n \"-1\": \"-IncludeEqual\",\n \"-2\": \"-IncludeEqual\",\n \"-3\": \"-IncludeEqual\",\n },\n forceArgs: true,\n};\n\nconst EXPAND_MAPPING: CommandMapping = {\n unix: \"expand\",\n ps: \"Get-Content\",\n flagMap: {\n \"-t\": \"-TabSize\",\n \"-i\": \"-Initial\",\n },\n forceArgs: true,\n};\n\nconst UNEXPAND_MAPPING: CommandMapping = {\n unix: \"unexpand\",\n ps: \"Get-Content\",\n flagMap: {\n \"-a\": \"-All\",\n \"-t\": \"-TabSize\",\n },\n forceArgs: true,\n};\n\nconst FOLD_MAPPING: CommandMapping = {\n unix: \"fold\",\n ps: \"Get-Content\",\n flagMap: {\n \"-b\": \"-Bytes\",\n \"-s\": \"-Spaces\",\n \"-w\": \"-Width\",\n },\n forceArgs: true,\n};\n\nconst FMT_MAPPING: CommandMapping = {\n unix: \"fmt\",\n ps: \"Get-Content\",\n flagMap: {\n \"-w\": \"-Width\",\n \"-g\": \"-Goal\",\n \"-p\": \"-Prefix\",\n },\n forceArgs: true,\n};\n\nconst TELNET_MAPPING: CommandMapping = {\n unix: \"telnet\",\n ps: \"Test-NetConnection\",\n flagMap: {\n \"-p\": \"-Port\",\n \"-l\": \"-Local\",\n },\n forceArgs: true,\n};\n\nconst NC_MAPPING: CommandMapping = {\n unix: \"nc\",\n ps: \"Test-NetConnection\",\n flagMap: {\n \"-v\": \"-Verbose\",\n \"-w\": \"-TimeoutSeconds\",\n \"-l\": \"-Listen\",\n \"-p\": \"-Port\",\n },\n forceArgs: true,\n};\n\nconst DIG_MAPPING: CommandMapping = {\n unix: \"dig\",\n ps: \"Resolve-DnsName\",\n flagMap: {\n \"+short\": \"-Type A\",\n \"+trace\": \"-Type NS\",\n \"-x\": \"-Type PTR\",\n },\n forceArgs: true,\n};\n\nconst NSLOOKUP_MAPPING: CommandMapping = {\n unix: \"nslookup\",\n ps: \"Resolve-DnsName\",\n flagMap: {\n \"-type\": \"-Type\",\n \"-port\": \"-Port\",\n \"-server\": \"-Server\",\n },\n forceArgs: true,\n};\n\nconst MAKE_MAPPING: CommandMapping = {\n unix: \"make\",\n ps: \"make\",\n flagMap: {\n \"-j\": \"-Jobs\",\n \"-f\": \"-File\",\n \"-C\": \"-Directory\",\n },\n forceArgs: false,\n};\n\nconst GCC_MAPPING: CommandMapping = {\n unix: \"gcc\",\n ps: \"gcc\",\n flagMap: {\n \"-o\": \"-Output\",\n \"-c\": \"-Compile\",\n \"-g\": \"-Debug\",\n },\n forceArgs: true,\n};\n\nconst GPP_MAPPING: CommandMapping = {\n unix: \"g++\",\n ps: \"g++\",\n flagMap: {\n \"-o\": \"-o\",\n \"-c\": \"-c\",\n \"-g\": \"-g\",\n \"-Wall\": \"-Wall\",\n \"-std\": \"-std\",\n },\n forceArgs: true,\n};\n\nconst GIT_MAPPING: CommandMapping = {\n unix: \"git\",\n ps: \"git\",\n flagMap: {\n \"clone\": \"clone\",\n \"pull\": \"pull\",\n \"push\": \"push\",\n \"commit\": \"commit\",\n },\n forceArgs: false,\n};\n\nconst APT_MAPPING: CommandMapping = {\n unix: \"apt\",\n ps: \"winget\",\n flagMap: {\n \"install\": \"install\",\n \"remove\": \"uninstall\",\n \"update\": \"upgrade\",\n \"upgrade\": \"upgrade\",\n \"search\": \"search\",\n \"list\": \"list\",\n },\n forceArgs: false,\n};\n\nconst APT_GET_MAPPING: CommandMapping = {\n unix: \"apt-get\",\n ps: \"winget\",\n flagMap: {\n \"install\": \"install\",\n \"remove\": \"uninstall\",\n \"update\": \"upgrade\",\n \"upgrade\": \"upgrade\",\n \"search\": \"search\",\n \"list\": \"list\",\n },\n forceArgs: false,\n};\n\nconst YUM_MAPPING: CommandMapping = {\n unix: \"yum\",\n ps: \"winget\",\n flagMap: {\n \"install\": \"install\",\n \"remove\": \"uninstall\",\n \"update\": \"upgrade\",\n \"upgrade\": \"upgrade\",\n \"search\": \"search\",\n \"list\": \"list\",\n },\n forceArgs: false,\n};\n\nconst DNF_MAPPING: CommandMapping = {\n unix: \"dnf\",\n ps: \"winget\",\n flagMap: {\n \"install\": \"install\",\n \"remove\": \"uninstall\",\n \"update\": \"upgrade\",\n \"upgrade\": \"upgrade\",\n \"search\": \"search\",\n \"list\": \"list\",\n },\n forceArgs: false,\n};\n\nconst BREW_MAPPING: CommandMapping = {\n unix: \"brew\",\n ps: \"winget\",\n flagMap: {\n \"install\": \"install\",\n \"uninstall\": \"uninstall\",\n \"update\": \"upgrade\",\n \"upgrade\": \"upgrade\",\n \"search\": \"search\",\n \"list\": \"list\",\n },\n forceArgs: false,\n};\n\n// System Information & Monitoring\nconst UNAME_MAPPING: CommandMapping = {\n unix: \"uname\",\n ps: \"Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, TotalPhysicalMemory\",\n flagMap: {\n \"-a\": \"-a\",\n \"-r\": \"-r\",\n \"-m\": \"-m\",\n \"-n\": \"-n\",\n \"-p\": \"-p\",\n \"-s\": \"-s\",\n },\n forceArgs: false,\n};\n\nconst ID_MAPPING: CommandMapping = {\n unix: \"id\",\n ps: \"Get-Process -Id $PID | Select-Object ProcessName, Id, UserName\",\n flagMap: {\n \"-u\": \"-u\",\n \"-g\": \"-g\",\n \"-G\": \"-G\",\n \"-n\": \"-n\",\n \"-r\": \"-r\",\n },\n forceArgs: false,\n};\n\nconst GROUPS_MAPPING: CommandMapping = {\n unix: \"groups\",\n ps: \"Get-LocalGroup | Select-Object Name, Description\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst WHO_MAPPING: CommandMapping = {\n unix: \"who\",\n ps: \"Get-Process | Where-Object {$_.ProcessName -like '*explorer*' -or $_.ProcessName -like '*winlogon*'} | Select-Object ProcessName, Id, UserName\",\n flagMap: {\n \"-a\": \"-a\",\n \"-b\": \"-b\",\n \"-d\": \"-d\",\n \"-H\": \"-H\",\n \"-i\": \"-i\",\n \"-l\": \"-l\",\n \"-p\": \"-p\",\n \"-r\": \"-r\",\n \"-t\": \"-t\",\n \"-u\": \"-u\",\n },\n forceArgs: false,\n};\n\nconst W_MAPPING: CommandMapping = {\n unix: \"w\",\n ps: \"Get-Process | Where-Object {$_.ProcessName -like '*explorer*' -or $_.ProcessName -like '*winlogon*'} | Select-Object ProcessName, Id, UserName, CPU, WorkingSet\",\n flagMap: {\n \"hide\": \"-h\",\n \"noheader\": \"-s\",\n \"short\": \"-s\",\n \"users\": \"-u\",\n },\n forceArgs: false,\n};\n\n// File & Text Operations\nconst REV_MAPPING: CommandMapping = {\n unix: \"rev\",\n ps: \"Get-Content $args | ForEach-Object { [string]::Join('', ($_.ToCharArray() | Sort-Object -Descending)) }\",\n flagMap: {},\n forceArgs: false,\n};\n\nconst TAC_MAPPING: CommandMapping = {\n unix: \"tac\",\n ps: \"Get-Content $args | Sort-Object -Descending\",\n flagMap: {\n \"before\": \"-b\",\n \"regex\": \"-r\",\n \"separator\": \"-s\",\n },\n forceArgs: false,\n};\n\nconst COLUMN_MAPPING: CommandMapping = {\n unix: \"column\",\n ps: \"Get-Content $args | Format-Table -AutoSize\",\n flagMap: {\n \"separator\": \"-s\",\n \"table\": \"-t\",\n \"width\": \"-w\",\n },\n forceArgs: false,\n};\n\nconst PR_MAPPING: CommandMapping = {\n unix: \"pr\",\n ps: \"Get-Content $args | Format-List\",\n flagMap: {\n \"columns\": \"-c\",\n \"double\": \"-d\",\n \"formfeed\": \"-f\",\n \"header\": \"-h\",\n \"length\": \"-l\",\n \"merge\": \"-m\",\n \"number\": \"-n\",\n \"output\": \"-o\",\n \"page\": \"-p\",\n \"separator\": \"-s\",\n \"width\": \"-w\",\n },\n forceArgs: false,\n};\n\nconst CSPLIT_MAPPING: CommandMapping = {\n unix: \"csplit\",\n ps: \"Get-Content $args | ForEach-Object { if ($_ -match $pattern) { $i++; Set-Content \\\"split$i.txt\\\" -Value $_ } }\",\n flagMap: {\n \"prefix\": \"-f\",\n \"digits\": \"-n\",\n \"keep\": \"-k\",\n \"quiet\": \"-q\",\n \"suppress\": \"-s\",\n },\n forceArgs: false,\n};\n\n// Advanced Text Processing\nconst TSORT_MAPPING: CommandMapping = {\n unix: \"tsort\",\n ps: \"Get-Content $args | Sort-Object\",\n flagMap: {},\n forceArgs: false,\n};\n\n// System Control\nconst SHUTDOWN_MAPPING: CommandMapping = {\n unix: \"shutdown\",\n ps: \"Stop-Computer\",\n flagMap: {\n \"halt\": \"-h\",\n \"poweroff\": \"-P\",\n \"reboot\": \"-r\",\n \"cancel\": \"-c\",\n \"time\": \"-t\",\n },\n forceArgs: false,\n};\n\nconst REBOOT_MAPPING: CommandMapping = {\n unix: \"reboot\",\n ps: \"Restart-Computer\",\n flagMap: {\n \"force\": \"-f\",\n \"now\": \"-n\",\n },\n forceArgs: false,\n};\n\nconst HALT_MAPPING: CommandMapping = {\n unix: \"halt\",\n ps: \"Stop-Computer -Force\",\n flagMap: {\n \"force\": \"-f\",\n \"poweroff\": \"-p\",\n \"reboot\": \"-r\",\n },\n forceArgs: false,\n};\n\nconst POWEROFF_MAPPING: CommandMapping = {\n unix: \"poweroff\",\n ps: \"Stop-Computer -Force\",\n flagMap: {\n \"force\": \"-f\",\n \"halt\": \"-h\",\n \"reboot\": \"-r\",\n },\n forceArgs: false,\n};\n\n// User Management\nconst USERADD_MAPPING: CommandMapping = {\n unix: \"useradd\",\n ps: \"New-LocalUser\",\n flagMap: {\n \"comment\": \"-c\",\n \"home\": \"-d\",\n \"expire\": \"-e\",\n \"gecos\": \"-g\",\n \"groups\": \"-G\",\n \"system\": \"-r\",\n \"shell\": \"-s\",\n \"uid\": \"-u\",\n },\n forceArgs: false,\n};\n\nconst USERDEL_MAPPING: CommandMapping = {\n unix: \"userdel\",\n ps: \"Remove-LocalUser\",\n flagMap: {\n \"force\": \"-f\",\n \"remove\": \"-r\",\n },\n forceArgs: false,\n};\n\nconst PASSWD_MAPPING: CommandMapping = {\n unix: \"passwd\",\n ps: \"Set-LocalUser -Password (Read-Host -AsSecureString 'Enter new password')\",\n flagMap: {\n \"delete\": \"-d\",\n \"expire\": \"-e\",\n \"force\": \"-f\",\n \"lock\": \"-l\",\n \"unlock\": \"-u\",\n },\n forceArgs: false,\n};\n\nconst SU_MAPPING: CommandMapping = {\n unix: \"su\",\n ps: \"Start-Process powershell -Verb RunAs\",\n flagMap: {\n \"command\": \"-c\",\n \"login\": \"-l\",\n \"preserve\": \"-p\",\n \"shell\": \"-s\",\n },\n forceArgs: false,\n};\n\nconst SUDO_MAPPING: CommandMapping = {\n unix: \"sudo\",\n ps: \"Start-Process powershell -Verb RunAs -ArgumentList\",\n flagMap: {\n \"command\": \"-c\",\n \"login\": \"-l\",\n \"preserve\": \"-p\",\n \"shell\": \"-s\",\n \"user\": \"-u\",\n \"group\": \"-g\",\n },\n forceArgs: true,\n};\n\n// Network Tools\n\nconst TRACEROUTE_MAPPING: CommandMapping = {\n unix: \"traceroute\",\n ps: \"Test-NetConnection -TraceRoute\",\n flagMap: {\n \"-n\": \"-NoResolve\",\n \"-w\": \"-TimeoutSeconds\",\n \"-q\": \"-Queries\",\n \"-m\": \"-MaxHops\",\n },\n forceArgs: true,\n};\n\nconst IFCONFIG_MAPPING: CommandMapping = {\n unix: \"ifconfig\",\n ps: \"Get-NetAdapter | Format-Table Name, Status, LinkSpeed, MacAddress -AutoSize\",\n flagMap: {\n \"-a\": \"-All\",\n \"-s\": \"-Statistics\",\n \"-u\": \"-Up\",\n \"-d\": \"-Down\",\n },\n forceArgs: false,\n};\n\n// Process Management\nconst PKILL_MAPPING: CommandMapping = {\n unix: \"pkill\",\n ps: \"Get-Process | Where-Object {$_.ProcessName -like\",\n flagMap: {\n \"signal\": \"-Signal\",\n \"exact\": \"-Exact\",\n \"full\": \"-Full\",\n },\n forceArgs: true,\n};\n\nconst PGREP_MAPPING: CommandMapping = {\n unix: \"pgrep\",\n ps: \"Get-Process | Where-Object {$_.ProcessName -like\",\n flagMap: {\n \"list\": \"-List\",\n \"full\": \"-Full\",\n \"exact\": \"-Exact\",\n },\n forceArgs: true,\n};\n\nconst KILLALL_MAPPING: CommandMapping = {\n unix: \"killall\",\n ps: \"Get-Process | Where-Object {$_.ProcessName -eq\",\n flagMap: {\n \"signal\": \"-Signal\",\n \"exact\": \"-Exact\",\n \"interactive\": \"-Interactive\",\n },\n forceArgs: true,\n};\n\nconst RENICE_MAPPING: CommandMapping = {\n unix: \"renice\",\n ps: \"Set-ProcessPriority\",\n flagMap: {\n \"priority\": \"-Priority\",\n \"pid\": \"-Id\",\n },\n forceArgs: true,\n};\n\n// File System Tools - mount and umount are system-specific and should not be translated\n\n// System Monitoring\nconst IOSTAT_MAPPING: CommandMapping = {\n unix: \"iostat\",\n ps: \"Get-Counter '\\\\PhysicalDisk(*)\\\\% Disk Time' | Select-Object -ExpandProperty CounterSamples | Format-Table InstanceName, CookedValue -AutoSize\",\n flagMap: {\n \"interval\": \"-Interval\",\n \"count\": \"-Count\",\n \"all\": \"-All\",\n },\n forceArgs: false,\n};\n\nconst VMSTAT_MAPPING: CommandMapping = {\n unix: \"vmstat\",\n ps: \"Get-Counter '\\\\Memory\\\\*' | Select-Object -ExpandProperty CounterSamples | Format-Table InstanceName, CookedValue -AutoSize\",\n flagMap: {\n \"interval\": \"-Interval\",\n \"count\": \"-Count\",\n \"all\": \"-All\",\n },\n forceArgs: false,\n};\n\nconst SAR_MAPPING: CommandMapping = {\n unix: \"sar\",\n ps: \"Get-Counter '\\\\Processor(_Total)\\\\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Format-Table InstanceName, CookedValue, Timestamp -AutoSize\",\n flagMap: {\n \"interval\": \"-Interval\",\n \"count\": \"-Count\",\n \"all\": \"-All\",\n },\n forceArgs: false,\n};\n\n// Package Management\nconst PIP_MAPPING: CommandMapping = {\n unix: \"pip\",\n ps: \"pip\",\n flagMap: {\n \"install\": \"install\",\n \"uninstall\": \"uninstall\",\n \"list\": \"list\",\n \"show\": \"show\",\n \"freeze\": \"freeze\",\n },\n forceArgs: false,\n};\n\nconst NPM_MAPPING: CommandMapping = {\n unix: \"npm\",\n ps: \"npm\",\n flagMap: {\n \"install\": \"install\",\n \"uninstall\": \"uninstall\",\n \"update\": \"update\",\n \"run\": \"run\",\n \"test\": \"test\",\n \"build\": \"build\",\n },\n forceArgs: false,\n};\n\nconst YARN_MAPPING: CommandMapping = {\n unix: \"yarn\",\n ps: \"yarn\",\n flagMap: {\n \"install\": \"install\",\n \"add\": \"add\",\n \"remove\": \"remove\",\n \"run\": \"run\",\n \"test\": \"test\",\n \"build\": \"build\",\n },\n forceArgs: false,\n};\n\nconst CARGO_MAPPING: CommandMapping = {\n unix: \"cargo\",\n ps: \"cargo\",\n flagMap: {\n \"build\": \"build\",\n \"run\": \"run\",\n \"test\": \"test\",\n \"check\": \"check\",\n \"clean\": \"clean\",\n \"update\": \"update\",\n },\n forceArgs: false,\n};\n\n// Development Tools\nconst CMAKE_MAPPING: CommandMapping = {\n unix: \"cmake\",\n ps: \"cmake\",\n flagMap: {\n \"build\": \"--build\",\n \"configure\": \"--configure\",\n \"install\": \"--install\",\n \"test\": \"--test\",\n },\n forceArgs: false,\n};\n\n// Additional System & Network Commands\nconst ROUTE_MAPPING: CommandMapping = {\n unix: \"route\",\n ps: \"Get-NetRoute | Format-Table DestinationPrefix, NextHop, RouteMetric, InterfaceAlias -AutoSize\",\n flagMap: {\n \"-n\": \"-NoResolve\",\n \"-e\": \"-Extended\",\n \"-v\": \"-Verbose\",\n \"-A\": \"-AddressFamily\",\n },\n forceArgs: false,\n};\n\nconst IWCONFIG_MAPPING: CommandMapping = {\n unix: \"iwconfig\",\n ps: \"Get-NetAdapter | Where-Object {$_.InterfaceDescription -like '*Wireless*'} | Select-Object Name, InterfaceDescription, Status, LinkSpeed\",\n flagMap: {\n \"all\": \"-All\",\n \"up\": \"-Status Up\",\n \"down\": \"-Status Down\",\n },\n forceArgs: false,\n};\n\nconst IWSCAN_MAPPING: CommandMapping = {\n unix: \"iwlist\",\n ps: \"netsh wlan show networks\",\n flagMap: {\n \"scan\": \"show networks\",\n \"essid\": \"show networks\",\n \"channel\": \"show networks\",\n },\n forceArgs: false,\n};\n\n// File System & Archive Commands\nconst ZIP_MAPPING: CommandMapping = {\n unix: \"zip\",\n ps: \"Compress-Archive\",\n flagMap: {\n \"r\": \"-Recurse\",\n \"f\": \"-Force\",\n \"u\": \"-Update\",\n \"d\": \"-DestinationPath\",\n },\n forceArgs: true,\n};\n\nconst UNZIP_MAPPING: CommandMapping = {\n unix: \"unzip\",\n ps: \"Expand-Archive\",\n flagMap: {\n \"l\": \"-ListOnly\",\n \"o\": \"-Force\",\n \"d\": \"-DestinationPath\",\n \"q\": \"-Quiet\",\n },\n forceArgs: true,\n};\n\n// Process & System Monitoring\nconst LSOF_MAPPING: CommandMapping = {\n unix: \"lsof\",\n ps: \"Get-Process | ForEach-Object { Get-NetTCPConnection | Where-Object {$_.OwningProcess -eq $_.Id} } | Format-Table LocalAddress, LocalPort, RemoteAddress, RemotePort, State, OwningProcess -AutoSize\",\n flagMap: {\n \"-i\": \"-Internet\",\n \"-p\": \"-Process\",\n \"-u\": \"-User\",\n \"-c\": \"-Command\",\n },\n forceArgs: false,\n};\n\nconst STrace_MAPPING: CommandMapping = {\n unix: \"strace\",\n ps: \"Get-Process | ForEach-Object { Write-Host \\\"Process: $($_.ProcessName) (PID: $($_.Id))\\\" }\",\n flagMap: {\n \"-p\": \"-ProcessId\",\n \"-e\": \"-Event\",\n \"-o\": \"-Output\",\n \"-f\": \"-Follow\",\n },\n forceArgs: true,\n};\n\n// Text Processing & Search\nconst LOCATE_MAPPING: CommandMapping = {\n unix: \"locate\",\n ps: \"Get-ChildItem -Recurse | Where-Object {$_.Name -like $args[0]} | Select-Object FullName\",\n flagMap: {\n \"-i\": \"-CaseInsensitive\",\n \"-n\": \"-Limit\",\n \"-r\": \"-Regex\",\n \"-q\": \"-Quiet\",\n },\n forceArgs: true,\n};\n\nconst UPDATEDB_MAPPING: CommandMapping = {\n unix: \"updatedb\",\n ps: \"Get-ChildItem -Recurse | ForEach-Object { $_.FullName } | Out-File -FilePath $env:TEMP\\\\locate.db -Encoding UTF8\",\n flagMap: {\n \"-o\": \"-Output\",\n \"-l\": \"-Local\",\n \"-U\": \"-Update\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: false,\n};\n\n// Network & Connectivity\nconst TRACEPATH_MAPPING: CommandMapping = {\n unix: \"tracepath\",\n ps: \"Test-NetConnection -TraceRoute -InformationLevel Detailed\",\n flagMap: {\n \"-n\": \"-NoResolve\",\n \"-b\": \"-Bind\",\n \"-m\": \"-MaxHops\",\n \"-l\": \"-Local\",\n },\n forceArgs: true,\n};\n\nconst MTR_MAPPING: CommandMapping = {\n unix: \"mtr\",\n ps: \"Test-NetConnection -TraceRoute -InformationLevel Detailed | ForEach-Object { Write-Host \\\"Hop $($_.Hop): $($_.Address) - $($_.ResponseTime)ms\\\" }\",\n flagMap: {\n \"-n\": \"-NoResolve\",\n \"-r\": \"-Report\",\n \"-c\": \"-Count\",\n \"-i\": \"-Interval\",\n },\n forceArgs: true,\n};\n\n// File System & Archives\nconst BZIP2_MAPPING: CommandMapping = {\n unix: \"bzip2\",\n ps: \"Compress-Archive -CompressionLevel Optimal\",\n flagMap: {\n \"-d\": \"-Decompress\",\n \"-k\": \"-Keep\",\n \"-f\": \"-Force\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: true,\n};\n\nconst BUNZIP2_MAPPING: CommandMapping = {\n unix: \"bunzip2\",\n ps: \"Expand-Archive\",\n flagMap: {\n \"-k\": \"-Keep\",\n \"-f\": \"-Force\",\n \"-v\": \"-Verbose\",\n \"-t\": \"-Test\",\n },\n forceArgs: true,\n};\n\n// Text Processing\nconst WC_MAPPING: CommandMapping = {\n unix: \"wc\",\n ps: \"Measure-Object\",\n flagMap: {\n \"-l\": \"-Line\",\n \"-w\": \"-Word\",\n \"-c\": \"-Character\",\n \"-m\": \"-Character\",\n \"-L\": \"-Maximum\",\n },\n forceArgs: false,\n};\n\nconst HEAD_MAPPING: CommandMapping = {\n unix: \"head\",\n ps: \"Get-Content | Select-Object -First\",\n flagMap: {\n \"-n\": \"-First\",\n \"-c\": \"-TotalCount\",\n \"-q\": \"-Quiet\",\n \"-v\": \"-Verbose\",\n },\n forceArgs: true,\n};\n\nconst TAIL_MAPPING: CommandMapping = {\n unix: \"tail\",\n ps: \"Get-Content | Select-Object -Last\",\n flagMap: {\n \"-n\": \"-Last\",\n \"-c\": \"-TotalCount\",\n \"-f\": \"-Wait\",\n \"-q\": \"-Quiet\",\n },\n forceArgs: true,\n};\n\n// System Information\nconst LSB_RELEASE_MAPPING: CommandMapping = {\n unix: \"lsb_release\",\n ps: \"Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, WindowsBuildLabEx\",\n flagMap: {\n \"a\": \"-All\",\n \"d\": \"-Description\",\n \"r\": \"-Release\",\n \"c\": \"-Codename\",\n },\n forceArgs: false,\n};\n\nconst DMESG_MAPPING: CommandMapping =