def load(p):
    raw = open(p, encoding='utf-8', newline='').read()
    return raw.replace('\r\n', '\n'), '\r\n' in raw

def save(p, s, crlf):
    open(p, 'w', encoding='utf-8', newline='').write(s.replace('\n', '\r\n') if crlf else s)

def once(s, old, new):
    assert s.count(old) == 1, (old[:80], s.count(old))
    return s.replace(old, new)

p = 'crates/spt/src/picker/model.rs'
s, c = load(p)
anchor = '    fn ep(id: &str, group: &str, status: EpStatus, is_local: bool) -> EndpointRow {'
s = once(s, anchor, '''    // [unit->REQ-PICKER-ADAPTER-VERSION] the suffix, and where each version
    // comes from: a local endpoint from this node's registry, a remote one from
    // ITS node's roster (never this node's install), nothing when unknown.
    #[test]
    fn adapter_versions_label_local_and_remote_endpoints_from_their_own_node() {
        assert_eq!(versioned("claude-spt:fast", Some("0.41.3")), "claude-spt:fast v0.41.3");
        assert_eq!(versioned("claude-spt", None), "claude-spt");
        assert_eq!(versioned("claude-spt", Some("")), "claude-spt", "no placeholder");
        assert_eq!(versioned("", Some("1.0.0")), "", "an empty address stays empty");

        let mut v = AdapterVersions::default();
        v.local.insert("claude-spt".into(), "0.41.3".into());
        v.peers.insert(("nodehex01".into(), "claude-spt".into()), "0.40.0".into());
        let mut local = ep("a", "g", EpStatus::Online, true);
        local.adapter_profile = "claude-spt:fast".into();
        assert_eq!(v.endpoint_label(&local), "claude-spt:fast v0.41.3");
        let remote = ep("b", "g", EpStatus::Online, false);
        assert_eq!(v.endpoint_label(&remote), "claude-spt v0.40.0", "the remote node's version");
        let mut unknown = ep("c", "g", EpStatus::Online, false);
        unknown.node_key = "otherhex".into();
        assert_eq!(v.endpoint_label(&unknown), "claude-spt", "no roster row, no suffix");
    }

''' + anchor)
save(p, s, c)

p = 'crates/spt/src/picker/view.rs'
s, c = load(p)
anchor = '''    // [unit->REQ-RUN-PICKER-HOME] the CreateHome screen lists the member subnets'''
s = once(s, anchor, '''    // [unit->REQ-PICKER-ADAPTER-VERSION] the adapter tree, the create title
    // and the endpoint panes all follow adapter[:profile] with its version.
    #[test]
    fn adapter_versions_render_in_the_tree_the_title_and_the_panes() {
        let rows = crate::picker::model::build_adapter_tree(&[AdapterInfo {
            name: "claude-spt".into(),
            shipped: vec!["fast".into()],
            local: vec![],
        }]);
        let mut m = PickerModel::new("p".into(), rows, vec![], None, None, vec![]);
        m.adapter_versions.local.insert("claude-spt".into(), "0.41.3".into());
        m.screen = Screen::CreateAdapter;
        let s = rendered(&m);
        assert!(s.contains("claude-spt v0.41.3"), "{s}");
        assert!(s.contains("claude-spt:fast v0.41.3"), "{s}");
        m.screen = Screen::CreateId;
        let s = rendered(&m);
        assert!(s.contains("New claude-spt v0.41.3 endpoint"), "{s}");

        let mut pick = PickerModel::new("spt-core".into(), vec![], vec![ep("doyle", EpStatus::Online, true)], None, None, vec![]);
        pick.adapter_versions.local.insert("claude-spt".into(), "0.41.3".into());
        pick.screen = Screen::PickExisting;
        pick.category = Category::Local;
        let s = rendered(&pick);
        assert!(s.contains("claude-spt:fast v0.41.3"), "the description pane: {s}");
    }

''' + anchor)
save(p, s, c)
print('ok')
