Skip to content

Feat: Introduced TUI, which supersedes CLI - #36

Merged
TriDefender merged 8 commits into
masterfrom
feat/tui
Aug 30, 2026
Merged

TriDefender merged 8 commits into
masterfrom
feat/tui

Conversation

@TriDefender

Copy link
Copy Markdown
Owner

这下真的是只要会动手指就能用了

- New src/tui/: hand-rolled ANSI renderer, VT input parser, CJK-safe
  display-width math, ring-buffer log pane with tail-following, and the
  app shell (alternate screen + raw mode + console interception) — zero
  new dependencies, Bun/Node compatible, bundles into both artifacts.
- Layout mirrors the Android app: Settings & Login / Proxy Server / Logs
  cards + toast + key-hint footer. Logs land in-pane via console capture;
  optional ZCODE_TUI_LOGFILE tee (best-effort, never affects handling).
- index.ts: new `tui` subcommand (dynamic import, claimCommand pattern);
  extracts updateConfigYaml / openBrowser / buildServerOptions into shared
  modules (config/edit.ts, runtime/open-browser.ts, server/server-options.ts)
  so the TUI reuses them without a static import cycle; exports VERSION.
- Default auth.mode flips apikey -> oauth (loader + template + example
  config): fresh configs onboard via `auth login`, matching the ZCode
  client's connection modes; explicit apikey configs are unaffected.
- 59 new tests (width/log-pane/keys/frame/config-edit + loader defaults);
  full suite 697 passing; verified live in Windows Terminal (render,
  provider switch + YAML persist, oauth start guard, clean quit).
…tton style

- keys.ts: parse SGR mouse events (ESC [< b;x;y M/m) — left-press maps to a
  0-based click, wheel 64/65 to scroll actions; releases, drags, right/middle
  buttons and malformed params are ignored. Escape sequences split across
  stdin chunks still complete.
- frame.ts: interactive rows now render as solid filled buttons (ANSI
  background colors — blue selected chip, green Start / OAuth Login, red
  Stop, gray secondary; dim un-filled for disabled) and buildFrame returns
  the frame text plus exact click hit regions per button. findRegion()
  hit-tests a (row,col) against the regions. Log title bar doubles as a
  follow button while scrolled; footer hints are themselves clickable
  (greedy layout: primary actions survive narrow terminals).
- app.ts: enables mouse reporting (1000h + 1006h, disabled on restore),
  dispatches clicks through the same handlers as the keyboard shortcuts,
  wheel scrolls the log pane by 3 lines. Provider/plan switch guard moved
  into applyConfigChange so clicks and keys share one path.
- A browser-panel GUI prototype was explored and shelved (git stash) —
  this mouse-driven TUI is the chosen direction (opencode-style).
- 709 tests passing (mouse parser, hit regions, filled-button layout).
Previously the selected option rendered first, so clicking zai/bigmodel or
coding-plan/start-plan made the buttons swap positions — a second click at
the same spot hit a different value. Slots are now fixed (zai | bigmodel,
coding-plan | start-plan, matching the Android segmented control); the
selection only changes the fill color, never the position.
Clicking Start on a start-plan config spammed the terminal/log pane with
%c%d font-size:0;color:transparent Error lines (~1/sec). Root cause: the
FeiLin SDK running inside the happy-dom guest escapes the VM realm for
bare-identifier lookups and probes the FULL host console surface
(log/debug/info/dir/table/group/…) with invisible browser-style formatting.
The existing guestConsole shield only covers window/page consoles.

- captcha-happy.ts: installGuestConsoleShield() wraps every function-valued
  host console key and swallows exactly the %c-styled lines (first arg
  startsWith %c or any arg containing font-size:0;color:transparent);
  everything else passes through. Installed at createDom (every captcha
  path), skipped under CAPTCHA_DEBUG. Display-only — no effect on solving
  or rejections. Also fixes the same spam in serve() on start-plan.
- tui/app.ts: intercept ALL console methods into the log pane, not just
  log/warn/error — anything unpatched would bypass the pane and write raw
  into the alt-screen frame.
- Verified with an isolated warmup repro: 0 spam lines in 25s (previously
  dozens); 711 tests passing (new shield unit test).
…pe point

The previous %c-pattern shield was too narrow: the FeiLin SDK also emits
plain-object logs, which reached the TUI pane as [object Object] spam.

Root cause (Bun): guest scripts run in the HOST realm; the globalThis
window-alias pass deliberately skips 'console' (HOST_CRITICAL_GLOBALS), so
a bare 'console' inside SDK code resolved straight to the host console —
any argument shape could escape.

Fix at the escape point itself: while the window aliases are installed,
globalThis.console is replaced with a dual console facade — calls whose
stack originates from alicdn.com/aliyuncs.com script URLs are dropped,
everything else forwards to the console captured at install time (the
TUI's interception or the serve terminal). Descriptor is saved at install
and restored on the last destroyDom (ref-counted like the aliases), so
host logging is untouched between solves. CAPTCHA_DEBUG skips the facade.

Verified on a real warmup: 0 spam lines ([object Object] or %c) and the
pool still minted 20 tokens; the pool's own host-side warnings still flow.
711 tests passing (dual-console unit test replaces the pattern test).
…lor)

Replace the bright ANSI green/red/blue/gray fills with muted 24-bit
truecolor equivalents (#238636 success / #da3633 danger / #1f6feb
primary / #30363d secondary). Modern terminals (Windows Terminal, mintty)
render natively; legacy terminals fall back with text intact.
- tui/app.ts: no-arg AuthManager + setOAuthCredential (oauth-only API);
  startProxy always requires a stored credential; drop all auth.mode
  branches (login guard, claim gate, boot hint); provider/plan switching
  no longer recreates the manager.
- tui/frame.ts: drop the authMode field and the apikey-mode Auth row —
  the pane is oauth-only like the proxy.
- loader.test.ts: remove the two pre-merge oauth-default tests (superseded
  by master's legacy-key-ignore test).
- Android server_bundle rebuilt from the merged tree (includes TUI +
  oauth-only).
@TriDefender TriDefender self-assigned this Aug 30, 2026
@TriDefender
TriDefender merged commit 0ad1324 into master Aug 30, 2026
1 check passed
@TriDefender
TriDefender deleted the feat/tui branch August 30, 2026 12:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant