@glidea/codex-switch 0.1.1 → 0.2.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/README.en.md +12 -4
- package/README.md +12 -4
- package/bin/codex-switch.mjs +282 -4
- package/package.json +2 -2
package/README.en.md
CHANGED
|
@@ -52,14 +52,22 @@ Restart is required to load the new profile
|
|
|
52
52
|
## Common Commands
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
|
+
codex-switch <profile>
|
|
55
56
|
codex-switch add <profile>
|
|
57
|
+
codex-switch current
|
|
58
|
+
codex-switch list
|
|
59
|
+
codex-switch edit <profile>
|
|
60
|
+
codex-switch rm <profile>
|
|
61
|
+
codex-switch completion
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Advanced commands
|
|
65
|
+
|
|
66
|
+
```bash
|
|
56
67
|
codex-switch add <profile> --from-current
|
|
57
68
|
codex-switch add <profile> --config <path> --auth <path>
|
|
58
|
-
codex-switch edit <profile>
|
|
59
|
-
codex-switch <profile>
|
|
60
69
|
codex-switch <profile> --copy
|
|
61
|
-
codex-switch
|
|
62
|
-
codex-switch current
|
|
70
|
+
codex-switch completion <zsh|bash|fish|powershell>
|
|
63
71
|
```
|
|
64
72
|
|
|
65
73
|
## File Layout
|
package/README.md
CHANGED
|
@@ -55,14 +55,22 @@ codex-switch glidea
|
|
|
55
55
|
## 常用命令
|
|
56
56
|
|
|
57
57
|
```bash
|
|
58
|
+
codex-switch <profile>
|
|
58
59
|
codex-switch add <profile>
|
|
60
|
+
codex-switch current
|
|
61
|
+
codex-switch list
|
|
62
|
+
codex-switch edit <profile>
|
|
63
|
+
codex-switch rm <profile>
|
|
64
|
+
codex-switch completion
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
高级命令
|
|
68
|
+
|
|
69
|
+
```bash
|
|
59
70
|
codex-switch add <profile> --from-current
|
|
60
71
|
codex-switch add <profile> --config <path> --auth <path>
|
|
61
|
-
codex-switch edit <profile>
|
|
62
|
-
codex-switch <profile>
|
|
63
72
|
codex-switch <profile> --copy
|
|
64
|
-
codex-switch
|
|
65
|
-
codex-switch current
|
|
73
|
+
codex-switch completion <zsh|bash|fish|powershell>
|
|
66
74
|
```
|
|
67
75
|
|
|
68
76
|
## 文件结构
|
package/bin/codex-switch.mjs
CHANGED
|
@@ -15,7 +15,26 @@ function fail(message) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
function usage() {
|
|
18
|
-
console.log(
|
|
18
|
+
console.log(
|
|
19
|
+
"usage: codex-switch <profile>|add <profile>|edit <profile>|rm <profile>|list|current|completion [zsh|bash|fish|powershell] [--copy]"
|
|
20
|
+
)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function help() {
|
|
24
|
+
usage()
|
|
25
|
+
console.log("")
|
|
26
|
+
console.log("commands:")
|
|
27
|
+
console.log(" codex-switch <profile>")
|
|
28
|
+
console.log(" codex-switch <profile> --copy")
|
|
29
|
+
console.log(" codex-switch add <profile>")
|
|
30
|
+
console.log(" codex-switch add <profile> --from-current")
|
|
31
|
+
console.log(" codex-switch add <profile> --config <path> --auth <path>")
|
|
32
|
+
console.log(" codex-switch edit <profile>")
|
|
33
|
+
console.log(" codex-switch rm <profile>")
|
|
34
|
+
console.log(" codex-switch list")
|
|
35
|
+
console.log(" codex-switch current")
|
|
36
|
+
console.log(" codex-switch completion")
|
|
37
|
+
console.log(" codex-switch completion <zsh|bash|fish|powershell>")
|
|
19
38
|
}
|
|
20
39
|
|
|
21
40
|
function profilePaths(profileName) {
|
|
@@ -176,10 +195,244 @@ function editProfile(profileName) {
|
|
|
176
195
|
console.log(`switched to ${profileName}`)
|
|
177
196
|
}
|
|
178
197
|
|
|
198
|
+
function deleteProfile(profileName) {
|
|
199
|
+
const paths = ensureProfileExists(profileName)
|
|
200
|
+
const currentProfile = getCurrentProfileName()
|
|
201
|
+
if (currentProfile === profileName) {
|
|
202
|
+
fail(
|
|
203
|
+
`profile is current: ${profileName}\nswitch to another profile first\nexample: codex-switch <other-profile> && codex-switch delete ${profileName}`
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
fs.rmSync(paths.dirPath, { recursive: true, force: true })
|
|
207
|
+
console.log(`deleted ${profileName}`)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function zshCompletionScript() {
|
|
211
|
+
return `#compdef codex-switch
|
|
212
|
+
|
|
213
|
+
_codex_switch_profiles() {
|
|
214
|
+
local -a profiles
|
|
215
|
+
profiles=("\${(@f)\$(codex-switch list 2>/dev/null)}")
|
|
216
|
+
_describe 'profile' profiles
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
_codex_switch() {
|
|
220
|
+
local -a commands
|
|
221
|
+
commands=(
|
|
222
|
+
'add:add profile'
|
|
223
|
+
'edit:edit profile'
|
|
224
|
+
'list:list profiles'
|
|
225
|
+
'current:show current profile'
|
|
226
|
+
'completion:print shell completion script'
|
|
227
|
+
)
|
|
228
|
+
|
|
229
|
+
if (( CURRENT == 2 )); then
|
|
230
|
+
_alternative 'commands:command:->cmds' 'profiles:profile:_codex_switch_profiles'
|
|
231
|
+
return
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
case "$words[2]" in
|
|
235
|
+
add|edit)
|
|
236
|
+
if (( CURRENT == 3 )); then
|
|
237
|
+
_codex_switch_profiles
|
|
238
|
+
fi
|
|
239
|
+
;;
|
|
240
|
+
completion)
|
|
241
|
+
_values 'shell' zsh bash fish powershell
|
|
242
|
+
;;
|
|
243
|
+
*)
|
|
244
|
+
if (( CURRENT == 2 )); then
|
|
245
|
+
_describe 'command' commands
|
|
246
|
+
fi
|
|
247
|
+
;;
|
|
248
|
+
esac
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
_codex_switch "$@"
|
|
252
|
+
`
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function bashCompletionScript() {
|
|
256
|
+
return `_codex_switch_profiles() {
|
|
257
|
+
codex-switch list 2>/dev/null
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
_codex_switch() {
|
|
261
|
+
local cur prev
|
|
262
|
+
COMPREPLY=()
|
|
263
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
264
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
265
|
+
local commands="add edit list current completion"
|
|
266
|
+
|
|
267
|
+
if [[ \${COMP_CWORD} -eq 1 ]]; then
|
|
268
|
+
local profiles
|
|
269
|
+
profiles="$(_codex_switch_profiles)"
|
|
270
|
+
COMPREPLY=( $(compgen -W "\${commands} \${profiles}" -- "\${cur}") )
|
|
271
|
+
return 0
|
|
272
|
+
fi
|
|
273
|
+
|
|
274
|
+
if [[ "\${prev}" == "completion" ]]; then
|
|
275
|
+
COMPREPLY=( $(compgen -W "zsh bash fish powershell" -- "\${cur}") )
|
|
276
|
+
return 0
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
if [[ "\${COMP_WORDS[1]}" == "add" || "\${COMP_WORDS[1]}" == "edit" ]]; then
|
|
280
|
+
local profiles
|
|
281
|
+
profiles="$(_codex_switch_profiles)"
|
|
282
|
+
COMPREPLY=( $(compgen -W "\${profiles}" -- "\${cur}") )
|
|
283
|
+
return 0
|
|
284
|
+
fi
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
complete -F _codex_switch codex-switch
|
|
288
|
+
`
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function fishCompletionScript() {
|
|
292
|
+
return `function __codex_switch_profiles
|
|
293
|
+
codex-switch list 2>/dev/null
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
complete -c codex-switch -f
|
|
297
|
+
complete -c codex-switch -n '__fish_use_subcommand' -a 'add edit list current completion (__codex_switch_profiles)'
|
|
298
|
+
complete -c codex-switch -n '__fish_seen_subcommand_from add edit' -a '(__codex_switch_profiles)'
|
|
299
|
+
complete -c codex-switch -n '__fish_seen_subcommand_from completion' -a 'zsh bash fish powershell'
|
|
300
|
+
`
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function powershellCompletionScript() {
|
|
304
|
+
return `Register-ArgumentCompleter -Native -CommandName codex-switch -ScriptBlock {
|
|
305
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
306
|
+
$words = $commandAst.CommandElements | ForEach-Object { $_.Extent.Text }
|
|
307
|
+
$commands = @('add', 'edit', 'list', 'current', 'completion')
|
|
308
|
+
$profiles = @(codex-switch list 2>$null)
|
|
309
|
+
$candidates = @()
|
|
310
|
+
|
|
311
|
+
if ($words.Count -le 2) {
|
|
312
|
+
$candidates = $commands + $profiles
|
|
313
|
+
} elseif ($words[1] -eq 'completion') {
|
|
314
|
+
$candidates = @('zsh', 'bash', 'fish', 'powershell')
|
|
315
|
+
} elseif ($words[1] -eq 'add' -or $words[1] -eq 'edit') {
|
|
316
|
+
$candidates = $profiles
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
$candidates |
|
|
320
|
+
Where-Object { $_ -like "$wordToComplete*" } |
|
|
321
|
+
ForEach-Object {
|
|
322
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
`
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
function completionScript(shellName) {
|
|
329
|
+
if (shellName === "zsh") {
|
|
330
|
+
return zshCompletionScript()
|
|
331
|
+
}
|
|
332
|
+
if (shellName === "bash") {
|
|
333
|
+
return bashCompletionScript()
|
|
334
|
+
}
|
|
335
|
+
if (shellName === "fish") {
|
|
336
|
+
return fishCompletionScript()
|
|
337
|
+
}
|
|
338
|
+
if (shellName === "powershell") {
|
|
339
|
+
return powershellCompletionScript()
|
|
340
|
+
}
|
|
341
|
+
fail(`unsupported shell: ${shellName}`)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function printCompletion(shellName) {
|
|
345
|
+
console.log(completionScript(shellName))
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function detectShellName() {
|
|
349
|
+
if (process.platform === "win32") {
|
|
350
|
+
return "powershell"
|
|
351
|
+
}
|
|
352
|
+
const shellPath = process.env.SHELL || ""
|
|
353
|
+
if (shellPath.endsWith("/zsh")) {
|
|
354
|
+
return "zsh"
|
|
355
|
+
}
|
|
356
|
+
if (shellPath.endsWith("/bash")) {
|
|
357
|
+
return "bash"
|
|
358
|
+
}
|
|
359
|
+
if (shellPath.endsWith("/fish")) {
|
|
360
|
+
return "fish"
|
|
361
|
+
}
|
|
362
|
+
fail("cannot detect shell, use: codex-switch completion install <shell>")
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
function appendIfMissing(filePath, marker, block) {
|
|
366
|
+
const content = fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : ""
|
|
367
|
+
if (content.includes(marker)) {
|
|
368
|
+
return
|
|
369
|
+
}
|
|
370
|
+
const next = content.endsWith("\n") || content.length === 0 ? content : `${content}\n`
|
|
371
|
+
fs.writeFileSync(filePath, `${next}${block}\n`)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function installCompletion(shellName) {
|
|
375
|
+
const resolvedShell = shellName || detectShellName()
|
|
376
|
+
const homeDir = os.homedir()
|
|
377
|
+
|
|
378
|
+
if (resolvedShell === "zsh") {
|
|
379
|
+
const zfuncDir = path.join(homeDir, ".zfunc")
|
|
380
|
+
const completionPath = path.join(zfuncDir, "_codex-switch")
|
|
381
|
+
fs.mkdirSync(zfuncDir, { recursive: true })
|
|
382
|
+
fs.writeFileSync(completionPath, completionScript("zsh"))
|
|
383
|
+
const zshrcPath = path.join(homeDir, ".zshrc")
|
|
384
|
+
appendIfMissing(
|
|
385
|
+
zshrcPath,
|
|
386
|
+
"# codex-switch completion",
|
|
387
|
+
"# codex-switch completion\nfpath=(~/.zfunc $fpath)\nautoload -Uz compinit && compinit"
|
|
388
|
+
)
|
|
389
|
+
console.log(`installed zsh completion: ${completionPath}`)
|
|
390
|
+
return
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (resolvedShell === "bash") {
|
|
394
|
+
const dirPath = path.join(homeDir, ".local", "share", "bash-completion", "completions")
|
|
395
|
+
const completionPath = path.join(dirPath, "codex-switch")
|
|
396
|
+
fs.mkdirSync(dirPath, { recursive: true })
|
|
397
|
+
fs.writeFileSync(completionPath, completionScript("bash"))
|
|
398
|
+
console.log(`installed bash completion: ${completionPath}`)
|
|
399
|
+
return
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
if (resolvedShell === "fish") {
|
|
403
|
+
const dirPath = path.join(homeDir, ".config", "fish", "completions")
|
|
404
|
+
const completionPath = path.join(dirPath, "codex-switch.fish")
|
|
405
|
+
fs.mkdirSync(dirPath, { recursive: true })
|
|
406
|
+
fs.writeFileSync(completionPath, completionScript("fish"))
|
|
407
|
+
console.log(`installed fish completion: ${completionPath}`)
|
|
408
|
+
return
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (resolvedShell === "powershell") {
|
|
412
|
+
const codexHomeDir = path.join(homeDir, ".codex")
|
|
413
|
+
const completionPath = path.join(codexHomeDir, "codex-switch-completion.ps1")
|
|
414
|
+
fs.mkdirSync(codexHomeDir, { recursive: true })
|
|
415
|
+
fs.writeFileSync(completionPath, completionScript("powershell"))
|
|
416
|
+
|
|
417
|
+
const profileDirPath = path.join(homeDir, "Documents", "PowerShell")
|
|
418
|
+
const profilePath = path.join(profileDirPath, "Microsoft.PowerShell_profile.ps1")
|
|
419
|
+
fs.mkdirSync(profileDirPath, { recursive: true })
|
|
420
|
+
appendIfMissing(
|
|
421
|
+
profilePath,
|
|
422
|
+
"# codex-switch completion",
|
|
423
|
+
`# codex-switch completion\n. '${completionPath.replace(/'/g, "''")}'`
|
|
424
|
+
)
|
|
425
|
+
console.log(`installed powershell completion: ${profilePath}`)
|
|
426
|
+
return
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
fail(`unsupported shell: ${resolvedShell}`)
|
|
430
|
+
}
|
|
431
|
+
|
|
179
432
|
function run() {
|
|
180
|
-
if (args.length === 0) {
|
|
181
|
-
|
|
182
|
-
process.exit(
|
|
433
|
+
if (args.length === 0 || args[0] === "help" || args[0] === "-h" || args[0] === "--help") {
|
|
434
|
+
help()
|
|
435
|
+
process.exit(0)
|
|
183
436
|
}
|
|
184
437
|
|
|
185
438
|
const command = args[0]
|
|
@@ -194,6 +447,21 @@ function run() {
|
|
|
194
447
|
return
|
|
195
448
|
}
|
|
196
449
|
|
|
450
|
+
if (command === "completion") {
|
|
451
|
+
if (args.length === 1) {
|
|
452
|
+
installCompletion("")
|
|
453
|
+
return
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const shellName = args[1]
|
|
457
|
+
if (!shellName || args.length !== 2) {
|
|
458
|
+
usage()
|
|
459
|
+
process.exit(1)
|
|
460
|
+
}
|
|
461
|
+
printCompletion(shellName)
|
|
462
|
+
return
|
|
463
|
+
}
|
|
464
|
+
|
|
197
465
|
if (command === "add") {
|
|
198
466
|
const profileName = args[1]
|
|
199
467
|
if (!profileName) {
|
|
@@ -214,6 +482,16 @@ function run() {
|
|
|
214
482
|
return
|
|
215
483
|
}
|
|
216
484
|
|
|
485
|
+
if (command === "rm") {
|
|
486
|
+
const profileName = args[1]
|
|
487
|
+
if (!profileName || args.length !== 2) {
|
|
488
|
+
usage()
|
|
489
|
+
process.exit(1)
|
|
490
|
+
}
|
|
491
|
+
deleteProfile(profileName)
|
|
492
|
+
return
|
|
493
|
+
}
|
|
494
|
+
|
|
217
495
|
const profileName = command
|
|
218
496
|
let useCopy = false
|
|
219
497
|
if (args.length > 1) {
|
package/package.json
CHANGED