Skip to main content

Tailscale preview command plugin for Takopi

Project description

takopi-preview

preview command plugin for takopi. starts a dev server (optional), exposes it via tailscale serve or Cloudflare quick tunnels, and tracks preview sessions by project/worktree context.

published as the takopi-preview package. the command id is preview.

features

  • /preview commands to start, list, stop, and clean up previews
  • provider options: tailnet-only URLs (tailscale) or public quick tunnels (cloudflare)
  • per-project overrides for ports and dev commands
  • optional dev server auto-start with {port} substitution
  • session registry with ttl expiration
  • allowlist support for sensitive commands (like killall)

requirements

  • python 3.14+
  • takopi >= 0.20
  • provider tooling:
    • tailscale installed and authenticated on the host (tailscale up)
    • or cloudflared installed for quick tunnels
  • dev server binds to 127.0.0.1 (tunnels proxy locally)
  • security groups should not expose the dev server port publicly

install

install into the same environment as takopi.

uv tool install -U takopi
uv tool install -U takopi --with takopi-transport-slack --with takopi-preview

or, with a virtualenv:

pip install takopi-transport-slack takopi-preview

setup

  1. install a provider: tailscale (tailscale up) or cloudflared.
  2. if using tailscale, enable magicdns so DEVICE.TAILNET.ts.net resolves.
  3. run takopi with your transport (slack or telegram) as usual.

configuration

add to ~/.takopi/takopi.toml:

[plugins]
enabled = ["takopi-transport-slack", "takopi-preview"]

[plugins.preview]
provider = "cloudflare"
default_port = 3000
dev_command = "pnpm dev -- --host 127.0.0.1 --port {port}"
auto_start = true
ttl_minutes = 120
path_prefix = "/preview"
allowed_user_ids = [123456789]

# optional env injection for the dev server
[plugins.preview.env]
NODE_ENV = "development"

# advanced overrides
local_host = "127.0.0.1"
cloudflared_bin = "cloudflared"
cloudflared_timeout_seconds = 30
cloudflared_args = ["--no-autoupdate"]
path_prefix = "/preview"

# tailscale-specific
tailscale_bin = "tailscale"

# per-project overrides (Takopi project tables are strict, so use plugins.preview.projects)
[plugins.preview.projects.myapp]
port = 5173
dev_command = "npm run dev -- --host 127.0.0.1 --port {port}"

notes:

  • provider = "cloudflare" uses quick tunnels (*.trycloudflare.com) and does not require a Cloudflare account.
  • provider = "tailscale" uses tailnet-only urls from tailscale serve.
  • dev_command may include {port}; it will be substituted at runtime.
  • dev_command is required when auto_start = true. set auto_start = false to manage the dev server yourself.
  • Inline --dev/-- overrides enable auto-start for that run; use --no-start to force manual mode.
  • To require an explicit command each run, omit dev_command and set auto_start = false, then pass --dev or --.
  • ttl_minutes = 0 disables expiration.
  • empty allowed_user_ids means no allowlist enforcement.

commands

  • /preview start [port]: start a preview for the current context
  • /preview start [port] --dev "<command>": override the dev command for this run
  • /preview start [port] -- <command>: shorthand for an inline dev command
  • /preview list: show active previews (url, port, uptime, context)
  • /preview stop [id|port]: stop a preview (defaults to current context)
  • /preview killall: stop all previews (restricted by allowlist)
  • /preview help: usage help

workflow

  1. choose a context: /myapp @feat/login or reply in an existing thread. previews only run in worktrees, so include a branch to create/use one.
  2. run /preview start (or /preview start 5173).
  3. open the returned url, for example:
https://random-words.trycloudflare.com
# tailscale provider example:
https://DEVICE.TAILNET.ts.net/preview/5173
  1. stop when done: /preview stop or /preview stop 5173.

state and ttl

  • tailscale: sessions are derived from tailscale serve status; no preview state file is written.
  • cloudflare: sessions are tracked in-process; list/killall will also scan for cloudflared tunnel --url processes (external URLs may be unavailable).
  • cloudflare: on the first preview command, takopi stops any existing cloudflared tunnel --url processes to prevent stale sessions.
  • tailscale: if the requested port is already served, takopi will attempt to disable the existing serve entry before starting a new preview.
  • tailscale: set path_prefix = "/" to serve from the tailnet root. This avoids subpath issues with apps that assume /, but only one preview can be served at a time.

dev server logs (when auto-started) are written to:

  • ~/.takopi/state/preview-logs/<session>.log

ttl_minutes controls automatic expiration for previews started by this takopi process; expired sessions are cleaned up on the next command invocation. worktrees that are pruned or deleted are also cleaned up on the next command. takopi shutdown stops all previews.

errors

  • missing tailscale: follow the install docs and run tailscale up.
  • missing cloudflared: install cloudflared from the Cloudflare docs or GitHub releases.
  • serve disabled: enable serve for your tailnet (Tailscale admin UI) if you see the "Serve is not enabled" error.
  • port already in use: when auto-starting, takopi will try to stop listeners on that port; if it is still busy, run /preview list or pick a new port.
  • not in a worktree: include a branch (ex: /myapp @feat/foo) to create/use a worktree.
  • dev server failures: the error includes log tail + log path.

spec alignment

this implementation follows the webapp preview workflow spec:

  • command surface: start/list/stop/killall/help
  • config in [plugins.preview] with per-project overrides
  • provider support: tailscale serve or cloudflare quick tunnels
  • tailnet-only https urls (tailscale) or public https urls (cloudflare)
  • tailscale serve registry or in-process tunnel registry
  • ttl-based expiration (ttl_minutes)
  • allowlist enforcement via allowed_user_ids

license

mit

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

takopi_preview-0.1.11.tar.gz (15.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

takopi_preview-0.1.11-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file takopi_preview-0.1.11.tar.gz.

File metadata

  • Download URL: takopi_preview-0.1.11.tar.gz
  • Upload date:
  • Size: 15.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for takopi_preview-0.1.11.tar.gz
Algorithm Hash digest
SHA256 55d7378810aaba69eeeec7c771bdf6322225a5e9d2130678d6670f97502a1440
MD5 84e93e3547e6d313c014adb996d2c65c
BLAKE2b-256 41fd37894a2e3bc61dab821d5aa212abffd659469dd3cb732a75f3c1c8320ace

See more details on using hashes here.

Provenance

The following attestation bundles were made for takopi_preview-0.1.11.tar.gz:

Publisher: workflow.yml on richardliang/takopi-preview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file takopi_preview-0.1.11-py3-none-any.whl.

File metadata

File hashes

Hashes for takopi_preview-0.1.11-py3-none-any.whl
Algorithm Hash digest
SHA256 f27117b255ab8a5c008648999d35cf9564331d09605e298265ebb72f13841ee3
MD5 ed289f3cbc964cecb87d33fbc1fef919
BLAKE2b-256 cfcbf1afd5a31f69af3cbb061b1309c7410cd92d90797b36f9ecad20c4ab7ac3

See more details on using hashes here.

Provenance

The following attestation bundles were made for takopi_preview-0.1.11-py3-none-any.whl:

Publisher: workflow.yml on richardliang/takopi-preview

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page