refactor: перенос файлов в claude/ + мульти-продуктовая структура

- Все claude-файлы перенесены в claude/ (uclaude_updater.py, скрипты, config)
- claude/README.md с инструкцией для Claude Code
- Корневой README — общий для всех продуктов (claude, codex, gemini, qwen, antigravity)
- Node.js v24.13+ автоустановка через nodesource
- Sparse checkout: клиент скачивает только latest версию cli.js

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
delta-cloud-208e
2026-02-21 11:51:09 +00:00
parent 18ec457c0d
commit 903520b0f9
8 changed files with 198 additions and 110 deletions

102
README.md
View File

@@ -1,92 +1,36 @@
# Unlimited Coding — Claude Code Patches
# Unlimited Coding
Patched Claude Code CLI for use with custom API endpoints. Automatic updater included.
Patched AI coding tools for use with custom API endpoints.
## Products
| Folder | Tool | Status |
|--------|------|--------|
| [claude/](claude/) | Claude Code | Active |
| codex/ | OpenAI Codex CLI | Planned |
| gemini/ | Gemini CLI | Planned |
| qwen/ | Qwen Code | Planned |
| antigravity/ | Antigravity | Planned |
## Quick Start
### First Install
See README in each product folder for installation instructions.
### Claude Code
```bash
# 1. Install Claude Code (if not installed)
npm install -g @anthropic-ai/claude-code
bash <(curl -s https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/uclaude_install.sh)
```
# 2. Clone and install (one command — downloads only latest version)
bash <(curl -s https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/uclaude_install.sh)
# Or manually:
git clone --depth 1 --no-checkout https://git.sensey24.ru/aibot777/unlimitedcoding.git
Or manually:
```bash
git clone --depth 1 https://git.sensey24.ru/aibot777/unlimitedcoding.git
cd unlimitedcoding
git sparse-checkout set '/*' 'claude/releases/index.json'
git checkout
# Read latest version from index, then checkout only that version:
VER=$(python3 -c "import json; print(json.load(open('claude/releases/index.json'))['latest'])")
git sparse-checkout add "claude/releases/v${VER}"
git checkout
sudo python3 uclaude_updater.py --force
```
### Update
```bash
cd unlimitedcoding
sudo bash uclaude_update.sh
```
The updater will automatically:
- Pull latest releases from the repo
- Detect installed Claude Code version
- Install the latest patched cli.js (with backup)
- Configure settings for all users on the system
### Check for Updates (without installing)
```bash
cd unlimitedcoding
bash uclaude_update.sh --check
```
### Other Options
```bash
sudo bash uclaude_update.sh --force # Force reinstall even if up to date
sudo bash uclaude_update.sh --settings-only # Only update settings, don't touch cli.js
```
### Windows
```cmd
uclaude_update.bat
```
or PowerShell:
```powershell
powershell -ExecutionPolicy Bypass -File uclaude_update.ps1
```
## What's Patched (15 patches)
- Custom API endpoint support (base URL, auth token, models)
- Auth/OAuth bypass for custom endpoints
- Telemetry disabled (Datadog, Segment)
- Permission prompts auto-accepted
- Root/sudo check removed
- Custom model picker with configurable model list
## What's Inside
```
uclaude_updater.py — main updater script
uclaude_update.sh — Linux/macOS wrapper (git pull + run updater)
uclaude_update.bat — Windows CMD wrapper
uclaude_update.ps1 — Windows PowerShell wrapper
patcher.config.json — API endpoint configuration
claude/releases/ — patched cli.js files per version
index.json — version index (latest, release list)
v2.1.50/cli.js — patched CLI for v2.1.50
sudo bash claude/uclaude_update.sh --force
```
## Requirements
- Node.js 18+
- Claude Code (`npm install -g @anthropic-ai/claude-code`)
- Python 3
- Git
- Python 3
- Node.js v24.13+ (auto-installed if missing/outdated)

61
claude/README.md Normal file
View File

