@sharnix/agent 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -0
- package/index.js +19 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @sharnix/agent
|
|
2
|
+
|
|
3
|
+
Instantly share your local app with anyone — no config, no port forwarding, no deployment.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
SHARNIX_API_KEY=shx_... npx @sharnix/agent --port 3000
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## What it does
|
|
10
|
+
|
|
11
|
+
`@sharnix/agent` opens a secure tunnel from [relay.sharnix.com](https://relay.sharnix.com) to your local machine. Visitors access your app through a shareable link — you never expose a port publicly.
|
|
12
|
+
|
|
13
|
+
- **Stable tunnel ID** per project directory — the same tunnel URL survives restarts
|
|
14
|
+
- **Auto-provisioned** — creates an agent credential on first run, stored in `~/.sharnix/`
|
|
15
|
+
- **Auto-suspends** share links when you disconnect, reactivates when you reconnect
|
|
16
|
+
- **Works with any framework** — Next.js, Vite, Django, Rails, anything on localhost
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Node.js 18 or later
|
|
21
|
+
- A free Sharnix account at [relay.sharnix.com](https://relay.sharnix.com)
|
|
22
|
+
- An API key from **Settings → API Keys**
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Tunnel port 3000
|
|
28
|
+
SHARNIX_API_KEY=shx_... npx @sharnix/agent --port 3000
|
|
29
|
+
|
|
30
|
+
# Tunnel a different port with a label
|
|
31
|
+
SHARNIX_API_KEY=shx_... npx @sharnix/agent --port 8080 --label "staging"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Set the key in your shell profile so you don't repeat it:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# ~/.bashrc or ~/.zshrc
|
|
38
|
+
export SHARNIX_API_KEY=shx_...
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then just:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @sharnix/agent --port 3000
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Options
|
|
48
|
+
|
|
49
|
+
| Flag | Default | Description |
|
|
50
|
+
|------|---------|-------------|
|
|
51
|
+
| `--port`, `-p` | `3000` | Local port to forward |
|
|
52
|
+
| `--label`, `-l` | — | Human-readable label for this tunnel |
|
|
53
|
+
| `--name` | `local-dev` | Agent name used on first-time setup |
|
|
54
|
+
| `--help`, `-h` | — | Show help |
|
|
55
|
+
|
|
56
|
+
## Environment variables
|
|
57
|
+
|
|
58
|
+
| Variable | Description |
|
|
59
|
+
|----------|-------------|
|
|
60
|
+
| `SHARNIX_API_KEY` | Your API key (required) |
|
|
61
|
+
| `SHARNIX_URL` | Override relay URL (default: `https://relay.sharnix.com`) |
|
|
62
|
+
|
|
63
|
+
## Creating share links
|
|
64
|
+
|
|
65
|
+
Once the agent is running, create share links from:
|
|
66
|
+
|
|
67
|
+
- **Dashboard** — [relay.sharnix.com/app](https://relay.sharnix.com/app)
|
|
68
|
+
- **AI agent** — via the [`@sharnix/mcp-server`](https://www.npmjs.com/package/@sharnix/mcp-server) MCP integration
|
|
69
|
+
- **API** — `POST /api/v1/orgs/:slug/tunnels/:id/links`
|
|
70
|
+
|
|
71
|
+
Share links support permissions (`read-only`, `full`), expiry dates, email restrictions, and one-time view mode.
|
|
72
|
+
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
1. On first run, the agent calls the Sharnix API to create a credential pair (`agentId` + `secret`), saved to `~/.sharnix/agent.json`
|
|
76
|
+
2. A stable tunnel ID is generated for the current working directory and saved to `~/.sharnix/tunnel-<hash>.json`
|
|
77
|
+
3. The agent opens a WebSocket to the relay and registers the tunnel
|
|
78
|
+
4. When a visitor opens a share link, the relay forwards their HTTP request over the WebSocket to your local app and streams the response back
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
package/index.js
CHANGED
|
@@ -23,6 +23,7 @@ const has = (flag) => args.includes(flag);
|
|
|
23
23
|
const port = parseInt(get('--port') || get('-p') || '3000', 10);
|
|
24
24
|
const label = get('--label') || get('-l') || null;
|
|
25
25
|
const agentName = get('--name') || 'local-dev';
|
|
26
|
+
const shareOnStart = has('--share');
|
|
26
27
|
|
|
27
28
|
if (has('--help') || has('-h')) {
|
|
28
29
|
console.log(`
|
|
@@ -36,6 +37,7 @@ if (has('--help') || has('-h')) {
|
|
|
36
37
|
--port, -p <n> Local port to forward (default: 3000)
|
|
37
38
|
--label, -l <s> Human-readable label for this tunnel
|
|
38
39
|
--name <s> Agent name used on first setup (default: local-dev)
|
|
40
|
+
--share Create a read-only share link on connect and print the URL
|
|
39
41
|
--help, -h Show this message
|
|
40
42
|
|
|
41
43
|
Environment:
|
|
@@ -145,6 +147,7 @@ function connect() {
|
|
|
145
147
|
console.log(` Dashboard → relay.sharnix.com/app/tunnels/${tunnelId}`);
|
|
146
148
|
console.log(` MCP agent → "create a share link for my tunnel"\n`);
|
|
147
149
|
console.log(` Press Ctrl+C to disconnect.\n`);
|
|
150
|
+
if (shareOnStart) await createShareLink();
|
|
148
151
|
});
|
|
149
152
|
|
|
150
153
|
ws.on('message', async (data) => {
|
|
@@ -166,6 +169,22 @@ function connect() {
|
|
|
166
169
|
});
|
|
167
170
|
}
|
|
168
171
|
|
|
172
|
+
async function createShareLink() {
|
|
173
|
+
try {
|
|
174
|
+
const orgs = await api('GET', '/api/v1/orgs');
|
|
175
|
+
if (!orgs.length) return;
|
|
176
|
+
const orgSlug = creds.orgSlug || orgs[0].slug;
|
|
177
|
+
const result = await api('POST', `/api/v1/orgs/${orgSlug}/tunnels/${tunnelId}/links`, {
|
|
178
|
+
permission: 'read-only',
|
|
179
|
+
label: label || 'Shared via agent',
|
|
180
|
+
});
|
|
181
|
+
console.log(` Share link : ${result.url}`);
|
|
182
|
+
console.log(` Permission : read-only\n`);
|
|
183
|
+
} catch (err) {
|
|
184
|
+
console.error(` Could not create share link: ${err.message}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
169
188
|
function startHeartbeat() {
|
|
170
189
|
clearInterval(heartbeatTimer);
|
|
171
190
|
heartbeatTimer = setInterval(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sharnix/agent",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Tunnel your local app through Sharnix — share previews with one command",
|
|
5
5
|
"keywords": ["tunnel", "preview", "sharing", "localhost", "sharnix"],
|
|
6
6
|
"homepage": "https://relay.sharnix.com",
|