🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

xtrans

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

xtrans - npm Package Compare versions

Comparing version
1.0.0
to
1.0.1
+6
-1
dist/commands/translate.js

@@ -8,3 +8,3 @@ import { Command, Args } from '@oclif/core';

import ora from 'ora';
import { startRepl, handleUseCommand } from '../ui/repl.js';
import { startRepl, handleUseCommand, handleCommand } from '../ui/repl.js';
import { confirm } from '@inquirer/prompts';

@@ -26,2 +26,7 @@ export default class Main extends Command {

}
// Direct command execution (e.g. "t /target en" or "t /status")
if (inputText.startsWith('/')) {
await handleCommand(inputText, configService);
return;
}
const spinner = ora('Translating...').start();

@@ -28,0 +33,0 @@ try {

+5
-5

@@ -32,7 +32,2 @@ import Conf from 'conf';

},
'openai': {
type: 'openai',
model: 'gpt-4o',
apiKey: '',
},
'lmstudio': {

@@ -44,2 +39,7 @@ type: 'lmstudio',

},
'openai': {
type: 'openai',
model: 'gpt-4o',
apiKey: '',
},
'deepseek': {

@@ -46,0 +46,0 @@ type: 'deepseek',

import { ConfigService } from '../services/config.js';
export declare function startRepl(configService: ConfigService, version: string): Promise<void>;
export declare function handleCommand(cmd: string, configService: ConfigService): Promise<boolean>;
export declare function handleUseCommand(configService: ConfigService): Promise<void>;

@@ -10,5 +10,3 @@ import chalk from 'chalk';

let lastWord = "";
export async function startRepl(configService, version) {
const historyService = new HistoryService();
console.log(chalk.cyan(`Welcome to xtrans v${version}`));
function printHeader(configService) {
const config = configService.config;

@@ -20,2 +18,7 @@ const currentProvider = configService.getCurrentService();

}
}
export async function startRepl(configService, version) {
const historyService = new HistoryService();
console.log(chalk.cyan(`Welcome to xtrans v${version}`));
printHeader(configService);
console.log(chalk.dim('Type "/" to open menu. Start typing to translate.\n'));

@@ -28,3 +31,3 @@ // Custom Input Loop with TTY handling

// 2. Read input manually to catch '/'
const line = await readLineOrCommand();
const line = await readLineOrCommand(historyService.getHistory());
if (!line)

@@ -49,3 +52,3 @@ continue; // Empty line

*/
function readLineOrCommand() {
function readLineOrCommand(history = []) {
return new Promise((resolve) => {

@@ -57,2 +60,4 @@ const { stdin, stdout } = process;

let buffer = '';
let historyIndex = -1;
let tempBuffer = ''; // Stores current typing when moving up into history
const onData = async (key) => {

@@ -74,2 +79,37 @@ // Ctrl+C (ETX)

}
// Up Arrow
if (key === '\u001b[A') {
if (history.length > 0 && historyIndex < history.length - 1) {
if (historyIndex === -1)
tempBuffer = buffer;
historyIndex++;
buffer = history[historyIndex];
// Redraw line
stdout.clearLine(0);
stdout.cursorTo(0);
stdout.write(chalk.cyan('› ') + buffer);
}
return;
}
// Down Arrow
if (key === '\u001b[B') {
if (historyIndex > -1) {
historyIndex--;
if (historyIndex === -1) {
buffer = tempBuffer;
}
else {
buffer = history[historyIndex];
}
// Redraw line
stdout.clearLine(0);
stdout.cursorTo(0);
stdout.write(chalk.cyan('› ') + buffer);
}
return;
}
// Left/Right Arrow - Ignore for now to prevent corruption
if (key === '\u001b[C' || key === '\u001b[D') {
return;
}
// Backspace (DEL)

@@ -148,3 +188,3 @@ if (key === '\x7f') {

}
async function handleCommand(cmd, configService) {
export async function handleCommand(cmd, configService) {
const [command, arg] = cmd.split(' ');

@@ -392,3 +432,7 @@ switch (command) {

const services = configService.listServices();
console.log(chalk.bold('\nServices Status:'));
const currentService = configService.config.current;
// Use the standard header format
console.log(''); // Spacing
printHeader(configService);
console.log(chalk.bold('\nServices Availability:'));
for (const [name, config] of Object.entries(services)) {

@@ -398,6 +442,15 @@ const provider = ProviderFactory.create(name, config);

const isHealthy = await provider.checkHealth();
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
if (process.stdout.isTTY) {
process.stdout.clearLine(0);
process.stdout.cursorTo(0);
}
else {
process.stdout.write('\n');
}
const status = isHealthy ? chalk.green('● Online') : chalk.red('○ Offline');
console.log(` ${name}: ${status}`);
const isActive = name === currentService ? chalk.blue(' (active)') : '';
// We don't need to duplicate model info here since it's in the header for the *current* one
// But for others, maybe we just show status?
// Let's keep it minimal as requested.
console.log(` ${name}: ${status}${isActive}`);
}

@@ -404,0 +457,0 @@ console.log('');

@@ -31,3 +31,3 @@ {

},
"version": "1.0.0"
"version": "1.0.1"
}
{
"name": "xtrans",
"description": "Minimalist AI-powered terminal translator / 极简 AI 终端翻译工具",
"version": "1.0.0",
"version": "1.0.1",
"author": "wengqianshan",

@@ -6,0 +6,0 @@ "bin": {

+66
-31

@@ -1,6 +0,8 @@

# xtrans (Open Translate)
# xtrans
Minimalist AI-powered terminal translator.
极简 AI 终端翻译工具。
极简主义的 AI 终端翻译工具。
支持本地大模型 (Ollama, LM Studio) 与主流在线 API。
**中文** | [English](README_EN.md)
[![Version](https://img.shields.io/npm/v/xtrans.svg)](https://npmjs.org/package/xtrans)

@@ -10,11 +12,11 @@ [![Downloads/week](https://img.shields.io/npm/dw/xtrans.svg)](https://npmjs.org/package/xtrans)

## Features
## 核心亮点
- **Minimalist**: Just type `xtrans <text>` (or alias `t`) to translate.
- **AI-Powered**: Uses OpenAI's GPT models for accurate and context-aware translations.
- **Interactive Mode**: Enter a REPL mode for continuous translation.
- **Stream Output**: Real-time translation streaming.
- **Configuration**: Easy setup with your API key.
- 🔒 **本地模型支持**: 完美支持 **Ollama** 和 **LM Studio**。无需联网,保护隐私。
- 🌍 **多服务商**: 内置 **OpenAI**, **DeepSeek**, **Kimi (Moonshot)** 以及 **Ollama/LM Studio** 支持。
- 🛠 **高度可扩展**: 轻松添加任何兼容 **OpenAI 格式** 的 API 服务。
- 🤖 **自动发现**: 自动获取服务商的模型列表(例如读取你的 `ollama list`)。
- ⚡ **极简体验**: 仅需输入 `t <text>` 即可快速翻译,或进入交互模式连续使用。
## Installation
## 安装

@@ -25,3 +27,3 @@ ```bash

Or run directly with npx:
或者使用 npx 直接运行:

@@ -32,37 +34,70 @@ ```bash

## Usage
## 使用指南
### Quick Translation
### 1. 快速翻译
使用别名 `t` (或 `xtrans`) 进行即时翻译。
### Quick Translation
Use `xtrans` followed by the text you want to translate. You can also use the shorter alias `t`.
```bash
xtrans hello world
# or alias
t hello world
t hello
# ┌───────────────────────────────────────────────────┐
# │ hello /həˈləʊ/ int. n. │
# │ │
# │ int. │
# │ • 你好 (用于问候、接电话或引起注意) │
# │ - Hello, Paul. I haven't seen you for ages. │
# │ │
# │ n. │
# │ • (Hello) 人名;(法)埃洛 │
# │ │
# │ Synonyms: hi, greetings │
# └───────────────────────────────────────────────────┘
```
### Interactive Mode
### 2. 交互模式 (REPL)
不带参数运行即可进入交互式 shell。支持上下键 (↑/↓) 切换历史记录。
Run without arguments to enter interactive mode.
```bash
xtrans
# > Enter text to translate...
# Welcome to xtrans v1.0.0
# Provider: ollama | Model: llama3 | Target: zh
# ›
```
### Help
### 3. 管理命令
你可以在交互模式内 (输入 `/`) 或直接从终端运行这些命令。
| 命令 | 说明 | 示例 |
|---------|-------------|---------|
| `/use` | 切换服务商或模型 (交互式) | `t /use` |
| `/target` | 设置目标语言 | `t /target ja` |
| `/status` | 检查服务状态及当前模型 | `t /status` |
| `/add` | 添加自定义 OpenAI 兼容服务商 | `t /add` |
| `/remove` | 移除服务商 | `t /remove` |
| `/clean` | 清理历史记录/缓存 | `t /clean` |
## 支持的服务商
xtrans 为主流服务预设了配置模板:
### 🏠 本地 (隐私优先)
- **Ollama**: 默认地址 `http://localhost:11434`。支持自动检测已安装模型。
- **LM Studio**: 默认地址 `http://localhost:1234/v1`。
### ☁️ 云端 API
- **OpenAI**: 标准支持。
- **DeepSeek**: 深度求索 API 支持。
- **Kimi (Moonshot)**: 月之暗面支持。
- **Custom (自定义)**: 添加任何支持 OpenAI Chat Completion 格式的服务。
## 配置
首次运行时,xtrans 会引导你设置首选服务商。你可以随时使用 `t /use` 进行切换。
如需添加自定义服务商(例如本地服务器或其他 API):
```bash
xtrans --help
t /add
```
## Configuration
## 许可证
On first run, the tool will prompt you for your OpenAI API Key and preferred model. Models can be configured via interactive prompts or config files.
## License
MIT