@cotestdev/mcp_playwright 0.0.1 → 0.0.3
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/lib/cli.d.ts +8 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +11 -0
- package/lib/cli.js.map +1 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +28 -5
- package/lib/index.js.map +1 -1
- package/lib/mcp/browser/actions.d.js +16 -0
- package/lib/mcp/browser/browserContextFactory.js +285 -0
- package/lib/mcp/browser/browserServerBackend.js +74 -0
- package/lib/mcp/browser/codegen.js +66 -0
- package/lib/mcp/browser/config.js +346 -0
- package/lib/mcp/browser/context.js +260 -0
- package/lib/mcp/browser/processUtils.js +102 -0
- package/lib/mcp/browser/response.js +169 -0
- package/lib/mcp/browser/sessionLog.js +160 -0
- package/lib/mcp/browser/tab.js +301 -0
- package/lib/mcp/browser/tools/common.js +71 -0
- package/lib/mcp/browser/tools/console.js +41 -0
- package/lib/mcp/browser/tools/dialogs.js +61 -0
- package/lib/mcp/browser/tools/evaluate.js +71 -0
- package/lib/mcp/browser/tools/files.js +54 -0
- package/lib/mcp/browser/tools/form.js +75 -0
- package/lib/mcp/browser/tools/install.js +69 -0
- package/lib/mcp/browser/tools/keyboard.js +85 -0
- package/lib/mcp/browser/tools/mouse.js +107 -0
- package/lib/mcp/browser/tools/navigate.js +63 -0
- package/lib/mcp/browser/tools/network.js +49 -0
- package/lib/mcp/browser/tools/pdf.js +59 -0
- package/lib/mcp/browser/tools/screenshot.js +95 -0
- package/lib/mcp/browser/tools/script.js +60 -0
- package/lib/mcp/browser/tools/snapshot.js +183 -0
- package/lib/mcp/browser/tools/tabs.js +71 -0
- package/lib/mcp/browser/tools/tool.js +49 -0
- package/lib/mcp/browser/tools/tracing.js +74 -0
- package/lib/mcp/browser/tools/utils.js +96 -0
- package/lib/mcp/browser/tools/verify.js +155 -0
- package/lib/mcp/browser/tools/wait.js +64 -0
- package/lib/mcp/browser/tools.js +79 -0
- package/lib/mcp/browser/watchdog.js +44 -0
- package/lib/mcp/sdk/bundle.js +75 -0
- package/lib/mcp/sdk/exports.js +32 -0
- package/lib/mcp/sdk/http.js +165 -0
- package/lib/mcp/sdk/inProcessTransport.js +71 -0
- package/lib/mcp/sdk/mdb.js +208 -0
- package/lib/mcp/sdk/proxyBackend.js +128 -0
- package/lib/mcp/sdk/server.js +155 -0
- package/lib/mcp/sdk/tool.js +46 -0
- package/lib/server.d.ts +8 -0
- package/lib/server.d.ts.map +1 -0
- package/lib/server.js +27 -0
- package/lib/server.js.map +1 -0
- package/package.json +10 -4
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var processUtils_exports = {};
|
|
30
|
+
__export(processUtils_exports, {
|
|
31
|
+
findBrowserProcess: () => findBrowserProcess,
|
|
32
|
+
getBrowserExecPath: () => getBrowserExecPath
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(processUtils_exports);
|
|
35
|
+
var import_child_process = __toESM(require("child_process"));
|
|
36
|
+
var import_fs = __toESM(require("fs"));
|
|
37
|
+
var import_registry = require("playwright-core/lib/server/registry/index");
|
|
38
|
+
function getBrowserExecPath(channelOrName) {
|
|
39
|
+
return import_registry.registry.findExecutable(channelOrName)?.executablePath("javascript");
|
|
40
|
+
}
|
|
41
|
+
function findBrowserProcess(execPath, arg) {
|
|
42
|
+
const predicate = (line) => line.includes(execPath) && line.includes(arg) && !line.includes("--type");
|
|
43
|
+
try {
|
|
44
|
+
switch (process.platform) {
|
|
45
|
+
case "darwin":
|
|
46
|
+
return findProcessMacos(predicate);
|
|
47
|
+
case "linux":
|
|
48
|
+
return findProcessLinux(predicate);
|
|
49
|
+
case "win32":
|
|
50
|
+
return findProcessWindows(execPath, arg, predicate);
|
|
51
|
+
default:
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
} catch {
|
|
55
|
+
return void 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function findProcessLinux(predicate) {
|
|
59
|
+
const procDirs = import_fs.default.readdirSync("/proc").filter((name) => /^\d+$/.test(name));
|
|
60
|
+
for (const pid of procDirs) {
|
|
61
|
+
try {
|
|
62
|
+
const cmdlineBuffer = import_fs.default.readFileSync(`/proc/${pid}/cmdline`);
|
|
63
|
+
const cmdline = cmdlineBuffer.toString().replace(/\0/g, " ").trim();
|
|
64
|
+
if (predicate(cmdline))
|
|
65
|
+
return `${pid} ${cmdline}`;
|
|
66
|
+
} catch {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
function findProcessMacos(predicate) {
|
|
73
|
+
const result = import_child_process.default.spawnSync("/bin/ps", ["-axo", "pid=,command="]);
|
|
74
|
+
if (result.status !== 0 || !result.stdout)
|
|
75
|
+
return void 0;
|
|
76
|
+
return findMatchingLine(result.stdout.toString(), predicate);
|
|
77
|
+
}
|
|
78
|
+
function findProcessWindows(execPath, arg, predicate) {
|
|
79
|
+
const psEscape = (path) => `'${path.replaceAll("'", "''")}'`;
|
|
80
|
+
const filter = `$_.ExecutablePath -eq ${psEscape(execPath)} -and $_.CommandLine.Contains(${psEscape(arg)}) -and $_.CommandLine -notmatch '--type'`;
|
|
81
|
+
const ps = import_child_process.default.spawnSync(
|
|
82
|
+
"powershell.exe",
|
|
83
|
+
[
|
|
84
|
+
"-NoProfile",
|
|
85
|
+
"-Command",
|
|
86
|
+
`Get-CimInstance Win32_Process | Where-Object { ${filter} } | Select-Object -Property ProcessId,CommandLine | ForEach-Object { "$($_.ProcessId) $($_.CommandLine)" }`
|
|
87
|
+
],
|
|
88
|
+
{ encoding: "utf8" }
|
|
89
|
+
);
|
|
90
|
+
if (ps.status !== 0 || !ps.stdout)
|
|
91
|
+
return void 0;
|
|
92
|
+
return findMatchingLine(ps.stdout.toString(), predicate);
|
|
93
|
+
}
|
|
94
|
+
function findMatchingLine(psOutput, predicate) {
|
|
95
|
+
const lines = psOutput.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
96
|
+
return lines.find(predicate);
|
|
97
|
+
}
|
|
98
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
99
|
+
0 && (module.exports = {
|
|
100
|
+
findBrowserProcess,
|
|
101
|
+
getBrowserExecPath
|
|
102
|
+
});
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var response_exports = {};
|
|
20
|
+
__export(response_exports, {
|
|
21
|
+
Response: () => Response
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(response_exports);
|
|
24
|
+
var import_tab = require("./tab");
|
|
25
|
+
class Response {
|
|
26
|
+
constructor(context, toolName, toolArgs) {
|
|
27
|
+
this._result = [];
|
|
28
|
+
this._code = [];
|
|
29
|
+
this._images = [];
|
|
30
|
+
this._includeSnapshot = "none";
|
|
31
|
+
this._includeTabs = false;
|
|
32
|
+
this._context = context;
|
|
33
|
+
this.toolName = toolName;
|
|
34
|
+
this.toolArgs = toolArgs;
|
|
35
|
+
}
|
|
36
|
+
addResult(result) {
|
|
37
|
+
this._result.push(result);
|
|
38
|
+
}
|
|
39
|
+
addError(error) {
|
|
40
|
+
this._result.push(error);
|
|
41
|
+
this._isError = true;
|
|
42
|
+
}
|
|
43
|
+
isError() {
|
|
44
|
+
return this._isError;
|
|
45
|
+
}
|
|
46
|
+
result() {
|
|
47
|
+
return this._result.join("\n");
|
|
48
|
+
}
|
|
49
|
+
addCode(code) {
|
|
50
|
+
this._code.push(code);
|
|
51
|
+
}
|
|
52
|
+
code() {
|
|
53
|
+
return this._code.join("\n");
|
|
54
|
+
}
|
|
55
|
+
addImage(image) {
|
|
56
|
+
this._images.push(image);
|
|
57
|
+
}
|
|
58
|
+
images() {
|
|
59
|
+
return this._images;
|
|
60
|
+
}
|
|
61
|
+
setIncludeSnapshot(full) {
|
|
62
|
+
this._includeSnapshot = full ?? "partial";
|
|
63
|
+
}
|
|
64
|
+
setIncludeTabs() {
|
|
65
|
+
this._includeTabs = true;
|
|
66
|
+
}
|
|
67
|
+
async finish() {
|
|
68
|
+
if (this._includeSnapshot !== "none" && this._context.currentTab())
|
|
69
|
+
this._tabSnapshot = await this._context.currentTabOrDie().captureSnapshot();
|
|
70
|
+
for (const tab of this._context.tabs())
|
|
71
|
+
await tab.updateTitle();
|
|
72
|
+
}
|
|
73
|
+
tabSnapshot() {
|
|
74
|
+
return this._tabSnapshot;
|
|
75
|
+
}
|
|
76
|
+
serialize() {
|
|
77
|
+
const response = [];
|
|
78
|
+
if (this._result.length) {
|
|
79
|
+
response.push("### Result");
|
|
80
|
+
response.push(this._result.join("\n"));
|
|
81
|
+
response.push("");
|
|
82
|
+
}
|
|
83
|
+
if (this._code.length) {
|
|
84
|
+
response.push(`### Ran Playwright code
|
|
85
|
+
\`\`\`js
|
|
86
|
+
${this._code.join("\n")}
|
|
87
|
+
\`\`\``);
|
|
88
|
+
response.push("");
|
|
89
|
+
}
|
|
90
|
+
if (this._includeSnapshot !== "none" || this._includeTabs)
|
|
91
|
+
response.push(...renderTabsMarkdown(this._context.tabs(), this._includeTabs));
|
|
92
|
+
if (this._tabSnapshot?.modalStates.length) {
|
|
93
|
+
response.push(...(0, import_tab.renderModalStates)(this._context, this._tabSnapshot.modalStates));
|
|
94
|
+
response.push("");
|
|
95
|
+
} else if (this._tabSnapshot) {
|
|
96
|
+
response.push(renderTabSnapshot(this._tabSnapshot, this._includeSnapshot === "full"));
|
|
97
|
+
response.push("");
|
|
98
|
+
}
|
|
99
|
+
const content = [
|
|
100
|
+
{ type: "text", text: response.join("\n") }
|
|
101
|
+
];
|
|
102
|
+
this._redactSecrets(content);
|
|
103
|
+
return { content, isError: this._isError };
|
|
104
|
+
}
|
|
105
|
+
_redactSecrets(content) {
|
|
106
|
+
if (!this._context.config.secrets)
|
|
107
|
+
return;
|
|
108
|
+
for (const item of content) {
|
|
109
|
+
if (item.type !== "text")
|
|
110
|
+
continue;
|
|
111
|
+
for (const [secretName, secretValue] of Object.entries(this._context.config.secrets))
|
|
112
|
+
item.text = item.text.replaceAll(secretValue, `<secret>${secretName}</secret>`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function renderTabSnapshot(tabSnapshot, fullSnapshot) {
|
|
117
|
+
const lines = [];
|
|
118
|
+
if (tabSnapshot.downloads.length) {
|
|
119
|
+
lines.push(`### Downloads`);
|
|
120
|
+
for (const entry of tabSnapshot.downloads) {
|
|
121
|
+
if (entry.finished)
|
|
122
|
+
lines.push(`- Downloaded file ${entry.download.suggestedFilename()} to ${entry.outputFile}`);
|
|
123
|
+
else
|
|
124
|
+
lines.push(`- Downloading file ${entry.download.suggestedFilename()} ...`);
|
|
125
|
+
}
|
|
126
|
+
lines.push("");
|
|
127
|
+
}
|
|
128
|
+
lines.push(`### Page state`);
|
|
129
|
+
lines.push(`- Page URL: ${tabSnapshot.url}`);
|
|
130
|
+
lines.push(`- Page Title: ${tabSnapshot.title}`);
|
|
131
|
+
if (!fullSnapshot && tabSnapshot.formattedAriaSnapshotDiff) {
|
|
132
|
+
lines.push(`- Page Snapshot Diff:`);
|
|
133
|
+
lines.push(tabSnapshot.formattedAriaSnapshotDiff);
|
|
134
|
+
} else {
|
|
135
|
+
lines.push(`- Page Snapshot:`);
|
|
136
|
+
lines.push("```yaml");
|
|
137
|
+
lines.push(tabSnapshot.ariaSnapshot);
|
|
138
|
+
lines.push("```");
|
|
139
|
+
}
|
|
140
|
+
return lines.join("\n");
|
|
141
|
+
}
|
|
142
|
+
function renderTabsMarkdown(tabs, force = false) {
|
|
143
|
+
if (tabs.length === 1 && !force)
|
|
144
|
+
return [];
|
|
145
|
+
if (!tabs.length) {
|
|
146
|
+
return [
|
|
147
|
+
"### Open tabs",
|
|
148
|
+
'No open tabs. Use the "browser_navigate" tool to navigate to a page first.',
|
|
149
|
+
""
|
|
150
|
+
];
|
|
151
|
+
}
|
|
152
|
+
const lines = ["### Open tabs"];
|
|
153
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
154
|
+
const tab = tabs[i];
|
|
155
|
+
const current = tab.isCurrentTab() ? " (current)" : "";
|
|
156
|
+
lines.push(`- ${i}:${current} [${tab.lastTitle()}] (${tab.page.url()})`);
|
|
157
|
+
}
|
|
158
|
+
lines.push("");
|
|
159
|
+
return lines;
|
|
160
|
+
}
|
|
161
|
+
function trim(text, maxLength) {
|
|
162
|
+
if (text.length <= maxLength)
|
|
163
|
+
return text;
|
|
164
|
+
return text.slice(0, maxLength) + "...";
|
|
165
|
+
}
|
|
166
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
167
|
+
0 && (module.exports = {
|
|
168
|
+
Response
|
|
169
|
+
});
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var sessionLog_exports = {};
|
|
30
|
+
__export(sessionLog_exports, {
|
|
31
|
+
SessionLog: () => SessionLog
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(sessionLog_exports);
|
|
34
|
+
var import_fs = __toESM(require("fs"));
|
|
35
|
+
var import_path = __toESM(require("path"));
|
|
36
|
+
var import_log = require("../log");
|
|
37
|
+
var import_config = require("./config");
|
|
38
|
+
class SessionLog {
|
|
39
|
+
constructor(sessionFolder) {
|
|
40
|
+
this._ordinal = 0;
|
|
41
|
+
this._pendingEntries = [];
|
|
42
|
+
this._sessionFileQueue = Promise.resolve();
|
|
43
|
+
this._folder = sessionFolder;
|
|
44
|
+
this._file = import_path.default.join(this._folder, "session.md");
|
|
45
|
+
}
|
|
46
|
+
static async create(config, clientInfo) {
|
|
47
|
+
const sessionFolder = await (0, import_config.outputFile)(config, clientInfo, `session-${Date.now()}`, { origin: "code" });
|
|
48
|
+
await import_fs.default.promises.mkdir(sessionFolder, { recursive: true });
|
|
49
|
+
console.error(`Session: ${sessionFolder}`);
|
|
50
|
+
return new SessionLog(sessionFolder);
|
|
51
|
+
}
|
|
52
|
+
logResponse(response) {
|
|
53
|
+
const entry = {
|
|
54
|
+
timestamp: performance.now(),
|
|
55
|
+
toolCall: {
|
|
56
|
+
toolName: response.toolName,
|
|
57
|
+
toolArgs: response.toolArgs,
|
|
58
|
+
result: response.result(),
|
|
59
|
+
isError: response.isError()
|
|
60
|
+
},
|
|
61
|
+
code: response.code(),
|
|
62
|
+
tabSnapshot: response.tabSnapshot()
|
|
63
|
+
};
|
|
64
|
+
this._appendEntry(entry);
|
|
65
|
+
}
|
|
66
|
+
logUserAction(action, tab, code, isUpdate) {
|
|
67
|
+
code = code.trim();
|
|
68
|
+
if (isUpdate) {
|
|
69
|
+
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
|
70
|
+
if (lastEntry?.userAction?.name === action.name) {
|
|
71
|
+
lastEntry.userAction = action;
|
|
72
|
+
lastEntry.code = code;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (action.name === "navigate") {
|
|
77
|
+
const lastEntry = this._pendingEntries[this._pendingEntries.length - 1];
|
|
78
|
+
if (lastEntry?.tabSnapshot?.url === action.url)
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const entry = {
|
|
82
|
+
timestamp: performance.now(),
|
|
83
|
+
userAction: action,
|
|
84
|
+
code,
|
|
85
|
+
tabSnapshot: {
|
|
86
|
+
url: tab.page.url(),
|
|
87
|
+
title: "",
|
|
88
|
+
ariaSnapshot: action.ariaSnapshot || "",
|
|
89
|
+
modalStates: [],
|
|
90
|
+
consoleMessages: [],
|
|
91
|
+
downloads: []
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this._appendEntry(entry);
|
|
95
|
+
}
|
|
96
|
+
_appendEntry(entry) {
|
|
97
|
+
this._pendingEntries.push(entry);
|
|
98
|
+
if (this._flushEntriesTimeout)
|
|
99
|
+
clearTimeout(this._flushEntriesTimeout);
|
|
100
|
+
this._flushEntriesTimeout = setTimeout(() => this._flushEntries(), 1e3);
|
|
101
|
+
}
|
|
102
|
+
async _flushEntries() {
|
|
103
|
+
clearTimeout(this._flushEntriesTimeout);
|
|
104
|
+
const entries = this._pendingEntries;
|
|
105
|
+
this._pendingEntries = [];
|
|
106
|
+
const lines = [""];
|
|
107
|
+
for (const entry of entries) {
|
|
108
|
+
const ordinal = (++this._ordinal).toString().padStart(3, "0");
|
|
109
|
+
if (entry.toolCall) {
|
|
110
|
+
lines.push(
|
|
111
|
+
`### Tool call: ${entry.toolCall.toolName}`,
|
|
112
|
+
`- Args`,
|
|
113
|
+
"```json",
|
|
114
|
+
JSON.stringify(entry.toolCall.toolArgs, null, 2),
|
|
115
|
+
"```"
|
|
116
|
+
);
|
|
117
|
+
if (entry.toolCall.result) {
|
|
118
|
+
lines.push(
|
|
119
|
+
entry.toolCall.isError ? `- Error` : `- Result`,
|
|
120
|
+
"```",
|
|
121
|
+
entry.toolCall.result,
|
|
122
|
+
"```"
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (entry.userAction) {
|
|
127
|
+
const actionData = { ...entry.userAction };
|
|
128
|
+
delete actionData.ariaSnapshot;
|
|
129
|
+
delete actionData.selector;
|
|
130
|
+
delete actionData.signals;
|
|
131
|
+
lines.push(
|
|
132
|
+
`### User action: ${entry.userAction.name}`,
|
|
133
|
+
`- Args`,
|
|
134
|
+
"```json",
|
|
135
|
+
JSON.stringify(actionData, null, 2),
|
|
136
|
+
"```"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
if (entry.code) {
|
|
140
|
+
lines.push(
|
|
141
|
+
`- Code`,
|
|
142
|
+
"```js",
|
|
143
|
+
entry.code,
|
|
144
|
+
"```"
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (entry.tabSnapshot) {
|
|
148
|
+
const fileName = `${ordinal}.snapshot.yml`;
|
|
149
|
+
import_fs.default.promises.writeFile(import_path.default.join(this._folder, fileName), entry.tabSnapshot.ariaSnapshot).catch(import_log.logUnhandledError);
|
|
150
|
+
lines.push(`- Snapshot: ${fileName}`);
|
|
151
|
+
}
|
|
152
|
+
lines.push("", "");
|
|
153
|
+
}
|
|
154
|
+
this._sessionFileQueue = this._sessionFileQueue.then(() => import_fs.default.promises.appendFile(this._file, lines.join("\n")));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
158
|
+
0 && (module.exports = {
|
|
159
|
+
SessionLog
|
|
160
|
+
});
|