@wangxt0223/codex-switcher 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.en.md +4 -0
- package/README.md +6 -2
- package/package.json +1 -1
- package/plugins/codex-switcher/README.en.md +6 -2
- package/plugins/codex-switcher/README.md +6 -2
- package/plugins/codex-switcher/scripts/codex-switcher +115 -19
- package/plugins/codex-switcher/scripts/test-switcher.sh +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0 - 2026-04-12
|
|
4
|
+
|
|
5
|
+
- Added automatic Codex CLI launch behavior for `use/switch` in interactive shells (`--launch=auto`).
|
|
6
|
+
- Added explicit `--launch` / `--no-launch` controls for `use/switch`.
|
|
7
|
+
- Added support for `use/switch -- <codex args...>` to switch profile and run Codex command in one step.
|
|
8
|
+
- Improved non-interactive UX with explicit auto-launch skip hint.
|
|
9
|
+
- Added smoke-test coverage for launch/no-launch behavior and argument conflict handling.
|
|
10
|
+
- Updated Chinese/English docs to describe launch semantics and new command forms.
|
|
11
|
+
|
|
3
12
|
## 0.4.1 - 2026-04-12
|
|
4
13
|
|
|
5
14
|
- Refined README wording for a more conversational background/auth mechanism explanation.
|
package/README.en.md
CHANGED
|
@@ -58,6 +58,10 @@ codex-switcher app use personal
|
|
|
58
58
|
- `login --sync`: sync `~/.codex` into the target profile (excluding `auth.json`).
|
|
59
59
|
- `use/switch --sync`: sync current CLI profile into target profile (excluding `auth.json`).
|
|
60
60
|
- `--no-sync`: keep strict isolation without data copy (default).
|
|
61
|
+
- `use/switch` defaults to `--launch=auto`: on an interactive terminal, `codex` starts automatically after switch.
|
|
62
|
+
- `use/switch --launch`: launch `codex` CLI immediately after switching.
|
|
63
|
+
- `use/switch --no-launch`: switch CLI pointer only, without launching `codex`.
|
|
64
|
+
- `use/switch -- <codex args...>`: run `codex` with args right after switch (implies launch).
|
|
61
65
|
|
|
62
66
|
## Command reference
|
|
63
67
|
|
package/README.md
CHANGED
|
@@ -55,6 +55,10 @@ codex-switcher app use personal
|
|
|
55
55
|
- `login --sync`:将 `~/.codex` 同步到目标 profile(不包含 `auth.json`)。
|
|
56
56
|
- `use/switch --sync`:将当前 CLI profile 同步到目标 profile(不包含 `auth.json`)。
|
|
57
57
|
- `--no-sync`:不进行数据同步(默认)。
|
|
58
|
+
- `use/switch` 默认 `--launch=auto`:交互终端中切换后会自动启动 `codex` CLI。
|
|
59
|
+
- `use/switch --launch`:切换后立即启动 `codex` CLI。
|
|
60
|
+
- `use/switch --no-launch`:仅切换当前 CLI profile,不启动 `codex` CLI。
|
|
61
|
+
- `use/switch -- <codex args...>`:切换后直接执行 `codex` 参数(隐式启用 launch)。
|
|
58
62
|
|
|
59
63
|
## 命令参考
|
|
60
64
|
|
|
@@ -67,8 +71,8 @@ codex-switcher app use personal
|
|
|
67
71
|
| Profile 管理 | `codex-switcher list` | 列出所有 profile |
|
|
68
72
|
| Profile 管理 | `codex-switcher current [cli\|app]` | 查看当前 CLI / App profile |
|
|
69
73
|
| Profile 管理 | `codex-switcher status` | 查看当前 profile 登录状态 |
|
|
70
|
-
| Profile 管理 | `codex-switcher use <profile> [--sync\|--no-sync]` | 切换当前 CLI profile |
|
|
71
|
-
| Profile 管理 | `codex-switcher switch <profile> [--sync\|--no-sync]` | `use` 的等价命令 |
|
|
74
|
+
| Profile 管理 | `codex-switcher use <profile> [--sync\|--no-sync] [--launch\|--no-launch] [-- <codex args...>]` | 切换当前 CLI profile,可选立即启动 `codex` |
|
|
75
|
+
| Profile 管理 | `codex-switcher switch <profile> [--sync\|--no-sync] [--launch\|--no-launch] [-- <codex args...>]` | `use` 的等价命令 |
|
|
72
76
|
| 数据迁移 | `codex-switcher import-default <profile> [--with-auth] [--force]` | 从 `~/.codex` 导入数据到 profile |
|
|
73
77
|
| CLI 登录态 | `codex-switcher login [profile] [--sync\|--no-sync]` | 登录指定或当前 CLI profile |
|
|
74
78
|
| CLI 登录态 | `codex-switcher logout [profile]` | 登出指定或当前 CLI profile |
|
package/package.json
CHANGED
|
@@ -18,8 +18,8 @@ codex-switcher add <profile>
|
|
|
18
18
|
codex-switcher remove <profile> [--force]
|
|
19
19
|
codex-switcher list
|
|
20
20
|
codex-switcher import-default <profile> [--with-auth] [--force]
|
|
21
|
-
codex-switcher use <profile> [--sync|--no-sync]
|
|
22
|
-
codex-switcher switch <profile> [--sync|--no-sync]
|
|
21
|
+
codex-switcher use <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
22
|
+
codex-switcher switch <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
23
23
|
codex-switcher current [cli|app]
|
|
24
24
|
codex-switcher status
|
|
25
25
|
|
|
@@ -75,6 +75,10 @@ codex-switcher import-default work --with-auth
|
|
|
75
75
|
- `login --sync`: overwrite sync from default `~/.codex` to target profile, excluding `auth.json`.
|
|
76
76
|
- `use/switch --sync`: overwrite sync from current CLI profile to target profile, excluding `auth.json`.
|
|
77
77
|
- `--no-sync`: explicit no-sync mode (default behavior).
|
|
78
|
+
- `use/switch` defaults to `--launch=auto`: in interactive terminals, `codex` starts right after switching.
|
|
79
|
+
- `use/switch --launch`: launch `codex` CLI immediately after switching profile.
|
|
80
|
+
- `use/switch --no-launch`: switch pointer only without launching `codex`.
|
|
81
|
+
- `use/switch -- <codex args...>`: run `codex` with provided args after switch (implies launch).
|
|
78
82
|
|
|
79
83
|
Examples:
|
|
80
84
|
|
|
@@ -18,8 +18,8 @@ codex-switcher add <profile>
|
|
|
18
18
|
codex-switcher remove <profile> [--force]
|
|
19
19
|
codex-switcher list
|
|
20
20
|
codex-switcher import-default <profile> [--with-auth] [--force]
|
|
21
|
-
codex-switcher use <profile> [--sync|--no-sync]
|
|
22
|
-
codex-switcher switch <profile> [--sync|--no-sync]
|
|
21
|
+
codex-switcher use <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
22
|
+
codex-switcher switch <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
23
23
|
codex-switcher current [cli|app]
|
|
24
24
|
codex-switcher status
|
|
25
25
|
|
|
@@ -75,6 +75,10 @@ codex-switcher import-default work --with-auth
|
|
|
75
75
|
- `login --sync`:从默认 `~/.codex` 覆盖同步到目标 profile,排除 `auth.json`。
|
|
76
76
|
- `use/switch --sync`:从当前 CLI profile 覆盖同步到目标 profile,排除 `auth.json`。
|
|
77
77
|
- `--no-sync`:显式关闭同步(默认行为)。
|
|
78
|
+
- `use/switch` 默认 `--launch=auto`:交互终端中切换后自动启动 `codex` CLI。
|
|
79
|
+
- `use/switch --launch`:切换后立即以目标 profile 启动 `codex` CLI。
|
|
80
|
+
- `use/switch --no-launch`:切换后只更新 profile 指针,不启动 `codex` CLI。
|
|
81
|
+
- `use/switch -- <codex args...>`:切换后执行指定 `codex` 参数(等价于隐式 `--launch`)。
|
|
78
82
|
|
|
79
83
|
示例:
|
|
80
84
|
|
|
@@ -18,8 +18,8 @@ Usage:
|
|
|
18
18
|
codex-sw remove <profile> [--force]
|
|
19
19
|
codex-sw list
|
|
20
20
|
codex-sw import-default <profile> [--with-auth] [--force]
|
|
21
|
-
codex-sw use <profile> [--sync|--no-sync]
|
|
22
|
-
codex-sw switch <profile> [--sync|--no-sync]
|
|
21
|
+
codex-sw use <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
22
|
+
codex-sw switch <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]
|
|
23
23
|
codex-sw current [cli|app]
|
|
24
24
|
codex-sw status
|
|
25
25
|
|
|
@@ -514,15 +514,53 @@ cmd_use() {
|
|
|
514
514
|
ensure_profile "$profile"
|
|
515
515
|
set_current cli "$profile"
|
|
516
516
|
log_event INFO "cli_use profile=$profile sync=$sync_mode"
|
|
517
|
-
echo "Switched CLI profile to: $profile"
|
|
518
|
-
echo "Run in current shell if needed:"
|
|
519
|
-
echo " export CODEX_HOME='$(profile_path "$profile")'"
|
|
520
517
|
}
|
|
521
518
|
|
|
522
519
|
cmd_switch() {
|
|
523
520
|
cmd_use "$1" "${2:-false}"
|
|
524
521
|
}
|
|
525
522
|
|
|
523
|
+
should_launch_codex() {
|
|
524
|
+
local mode="$1"
|
|
525
|
+
case "$mode" in
|
|
526
|
+
true)
|
|
527
|
+
return 0
|
|
528
|
+
;;
|
|
529
|
+
false)
|
|
530
|
+
return 1
|
|
531
|
+
;;
|
|
532
|
+
auto)
|
|
533
|
+
[[ -t 0 && -t 1 ]]
|
|
534
|
+
;;
|
|
535
|
+
*)
|
|
536
|
+
return 1
|
|
537
|
+
;;
|
|
538
|
+
esac
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
cmd_use_and_maybe_launch() {
|
|
542
|
+
local mode_cmd="$1"
|
|
543
|
+
local profile="$2"
|
|
544
|
+
local sync_mode="${3:-false}"
|
|
545
|
+
local launch_mode="${4:-auto}"
|
|
546
|
+
shift 4 || true
|
|
547
|
+
|
|
548
|
+
with_lock "$mode_cmd" "$profile" "$sync_mode"
|
|
549
|
+
|
|
550
|
+
echo "Switched CLI profile to: $profile"
|
|
551
|
+
if should_launch_codex "$launch_mode"; then
|
|
552
|
+
echo "Launching codex with profile: $profile"
|
|
553
|
+
CODEX_HOME="$(profile_path "$profile")" command codex "$@"
|
|
554
|
+
return
|
|
555
|
+
fi
|
|
556
|
+
|
|
557
|
+
if [[ "$launch_mode" == "auto" ]]; then
|
|
558
|
+
echo "Auto launch skipped (non-interactive shell). Use --launch to force start."
|
|
559
|
+
fi
|
|
560
|
+
echo "Run in current shell if needed:"
|
|
561
|
+
echo " export CODEX_HOME='$(profile_path "$profile")'"
|
|
562
|
+
}
|
|
563
|
+
|
|
526
564
|
cmd_current() {
|
|
527
565
|
local target="${1:-all}"
|
|
528
566
|
case "$target" in
|
|
@@ -977,30 +1015,88 @@ main() {
|
|
|
977
1015
|
with_lock cmd_import_default "$profile" "$with_auth" "$force"
|
|
978
1016
|
;;
|
|
979
1017
|
use)
|
|
980
|
-
[[ "$#" -ge 1
|
|
1018
|
+
[[ "$#" -ge 1 ]] || err "usage: $SCRIPT_NAME use <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]"
|
|
981
1019
|
local profile="$1"
|
|
1020
|
+
shift
|
|
982
1021
|
local sync="false"
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
1022
|
+
local launch="auto"
|
|
1023
|
+
local codex_args=()
|
|
1024
|
+
while [[ "$#" -gt 0 ]]; do
|
|
1025
|
+
case "$1" in
|
|
1026
|
+
--sync)
|
|
1027
|
+
sync="true"
|
|
1028
|
+
;;
|
|
1029
|
+
--no-sync)
|
|
1030
|
+
sync="false"
|
|
1031
|
+
;;
|
|
1032
|
+
--launch)
|
|
1033
|
+
launch="true"
|
|
1034
|
+
;;
|
|
1035
|
+
--no-launch)
|
|
1036
|
+
launch="false"
|
|
1037
|
+
;;
|
|
1038
|
+
--)
|
|
1039
|
+
shift
|
|
1040
|
+
codex_args=("$@")
|
|
1041
|
+
break
|
|
1042
|
+
;;
|
|
1043
|
+
*)
|
|
1044
|
+
err "unknown option: $1"
|
|
1045
|
+
;;
|
|
1046
|
+
esac
|
|
1047
|
+
shift
|
|
1048
|
+
done
|
|
1049
|
+
if [[ "${#codex_args[@]}" -gt 0 ]]; then
|
|
1050
|
+
[[ "$launch" != "false" ]] || err "cannot pass codex args with --no-launch"
|
|
1051
|
+
launch="true"
|
|
1052
|
+
fi
|
|
1053
|
+
if [[ "${#codex_args[@]}" -gt 0 ]]; then
|
|
1054
|
+
cmd_use_and_maybe_launch cmd_use "$profile" "$sync" "$launch" "${codex_args[@]}"
|
|
987
1055
|
else
|
|
988
|
-
|
|
1056
|
+
cmd_use_and_maybe_launch cmd_use "$profile" "$sync" "$launch"
|
|
989
1057
|
fi
|
|
990
|
-
with_lock cmd_use "$profile" "$sync"
|
|
991
1058
|
;;
|
|
992
1059
|
switch)
|
|
993
|
-
[[ "$#" -ge 1
|
|
1060
|
+
[[ "$#" -ge 1 ]] || err "usage: $SCRIPT_NAME switch <profile> [--sync|--no-sync] [--launch|--no-launch] [-- <codex args...>]"
|
|
994
1061
|
local profile="$1"
|
|
1062
|
+
shift
|
|
995
1063
|
local sync="false"
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1064
|
+
local launch="auto"
|
|
1065
|
+
local codex_args=()
|
|
1066
|
+
while [[ "$#" -gt 0 ]]; do
|
|
1067
|
+
case "$1" in
|
|
1068
|
+
--sync)
|
|
1069
|
+
sync="true"
|
|
1070
|
+
;;
|
|
1071
|
+
--no-sync)
|
|
1072
|
+
sync="false"
|
|
1073
|
+
;;
|
|
1074
|
+
--launch)
|
|
1075
|
+
launch="true"
|
|
1076
|
+
;;
|
|
1077
|
+
--no-launch)
|
|
1078
|
+
launch="false"
|
|
1079
|
+
;;
|
|
1080
|
+
--)
|
|
1081
|
+
shift
|
|
1082
|
+
codex_args=("$@")
|
|
1083
|
+
break
|
|
1084
|
+
;;
|
|
1085
|
+
*)
|
|
1086
|
+
err "unknown option: $1"
|
|
1087
|
+
;;
|
|
1088
|
+
esac
|
|
1089
|
+
shift
|
|
1090
|
+
done
|
|
1091
|
+
if [[ "${#codex_args[@]}" -gt 0 ]]; then
|
|
1092
|
+
[[ "$launch" != "false" ]] || err "cannot pass codex args with --no-launch"
|
|
1093
|
+
launch="true"
|
|
1094
|
+
fi
|
|
1095
|
+
if [[ "${#codex_args[@]}" -gt 0 ]]; then
|
|
1096
|
+
cmd_use_and_maybe_launch cmd_switch "$profile" "$sync" "$launch" "${codex_args[@]}"
|
|
1000
1097
|
else
|
|
1001
|
-
|
|
1098
|
+
cmd_use_and_maybe_launch cmd_switch "$profile" "$sync" "$launch"
|
|
1002
1099
|
fi
|
|
1003
|
-
with_lock cmd_switch "$profile" "$sync"
|
|
1004
1100
|
;;
|
|
1005
1101
|
current)
|
|
1006
1102
|
[[ "$#" -le 1 ]] || err "usage: $SCRIPT_NAME current [cli|app]"
|
|
@@ -21,6 +21,7 @@ trap cleanup EXIT INT TERM
|
|
|
21
21
|
cat > "$BIN/codex" <<'FAKE'
|
|
22
22
|
#!/usr/bin/env bash
|
|
23
23
|
set -euo pipefail
|
|
24
|
+
echo "${CODEX_HOME:-}|$*" >> "${CODEX_SWITCHER_TEST_CODEX_LOG:?}"
|
|
24
25
|
if [[ "${1:-}" == "login" && "${2:-}" == "status" ]]; then
|
|
25
26
|
if [[ -f "${CODEX_HOME}/auth.json" ]]; then
|
|
26
27
|
echo "Logged in"
|
|
@@ -64,6 +65,8 @@ export CODEX_SWITCHER_APP_BIN="$BIN/fake-codex-app"
|
|
|
64
65
|
export CODEX_SWITCHER_LOCK_WAIT_SECONDS=2
|
|
65
66
|
export CODEX_SWITCHER_DEFAULT_HOME="$TMPBASE/default-home"
|
|
66
67
|
export CODEX_SWITCHER_TEST_NPM_LOG="$TMPBASE/npm-args.log"
|
|
68
|
+
export CODEX_SWITCHER_TEST_CODEX_LOG="$TMPBASE/codex-args.log"
|
|
69
|
+
: > "$CODEX_SWITCHER_TEST_CODEX_LOG"
|
|
67
70
|
|
|
68
71
|
mkdir -p "$CODEX_SWITCHER_DEFAULT_HOME/memories"
|
|
69
72
|
echo '{"auth_mode":"chatgpt"}' > "$CODEX_SWITCHER_DEFAULT_HOME/auth.json"
|
|
@@ -79,9 +82,22 @@ grep -q "i -g @wangxt0223/codex-switcher@latest --registry https://registry.npmj
|
|
|
79
82
|
|
|
80
83
|
"$SW" add work
|
|
81
84
|
"$SW" add personal
|
|
82
|
-
"$
|
|
85
|
+
codex_calls_before="$(wc -l < "$CODEX_SWITCHER_TEST_CODEX_LOG" 2>/dev/null || echo 0)"
|
|
86
|
+
"$SW" use personal --no-launch
|
|
87
|
+
codex_calls_after="$(wc -l < "$CODEX_SWITCHER_TEST_CODEX_LOG" 2>/dev/null || echo 0)"
|
|
88
|
+
[[ "$codex_calls_before" -eq "$codex_calls_after" ]]
|
|
83
89
|
[[ "$("$SW" current cli)" == "personal" ]]
|
|
84
90
|
|
|
91
|
+
"$SW" use personal -- --version
|
|
92
|
+
grep -Fq "$PROFILES/personal|--version" "$CODEX_SWITCHER_TEST_CODEX_LOG"
|
|
93
|
+
|
|
94
|
+
set +e
|
|
95
|
+
"$SW" use personal --no-launch -- --version >/tmp/codex_sw_use_no_launch_conflict 2>&1
|
|
96
|
+
use_no_launch_conflict_rc=$?
|
|
97
|
+
set -e
|
|
98
|
+
[[ "$use_no_launch_conflict_rc" -ne 0 ]]
|
|
99
|
+
grep -q "cannot pass codex args with --no-launch" /tmp/codex_sw_use_no_launch_conflict
|
|
100
|
+
|
|
85
101
|
"$SW" login personal
|
|
86
102
|
"$SW" login sync-login --sync
|
|
87
103
|
[[ -f "$PROFILES/sync-login/state_5.sqlite" ]]
|