@carjms/codexswitch 0.6.0 → 0.6.2

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.ko.md CHANGED
@@ -218,6 +218,7 @@ cxs list # 계정별 5h/week 사용량 % 확인
218
218
  | `cxs order [이름들...]` | 로테이션 순서 고정(pin); 나열하지 않은 계정은 **주간 리셋이 빠른 순**으로 자동 소진 (use-or-lose) |
219
219
  | `cxs model [모델명]` | `run`/`exec`에 자동 적용할 기본 모델 설정 (`default`로 초기화) |
220
220
  | `cxs threshold [5h%] [주간%]` | 사용량이 이 퍼센트에 도달하면 다음 계정으로 전환 (기본 95, 값 하나면 둘 다) |
221
+ | `cxs reasoning <show\|concise\|hide>` | 실행 중 모델 추론("생각") 출력량 조절 — `hide`는 완전 숨김, `concise`는 한 줄 요약 |
221
222
  | `cxs patterns [add/remove]` | 한도 감지에 쓸 커스텀 정규식 패턴 추가/삭제 |
222
223
  | `cxs export <파일>` | 전체 계정·설정 백업 (⚠️ 토큰 포함 — 비밀번호처럼 취급) |
223
224
  | `cxs restore <파일>` | 백업 파일에서 계정 복원 (다른 PC 이전용) |
package/README.md CHANGED
@@ -220,6 +220,7 @@ cxs list # per-account 5h/week usage columns
220
220
  | `cxs order [names...]` | Pin the rotation order; unlisted accounts rotate by **soonest weekly reset** (use-or-lose) |
221
221
  | `cxs model [name]` | Set the default model injected into `run`/`exec` (`default` to reset) |
222
222
  | `cxs threshold [5h%] [wk%]` | Rotate to the next account when usage reaches these percents (default 95; one value sets both) |
223
+ | `cxs reasoning <show\|concise\|hide>` | How much model reasoning ("thinking") to print during runs — `hide` for clean output, `concise` for one-line summaries |
223
224
  | `cxs patterns [add/remove]` | Custom regex patterns treated as rate-limit errors |
224
225
  | `cxs export <file>` | Back up all accounts + settings (⚠️ contains tokens — treat like a password) |
225
226
  | `cxs restore <file>` | Restore accounts from a backup (for moving machines) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carjms/codexswitch",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Multi-account manager for OpenAI Codex CLI with quota-based rotation (inspired by KarpelesLab/teamclaude)",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/cli.js CHANGED
@@ -51,6 +51,8 @@ Running codex
51
51
 
52
52
  Settings
53
53
  model [name|default] show/set the default model injected into run/exec
54
+ reasoning [mode] how much model reasoning to print during runs:
55
+ show (codex default) | concise | hide
54
56
  threshold [5h%] [wk%] rotate early when recorded usage reaches these percents
55
57
  of the 5-hour / weekly window (default 95, one value = both)
56
58
  cooldown [minutes] show/set rate-limit cooldown (default 60)
