Skip to content

refactor(tui): remove 16 dead modules, the MCP loaders and the folder-trust gate (plan D.8, decision 10) - #62

Merged
zy1233 merged 8 commits into
fix/tui-resume-picker-age-limitfrom
refactor/tui-remove-dead-modules
Oct 31, 2026
Merged

zy1233 merged 8 commits into
fix/tui-resume-picker-age-limitfrom
refactor/tui-remove-dead-modules

Conversation

@zy1233

@zy1233 zy1233 commented Oct 30, 2026

Copy link
Copy Markdown
Owner

Summary

Plan phase D.8 and decision 10. The call graph lists 16 modules that no live code refers to. The MCP loaders of pi-shell and recent_dirs of pi-pager have no caller either (decision 10). All of it goes. The compiler then found the code that only these called (15 warnings, and the ceiling is 0), and that goes too.

 tui/crates/codegen/
 ├── pi-hooks/
-│   ├── dispatcher, result, runner, runner::command, runner::http   # 4,339 lines + tests/integration.rs
-│   └── deps: reqwest, url, tokio, pi-extra-ca
 ├── pi-shell/
-│   ├── session::events, session::telemetry, session::unified_list
-│   ├── upload, upload::turn, auth::flow, config::reloader
-│   ├── util/config/mcp.rs: load_mcp_servers + the loaders under it, the registry helpers
-│   ├── agent::folder_trust: the consume side of the gate (cache, project_scope_allowed, ...)
-│   ├── config::resolve_effective_plugins_config, claude_import, PluginsConfig::{merge_claude_enabled_plugins, to_discovery_config}
-│   └── deps: pi-session-events, dirs
-├── pi-workspace/publish
-├── pi-tools/implementations/editor_infra
-├── pi-mcp/wire
-├── pi-agent/prompt/browser_verification
-└── pi-pager/recent_dirs

Eight commits. Read them in order:

# Commit Lines removed
1 pi-hooks: dispatcher and runners 5,220
2 pi-shell: seven dead modules 1,021
3 four more dead modules (pi-workspace, pi-tools, pi-mcp, pi-agent) 805
4 decision 10: MCP loaders, recent_dirs 583
5 the registry helpers (not on the plan list) 155
6 what only the removed loaders called: 15 warnings 1,283
7 ratchets 4 (10 added)
8 CHANGELOG.md, docs/baselines/tui-support.md docs

