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
3 changes: 0 additions & 3 deletions .github/workflows/preview-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ jobs:
run: |
mkdir -p "artifacts/${{ matrix.id }}/binary"
cp "zig-out/bin/${{ matrix.binary_name }}" "artifacts/${{ matrix.id }}/binary/${{ matrix.binary_name }}"
if [[ "${{ matrix.id }}" == win32-* ]]; then
cp "zig-out/bin/codex-auth-auto.exe" "artifacts/${{ matrix.id }}/binary/codex-auth-auto.exe"
fi

- name: Upload artifact bundle
uses: actions/upload-artifact@v7
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,6 @@ jobs:
run: |
mkdir -p "artifacts/${{ matrix.id }}/binary"
cp "zig-out/bin/${{ matrix.binary_name }}" "artifacts/${{ matrix.id }}/binary/${{ matrix.binary_name }}"
if [[ "${{ matrix.id }}" == win32-* ]]; then
cp "zig-out/bin/codex-auth-auto.exe" "artifacts/${{ matrix.id }}/binary/codex-auth-auto.exe"
fi
if [[ "${{ matrix.archive_name }}" == *.zip ]]; then
(
cd "artifacts/${{ matrix.id }}/binary"
Expand Down
4 changes: 0 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ Detailed command documentation lives in [docs/commands/README.md](./docs/command
| [`codex-auth remove [--live] [--api\|--skip-api]`](./docs/commands/remove.md) | Remove accounts interactively |
| [`codex-auth remove <query> [<query>...]`](./docs/commands/remove.md) | Remove accounts by selector |
| [`codex-auth remove --all`](./docs/commands/remove.md) | Remove all stored accounts |
| [`codex-auth status`](./docs/commands/status.md) | Show auto-switch, service, and usage status |

### Import and Maintenance

Expand All @@ -83,8 +82,6 @@ Detailed command documentation lives in [docs/commands/README.md](./docs/command

| Command | Description |
|---------|-------------|
| [`codex-auth config auto enable\|disable`](./docs/commands/config.md) | Enable or disable background auto-switching |
| [`codex-auth config auto --5h <percent> [--weekly <percent>]`](./docs/commands/config.md) | Configure background auto-switch thresholds |
| [`codex-auth config live --interval <seconds>`](./docs/commands/config.md) | Configure live TUI refresh interval |

## Quick Examples
Expand All @@ -97,7 +94,6 @@ codex-auth switch 02
codex-auth remove work
codex-auth import /path/to/auth.json --alias personal
codex-auth list --skip-api
codex-auth status
```

## Q&A
Expand Down
35 changes: 0 additions & 35 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,55 +1,27 @@
const std = @import("std");

fn linkWindowsTaskSchedulerLibraries(module: *std.Build.Module) void {
module.linkSystemLibrary("ole32", .{});
module.linkSystemLibrary("oleaut32", .{});
}

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const is_windows = target.result.os.tag == .windows;
const package_module = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
if (is_windows) {
linkWindowsTaskSchedulerLibraries(package_module);
}

const main_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
if (is_windows) {
linkWindowsTaskSchedulerLibraries(main_module);
}
const exe = b.addExecutable(.{
.name = "codex-auth",
.root_module = main_module,
});
b.installArtifact(exe);

if (is_windows) {
const auto_module = b.createModule(.{
.root_source_file = b.path("src/auto_main.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
});
linkWindowsTaskSchedulerLibraries(auto_module);
const auto_exe = b.addExecutable(.{
.name = "codex-auth-auto",
.root_module = auto_module,
});
auto_exe.subsystem = .Windows;
b.installArtifact(auto_exe);
}

const fake_node_module = b.createModule(.{
.root_source_file = b.path("tests/fake_node.zig"),
.target = target,
Expand All @@ -73,17 +45,13 @@ pub fn build(b: *std.Build) void {
"tests/api_http_test.zig",
"tests/api_me_test.zig",
"tests/api_usage_test.zig",
"tests/auth_account_test.zig",
"tests/auth_test.zig",
"tests/auto_candidate_test.zig",
"tests/auto_daemon_test.zig",
"tests/cli_behavior_test.zig",
"tests/cli_picker_test.zig",
"tests/compat_fs_test.zig",
"tests/cli_integration_test.zig",
"tests/lib_compile_test.zig",
"tests/registry_import_test.zig",
"tests/registry_purge_import_test.zig",
"tests/registry_test.zig",
"tests/session_test.zig",
"tests/terminal_color_test.zig",
Expand All @@ -107,9 +75,6 @@ pub fn build(b: *std.Build) void {
.{ .name = "codex_auth", .module = package_module },
},
});
if (is_windows) {
linkWindowsTaskSchedulerLibraries(test_module);
}
const test_artifact = b.addTest(.{
.root_module = test_module,
});
Expand Down
12 changes: 0 additions & 12 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,14 @@ The `accounts/check` response is parsed by `chatgpt_account_id`. `name: null` an
- with `--skip-api`, foreground refresh still uses only the active local rollout data because local session files do not identify the other stored accounts
- `list` and interactive `switch` use the API-backed path by default; `--api` is accepted as an explicit equivalent
- `list --skip-api` and interactive `switch --skip-api` disable the foreground usage API path for that command
- in `switch --live`, the initial live display and later refreshed displays trigger a foreground auto-switch when the active account shows `0%` on the 5h window, `0%` on the weekly window, or a numeric non-`200` usage API status overlay for the active row
- `switch --live` still excludes errored rows from candidate selection, and it also skips candidates whose current displayed 5h or weekly value is already `0%`
- with `--skip-api`, `list` and `switch --live` can still refresh only the active account from local rollout data; non-active `switch` rows and non-active foreground auto-switch candidates still come from stored registry data
- single-shot `switch --skip-api` skips the pre-render refresh round entirely and shows the stored registry picker directly
- `switch <query>` always resolves selectors locally from stored data and does not accept `--live`, `--api`, or `--skip-api`
- interactive `remove`, including `remove --live`, always stays local-only and never makes foreground usage API requests
- `remove <query>` and `remove --all` always resolve selectors from stored local data and do not accept `--live`
- single-shot `switch` does not perform another foreground usage refresh after the new account is activated
- in `switch --live`, a successful selection patches the current picker state in memory instead of rebuilding it from disk; the active account and `Switched to ...` message both come from the persisted registry state after the local switch succeeds, while the current display keeps its existing usage/account overlays, including any overlay already shown on the newly active row, until the next scheduled live refresh reapplies fresh data asynchronously
- in `switch --live`, a successful manual selection immediately re-runs the foreground auto-switch check on that patched current display instead of waiting for the next scheduled refresh; if the newly active row still shows `0%` or a numeric non-`200` usage overlay in the current display, the auto-switch loop may switch away again right away
- in `remove --live`, a successful delete also patches the current picker state in memory; removed rows disappear immediately, surviving overlays stay in place until the next scheduled refresh, and the surviving active account plus the `Removed ...` summary come from the persisted registry state after removal succeeds
- the auto-switch daemon refreshes the current active account usage during each cycle when `auto_switch.enabled = true`
- the auto-switch daemon may also refresh a small number of non-active candidate accounts from stored snapshots so it can score switch candidates
- the daemon usage paths are cooldown-limited; see [docs/auto-switch.md](./auto-switch.md) for the broader runtime loop

## Account Name Refresh Rules

Expand All @@ -73,11 +67,7 @@ The `accounts/check` response is parsed by `chatgpt_account_id`. `name: null` an
- `switch <query>` always stays local-only and does not accept `--live`, `--api`, or `--skip-api`.
- `remove <query>` and `remove --all` always stay local-only and do not accept `--live`.
- `list` and interactive `switch` load the request auth context from the current active `auth.json` when they do refresh.
- the auto-switch daemon still uses a grouped-scope scan during each cycle when `auto_switch.enabled = true`.
- daemon refreshes load the request auth context from stored account snapshots under `accounts/` and do not depend on the current `auth.json` belonging to the scope being refreshed.
- when multiple stored ChatGPT snapshots exist for one grouped scope, daemon refreshes pick the snapshot with the newest `last_refresh`.
- stored snapshots without a usable `access_token` or `chatgpt_account_id` are skipped.
- daemon refreshes do not backfill missing `plan` or `auth_mode` from stored snapshots before deciding whether a grouped Team scope qualifies.

At most one `accounts/check` request is attempted per grouped user scope in a given refresh pass.
Request failures and unparseable responses are non-fatal and leave stored `account_name` values unchanged.
Expand All @@ -88,7 +78,6 @@ Grouped account-name refresh always operates on one `chatgpt_user_id` scope at a

- `login` and single-file `import` start from the just-parsed auth info
- `list` and interactive `switch` start from the current active auth info when foreground refresh is enabled
- the auto-switch daemon scans registry-backed grouped scopes and refreshes each qualifying scope independently

That scope includes:

Expand Down Expand Up @@ -143,4 +132,3 @@ Then:
- `Team #1` is filled with `Prod Workspace`
- `Team #2` is overwritten from `Old Workspace` to `Sandbox Workspace`

The same grouped-scope rule also applies to synchronous `list` / interactive `switch` refreshes and to the auto-switch daemon.
114 changes: 0 additions & 114 deletions docs/auto-switch.md

This file was deleted.

2 changes: 0 additions & 2 deletions docs/commands/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ This directory documents command behavior by command. Use `codex-auth <command>
| `remove` | [docs/commands/remove.md](./remove.md) |
| `clean` | [docs/commands/clean.md](./clean.md) |
| `config` | [docs/commands/config.md](./config.md) |
| `status` | [docs/commands/status.md](./status.md) |
| `daemon` | [docs/commands/daemon.md](./daemon.md) |

## Shared Behavior

Expand Down
9 changes: 9 additions & 0 deletions docs/commands/clean.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

```shell
codex-auth clean
codex-auth clean background
```

## Behavior
Expand All @@ -15,6 +16,14 @@ codex-auth clean

If `accounts/registry.json` is missing, `clean` still prunes backup files but skips stale snapshot deletion so recovery snapshots remain available for `import --purge` or manual repair.

`clean background` removes legacy background registrations created by older versions:

- Linux user units named `codex-auth-autoswitch.service` and `codex-auth-autoswitch.timer`.
- macOS LaunchAgent `com.loongphy.codex-auth.auto`.
- Windows scheduled task `CodexAuthAutoSwitch`.

This is a one-time migration cleanup command. It does not install, start, or run background refresh.

## Related Docs

- Backup behavior: [docs/implement.md](../implement.md)
Expand Down
Loading
Loading