@@ -642,7 +644,7 @@ function cmdNames() {
642
644
 
643
645
  const COMMANDS =
644
646
  'login import add-key list usage watch probe log chat server use current next run exec order model remove rename ' +
645
- 'enable disable priority clear-limit cooldown threshold patterns export restore sync completion help';
647
+ 'enable disable priority clear-limit cooldown threshold reasoning patterns export restore sync completion help';
646
648
 
647
649
  function cmdCompletion(args) {
648
650
  const shell = args[0];
@@ -682,9 +684,42 @@ function injectExecFlags(rest, meta) {
682
684
  if (!args.includes('--skip-git-repo-check')) args.unshift('--skip-git-repo-check');
683
685
  const hasModel = args.some((a) => a === '-m' || a === '--model' || a.startsWith('--model='));
684
686
  if (meta.model && !hasModel) args.unshift('-m', meta.model);
687
+ args.unshift(...reasoningFlags(meta, args));
685
688
  return args;
686
689
  }
687
690
 
691
+ // -c overrides implementing "cxs reasoning hide|concise|show".
692
+ function reasoningFlags(meta, existing = []) {
693
+ if (!meta.reasoning || meta.reasoning === 'show') return [];
694
+ if (existing.some((a) => /hide_agent_reasoning|model_reasoning_summary/.test(a))) return [];
695
+ if (meta.reasoning === 'hide') return ['-c', 'hide_agent_reasoning=true'];
696
+ return ['-c', 'model_reasoning_summary=concise']; // 'concise'
697
+ }
698
+
699
+ function cmdReasoning(args) {
700
+ const meta = store.loadMeta();
701
+ if (args[0] == null) {
702
+ out(`reasoning: ${meta.reasoning || 'show'} ${ui.dim('(show | concise | hide)')}`);
703
+ return;
704
+ }
705
+ const value = args[0];
706
+ if (!['show', 'concise', 'hide'].includes(value)) {
707
+ throw new Error('usage: codexswitch reasoning <show|concise|hide>');
708
+ }
709
+ if (value === 'show') delete meta.reasoning;
710
+ else meta.reasoning = value;
711
+ store.saveMeta(meta);
712
+ out(
713
+ ui.ok(
714
+ value === 'hide'
715
+ ? 'reasoning output hidden (hide_agent_reasoning=true)'
716
+ : value === 'concise'
717
+ ? 'reasoning output shortened (model_reasoning_summary=concise)'
718
+ : 'reasoning output back to codex default'
719
+ )
720
+ );
721
+ }
722
+
688
723
  // EXPERIMENTAL: foreground proxy server for per-request rotation.
689
724
  async function cmdServer(args) {
690
725
  const proxy = require('./proxy.js');
@@ -744,8 +779,10 @@ async function cmdRun(args) {
744
779
  const meta = store.loadMeta();
745
780
  if (rest[0] === 'exec') {
746
781
  rest = ['exec', ...buildExecArgs(rest.slice(1), meta)];
747
- } else if (meta.model && rest.length === 0) {
748
- rest = ['-m', meta.model];
782
+ } else if (rest.length === 0) {
783
+ // interactive TUI launch — apply the same defaults
784
+ if (meta.model) rest = ['-m', meta.model];
785
+ rest = [...reasoningFlags(meta), ...rest];
749
786
  }
750
787
  out(ui.info(`running codex as ${ui.bold(`"${name}"`)}${proxyPort ? ui.dim(` via proxy :${proxyPort}`) : ''}`));
751
788
  const startTs = Date.now();
@@ -772,6 +809,14 @@ async function cmdExec(args) {
772
809
  if (explicit && !store.accountExists(explicit)) throw new Error(`no such account: ${explicit}`);
773
810
  if (rest[0] === 'resume') allowResume = false; // user drives resume themselves
774
811
 
812
+ // A prompt like "- item one ..." would be parsed as an option by codex;
813
+ // if the last argument starts with "-" but contains whitespace it can only
814
+ // be a prompt, so protect it with a "--" separator.
815
+ if (!rest.includes('--')) {
816
+ const last = rest[rest.length - 1];
817
+ if (last && /^-/.test(last) && /\s/.test(last)) rest.splice(rest.length - 1, 0, '--');
818
+ }
819
+
775
820
  store.syncBack(); // pick up tokens refreshed by plain codex before overlaying
776
821
  const meta = store.loadMeta();
777
822
  const total = store.listAccounts().length;
@@ -795,7 +840,7 @@ async function cmdExec(args) {
795
840
  // On rotation, continue the same session with the next account instead
796
841
  // of restarting the whole prompt — the session files are shared.
797
842
  const codexArgs = useResume
798
- ? ['exec', 'resume', '--last', ...buildExecArgs([], meta), RESUME_PROMPT]
843
+ ? ['exec', 'resume', '--last', ...buildExecArgs([], meta), '--', RESUME_PROMPT]
799
844
  : ['exec', ...buildExecArgs(rest, meta)];
800
845
  const startTs = Date.now();
801
846
  const res = await runner.runCodex(name, codexArgs, { capture: true });
@@ -900,7 +945,9 @@ async function cmdChat() {
900
945
  continue;
901
946
  }
902
947
 
903
- const code = await cmdExec(inSession ? ['resume', '--last', line] : [line]);
948
+ // "--" marks the prompt as positional so lines starting with "-" are
949
+ // never parsed as codex options.
950
+ const code = await cmdExec(inSession ? ['resume', '--last', '--', line] : ['--', line]);
904
951
  if (code === 0) inSession = true;
905
952
  else if (code === 2) out(ui.fail('all accounts exhausted — try again later or /use a specific account'));
906
953
  }
@@ -980,6 +1027,8 @@ async function main(argv) {
980
1027
  return cmdOrder(args), 0;
981
1028
  case 'model':
982
1029
  return cmdModel(args), 0;
1030
+ case 'reasoning':
1031
+ return cmdReasoning(args), 0;
983
1032
  case 'add-key':
984
1033
  case 'apikey':
985
1034
  return cmdAddKey(args), 0;