Metadata-Version: 2.4
Name: signalmesh-meshd
Version: 0.1.6
Summary: Outbound-only edge daemon for the SignalMesh Submesh Protocol — wrap local software as callable mesh coords with zero inbound ports.
Author-email: acecalisto3 <acecalisto3@gmail.com>
License: MIT
Project-URL: Homepage, https://huggingface.co/spaces/acecalisto3/SignalMesh
Project-URL: HuggingFace Space, https://huggingface.co/spaces/acecalisto3/SignalMesh
Project-URL: Live App, https://acecalisto3-signalmesh.hf.space
Project-URL: Live Lander, https://kyklos.io/submesh/
Keywords: mesh,agents,protocol,websocket,cli
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0
Requires-Dist: websockets>=12
Requires-Dist: PyYAML>=6.0
Provides-Extra: test
Requires-Dist: pytest>=7.0; extra == "test"
Dynamic: license-file

# signalmesh-meshd

Outbound-only edge daemon for the SignalMesh Submesh Protocol. It holds one
persistent WebSocket to the SignalMesh cloud, walks
`~/.signalmesh/harnesses/*/SKILL.md` for op manifests, and executes
`call_request`s as local subprocesses — no inbound ports, ever.

## Install

```bash
pipx install signalmesh-meshd
```

Not on PyPI yet? Install straight from the built wheel:

```bash
pipx install /path/to/signalmesh_meshd-0.1.3-py3-none-any.whl
```

## Quick start

Pair once — exchanges your SignalMesh key for a `device_id` + `device_token`,
written to `~/.signalmesh/meshd.yaml` at mode `0600`:

```bash
meshd pair --key=smesh-XXXXXX --name=my-desktop
```

Connect — opens the outbound WebSocket, advertises discovered ops, and blocks
serving `call_request`s until you kill it:

```bash
meshd connect
```

Invoke a coord from the cloud (this is what the SignalMesh backend does on
your behalf when a mesh caller routes to your device):

```bash
curl -X POST https://acecalisto3-signalmesh.hf.space/api/submesh/call \
  -H "Content-Type: application/json" \
  -H "X-SignalMesh-Key: smesh-XXXXXX" \
  -d '{"coord": "submesh.my_desktop.echo_test.say", "input": {"msg": "hello mesh"}}'
```

## Writing a SKILL.md manifest

Drop a directory under `~/.signalmesh/harnesses/<harness-name>/` containing a
`SKILL.md` with YAML frontmatter. meshd parses the frontmatter block, refuses
any `exec` argv containing shell metacharacters, and advertises one coord per
subcommand.

`~/.signalmesh/harnesses/echo-test/SKILL.md`:

```markdown
---
binary: /bin/echo
subcommands:
  - op_id: say
    exec: ["{msg}"]
    summary: "Echo a string back through the mesh."
    params_schema:
      msg: string
    timeout_ms: 5000
---

# echo-test

Minimal harness proving the mesh call → subprocess → response round trip.
```

This advertises `submesh.<device_name>.echo_test.say`, callable with
`{"msg": "..."}`.

## Android apps (APK) as mesh nodes

Any Android app reachable over `adb` can be a submesh node — mesh-anything
includes your phone. Point `meshd apk wrap` at an installed package name or a
local `.apk` (it installs it first):

```
meshd apk wrap com.example.app
meshd apk wrap ~/Downloads/some-app.apk
```

This resolves the launcher activity and writes an adb-backed SKILL.md harness
exposing `submesh.<device>.apk_<pkg>.{launch,stop,deeplink,tap,text,screenshot}`.
Restart `meshd connect` and the app's coords are advertised to the mesh like
any other harness — same metachar guard, same `shell=False` execution.
Requires Android platform-tools (`adb`) and a device or emulator visible to
`adb devices`.

## Android Studio toolchain as mesh capabilities

Wrap the SDK that ships with Android Studio — emulator, AVDs, adb — so a mesh
caller can boot a headful emulator on your desktop, install builds, and drive
demos/tests end-to-end:

```
meshd studio wrap                       # ~/Library/Android/sdk (or --sdk PATH)
meshd studio wrap-project ~/code/MyApp  # wraps the project's ./gradlew
```

Coords advertised after `meshd connect`:

```
submesh.<device>.android_avds.list                enumerate AVDs
submesh.<device>.android_emulator.boot            boot an AVD headful (detached)
submesh.<device>.android_adb.{devices,kill,install,screenshot,wait_boot}
submesh.<device>.android_project_<name>.{assemble,install,unit_test,instrumented}
```

Emulator boot detaches via a generated launch script, so the mesh call
returns immediately while the emulator window appears on the host. Chain
`boot → wait_boot → install → apk_<pkg>.launch → screenshot` for a full
headful demo of a mobile app, driven entirely by mesh coords.

## Safety model

Every argv token is checked against a shell-metachar denylist twice: once at
manifest-load time (before a coord is even advertised) and once again after
`{param}` substitution (before the subprocess actually runs) — a manifest
can't sneak a malicious literal past you, and a caller can't sneak one in
through input params either. Subprocesses always run with `shell=False`.
Path-typed params are additionally checked against each subcommand's
`allow_paths` glob list; anything that resolves outside the allowlist is
rejected before it ever reaches `argv`.

## Links

- 🤗 **HuggingFace Space** (canonical): https://huggingface.co/spaces/acecalisto3/SignalMesh
- Live app (API endpoints): https://acecalisto3-signalmesh.hf.space
- Interactive lander: https://kyklos.io/submesh/
- Protocol docs: see the Space's `/api/submesh/*` routes (`device/pair`,
  `device/{id}/revoke`, `devices`, `edge`, `call`)

## License

MIT
