@claw-link/gateway-host 0.1.0 → 0.1.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 +7 -5
- package/bin/cli.js +2 -2
- package/package.json +3 -1
- package/src/adapters/base.js +6 -4
- package/src/adapters/cli.js +2 -1
- package/src/adapters/openclaw.js +4 -2
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# @claw-link/gateway-host — ClawLink Host Gateway
|
|
2
2
|
|
|
3
3
|
Run **any local agent CLI** — OpenClaw, [Hermes](https://hermes-agent.nousresearch.com),
|
|
4
|
-
Claude, Codex, or Cursor — as
|
|
5
|
-
**outbound-only** process: it dials out to ClawLink, claims
|
|
6
|
-
for your agent, runs the chosen runtime locally, and streams the
|
|
7
|
-
inbound ports, no Tailscale Funnel — just a per-agent **Host Token**.
|
|
4
|
+
Claude, Codex, or Cursor — as an agent on the [ClawLink](https://claw-link.co) platform.
|
|
5
|
+
The host worker is a small, **outbound-only** process: it dials out to ClawLink, claims
|
|
6
|
+
customer/admin messages for your agent, runs the chosen runtime locally, and streams the
|
|
7
|
+
reply back. No inbound ports, no Tailscale Funnel — just a per-agent **Host Token**.
|
|
8
8
|
|
|
9
9
|
```
|
|
10
10
|
ClawLink (cloud) ──enqueues message──▶ host-bridge
|
|
@@ -85,4 +85,6 @@ Outbound-only, per-agent token (stored server-side as a hash only), **machine-bo
|
|
|
85
85
|
on first connect (a stolen token fails from any other host), no shell injection, runs
|
|
86
86
|
only the configured binary. See [SECURITY.md](./SECURITY.md).
|
|
87
87
|
|
|
88
|
-
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
Part of [ClawLink](https://claw-link.co) — the multi-tenant AI agent platform. MIT.
|
package/bin/cli.js
CHANGED
|
@@ -42,7 +42,7 @@ async function main() {
|
|
|
42
42
|
console.log([
|
|
43
43
|
'ClawLink Host Gateway',
|
|
44
44
|
'',
|
|
45
|
-
'Usage:
|
|
45
|
+
'Usage: gateway-host <command>',
|
|
46
46
|
' install Install the background service (one-time)',
|
|
47
47
|
' add-agent Add an agent by pasting its Host Token (pulls runtime from ClawLink)',
|
|
48
48
|
' setup install + add-agent in one flow (default)',
|
|
@@ -54,7 +54,7 @@ async function main() {
|
|
|
54
54
|
return;
|
|
55
55
|
|
|
56
56
|
default:
|
|
57
|
-
console.error(`Unknown command '${cmd}'. Try:
|
|
57
|
+
console.error(`Unknown command '${cmd}'. Try: gateway-host help`);
|
|
58
58
|
process.exit(1);
|
|
59
59
|
}
|
|
60
60
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claw-link/gateway-host",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "ClawLink Host Gateway — a secure, outbound-only worker that bridges a local agent CLI (OpenClaw, Hermes, Claude, Codex, Cursor) to your ClawLink agents. No inbound ports; authenticated per-agent by a Host Token.",
|
|
5
|
+
"homepage": "https://claw-link.co",
|
|
5
6
|
"bin": {
|
|
7
|
+
"gateway-host": "bin/cli.js",
|
|
6
8
|
"claw-host": "bin/cli.js"
|
|
7
9
|
},
|
|
8
10
|
"scripts": {
|
package/src/adapters/base.js
CHANGED
|
@@ -50,11 +50,13 @@ async function* spawnStreaming({ binary, argv, cwd, env, timeoutMs = 600000, std
|
|
|
50
50
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
// No hard timeout by default — long generations must NOT be cut off (production
|
|
54
|
+
// learned the 10-min cap dropped legitimate long runs). Set CLAWHOST_TIMEOUT_MS
|
|
55
|
+
// only if an operator explicitly wants a kill-switch.
|
|
53
56
|
let killed = false;
|
|
54
|
-
const timer =
|
|
55
|
-
killed = true;
|
|
56
|
-
|
|
57
|
-
}, timeoutMs);
|
|
57
|
+
const timer = timeoutMs > 0
|
|
58
|
+
? setTimeout(() => { killed = true; try { child.kill('SIGKILL'); } catch { /* gone */ } }, timeoutMs)
|
|
59
|
+
: null;
|
|
58
60
|
|
|
59
61
|
if (stdinInput != null) {
|
|
60
62
|
try { child.stdin.write(stdinInput); } catch { /* ignore */ }
|
package/src/adapters/cli.js
CHANGED
|
@@ -62,7 +62,8 @@ function makeCliAdapter(cfg) {
|
|
|
62
62
|
const fullPrompt = systemPrompt ? `${systemPrompt}\n\n---\n\nUser request:\n${userPrompt}` : userPrompt;
|
|
63
63
|
const clSession = job.session_key || job.session_id || null;
|
|
64
64
|
const resumeId = clSession ? sessionStore.get(cfg.name, clSession) : null;
|
|
65
|
-
|
|
65
|
+
// 0 = no timeout (default) — don't cut off long generations. Opt in with CLAWHOST_TIMEOUT_MS.
|
|
66
|
+
const timeoutMs = cfg.timeoutMs || Number(process.env.CLAWHOST_TIMEOUT_MS) || 0;
|
|
66
67
|
|
|
67
68
|
// Run inside the agent's workspace/scratch dir. Create it if missing so the
|
|
68
69
|
// spawn never fails with ENOENT (coding workspaces are validated at setup).
|
package/src/adapters/openclaw.js
CHANGED
|
@@ -31,7 +31,9 @@ module.exports = {
|
|
|
31
31
|
if (job.system_prompt) messages.push({ role: 'system', content: job.system_prompt });
|
|
32
32
|
messages.push({ role: 'user', content: job.content || '' });
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
// No timeout by default — long generations must not be dropped (production
|
|
35
|
+
// saw the 10-min cap kill legitimate long runs). Opt in via CLAWHOST_TIMEOUT_MS.
|
|
36
|
+
const timeoutMs = Number(process.env.CLAWHOST_TIMEOUT_MS) || 0;
|
|
35
37
|
const res = await fetch(`${url}/v1/chat/completions`, {
|
|
36
38
|
method: 'POST',
|
|
37
39
|
headers: {
|
|
@@ -44,7 +46,7 @@ module.exports = {
|
|
|
44
46
|
stream: false,
|
|
45
47
|
user: job.session_key || job.session_id || undefined,
|
|
46
48
|
}),
|
|
47
|
-
signal: AbortSignal.timeout(timeoutMs),
|
|
49
|
+
...(timeoutMs > 0 ? { signal: AbortSignal.timeout(timeoutMs) } : {}),
|
|
48
50
|
});
|
|
49
51
|
if (!res.ok) throw new Error(`local OpenClaw gateway HTTP ${res.status}`);
|
|
50
52
|
const data = await res.json();
|