Skip to content

feat: command system, stable session switch, streaming, and UI polish#58

Open
gzjggg wants to merge 25 commits into
deflating:mainfrom
gzjggg:feature/command-system-ui
Open

feat: command system, stable session switch, streaming, and UI polish#58
gzjggg wants to merge 25 commits into
deflating:mainfrom
gzjggg:feature/command-system-ui

Conversation

@gzjggg

@gzjggg gzjggg commented Jul 14, 2026

Copy link
Copy Markdown

Summary

Upstream-oriented subset of work that originated in gzjggg/gzTau (product line; formerly gzjggg/tau). This PR is opened from gzjggg/tau-pr (fork of deflating/tau) and is not the primary product tree.

Product (full stack, including Desktop): https://github.com/gzjggg/gzTau
This PR: contribution slice for upstream review (web/command/session fixes; no Tauri desktop packaging).

Highlights (in this PR)

  • Command system: slash completion, Command Center, Pi command dispatch via guarded adapter
  • Session cover: Hephaestus-inspired prologue (UI-only)
  • Stable session switching: same-cwd live resume via TUI /resume path; other-directory sessions are read-only history
  • No stale extension ctx: module-level activePi + shared WebSocket clients singleton so prompts, thinking level, model, and streaming survive session replacement
  • Streaming reliability: slim event payloads, circular-safe JSON, paint history from disk when returning to a session
  • Safety: browser close does not kill Pi by default; fixed barePath ReferenceError on /api/shutdown
  • Defaults (personal-tool): listen on loopback by default; explicit remote for LAN; session delete / file APIs scoped; Markdown XSS harden
  • Model picker: select by provider + id so the same model on multiple providers is not double-highlighted
  • Quieter TUI: routine logs gated behind TAU_DEBUG=1
  • Docs: English + Simplified Chinese READMEs; default port 38471

Not in this PR (stays on gzTau only)

  • Tau Desktop (Tauri), NSIS installer, bundled UI shell
  • Product branding / repo rename path (gzTau)

Test plan

  • Fresh pi start loads Tau without crash; browser connects
  • Chat streams assistant replies in GUI without switching sessions
  • Same-cwd sidebar resume updates TUI + GUI; cross-cwd is read-only
  • New session from GUI syncs TUI
  • Thinking level and model switch work after a session switch
  • Same model id on two providers: only the active provider is highlighted
  • Closing the browser tab does not kill Pi (default)
  • Terminal remains usable (no log spam unless TAU_DEBUG=1)

Notes

  • Larger surface area vs upstream; happy to split or adjust scope per maintainer feedback.
  • Primary product repository: https://github.com/gzjggg/gzTau (not a 1:1 “maintained mirror” of this PR branch).

gzjggg and others added 25 commits July 13, 2026 22:48
Add slash completion, Command Center, Hephaestus-style session cover,
Pi switchSession sidebar switching, browser-close shutdown, port 38471
defaults, and UI polish. Brand mark black body is 34x36. Dual English
and Simplified Chinese READMEs for the gzjggg/tau public fork.
Removed reference to session cover inspired by pi-ui-hephaestus.
Removed a reference to the inspiration for the session cover.
Live Pi switch is limited to sessions under the current working
directory so the GUI never waits on TUI cwd-missing confirmation.
Other-directory sessions open read-only and render grey/compact with
an RO tag. Code blocks and tool cards shrink-wrap to content width.
session_shutdown no longer stops HTTP/WS (that fired on every
switch and dropped browser clients). session_start rebinds and
broadcasts when already running. Tab-close shutdown is suppressed
during switch ops and ignores bfcache pagehide.
After switchSession, broadcast snapshot and recover if TUI already
moved. Browser close only stops the mirror (exitProcess opt-in).
Tool/thinking/code cards use unified width with right gutter.
Sidebar only opens history read-only; never calls switchSession
(that path reloaded memctx and tore down the process). Remove
pagehide/beacon/process.exit. Live session follows TUI /resume.
Same-cwd sidebar clicks call /api/sessions/resume which runs the same
handleResumeSession path as picking a session after /resume, with cwd
preflight and process.exit blocked. Other dirs stay history-only.
Tool/thinking/code cards share a max width and right gutter.
Load session history via /api/sessions/by-path to avoid Windows dir
encoding failures. Soft-succeed resume when live file already matches.
Force tool/thinking/code min-width so thinking no longer collapses.
Cache-bust static assets v1.1.3.
Root cause of resume failure: closed-over ExtensionCommandContext
became invalid after switch (Pi stale-ctx error). Capture interactive
handleResumeSession instead, pass withSession to update latestCtx,
treat stale errors as soft success, never notify/snapshot via old ctx.
After browsing a foreign-dir session, re-selecting a same-cwd session
cleared the chat and waited on mirror_sync which could arrive empty and
show a blank UI. Always load by-path history first, then overlay live
sync; empty snapshots no longer wipe existing content.
Prompts no longer call stale latestCtx.isIdle (which swallowed sends).
Use session.prompt / sendUserMessage via rebinding path. Wire GUI new
session to interactive newSession. Re-enable pagehide exit with
exitProcess, suppressed only during resume/new ops.
Auto-open / leftover Tau tabs sent pagehide exit beacons that killed
Pi immediately after switchSession was captured. Block process.exit
and stopServer for 25s after listen; client skips exit until page is
8s old and had a live WebSocket; skip exit if other clients remain.
Startup 秒退 was leftover Tau tabs sending exit beacons. Disable
exitOnBrowserClose unless settings explicitly set true. Ignore all
shutdown beacons during 60s grace. Stop auto pagehide exit client-side.
Intercept process.exit and process.kill(self) so leftover browser
beacons cannot 秒退 Pi. Log tau-2026-07-14-no-exit-v3 on load so
users can verify the new extension is actually running.
ReferenceError barePath is not defined when /api/shutdown hit on
startup from leftover browser tabs. Define barePath at top of
handleApiRoute and use it consistently.
Stop intercepting process.kill — signal 0 is used by getRunningInstances
and was spamming TUI. Prefer pi.sendUserMessage for prompts so mirror
events fire; put eventType last when spreading event payloads.
Slim high-frequency event payloads and circular-safe JSON.stringify
so message_update reaches browsers. Create streaming bubble if
message_start was missed. Stop blocking kill(pid,0) noise.
Pi re-invokes the extension factory on every session switch. Local
clients Set was empty after rebind so message_update never reached
browsers. Hoist server/clients/latestCtx to module scope.
HTTP handlers started by the first factory closed over a stale
ExtensionAPI after switchSession. Keep module-level activePi updated
on every factory invoke; cycle/set thinking and model use getApi().
Use getApi() in buildStateSnapshot/session cover/auto-title so they
do not touch a stale factory pi. Broadcast thinking_level_changed.
Show GUI error if cycle thinking fails. Stop intercepting process.exit
so Pi /quit works again.
Active model highlight uses provider and id so the same model on
deepseek vs bailian is not double-selected. Header shows provider when
ids collide. Gate routine Mirror/Tau console output behind TAU_DEBUG=1
and shrink startup notify/status line.
Personal-tool policy B: listen on 127.0.0.1 by default; enable LAN
with TAU_REMOTE=1 or tau.remote=true (non-loopback host still works).
Restrict session delete to sessions dir and file APIs to workspace;
sanitize markdown URLs and escape plain text; safe file-browser names.
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