@@ -0,0 +1,61 @@
# Claude Code — Patched CLI
Patched Claude Code CLI for use with custom API endpoints. 15 patches applied.
## Requirements
- Node.js v24.13+ ([nodejs.org](https://nodejs.org/)) — updater will auto-install if missing or outdated
- Python 3
- Git
## Install
```bash
# Install Claude Code
npm install -g @anthropic-ai/claude-code
# One-line install (from repo root):
sudo bash claude/uclaude_update.sh --force
```
## Update
```bash
sudo bash claude/uclaude_update.sh
```
## Options
```bash
sudo bash claude/uclaude_update.sh --check # check for updates
sudo bash claude/uclaude_update.sh --force # force reinstall
sudo bash claude/uclaude_update.sh --settings-only # only patch settings
```
## Windows
```cmd
claude\uclaude_update.bat
```
## What's Patched
- Custom API endpoint (base URL, auth token)
- Custom model picker (configurable model list)
- Auth/OAuth bypass for custom endpoints
- Telemetry disabled (Datadog, Segment)
- Permission prompts auto-accepted
- Root/sudo check removed
## Files
| File | Purpose |
|------|---------|
| `uclaude_updater.py` | Main updater — version check, cli.js install, settings patch |
| `uclaude_update.sh` | Linux/macOS wrapper |
| `uclaude_update.bat` | Windows CMD wrapper |
| `uclaude_update.ps1` | Windows PowerShell wrapper |
| `uclaude_install.sh` | One-line installer (curl-friendly) |
| `patcher.config.json` | API endpoint config (base_url, api_key, models) |
| `releases/index.json` | Version index |
| `releases/v*/cli.js` | Patched cli.js per version |

View File

@@ -1,7 +1,6 @@
#!/bin/bash
# UClaude — one-line installer
# Usage: bash <(curl -s https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/uclaude_install.sh)
# Or: curl -s URL | bash
# Usage: bash <(curl -s https://git.sensey24.ru/aibot777/unlimitedcoding/raw/branch/master/claude/uclaude_install.sh)
set -e
REPO_URL="https://git.sensey24.ru/aibot777/unlimitedcoding.git"
@@ -13,7 +12,8 @@ echo " Install dir: $INSTALL_DIR"
# Check prerequisites
command -v git >/dev/null 2>&1 || { echo "ERROR: git not found. Install git first."; exit 1; }
command -v python3 >/dev/null 2>&1 || { echo "ERROR: python3 not found. Install Python 3 first."; exit 1; }
command -v node >/dev/null 2>&1 || { echo "ERROR: node not found. Install Node.js 18+ first."; exit 1; }
# Node.js check — will be auto-installed by updater if needed
command -v node >/dev/null 2>&1 || echo "WARNING: node not found. Updater will attempt auto-install."
if [ -d "$INSTALL_DIR/.git" ]; then
echo " Already cloned, updating..."
@@ -27,12 +27,12 @@ else
git clone --depth 1 --no-checkout "$REPO_URL" "$INSTALL_DIR"
cd "$INSTALL_DIR"
# Enable sparse checkout: root files + index.json only (first pass)
# Enable sparse checkout: root + claude core files + index.json (first pass)
git sparse-checkout init --no-cone
git sparse-checkout set '/*' 'claude/releases/index.json'
git sparse-checkout set '/*' 'claude/*' '!claude/releases/v*' 'claude/releases/index.json'
git checkout 2>/dev/null
# Now read latest version from index.json and add that release dir
# Read latest version from index.json and add only that release dir
if [ -f claude/releases/index.json ]; then
VER=$(python3 -c "import json; print(json.load(open('claude/releases/index.json'))['latest'])")
echo " Latest version: v${VER}"
@@ -46,12 +46,12 @@ echo " Running updater..."
# Run updater (needs root for cli.js replacement)
if [ "$(id -u)" -eq 0 ]; then
python3 uclaude_updater.py --force
python3 claude/uclaude_updater.py --force
else
echo " Root privileges required to install cli.js."
sudo python3 uclaude_updater.py --force
sudo python3 claude/uclaude_updater.py --force
fi
echo ""
echo "=== Installation complete ==="
echo " To update later: cd $INSTALL_DIR && sudo bash uclaude_update.sh"
echo " To update later: cd $INSTALL_DIR && sudo bash claude/uclaude_update.sh"

View File

@@ -1,16 +1,16 @@
@echo off
REM UClaude Updater — automatic Claude Code patch updater
REM Usage: uclaude_update.bat [--check] [--force] [--settings-only]
REM Usage: claude\uclaude_update.bat [--check] [--force] [--settings-only]
setlocal enabledelayedexpansion
set "SCRIPT_DIR=%~dp0"
cd /d "%SCRIPT_DIR%"
cd /d "%SCRIPT_DIR%\.."
REM Pull latest artifacts
git pull --quiet 2>nul
REM Run updater
python uclaude_updater.py %*
python claude\uclaude_updater.py %*
if errorlevel 1 (
echo.
echo If you see permission errors, run this script as Administrator.

View File

@@ -1,9 +1,10 @@
# UClaude Updater — automatic Claude Code patch updater
# Usage: powershell -ExecutionPolicy Bypass -File uclaude_update.ps1 [--check] [--force] [--settings-only]
# Usage: powershell -ExecutionPolicy Bypass -File claude\uclaude_update.ps1 [--check] [--force] [--settings-only]
$ErrorActionPreference = "Continue"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
Set-Location $ScriptDir
$RepoRoot = Split-Path -Parent $ScriptDir
Set-Location $RepoRoot
# Pull latest artifacts
git pull --quiet 2>$null
@@ -17,4 +18,4 @@ if (-not $isAdmin) {
}
# Run updater
& python uclaude_updater.py @args
& python claude\uclaude_updater.py @args

View File

@@ -1,10 +1,11 @@
#!/bin/bash
# UClaude Updater — automatic Claude Code patch updater
# Usage: sudo bash uclaude_update.sh [--check] [--force] [--settings-only]
# Usage: sudo bash claude/uclaude_update.sh [--check] [--force] [--settings-only]
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR"
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$REPO_ROOT"
# Fetch latest commit (shallow — no history)
git fetch --depth 1 origin master 2>/dev/null && git reset --hard origin/master 2>/dev/null || git pull --quiet 2>/dev/null || true
@@ -20,8 +21,8 @@ fi
# Run updater
if [ "$(id -u)" -eq 0 ]; then
python3 uclaude_updater.py "$@"
python3 claude/uclaude_updater.py "$@"
else
echo "Root privileges required. Re-running with sudo..."
sudo python3 uclaude_updater.py "$@"
sudo python3 claude/uclaude_updater.py "$@"
fi

View File

@@ -30,7 +30,8 @@ try:
except ImportError:
HAS_PWD = False
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) # claude/
REPO_ROOT = os.path.dirname(SCRIPT_DIR) # unlimitedcoding/
# ANSI colors
G = "\033[92m" # green
@@ -68,6 +69,82 @@ def eprint(*args, **kwargs):
print(*args, file=sys.stderr, **kwargs)
# ============================================================
# Node.js check and auto-install
# ============================================================
MIN_NODE_VERSION = (24, 13, 0)
def get_node_version():
"""Get installed Node.js version as tuple, or None."""
try:
result = subprocess.run(
["node", "--version"],
capture_output=True, text=True, timeout=10,
)
m = re.match(r"v?(\d+)\.(\d+)\.(\d+)", result.stdout.strip())
if m:
return (int(m.group(1)), int(m.group(2)), int(m.group(3)))
except (FileNotFoundError, subprocess.TimeoutExpired):
pass
return None
def install_node():
"""Auto-install Node.js v24+ using the official nodesource setup."""
print(f" {Y}Node.js v{'.'.join(map(str, MIN_NODE_VERSION))}+ required.{D}")
if IS_WINDOWS:
print(f" {R}Please install Node.js manually: https://nodejs.org/{D}")
return False
print(f" Installing Node.js v24 via nodesource...")
try:
# Use nodesource setup script
result = subprocess.run(
["bash", "-c", "curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && apt-get install -y nodejs"],
timeout=120, capture_output=True, text=True,
)
if result.returncode == 0:
ver = get_node_version()
if ver:
print(f" {G}Node.js v{'.'.join(map(str, ver))} installed{D}")
return True
# Fallback: try nvm-like approach or direct download
eprint(f" {R}Auto-install failed. Install manually: https://nodejs.org/{D}")
if result.stderr:
eprint(f" {result.stderr.strip()[:200]}")
return False
except Exception as e:
eprint(f" {R}Auto-install error: {e}{D}")
return False
def ensure_node():
"""Check Node.js version, auto-install/update if needed. Returns True if OK."""
ver = get_node_version()
if ver is None:
print(f" {Y}Node.js not found.{D}")
if is_admin():
return install_node()
else:
eprint(f" {R}Install Node.js v{'.'.join(map(str, MIN_NODE_VERSION))}+: https://nodejs.org/{D}")
return False
if ver < MIN_NODE_VERSION:
print(f" {Y}Node.js v{'.'.join(map(str, ver))} found, need v{'.'.join(map(str, MIN_NODE_VERSION))}+{D}")
if is_admin():
return install_node()
else:
eprint(f" {R}Update Node.js: https://nodejs.org/{D}")
return False
return True
# ============================================================
# Version detection
# ============================================================
@@ -126,7 +203,7 @@ def get_installed_version():
def get_latest_version():
"""Read latest version from local index.json."""
index_path = os.path.join(SCRIPT_DIR, "claude", "releases", "index.json")
index_path = os.path.join(SCRIPT_DIR, "releases", "index.json")
if not os.path.isfile(index_path):
return None
try:
@@ -153,13 +230,13 @@ def git_pull():
# Shallow fetch + reset — downloads only latest commit, not full history
result = subprocess.run(
["git", "fetch", "--depth", "1", "origin", "master"],
cwd=SCRIPT_DIR, capture_output=True, text=True, timeout=60,
cwd=REPO_ROOT, capture_output=True, text=True, timeout=60,
)
if result.returncode != 0:
# Fallback to regular pull
result = subprocess.run(
["git", "pull", "--quiet"],
cwd=SCRIPT_DIR, capture_output=True, text=True, timeout=60,
cwd=REPO_ROOT, capture_output=True, text=True, timeout=60,
)
if result.returncode != 0:
eprint(f" {Y}git pull warning: {result.stderr.strip()}{D}")
@@ -168,7 +245,7 @@ def git_pull():
# Reset to fetched state
subprocess.run(
["git", "reset", "--hard", "origin/master"],
cwd=SCRIPT_DIR, capture_output=True, text=True, timeout=10,
cwd=REPO_ROOT, capture_output=True, text=True, timeout=10,
)
# Setup sparse checkout to download only latest version's cli.js
@@ -189,7 +266,7 @@ def _setup_sparse_checkout():
This avoids downloading cli.js for ALL versions (each ~12MB).
Only the latest version's cli.js is checked out.
"""
index_path = os.path.join(SCRIPT_DIR, "claude", "releases", "index.json")
index_path = os.path.join(SCRIPT_DIR, "releases", "index.json")
if not os.path.isfile(index_path):
return
@@ -205,10 +282,10 @@ def _setup_sparse_checkout():
# Enable sparse checkout
subprocess.run(
["git", "config", "core.sparseCheckout", "true"],
cwd=SCRIPT_DIR, capture_output=True,
cwd=REPO_ROOT, capture_output=True,
)
sparse_file = os.path.join(SCRIPT_DIR, ".git", "info", "sparse-checkout")
sparse_file = os.path.join(REPO_ROOT, ".git", "info", "sparse-checkout")
os.makedirs(os.path.dirname(sparse_file), exist_ok=True)
patterns = [
@@ -223,7 +300,7 @@ def _setup_sparse_checkout():
# Apply sparse checkout
subprocess.run(
["git", "checkout", "HEAD", "--", "."],
cwd=SCRIPT_DIR, capture_output=True, timeout=30,
cwd=REPO_ROOT, capture_output=True, timeout=30,
)
@@ -233,7 +310,7 @@ def _setup_sparse_checkout():
def install_cli_js(version, cli_js_path):
"""Install patched cli.js for the given version."""
release_cli = os.path.join(SCRIPT_DIR, "claude", "releases", f"v{version}", "cli.js")
release_cli = os.path.join(SCRIPT_DIR, "releases", f"v{version}", "cli.js")
if not os.path.isfile(release_cli):
eprint(f" {R}Release cli.js not found: {release_cli}{D}")
return False
@@ -529,10 +606,14 @@ def cmd_check():
def cmd_update(force=False, settings_only=False):
"""Full update: git pull → install cli.js → patch settings."""
installed, cli_js = get_installed_version()
print(f"\n{W}=== UClaude Updater ==={D}")
# Check Node.js version
if not ensure_node():
return 1
installed, cli_js = get_installed_version()
# Git pull to get latest artifacts
print(f"\n Pulling latest updates...")
git_pull()