@browsers-cli/se-cli 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.
Files changed (87) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +379 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +14 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/config.d.ts +17 -0
  7. package/dist/config.js +80 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/daemon/backend.d.ts +9 -0
  10. package/dist/daemon/backend.js +52 -0
  11. package/dist/daemon/backend.js.map +1 -0
  12. package/dist/daemon/server.d.ts +1 -0
  13. package/dist/daemon/server.js +341 -0
  14. package/dist/daemon/server.js.map +1 -0
  15. package/dist/daemon/tools/check.d.ts +7 -0
  16. package/dist/daemon/tools/check.js +20 -0
  17. package/dist/daemon/tools/check.js.map +1 -0
  18. package/dist/daemon/tools/click.d.ts +4 -0
  19. package/dist/daemon/tools/click.js +14 -0
  20. package/dist/daemon/tools/click.js.map +1 -0
  21. package/dist/daemon/tools/eval.d.ts +5 -0
  22. package/dist/daemon/tools/eval.js +18 -0
  23. package/dist/daemon/tools/eval.js.map +1 -0
  24. package/dist/daemon/tools/fill.d.ts +6 -0
  25. package/dist/daemon/tools/fill.js +25 -0
  26. package/dist/daemon/tools/fill.js.map +1 -0
  27. package/dist/daemon/tools/find.d.ts +5 -0
  28. package/dist/daemon/tools/find.js +84 -0
  29. package/dist/daemon/tools/find.js.map +1 -0
  30. package/dist/daemon/tools/goto.d.ts +4 -0
  31. package/dist/daemon/tools/goto.js +25 -0
  32. package/dist/daemon/tools/goto.js.map +1 -0
  33. package/dist/daemon/tools/index.d.ts +1 -0
  34. package/dist/daemon/tools/index.js +37 -0
  35. package/dist/daemon/tools/index.js.map +1 -0
  36. package/dist/daemon/tools/navigation.d.ts +4 -0
  37. package/dist/daemon/tools/navigation.js +21 -0
  38. package/dist/daemon/tools/navigation.js.map +1 -0
  39. package/dist/daemon/tools/press.d.ts +4 -0
  40. package/dist/daemon/tools/press.js +23 -0
  41. package/dist/daemon/tools/press.js.map +1 -0
  42. package/dist/daemon/tools/screenshot.d.ts +5 -0
  43. package/dist/daemon/tools/screenshot.js +57 -0
  44. package/dist/daemon/tools/screenshot.js.map +1 -0
  45. package/dist/daemon/tools/select.d.ts +5 -0
  46. package/dist/daemon/tools/select.js +13 -0
  47. package/dist/daemon/tools/select.js.map +1 -0
  48. package/dist/daemon/tools/shared.d.ts +4 -0
  49. package/dist/daemon/tools/shared.js +35 -0
  50. package/dist/daemon/tools/shared.js.map +1 -0
  51. package/dist/daemon/tools/snapshot.d.ts +6 -0
  52. package/dist/daemon/tools/snapshot.js +90 -0
  53. package/dist/daemon/tools/snapshot.js.map +1 -0
  54. package/dist/daemon/tools/title.d.ts +2 -0
  55. package/dist/daemon/tools/title.js +8 -0
  56. package/dist/daemon/tools/title.js.map +1 -0
  57. package/dist/daemon/tools/type.d.ts +4 -0
  58. package/dist/daemon/tools/type.js +9 -0
  59. package/dist/daemon/tools/type.js.map +1 -0
  60. package/dist/daemon/tools/url.d.ts +2 -0
  61. package/dist/daemon/tools/url.js +8 -0
  62. package/dist/daemon/tools/url.js.map +1 -0
  63. package/dist/minimist.d.ts +10 -0
  64. package/dist/minimist.js +52 -0
  65. package/dist/minimist.js.map +1 -0
  66. package/dist/output.d.ts +6 -0
  67. package/dist/output.js +32 -0
  68. package/dist/output.js.map +1 -0
  69. package/dist/program.d.ts +2 -0
  70. package/dist/program.js +200 -0
  71. package/dist/program.js.map +1 -0
  72. package/dist/protocol.d.ts +29 -0
  73. package/dist/protocol.js +3 -0
  74. package/dist/protocol.js.map +1 -0
  75. package/dist/registry.d.ts +19 -0
  76. package/dist/registry.js +91 -0
  77. package/dist/registry.js.map +1 -0
  78. package/dist/response.d.ts +23 -0
  79. package/dist/response.js +64 -0
  80. package/dist/response.js.map +1 -0
  81. package/dist/session.d.ts +23 -0
  82. package/dist/session.js +264 -0
  83. package/dist/session.js.map +1 -0
  84. package/dist/snapshot/aria-snapshot.d.ts +1 -0
  85. package/dist/snapshot/aria-snapshot.js +200 -0
  86. package/dist/snapshot/aria-snapshot.js.map +1 -0
  87. package/package.json +55 -0
