diff --git a/README.md b/README.md index 255ac1f..f3ba598 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,23 @@ [![npm version](https://badge.fury.io/js/veniceai-cli.svg)](https://www.npmjs.com/package/veniceai-cli) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -The official command-line interface for [Venice AI](https://venice.ai). Chat with AI models, generate images, convert text to speech, transcribe audio, and moreβ€”all from your terminal. +The official command-line interface for [Venice AI](https://venice.ai). Chat with AI models, generate images, convert text to speech, transcribe audio, and more β€” all from your terminal. Full codebase context, agentic file tools, and an interactive REPL make it as capable as GitHub Copilot CLI and Gemini CLI. ## Installation +### Termux (Android) β€” one-liner + +```bash +curl -fsSL https://raw.githubusercontent.com/DUptain1993/venice-cli/main/install.sh | sh +``` + +The installer automatically: +- Detects Termux and installs Node.js via `pkg` if needed +- Fixes npm global prefix to `$PREFIX` +- Adds `$PREFIX/bin` to your PATH + +### Linux / macOS + ```bash npm install -g veniceai-cli ``` @@ -23,13 +36,16 @@ npx veniceai-cli chat 'Hello, world!' 1. **Get your API key** from [Venice AI Settings](https://venice.ai/settings/api) -2. **Configure the CLI**: +2. **Run the setup wizard**: ```bash - venice config set api_key YOUR_API_KEY + venice setup ``` - - Or use an environment variable: + This tests your connection, shows your available models by number, and saves everything to `~/.venice/config.json`. + + Or set the key manually: ```bash + venice config set api_key YOUR_API_KEY + # or via env var: export VENICE_API_KEY=YOUR_API_KEY ``` @@ -38,9 +54,19 @@ npx veniceai-cli chat 'Hello, world!' venice chat "What is the meaning of life?" ``` +4. **Launch the interactive REPL** for a full session with file tools: + ```bash + venice repl + ``` + ## Features - πŸ€– **Chat** with state-of-the-art AI models +- πŸ–₯️ **Interactive REPL** with persistent conversation and file tools +- πŸ“ **Full Codebase Context** β€” load your entire project into AI context +- πŸ”§ **Agentic File Tools** β€” read, write, edit, search, delete files and run shell commands +- πŸ’‘ **Shell Suggestions** β€” describe a task, get the right command (Termux-aware) +- πŸ“± **Termux Native** β€” plug-and-play on Android with one-liner install - πŸ” **End-to-End Encryption (E2EE)** for maximum privacy - πŸ›‘οΈ **TEE Attestation** verification for trusted execution - πŸ” **Web Search** with AI-powered synthesis @@ -49,7 +75,6 @@ npx veniceai-cli chat 'Hello, world!' - 🎀 **Speech-to-Text** transcription with timestamps - 🎬 **Video Generation** (text-to-video, image-to-video) - πŸ“ **Embeddings** generation -- πŸ”§ **Function Calling** with built-in tools - 🎭 **Character Personas** for fun interactions - πŸ’Ύ **Conversation History** with continue mode - πŸ“Š **Usage Tracking** for token monitoring @@ -81,8 +106,26 @@ venice chat -t calculator,weather "What's 25 * 4.5?" # JSON output for scripting venice chat -f json "List 3 colors" | jq '.content' -# Disable streaming -venice chat --no-stream "Quick question" +# ── Codebase & file context ────────────────────────────────────────────────── + +# Load your entire project into context +venice chat --codebase "Summarize this codebase and identify potential improvements" + +# Load context from a specific directory +venice chat --codebase ./src "Explain the architecture of the source files" + +# Load specific files +venice chat --file src/index.ts src/lib/api.ts "What does this code do?" + +# ── Agent mode (AI can read/write/run files) ───────────────────────────────── + +# Enable file + shell tools +venice chat --agent "Find all TODO comments in the codebase and create a summary" + +# Skip confirmation prompts +venice chat --agent --auto-approve "Fix the TypeScript errors in src/commands/chat.ts" + +# ── Privacy & encryption ───────────────────────────────────────────────────── # E2EE encrypted chat (auto-enabled based on model capabilities) venice chat -m e2ee-qwen3-5-122b-a10b "This message is end-to-end encrypted" @@ -113,12 +156,138 @@ venice chat -m e2ee-qwen3-5-122b-a10b -q "This is encrypted but looks like norma | `--strip-thinking` | Strip thinking blocks from response | | `--no-venice-prompt` | Disable Venice system prompts | | `--search-results-in-stream` | Include search results in stream | +| `--file ` | Load specific files into context | +| `--codebase [dir]` | Load entire codebase into context | +| `--codebase-tokens ` | Token budget for codebase (default: 80000) | +| `--agent` | Enable all file + shell tools | +| `--auto-approve` | Auto-approve all tool calls without prompting | | `--e2ee` | Enable E2EE encryption (auto-enabled for models with E2EE capability) | -| `--no-e2ee` | Disable E2EE, use TEE-only mode (verifies attestation without encryption) | +| `--no-e2ee` | Disable E2EE, use TEE-only mode | | `--tee-verify` | Show TEE attestation details | | `-q, --quiet` | Hide E2EE/TEE status messages (show only response) | | `-f, --format ` | Output format (pretty\|json\|markdown\|raw) | +--- + +### REPL (Interactive Session) + +The REPL provides a persistent, multi-turn conversation with full file system access β€” like having a coding assistant always available. + +```bash +# Start the REPL +venice repl + +# Start with a model +venice repl -m llama-3.3-70b + +# Load your project into context at startup +venice repl --codebase + +# Load a specific directory +venice repl --codebase --codebase-dir ./src + +# Skip tool approval prompts +venice repl --auto-approve +``` + +**Slash commands inside the REPL:** + +| Command | Description | +|---------|-------------| +| `/help` | Show all available commands | +| `/exit` or `/quit` | Exit the REPL | +| `/clear` | Clear conversation history (keep context) | +| `/model [name]` | Show current model or switch to a new one | +| `/files [dir]` | Load codebase from a directory into context | +| `/file ` | Load a specific file into context | +| `/tools [on\|off]` | List tools or enable/disable them | +| `/approve` | Toggle auto-approve for tool calls | +| `/history` | Show recent conversation messages | +| `/save [filename]` | Save conversation to a JSON file | + +**Example session:** + +``` +venice> /files ./src +βœ“ Loaded 12 files (~8400 tokens) + +venice> what does the chat command do? +The chat command handles... [AI explains] + +venice> /model llama-3.3-70b +Model switched to: llama-3.3-70b + +venice> write a test for the config module +[AI writes the test, calling write_file with your approval] + +venice> /exit +Goodbye! +``` + +**Options:** + +| Option | Description | +|--------|-------------| +| `-m, --model ` | Model to use | +| `-s, --system ` | Additional system prompt | +| `--codebase` | Load codebase into context at startup | +| `--codebase-dir ` | Directory for codebase context | +| `--auto-approve` | Auto-approve all tool calls | +| `--max-tokens ` | Token budget for codebase context | +| `--no-tools` | Disable file system and shell tools | +| `-t, --tools ` | Additional tools to enable | + +--- + +### Shell Suggestions + +Get shell commands by describing what you want β€” Termux-aware, platform-specific. + +```bash +# Get a shell command suggestion +venice suggest "recursively find all TypeScript files modified today" + +# Termux-specific suggestions +venice suggest "install the requests library" --platform termux +# β†’ pkg install python && pip install requests + +# Run the suggested command immediately +venice suggest "show disk usage sorted by size" --execute + +# Target a specific shell +venice suggest "loop over all JSON files" --shell zsh +``` + +**Options:** + +| Option | Description | +|--------|-------------| +| `-m, --model ` | Model to use | +| `--shell ` | Target shell: bash, zsh, fish, sh | +| `--platform ` | Target platform: linux, macos, termux | +| `--execute` | Run the suggested command after confirmation | + +--- + +### Setup Wizard + +First-time setup with live model selection: + +```bash +venice setup +# or equivalently: +venice config init +``` + +The wizard: +1. Prompts for your API key and tests the connection +2. Fetches your available models and shows a numbered list to pick from +3. Sets your default image model +4. Configures preferences (usage display, colors) +5. Prints quick-start commands + +--- + ### Web Search ```bash @@ -300,7 +469,10 @@ venice embeddings -o vectors.json "Text to embed" ### Configuration ```bash -# Interactive setup +# Recommended: interactive setup wizard +venice setup + +# Or: interactive setup via config subcommand venice config init # Show current config @@ -332,6 +504,9 @@ venice config path | `output_format` | Default output format | | `no_color` | Disable colored output | | `show_usage` | Show token usage after requests | +| `auto_approve` | Auto-approve tool calls without prompting | +| `max_context_tokens` | Token budget for `--codebase` (default: 80000) | +| `shell` | Preferred shell for `venice suggest` | ### Conversation History @@ -397,9 +572,11 @@ venice completions zsh >> ~/.zshrc venice completions fish > ~/.config/fish/completions/venice.fish ``` +--- + ## Built-in Tools -The CLI includes several built-in tools for function calling: +The CLI includes built-in tools for function calling. Use them with `--tools` or enable all file/shell tools at once with `--agent`. | Tool | Description | |------|-------------| @@ -409,16 +586,36 @@ The CLI includes several built-in tools for function calling: | `random` | Random number/choice generation | | `base64` | Base64 encoding/decoding | | `hash` | Hash generation (md5, sha256, etc.) | +| `read_file` | Read file contents (supports offset/limit, max 1MB) | +| `write_file` | Write or overwrite a file (creates parent dirs) | +| `list_files` | List directory recursively with glob filter | +| `search_files` | Regex search across files, returns file + line + match | +| `delete_file` | Delete a file (requires `confirm: true`) | +| `run_shell` | Execute a shell command, returns stdout/stderr/exit code | + +> **Safety:** `write_file`, `delete_file`, and `run_shell` always prompt for approval unless `--auto-approve` is set. ```bash -# Use tools +# Use individual tools venice chat -t calculator "What's the square root of 144?" venice chat -t datetime "What day is it today?" -# Interactive tool approval +# Approve each tool call interactively venice chat --interactive-tools -t calculator "Calculate 15% tip on $85" + +# Agent mode: enable all file + shell tools +venice chat --agent "Find all TODO comments and create a TASKS.md" + +# Agent mode with auto-approve (no prompts) +venice chat --agent --auto-approve "Add JSDoc comments to all exported functions in src/lib/" + +# Load the codebase and ask questions +venice chat --codebase "What is the entry point of this application?" +venice chat --codebase ./src "Which files would I need to change to add a new command?" ``` +--- + ## Output Formats | Format | Description | Use Case | @@ -438,15 +635,49 @@ venice chat -f json "List items" | jq '.' venice chat "Generate code" | pbcopy ``` +--- + +## Termux (Android) + +Venice CLI runs natively on Android via [Termux](https://termux.dev) with no extra configuration needed. + +```bash +# One-liner install (installs Node.js via pkg if needed): +curl -fsSL https://raw.githubusercontent.com/DUptain1993/venice-cli/main/install.sh | sh + +# First-time setup: +venice setup + +# Start an interactive session with file tools: +venice repl +``` + +The installer handles: +- Detecting Termux and running `pkg install nodejs` if Node.js is missing +- Setting the npm global prefix to `$PREFIX` so `venice` is in your PATH +- Adding `$PREFIX/bin` to `~/.bashrc` and `~/.profile` if needed + +**Termux-aware suggestions:** `venice suggest` automatically detects Termux and produces Android-appropriate commands: + +```bash +venice suggest "install python" +# β†’ pkg install python + +venice suggest "update all packages" +# β†’ pkg update && pkg upgrade +``` + +--- + ## Privacy Venice CLI is designed with privacy in mind: -- **End-to-End Encryption (E2EE)**: Messages encrypted client-side, decrypted only in the TEEβ€”Venice cannot read your data +- **End-to-End Encryption (E2EE)**: Messages encrypted client-side, decrypted only in the TEE β€” Venice cannot read your data - **TEE Attestation**: Cryptographically verify that models run in secure enclaves before sending data - **No browser tracking**: Terminal interactions don't expose browser metadata - **No telemetry**: The CLI doesn't collect or send usage data -- **Local configuration**: API key stored locally with restricted permissions +- **Local configuration**: API key stored locally with restricted permissions (mode `0o600`) - **Transparent**: You can see exactly what's being sent to the API - **Privacy-preserving models**: Use `venice models --privacy` to find models with no data retention @@ -485,6 +716,8 @@ venice models --tee venice chat -m "Verified secure execution" ``` +--- + ## Environment Variables | Variable | Description | @@ -492,10 +725,14 @@ venice chat -m "Verified secure execution" | `VENICE_API_KEY` | API key (overrides config file) | | `NO_COLOR` | Disable colored output | +--- + ## Requirements - Node.js 18.0.0 or higher -- A Venice AI API key +- A Venice AI API key ([get one here](https://venice.ai/settings/api)) + +--- ## Development @@ -512,6 +749,9 @@ npm run build # Run locally npm run dev -- chat "Hello" + +# Run the REPL locally +npm run dev -- repl ``` ## Contributing diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..ecb68c8 --- /dev/null +++ b/install.sh @@ -0,0 +1,149 @@ +#!/bin/sh +# Venice CLI β€” Termux-Native Install Script +# Usage: curl -fsSL https://raw.githubusercontent.com/DUptain1993/venice-cli/main/install.sh | sh +# Or: sh install.sh + +set -e + +REPO_URL="https://github.com/DUptain1993/venice-cli.git" +BRANCH="main" +BIN_NAME="venice" + +log() { printf '\033[1;34m[venice]\033[0m %s\n' "$*"; } +ok() { printf '\033[1;32m[venice]\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33m[venice]\033[0m %s\n' "$*"; } +die() { printf '\033[1;31m[venice]\033[0m %s\n' "$*" >&2; exit 1; } + +is_termux() { + [ -n "$PREFIX" ] && echo "$PREFIX" | grep -q 'com.termux' +} + +check_node() { + if ! command -v node >/dev/null 2>&1; then + return 1 + fi + NODE_VERSION=$(node -e "process.stdout.write(process.versions.node)" 2>/dev/null || echo "0.0.0") + MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1) + [ "$MAJOR" -ge 18 ] +} + +# ── Install Node.js if missing ─────────────────────────────────────────────── + +if is_termux; then + log "Termux detected (Android native environment)" + + if ! check_node; then + log "Installing Node.js via pkg..." + pkg update -y 2>/dev/null || true + pkg install nodejs -y || die "Failed to install Node.js. Run: pkg install nodejs" + fi + + NODE_VERSION=$(node --version) + ok "Node.js $NODE_VERSION ready" + + CURRENT_PREFIX=$(npm config get prefix 2>/dev/null || echo "") + if [ "$CURRENT_PREFIX" != "$PREFIX" ]; then + log "Setting npm global prefix to \$PREFIX ($PREFIX)..." + npm config set prefix "$PREFIX" + fi + +else + log "Standard Linux/macOS environment" + + if ! check_node; then + die "Node.js 18+ is required but not found. +Install it from: https://nodejs.org +Or via nvm: https://github.com/nvm-sh/nvm" + fi + + NODE_VERSION=$(node --version) + ok "Node.js $NODE_VERSION ready" +fi + +# ── Ensure git is available ────────────────────────────────────────────────── + +if ! command -v git >/dev/null 2>&1; then + if is_termux; then + log "Installing git via pkg..." + pkg install git -y || die "Failed to install git. Run: pkg install git" + else + die "git is required but not found. Install it and try again." + fi +fi + +# ── Clone and build from GitHub ────────────────────────────────────────────── + +INSTALL_SRC="$HOME/.venice-cli-src" + +if [ -d "$INSTALL_SRC/.git" ]; then + log "Updating existing source in $INSTALL_SRC..." + git -C "$INSTALL_SRC" fetch --depth=1 origin "$BRANCH" 2>&1 | grep -v '^$' || true + git -C "$INSTALL_SRC" reset --hard "origin/$BRANCH" 2>&1 | grep -v '^$' || true +else + log "Cloning venice CLI from GitHub..." + rm -rf "$INSTALL_SRC" + git clone --depth=1 --branch "$BRANCH" "$REPO_URL" "$INSTALL_SRC" 2>&1 | grep -v '^$' || \ + die "Failed to clone repository. Check your internet connection." +fi + +log "Installing dependencies and building..." +cd "$INSTALL_SRC" +npm install --prefer-offline 2>&1 | tail -3 || npm install 2>&1 | tail -3 || \ + die "npm install failed. Check your internet connection." + +npm run build 2>&1 | tail -3 || die "Build failed." + +# ── Install venice CLI globally ────────────────────────────────────────────── + +log "Installing venice globally..." + +if is_termux; then + npm install -g . --prefix "$PREFIX" 2>&1 | tail -3 || { + warn "Retrying with --unsafe-perm..." + npm install -g . --prefix "$PREFIX" --unsafe-perm 2>&1 | tail -3 || \ + die "Installation failed." + } +else + npm install -g . 2>&1 | tail -3 || { + warn "Trying with sudo..." + sudo npm install -g . 2>&1 | tail -3 || \ + die "Installation failed. Try: sudo npm install -g ." + } +fi + +# ── Verify installation ────────────────────────────────────────────────────── + +if command -v "$BIN_NAME" >/dev/null 2>&1; then + VERSION=$("$BIN_NAME" --version 2>/dev/null || echo "unknown") + ok "venice $VERSION installed successfully!" +elif is_termux && [ -x "$PREFIX/bin/$BIN_NAME" ]; then + warn "$BIN_NAME installed but not in PATH." + for RC in "$HOME/.bashrc" "$HOME/.profile" "$HOME/.zshrc"; do + if [ -f "$RC" ] || [ "$RC" = "$HOME/.bashrc" ]; then + if ! grep -q 'PREFIX/bin' "$RC" 2>/dev/null; then + printf '\nexport PATH="$PREFIX/bin:$PATH"\n' >> "$RC" + log "Updated $RC" + fi + fi + done + ok "Run: export PATH=\"\$PREFIX/bin:\$PATH\"" + ok "Or restart Termux to apply permanently." +else + die "Installation may have failed β€” 'venice' not found in PATH." +fi + +# ── Done ───────────────────────────────────────────────────────────────────── + +printf '\n' +ok "Installation complete!" +printf '\n' +printf ' Run \033[1;36mvenice setup\033[0m to configure your API key and get started.\n' +printf '\n' +printf ' Quick commands:\n' +printf ' \033[36mvenice setup\033[0m First-time configuration\n' +printf ' \033[36mvenice chat "Hello!"\033[0m Chat with AI\n' +printf ' \033[36mvenice repl\033[0m Interactive session\n' +printf ' \033[36mvenice suggest "list big files"\033[0m Shell command helper\n' +printf ' \033[36mvenice chat --codebase "review"\033[0m Full project context\n' +printf ' \033[36mvenice --help\033[0m See all commands\n' +printf '\n' diff --git a/package-lock.json b/package-lock.json index 42e7da0..9f55e3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,19 +1,16 @@ { "name": "veniceai-cli", - "version": "2.1.0", + "version": "2.3.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "veniceai-cli", - "version": "2.1.0", + "version": "2.3.0", "license": "MIT", "dependencies": { - "@noble/ciphers": "^1.3.0", - "@noble/hashes": "^1.8.0", "chalk": "^5.3.0", "commander": "^12.1.0", - "elliptic": "^6.6.1", "ora": "^8.0.1", "update-notifier": "^7.3.1" }, @@ -21,7 +18,6 @@ "venice": "dist/index.js" }, "devDependencies": { - "@types/elliptic": "^6.4.18", "@types/node": "^20.11.0", "@typescript-eslint/eslint-plugin": "^8.57.0", "@typescript-eslint/parser": "^8.57.0", @@ -634,30 +630,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", @@ -699,26 +671,6 @@ "node": ">=12" } }, - "node_modules/@types/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/elliptic": { - "version": "6.4.18", - "resolved": "https://registry.npmjs.org/@types/elliptic/-/elliptic-6.4.18.tgz", - "integrity": "sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bn.js": "*" - } - }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -1114,12 +1066,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, "node_modules/boxen": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", @@ -1155,12 +1101,6 @@ "node": "18 || 20 || >=22" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, "node_modules/camelcase": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", @@ -1331,21 +1271,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/emoji-regex": { "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", @@ -1735,27 +1660,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -1776,12 +1680,6 @@ "node": ">=0.8.19" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, "node_modules/ini": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz", @@ -2037,18 +1935,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "license": "ISC" - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, "node_modules/minimatch": { "version": "10.2.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", diff --git a/package.json b/package.json index 2a00fd8..09dd947 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,34 @@ { "name": "veniceai-cli", - "version": "2.1.0", - "description": "Privacy-first command line interface for Venice AI", + "version": "2.3.0", + "description": "Venice AI CLI β€” Termux-native chat, REPL, and shell suggestions", "type": "module", "main": "dist/index.js", "bin": { "venice": "dist/index.js" }, "scripts": { + "prepare": "npm run build", "build": "tsc", "dev": "tsx src/index.ts", "start": "node dist/index.js", - "test": "npm run build && node --test \"dist/**/*.test.js\"", "lint": "eslint \"src/**/*.ts\"", "clean": "node -e \"const fs = require('fs'); fs.rmSync('dist', { recursive: true, force: true });\"", "prepublishOnly": "npm run clean && npm run build" }, "files": [ "dist", - "examples", + "install.sh", "README.md", "LICENSE" ], "dependencies": { - "@noble/ciphers": "^1.3.0", - "@noble/hashes": "^1.8.0", "chalk": "^5.3.0", "commander": "^12.1.0", - "elliptic": "^6.6.1", "ora": "^8.0.1", "update-notifier": "^7.3.1" }, "devDependencies": { - "@types/elliptic": "^6.4.18", "@types/node": "^20.11.0", "@typescript-eslint/eslint-plugin": "^8.57.0", "@typescript-eslint/parser": "^8.57.0", @@ -48,21 +44,20 @@ "ai", "cli", "llm", - "openai", "chat", - "image-generation", - "text-to-speech", - "transcription", + "termux", + "android", + "repl", "privacy" ], "author": "Venice AI", "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/veniceai/venice-cli" + "url": "https://github.com/DUptain1993/venice-cli" }, "bugs": { - "url": "https://github.com/veniceai/venice-cli/issues" + "url": "https://github.com/DUptain1993/venice-cli/issues" }, "homepage": "https://venice.ai" } diff --git a/src/commands/audio.ts b/src/commands/audio.ts deleted file mode 100644 index d2b50a5..0000000 --- a/src/commands/audio.ts +++ /dev/null @@ -1,187 +0,0 @@ -/** - * Audio Commands - Text-to-speech and transcription - */ - -import { Command } from 'commander'; -import * as fs from 'fs'; -import * as path from 'path'; -import { textToSpeech, transcribe } from '../lib/api.js'; -import { getDefaultVoice } from '../lib/config.js'; -import { - formatSuccess, - formatError, - getChalk, - detectOutputFormat, -} from '../lib/output.js'; - -export function registerAudioCommands(program: Command): void { - // Text to speech - program - .command('tts [text...]') - .alias('speak') - .description('Convert text to speech') - .option('-v, --voice ', 'Voice to use (default: af_sky)') - .option('-m, --model ', 'Model to use', 'tts-kokoro') - .option('-o, --output ', 'Output file path', 'output.mp3') - .option('--format ', 'Audio format (mp3|wav|opus|aac|flac)', 'mp3') - .option('-s, --speed ', 'Speech speed (0.25-4.0)', '1.0') - .action(async (textParts: string[], options) => { - let text = textParts.join(' '); - - // Read from stdin if no text provided - if (!text && !process.stdin.isTTY) { - text = await readStdin(); - } - - if (!text) { - console.error(formatError('No text provided. Usage: venice tts "Your text"')); - process.exit(1); - } - - const voice = options.voice || getDefaultVoice(); - - try { - const audioBuffer = await textToSpeech(text, { - model: options.model, - voice, - format: options.format, - }); - - // Determine output path - let outputPath = options.output; - if (!outputPath.endsWith(`.${options.format}`)) { - outputPath = outputPath.replace(/\.[^.]+$/, `.${options.format}`); - } - - fs.writeFileSync(outputPath, Buffer.from(audioBuffer)); - console.log(formatSuccess(`Saved audio to ${outputPath}`)); - } catch (error) { - console.error(formatError(error instanceof Error ? error.message : String(error))); - process.exit(1); - } - }); - - // Transcription - program - .command('transcribe