Commit 6 builds on commit 5. Kept on purpose: grant_folder_trust (the pager calls it for --trust, and the pager's trust dialog still uses the decision side in pi-workspace), pi-tools::types::error (holds the From impls for ToolError), parse_mcp_servers_from_toml (Config reads [mcp_servers]). The guard test project_config_never_sources_feedback_user stays: it used a removed function, so it now uses find_project_configs to show that the project config is found.

Left for later (names only): the docs of pi-session-events and pi-telemetry/src/events/permission_analytics.rs still name the removed goal and laziness reasons and the removed drift test; pi-hooks/examples/; three functions of pi-config-types::mcp (resolve_setup, expand_strings, to_acp_mcp_server) that only their own tests call now.

Evidence

  • Before: main at 7cb9e23. The call graph (docs/baselines/tui-support.md): 17 dead units, 6,192 lines in the support crates.
    After: 1 dead unit, pi-tools::types::error (44 lines), kept on purpose.
  • Before: commits 1 to 5 only. tui_baseline.py check: warnings 15 (ceiling 0): folder_trust (7 items), claude_import (4), resolve_effective_plugins_config, the two PluginsConfig methods (one warning) and 2 unused imports.
    After: tui_baseline.py check on 272a52a (Linux, WSL2) is all green: warnings 0, cargo check of the consumer build exit 0, cargo check --workspace --tests exit 0 (--locked), residue leader 239/239 and x.ai 282/282, graph 970/970.
  • Tests (tui_baseline.py test, nextest): pi-shell 784 passed, 0 failed, 1 skipped (838 before; the 54 are folder_trust 19, MCP loaders 9, claude_import 7, config::reloader 6, session::telemetry 6, resolver 3, session::events 2, auth::flow 1, upload::turn 1; none new). pi-pager 5,651 passed, 0 failed, 12 skipped (unchanged; includes python_agent_e2e against the real Python agent). pi-hooks (not a suite of the manifest): 130 passed, 0 failed.
  • tui_notices.py check: 984 packages ship, 984 entries, 0 missing, 0 stale. Cargo.lock loses 6 dependency lines and no package.
  • ruff check . and ruff format --check . pass; pytest scripts/tests: 234 passed, 11 skipped. No Python file changes.

Merge Danger

Door: two-way. One revert brings everything back.

Blast Radius: the tui/ source tree. It removes code that no build refers to, and its tests: 9,067 lines go and 65 come, in 47 files under tui/. zypi does not change: the build that ships has 0 warnings, and nothing else names the removed items. Two tests change what they check (session_new_and_load_send_no_mcp_servers and project_config_never_sources_feedback_user).

CHANGELOG.md conflicts with #60 and #61: all three add a section under [Unreleased]. Keep both sections. A test merge with #56, #57, #58, #59, #60 and #61 shows no other conflict. The manifest numbers do not collide: #61 changes the pi-pager numbers, and this PR changes the pi-shell numbers and the two ceilings.

…othing calls

The dispatcher, the command runner and the HTTP runner of pi-hooks had no caller since the Rust
agent runtime left (plan D.8). The call-graph tool lists dispatcher, result, runner,
runner::command and runner::http as dead units: 4,339 lines, 48 % of the crate. The crate keeps what
pi-agent, pi-workspace and pi-config still read: the hook definitions (config), the file discovery,
the event types, the matcher, the trust files and the env expansion.

- Delete src/dispatcher.rs, src/result.rs, src/runner/ and tests/integration.rs.
- env_expand.rs: expand_env_vars_with_extra is a test helper now, so it moves into the test module.
  The docs no longer name the deleted modules.
- Cargo.toml: remove reqwest, pi-extra-ca, url and tokio. No source file of the crate names them
  now. Cargo.lock follows.
- lib.rs: the crate docs say that the crate loads and checks hook definitions and does not run them.

The examples in pi-hooks/examples describe hooks of the old runtime that nothing runs. They stay
for now.
Plan D.8. The call-graph tool lists seven units of pi-shell as dead: auth::flow, config::reloader,
session::events, session::telemetry, session::unified_list, upload and upload::turn (1,008 lines).
Five of them hold only tests: auth::flow, config::reloader, upload, upload::turn and
session::telemetry. The tests of session::telemetry are a drift guard between the telemetry enums
and the permission reasons, and no code emits these telemetry events. session::events holds the
reason strings of goal and laziness events that nothing sends. session::unified_list builds the
_meta of a session/list row that nothing builds.

- Delete the files and their `mod` lines.
- Cargo.toml: remove pi-session-events. Only session::events named it. Cargo.lock follows.
- pi-workspace, permission/manager/reasons.rs: two comments no longer say that a telemetry enum
  asserts coverage against `ALL`. The test that did is gone.

pi-session-events still names these reason strings in the docs of its events, and
pi-telemetry/events/permission_analytics.rs still names the drift test. Both are candidates for
the next cleanup.
… pi-mcp, pi-agent)

Plan D.8. The call-graph tool lists these units as dead, and no file under tui/crates names them:

