@alfe.ai/openclaw-remote 0.0.0 → 0.0.1
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/dist/index.cjs +7 -2
- package/dist/index.d.cts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +2 -2
- package/dist/plugin.cjs +2 -304
- package/dist/plugin.d.cts +4 -0
- package/dist/plugin.d.ts +4 -0
- package/dist/plugin.js +1 -304
- package/dist/plugin2.cjs +423 -0
- package/dist/plugin2.js +412 -0
- package/package.json +16 -6
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_plugin = require("./plugin2.cjs");
|
|
6
|
+
exports.buildIsNavigationAllowed = require_plugin.buildIsNavigationAllowed;
|
|
7
|
+
exports.default = require_plugin.plugin;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,45 @@
|
|
|
1
1
|
import { n as RemotePluginConfig, t as plugin } from "./plugin.cjs";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
//#region src/ssrf.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SSRF navigation guard for the shared co-browse surface.
|
|
7
|
+
*
|
|
8
|
+
* Builds the `isNavigationAllowed` predicate that `BrowserSurface` consults
|
|
9
|
+
* before the AGENT's `browser_navigate` tool drives a `page.goto` (see
|
|
10
|
+
* @alfe.ai/browser `BrowserAutomation.navigate`). v1 is a synchronous
|
|
11
|
+
* hostname / IP-literal check: it blocks navigation to private, loopback,
|
|
12
|
+
* link-local, `.internal`, and cloud-metadata (169.254.169.254) hosts UNLESS
|
|
13
|
+
* the integration's SSRF policy explicitly allows the private network
|
|
14
|
+
* (`dangerouslyAllowPrivateNetwork`). The policy is the same one the `alfe`
|
|
15
|
+
* integration exposes under `browser.ssrfPolicy` and threads into runtime
|
|
16
|
+
* config.
|
|
17
|
+
*
|
|
18
|
+
* SCOPE — what this guard does and does NOT cover:
|
|
19
|
+
* - GATES the AGENT's `browser_navigate` tool (the only path through
|
|
20
|
+
* `automation.navigate`).
|
|
21
|
+
* - Does NOT gate HUMAN navigation during a takeover: the human types URLs
|
|
22
|
+
* into the live browser and those never pass through this predicate.
|
|
23
|
+
* Blocking that requires CDP-level request interception
|
|
24
|
+
* (`Fetch.enable` / `Network.requestIntercept`) inside the surface —
|
|
25
|
+
* deferred (follow-up).
|
|
26
|
+
* - Does NOT defend against DNS rebinding: we deliberately do not resolve
|
|
27
|
+
* hostnames to IPs here (no async DNS in a sync predicate). A public
|
|
28
|
+
* hostname that resolves to a private IP at goto-time is NOT caught in v1
|
|
29
|
+
* — also a follow-up (resolve-and-recheck, or CDP-level enforcement).
|
|
30
|
+
*/
|
|
31
|
+
interface SsrfPolicy {
|
|
32
|
+
/** When true, disables the private-network block entirely (allow-all). */
|
|
33
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the navigation predicate for a given SSRF policy. When
|
|
37
|
+
* `dangerouslyAllowPrivateNetwork` is true the predicate is allow-all
|
|
38
|
+
* (matching the `alfe` integration's current default); otherwise it blocks
|
|
39
|
+
* the reserved ranges above and any non-http(s) scheme.
|
|
40
|
+
*/
|
|
41
|
+
declare function buildIsNavigationAllowed(policy: SsrfPolicy | undefined, log?: {
|
|
42
|
+
warn(msg: string): void;
|
|
43
|
+
}): (url: string) => boolean;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { type RemotePluginConfig, type SsrfPolicy, buildIsNavigationAllowed, plugin as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,45 @@
|
|
|
1
1
|
import { n as RemotePluginConfig, t as plugin } from "./plugin.js";
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
//#region src/ssrf.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SSRF navigation guard for the shared co-browse surface.
|
|
7
|
+
*
|
|
8
|
+
* Builds the `isNavigationAllowed` predicate that `BrowserSurface` consults
|
|
9
|
+
* before the AGENT's `browser_navigate` tool drives a `page.goto` (see
|
|
10
|
+
* @alfe.ai/browser `BrowserAutomation.navigate`). v1 is a synchronous
|
|
11
|
+
* hostname / IP-literal check: it blocks navigation to private, loopback,
|
|
12
|
+
* link-local, `.internal`, and cloud-metadata (169.254.169.254) hosts UNLESS
|
|
13
|
+
* the integration's SSRF policy explicitly allows the private network
|
|
14
|
+
* (`dangerouslyAllowPrivateNetwork`). The policy is the same one the `alfe`
|
|
15
|
+
* integration exposes under `browser.ssrfPolicy` and threads into runtime
|
|
16
|
+
* config.
|
|
17
|
+
*
|
|
18
|
+
* SCOPE — what this guard does and does NOT cover:
|
|
19
|
+
* - GATES the AGENT's `browser_navigate` tool (the only path through
|
|
20
|
+
* `automation.navigate`).
|
|
21
|
+
* - Does NOT gate HUMAN navigation during a takeover: the human types URLs
|
|
22
|
+
* into the live browser and those never pass through this predicate.
|
|
23
|
+
* Blocking that requires CDP-level request interception
|
|
24
|
+
* (`Fetch.enable` / `Network.requestIntercept`) inside the surface —
|
|
25
|
+
* deferred (follow-up).
|
|
26
|
+
* - Does NOT defend against DNS rebinding: we deliberately do not resolve
|
|
27
|
+
* hostnames to IPs here (no async DNS in a sync predicate). A public
|
|
28
|
+
* hostname that resolves to a private IP at goto-time is NOT caught in v1
|
|
29
|
+
* — also a follow-up (resolve-and-recheck, or CDP-level enforcement).
|
|
30
|
+
*/
|
|
31
|
+
interface SsrfPolicy {
|
|
32
|
+
/** When true, disables the private-network block entirely (allow-all). */
|
|
33
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build the navigation predicate for a given SSRF policy. When
|
|
37
|
+
* `dangerouslyAllowPrivateNetwork` is true the predicate is allow-all
|
|
38
|
+
* (matching the `alfe` integration's current default); otherwise it blocks
|
|
39
|
+
* the reserved ranges above and any non-http(s) scheme.
|
|
40
|
+
*/
|
|
41
|
+
declare function buildIsNavigationAllowed(policy: SsrfPolicy | undefined, log?: {
|
|
42
|
+
warn(msg: string): void;
|
|
43
|
+
}): (url: string) => boolean;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { type RemotePluginConfig, type SsrfPolicy, buildIsNavigationAllowed, plugin as default };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import plugin from "./
|
|
2
|
-
export { plugin as default };
|
|
1
|
+
import { n as buildIsNavigationAllowed, t as plugin } from "./plugin2.js";
|
|
2
|
+
export { buildIsNavigationAllowed, plugin as default };
|
package/dist/plugin.cjs
CHANGED
|
@@ -1,304 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
let _alfe_ai_remote = require("@alfe.ai/remote");
|
|
4
|
-
let _alfe_ai_browser = require("@alfe.ai/browser");
|
|
5
|
-
let _alfe_ai_terminal = require("@alfe.ai/terminal");
|
|
6
|
-
//#region src/plugin.ts
|
|
7
|
-
/**
|
|
8
|
-
* @alfe.ai/openclaw-remote — OpenClaw plugin for the interactive remote-control
|
|
9
|
-
* relay. Owns one outbound WS to the relay and routes per-session frames to the
|
|
10
|
-
* browser co-browse surface (@alfe.ai/browser) or the web terminal surface
|
|
11
|
-
* (@alfe.ai/terminal). Registers the agent-callable browser tools, including
|
|
12
|
-
* `request_browser_takeover` ("help me complete these").
|
|
13
|
-
*
|
|
14
|
-
* Follows the established Alfe plugin shape (see @alfe.ai/openclaw-webhooks):
|
|
15
|
-
* tools register on every activate(); the long-lived connection is guarded and
|
|
16
|
-
* created inside registerService.start.
|
|
17
|
-
*/
|
|
18
|
-
const pkg = (0, require("node:module").createRequire)(require("url").pathToFileURL(__filename).href)("../package.json");
|
|
19
|
-
const ACTIVATED_KEY = "__alfeRemotePluginActivated";
|
|
20
|
-
const DEFAULT_HANDOFF_TIMEOUT_MS = 600 * 1e3;
|
|
21
|
-
const DEFAULT_CHROME_PATH = "/usr/bin/google-chrome-stable";
|
|
22
|
-
let remoteClient = null;
|
|
23
|
-
let browserSurface = null;
|
|
24
|
-
let terminalSurface = null;
|
|
25
|
-
let apiClient = null;
|
|
26
|
-
let handoffTimeoutMs = DEFAULT_HANDOFF_TIMEOUT_MS;
|
|
27
|
-
const sessionSurfaces = /* @__PURE__ */ new Map();
|
|
28
|
-
function g() {
|
|
29
|
-
return globalThis;
|
|
30
|
-
}
|
|
31
|
-
/** Coerce an unknown tool param to a string (empty if not a string). */
|
|
32
|
-
function asStr(v) {
|
|
33
|
-
return typeof v === "string" ? v : "";
|
|
34
|
-
}
|
|
35
|
-
/** Coerce an unknown tool param to a string or undefined. */
|
|
36
|
-
function optStr(v) {
|
|
37
|
-
return typeof v === "string" ? v : void 0;
|
|
38
|
-
}
|
|
39
|
-
/** Route an inbound relay frame to the owning surface by session. */
|
|
40
|
-
function dispatchFrame(frame, log) {
|
|
41
|
-
if (frame.type === _alfe_ai_remote.RemoteFrameType.SESSION_OPEN) {
|
|
42
|
-
const open = (0, _alfe_ai_remote.decodeJson)(frame.payload);
|
|
43
|
-
if (!open) return;
|
|
44
|
-
const handler = open.surface === "terminal" ? terminalSurface : browserSurface;
|
|
45
|
-
if (!handler) {
|
|
46
|
-
log.warn(`No handler for surface ${open.surface}`);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
sessionSurfaces.set(frame.sessionId, open.surface);
|
|
50
|
-
Promise.resolve(handler.openSession(frame.sessionId, open)).catch((err) => {
|
|
51
|
-
log.warn(`openSession failed: ${err.message}`);
|
|
52
|
-
});
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const surface = sessionSurfaces.get(frame.sessionId);
|
|
56
|
-
const handler = surface === "terminal" ? terminalSurface : surface === "browser" ? browserSurface : null;
|
|
57
|
-
if (!handler) return;
|
|
58
|
-
if (frame.type === _alfe_ai_remote.RemoteFrameType.SESSION_CLOSE) {
|
|
59
|
-
handler.closeSession(frame.sessionId);
|
|
60
|
-
sessionSurfaces.delete(frame.sessionId);
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
handler.handleFrame(frame);
|
|
64
|
-
}
|
|
65
|
-
function startService(pluginConfig, workspaceDir, log) {
|
|
66
|
-
if (g()[ACTIVATED_KEY] === true) {
|
|
67
|
-
log.debug("Alfe Remote plugin already activated — skipping duplicate");
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
g()[ACTIVATED_KEY] = true;
|
|
71
|
-
let alfeConfig = null;
|
|
72
|
-
try {
|
|
73
|
-
alfeConfig = (0, _alfe_ai_config.resolveConfig)();
|
|
74
|
-
} catch {
|
|
75
|
-
log.info("Could not resolve Alfe config — remote plugin idle");
|
|
76
|
-
}
|
|
77
|
-
const wsUrl = pluginConfig.remoteWsUrl;
|
|
78
|
-
const apiKey = alfeConfig?.apiKey;
|
|
79
|
-
const apiUrl = alfeConfig?.apiUrl;
|
|
80
|
-
if (!wsUrl || !apiKey || !apiUrl) {
|
|
81
|
-
log.info("Remote relay URL or credentials not configured — plugin running without relay");
|
|
82
|
-
g()[ACTIVATED_KEY] = false;
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
handoffTimeoutMs = pluginConfig.handoffTimeoutMs ?? DEFAULT_HANDOFF_TIMEOUT_MS;
|
|
86
|
-
apiClient = new _alfe_ai_agent_api_client.AgentApiClient({
|
|
87
|
-
apiKey,
|
|
88
|
-
apiUrl
|
|
89
|
-
});
|
|
90
|
-
const sendFrame = (buf) => {
|
|
91
|
-
remoteClient?.sendFrame(buf);
|
|
92
|
-
};
|
|
93
|
-
browserSurface = new _alfe_ai_browser.BrowserSurface({
|
|
94
|
-
executablePath: pluginConfig.browserExecutablePath ?? DEFAULT_CHROME_PATH,
|
|
95
|
-
headless: pluginConfig.browserHeadless ?? true,
|
|
96
|
-
noSandbox: pluginConfig.browserNoSandbox ?? true,
|
|
97
|
-
userDataDir: `${workspaceDir ?? alfeConfig?.workspacePath ?? "."}/.alfe-browser-profile`,
|
|
98
|
-
logger: log
|
|
99
|
-
}, sendFrame);
|
|
100
|
-
terminalSurface = new _alfe_ai_terminal.TerminalSurface({
|
|
101
|
-
cwd: workspaceDir ?? alfeConfig?.workspacePath,
|
|
102
|
-
logger: log
|
|
103
|
-
}, sendFrame);
|
|
104
|
-
remoteClient = new _alfe_ai_remote.RemoteServiceClient({
|
|
105
|
-
wsUrl,
|
|
106
|
-
apiKey,
|
|
107
|
-
onFrame: (frame) => {
|
|
108
|
-
dispatchFrame(frame, log);
|
|
109
|
-
},
|
|
110
|
-
onConnectionChange: (connected) => {
|
|
111
|
-
log.info(`Remote relay connection: ${connected ? "connected" : "disconnected"}`);
|
|
112
|
-
},
|
|
113
|
-
logger: log
|
|
114
|
-
});
|
|
115
|
-
remoteClient.start();
|
|
116
|
-
log.info(`Remote plugin started — relay ${wsUrl}`);
|
|
117
|
-
}
|
|
118
|
-
function stopService(log) {
|
|
119
|
-
g()[ACTIVATED_KEY] = false;
|
|
120
|
-
remoteClient?.stop();
|
|
121
|
-
remoteClient = null;
|
|
122
|
-
browserSurface?.shutdown();
|
|
123
|
-
browserSurface = null;
|
|
124
|
-
terminalSurface?.shutdown();
|
|
125
|
-
terminalSurface = null;
|
|
126
|
-
apiClient = null;
|
|
127
|
-
sessionSurfaces.clear();
|
|
128
|
-
log.info("Remote plugin stopped");
|
|
129
|
-
}
|
|
130
|
-
function registerTools(api) {
|
|
131
|
-
const needBrowser = () => {
|
|
132
|
-
if (!browserSurface) throw new Error("Browser surface not available (remote relay not connected)");
|
|
133
|
-
return browserSurface;
|
|
134
|
-
};
|
|
135
|
-
api.registerTool({
|
|
136
|
-
name: "browser_navigate",
|
|
137
|
-
label: "browser_navigate",
|
|
138
|
-
description: "Navigate the shared browser to a URL. Returns the final URL and page title.",
|
|
139
|
-
parameters: {
|
|
140
|
-
type: "object",
|
|
141
|
-
properties: { url: {
|
|
142
|
-
type: "string",
|
|
143
|
-
description: "The URL to open"
|
|
144
|
-
} },
|
|
145
|
-
required: ["url"]
|
|
146
|
-
},
|
|
147
|
-
execute: async (_id, params) => needBrowser().automation.navigate(asStr(params.url))
|
|
148
|
-
});
|
|
149
|
-
api.registerTool({
|
|
150
|
-
name: "browser_click",
|
|
151
|
-
label: "browser_click",
|
|
152
|
-
description: "Click an element in the shared browser by CSS selector.",
|
|
153
|
-
parameters: {
|
|
154
|
-
type: "object",
|
|
155
|
-
properties: { selector: {
|
|
156
|
-
type: "string",
|
|
157
|
-
description: "CSS selector to click"
|
|
158
|
-
} },
|
|
159
|
-
required: ["selector"]
|
|
160
|
-
},
|
|
161
|
-
execute: async (_id, params) => {
|
|
162
|
-
await needBrowser().automation.click(asStr(params.selector));
|
|
163
|
-
return { ok: true };
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
api.registerTool({
|
|
167
|
-
name: "browser_type",
|
|
168
|
-
label: "browser_type",
|
|
169
|
-
description: "Type text into an element in the shared browser by CSS selector.",
|
|
170
|
-
parameters: {
|
|
171
|
-
type: "object",
|
|
172
|
-
properties: {
|
|
173
|
-
selector: {
|
|
174
|
-
type: "string",
|
|
175
|
-
description: "CSS selector of the input"
|
|
176
|
-
},
|
|
177
|
-
text: {
|
|
178
|
-
type: "string",
|
|
179
|
-
description: "Text to type"
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
required: ["selector", "text"]
|
|
183
|
-
},
|
|
184
|
-
execute: async (_id, params) => {
|
|
185
|
-
await needBrowser().automation.type(asStr(params.selector), asStr(params.text));
|
|
186
|
-
return { ok: true };
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
api.registerTool({
|
|
190
|
-
name: "browser_wait_for",
|
|
191
|
-
label: "browser_wait_for",
|
|
192
|
-
description: "Wait for a selector to appear, a URL substring to match, or a fixed delay.",
|
|
193
|
-
parameters: {
|
|
194
|
-
type: "object",
|
|
195
|
-
properties: {
|
|
196
|
-
selector: { type: "string" },
|
|
197
|
-
urlPattern: { type: "string" },
|
|
198
|
-
ms: { type: "number" }
|
|
199
|
-
}
|
|
200
|
-
},
|
|
201
|
-
execute: async (_id, params) => {
|
|
202
|
-
await needBrowser().automation.waitFor({
|
|
203
|
-
selector: optStr(params.selector),
|
|
204
|
-
urlPattern: optStr(params.urlPattern),
|
|
205
|
-
ms: typeof params.ms === "number" ? params.ms : void 0
|
|
206
|
-
});
|
|
207
|
-
return { ok: true };
|
|
208
|
-
}
|
|
209
|
-
});
|
|
210
|
-
api.registerTool({
|
|
211
|
-
name: "browser_screenshot",
|
|
212
|
-
label: "browser_screenshot",
|
|
213
|
-
description: "Capture a JPEG screenshot of the shared browser's current page (base64).",
|
|
214
|
-
parameters: {
|
|
215
|
-
type: "object",
|
|
216
|
-
properties: {}
|
|
217
|
-
},
|
|
218
|
-
execute: async () => ({ imageBase64: await needBrowser().automation.screenshot() })
|
|
219
|
-
});
|
|
220
|
-
api.registerTool({
|
|
221
|
-
name: "browser_evaluate",
|
|
222
|
-
label: "browser_evaluate",
|
|
223
|
-
description: "Evaluate a JavaScript expression in the shared browser page and return the result.",
|
|
224
|
-
parameters: {
|
|
225
|
-
type: "object",
|
|
226
|
-
properties: { expression: {
|
|
227
|
-
type: "string",
|
|
228
|
-
description: "JS expression to evaluate"
|
|
229
|
-
} },
|
|
230
|
-
required: ["expression"]
|
|
231
|
-
},
|
|
232
|
-
execute: async (_id, params) => ({ result: await needBrowser().automation.evaluate(asStr(params.expression)) })
|
|
233
|
-
});
|
|
234
|
-
api.registerTool({
|
|
235
|
-
name: "request_browser_takeover",
|
|
236
|
-
label: "request_browser_takeover",
|
|
237
|
-
description: "Ask a human to take over the browser you're currently looking at and complete a step you can't do yourself — logging in, solving a captcha, or clicking through a manual flow. The human sees your current live page, completes the instructions, and hands control back; you then resume on the same authenticated page. Blocks until the human is done or the request times out.",
|
|
238
|
-
parameters: {
|
|
239
|
-
type: "object",
|
|
240
|
-
properties: {
|
|
241
|
-
instructions: {
|
|
242
|
-
type: "string",
|
|
243
|
-
description: "What you need the human to do, e.g. 'Log in with the saved credentials and complete the 2FA prompt, then click Continue.'"
|
|
244
|
-
},
|
|
245
|
-
url: {
|
|
246
|
-
type: "string",
|
|
247
|
-
description: "Optional: the page you're stuck on (display only — the human sees your live page)."
|
|
248
|
-
},
|
|
249
|
-
conversationId: {
|
|
250
|
-
type: "string",
|
|
251
|
-
description: "Optional: the chat conversation to surface the request in."
|
|
252
|
-
}
|
|
253
|
-
},
|
|
254
|
-
required: ["instructions"]
|
|
255
|
-
},
|
|
256
|
-
execute: async (_id, params) => {
|
|
257
|
-
const surface = needBrowser();
|
|
258
|
-
if (!apiClient) throw new Error("Remote plugin not connected");
|
|
259
|
-
const { sessionId } = await apiClient.requestBrowserTakeover({
|
|
260
|
-
instructions: asStr(params.instructions),
|
|
261
|
-
url: optStr(params.url),
|
|
262
|
-
conversationId: optStr(params.conversationId)
|
|
263
|
-
});
|
|
264
|
-
try {
|
|
265
|
-
return {
|
|
266
|
-
sessionId,
|
|
267
|
-
...await surface.requestHandoff(handoffTimeoutMs)
|
|
268
|
-
};
|
|
269
|
-
} finally {
|
|
270
|
-
await apiClient.completeRemoteSession(sessionId).catch(() => {});
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
const plugin = {
|
|
276
|
-
id: "@alfe.ai/openclaw-remote",
|
|
277
|
-
name: "Remote",
|
|
278
|
-
description: "Interactive remote control — browser co-browse takeover and web terminal",
|
|
279
|
-
version: pkg.version,
|
|
280
|
-
activate(api) {
|
|
281
|
-
const log = api.logger;
|
|
282
|
-
const pluginConfig = api.config?.plugins?.entries?.["@alfe.ai/openclaw-remote"]?.config ?? {};
|
|
283
|
-
pluginConfig.browserExecutablePath ??= api.config?.browser?.executablePath;
|
|
284
|
-
pluginConfig.browserHeadless ??= api.config?.browser?.headless;
|
|
285
|
-
pluginConfig.browserNoSandbox ??= api.config?.browser?.noSandbox;
|
|
286
|
-
registerTools(api);
|
|
287
|
-
api.registerService({
|
|
288
|
-
id: "alfe-remote",
|
|
289
|
-
start: (ctx) => {
|
|
290
|
-
startService(pluginConfig, ctx.workspaceDir, log);
|
|
291
|
-
},
|
|
292
|
-
stop: () => {
|
|
293
|
-
stopService(log);
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
log.info("Alfe Remote plugin activated");
|
|
297
|
-
},
|
|
298
|
-
deactivate(api) {
|
|
299
|
-
stopService(api.logger);
|
|
300
|
-
api.logger.info("Alfe Remote plugin deactivated");
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
//#endregion
|
|
304
|
-
module.exports = plugin;
|
|
1
|
+
const require_plugin = require("./plugin2.cjs");
|
|
2
|
+
module.exports = require_plugin.plugin;
|
package/dist/plugin.d.cts
CHANGED
|
@@ -37,6 +37,10 @@ interface OpenClawConfig {
|
|
|
37
37
|
executablePath?: string;
|
|
38
38
|
headless?: boolean;
|
|
39
39
|
noSandbox?: boolean;
|
|
40
|
+
/** SSRF policy the `alfe` integration writes; consumed by the nav guard. */
|
|
41
|
+
ssrfPolicy?: {
|
|
42
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
43
|
+
};
|
|
40
44
|
[key: string]: unknown;
|
|
41
45
|
};
|
|
42
46
|
[key: string]: unknown;
|
package/dist/plugin.d.ts
CHANGED
|
@@ -37,6 +37,10 @@ interface OpenClawConfig {
|
|
|
37
37
|
executablePath?: string;
|
|
38
38
|
headless?: boolean;
|
|
39
39
|
noSandbox?: boolean;
|
|
40
|
+
/** SSRF policy the `alfe` integration writes; consumed by the nav guard. */
|
|
41
|
+
ssrfPolicy?: {
|
|
42
|
+
dangerouslyAllowPrivateNetwork?: boolean;
|
|
43
|
+
};
|
|
40
44
|
[key: string]: unknown;
|
|
41
45
|
};
|
|
42
46
|
[key: string]: unknown;
|