surf-cli 2.14.0 → 2.15.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/README.md +62 -33
- package/agents/gpt-pro.md +19 -0
- package/native/browser-scheduler.cjs +348 -0
- package/native/browser-session-store.cjs +271 -0
- package/native/cli.cjs +331 -60
- package/native/do-executor.cjs +5 -0
- package/native/host-helpers.cjs +19 -3
- package/native/host-sessions.cjs +8 -1
- package/native/host.cjs +766 -19
- package/native/playbook-cli.cjs +16 -3
- package/native/surf-error.cjs +47 -0
- package/native/tool-scope.cjs +107 -0
- package/native/workflow-definition.cjs +7 -0
- package/package.json +8 -2
- package/pi-extension/surf.ts +18 -4
- package/skills/surf/SKILL.md +48 -21
package/native/host-helpers.cjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const networkFormatters = require("./formatters/network.cjs");
|
|
3
|
+
const { recoveryFor } = require("./surf-error.cjs");
|
|
3
4
|
|
|
4
5
|
function buildProviderUploadMessage(provider, tabId, filePaths, id) {
|
|
5
6
|
const normalizedProvider = String(provider || "").toLowerCase();
|
|
@@ -19,11 +20,22 @@ function formatToolError(error) {
|
|
|
19
20
|
: typeof error === "string"
|
|
20
21
|
? error
|
|
21
22
|
: error?.message || String(error);
|
|
22
|
-
const
|
|
23
|
+
const recoveryCommand = recoveryFor(error);
|
|
24
|
+
const display = recoveryCommand ? `${message}\nRecovery: ${recoveryCommand}` : message;
|
|
25
|
+
const result = { content: [{ type: "text", text: display }] };
|
|
23
26
|
if (error && typeof error === "object") {
|
|
24
27
|
result.message = message;
|
|
25
28
|
if (typeof error.code === "string") result.code = error.code;
|
|
26
29
|
if (typeof error.jobId === "string") result.jobId = error.jobId;
|
|
30
|
+
const details = typeof error.toJSON === "function" ? error.toJSON() : {};
|
|
31
|
+
for (const key of [
|
|
32
|
+
"session", "target", "lastUrl", "laneKey", "resourceKeys", "retryable", "queue", "reason",
|
|
33
|
+
"browserEpoch", "expectedBrowserEpoch", "recoveryCommand",
|
|
34
|
+
]) {
|
|
35
|
+
if (error[key] !== undefined) details[key] = error[key];
|
|
36
|
+
}
|
|
37
|
+
if (recoveryCommand) details.recoveryCommand = recoveryCommand;
|
|
38
|
+
if (Object.keys(details).length > 0) result.details = details;
|
|
27
39
|
}
|
|
28
40
|
return result;
|
|
29
41
|
}
|
|
@@ -38,6 +50,10 @@ function formatToolContent(result, log = () => {}, options = {}) {
|
|
|
38
50
|
const text = (s) => [{ type: "text", text: s }];
|
|
39
51
|
|
|
40
52
|
if (!result) return text("OK");
|
|
53
|
+
|
|
54
|
+
if (result.session || Array.isArray(result.sessions) || Object.hasOwn(result, "targetClosed")) {
|
|
55
|
+
return text(JSON.stringify(result, null, 2));
|
|
56
|
+
}
|
|
41
57
|
|
|
42
58
|
if (result.aiResult) {
|
|
43
59
|
if (result.mode === "find") {
|
|
@@ -805,7 +821,7 @@ function mapToolToMessage(tool, args, tabId) {
|
|
|
805
821
|
case "switch_tab":
|
|
806
822
|
return { type: "SWITCH_TAB", tabId: a.tab_id || a.tabId };
|
|
807
823
|
case "close_tab":
|
|
808
|
-
return { type: "CLOSE_TAB", tabId: a.tab_id || a.tabId, tabIds: a.tab_ids || a.tabIds };
|
|
824
|
+
return { type: "CLOSE_TAB", tabId: a.tab_id || a.tabId || tabId, tabIds: a.tab_ids || a.tabIds };
|
|
809
825
|
case "tab.list":
|
|
810
826
|
return { type: "LIST_TABS" };
|
|
811
827
|
case "tab.new":
|
|
@@ -823,7 +839,7 @@ function mapToolToMessage(tool, args, tabId) {
|
|
|
823
839
|
if (typeof id === "string" && !/^\d+$/.test(id)) {
|
|
824
840
|
return { type: "NAMED_TAB_CLOSE", name: id };
|
|
825
841
|
}
|
|
826
|
-
return { type: "CLOSE_TAB", tabId: id, tabIds: ids };
|
|
842
|
+
return { type: "CLOSE_TAB", tabId: id ?? tabId, tabIds: ids };
|
|
827
843
|
}
|
|
828
844
|
case "tab.move": {
|
|
829
845
|
const id = a.id || a.tab_id || a.tabId;
|
package/native/host-sessions.cjs
CHANGED
|
@@ -123,7 +123,7 @@ class HostSessionManager {
|
|
|
123
123
|
context.stream = false;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
beginRequest(context, { id, tool, deadlineMs }) {
|
|
126
|
+
beginRequest(context, { id, tool, deadlineMs, skipLease = false }) {
|
|
127
127
|
if (context.closed) return Promise.reject(new Error("connection is closed"));
|
|
128
128
|
if (context.workTimer) {
|
|
129
129
|
clearTimeout(context.workTimer);
|
|
@@ -149,8 +149,15 @@ class HostSessionManager {
|
|
|
149
149
|
controller,
|
|
150
150
|
signal: controller.signal,
|
|
151
151
|
tombstoned: false,
|
|
152
|
+
skipLease,
|
|
152
153
|
};
|
|
153
154
|
context.activeRequest = request;
|
|
155
|
+
if (skipLease) {
|
|
156
|
+
request.queued = false;
|
|
157
|
+
request.timer = setTimeout(() => this.onRequestTimeout(context, request), request.deadlineMs);
|
|
158
|
+
this.audit({ event: "admission", context, request, outcome: "accepted" });
|
|
159
|
+
return Promise.resolve(request);
|
|
160
|
+
}
|
|
154
161
|
const grant = () => {
|
|
155
162
|
if (context.closed) return Promise.reject(new Error("connection closed while waiting for browser lease"));
|
|
156
163
|
request.queued = false;
|