@ystemsrx/cfshare 0.1.0
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/LICENSE +21 -0
- package/README.md +337 -0
- package/README.zh.md +337 -0
- package/index.ts +15 -0
- package/openclaw.plugin.json +65 -0
- package/package.json +45 -0
- package/skills/cfshare/SKILL.md +143 -0
- package/src/manager.ts +2712 -0
- package/src/policy.ts +175 -0
- package/src/schemas.ts +255 -0
- package/src/templates/fileExplorerTemplate.ts +1356 -0
- package/src/templates/markdownPreviewTemplate.ts +244 -0
- package/src/tools.ts +256 -0
- package/src/types.ts +110 -0
package/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
2
|
+
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk";
|
|
3
|
+
import { registerCfshareTools } from "./src/tools.js";
|
|
4
|
+
|
|
5
|
+
const plugin = {
|
|
6
|
+
id: "cfshare",
|
|
7
|
+
name: "CFShare",
|
|
8
|
+
description: "Cloudflare Quick Tunnel wrapper for secure temporary sharing",
|
|
9
|
+
configSchema: emptyPluginConfigSchema(),
|
|
10
|
+
register(api: OpenClawPluginApi) {
|
|
11
|
+
registerCfshareTools(api);
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export default plugin;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "cfshare",
|
|
3
|
+
"name": "CFShare",
|
|
4
|
+
"description": "Secure Cloudflare Quick Tunnel wrapper for temporary port and file exposure",
|
|
5
|
+
"skills": ["./skills"],
|
|
6
|
+
"configSchema": {
|
|
7
|
+
"type": "object",
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"stateDir": { "type": "string" },
|
|
11
|
+
"cloudflaredPath": { "type": "string" },
|
|
12
|
+
"policyFile": { "type": "string" },
|
|
13
|
+
"ignoreFile": { "type": "string" },
|
|
14
|
+
"defaultTtlSeconds": { "type": "integer", "minimum": 60, "maximum": 86400 },
|
|
15
|
+
"maxTtlSeconds": { "type": "integer", "minimum": 60, "maximum": 604800 },
|
|
16
|
+
"defaultExposePortAccess": { "type": "string", "enum": ["token", "basic", "none"] },
|
|
17
|
+
"defaultExposeFilesAccess": { "type": "string", "enum": ["token", "basic", "none"] },
|
|
18
|
+
"blockedPorts": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": { "type": "integer", "minimum": 1, "maximum": 65535 }
|
|
21
|
+
},
|
|
22
|
+
"allowedPathRoots": {
|
|
23
|
+
"type": "array",
|
|
24
|
+
"items": { "type": "string" }
|
|
25
|
+
},
|
|
26
|
+
"tunnel": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"properties": {
|
|
30
|
+
"edgeIpVersion": { "type": "string", "enum": ["4", "6", "auto"] },
|
|
31
|
+
"protocol": { "type": "string", "enum": ["http2", "quic", "auto"] }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"rateLimit": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"additionalProperties": false,
|
|
37
|
+
"properties": {
|
|
38
|
+
"enabled": { "type": "boolean" },
|
|
39
|
+
"windowMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 },
|
|
40
|
+
"maxRequests": { "type": "integer", "minimum": 1, "maximum": 100000 }
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"uiHints": {
|
|
46
|
+
"cloudflaredPath": {
|
|
47
|
+
"label": "cloudflared Path",
|
|
48
|
+
"placeholder": "cloudflared",
|
|
49
|
+
"help": "Binary name or absolute path"
|
|
50
|
+
},
|
|
51
|
+
"stateDir": {
|
|
52
|
+
"label": "State Directory",
|
|
53
|
+
"placeholder": "~/.openclaw/cfshare",
|
|
54
|
+
"advanced": true
|
|
55
|
+
},
|
|
56
|
+
"defaultTtlSeconds": {
|
|
57
|
+
"label": "Default TTL (seconds)",
|
|
58
|
+
"help": "Default expiration for new exposures"
|
|
59
|
+
},
|
|
60
|
+
"maxTtlSeconds": {
|
|
61
|
+
"label": "Max TTL (seconds)",
|
|
62
|
+
"help": "Upper TTL limit enforced by policy"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ystemsrx/cfshare",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "OpenClaw plugin to safely expose local ports/files via Cloudflare Quick Tunnel",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"files": [
|
|
8
|
+
"index.ts",
|
|
9
|
+
"src",
|
|
10
|
+
"skills",
|
|
11
|
+
"openclaw.plugin.json"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"openclaw",
|
|
15
|
+
"cloudflared",
|
|
16
|
+
"cloudflare",
|
|
17
|
+
"tunnel",
|
|
18
|
+
"file-share"
|
|
19
|
+
],
|
|
20
|
+
"openclaw": {
|
|
21
|
+
"extensions": [
|
|
22
|
+
"./index.ts"
|
|
23
|
+
],
|
|
24
|
+
"install": {
|
|
25
|
+
"npmSpec": "@ystemsrx/cfshare",
|
|
26
|
+
"localPath": ".",
|
|
27
|
+
"defaultChoice": "npm"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@sinclair/typebox": "0.34.48",
|
|
32
|
+
"ignore": "^7.0.5",
|
|
33
|
+
"mime-types": "^3.0.1",
|
|
34
|
+
"yazl": "^3.3.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/mime-types": "^3.0.1",
|
|
38
|
+
"@types/node": "^25.0.10",
|
|
39
|
+
"openclaw": "2026.1.29",
|
|
40
|
+
"typescript": "^5.7.0"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"openclaw": ">=2026.1.29"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfshare
|
|
3
|
+
description: Expose local services, ports, files, or directories as temporary public HTTPS links via Cloudflare Quick Tunnel. Use for sharing local services, sending downloadable files, previewing content, etc.
|
|
4
|
+
metadata:
|
|
5
|
+
{
|
|
6
|
+
"openclaw":
|
|
7
|
+
{
|
|
8
|
+
"emoji": "☁️",
|
|
9
|
+
"skillKey": "cfshare",
|
|
10
|
+
"requires":
|
|
11
|
+
{
|
|
12
|
+
"bins": ["cloudflared"],
|
|
13
|
+
"config": ["plugins.entries.cfshare.enabled"],
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
}
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# CFShare — Cloudflare Quick Tunnel Exposure
|
|
20
|
+
|
|
21
|
+
Expose local services, ports, files, or directories as temporary public `https://*.trycloudflare.com` links.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Standard Workflow
|
|
26
|
+
|
|
27
|
+
1. **`env_check()`** — Always call first to verify `cloudflared` is available and see current policy defaults.
|
|
28
|
+
2. **Create exposure:**
|
|
29
|
+
- Have a running local service? → `expose_port(port, opts?)`
|
|
30
|
+
- Need to share/preview files or directories? → `expose_files(paths, opts?)`
|
|
31
|
+
3. **After creation succeeds:** Present `public_url` and `expires_at` to the user. Remind them to call `exposure_stop` when finished.
|
|
32
|
+
4. **Inspect / monitor:** `exposure_get(id)` with optional `probe_public: true` to verify end-to-end reachability.
|
|
33
|
+
5. **Troubleshoot:** `exposure_logs(id)` when something goes wrong.
|
|
34
|
+
6. **Cleanup:** `exposure_stop(id)` or `exposure_stop(id="all")`.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Tool Reference
|
|
39
|
+
|
|
40
|
+
### 1. `env_check`
|
|
41
|
+
|
|
42
|
+
Check that `cloudflared` is installed, resolve its version, and return effective policy defaults.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
### 2. `expose_port`
|
|
47
|
+
|
|
48
|
+
Expose an already-running local service via Cloudflare Quick Tunnel. The tool probes `127.0.0.1:<port>` before proceeding and rejects blocked ports.
|
|
49
|
+
|
|
50
|
+
**Errors:** `"invalid port"`, `"port blocked by policy: <N>"`, `"local service is not reachable on 127.0.0.1:<N>"`.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
### 3. `expose_files`
|
|
55
|
+
|
|
56
|
+
Copy files/directories into a temporary workspace, start a read-only static file server, and tunnel it publicly.
|
|
57
|
+
|
|
58
|
+
**File Serving Behavior**
|
|
59
|
+
|
|
60
|
+
Mode: normal
|
|
61
|
+
|
|
62
|
+
- Single file → served directly at the root URL.
|
|
63
|
+
- Multiple files or a directory → displayed in an intuitive file explorer interface.
|
|
64
|
+
|
|
65
|
+
Mode: zip
|
|
66
|
+
|
|
67
|
+
- All files are packaged into a ZIP archive.
|
|
68
|
+
|
|
69
|
+
**Presentation**
|
|
70
|
+
|
|
71
|
+
- Default behaviors: download | preview | raw
|
|
72
|
+
- Behavior can be overridden via query parameters.
|
|
73
|
+
- download → forces browser file save.
|
|
74
|
+
- preview → renders inline (images, PDF, Markdown, audio/video, HTML, text, etc.).
|
|
75
|
+
- raw → serves original content without any wrapper.
|
|
76
|
+
- If a file type is not previewable, preview automatically falls back to raw, then to download.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### 4. `exposure_list`
|
|
81
|
+
|
|
82
|
+
List all tracked sessions (both active and recently-stopped within-process).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### 5. `exposure_get`
|
|
87
|
+
|
|
88
|
+
Get detailed information about one or more sessions. Supports three selection modes (mutually exclusive input shapes via union schema):
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
### 6. `exposure_stop`
|
|
93
|
+
|
|
94
|
+
Stop one, several, or all exposures. Terminates cloudflared process, shuts down origin/proxy servers, and deletes temporary workspace files.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### 7. `exposure_logs`
|
|
99
|
+
|
|
100
|
+
Fetch merged logs from cloudflared tunnel and origin server components.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### 8. `maintenance`
|
|
105
|
+
|
|
106
|
+
Lifecycle management operations.
|
|
107
|
+
|
|
108
|
+
**Action details:**
|
|
109
|
+
|
|
110
|
+
- **`start_guard`** — Start the TTL expiration reaper (runs periodically; usually auto-started).
|
|
111
|
+
- **`run_gc`** — Clean up orphaned workspace directories and stale processes not tracked by any active session.
|
|
112
|
+
- **`set_policy`** — Persist a policy change to disk and reload. Requires at least one of `opts.policy` or `opts.ignore_patterns`.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### 9. `audit_query`
|
|
117
|
+
|
|
118
|
+
Search audit event log.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
### 10. `audit_export`
|
|
123
|
+
|
|
124
|
+
Export filtered audit events to a local JSONL file.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Security & Policy Defaults
|
|
129
|
+
|
|
130
|
+
Policy priority (highest wins): **policy JSON file** > **plugin config** > **built-in defaults**.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Response Behavior Rules
|
|
135
|
+
|
|
136
|
+
When presenting results to the user, the LLM **must**:
|
|
137
|
+
|
|
138
|
+
1. **Always display `public_url` and `expires_at`** after creating an exposure.
|
|
139
|
+
2. **Present timestamps** in the user’s local time zone using a human-readable format (`yyyy-mm-dd HH:MM:SS`). Never include timezone indicators or raw ISO strings.
|
|
140
|
+
3. **Warn** when `access` mode is `"none"` — the link is publicly accessible without authentication.
|
|
141
|
+
4. **Include cleanup instructions** — include `exposure_stop` guidance after successful sharing.
|
|
142
|
+
5. **On error**, suggest `exposure_logs(id)` for diagnostics.
|
|
143
|
+
6. **For security** — if user intent is ambiguous or potentially sensitive, request confirmation before creating exposure.
|