Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
f445381
chore(worktrees): snapshot cleanup round2 (20260223-034902)
KooshaPari Feb 23, 2026
f2df50d
chore(worktrees): snapshot cleanup round2 (20260223-035004)
KooshaPari Feb 23, 2026
40ec26b
feat: add service setup helper and homebrew service docs
KooshaPari Feb 25, 2026
febf3f9
Merge feat/cliproxy-service-setup into main (clean merge)
KooshaPari Feb 25, 2026
b1e1675
Merge remote-tracking branch 'origin/snapshots/worktree-cleanup-round…
KooshaPari Feb 25, 2026
03b2fdf
Merge remote-tracking branch 'origin/snapshots/worktree-cleanup-round…
KooshaPari Feb 25, 2026
75eac69
fix(auth): align codex auth import types for sdk build
KooshaPari Feb 26, 2026
6e7b545
Merge pull request #619 from KooshaPari/fix/pr617-base-auth-type-alia…
KooshaPari Feb 26, 2026
4192683
fix(auth): use internal codex auth packages in sdk login flow
KooshaPari Feb 26, 2026
7a28a2f
Merge pull request #621 from KooshaPari/fix/pr617-main-ci-fix1b
KooshaPari Feb 26, 2026
0d866c9
fix(auth): align codex device flow package with sdk login path
KooshaPari Feb 26, 2026
200c201
Merge pull request #622 from KooshaPari/fix/pr617-main-ci-fix2
KooshaPari Feb 26, 2026
42e51bf
chore(repo): ignore local worktrees and build artifacts
KooshaPari Feb 26, 2026
3513a01
Merge pull request #624 from KooshaPari/chore/repo-ignore-local-workt…
KooshaPari Feb 26, 2026
c1e01ce
fix(auth): align codex sdk import types
KooshaPari Feb 26, 2026
04fea06
Merge pull request #625 from KooshaPari/fix/pr617-main-ci-fix3-sdk-au…
KooshaPari Feb 26, 2026
8e043e9
fix(ci): sync required checks manifest with workflows
KooshaPari Feb 26, 2026
ff6186b
Merge pull request #626 from KooshaPari/fix/pr617-main-ci-fix4-requir…
KooshaPari Feb 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions .github/required-checks.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
# workflow_file|job_name
pr-test-build.yml|go-ci
pr-test-build.yml|quality-ci
pr-test-build.yml|quality-staged-check
pr-test-build.yml|fmt-check
pr-test-build.yml|golangci-lint
pr-test-build.yml|route-lifecycle
pr-test-build.yml|provider-smoke-matrix
pr-test-build.yml|provider-smoke-matrix-cheapest
pr-test-build.yml|test-smoke
pr-test-build.yml|pre-release-config-compat-smoke
pr-test-build.yml|distributed-critical-paths
pr-test-build.yml|changelog-scope-classifier
pr-test-build.yml|docs-build
pr-test-build.yml|ci-summary
pr-test-build.yml|build
pr-path-guard.yml|ensure-no-translator-changes
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
cli-proxy-api
cliproxy
*.exe
cli-proxy-api-plus
server


