Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 11 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ jobs:
shell: powershell
run: tests/claude-compat.Tests.ps1

- name: Windows lifecycle tests
shell: powershell
run: tests/windows-lifecycle.ps1

- name: Windows native installer lifecycle tests
shell: powershell
run: tests/windows-installer-lifecycle.ps1

- name: batch launcher is CRLF and BOM-free
shell: pwsh
run: |
Expand All @@ -74,16 +82,13 @@ jobs:
if ($text -notmatch "`r`n") { throw 'qbraid-code.cmd must use CRLF line endings' }
'CRLF ok, no BOM'

- name: launcher reports a missing install instead of crashing
- name: launcher help works without an installation
shell: cmd
run: |
set QBRAID_CODE_HOME=%TEMP%\qc-does-not-exist
call qbraid-code.cmd --help
if not errorlevel 1 exit /b 1
echo missing-install path reports an error
rem `echo` does not reset ERRORLEVEL in cmd, so the expected 1 would
rem otherwise leak out and fail the step.
exit /b 0
if errorlevel 1 exit /b 1
if exist "%QBRAID_CODE_HOME%" exit /b 1

claude-compat:
strategy:
Expand Down
62 changes: 39 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ qbraid-code -p "explain this error"

Run `qbraid-code --doctor` to check the active profile.

List the qbraid-code commands without contacting qBraid or reading a profile.

```bash
qbraid-code --help
```

Run `claude --help` for arguments that qbraid-code forwards to Claude Code.

## Switch organizations

List the installed organization profiles. The active profile has an asterisk.
Expand Down Expand Up @@ -112,9 +120,19 @@ qbraid-code --profile research --doctor
Put `--profile NAME` first. The launcher removes both arguments before it starts
Claude Code.

To update a profile, close its running sessions and run the installer again.
The installer stages a complete metadata generation, then switches `current`.
If the update fails, the previous generation and key remain active.
To replace an expired or revoked key, close sessions that use the profile.
Then run this command:

```bash
qbraid-code --profile research --update-key
```

The command downloads the official installer and prompts for the replacement
key. The installer verifies that the key belongs to the profile's organization.
It stages a complete metadata generation, then switches `current`. If the
update fails, the previous generation and key remain active.

Run the installer again when you need to update other profile settings.

## Protect profile credentials

Expand Down Expand Up @@ -160,7 +178,8 @@ qBraid Research Lab (local · org a1b2c3d4…) · 4281 credits
```

Credit snapshots show `stale` after five minutes without a successful launch
refresh.
refresh. A confirmed `401` or `403` response shows `key expired` until a key
check succeeds or you rotate the key.

## Choose a model

Expand Down Expand Up @@ -236,6 +255,7 @@ claude mcp login qbraid

| Path | Purpose |
|---|---|
| `~/.qbraid-code/.qbraid-code-install` | Ownership marker for safe custom-root removal |
| `~/.qbraid-code/active-profile` | Future-session profile pointer |
| `~/.qbraid-code/profiles/<name>/current` | Atomic metadata-generation pointer |
| `~/.qbraid-code/profiles/<name>/generations/*/env` | URLs, model, secret reference, and proxy binary |
Expand All @@ -244,6 +264,7 @@ claude mcp login qbraid
| `~/.qbraid-code/secrets/*` | Linux-only private key fallback |
| `~/.qbraid-code/runtime.*` | Short-lived proxy state |
| `~/.qbraid-code/session.*` | Short-lived non-secret status snapshot |
| `~/.qbraid-code/profiles/<name>/generations/*/key-status` | Confirmed local key-rejection marker |
| `~/.qbraid-code/statusline.sh` | Unix statusline adapter |
| `~/.local/bin/qbraid-code` | Unix launcher |

Expand All @@ -256,8 +277,9 @@ Windows stores profile and runtime files under
Start with `qbraid-code --doctor`.

**Rejected key.** Create a key at
[account.qbraid.com/account/api-keys](https://account.qbraid.com/account/api-keys),
then update the affected profile.
[account.qbraid.com/account/api-keys](https://account.qbraid.com/account/api-keys).
Then close sessions that use the profile and run
`qbraid-code --profile NAME --update-key`.

**Wrong organization name.** Reinstall that profile with
`QBRAID_CODE_PROFILE_LABEL` set to a readable local name. API-key
Expand All @@ -272,26 +294,20 @@ without a real parser.

## Uninstall

On macOS or Linux, stop the proxies and remove the installed files.
Close every qbraid-code session. Then remove qbraid-code from this device.

```bash
qbraid-code --stop
rm -rf ~/.qbraid-code ~/.local/bin/qbraid-code ~/.local/bin/qbraid-code.home
claude mcp remove qbraid
qbraid-code --uninstall
```

On Windows, run these commands in PowerShell.
Type `uninstall` when prompted. For unattended local cleanup, use
`qbraid-code --uninstall --yes`.

```powershell
qbraid-code --stop
Remove-Item -Recurse -Force "$env:USERPROFILE\.qbraid-code"
Remove-Item -Force "$env:USERPROFILE\.local\bin\qbraid-code.cmd"
Remove-Item -Force "$env:USERPROFILE\.local\bin\qbraid-launch.ps1"
Remove-Item -Force "$env:USERPROFILE\.local\bin\qbraid-code.home"
claude mcp remove qbraid
```
The command stops owned local proxies and removes every qbraid-code profile,
stored local key, runtime file, proxy binary, statusline entry, qBraid MCP
entry, and installed launcher. It preserves unrelated Claude settings and MCP
servers. It tolerates files or credentials that are already missing.

Remove the qBraid `statusLine` from the Claude user settings file. Delete
`qbraid-code` entries from Keychain or Windows Credential Manager. On Linux,
delete the matching Secret Service entries. Removing `~/.qbraid-code` also
deletes the headless Linux file fallback.
Uninstall does not contact qBraid, Anthropic, or an OAuth service. It does not
revoke API keys in your qBraid account. Revoke those keys separately at
[account.qbraid.com/account/api-keys](https://account.qbraid.com/account/api-keys).
4 changes: 4 additions & 0 deletions doctor.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ Write-Host "capabilities: mcp-add=$($mcpAdd.ToString().ToLower()) mcp-get=$($mcp
try {
$balance = Invoke-RestMethod -Uri "$apiBase/billing/credits/balance" `
-Headers @{ 'X-API-Key' = $token } -TimeoutSec 20
Remove-Item (Join-Path $ProfileDir 'key-status') -Force -ErrorAction SilentlyContinue
Write-Host 'key: valid'
$raw = $balance.data.qbraidCredits
if ($null -ne $raw) {
Expand All @@ -120,7 +121,10 @@ try {
$status = $null
if ($_.Exception.Response) { $status = [int]$_.Exception.Response.StatusCode }
if ($status -eq 401 -or $status -eq 403) {
[IO.File]::WriteAllText((Join-Path $ProfileDir 'key-status'), 'expired', (New-Object Text.UTF8Encoding $false))
Write-Host 'key: REJECTED - make a new one at https://account.qbraid.com/account/api-keys'
$selectedProfile = if ($env:QBRAID_CODE_PROFILE) { $env:QBRAID_CODE_PROFILE } else { 'default' }
Write-Host "replace: qbraid-code --profile $selectedProfile --update-key"
} elseif ($status) {
Write-Host "key: UNKNOWN - qBraid returned HTTP $status"
} else {
Expand Down
Loading
Loading