Skip to content

refactor(tui): rename the Grok leftovers to zypi and fix the hints that name missing commands (stacked on #7) - #8

Merged
zy1233 merged 11 commits into
mainfrom
codex/branding-cleanup
Oct 6, 2026
Merged

zy1233 merged 11 commits into
mainfrom
codex/branding-cleanup

Conversation

@zy1233

@zy1233 zy1233 commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

Renames the user-visible "Grok" leftovers in the TUI to zypi and fixes the hints that pointed at things that do not exist. #7 is merged (squash commit 455527c); this branch is rebased onto it with git rebase --onto, so only this PR's own commits are left, and the PR targets main.

Decision for you. You asked for the branding cleanup but did not pick a new name, so this uses zypi, which the product already goes by (brand.rs, terminal title, hero banner, --help). To use another name, change the constants in brand.rs and the two theme ids (zypinight, zypiday).

Three of the changes are bug fixes, not renames:

  1. zypi doctor fix ssh-wrap installed a broken alias. It wrote alias ssh='grok wrap ssh' into the user's shell rc. There is no grok command, so ssh stopped working. It now writes alias ssh='zypi wrap ssh', inside a block marked # >>> zypi doctor >>>. Anyone who ran the old fix has to delete the old # >>> grok doctor >>> block by hand; the new version does not recognise it.
  2. The home directory was shown under the wrong name. Messages said ~/.grok / $GROK_HOME (settings footer, the backup path in the copy toast, doctor notes) while the home is ~/.pi-python / $PI_HOME. Users were sent to files that do not exist.
  3. Hints named commands that do not exist. There is no /doctor, /minimal, /fullscreen or /copy slash command, and no grok wrap or grok worktree gc|rm|db rebuild. The hints now name what is there: zypi doctor, zypi wrap ssh <host>, --minimal / --fullscreen. zypi du drops its worktree hints.
Where Before After
/theme, settings Grok Night / Grok Day, ids groknight / grokday zypi Night / zypi Day, ids zypinight / zypiday. The old ids and aliases (groknight, grok-night, GrokNight, grokday, grok-day, dark, light, day) still resolve and show the renamed theme as selected, so existing config.toml files keep working
Desktop notification title Grok zypi
zypi doctor title Grok Doctor, pointers to /doctor zypi Doctor, real commands
Startup / SSH tip "Run /doctor for details and fixes." "Run zypi doctor for details and fixes."
Settings text "…with /minimal or /fullscreen", "Show a /doctor tip…", "(Grok STT)" --minimal / --fullscreen, zypi doctor, no STT brand
Copy toasts "use grok wrap or /minimal", "Try /doctor or /minimal" "use zypi wrap or --minimal", "Try zypi doctor or --minimal"
--minimal mode welcome title Grok Build, "Sign in to Grok", trust prompt "Grok Build may run or modify…" zypi
Misc "Couldn't start Grok", "Restart Grok", "encode Grok's payload", grok wrap: error prefix zypi

One change is not about branding. bafc15e fixes a Python bug that main newly exposed: on macOS a project's AGENTS.md reached the prompt twice. AGENTS.md and AGENTS.MD are both looked for, they name one file on a case-insensitive file system, the repeat check compared path strings, and Path.resolve keeps the spelling it was given on macOS. Repeats are now skipped by file identity (device and inode), which also covers hard links. The new test fails without the fix, together with main's test_context_files_are_loaded_whatever_the_trust. You asked for it to go in with this PR.

Left alone on purpose

  • Names users may rely on: the GROK_* environment variables (GROK_HOME alone is referenced 241 times; GROK_SANDBOX still shows in --help), the project path .grok/sandbox.toml, and the grok_home field of zypi du --json (machine readable; renaming it needs a schema decision). Renaming them breaks existing setups, so it is your call.
  • Internal identifiers: ThemeKind::GrokNight / GrokDay, theme/groknight.rs / grokday.rs, assets/grok-night.tmTheme / grok-day.tmTheme, the grok_* function and field names (default_grok_home, display_user_grok_path), x-grok-* HTTP headers, and the xai_grok_pager__*.snap snapshot file names.
  • Dead-world strings that belong to later stages: SuperGrok billing (app/dispatch/billing.rs), the tutorial (views/tutorial.rs), the privacy banner (views/privacy_banner.rs), pi-update (grok update, version_policy.rs), the grok login hints in pi-auth / pi-shell / pi-workspace, the model-facing parameter text in pi-tools (for example the workflow tool's ~/.grok/workflows/), and the ACP auth method labelled "Grok".
  • The embedded user guide (tui/crates/codegen/pi-pager/docs/user-guide/06-theming.md, Stage C.2) still lists GrokNight / GrokDay. Those names remain valid aliases, so the guide is stale rather than wrong.

Review guide

Eleven commits: six Rust commits that each carry their own tests (they touch only the strings and tests they name; nothing is reformatted), one Python fix, four docs commits.

Commit What
462ba3a Home label (~/.pi-python / $PI_HOME) and the copy toasts
c67d681 Theme rename with legacy aliases, settings footer and text
ab7e7a6 zypi doctor text, fix commands and the ssh-wrap alias, startup / SSH tips
01e9166 Notification titles
0bc0e80 zypi du hints
1c56352 --minimal, startup failure, voice, status line, zypi wrap strings
bafc15e Python: a context file is loaded once however many names it has (AGENTS.md twice on macOS), with a test
9332506, 4528bed, 484d4e1, 0d6867b Plan r6 (section 10.8) and its Linux CI result; r7 (section 10.9: the merge of main into #7, the AGENTS.md fix, how the squash merges were done). Docs only; TUI CI runs again anyway because the PR as a whole touches tui/**

Verification

  • Build: cargo check -p pi-pager-render -p pi-pager -p pi-pager-minimal --all-targets has 0 errors and 0 warnings; the debug zypi build has 0 warnings.
  • Tests, macOS local (--test-threads=2, relevant filters only): pi-pager-render theme / util / clipboard 265 passed; pi-pager-minimal 79; pi-pager --lib theme / settings / doctor / diagnostics / disk_usage / notifications / startup / tips / wrap / status_line 1,068; settings_e2e 251; grok_home_paths 2; doctor_early_dispatch (real binary, --ignored) 13, including the one that writes the rc alias.
  • New regression tests: old theme ids still resolve and the persisted ids contain no grok; the home label names the real directory; fix commands and the alias use brand::CLI_NAME; DOCTOR_ACTION carries no slash; copy toasts, settings text and clipboard fixes name no grok and no missing slash command; zypi du suggests no worktree gc|rm or db rebuild.
  • PTY (debug zypi against the agent with PI_USE_MOCK=1, no network): fullscreen welcome, slash dropdown, /help, /theme, /settings (walked 160 rows plus G, 16 distinct screens), /model, a turn, /resume, the Ctrl+C hint; --minimal welcome, /help, a turn. Lines containing grok or a missing slash command: 0. With theme = "grokday" in config.toml, /theme marks zypiday as active. The settings footer reads ~/.pi-python/config.toml for the default home and $PI_HOME/config.toml when PI_HOME points elsewhere.
  • CLI: --help of the top level and of every subcommand (completions, doctor, doctor fix, du, export, help, version, wrap), plus the output of zypi doctor, zypi du and zypi version: the only hit is [env: GROK_SANDBOX=] in the top-level --help (an env var name, kept).
  • Python: one fix (context_files.py); ruff check and ruff format --check pass. Full pytest on macOS: 2,001 passed, 5 failed. The 5 fail the same way on main and are macOS-only (4 workflow-sandbox tests, 1 non-UTF-8 file name); Linux CI runs them green. Mutation check: without the fix, the new test and main's test_context_files_are_loaded_whatever_the_trust fail.
  • Linux CI, green on the final head 0d6867b (rebased onto main at 455527c): TUI CI run 37488552588: dependency graph 980 packages (ceiling 980), 0 warnings, cargo check --workspace --tests passes, the 8 suites pass 7,444 / 0 failed / 20 ignored (the same as before the rebase, as the Rust tree is identical); CI run 37488553959 (Ruff, pytest on Python 3.11 / 3.12 / 3.13), which runs the new context-file test and the tests that fail on macOS. main is green at 455527c too: TUI CI run 37487963487, CI run 37487963598. The macOS-flaky test below passes on Linux.

Not verified

  • Linux does not run the tests I added in pi-pager-render and pi-pager-minimal. The TUI CI suites (scripts/tui_baseline.toml) do not include those two crates, so Linux only compiled them (cargo check --workspace --tests). The theme alias, home label, clipboard toast and --minimal tests ran on macOS only. Adding the two crates to the baseline is a small change, but it needs reference counts measured on Linux and changes the CI gate (enforce = true), so I left it for you to decide.
  • Windows, and macOS-only paths of the new tests (the PTY runs are macOS).
  • One filtered local run saw session_startup::tests::remote_miss_restore_code_with_worktree_defers fail on macOS: it reads the real ~/.pi-python/sessions/<temp repo path> (/var vs /private/var) and errors when that directory is missing. It is unrelated to this change and passed in later runs.
  • rustfmt was not run over whole crates (the toolchain differs from CI's and would reformat untouched files); the hunks this PR adds are formatted, checked against the diff only.

@zy1233
zy1233 changed the base branch from codex/rust-agent-runtime-removal-plan to main October 6, 2026 15:29
zy1233 added 11 commits October 6, 2026 23:30
…ng commands from the copy toasts

The home was shown as ~/.grok or $GROK_HOME in the settings footer, the copy
toast's backup path and the doctor notes, although it is ~/.pi-python (or
$PI_HOME, see pi-home). Users were sent to files that do not exist.

The copy toasts pointed at `grok wrap`, `/minimal`, `/doctor`: zypi has the
subcommands `wrap` and `doctor` and the --minimal flag, and no such slash
commands. Add a test that no toast names a missing command.
… the old ids as aliases

Persisted ids become zypinight / zypiday and the labels zypi Night / zypi Day.
from_name() still accepts groknight, grok-night, GrokNight, grokday, grok-day
(and dark / light / day), canonical_name() normalizes them, so an existing
config.toml keeps working and shows the renamed theme as selected.

The settings footer no longer advertises asking Grok about the docs (there is
no such feature); it says where the settings are saved. Setting text no longer
mentions /minimal, /fullscreen, /doctor or Grok STT.
…alls alias ssh='grok wrap ssh'

`zypi doctor fix ssh-wrap` wrote an alias for a command that does not exist
into the user's shell rc, which breaks ssh. It now writes
alias ssh='zypi wrap ssh', in a block marked '# >>> zypi doctor >>>'.

Report titles, notes, fixes and the startup / SSH tips name zypi doctor,
zypi wrap and --minimal instead of /doctor, /copy, /minimal and grok.
The hints told users to run worktree gc / rm / db rebuild; zypi has no worktree
subcommand. Keep the one piece of advice that holds (delete what is listed).
--minimal welcome screen and trust prompt, startup timeout message, voice toast,
status-line payload error, zypi wrap error prefix.
discover_context_files looks for AGENTS.md and AGENTS.MD (and CLAUDE.md and CLAUDE.MD) in every
directory and skipped repeats by the resolved path string. On a case-insensitive file system the
two spellings are one file, and Path.resolve keeps the spelling it was given on macOS, so the
project's AGENTS.md was read twice and reached the prompt twice. The bug dates from the Phase 5
prompt engine; main's test_context_files_are_loaded_whatever_the_trust is the first test to
catch it, and it failed on macOS on main itself.

Repeats are now skipped by file identity (device and inode; the path where there is no inode),
which also covers hard links.

The new test makes one file with two names by itself on a case-insensitive file system and with
a hard link elsewhere. Without the fix it fails together with main's test.
@zy1233
zy1233 force-pushed the codex/branding-cleanup branch 2 times, most recently from 00df03f to 0d6867b Compare October 6, 2026 15:33
@zy1233
zy1233 merged commit 4b5848f into main Oct 6, 2026
8 of 14 checks passed
@zy1233
zy1233 deleted the codex/branding-cleanup branch October 6, 2026 16:10
zy1233 added a commit that referenced this pull request Oct 10, 2026
…8, run on WSL2) (#9)

## Summary

The macOS half of `docs/PLAN/PLAN-RUST-AGENT-RUNTIME-REMOVAL.md` is merged (#6 to #8). This is the Linux half, run in WSL2 (Ubuntu 24.04, kernel 5.10 **without Landlock**, bubblewrap 0.9.0): build the TUI, run its Rust suites, drive a real `zypi` under a pseudo-terminal, and look at what it leaves behind. That turned up six things, and this PR fixes them. The plan's section 10.10 has the full record (what was run, what was found, what is not verified).

**What this PR is for in CI.** The numbers below were measured on WSL2, not on the runner. This PR's first TUI CI run is what confirms or corrects them:

- `doctor_cmd::` is no longer skipped in `pi-pager` (12 tests). The skip existed because the voice probe hung on macOS CoreAudio; the probe is gone and the tests pass here without an audio device. If they do not hold on the runner, put the skip back (one line in `scripts/tui_baseline.toml`).
- Two suites join the manifest: `pi-pager-render` (1,092 passed, 2 ignored) and `pi-pager-minimal` (79 passed).
- `pi-pager` `reference_passed` 5552 -> 5577; `pi-pager-bin` 20 -> 21.
- One known failure, `tmux_probe::tests::successful_near_deadline_exit_still_returns_captured_output`, is listed in `known_failures`. It spends 1.2 s of a 1.5 s budget in a shell script, so it fails when the machine stalls (twice on WSL2, both on the first run after linking, never in the 94 runs after). It is reported when it fails and does not block.

**CI result.** The runs on `d84d98a` are green (TUI CI [run 38052332014](https://github.com/zy1233/pi-python/actions/runs/38052332014)): 10 suites, **8,634 passed / 0 failed / 22 ignored**, each suite equal to its `reference_passed`. That is the local 8,633 plus the one known failure, which passed on the runner, so `known_failures` stays as a safety net and was not needed this time. `doctor_cmd::` held on the runner without the skip. `cargo test` took 32 m 40 s, `Gates + cargo check` 8 m 21 s, Ruff 8 s, pytest on 3.11 / 3.12 / 3.13 about 2 minutes each; the release build baseline is skipped by design.

## The six findings

| # | What was wrong | Fix |
|---|---|---|
| 1 | `zypi -p` runs the Python agent as a plain child on the user's terminal, so the agent never sees EOF when only zypi is killed (`kill -9`, `kill <pid>`, an IDE's stop button). The agent and a `sleep 300` it had started kept running. | zypi names itself in `PI_AGENT_PARENT_PID`; `pi_agent_cli` polls `os.getppid()` every 0.5 s in `-p` mode and stops as it does on SIGTERM (cancel the turn, reap every tool's process group). `-p` also stops on SIGTERM / SIGHUP now (exit status 128 + signal). |
| 1b | With `--sandbox`, zypi re-executes itself under bubblewrap, and a plain bwrap only waits for its child. SIGKILL / SIGTERM / SIGHUP to bwrap alone left zypi, the agent and its tools running. | `bwrap --die-with-parent`, as its own commit. |
| 2 | `SandboxManager::apply()` degrades on purpose (no Landlock, or applying fails): it logs, returns `Ok`, and the run goes on with none of the profile's limits. The user was never told. | The reason is kept; a warning is printed on stderr at start-up, and the welcome bar and status bar show `sandbox:<profile> (not enforced)` in the error colour. |
| 3 | The agent's stderr went to `/dev/null` once the TUI was up, so a Python traceback went nowhere. | `<home>/logs/agent.stderr.log`: appended, one marker line per spawn, `0600`, rotated at 1 MiB at spawn, and a log that cannot be opened does not stop the agent. `-p` keeps the terminal. |
| 4 | Two tests failed intermittently on WSL2. | Test-only: a 25 ms gap between two writes (the 100 Hz kernel clock makes ctime coarse), and `theme_cache::test_lock()` in a test that raced the terminal-native tests. |
| 5 | The manifest skipped `doctor_cmd::` and had no `pi-pager-render` / `pi-pager-minimal`. | See the CI section above. |
| 6 | The Linux-only checks (what is left running after each way of leaving zypi, the sandbox label, `-p` shutdown) had no repeatable form. | `scripts/tui_pty/` drives a built `zypi` under a pty (a `pyte` screen reads what it draws) and inspects the process tree. They need a built binary, so they are **not** part of pytest or CI. |

## Decision for you

**`--die-with-parent` has a cost.** The sandboxed child is SIGKILLed when bwrap dies, so when only the outer bwrap gets SIGTERM or SIGHUP, zypi cannot restore the terminal (alternate screen, raw mode). Before the flag, the whole tree stayed up instead. I judged an unrestorable terminal better than a running agent nobody can see, but it is a trade, and the commit is only the flag and its test, so it is easy to revert. If you revert it, the CHANGELOG line and the plan's section 10.10 need the same edit.

## Not verified

- **Landlock itself.** It needs kernel 5.13 or later and the WSL2 kernel is 5.10, so the "applied" side of the sandbox is covered by unit tests only (applying it would confine the test process for good).
- **`-p` with a wrapper script as `PI_AGENT_COMMAND`.** The watch stays off when the process that started the agent is not the one named, so killing only zypi still leaves that agent behind. Windows has no counterpart for the watch.
- Section 10.10 of the plan lists the rest.

## Review guide

Nine commits. The first is not part of the Linux work: it was on local `main` and never pushed, so it rides along. If you squash-merge, it goes in under this PR's title; a rebase-merge keeps the nine as they are.

| Commit | What |
|---|---|
| `eafc578` | Not mine: phase7 fix (project-trust for saved workflows, a bad meta description no longer breaks the session) |
| `c13f7cc` | Finding 1: `-p` parent watch (Rust passes the pid; 15 pytest cases, POSIX only; 1 Rust test) |
| `d14e6f8` | Finding 1b: `--die-with-parent` and the test that pins its position before `--` |
| `2d499ad` | Finding 2: not-enforced notice (`pi-sandbox`, `pi-shell`, two render sites; 5 tests) |
| `91b5f62` | Finding 3: agent stderr log (6 tests) |
| `9489975` | Finding 4: two flaky tests, no production code |
| `478aa8a` | Finding 5: manifest |
| `15d2d85` | Finding 6: `scripts/tui_pty/` and `scripts/tests/test_tui_pty.py` |
| `4cf989f` | Docs: plan 10.10 and r8, `docs/baselines/tui.md`, CHANGELOG, AGENTS files |

## Verification

On WSL2, the whole manifest (`python scripts/tui_baseline.py test`): exit 0, 10 suites, 8,633 passed, 1 known failure, 22 ignored. pytest: 2,160 passed / 30 skipped on Linux (WSL), 2,156 passed / 34 skipped on Windows. `ruff check` and `ruff format --check` are clean. With a built `zypi` under a pty: `smoke.py` 23 checks (26 with `--sandbox workspace`), `exit_matrix.py` 12/12 (14/14 with the sandbox), `print_exit.py` 4/4 (the tool survived before the `-p` fix).
zy1233 added a commit that referenced this pull request Oct 10, 2026
…ds the merge order

The ADR1 PR 1 branch and the mode_a branch were local when the plan and the baseline report were
written, and said "not pushed" in eight places. They are pushed now: #11 (codex/adr1-pr1-python) on
top of #10, #12 (codex/phase1-mode-a) on top of #11. Those places name the PRs instead; the r9
statements that were true when they were written stay, as the r10 entry already says.

The r10 entry in the revision log gets the last step. The user asked to sync main to origin and
merge the processed PRs. The stack has four (#9, #10, #11, #12), and the upper ones have nothing to
merge into until the lower ones are in, so all four are merged, bottom-up, one squash each (the
convention of #7 and #8), with the base moved to main before each merge and the tree of main compared
with the branch's afterwards. Local main is 9 commits ahead of origin/main; all of them except one
older docs commit (superseded by the revised one in #9) are already in #9's branch, so main is not
pushed: after the merges it is reset to origin/main, and the old main stays on a backup branch.

Docs only: the plan, docs/baselines/tui.md.
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