Native C++ 9P2000 client over QLocalSocket (no libplumb/lib9pclient
link) talking to a running plan9port plumber:
- ninep: Tversion/Tattach/Twalk/Topen/Tread/Twrite/Tclunk, LE wire,
msize negotiated from 8192; cancellable split read (beginRead +
recvReadReply) so the edit-port reader thread honours a stop flag
without a second outstanding Tread or any cross-thread socket touch.
- plumbmsg: PlumbMsg pack/unpack with libplumb attribute quoting;
unit-tested against golden bytes captured from a live plumber.
- plumbresolve: plan9 addr (N / N:C / N.C, 1-based) -> 0-based cursor.
- plumber: send() via the send port; PlumbReader QThread on the edit
port emits edit(file,addr,wdir) via a queued signal. Namespace socket
is $NAMESPACE/plumb or /tmp/ns.$USER.$DISPLAY/plumb (plan9 getns).
Plugin: F2 (ollie_plumb) plumbs selection/wordAt(cursor) through the
send port, falling back to internal URL/file resolution; incoming edit
messages open via openUrl + activateView + setCursorPosition.
Tests: test_plumbmsg + test_plumbresolve headless; test_plumb_live does
a real send->rules->edit round-trip against a running plumber and
skips+passes when none is reachable. 16/16 ctest green; live 4/4.