1 Commits

Author SHA1 Message Date
dependabot[bot]
065eaeaa4e chore(deps): bump tonic from 0.13.1 to 0.14.2 in /llmx-rs
Bumps [tonic](https://github.com/hyperium/tonic) from 0.13.1 to 0.14.2.
- [Release notes](https://github.com/hyperium/tonic/releases)
- [Changelog](https://github.com/hyperium/tonic/blob/master/CHANGELOG.md)
- [Commits](https://github.com/hyperium/tonic/compare/v0.13.1...v0.14.2)

---
updated-dependencies:
- dependency-name: tonic
  dependency-version: 0.14.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-12 19:46:57 +00:00
14 changed files with 110 additions and 76 deletions

View File

@@ -27,6 +27,34 @@
"path": "llmx.exe"
}
}
},
"llmx-responses-api-proxy": {
"platforms": {
"macos-aarch64": {
"regex": "^llmx-responses-api-proxy-aarch64-apple-darwin\\.zst$",
"path": "llmx-responses-api-proxy"
},
"macos-x86_64": {
"regex": "^llmx-responses-api-proxy-x86_64-apple-darwin\\.zst$",
"path": "llmx-responses-api-proxy"
},
"linux-x86_64": {
"regex": "^llmx-responses-api-proxy-x86_64-unknown-linux-musl\\.zst$",
"path": "llmx-responses-api-proxy"
},
"linux-aarch64": {
"regex": "^llmx-responses-api-proxy-aarch64-unknown-linux-musl\\.zst$",
"path": "llmx-responses-api-proxy"
},
"windows-x86_64": {
"regex": "^llmx-responses-api-proxy-x86_64-pc-windows-msvc\\.exe\\.zst$",
"path": "llmx-responses-api-proxy.exe"
},
"windows-aarch64": {
"regex": "^llmx-responses-api-proxy-aarch64-pc-windows-msvc\\.exe\\.zst$",
"path": "llmx-responses-api-proxy.exe"
}
}
}
}
}

BIN
.github/llmx-cli-login.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

BIN
.github/llmx-cli-permissions.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

BIN
.github/llmx-cli-splash.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

View File

@@ -445,19 +445,7 @@ jobs:
run: |
./scripts/stage_npm_packages.py \
--release-version "${{ steps.release_name.outputs.name }}" \
--package llmx
# Delete any existing release to avoid conflicts with dotslash manifest file
- name: Delete existing release if present
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
if gh release view "${{ github.ref_name }}" --repo "${{ github.repository }}" >/dev/null 2>&1; then
echo "Deleting existing release ${{ github.ref_name }}"
gh release delete "${{ github.ref_name }}" --repo "${{ github.repository }}" --yes
else
echo "No existing release found for ${{ github.ref_name }}"
fi
--package @valknar/llmx
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
@@ -476,7 +464,9 @@ jobs:
tag: ${{ github.ref_name }}
config: .github/dotslash-config.json
# Publish to npm using authentication token
# Publish to npm using OIDC authentication.
# July 31, 2025: https://github.blog/changelog/2025-07-31-npm-trusted-publishing-with-oidc-is-generally-available/
# npm docs: https://docs.npmjs.com/trusted-publishers
publish-npm:
# Publish to npm for stable releases and alpha pre-releases with numeric suffixes.
if: ${{ needs.release.outputs.should_publish_npm == 'true' }}
@@ -484,6 +474,7 @@ jobs:
needs: release
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC
contents: read
steps:
@@ -492,6 +483,11 @@ jobs:
with:
node-version: 22
registry-url: "https://registry.npmjs.org"
scope: "@valknar"
# Trusted publishing requires npm CLI version 11.5.1 or later.
- name: Update npm
run: npm install -g npm@latest
- name: Download npm tarballs from release
env:
@@ -503,18 +499,15 @@ jobs:
mkdir -p dist/npm
gh release download "$tag" \
--repo "${GITHUB_REPOSITORY}" \
--pattern "llmx-npm-${version}.tgz" \
--pattern "valknar-llmx-npm-${version}.tgz" \
--dir dist/npm
# No NODE_AUTH_TOKEN needed because we use OIDC.
- name: Publish to npm
env:
VERSION: ${{ needs.release.outputs.version }}
NPM_TAG: ${{ needs.release.outputs.npm_tag }}
run: |
# Write auth token to the .npmrc file that setup-node created
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" >> ${NPM_CONFIG_USERCONFIG}
set -euo pipefail
tag_args=()
if [[ -n "${NPM_TAG}" ]]; then
@@ -522,7 +515,7 @@ jobs:
fi
tarballs=(
"llmx-npm-${VERSION}.tgz"
"valknar-llmx-npm-${VERSION}.tgz"
)
for tarball in "${tarballs[@]}"; do

