AI prompts
base on Unix pipes between devices # Dumb pipe
This is an example to use [iroh](https://crates.io/crates/iroh) to create a dumb pipe to connect two machines with a QUIC connection.
Iroh will take care of hole punching and NAT traversal whenever possible, and fall back to a
relay if hole punching does not succeed.
It is also useful as a standalone tool for quick copy jobs.
This is inspired by the unix tool [netcat](https://en.wikipedia.org/wiki/Netcat). While netcat
works with IP addresses, dumbpipe works with 256 bit node ids and therefore is somewhat location transparent. In addition, connections are encrypted using TLS.
# Installation
With [Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html):
```
cargo install dumbpipe
```
If you've installed [Homebrew](https://brew.sh), you can install it using the following command:
```
brew install dumbpipe
```
# Examples
## Use dumbpipe to stream video using [ffmpeg / ffplay](https://ffmpeg.org/):
This is using standard input and output.
### Sender side
On Mac OS:
```
ffmpeg -f avfoundation -r 30 -i "0" -pix_fmt yuv420p -f mpegts - | dumbpipe listen
```
On Linux:
```
ffmpeg -f v4l2 -i /dev/video0 -r 30 -preset ultrafast -vcodec libx264 -tune zerolatency -f mpegts - | dumbpipe listen
```
outputs ticket
### Receiver side
```
dumbpipe connect nodeealvvv4nwa522qhznqrblv6jxcrgnvpapvakxw5i6mwltmm6ps2r4aicamaakdu5wtjasadei2qdfuqjadakqk3t2ieq | ffplay -f mpegts -fflags nobuffer -framedrop -
```
- Adjust the ffmpeg options according to your local platform and video capture devices.
- Use ticket from sender side
## Share a shell for pair- or ensemble programming with [tty-share](https://github.com/elisescu/tty-share):
Sharing a terminal session over the internet is useful for collaboration between programmers, but the public [tty-share](https://github.com/elisescu/tty-share) server isn't very reliable and, more importantly, [it is not end-to-end encrypted](https://tty-share.com/how-it-works/#end-to-end-encryption).
On the server:
```
$ dumbpipe listen-tcp --host localhost:8000 &
$ tty-share
```
On the client(s):
```
$ dumbpipe connect-tcp --addr localhost:8000 <ticket> &
$ tty-share http://localhost:8000/s/local/
```
## Forward development web server
You have a development webserver running on port 3000, and want to share it with
a colleague in another office or on the other side of the world.
### The web server
```
npm run dev
> - Local: http://localhost:3000
```
### The dumbpipe listener
*Listens* on an endpoint and forwards all incoming requests to the dev web
server that is listening on localhost on port 3000. Any number of connections can
flow through a single dumb pipe, but they will be separate local tcp connections.
```
dumbpipe listen-tcp --host localhost:3000
```
This command will output a ticket that can be used to connect.
### The dumbpipe connector
*Listens* on a tcp interface and port on the local machine. In this case on port 3001.
Forwards all incoming connections to the endpoint given in the ticket.
```
dumbpipe connect-tcp --addr 0.0.0.0:3001 <ticket>
```
### Testing it
You can now browse the website on port 3001.
## Forward a Unix Socket Application (e.g., Zellij)
You can forward applications that communicate over Unix sockets, like the terminal multiplexer [Zellij](https://zellij.dev/).
Note: Zellij keeps its session sockets under `$ZELLIJ_SOCKET_DIR/<VERSION>/session-name`

1. On the remote host (with Zellij running):
```bash
zellij --version
# zellij 0.42.2
# Forward the remote Zellij socket
# Socket path follows pattern: /tmp/zellij-0/<VERSION>/<session-name>
dumbpipe listen-unix --socket-path /tmp/zellij-0/0.42.2/remote-task-1234
```
This will give you a `<ticket>`.
2. On your local machine:
```bash
zellij --version
# zellij 0.42.1
# Create the local socket directory structure
mkdir -p /tmp/zj-remote/0.42.1
# Create a local socket connected to the remote one
dumbpipe connect-unix --socket-path /tmp/zj-remote/0.42.1/remote-task-1234 <ticket>
```
3. Attach your local Zellij client:
```bash
# In a new terminal window/tab, set the socket directory and attach
ZELLIJ_SOCKET_DIR=/tmp/zj-remote zellij attach remote-task-1234
```
# Advanced features
## Combining Listeners
You can mix and match listeners. For example, forward from a remote Unix socket to a local TCP port:
```bash
# Machine A: Listen on a Unix socket
dumbpipe listen-unix --socket-path /var/run/my-app.sock
# Machine B: Connect to it via a local TCP port
dumbpipe connect-tcp --addr 127.0.0.1:8080 <ticket>
```
## Custom ALPNs
Dumbpipe has an expert feature to specify a custom [ALPN](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation) string. You can use it to interact with
existing iroh services.
E.g. here is how to interact with the iroh-blobs
protocol:
```
echo request1.bin | dumbpipe connect <ticket> --custom-alpn utf8:/iroh-bytes/2 > response1.bin
```
(`/iroh-bytes/2` is the ALPN string for the iroh-blobs protocol, which used to be called iroh-bytes.)
if request1.bin contained a valid request for the `/iroh-bytes/2` protocol, response1.bin will
now contain the response.
", Assign "at most 3 tags" to the expected json: {"id":"14421","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"