Signal-type popup, NC pin tagging, interactive viewer hygiene.

- Enter on a signal entry (net / explore) opens a modal popup to pick
  power / gnd / other. Recording is deduped: a sequence of toggles on
  the same signal collapses to a single `set-signal-type` line; no-op
  selections record nothing.
- Bare interactive commands (the ones that open a full-screen mode)
  are no longer recorded by `script-save`. Their inline forms still
  are. Mutating actions inside a screen record their own canonical
  line.
- Mentor importer treats signals whose name starts with `unconnected`
  as no-connect — the pin is kept on the part without a signal and
  tagged `ImportedUnconnected`.
- `drop_singleton_signals` runs at the end of `load`: any signal with
  exactly one pin is detached (singletons are NC by definition); the
  pin is tagged `DroppedSingleton`. Count is reported inline.
- `verify` gains a one-line orphan summary (imported NC / dropped
  singleton totals). Pins materialised by `FillIdentityNCs` are
  excluded via a `pin_map` filter — they are bridged to a real signal
  on the peer module and are not real NCs at system level.
- NcOrigin tag is serialized in save snapshots as an optional 4th
  field on N records (backward-compatible).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-13 07:56:46 +02:00
parent 043fef0a31
commit 280526304d
16 changed files with 295 additions and 16 deletions

View File

@@ -41,8 +41,10 @@ void Tui::Run() {
auto search_screen = BuildSearchScreen();
auto connect_screen = BuildConnectScreen();
auto settype_screen = BuildSettypeScreen();
auto explore_screen = BuildExploreScreen();
auto net_screen = BuildNetScreen();
auto explore_screen = BuildExploreScreen() | Modal(BuildSignalTypeModal(),
&sigtype_dialog_open);
auto net_screen = BuildNetScreen() | Modal(BuildSignalTypeModal(),
&sigtype_dialog_open);
auto tab = Container::Tab(
{main_screen, search_screen, connect_screen, settype_screen, explore_screen,
@@ -50,6 +52,10 @@ void Tui::Run() {
&screen_idx);
auto root = CatchEvent(tab, [this](Event e) {
// The signal-type popup must own Escape / Tab while it's open so the
// outer switch doesn't yank us back to the main screen.
if (sigtype_dialog_open) return false;
switch (screen_idx) {
case 5: // net
if (e == Event::Escape) { screen_idx = 0; return true; }