teamclaude-cloud 1.5.5 → 1.5.6

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tui.js +18 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "teamclaude-cloud",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Multi-account Claude proxy with quota-based rotation + cloud token sync and auth-key control",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/tui.js CHANGED
@@ -201,12 +201,26 @@ export class TUI {
201
201
  }
202
202
 
203
203
  _addLog(msg) {
204
- msg = msg.replace(/^\[TeamClaude\]\s*/, '');
205
- this.log.unshift({ t: timestamp(), msg });
204
+ // Store RAW; masking is applied at RENDER time (_maskLog) so a mid-session mask
205
+ // toggle re-masks already-buffered lines too (Codex HIGH: buffered logs stayed raw).
206
+ this.log.unshift({ t: timestamp(), msg: msg.replace(/^\[TeamClaude\]\s*/, '') });
206
207
  if (this.log.length > 200) this.log.length = 200;
207
208
  if (this.running) this.render();
208
209
  }
209
210
 
211
+ // Mask every email in a log line when mask mode is on — applied at RENDER time. Uses
212
+ // an email REGEX (not the current account list) so it also masks a just-deleted
213
+ // account's name and can't partially expose one email that is a substring of another
214
+ // (Codex HIGH ×3). Covers TUI-generated lines AND redirected server/account-manager
215
+ // console output, so ordinary request/activity logging can't bypass mask mode.
216
+ _maskLog(s) {
217
+ if (this.config?.maskMode !== true || typeof s !== 'string') return s;
218
+ return s.replace(/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, (m) => maskIf(m, true));
219
+ }
220
+
221
+ // Mask a single account name for direct render (active-requests line, etc.).
222
+ _mn(name) { return maskIf(name, this.config?.maskMode === true); }
223
+
210
224
  // ── input handling ─────────────────────────────────
211
225
 
212
226
  _onData(d) {
@@ -736,7 +750,7 @@ export class TUI {
736
750
  for (const [, r] of this.active) {
737
751
  const el = ((now - r.started) / 1000).toFixed(1);
738
752
  const sp = cyan(SPINNER[this.frame]);
739
- const a = r.account ? ` → ${r.account}` : '';
753
+ const a = r.account ? ` → ${this._mn(r.account)}` : '';
740
754
  lines.push(` ${sp} ${gray(r.t)} ${r.method} ${r.path}${a} ${dim(`(${el}s...)`)}`);
741
755
  }
742
756
 
@@ -744,7 +758,7 @@ export class TUI {
744
758
  const footerH = 2;
745
759
  const space = Math.max(0, H - lines.length - footerH);
746
760
  for (let i = 0; i < space && i < this.log.length; i++) {
747
- lines.push(` ${gray(this.log[i].t)} ${this.log[i].msg}`);
761
+ lines.push(` ${gray(this.log[i].t)} ${this._maskLog(this.log[i].msg)}`);
748
762
  }
749
763
 
750
764
  // Pad to fill