<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Cradicle Explorer</title>
    <link href="/css/bootstrap/bootstrap.min.css" rel="stylesheet">
    <style>
      .form-control-dark::placeholder {
          color: #aaa;
          opacity: 1;
      }
    </style>
    <link rel="stylesheet" href="/assets/fontawesome/css/all.min.css">
    <link rel="icon" type="image/png" href="/favicon.png">


                <link href="/css/dashboard.css" rel="stylesheet">
                </head>
                <body>
                <header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
                  <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="/">Cradicle Explorer</a>
                  <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                  </button>
                  <form method="get" action="/cgi-bin/main" style="width:100%;"><input class="form-control form-control-dark w-100 rounded-0 border-0" type="text" name="q" placeholder="Search repos" aria-label="Search"></form>
                  <div class="navbar-nav flex-row">
                    <div class="nav-item text-nowrap">
                      <a class="nav-link px-3 active" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5">pear-on</a>
                    </div>
                  </div>
                </header>
                <div class="container-fluid">
                  <div class="row">
                    <nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-dark sidebar collapse">
                      <div class="position-sticky pt-3 sidebar-sticky">
                        <ul class="nav flex-column">
                          <li class="nav-item">
                            <a class="nav-link active" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5">
                              <i class="align-text-bottom fa-solid fa-info"></i>
                              Info
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5&issue=list">
                              <i class="align-text-bottom fa-solid fa-layer-group"></i>
                              Issues
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5&patch=list">
                              <i class="align-text-bottom fa-solid fa-vest-patches"></i>
                              Patches
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5&wallet=list">
                              <i class="align-text-bottom fa-solid fa-wallet"></i>
                              Wallets
                            </a>
                          </li>
                          <li class="nav-item">
                            <a class="nav-link" href="/cgi-bin/repo?id=z3HMmZuGCihcWYqbCxAr46ARoegK5&source=.">
                              <i class="align-text-bottom fa-solid fa-code"></i>
                              Source
                            </a>
                          </li>
                        <h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted text-uppercase">
                          <span></span>
                        </h6>
                        <ul class="nav flex-column mb-2">
                        
                        </ul>
                      </div>
                    </nav>
                <main class="col-md-9 ms-sm-auto col-lg-10">
                  <div class="container px-1 py-3">
        

    <div class="list-group">
    <div class="list-group-item">
    <div style="font-size:1.3rem;">pear-on</div>
    <div class="repo-item">Collaboratively program and Pear-On code via your terminal </div>
    <div>rad:z3HMmZuGCihcWYqbCxAr46ARoegK5</div>
    </div>
    <div class="list-group-item">
    <div>Visibility</div>
    <div class="repo-item">public</div>
    </div>
    <div class="list-group-item">
    <div>Delegates</div><div class="repo-item">did:key:z6MkpsiSHUKwmyUAwfnaJ2HDG3P2u66bebLmksu16K8u5ic1</div>
    </div>
    <div class="list-group-item">
    <div>Default branch</div>
    <div><span class="repo-item">main &#8594 ac93177e0c3ab563cc7ec1be90b68f36ebe35cc3</span> (Fri Mar  8 22:09:28 2024)</div>
    </div>
    <div class="list-group-item">
    <div>Threshold</div>
    <div class="repo-item">1</div>
    </div>
    </div>
    
        <div class="list-group mt-3">
        <div class="list-group-item">
        <div class="mb-2" style="font-weight:bold;"><i class="fa-solid fa-book"></i> README.md</div>
        <pre style="margin:0; font-size:0.85rem; overflow-x:auto; color:#fafafa;"># Pear-On

&lt;img src=&quot;https://git.sr.ht/~meejah/pear-on/blob/main/assets/images/icon.png&quot; alt= &quot;(A picture of 
two excited anthropomorphic pears in front of a computer monitor)&quot; /&gt;

## Motivation

Pair-programming can be a great and producive way to collaborate.

Many ways of doing this involve central services and although these are frequently using Free/Open software to run them, setting up one own services is an impediment.

Pear-On uses Magic Wormhole with Dilation to enable peer-to-peer collaborative sessions.


## Origin Story

We often use `tty-share` (https://tty-share.com/) to join a collaborative pair-programming session (either one-on-one or one-to-many).
This is a great program!

However, having a live and interactive terminal session running through a third-party-run server doesn&#x27;t leave the best feelings.

Knowing about Magic Wormhole, an obvious use of its &quot;Dilation&quot; feature is to forward TCP streams back (or forth).
Since `tty-share` is using WebSockets, has an open-source and easy-to-run server, this is a perfect test-bed.

Terminal-sharing is interesting and useful -- but of course not an entire &quot;pair programming&quot; toolkit by itself.
We hope to expand Pear-On to include other streaming features (such as audio, video, etc).


## The Technical Details

Looking just at the `tty-share` use-case, we have:

- the &quot;host&quot; runs `tty-share` as a server
- one or more &quot;guests&quot; run ``tty-share` as the client
- required: some way to stream data between the two

Now comes an unfortunately longstanding Internet problem: securely connecting two peers is hard (still, for various network reasons)!

### A Public Service

The author of `tty-share` runs infrastructure allowing the host and any guests to connect via a public Web site.
This is a great service!
We have no reason to believe it is malicious in any way -- but it would be very nice not to depend on it.

Hosting a service on a public-routed IP address is a popular way around the issue of connecting peers on the Internet.


### Magic Wormhole

Consider [Magic Wormhole](https://magic-wormhole.readthedocs.io/en/latest/welcome.html): it *also* solves the peer problem by having a public service.

However, it is a little more general-purpose: with the Dilation feature, we can use Magic Wormhole&#x27;s public service for _any_ kind of peer communication (not just terminal-sharing, or whatever).

Magic Wormhole also does _end-to-end encryption_, meaning that the service cannot see the contents of our messages even if the operator is malicious (or is compromised by a malicious actor).


### Connecting the Pieces

Pear-On consists of:

- a GUI (written in Haskell + monomer)
- a way to start a Dilated Magic Wormhole (currently [fowl](https://github.com/meejah/fowl)
- glue to connect `tty-share` via the Wormholes

#### Why Not Pure Haskell?

Note that there *is* a [Haskell Magic-Wormhole library](https://hackage.haskell.org/package/magic-wormhole) but it does not yet support Dilation.

`fowl` is my attempt to give authors a way to leverage the full-featured Python implementation of Dilation + Magic Wormhole from a &quot;black box&quot; CLI program -- no need for Python bindings, etc!

That said, I&#x27;d love to see the Haskell Wormhole library grow a Dilation implementation -- then Pear-On could be pure Haskell!


## Running the Software

Okay, great, lets use the software!

Currently you must have `fowl` in your `PATH`.
I use a &quot;virtualenv&quot; to accomplish this::

    python -m venv venv
    ./venv/bin/pip install fowl
    source venv/bin/activate
    fowl --help

Once `fowl` is in your `PATH` and can be run as a normal program, you can start &quot;pear-on&quot; using cabal::

    cabal run

Note that you might need to `export PYTHONUNBUFFERED=1` into the shell to get things working (see https://github.com/meejah/fowl/issues/6 ).

This should pop up the GUI (such as it is so far)
</pre>
        </div>
        </div>

</div>
</main>
</div>
</div>


</body>
</html>

