The Problem

Enterprises and power users need a privacy‑first, decentralized network that can traverse firewalls and NAT without relying on a central cloud. Existing VPN or SD‑WAN solutions either expose traffic to a single provider or require heavyweight infrastructure.

What This Does

ztm implements a software‑defined mesh built on HTTP/2 tunnels, providing end‑to‑end TLS and certificate‑based identity. The repository is a portfolio of five self‑contained projects:

  • gui – the desktop UI (Vite + Tauri) under gui/. Core UI logic lives in gui/src/service/ZtmService.js (28 functions) and gui/src/service/common/request.js (29 functions) which wrap network calls.
  • agent – the runtime daemon (agent/main.js, agent/mesh.js). It handles peer discovery, NAT traversal (agent/nat.js), and proxy stitching.
  • cli – thin command‑line wrappers (cli/main.js, 80 functions) that invoke the same agent APIs.
  • hub – a minimal orchestration entry point (hub/main.js).
  • ca – Certificate Authority utilities (ca/).

All projects share a common request layer (gui/src/service/common/request.js) that issues HTTP calls via axios. The UI, daemon, and CLI ultimately call the same service functions, e.g. request.getUrl, request.postWithStream, and agent/api.js helpers like findMesh and init.

How It Is Wired

Execution begins at the binary produced by the CLI or the GUI. For the CLI the entry point is cli/main.jsmain() (line 6) which parses arguments and dispatches to sub‑commands such as agent/apps/ztm/chat/cli.jsmain()doCommand().

  • cli/main.js calls agent/api.js (init, findMesh) and agent/mesh.js (connectProxy, makeInitRequest).
  • agent/mesh.js (125 functions) is the most connected module: it reads/writes files, makes outbound network calls, and is called from 11 other files.
  • The request flow that touches the outside world is: cli/main.jsagent/api.initagent/mesh.connectProxygui/src/service/common/request.getUrlaxios.get(...). This path involves four distinct hops before a network request leaves the process.
  • The UI follows a similar chain: UI actions invoke ZtmService.login (in gui/src/service/ZtmService.js), which calls request.postWithStream, ultimately reaching the same axios layer.

The internal call graph shows request being invoked from 104 distinct locations, making it a high‑blast‑radius function. Conversely, agent/fs.js (10 functions) handles local persistence without network impact and is called from nine places.

No circular import cycles were detected, which simplifies static reasoning. However, deep nesting (max depth 8) and duplicated CLI scaffolding across agent/apps/ztm/*/cli.js increase cognitive load.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/ztm
cd ztm

# Install JavaScript dependencies
npm ci   # uses package-lock.json

# Build the desktop UI (requires Rust/Tauri)
cd gui
npm run build   # invokes Vite + Tauri build defined in gui/apps/.../vite.config.js

# Run the CLI (example: start a chat service)
node cli/main.js chat --help

Configuration files are expected under gui/.env (currently committed – see health notes). The daemon reads its identity from files managed by agent/fs.js and agent/ca/ utilities.

Real‑World Use

A remote‑worker could install the CLI on a laptop, run node cli/main.js tunnel start --mesh prod, and have the daemon create an HTTP/2 tunnel to a corporate hub. The hub (hub/main.js) accepts the connection, authenticates via the certificate chain, and routes traffic to internal services without exposing them to the public Internet.

Code Health & Issues

  • High – Pin GitHub Actions.github/workflows/*.yml use version tags (e.g. Swisyn/setup-android-sdk@v1). Replace with commit SHAs.
  • High – No test suite – 283 source files, zero test files. Add tests for each public entry point.
  • High – Committed .envgui/.env and gui/.env.development contain secrets. Remove, git‑ignore, and rotate credentials.
  • High – Eval over runtime valuecli/main.js executes exec() on a computed string. Refactor to explicit parsing.
  • Medium – Least‑privilege GITHUB_TOKEN – workflows lack permissions: blocks. Declare minimal scopes.
  • Medium – Enable Dependabot – no dependabot config; add .github/dependabot.yml.
  • Medium – Pin Docker base imagebuild/docker/Dockerfile uses mutable debian:12-slim. Pin by digest.
  • Medium – Dependency‑vulnerability gate – CI lacks a scan step; add dependency-review-action or osv-scanner.
  • Medium – Pre‑commit secret scan – No secret‑gate; add a pre‑commit hook (e.g. git-secrets).
  • Medium – Checkout persist‑credentials – set persist-credentials: false in Android build workflow.

Additional observations: the repository includes a license file, CI via GitHub Actions, and a Dockerfile, but the presence of committed secrets and lack of tests are critical blockers for production use.

The Bottom Line

ztm delivers a functional, cross‑platform mesh built on HTTP/2 and TLS, with a clear separation between UI, daemon, and CLI. The codebase is large and loosely organized, showing deep nesting and duplicated CLI scaffolding that hamper maintainability. Security hygiene needs immediate attention (committed secrets, eval usage, unpinned actions). Suitable for teams willing to invest in refactoring and testing; not ready for unmodified production deployment.