# Configuration
Expand Down Expand Up @@ -53,3 +55,4 @@ _bmad-output/*
.DS_Store
._*
*.bak
PROJECT-wtrees/
16 changes: 15 additions & 1 deletion docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,19 @@ sudo systemctl restart cliproxyapi-plusplus
sudo systemctl stop cliproxyapi-plusplus
```

Cross-platform helper (optional):

```bash
./scripts/service install
./scripts/service start
./scripts/service status
./scripts/service restart
./scripts/service stop
./scripts/service remove
```

On Linux the script writes the systemd unit to `/etc/systemd/system` and requires root privileges.

### macOS (Homebrew + launchd)

Homebrew installs typically place artifacts under `/opt/homebrew`. If installed elsewhere, keep the same launchd flow and swap the binary/config paths.
Expand All @@ -163,9 +176,10 @@ launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.router-for-me.clipro
launchctl kickstart -k gui/$(id -u)/com.router-for-me.cliproxyapi-plusplus
```

If your Homebrew formula supports service hooks:
You can also use a local Homebrew formula with service hooks:

```bash
brew install --HEAD --formula examples/homebrew/cliproxyapi-plusplus.rb
brew services start cliproxyapi-plusplus
brew services restart cliproxyapi-plusplus
```
Expand Down
27 changes: 27 additions & 0 deletions examples/homebrew/cliproxyapi-plusplus.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class CliproxyapiPlusplus < Formula
desc "LLM proxy CLI for OpenAI-compatible and provider-specific APIs"
homepage "https://github.com/router-for-me/CLIProxyAPI"
head "https://github.com/router-for-me/CLIProxyAPI.git", branch: "main"

depends_on "go" => :build

def install
system "go", "build", "-o", bin/"cliproxyapi++", "./cmd/server"
end

service do
run [opt_bin/"cliproxyapi++", "--config", etc/"cliproxyapi/config.yaml"]
working_dir var/"log/cliproxyapi"
keep_alive true
log_path var/"log/cliproxyapi-plusplus.log"
error_log_path var/"log/cliproxyapi-plusplus.err"
end

def post_install
(etc/"cliproxyapi").mkpath
end

test do
assert_predicate bin/"cliproxyapi++", :exist?
end
end
232 changes: 232 additions & 0 deletions scripts/service
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#!/usr/bin/env bash
set -euo pipefail

IFS=$'\n\t'

SERVICE_NAME="cliproxyapi-plusplus"
SERVICE_LABEL="com.router-for-me.cliproxyapi-plusplus"
SYSTEMD_UNIT="$SERVICE_NAME.service"
SYSTEMD_DEST="/etc/systemd/system"
SYSTEMD_ENV="/etc/default/cliproxyapi"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
LAUNCHD_SOURCE="$REPO_ROOT/examples/launchd/$SERVICE_LABEL.plist"
SYSTEMD_SOURCE="$REPO_ROOT/examples/systemd/$SYSTEMD_UNIT"
SYSTEMD_ENV_SOURCE="$REPO_ROOT/examples/systemd/cliproxyapi-plusplus.env"

usage() {
cat <<'USAGE'
Usage:
./scripts/service <action> [--config PATH]

Actions:
install register service files and enable on boot
remove disable and remove service files
start start service now
stop stop service now
restart stop then start
status show service status

Options:
--config PATH only used for macOS launchd fallback
USAGE
}

command_exists() {
command -v "$1" >/dev/null 2>&1
}

ensure_root() {
if [ "$(id -u)" -ne 0 ]; then
echo "This action requires root on Linux. Re-run with sudo."
exit 1
fi
}

has_brew_formula() {
command_exists brew && brew list --formula | grep -qx "cliproxyapi-plusplus"
}

install_macos() {
local cfg="${1:-/opt/homebrew/etc/cliproxyapi/config.yaml}"

if has_brew_formula; then
brew services start cliproxyapi-plusplus
return 0
fi

if ! command_exists launchctl || ! command_exists sed; then
echo "launchctl and sed are required for fallback launchd setup"
exit 1
fi

local prefix
local plist_dest="$HOME/Library/LaunchAgents/$SERVICE_LABEL.plist"
prefix="$(command_exists brew && brew --prefix || echo /opt/homebrew)"
mkdir -p "$HOME/Library/LaunchAgents"
sed -e "s#/opt/homebrew#$prefix#g" \
-e "s#/opt/homebrew/etc/cliproxyapi/config.yaml#$cfg#g" \
"$LAUNCHD_SOURCE" > "$plist_dest"
launchctl bootstrap "gui/$(id -u)" "$plist_dest"
}

remove_macos() {
if has_brew_formula; then
brew services stop cliproxyapi-plusplus
brew services uninstall cliproxyapi-plusplus || true
return 0
fi

if command_exists launchctl; then
launchctl bootout "gui/$(id -u)" "$SERVICE_LABEL" || true
fi
rm -f "$HOME/Library/LaunchAgents/$SERVICE_LABEL.plist"
}

start_macos() {
if has_brew_formula; then
brew services start cliproxyapi-plusplus
return 0
fi

if command_exists launchctl; then
launchctl kickstart -k "gui/$(id -u)/$SERVICE_LABEL"
fi
}

stop_macos() {
if has_brew_formula; then
brew services stop cliproxyapi-plusplus
return 0
fi

if command_exists launchctl; then
launchctl stop "$SERVICE_LABEL"
fi
}

status_macos() {
if has_brew_formula; then
brew services list | grep "cliproxyapi-plusplus"
return 0
fi

if command_exists launchctl; then
launchctl print "gui/$(id -u)/$SERVICE_LABEL" || true
fi
}

install_linux() {
ensure_root

if ! command_exists systemctl; then
echo "systemctl not available"
exit 1
fi
if [ ! -f "$SYSTEMD_SOURCE" ]; then
echo "systemd unit template missing: $SYSTEMD_SOURCE"
exit 1
fi

mkdir -p "$SYSTEMD_DEST"
cp "$SYSTEMD_SOURCE" "$SYSTEMD_DEST/$SYSTEMD_UNIT"
if [ -f "$SYSTEMD_ENV_SOURCE" ]; then
mkdir -p /etc/default
cp "$SYSTEMD_ENV_SOURCE" "$SYSTEMD_ENV"
fi
systemctl daemon-reload
systemctl enable "$SYSTEMD_UNIT"
}

remove_linux() {
ensure_root

if ! command_exists systemctl; then
echo "systemctl not available"
exit 1
fi

systemctl disable "$SYSTEMD_UNIT" || true
systemctl stop "$SYSTEMD_UNIT" || true
rm -f "$SYSTEMD_DEST/$SYSTEMD_UNIT" "$SYSTEMD_ENV"
systemctl daemon-reload
}

start_linux() {
ensure_root
systemctl start "$SYSTEMD_UNIT"
}

stop_linux() {
ensure_root
systemctl stop "$SYSTEMD_UNIT"
}

status_linux() {
if ! command_exists systemctl; then
echo "systemctl not available"
exit 1
fi
systemctl status "$SYSTEMD_UNIT" --no-pager
}

main() {
local action="${1:-}"
local config_path="/opt/homebrew/etc/cliproxyapi/config.yaml"
shift || true

while [ "$#" -gt 0 ]; do
case "$1" in
--config)
config_path="${2:-}"
shift 2
;;
-h|--help)
usage
return 0
;;
*)
echo "Unknown option: $1"
usage
return 1
;;
esac
done

if [ -z "$action" ] || [ "$action" = "--help" ] || [ "$action" = "-h" ]; then
usage
return 0
fi

case "$(uname -s)" in
Darwin)
case "$action" in
install) install_macos "$config_path" ;;
remove|uninstall) remove_macos ;;
start) start_macos ;;
stop) stop_macos ;;
restart) stop_macos; start_macos ;;
status) status_macos ;;
*) usage; exit 1 ;;
esac
;;
Linux)
case "$action" in
install) install_linux ;;
remove|uninstall) remove_linux ;;
start) start_linux ;;
stop) stop_linux ;;
restart) stop_linux; start_linux ;;
status) status_linux ;;
*) usage; exit 1 ;;
esac
;;
*)
echo "Unsupported OS: $(uname -s)"
exit 1
;;
esac
}

main "$@"
6 changes: 3 additions & 3 deletions sdk/auth/codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import (
"strings"
"time"

"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/auth/codex"
"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/browser"
"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/auth/codex"
// legacy client removed
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/misc"
"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/util"
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
log "github.com/sirupsen/logrus"
)
Expand Down
2 changes: 1 addition & 1 deletion sdk/auth/codex_device.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"strings"
"time"

"github.com/router-for-me/CLIProxyAPI/v6/internal/auth/codex"
"github.com/router-for-me/CLIProxyAPI/v6/pkg/llmproxy/auth/codex"
"github.com/router-for-me/CLIProxyAPI/v6/internal/browser"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
Expand Down Expand Up @@ -109,7 +109,7 @@
}

authSvc := codex.NewCodexAuth(cfg)
authBundle, err := authSvc.ExchangeCodeForTokensWithRedirect(

Check failure on line 112 in sdk/auth/codex_device.go

View workflow job for this annotation

GitHub Actions / Analyze (Go) (go)

authSvc.ExchangeCodeForTokensWithRedirect undefined (type *codex.CodexAuth has no field or method ExchangeCodeForTokensWithRedirect)

Check failure on line 112 in sdk/auth/codex_device.go

View workflow job for this annotation

GitHub Actions / build

authSvc.ExchangeCodeForTokensWithRedirect undefined (type *codex.CodexAuth has no field or method ExchangeCodeForTokensWithRedirect)

Check failure on line 112 in sdk/auth/codex_device.go

View workflow job for this annotation

GitHub Actions / Analyze (Go) (go)

authSvc.ExchangeCodeForTokensWithRedirect undefined (type *codex.CodexAuth has no field or method ExchangeCodeForTokensWithRedirect)
ctx,
authCode,
codexDeviceTokenExchangeRedirectURI,
Expand Down
Loading