@@ -0,0 +1,6 @@
1
+ import type { ServerMessage } from './protocol';
2
+ export declare class CliError extends Error {
3
+ code?: string | undefined;
4
+ constructor(message: string, code?: string | undefined);
5
+ }
6
+ export declare function render(msg: ServerMessage): void;
package/dist/output.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CliError = void 0;
4
+ exports.render = render;
5
+ class CliError extends Error {
6
+ code;
7
+ constructor(message, code) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = 'CliError';
11
+ }
12
+ }
13
+ exports.CliError = CliError;
14
+ function render(msg) {
15
+ if (!msg.ok) {
16
+ let text = `Error: ${msg.error || 'unknown'}\n`;
17
+ if (msg.code === 'DAEMON_DEAD') {
18
+ text += 'Hint: run `se-cli open` to start a session.\n';
19
+ }
20
+ else if (msg.code === 'ELEMENT_NOT_FOUND') {
21
+ text += 'Hint: run `se-cli snapshot` to refresh refs.\n';
22
+ }
23
+ throw new CliError(text.trim(), msg.code);
24
+ }
25
+ if (msg.text !== undefined)
26
+ process.stdout.write(msg.text + '\n');
27
+ else if (msg.raw !== undefined)
28
+ process.stdout.write(msg.raw);
29
+ else if (msg.json !== undefined)
30
+ process.stdout.write(JSON.stringify(msg.json, null, 2) + '\n');
31
+ }
32
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":";;;AASA,wBAaC;AApBD,MAAa,QAAS,SAAQ,KAAK;IACG;IAApC,YAAY,OAAe,EAAS,IAAa;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QADmB,SAAI,GAAJ,IAAI,CAAS;QAE/C,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AALD,4BAKC;AAED,SAAgB,MAAM,CAAC,GAAkB;IACvC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,IAAI,IAAI,GAAG,UAAU,GAAG,CAAC,KAAK,IAAI,SAAS,IAAI,CAAC;QAChD,IAAI,GAAG,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC/B,IAAI,IAAI,+CAA+C,CAAC;QAC1D,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;YAC5C,IAAI,IAAI,gDAAgD,CAAC;QAC3D,CAAC;QACD,MAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;SAC7D,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SACzD,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAClG,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function main(argv: string[]): Promise<void>;
2
+ export declare function findWorkspaceDir(cwd: string): string;
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.main = main;
37
+ exports.findWorkspaceDir = findWorkspaceDir;
38
+ const minimist_1 = require("./minimist");
39
+ const session_1 = require("./session");
40
+ const registry_1 = require("./registry");
41
+ const config_1 = require("./config");
42
+ const output_1 = require("./output");
43
+ const path = __importStar(require("path"));
44
+ const fs = __importStar(require("fs"));
45
+ async function main(argv) {
46
+ const opts = {
47
+ boolean: ['headed', 'raw', 'json', 'persistent', 'help'],
48
+ string: ['browser', 'filename', 'depth', 's', 'session', 'cdp'],
49
+ alias: { s: 'session' },
50
+ };
51
+ const args = (0, minimist_1.parseArgs)(argv, opts);
52
+ if (args.help || argv.length === 0) {
53
+ printHelp();
54
+ process.exit(0);
55
+ }
56
+ const sessionName = args.session || process.env.SE_CLI_SESSION || 'default';
57
+ const cwd = process.cwd();
58
+ const workspaceDir = findWorkspaceDir(cwd);
59
+ const session = new session_1.Session(workspaceDir, sessionName);
60
+ const cmd = args._[0];
61
+ if (cmd === 'open') {
62
+ const url = args._[1];
63
+ const openOpts = {};
64
+ if (args.browser)
65
+ openOpts.browserName = args.browser;
66
+ if (args.headed)
67
+ openOpts.headed = true;
68
+ if (args.cdp)
69
+ openOpts.cdpEndpoint = args.cdp;
70
+ await session.startDaemon(openOpts);
71
+ if (url) {
72
+ const resp = await session.run(['goto', url], cwd, { raw: args.raw, json: args.json });
73
+ (0, output_1.render)(resp);
74
+ }
75
+ return;
76
+ }
77
+ if (cmd === 'close') {
78
+ await session.stop();
79
+ return;
80
+ }
81
+ if (cmd === 'list') {
82
+ const registry = new registry_1.Registry((0, config_1.baseDaemonDir)());
83
+ const wsHash = (0, config_1.workspaceHash)(workspaceDir);
84
+ const sessions = registry.listSessions(wsHash);
85
+ for (const s of sessions) {
86
+ const alive = await new session_1.Session(workspaceDir, s.name).canConnect();
87
+ const status = alive ? 'live' : 'dead';
88
+ console.log(`${s.name}\t${status}\t${s.browserName}\t${new Date(s.timestamp).toISOString()}`);
89
+ }
90
+ return;
91
+ }
92
+ if (cmd === 'close-all') {
93
+ const registry = new registry_1.Registry((0, config_1.baseDaemonDir)());
94
+ const wsHash = (0, config_1.workspaceHash)(workspaceDir);
95
+ const sessions = registry.listSessions(wsHash);
96
+ for (const s of sessions) {
97
+ const sess = new session_1.Session(workspaceDir, s.name);
98
+ try {
99
+ await sess.stop();
100
+ }
101
+ catch { }
102
+ }
103
+ return;
104
+ }
105
+ if (cmd === 'kill-all') {
106
+ const registry = new registry_1.Registry((0, config_1.baseDaemonDir)());
107
+ const wsHash = (0, config_1.workspaceHash)(workspaceDir);
108
+ const sessions = registry.listSessions(wsHash);
109
+ for (const s of sessions) {
110
+ // Force-kill daemon process if we have a PID
111
+ const cfg = registry.loadSession(wsHash, s.name);
112
+ if (cfg && cfg.pid) {
113
+ try {
114
+ process.kill(cfg.pid, 'SIGKILL');
115
+ }
116
+ catch { }
117
+ }
118
+ // Also try graceful stop in case process is still alive
119
+ const sess = new session_1.Session(workspaceDir, s.name);
120
+ try {
121
+ await sess.stop();
122
+ }
123
+ catch { }
124
+ registry.deleteSession(wsHash, s.name);
125
+ }
126
+ return;
127
+ }
128
+ // Tool commands — forward to daemon.
129
+ // Strip CLI-level flags (--raw, --json, --headed, --browser, --cdp, -s, --session,
130
+ // --persistent, --help) so the daemon only sees the command and its tool-specific
131
+ // flags (e.g. --filename, --depth, --regex, --submit).
132
+ const cliFlags = new Set(['raw', 'json', 'headed', 'persistent', 'help', 'browser', 'cdp', 's', 'session']);
133
+ const forwardArgs = argv.filter(arg => {
134
+ const m = arg.match(/^-{1,2}([\w-]+)(=.*)?$/);
135
+ if (!m)
136
+ return true; // positional arg — keep
137
+ return !cliFlags.has(m[1]);
138
+ });
139
+ let resp;
140
+ try {
141
+ resp = await session.run(forwardArgs, cwd, { raw: args.raw, json: args.json });
142
+ }
143
+ catch (e) {
144
+ // Connection failed: clean up orphan session file and hint to reopen
145
+ const registry = new registry_1.Registry((0, config_1.baseDaemonDir)());
146
+ const wsHash = (0, config_1.workspaceHash)(workspaceDir);
147
+ registry.deleteSession(wsHash, sessionName);
148
+ console.error('### Error\nDaemon not reachable: ' + (e.message || e) + '\nHint: run `se-cli open` to start a new session.');
149
+ process.exit(1);
150
+ }
151
+ (0, output_1.render)(resp);
152
+ }
153
+ function findWorkspaceDir(cwd) {
154
+ let dir = cwd;
155
+ for (let i = 0; i < 10; i++) {
156
+ if (fs.existsSync(path.join(dir, '.se-cli')))
157
+ return dir;
158
+ const parent = path.dirname(dir);
159
+ if (parent === dir)
160
+ break;
161
+ dir = parent;
162
+ }
163
+ return cwd;
164
+ }
165
+ function printHelp() {
166
+ console.log(`se-cli - token-efficient Selenium browser automation
167
+
168
+ Usage:
169
+ se-cli open [url] [--browser=chrome|edge|firefox] [--headed] [--cdp=url]
170
+ se-cli close
171
+ se-cli list
172
+ se-cli close-all
173
+ se-cli kill-all
174
+ se-cli -s=<name> <cmd>
175
+
176
+ Commands:
177
+ goto <url> navigate to url
178
+ go-back / go-forward / reload
179
+ click <ref|selector> click element
180
+ fill <ref|selector> <text>
181
+ type <text> type into focused element
182
+ press <key> press keyboard key
183
+ select <ref> <value> select dropdown option
184
+ check <ref> / uncheck <ref>
185
+ snapshot [ref] [--depth=N]
186
+ find <text> / find --regex <pattern>
187
+ screenshot [ref] [--filename=f]
188
+ eval "<js>" [ref]
189
+ title / url
190
+
191
+ Flags:
192
+ --raw output only the result value
193
+ --json structured JSON output
194
+ -s=<name> session name
195
+ --browser=chrome browser (default chrome)
196
+ --headed show browser window (default headless)
197
+ --cdp=<url> attach to running Chrome via CDP
198
+ `);
199
+ }
200
+ //# sourceMappingURL=program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type Method = 'run' | 'stop' | 'ping';
2
+ export interface ClientMessage {
3
+ method: Method;
4
+ params: {
5
+ args: string[];
6
+ cwd: string;
7
+ raw?: boolean;
8
+ json?: boolean;
9
+ };
10
+ }
11
+ export interface PageMeta {
12
+ url: string;
13
+ title: string;
14
+ }
15
+ export interface SerializedResponse {
16
+ page?: PageMeta;
17
+ snapshot?: string;
18
+ code?: string[];
19
+ result?: string;
20
+ error?: string;
21
+ }
22
+ export interface ServerMessage {
23
+ ok: boolean;
24
+ text?: string;
25
+ raw?: string;
26
+ json?: SerializedResponse;
27
+ error?: string;
28
+ code?: 'ELEMENT_NOT_FOUND' | 'DAEMON_DEAD' | 'VERSION_MISMATCH' | 'DRIVER_ERROR' | 'TIMEOUT';
29
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ export interface SessionConfig {
2
+ name: string;
3
+ version: string;
4
+ timestamp: number;
5
+ socketPath: string;
6
+ workspaceDir: string;
7
+ persistent: boolean;
8
+ browserName: 'chrome' | 'edge' | 'firefox';
9
+ pid?: number;
10
+ }
11
+ export declare class Registry {
12
+ private baseDir;
13
+ constructor(baseDir: string);
14
+ private sessionFile;
15
+ writeSession(wsHash: string, config: SessionConfig): void;
16
+ loadSession(wsHash: string, sessionName: string): SessionConfig | null;
17
+ listSessions(wsHash: string): SessionConfig[];
18
+ deleteSession(wsHash: string, sessionName: string): void;
19
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Registry = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class Registry {
40
+ baseDir;
41
+ constructor(baseDir) {
42
+ this.baseDir = baseDir;
43
+ }
44
+ sessionFile(wsHash, sessionName) {
45
+ return path.join(this.baseDir, wsHash, `${sessionName}.session`);
46
+ }
47
+ writeSession(wsHash, config) {
48
+ const file = this.sessionFile(wsHash, config.name);
49
+ fs.mkdirSync(path.dirname(file), { recursive: true });
50
+ fs.writeFileSync(file, JSON.stringify(config, null, 2));
51
+ }
52
+ loadSession(wsHash, sessionName) {
53
+ const file = this.sessionFile(wsHash, sessionName);
54
+ try {
55
+ const data = JSON.parse(fs.readFileSync(file, 'utf8'));
56
+ return data;
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ listSessions(wsHash) {
63
+ const dir = path.join(this.baseDir, wsHash);
64
+ if (!fs.existsSync(dir))
65
+ return [];
66
+ const sessions = [];
67
+ for (const file of fs.readdirSync(dir)) {
68
+ if (!file.endsWith('.session'))
69
+ continue;
70
+ try {
71
+ const data = JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8'));
72
+ sessions.push(data);
73
+ }
74
+ catch {
75
+ // skip invalid files
76
+ }
77
+ }
78
+ return sessions;
79
+ }
80
+ deleteSession(wsHash, sessionName) {
81
+ const file = this.sessionFile(wsHash, sessionName);
82
+ try {
83
+ fs.unlinkSync(file);
84
+ }
85
+ catch {
86
+ // ignore
87
+ }
88
+ }
89
+ }
90
+ exports.Registry = Registry;
91
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAa7B,MAAa,QAAQ;IACC;IAApB,YAAoB,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;IAAG,CAAC;IAE/B,WAAW,CAAC,MAAc,EAAE,WAAmB;QACrD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,WAAW,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,YAAY,CAAC,MAAc,EAAE,MAAqB;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,WAAW,CAAC,MAAc,EAAE,WAAmB;QAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YACvD,OAAO,IAAqB,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,YAAY,CAAC,MAAc;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAoB,EAAE,CAAC;QACrC,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAAE,SAAS;YACzC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;gBACvE,QAAQ,CAAC,IAAI,CAAC,IAAqB,CAAC,CAAC;YACvC,CAAC;YAAC,MAAM,CAAC;gBACP,qBAAqB;YACvB,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,aAAa,CAAC,MAAc,EAAE,WAAmB;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;CACF;AA/CD,4BA+CC"}
@@ -0,0 +1,23 @@
1
+ import type { PageMeta } from './protocol';
2
+ export interface ResponseOptions {
3
+ raw: boolean;
4
+ json: boolean;
5
+ }
6
+ export declare class Response {
7
+ private opts;
8
+ private page?;
9
+ private snapshot?;
10
+ private code;
11
+ private results;
12
+ private errors;
13
+ constructor(opts: ResponseOptions);
14
+ addPage(meta: PageMeta): void;
15
+ addSnapshot(yaml: string): void;
16
+ addCode(line: string): void;
17
+ addResult(text: string): void;
18
+ addError(text: string): void;
19
+ serialize(): string;
20
+ private serializeText;
21
+ private serializeRaw;
22
+ private serializeJson;
23
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Response = void 0;
4
+ class Response {
5
+ opts;
6
+ page;
7
+ snapshot;
8
+ code = [];
9
+ results = [];
10
+ errors = [];
11
+ constructor(opts) {
12
+ this.opts = opts;
13
+ }
14
+ addPage(meta) { this.page = meta; }
15
+ addSnapshot(yaml) { this.snapshot = yaml; }
16
+ addCode(line) { this.code.push(line); }
17
+ addResult(text) { this.results.push(text); }
18
+ addError(text) { this.errors.push(text); }
19
+ serialize() {
20
+ if (this.opts.json)
21
+ return this.serializeJson();
22
+ if (this.opts.raw)
23
+ return this.serializeRaw();
24
+ return this.serializeText();
25
+ }
26
+ serializeText() {
27
+ const sections = [];
28
+ if (this.errors.length) {
29
+ sections.push('### Error\n' + this.errors.join('\n'));
30
+ }
31
+ if (this.page) {
32
+ sections.push(`### Page\n- Page URL: ${this.page.url}\n- Page Title: ${this.page.title}`);
33
+ }
34
+ if (this.snapshot) {
35
+ sections.push('### Snapshot\n' + this.snapshot);
36
+ }
37
+ if (this.code.length) {
38
+ sections.push('### Ran Selenium code\n```js\n' + this.code.join('\n') + '\n```');
39
+ }
40
+ if (this.results.length) {
41
+ sections.push('### Result\n' + this.results.join('\n'));
42
+ }
43
+ return sections.join('\n\n');
44
+ }
45
+ serializeRaw() {
46
+ return this.results.join('\n');
47
+ }
48
+ serializeJson() {
49
+ const obj = {};
50
+ if (this.page)
51
+ obj.page = this.page;
52
+ if (this.snapshot)
53
+ obj.snapshot = this.snapshot;
54
+ if (this.code.length)
55
+ obj.code = this.code;
56
+ if (this.results.length)
57
+ obj.result = this.results.join('\n');
58
+ if (this.errors.length)
59
+ obj.error = this.errors.join('\n');
60
+ return JSON.stringify(obj, null, 2);
61
+ }
62
+ }
63
+ exports.Response = Response;
64
+ //# sourceMappingURL=response.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response.js","sourceRoot":"","sources":["../src/response.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { SessionConfig } from './registry';
2
+ import type { ServerMessage } from './protocol';
3
+ export declare class Session {
4
+ private workspaceDir;
5
+ private sessionName;
6
+ private socketPath;
7
+ private wsHash;
8
+ private registry;
9
+ constructor(workspaceDir: string, sessionName?: string);
10
+ canConnect(): Promise<boolean>;
11
+ startDaemon(opts?: {
12
+ browserName?: string;
13
+ headed?: boolean;
14
+ cdpEndpoint?: string;
15
+ }): Promise<void>;
16
+ run(args: string[], cwd: string, opts?: {
17
+ raw?: boolean;
18
+ json?: boolean;
19
+ }): Promise<ServerMessage>;
20
+ stop(): Promise<void>;
21
+ private sendAndClose;
22
+ loadConfig(): SessionConfig | null;
23
+ }