View File

@@ -1,9 +1,13 @@
<p align="center"><code>npm i -g @valknarthing/llmx</code></p>
<p align="center"><code>npm i -g @valknar/llmx</code><br />or <code>brew install --cask llmx</code></p>
<p align="center"><strong>LLMX CLI</strong> is a coding agent powered by LiteLLM that runs locally on your computer.
</br>
</br>This project is a community fork with enhanced support for multiple LLM providers via LiteLLM.
</br>Original project: <a href="https://github.com/openai/codex">github.com/openai/codex</a></p>
</br>Original project: <a href="https://github.com/openai/llmx">github.com/openai/llmx</a></p>
<p align="center">
<img src="./.github/llmx-cli-splash.png" alt="LLMX CLI splash" width="80%" />
</p>
---
@@ -11,10 +15,16 @@
### Installing and running LLMX CLI
Install globally with npm:
Install globally with your preferred package manager. If you use npm:
```shell
npm install -g @valknarthing/llmx
npm install -g @valknar/llmx
```
Alternatively, if you use Homebrew:
```shell
brew install --cask llmx
```
Then simply run `llmx` to get started:
@@ -23,8 +33,10 @@ Then simply run `llmx` to get started:
llmx
```
If you're running into upgrade issues with Homebrew, see the [FAQ entry on brew upgrade llmx](./docs/faq.md#brew-upgrade-llmx-isnt-upgrading-me).
<details>
<summary>You can also go to the <a href="https://github.com/valknarthing/llmx/releases/latest">latest GitHub Release</a> and download the appropriate binary for your platform.</summary>
<summary>You can also go to the <a href="https://github.com/valknar/llmx/releases/latest">latest GitHub Release</a> and download the appropriate binary for your platform.</summary>
Each GitHub Release contains many executables, but in practice, you likely want one of these:
@@ -84,7 +96,7 @@ LLMX CLI supports a rich set of configuration options, with preferences stored i
- [Auth methods](./docs/authentication.md#forcing-a-specific-auth-method-advanced)
- [Login on a "Headless" machine](./docs/authentication.md#connecting-on-a-headless-machine)
- **Automating LLMX**
- [GitHub Action](https://github.com/valknarthing/llmx-action)
- [GitHub Action](https://github.com/valknar/llmx-action)
- [TypeScript SDK](./sdk/typescript/README.md)
- [Non-interactive mode (`llmx exec`)](./docs/exec.md)
- [**Advanced**](./docs/advanced.md)

View File

@@ -1,5 +1,5 @@
{
"name": "@valknarthing/llmx",
"name": "@valknar/llmx",
"version": "0.1.0",
"license": "Apache-2.0",
"description": "LLMX CLI - Multi-provider coding agent powered by LiteLLM",
@@ -16,7 +16,7 @@
],
"repository": {
"type": "git",
"url": "git+https://github.com/valknarthing/llmx.git",
"url": "git+https://github.com/valknar/llmx.git",
"directory": "llmx-cli"
}
}

View File

@@ -33,7 +33,7 @@ def parse_args() -> argparse.Namespace:
"--package",
choices=("llmx", "llmx-responses-api-proxy", "llmx-sdk"),
default="llmx",
help="Which npm package to stage (default: llmx).",
help="Which npm package to stage (default: codex).",
)
parser.add_argument(
"--version",

54
llmx-rs/Cargo.lock generated
View File

@@ -2227,7 +2227,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.6.0",
"socket2",
"system-configuration",
"tokio",
"tower-service",
@@ -3330,7 +3330,7 @@ dependencies = [
"serde_json",
"strum_macros 0.27.2",
"tokio",
"tonic",
"tonic 0.14.2",
"tracing",
]
@@ -4222,7 +4222,7 @@ dependencies = [
"serde_json",
"thiserror 2.0.17",
"tokio",
"tonic",
"tonic 0.13.1",
"tracing",
]
@@ -4238,7 +4238,7 @@ dependencies = [
"opentelemetry_sdk",
"prost",
"serde",
"tonic",
"tonic 0.13.1",
]
[[package]]
@@ -4710,7 +4710,7 @@ dependencies = [
"quinn-udp",
"rustc-hash 2.1.1",
"rustls",
"socket2 0.6.0",
"socket2",
"thiserror 2.0.17",
"tokio",
"tracing",
@@ -4747,7 +4747,7 @@ dependencies = [
"cfg_aliases 0.2.1",
"libc",
"once_cell",
"socket2 0.6.0",
"socket2",
"tracing",
"windows-sys 0.60.2",
]
@@ -5819,16 +5819,6 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "socket2"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "socket2"
version = "0.6.0"
@@ -6374,7 +6364,7 @@ dependencies = [
"pin-project-lite",
"signal-hook-registry",
"slab",
"socket2 0.6.0",
"socket2",
"tokio-macros",
"windows-sys 0.59.0",
]
@@ -6505,6 +6495,32 @@ name = "tonic"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9"
dependencies = [
"async-trait",
"base64",
"bytes",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-timeout",
"hyper-util",
"percent-encoding",
"pin-project",
"prost",
"tokio",
"tokio-stream",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tonic"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203"
dependencies = [
"async-trait",
"axum",
@@ -6519,8 +6535,8 @@ dependencies = [
"hyper-util",
"percent-encoding",
"pin-project",
"prost",
"socket2 0.5.10",
"socket2",
"sync_wrapper",
"tokio",
"tokio-stream",
"tower",

View File

@@ -190,7 +190,7 @@ tokio-test = "0.4"
tokio-util = "0.7.16"
toml = "0.9.5"
toml_edit = "0.23.4"
tonic = "0.13.1"
tonic = "0.14.2"
tracing = "0.1.41"
tracing-appender = "0.2.3"
tracing-subscriber = "0.3.20"

View File

@@ -2,6 +2,7 @@ use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::to_response;
use llmx_app_server_protocol::CancelLoginChatGptParams;
use llmx_app_server_protocol::CancelLoginChatGptResponse;
use llmx_app_server_protocol::GetAuthStatusParams;
use llmx_app_server_protocol::GetAuthStatusResponse;
use llmx_app_server_protocol::JSONRPCError;
@@ -109,35 +110,21 @@ async fn login_and_cancel_chatgpt() -> Result<()> {
login_id: login.login_id,
})
.await?;
// The cancel might succeed or fail with "login id not found" if the login
// completed/cancelled already due to a race condition. Either outcome is acceptable.
// Use a timeout and allow either success or error response.
let cancel_result = timeout(
Duration::from_secs(5),
let cancel_resp: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(cancel_id)),
)
.await;
match cancel_result {
Ok(Ok(_)) => {
// Successfully cancelled
eprintln!("cancel succeeded");
}
Ok(Err(_)) | Err(_) => {
// Cancel failed or timed out - acceptable in race condition
eprintln!("cancel failed or timed out (expected in race condition)");
}
}
.await??;
let _ok: CancelLoginChatGptResponse = to_response(cancel_resp)?;
// Optionally observe the completion notification; do not fail if it races.
let maybe_note = timeout(
Duration::from_secs(2),
mcp.read_stream_until_notification_message("loginChatGptComplete"),
mcp.read_stream_until_notification_message("llmx/event/login_chat_gpt_complete"),
)
.await;
if maybe_note.is_err() {
eprintln!("warning: did not observe loginChatGptComplete notification after cancel");
eprintln!("warning: did not observe login_chat_gpt_complete notification after cancel");
}
Ok(())
}

View File

@@ -1,5 +1,5 @@
{
"name": "@valknarthing/llmx-responses-api-proxy",
"name": "@valknar/llmx-responses-api-proxy",
"version": "0.1.0",
"license": "Apache-2.0",
"bin": {
@@ -15,7 +15,7 @@
],
"repository": {
"type": "git",
"url": "git+https://github.com/valknarthing/llmx.git",
"url": "git+https://github.com/valknar/llmx.git",
"directory": "llmx-rs/responses-api-proxy/npm"
}
}

View File

@@ -148,9 +148,7 @@ def main() -> int:
print(f"should `git checkout {resolved_head_sha}`")
for package in packages:
# Sanitize package name for use in filesystem path (replace / with -)
safe_package_name = package.replace("/", "-").replace("@", "")
staging_dir = Path(tempfile.mkdtemp(prefix=f"npm-stage-{safe_package_name}-", dir=runner_temp))
staging_dir = Path(tempfile.mkdtemp(prefix=f"npm-stage-{package}-", dir=runner_temp))
pack_output = output_dir / f"{package}-npm-{args.release_version}.tgz"
cmd = [

View File

@@ -1,10 +1,10 @@
{
"name": "@valknarthing/llmx-sdk",
"name": "@valknar/llmx-sdk",
"version": "0.1.0",
"description": "TypeScript SDK for LLMX - Multi-provider coding agent",
"repository": {
"type": "git",
"url": "git+https://github.com/valknarthing/llmx.git",
"url": "git+https://github.com/valknar/llmx.git",
"directory": "sdk/typescript"
},
"keywords": [