- pi-workspace, publish (462 lines): the merge-or-fail publish flow of the old app deployer.
- pi-tools, implementations::editor_infra (276 lines): a file-operation lock.
- pi-mcp, wire (39 lines): the x.ai/mcp/* ACP method strings.
- pi-agent, prompt::browser_verification (24 lines): a rule text. The prompt template keeps its own
  <browser_verification> block, and the flag include_browser_verification stays.

pi-tools types::error is on the same list, but it stays: it holds the From impls for ToolError that
the `?` operator needs.
…dirs (plan decision 10)

load_mcp_servers has had no caller since zypi stopped handing MCP servers to the agent (plan 1.P4).
It was the only user of the chain below it, so the chain goes with it, in pi-shell
util/config/mcp.rs:

- load_mcp_servers and reload_mcp_servers_merged.
- The loaders for mcp_preferences.json, .mcp.json, ~/.claude.json and ~/.cursor/mcp.json, and their
  helpers (McpPreferencesLoad, mcp_config_from_json_value, claude_json_mcp_from_value,
  read_mcp_json). The re-export of find_mcp_json_files goes too; the function stays in pi-workspace.
- Seven tests. Four of them built the merge of the old loader by hand ("project overrides global")
  and tested nothing else. Two read a file with read_mcp_json. One checked the JSON map of the
  loader.

parse_mcp_servers_from_toml stays: Config still reads [mcp_servers] through it (agent/config.rs),
and so do its tests.

pi-pager recent_dirs.rs had one doc comment and nothing else. Its `mod` line goes too.

The pager test session_new_and_load_send_no_mcp_servers called load_mcp_servers to show that its
fixture is something the old code found. That premise check goes. The test still checks that
session/new and session/load carry no servers, and a comment says what the fixture is.
…s that nothing calls

Both sat in util/config/mcp.rs, and no file outside that file names them (a search of tui/crates,
whole words):

- load_cli_plugin_registry. Its doc says that the pager's /agents modal uses it. The pager does not.
- The session-registry helpers: session_registry_from_toml_opt, session_registry_from_env_opt,
  session_registry_local_override_sourced, RegistrySource and SESSION_REGISTRY_ENV_VAR.
- Their two tests.

This is not on the list of plan decision 10. The next commit builds on it: it removes the code
that load_cli_plugin_registry was the last to call.
The commits before this one left more dead code behind. `cargo check` found it: 15 warnings, and
the ceiling of the baseline is 0.

- `agent::folder_trust`: the consume side of the folder-trust gate (the cache of verdicts,
  `project_scope_allowed`, `resolve_and_record` and their helpers) and its 19 tests. The loaders
  of MCP servers, plugins and permission policy were the only callers. `grant_folder_trust` stays,
  because the pager calls it. The decision side stays in `pi-workspace`, for the pager's dialog.
- `config::resolve_effective_plugins_config` (the last callers went with the plugin-registry
  helpers), `PluginsConfig::merge_claude_enabled_plugins`, `PluginsConfig::to_discovery_config`
  and the module `claude_import` (7 tests). `PluginsConfig` stays as a section of the config.
- The 3 tests of `resolve_effective_plugins_config` in `config/tests.rs`. The test
  `project_config_never_sources_feedback_user` stays: it guards live code. It now checks with
  `find_project_configs` that the project config is found.
- The re-export `util::config::McpConfig`: two tests use the type, and they import it from
  `pi-config-types` now.
- The dependency `dirs` of `pi-shell`. Its only use was `merge_claude_enabled_plugins`.
- Two doc comments in `pi-workspace`, and one line in the README of `pi-shell`, that named the
  removed code.

Tests of `pi-shell`: 838 - 54 = 784 (with the commits before this one).
- Residue ceilings: `leader` 243 to 239, `x.ai` 297 to 282. The gate asks for it, and the manifest
  says to lower a ceiling in the commit that removes lines.
- Tests of `pi-shell`: reference 838 to 784, floor 820 to 766 (the same distance, 18). 54 tests
  went with the code that they tested; none was added. The comment in the manifest has the
  count for each part.
- The dependency graph stays at 970 packages (measured): the other crates still use what the
  removed code used.
- CHANGELOG.md: an entry under Removed for the commits above. It says what went, what stays on
  purpose (`grant_folder_trust`, `pi-tools::types::error`), and the numbers.
- docs/baselines/tui-support.md: generated again with `python scripts/tui_callgraph.py keep`
  (it names commit ebc6106). The support crates have one dead unit left, `pi-tools::types::error`.
  It stays: it holds the `From` impls for `ToolError`, which code uses without a name.
@zy1233

zy1233 commented Oct 31, 2026

Copy link
Copy Markdown
Owner Author

Stack #66, bottom to top: #58, #59, #56, #57, #60, #61, #62, #63, #64, #65. One atomic squash merge (gh stack merge).

Position 7 of 10. Base: fix/tui-resume-picker-age-limit (#61). Head 272a52a -> f3b280e. Seven of the eight commits have the same patch. The last one (CHANGELOG.md and docs/baselines/tui-support.md) changed in one place: [Unreleased] now has the sections Changed (#60), Removed (this PR), Fixed (#61), in the order of the Keep a Changelog sections. The support list is the same as before: the tool, run again on the stacked tree, writes the committed file (the line with the commit id excepted).

@zy1233
zy1233 merged commit c837402 into main Oct 31, 2026
8 of 14 checks passed
@zy1233
zy1233 deleted the refactor/tui-remove-dead-modules branch October 31, 2026 03:17
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