Skip to content

Repository files navigation

giveurl

Turn a local file, directory, or service into a URL with zero configuration.

$ npx giveurl ./report.html
https://laptop.example.ts.net/giveurl/20260802T154500Z-a1b2c3d4e5f60708/artifact.html

giveurl inspects providers already installed and authenticated on the current machine. Tailscale and GitHub Gists work today; Cloudflare remains visible in discovery behind the same provider interface for a future transport.

Why

Agents and their harnesses often run on different machines. A screenshot, Markdown handoff, HTML lesson, or localhost preview should cross that boundary without choosing ports, editing configuration, or uploading private material to an arbitrary third party.

With Tailscale, each share gets a unique HTTPS route on the source machine. Files and directories are served from an OS-assigned loopback port behind Tailscale Serve, so concurrent machines and agents do not contend for ports. Access remains governed by the tailnet and its ACLs.

Requirements

  • Node.js 20 or newer
  • At least one ready provider:
    • Tailscale installed, signed in, and running with MagicDNS and HTTPS available
    • GitHub CLI installed and authenticated to github.com with the gist scope

No runtime npm dependencies are installed. Standard gh auth login authentication includes the Gist scope.

Usage

Share a file, a directory with relative assets, or a localhost service:

npx giveurl screenshot.png
npx giveurl ./lesson
npx giveurl http://127.0.0.1:3000
npx giveurl 3000

The URL is the only value written to stdout. Human diagnostics and the cleanup command go to stderr, so command substitution stays clean:

url="$(npx giveurl -- ./report.md)"
curl -fL "$url"

For agents and scripts, use stable JSON:

npx giveurl ./report.md --json
npx giveurl providers --json
npx giveurl status --json

Preview a change without creating a server, Tailscale route, or Gist:

npx giveurl ./site --dry-run

Tailscale shares remain available while the source machine and local backend are running; GitHub Gists remain hosted until deleted. Stop the share represented by a particular URL:

npx giveurl stop https://laptop.example.ts.net/giveurl/ID/artifact.html

Provider discovery

$ npx giveurl providers
PROVIDER         INSTALLED  AUTHENTICATED  SUPPORT  DETAIL
Tailscale        yes        yes            ready    laptop.example.ts.net
GitHub Gists     yes        yes            ready    authenticated; UTF-8 text files ready
Cloudflare       no         no             planned  not installed

Provider selection defaults to auto, preferring Tailscale when it is ready and falling back to GitHub for compatible files. The provider name can be pinned for reproducible automation:

npx giveurl ./report.html --provider tailscale
npx giveurl ./report.md --provider github

Current provider status:

Provider Discovery Publishing
Tailscale tailscale status --json Files, directories, and localhost services
GitHub Gists gh auth status UTF-8 text files up to 10 MB
Cloudflare wrangler whoami Planned

GitHub Gists

The GitHub provider creates a secret Gist and prints the direct raw file URL rather than the Gist HTML page:

npx giveurl ./report.md --provider github

GitHub Gists support one UTF-8 text file per share. Binary files, directories, and localhost services require Tailscale. giveurl status recognizes only Gists carrying its internal description marker, and giveurl stop <url> verifies the account, marker, and unmodified page or raw URL before deleting the Gist.

Security and lifetime

giveurl does not make Tailscale shares public to the internet. Any tailnet peer permitted by your Tailscale policy may be able to read the shared route, so publish the narrowest useful file or directory. Filesystem shares start a detached loopback server and persist across terminal sessions until giveurl stop is run or the source machine restarts.

A secret GitHub Gist is unlisted, not private: anyone who receives its URL can read it. GitHub hosts the file after the source machine goes offline, and the share remains available until giveurl stop deletes the Gist or it is deleted through GitHub.

Existing Tailscale Serve handlers are preserved. Cleanup turns off the exact /giveurl/<id> route and its matching loopback process rather than resetting the machine's Serve configuration. GitHub cleanup deletes only a Gist that belongs to the authenticated account and carries the giveurl marker.

Agent skill

The small giveurl skill in skills/giveurl/SKILL.md teaches an agent when to publish, verify, consume, and stop a share. Install or link it using the skill mechanism supported by your agent harness.

Install it globally with the Skills CLI:

npx skills add https://github.com/adinvadim/giveurl --skill giveurl -g

Development

npm test
npm pack --dry-run
npm run smoke:tailscale -- --receiver root@runner
# Or use regular SSH over a Tailscale IP:
npm run smoke:tailscale -- --receiver-ssh mini@100.64.0.1 --identity ~/.ssh/id_ed25519
# If the receiver intentionally has MagicDNS disabled:
npm run smoke:tailscale -- --receiver root@runner --resolve-source

The live smoke test publishes every supported MIME type, directories, concurrent shares, HTTP ports, localhost URLs, and an https+insecure service. With --receiver, every artifact is fetched from another tailnet machine over Tailscale SSH; --receiver-ssh supports regular SSH over a Tailscale IP. It also verifies exact bytes, content types, Range requests, nested-route cleanup, and restoration of the previous Serve configuration. --resolve-source preserves TLS hostname validation while routing directly to the source Tailscale IP, which is useful only when the receiver has MagicDNS intentionally disabled.

The CLI uses only Node.js built-ins. Provider-specific behavior lives under src/providers/ so new transports do not complicate the default command.

About

Turn a local file, directory, or service into a URL with zero config.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages