@wangxt0223/codex-switcher 0.4.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 +38 -0
- package/LICENSE +21 -0
- package/README.en.md +91 -0
- package/README.md +92 -0
- package/docs/macos-manual-checklist.md +34 -0
- package/docs/publish.md +41 -0
- package/docs/upgrade.md +31 -0
- package/package.json +46 -0
- package/plugins/codex-switcher/.app.json +3 -0
- package/plugins/codex-switcher/.codex-plugin/plugin.json +48 -0
- package/plugins/codex-switcher/.mcp.json +3 -0
- package/plugins/codex-switcher/README.en.md +112 -0
- package/plugins/codex-switcher/README.md +112 -0
- package/plugins/codex-switcher/assets/icon.png +0 -0
- package/plugins/codex-switcher/assets/logo.png +0 -0
- package/plugins/codex-switcher/assets/screenshot1.png +0 -0
- package/plugins/codex-switcher/hooks.json +3 -0
- package/plugins/codex-switcher/scripts/codex-sw +5 -0
- package/plugins/codex-switcher/scripts/codex-switcher +1133 -0
- package/plugins/codex-switcher/scripts/test-switcher.sh +183 -0
- package/plugins/codex-switcher/skills/README.md +3 -0
- package/scripts/install.sh +15 -0
- package/scripts/uninstall.sh +37 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
+
SW="$ROOT/scripts/codex-sw"
|
|
6
|
+
|
|
7
|
+
bash -n "$SW"
|
|
8
|
+
|
|
9
|
+
TMPBASE="$(mktemp -d /tmp/codex-switcher-test.XXXXXX)"
|
|
10
|
+
STATE="$TMPBASE/state"
|
|
11
|
+
PROFILES="$TMPBASE/profiles"
|
|
12
|
+
BIN="$TMPBASE/bin"
|
|
13
|
+
mkdir -p "$BIN"
|
|
14
|
+
|
|
15
|
+
cleanup() {
|
|
16
|
+
pkill -f "$BIN/fake-codex-app" >/dev/null 2>&1 || true
|
|
17
|
+
rm -rf "$TMPBASE"
|
|
18
|
+
}
|
|
19
|
+
trap cleanup EXIT INT TERM
|
|
20
|
+
|
|
21
|
+
cat > "$BIN/codex" <<'FAKE'
|
|
22
|
+
#!/usr/bin/env bash
|
|
23
|
+
set -euo pipefail
|
|
24
|
+
if [[ "${1:-}" == "login" && "${2:-}" == "status" ]]; then
|
|
25
|
+
if [[ -f "${CODEX_HOME}/auth.json" ]]; then
|
|
26
|
+
echo "Logged in"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
echo "Not logged in"
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
if [[ "${1:-}" == "login" ]]; then
|
|
33
|
+
mkdir -p "$CODEX_HOME"
|
|
34
|
+
echo '{"auth_mode":"api_key"}' > "$CODEX_HOME/auth.json"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
if [[ "${1:-}" == "logout" ]]; then
|
|
38
|
+
rm -f "$CODEX_HOME/auth.json"
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
exit 0
|
|
42
|
+
FAKE
|
|
43
|
+
chmod +x "$BIN/codex"
|
|
44
|
+
|
|
45
|
+
cat > "$BIN/fake-codex-app" <<'APP'
|
|
46
|
+
#!/usr/bin/env bash
|
|
47
|
+
set -euo pipefail
|
|
48
|
+
sleep 30
|
|
49
|
+
APP
|
|
50
|
+
chmod +x "$BIN/fake-codex-app"
|
|
51
|
+
|
|
52
|
+
cat > "$BIN/npm" <<'NPM'
|
|
53
|
+
#!/usr/bin/env bash
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
echo "$*" > "${CODEX_SWITCHER_TEST_NPM_LOG:?}"
|
|
56
|
+
exit 0
|
|
57
|
+
NPM
|
|
58
|
+
chmod +x "$BIN/npm"
|
|
59
|
+
|
|
60
|
+
export PATH="$BIN:$PATH"
|
|
61
|
+
export CODEX_SWITCHER_STATE_DIR="$STATE"
|
|
62
|
+
export CODEX_SWITCHER_PROFILES_DIR="$PROFILES"
|
|
63
|
+
export CODEX_SWITCHER_APP_BIN="$BIN/fake-codex-app"
|
|
64
|
+
export CODEX_SWITCHER_LOCK_WAIT_SECONDS=2
|
|
65
|
+
export CODEX_SWITCHER_DEFAULT_HOME="$TMPBASE/default-home"
|
|
66
|
+
export CODEX_SWITCHER_TEST_NPM_LOG="$TMPBASE/npm-args.log"
|
|
67
|
+
|
|
68
|
+
mkdir -p "$CODEX_SWITCHER_DEFAULT_HOME/memories"
|
|
69
|
+
echo '{"auth_mode":"chatgpt"}' > "$CODEX_SWITCHER_DEFAULT_HOME/auth.json"
|
|
70
|
+
echo '{"projects":["demo"]}' > "$CODEX_SWITCHER_DEFAULT_HOME/state_5.sqlite"
|
|
71
|
+
echo '{"memo":"persist"}' > "$CODEX_SWITCHER_DEFAULT_HOME/memories/demo.json"
|
|
72
|
+
|
|
73
|
+
check_out="$("$SW" check)"
|
|
74
|
+
echo "$check_out" | grep -q "check: ok"
|
|
75
|
+
init_out="$("$SW" init --dry-run)"
|
|
76
|
+
echo "$init_out" | grep -q "\[dry-run\]"
|
|
77
|
+
"$SW" upgrade
|
|
78
|
+
grep -q "i -g @wangxt0223/codex-switcher@latest --registry https://registry.npmjs.org/" "$CODEX_SWITCHER_TEST_NPM_LOG"
|
|
79
|
+
|
|
80
|
+
"$SW" add work
|
|
81
|
+
"$SW" add personal
|
|
82
|
+
"$SW" use personal
|
|
83
|
+
[[ "$("$SW" current cli)" == "personal" ]]
|
|
84
|
+
|
|
85
|
+
"$SW" login personal
|
|
86
|
+
"$SW" login sync-login --sync
|
|
87
|
+
[[ -f "$PROFILES/sync-login/state_5.sqlite" ]]
|
|
88
|
+
[[ -f "$PROFILES/sync-login/memories/demo.json" ]]
|
|
89
|
+
[[ -f "$PROFILES/sync-login/auth.json" ]]
|
|
90
|
+
|
|
91
|
+
echo '{"auth_mode":"api_key","owner":"personal"}' > "$PROFILES/personal/auth.json"
|
|
92
|
+
echo '{"auth_mode":"api_key","owner":"work"}' > "$PROFILES/work/auth.json"
|
|
93
|
+
echo "from-personal-newer" > "$PROFILES/personal/history.jsonl"
|
|
94
|
+
echo "from-work-older-baseline" > "$PROFILES/work/history.jsonl"
|
|
95
|
+
"$SW" switch work --sync
|
|
96
|
+
[[ "$("$SW" current cli)" == "work" ]]
|
|
97
|
+
grep -q "from-personal-newer" "$PROFILES/work/history.jsonl"
|
|
98
|
+
grep -q '"owner":"work"' "$PROFILES/work/auth.json"
|
|
99
|
+
grep -q '"owner":"personal"' "$PROFILES/personal/auth.json"
|
|
100
|
+
|
|
101
|
+
"$SW" import-default imported
|
|
102
|
+
[[ -f "$PROFILES/imported/state_5.sqlite" ]]
|
|
103
|
+
[[ -f "$PROFILES/imported/memories/demo.json" ]]
|
|
104
|
+
[[ ! -f "$PROFILES/imported/auth.json" ]]
|
|
105
|
+
set +e
|
|
106
|
+
CODEX_HOME="$PROFILES/imported" codex login status >/tmp/codex_sw_imported_login 2>&1
|
|
107
|
+
imported_login_rc=$?
|
|
108
|
+
set -e
|
|
109
|
+
[[ "$imported_login_rc" -ne 0 ]]
|
|
110
|
+
|
|
111
|
+
"$SW" import-default imported-auth --with-auth
|
|
112
|
+
[[ -f "$PROFILES/imported-auth/auth.json" ]]
|
|
113
|
+
CODEX_HOME="$PROFILES/imported-auth" codex login status >/tmp/codex_sw_imported_auth_login 2>&1
|
|
114
|
+
[[ "$?" -eq 0 ]]
|
|
115
|
+
|
|
116
|
+
"$SW" logout work
|
|
117
|
+
|
|
118
|
+
set +e
|
|
119
|
+
"$SW" app open ghost >/tmp/codex_sw_app_open_missing 2>&1
|
|
120
|
+
app_open_missing_rc=$?
|
|
121
|
+
set -e
|
|
122
|
+
[[ "$app_open_missing_rc" -ne 0 ]]
|
|
123
|
+
grep -q "profile 'ghost' not found" /tmp/codex_sw_app_open_missing
|
|
124
|
+
|
|
125
|
+
set +e
|
|
126
|
+
"$SW" app use work >/tmp/codex_sw_app_use_unauthed 2>&1
|
|
127
|
+
app_use_unauthed_rc=$?
|
|
128
|
+
set -e
|
|
129
|
+
[[ "$app_use_unauthed_rc" -ne 0 ]]
|
|
130
|
+
grep -q "profile 'work' is not logged in" /tmp/codex_sw_app_use_unauthed
|
|
131
|
+
|
|
132
|
+
"$SW" login work
|
|
133
|
+
"$SW" app use work
|
|
134
|
+
[[ "$("$SW" app current)" == "work" ]]
|
|
135
|
+
|
|
136
|
+
set +e
|
|
137
|
+
"$SW" status >/tmp/codex_sw_status_1
|
|
138
|
+
status_rc=$?
|
|
139
|
+
set -e
|
|
140
|
+
[[ "$status_rc" -eq 0 ]]
|
|
141
|
+
grep -q "cli(work): logged-in" /tmp/codex_sw_status_1
|
|
142
|
+
grep -q "app(work): logged-in" /tmp/codex_sw_status_1
|
|
143
|
+
|
|
144
|
+
"$SW" logout work
|
|
145
|
+
set +e
|
|
146
|
+
"$SW" status >/tmp/codex_sw_status_2
|
|
147
|
+
status_rc=$?
|
|
148
|
+
set -e
|
|
149
|
+
[[ "$status_rc" -eq 1 ]]
|
|
150
|
+
grep -q "cli(work): not-logged-in" /tmp/codex_sw_status_2
|
|
151
|
+
|
|
152
|
+
"$SW" app status >/tmp/codex_sw_app_status_1
|
|
153
|
+
[[ "$?" -eq 0 ]]
|
|
154
|
+
grep -q "running" /tmp/codex_sw_app_status_1
|
|
155
|
+
|
|
156
|
+
"$SW" app stop
|
|
157
|
+
set +e
|
|
158
|
+
"$SW" app status >/tmp/codex_sw_app_status_2
|
|
159
|
+
app_status_rc=$?
|
|
160
|
+
set -e
|
|
161
|
+
[[ "$app_status_rc" -eq 1 ]]
|
|
162
|
+
|
|
163
|
+
printf '***bad***\n' > "$STATE/current_cli"
|
|
164
|
+
set +e
|
|
165
|
+
"$SW" status >/tmp/codex_sw_status_3
|
|
166
|
+
status_rc=$?
|
|
167
|
+
set -e
|
|
168
|
+
[[ "$status_rc" -eq 2 ]]
|
|
169
|
+
|
|
170
|
+
"$SW" recover
|
|
171
|
+
validate_cli="$("$SW" current cli)"
|
|
172
|
+
[[ -n "$validate_cli" ]]
|
|
173
|
+
|
|
174
|
+
doctor_out="$("$SW" doctor --fix)"
|
|
175
|
+
echo "$doctor_out" | grep -q "doctor --fix: completed"
|
|
176
|
+
check_out="$("$SW" check)"
|
|
177
|
+
echo "$check_out" | grep -q "check: ok"
|
|
178
|
+
|
|
179
|
+
"$SW" remove work --force
|
|
180
|
+
"$SW" list >/tmp/codex_sw_list
|
|
181
|
+
grep -q "personal" /tmp/codex_sw_list
|
|
182
|
+
|
|
183
|
+
echo "smoke-test: ok"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
+
BIN="$ROOT/plugins/codex-switcher/scripts/codex-sw"
|
|
6
|
+
|
|
7
|
+
[[ -x "$BIN" ]] || { echo "codex-sw binary not executable: $BIN" >&2; exit 1; }
|
|
8
|
+
|
|
9
|
+
mkdir -p "$HOME/.local/bin"
|
|
10
|
+
ln -sf "$BIN" "$HOME/.local/bin/codex-sw"
|
|
11
|
+
ln -sf "$ROOT/plugins/codex-switcher/scripts/codex-switcher" "$HOME/.local/bin/codex-switcher"
|
|
12
|
+
|
|
13
|
+
"$BIN" init --shell "$(basename "${SHELL:-zsh}")"
|
|
14
|
+
|
|
15
|
+
echo "Installed codex-sw. Run: source ~/.zshrc (or your shell rc file)"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
PURGE="false"
|
|
5
|
+
if [[ "${1:-}" == "--purge" ]]; then
|
|
6
|
+
PURGE="true"
|
|
7
|
+
elif [[ -n "${1:-}" ]]; then
|
|
8
|
+
echo "Usage: $0 [--purge]" >&2
|
|
9
|
+
exit 1
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
remove_block() {
|
|
13
|
+
local file="$1"
|
|
14
|
+
local start="# >>> codex-sw init >>>"
|
|
15
|
+
local end="# <<< codex-sw init <<<"
|
|
16
|
+
[[ -f "$file" ]] || return 0
|
|
17
|
+
|
|
18
|
+
awk -v s="$start" -v e="$end" '
|
|
19
|
+
$0 == s {skip=1; next}
|
|
20
|
+
$0 == e {skip=0; next}
|
|
21
|
+
skip != 1 {print}
|
|
22
|
+
' "$file" > "$file.tmp"
|
|
23
|
+
mv "$file.tmp" "$file"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
rm -f "$HOME/.local/bin/codex-sw" "$HOME/.local/bin/codex-switcher"
|
|
27
|
+
remove_block "$HOME/.zshrc"
|
|
28
|
+
remove_block "$HOME/.bashrc"
|
|
29
|
+
|
|
30
|
+
if [[ "$PURGE" == "true" ]]; then
|
|
31
|
+
rm -rf "$HOME/.codex-switcher" "$HOME/.codex-profiles"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
echo "Uninstalled codex-sw."
|
|
35
|
+
if [[ "$PURGE" == "true" ]]; then
|
|
36
|
+
echo "State and profiles removed."
|
|
37
|
+
fi
|