@moejay/wrightty 0.1.0 → 0.2.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/dist/cli.d.ts +3 -0
- package/dist/cli.js +150 -0
- package/dist/terminal.d.ts +2 -0
- package/dist/terminal.js +22 -0
- package/dist/types.d.ts +8 -0
- package/package.json +4 -1
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/** wrightty CLI for Node.js — control terminals from the command line. */
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
const terminal_1 = require("./terminal");
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const command = args[0];
|
|
8
|
+
function usage() {
|
|
9
|
+
console.log(`wrightty-js — Playwright for terminals (Node.js)
|
|
10
|
+
|
|
11
|
+
Note: This is a client CLI. To start a server: cargo install wrightty
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
wrightty-js run <command> [--timeout <s>] Run a command and print output
|
|
15
|
+
wrightty-js read Read the terminal screen
|
|
16
|
+
wrightty-js send-text <text> Send raw text
|
|
17
|
+
wrightty-js send-keys <key> [<key>...] Send keystrokes
|
|
18
|
+
wrightty-js screenshot [--format svg|text] Take a screenshot
|
|
19
|
+
wrightty-js wait-for <pattern> [--timeout] Wait for text on screen
|
|
20
|
+
wrightty-js info Show server info
|
|
21
|
+
wrightty-js size Get terminal dimensions
|
|
22
|
+
wrightty-js discover Find running servers
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
--url <url> Server URL (default: auto-discover)
|
|
26
|
+
--session <id> Session ID (default: first available)
|
|
27
|
+
--password <pass> Password for server authentication
|
|
28
|
+
--help Show this help`);
|
|
29
|
+
}
|
|
30
|
+
function getOpt(name) {
|
|
31
|
+
const idx = args.indexOf(name);
|
|
32
|
+
return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : undefined;
|
|
33
|
+
}
|
|
34
|
+
function hasFlag(name) {
|
|
35
|
+
return args.includes(name);
|
|
36
|
+
}
|
|
37
|
+
async function getTerminal() {
|
|
38
|
+
const url = getOpt("--url");
|
|
39
|
+
const sessionId = getOpt("--session");
|
|
40
|
+
const password = getOpt("--password");
|
|
41
|
+
return terminal_1.Terminal.connect({ url, sessionId, password });
|
|
42
|
+
}
|
|
43
|
+
async function main() {
|
|
44
|
+
if (!command || hasFlag("--help") || hasFlag("-h")) {
|
|
45
|
+
usage();
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
switch (command) {
|
|
50
|
+
case "discover": {
|
|
51
|
+
const servers = await terminal_1.Terminal.discover();
|
|
52
|
+
if (servers.length === 0) {
|
|
53
|
+
console.log("No wrightty servers found.");
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
for (const s of servers) {
|
|
57
|
+
const name = s.name ? ` [${s.name}]` : "";
|
|
58
|
+
const auth = s.authentication ? ` (auth: ${s.authentication})` : "";
|
|
59
|
+
console.log(` ${s.url} ${s.implementation} v${s.version}${name}${auth}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case "run": {
|
|
65
|
+
const cmd = args[1];
|
|
66
|
+
if (!cmd) {
|
|
67
|
+
console.error("Usage: wrightty-js run <command>");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const timeout = parseInt(getOpt("--timeout") ?? "30", 10) * 1000;
|
|
71
|
+
const term = await getTerminal();
|
|
72
|
+
const output = await term.run(cmd, timeout);
|
|
73
|
+
console.log(output);
|
|
74
|
+
term.close();
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "read": {
|
|
78
|
+
const term = await getTerminal();
|
|
79
|
+
console.log(await term.readScreen());
|
|
80
|
+
term.close();
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
case "send-text": {
|
|
84
|
+
const text = args[1];
|
|
85
|
+
if (!text) {
|
|
86
|
+
console.error("Usage: wrightty-js send-text <text>");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const term = await getTerminal();
|
|
90
|
+
await term.sendText(text.replace(/\\n/g, "\n"));
|
|
91
|
+
term.close();
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "send-keys": {
|
|
95
|
+
const keys = args.slice(1).filter(k => !k.startsWith("--"));
|
|
96
|
+
if (keys.length === 0) {
|
|
97
|
+
console.error("Usage: wrightty-js send-keys <key> [...]");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const term = await getTerminal();
|
|
101
|
+
await term.sendKeys(...keys);
|
|
102
|
+
term.close();
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case "screenshot": {
|
|
106
|
+
const format = (getOpt("--format") ?? "text");
|
|
107
|
+
const term = await getTerminal();
|
|
108
|
+
const result = await term.screenshot(format);
|
|
109
|
+
console.log(result.data);
|
|
110
|
+
term.close();
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case "wait-for": {
|
|
114
|
+
const pattern = args[1];
|
|
115
|
+
if (!pattern) {
|
|
116
|
+
console.error("Usage: wrightty-js wait-for <pattern>");
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
const timeout = parseInt(getOpt("--timeout") ?? "30", 10) * 1000;
|
|
120
|
+
const term = await getTerminal();
|
|
121
|
+
const screen = await term.waitFor(pattern, timeout);
|
|
122
|
+
console.log(screen);
|
|
123
|
+
term.close();
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case "info": {
|
|
127
|
+
const term = await getTerminal();
|
|
128
|
+
console.log(JSON.stringify(await term.getInfo(), null, 2));
|
|
129
|
+
term.close();
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
case "size": {
|
|
133
|
+
const term = await getTerminal();
|
|
134
|
+
const [cols, rows] = await term.getSize();
|
|
135
|
+
console.log(`${cols}x${rows}`);
|
|
136
|
+
term.close();
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
default:
|
|
140
|
+
console.error(`Unknown command: ${command}`);
|
|
141
|
+
usage();
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
console.error(`Error: ${err.message}`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
main();
|
package/dist/terminal.d.ts
CHANGED
|
@@ -35,6 +35,8 @@ export declare class Terminal {
|
|
|
35
35
|
resize(cols: number, rows: number): Promise<void>;
|
|
36
36
|
/** Get server info and capabilities. */
|
|
37
37
|
getInfo(): Promise<Record<string, any>>;
|
|
38
|
+
/** Authenticate with the server using a password. */
|
|
39
|
+
authenticate(password: string): Promise<void>;
|
|
38
40
|
/** Start recording raw PTY I/O (asciicast v2 format). */
|
|
39
41
|
startSessionRecording(includeInput?: boolean): Promise<string>;
|
|
40
42
|
/** Stop a session recording and return asciicast data. */
|
package/dist/terminal.js
CHANGED
|
@@ -29,6 +29,8 @@ class Terminal {
|
|
|
29
29
|
version: info.version ?? "unknown",
|
|
30
30
|
implementation: info.implementation ?? "unknown",
|
|
31
31
|
capabilities: info.capabilities ?? {},
|
|
32
|
+
name: info.name,
|
|
33
|
+
authentication: info.authentication,
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
finally {
|
|
@@ -56,6 +58,14 @@ class Terminal {
|
|
|
56
58
|
url = servers[0].url;
|
|
57
59
|
}
|
|
58
60
|
const client = await client_1.WrighttyClient.connect(url, options.timeout ?? 5000);
|
|
61
|
+
const info = await client.request("Wrightty.getInfo");
|
|
62
|
+
if (info.authentication === "password") {
|
|
63
|
+
if (!options.password) {
|
|
64
|
+
client.close();
|
|
65
|
+
throw new Error("Server requires password authentication but no password was provided");
|
|
66
|
+
}
|
|
67
|
+
await client.request("Wrightty.authenticate", { password: options.password });
|
|
68
|
+
}
|
|
59
69
|
let sessionId = options.sessionId;
|
|
60
70
|
if (!sessionId) {
|
|
61
71
|
const result = await client.request("Session.list");
|
|
@@ -68,6 +78,14 @@ class Terminal {
|
|
|
68
78
|
static async spawn(options = {}) {
|
|
69
79
|
const url = options.serverUrl ?? "ws://127.0.0.1:9420";
|
|
70
80
|
const client = await client_1.WrighttyClient.connect(url);
|
|
81
|
+
const info = await client.request("Wrightty.getInfo");
|
|
82
|
+
if (info.authentication === "password") {
|
|
83
|
+
if (!options.password) {
|
|
84
|
+
client.close();
|
|
85
|
+
throw new Error("Server requires password authentication but no password was provided");
|
|
86
|
+
}
|
|
87
|
+
await client.request("Wrightty.authenticate", { password: options.password });
|
|
88
|
+
}
|
|
71
89
|
const result = await client.request("Session.create", {
|
|
72
90
|
cols: options.cols ?? 120,
|
|
73
91
|
rows: options.rows ?? 40,
|
|
@@ -174,6 +192,10 @@ class Terminal {
|
|
|
174
192
|
async getInfo() {
|
|
175
193
|
return this.client.request("Wrightty.getInfo");
|
|
176
194
|
}
|
|
195
|
+
/** Authenticate with the server using a password. */
|
|
196
|
+
async authenticate(password) {
|
|
197
|
+
await this.client.request("Wrightty.authenticate", { password });
|
|
198
|
+
}
|
|
177
199
|
// --- Recording ---
|
|
178
200
|
/** Start recording raw PTY I/O (asciicast v2 format). */
|
|
179
201
|
async startSessionRecording(includeInput = false) {
|
package/dist/types.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export interface ServerInfo {
|
|
|
3
3
|
version: string;
|
|
4
4
|
implementation: string;
|
|
5
5
|
capabilities: Capabilities;
|
|
6
|
+
name?: string;
|
|
7
|
+
authentication: "none" | "password";
|
|
6
8
|
}
|
|
7
9
|
export interface Capabilities {
|
|
8
10
|
screenshot: ScreenshotFormat[];
|
|
@@ -72,6 +74,8 @@ export interface DiscoveredServer {
|
|
|
72
74
|
version: string;
|
|
73
75
|
implementation: string;
|
|
74
76
|
capabilities: Capabilities;
|
|
77
|
+
name?: string;
|
|
78
|
+
authentication?: string;
|
|
75
79
|
}
|
|
76
80
|
export interface ConnectOptions {
|
|
77
81
|
/** Server URL (default: auto-discover) */
|
|
@@ -80,6 +84,8 @@ export interface ConnectOptions {
|
|
|
80
84
|
sessionId?: string;
|
|
81
85
|
/** Connection timeout in ms (default: 5000) */
|
|
82
86
|
timeout?: number;
|
|
87
|
+
/** Password for server authentication */
|
|
88
|
+
password?: string;
|
|
83
89
|
}
|
|
84
90
|
export interface SpawnOptions {
|
|
85
91
|
shell?: string;
|
|
@@ -87,4 +93,6 @@ export interface SpawnOptions {
|
|
|
87
93
|
rows?: number;
|
|
88
94
|
cwd?: string;
|
|
89
95
|
serverUrl?: string;
|
|
96
|
+
/** Password for server authentication */
|
|
97
|
+
password?: string;
|
|
90
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moejay/wrightty",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Node.js SDK for Wrightty terminal automation protocol",
|
|
5
5
|
"author": "Moe Jay",
|
|
6
6
|
"homepage": "https://github.com/moejay/wrightty",
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
},
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"types": "dist/index.d.ts",
|
|
17
|
+
"bin": {
|
|
18
|
+
"wrightty-js": "dist/cli.js"
|
|
19
|
+
},
|
|
17
20
|
"files": [
|
|
18
21
|
"dist"
|
|
19
22
|
],
|