repterm 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.
- package/dist/api/describe.d.ts +18 -0
- package/dist/api/describe.d.ts.map +1 -0
- package/dist/api/describe.js +33 -0
- package/dist/api/describe.js.map +1 -0
- package/dist/api/expect.d.ts +43 -0
- package/dist/api/expect.d.ts.map +1 -0
- package/dist/api/expect.js +167 -0
- package/dist/api/expect.js.map +1 -0
- package/dist/api/hooks.d.ts +178 -0
- package/dist/api/hooks.d.ts.map +1 -0
- package/dist/api/hooks.js +231 -0
- package/dist/api/hooks.js.map +1 -0
- package/dist/api/steps.d.ts +45 -0
- package/dist/api/steps.d.ts.map +1 -0
- package/dist/api/steps.js +106 -0
- package/dist/api/steps.js.map +1 -0
- package/dist/api/test.d.ts +101 -0
- package/dist/api/test.d.ts.map +1 -0
- package/dist/api/test.js +207 -0
- package/dist/api/test.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +203 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/reporter.d.ts +108 -0
- package/dist/cli/reporter.d.ts.map +1 -0
- package/dist/cli/reporter.js +368 -0
- package/dist/cli/reporter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/index.d.ts +47 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +86 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/withPlugins.d.ts +71 -0
- package/dist/plugin/withPlugins.d.ts.map +1 -0
- package/dist/plugin/withPlugins.js +101 -0
- package/dist/plugin/withPlugins.js.map +1 -0
- package/dist/recording/recorder.d.ts +45 -0
- package/dist/recording/recorder.d.ts.map +1 -0
- package/dist/recording/recorder.js +97 -0
- package/dist/recording/recorder.js.map +1 -0
- package/dist/runner/artifacts.d.ts +39 -0
- package/dist/runner/artifacts.d.ts.map +1 -0
- package/dist/runner/artifacts.js +59 -0
- package/dist/runner/artifacts.js.map +1 -0
- package/dist/runner/config.d.ts +46 -0
- package/dist/runner/config.d.ts.map +1 -0
- package/dist/runner/config.js +65 -0
- package/dist/runner/config.js.map +1 -0
- package/dist/runner/filter.d.ts +26 -0
- package/dist/runner/filter.d.ts.map +1 -0
- package/dist/runner/filter.js +88 -0
- package/dist/runner/filter.js.map +1 -0
- package/dist/runner/loader.d.ts +32 -0
- package/dist/runner/loader.d.ts.map +1 -0
- package/dist/runner/loader.js +252 -0
- package/dist/runner/loader.js.map +1 -0
- package/dist/runner/models.d.ts +261 -0
- package/dist/runner/models.d.ts.map +1 -0
- package/dist/runner/models.js +5 -0
- package/dist/runner/models.js.map +1 -0
- package/dist/runner/runner.d.ts +36 -0
- package/dist/runner/runner.d.ts.map +1 -0
- package/dist/runner/runner.js +216 -0
- package/dist/runner/runner.js.map +1 -0
- package/dist/runner/scheduler.d.ts +59 -0
- package/dist/runner/scheduler.d.ts.map +1 -0
- package/dist/runner/scheduler.js +157 -0
- package/dist/runner/scheduler.js.map +1 -0
- package/dist/runner/worker-runner.d.ts +6 -0
- package/dist/runner/worker-runner.d.ts.map +1 -0
- package/dist/runner/worker-runner.js +51 -0
- package/dist/runner/worker-runner.js.map +1 -0
- package/dist/runner/worker.d.ts +54 -0
- package/dist/runner/worker.d.ts.map +1 -0
- package/dist/runner/worker.js +112 -0
- package/dist/runner/worker.js.map +1 -0
- package/dist/terminal/session.d.ts +56 -0
- package/dist/terminal/session.d.ts.map +1 -0
- package/dist/terminal/session.js +126 -0
- package/dist/terminal/session.js.map +1 -0
- package/dist/terminal/terminal.d.ts +284 -0
- package/dist/terminal/terminal.d.ts.map +1 -0
- package/dist/terminal/terminal.js +1167 -0
- package/dist/terminal/terminal.js.map +1 -0
- package/dist/utils/dependencies.d.ts +19 -0
- package/dist/utils/dependencies.d.ts.map +1 -0
- package/dist/utils/dependencies.js +58 -0
- package/dist/utils/dependencies.js.map +1 -0
- package/dist/utils/timing.d.ts +55 -0
- package/dist/utils/timing.d.ts.map +1 -0
- package/dist/utils/timing.js +87 -0
- package/dist/utils/timing.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker process runner for parallel test execution
|
|
3
|
+
* Runs tests in isolated worker processes
|
|
4
|
+
*/
|
|
5
|
+
import { fork } from 'child_process';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
/**
|
|
8
|
+
* Worker process manager
|
|
9
|
+
*/
|
|
10
|
+
export class Worker extends EventEmitter {
|
|
11
|
+
process = null;
|
|
12
|
+
config;
|
|
13
|
+
busy = false;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
super();
|
|
16
|
+
this.config = config;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Start the worker process
|
|
20
|
+
*/
|
|
21
|
+
start() {
|
|
22
|
+
if (this.process) {
|
|
23
|
+
throw new Error('Worker already started');
|
|
24
|
+
}
|
|
25
|
+
// Fork a new process running the worker script
|
|
26
|
+
this.process = fork(new URL('./worker-runner.js', import.meta.url).pathname, [], {
|
|
27
|
+
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
|
|
28
|
+
});
|
|
29
|
+
// Handle messages from worker
|
|
30
|
+
this.process.on('message', (message) => {
|
|
31
|
+
this.handleMessage(message);
|
|
32
|
+
});
|
|
33
|
+
// Handle worker exit
|
|
34
|
+
this.process.on('exit', (code) => {
|
|
35
|
+
this.emit('exit', code);
|
|
36
|
+
});
|
|
37
|
+
// Handle worker errors
|
|
38
|
+
this.process.on('error', (error) => {
|
|
39
|
+
this.emit('error', error);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Run a test suite in the worker
|
|
44
|
+
*/
|
|
45
|
+
runSuite(suite) {
|
|
46
|
+
if (!this.process) {
|
|
47
|
+
throw new Error('Worker not started');
|
|
48
|
+
}
|
|
49
|
+
if (this.busy) {
|
|
50
|
+
throw new Error('Worker is busy');
|
|
51
|
+
}
|
|
52
|
+
this.busy = true;
|
|
53
|
+
// Send suite to worker
|
|
54
|
+
this.process.send({
|
|
55
|
+
type: 'run',
|
|
56
|
+
data: {
|
|
57
|
+
suite,
|
|
58
|
+
config: this.config.config,
|
|
59
|
+
artifactBaseDir: this.config.artifactBaseDir,
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Stop the worker
|
|
65
|
+
*/
|
|
66
|
+
stop() {
|
|
67
|
+
if (this.process) {
|
|
68
|
+
this.process.kill();
|
|
69
|
+
this.process = null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if worker is busy
|
|
74
|
+
*/
|
|
75
|
+
isBusy() {
|
|
76
|
+
return this.busy;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get worker ID
|
|
80
|
+
*/
|
|
81
|
+
getWorkerId() {
|
|
82
|
+
return this.config.workerId;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Handle message from worker
|
|
86
|
+
*/
|
|
87
|
+
handleMessage(message) {
|
|
88
|
+
switch (message.type) {
|
|
89
|
+
case 'ready':
|
|
90
|
+
this.emit('ready');
|
|
91
|
+
break;
|
|
92
|
+
case 'result':
|
|
93
|
+
this.emit('result', message.data);
|
|
94
|
+
break;
|
|
95
|
+
case 'done':
|
|
96
|
+
this.busy = false;
|
|
97
|
+
this.emit('done', message.data);
|
|
98
|
+
break;
|
|
99
|
+
case 'error':
|
|
100
|
+
this.busy = false;
|
|
101
|
+
this.emit('error', message.data);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create a worker
|
|
108
|
+
*/
|
|
109
|
+
export function createWorker(config) {
|
|
110
|
+
return new Worker(config);
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../../src/runner/worker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal session abstraction around bun-pty
|
|
3
|
+
* Provides core PTY operations for terminal interaction
|
|
4
|
+
*/
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
export interface SessionConfig {
|
|
7
|
+
cols?: number;
|
|
8
|
+
rows?: number;
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
export interface SessionOptions extends SessionConfig {
|
|
12
|
+
shell?: string;
|
|
13
|
+
args?: string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Terminal session wrapper around bun-pty
|
|
17
|
+
*/
|
|
18
|
+
export declare class TerminalSession extends EventEmitter {
|
|
19
|
+
private pty;
|
|
20
|
+
private outputBuffer;
|
|
21
|
+
private config;
|
|
22
|
+
constructor(config?: SessionConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Start the terminal session
|
|
25
|
+
*/
|
|
26
|
+
start(options?: SessionOptions): void;
|
|
27
|
+
/**
|
|
28
|
+
* Write data to the terminal
|
|
29
|
+
*/
|
|
30
|
+
write(data: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get the current output buffer
|
|
33
|
+
*/
|
|
34
|
+
getOutput(): string;
|
|
35
|
+
/**
|
|
36
|
+
* Clear the output buffer
|
|
37
|
+
*/
|
|
38
|
+
clearOutput(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Resize the terminal
|
|
41
|
+
*/
|
|
42
|
+
resize(cols: number, rows: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Kill the terminal process
|
|
45
|
+
*/
|
|
46
|
+
kill(signal?: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Check if the session is active
|
|
49
|
+
*/
|
|
50
|
+
isActive(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Get the process ID
|
|
53
|
+
*/
|
|
54
|
+
getPid(): number | undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/terminal/session.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAKD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,MAAM,CAAgB;gBAElB,MAAM,GAAE,aAAkB;IAsBtC;;OAEG;IACH,KAAK,CAAC,OAAO,GAAE,cAAmB,GAAG,IAAI;IA0CzC;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAOzB;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAOxC;;OAEG;IACH,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAO3B;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,MAAM,IAAI,MAAM,GAAG,SAAS;CAG7B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal session abstraction around bun-pty
|
|
3
|
+
* Provides core PTY operations for terminal interaction
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from 'bun-pty';
|
|
6
|
+
import { EventEmitter } from 'events';
|
|
7
|
+
const DEFAULT_COLS = 80;
|
|
8
|
+
const DEFAULT_ROWS = 24;
|
|
9
|
+
/**
|
|
10
|
+
* Terminal session wrapper around bun-pty
|
|
11
|
+
*/
|
|
12
|
+
export class TerminalSession extends EventEmitter {
|
|
13
|
+
pty = null;
|
|
14
|
+
outputBuffer = '';
|
|
15
|
+
config;
|
|
16
|
+
constructor(config = {}) {
|
|
17
|
+
super();
|
|
18
|
+
// Convert process.env to Record<string, string> by filtering undefined values
|
|
19
|
+
let env = {};
|
|
20
|
+
if (config.env) {
|
|
21
|
+
env = config.env;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
for (const [key, value] of Object.entries(process.env)) {
|
|
25
|
+
if (value !== undefined) {
|
|
26
|
+
env[key] = value;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
this.config = {
|
|
31
|
+
cols: config.cols ?? DEFAULT_COLS,
|
|
32
|
+
rows: config.rows ?? DEFAULT_ROWS,
|
|
33
|
+
env,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Start the terminal session
|
|
38
|
+
*/
|
|
39
|
+
start(options = {}) {
|
|
40
|
+
if (this.pty) {
|
|
41
|
+
throw new Error('Terminal session already started');
|
|
42
|
+
}
|
|
43
|
+
const shell = options.shell ?? process.env.SHELL ?? '/bin/bash';
|
|
44
|
+
const args = options.args ?? [];
|
|
45
|
+
// Merge environment variables, filtering out undefined values
|
|
46
|
+
const mergedEnv = { ...this.config.env, ...options.env };
|
|
47
|
+
const env = {};
|
|
48
|
+
for (const [key, value] of Object.entries(mergedEnv)) {
|
|
49
|
+
if (value !== undefined) {
|
|
50
|
+
env[key] = value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Ensure TERM is set to xterm-256color for proper color support
|
|
54
|
+
if (!env.TERM) {
|
|
55
|
+
env.TERM = 'xterm-256color';
|
|
56
|
+
}
|
|
57
|
+
this.pty = spawn(shell, args, {
|
|
58
|
+
name: 'xterm-256color', // Support 256 colors (like simple-example.js)
|
|
59
|
+
cols: options.cols ?? this.config.cols ?? DEFAULT_COLS,
|
|
60
|
+
rows: options.rows ?? this.config.rows ?? DEFAULT_ROWS,
|
|
61
|
+
cwd: process.cwd(),
|
|
62
|
+
env,
|
|
63
|
+
});
|
|
64
|
+
// Capture output
|
|
65
|
+
this.pty.onData((data) => {
|
|
66
|
+
this.outputBuffer += data;
|
|
67
|
+
this.emit('data', data);
|
|
68
|
+
});
|
|
69
|
+
// Handle exit
|
|
70
|
+
this.pty.onExit(({ exitCode, signal }) => {
|
|
71
|
+
this.emit('exit', { exitCode, signal });
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Write data to the terminal
|
|
76
|
+
*/
|
|
77
|
+
write(data) {
|
|
78
|
+
if (!this.pty) {
|
|
79
|
+
throw new Error('Terminal session not started');
|
|
80
|
+
}
|
|
81
|
+
this.pty.write(data);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the current output buffer
|
|
85
|
+
*/
|
|
86
|
+
getOutput() {
|
|
87
|
+
return this.outputBuffer;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Clear the output buffer
|
|
91
|
+
*/
|
|
92
|
+
clearOutput() {
|
|
93
|
+
this.outputBuffer = '';
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Resize the terminal
|
|
97
|
+
*/
|
|
98
|
+
resize(cols, rows) {
|
|
99
|
+
if (!this.pty) {
|
|
100
|
+
throw new Error('Terminal session not started');
|
|
101
|
+
}
|
|
102
|
+
this.pty.resize(cols, rows);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Kill the terminal process
|
|
106
|
+
*/
|
|
107
|
+
kill(signal) {
|
|
108
|
+
if (this.pty) {
|
|
109
|
+
this.pty.kill(signal);
|
|
110
|
+
this.pty = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Check if the session is active
|
|
115
|
+
*/
|
|
116
|
+
isActive() {
|
|
117
|
+
return this.pty !== null;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Get the process ID
|
|
121
|
+
*/
|
|
122
|
+
getPid() {
|
|
123
|
+
return this.pty?.pid;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/terminal/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal API implementation
|
|
3
|
+
* Provides high-level terminal interaction (start/send/wait/snapshot)
|
|
4
|
+
*
|
|
5
|
+
* 执行架构:
|
|
6
|
+
* - 非录制、非交互模式:使用 Bun.spawn,stdout/stderr 分离,exitCode 精确
|
|
7
|
+
* - 录制或交互模式:使用 PTY,支持复杂交互,但 exitCode 不可靠
|
|
8
|
+
*/
|
|
9
|
+
import type { TerminalAPI, WaitOptions, RunOptions, PTYProcess, PluginFactory, TerminalWithPlugins, CommandLog } from '../runner/models.js';
|
|
10
|
+
import { TerminalSession } from './session.js';
|
|
11
|
+
import { EventEmitter } from 'events';
|
|
12
|
+
/**
|
|
13
|
+
* 计算 tmux 输出捕获的行范围
|
|
14
|
+
* 纯函数,可独立单元测试
|
|
15
|
+
*/
|
|
16
|
+
export declare function calculateOutputRange(beforeCursorY: number, beforeHistorySize: number, afterCursorY: number, afterHistorySize: number, promptLineCount: number): {
|
|
17
|
+
startLine: number;
|
|
18
|
+
endLine: number;
|
|
19
|
+
};
|
|
20
|
+
export interface TerminalConfig {
|
|
21
|
+
cols?: number;
|
|
22
|
+
rows?: number;
|
|
23
|
+
recording?: boolean;
|
|
24
|
+
recordingPath?: string;
|
|
25
|
+
ptyOnly?: boolean;
|
|
26
|
+
tmuxSessionName?: string;
|
|
27
|
+
tmuxPaneId?: string;
|
|
28
|
+
promptLineCount?: number;
|
|
29
|
+
}
|
|
30
|
+
export interface SharedTerminalState {
|
|
31
|
+
paneCount: number;
|
|
32
|
+
currentActivePane?: number;
|
|
33
|
+
paneOutputs: Map<number, string>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* High-level Terminal API for test authoring
|
|
37
|
+
*/
|
|
38
|
+
export declare class Terminal extends EventEmitter implements TerminalAPI {
|
|
39
|
+
private session;
|
|
40
|
+
private recording;
|
|
41
|
+
private ptyOnly;
|
|
42
|
+
private recordingPath?;
|
|
43
|
+
private closed;
|
|
44
|
+
private initialized;
|
|
45
|
+
private tmuxSessionName?;
|
|
46
|
+
private tmuxPaneId?;
|
|
47
|
+
private sharedState;
|
|
48
|
+
private paneIndex?;
|
|
49
|
+
private nonInteractiveOutput;
|
|
50
|
+
private commandLogs;
|
|
51
|
+
private pluginFactory?;
|
|
52
|
+
plugins?: Record<string, unknown>;
|
|
53
|
+
private beforeEnterHistorySize;
|
|
54
|
+
private beforeEnterCursorY;
|
|
55
|
+
private commandLineCount;
|
|
56
|
+
private promptLineCount;
|
|
57
|
+
private promptLineCountConfigured;
|
|
58
|
+
private detectedPromptPattern?;
|
|
59
|
+
constructor(config?: TerminalConfig);
|
|
60
|
+
/**
|
|
61
|
+
* Get tmux session name (for multi-terminal coordination)
|
|
62
|
+
*/
|
|
63
|
+
getTmuxSessionName(): string | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Get tmux pane ID (for multi-terminal coordination)
|
|
66
|
+
*/
|
|
67
|
+
getTmuxPaneId(): string | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Get terminal session (for direct access)
|
|
70
|
+
*/
|
|
71
|
+
getSession(): TerminalSession;
|
|
72
|
+
/**
|
|
73
|
+
* Get shared state (for factory to update pane count)
|
|
74
|
+
*/
|
|
75
|
+
getSharedState(): SharedTerminalState;
|
|
76
|
+
/**
|
|
77
|
+
* Increment pane count (called by factory when creating new panes)
|
|
78
|
+
*/
|
|
79
|
+
incrementPaneCount(): void;
|
|
80
|
+
/**
|
|
81
|
+
* Set parent session (for child terminals that share a session)
|
|
82
|
+
*/
|
|
83
|
+
setParentSession(session: TerminalSession, sharedState: SharedTerminalState, paneIndex: number): void;
|
|
84
|
+
/**
|
|
85
|
+
* Select the tmux pane that this terminal is bound to
|
|
86
|
+
* Uses arrow key navigation to switch panes without showing pane IDs
|
|
87
|
+
*/
|
|
88
|
+
private selectPane;
|
|
89
|
+
/**
|
|
90
|
+
* 执行命令,返回 PTYProcess
|
|
91
|
+
*
|
|
92
|
+
* 执行模式:
|
|
93
|
+
* - 非录制、非交互(默认):使用 Bun.spawn,stdout/stderr 分离,exitCode 精确
|
|
94
|
+
* - 录制或交互:使用 PTY,支持 expect/send,但 exitCode 返回 -1
|
|
95
|
+
*
|
|
96
|
+
* 用法:
|
|
97
|
+
* - 直接 await: 自动调用 wait(),返回 CommandResult
|
|
98
|
+
* - 不 await: 返回 PTYProcess 控制器,可调用 expect/send/wait 等方法
|
|
99
|
+
*
|
|
100
|
+
* @param command - 要执行的命令
|
|
101
|
+
* @param options - 可选配置,包括 interactive: true 启用交互模式
|
|
102
|
+
*/
|
|
103
|
+
run(command: string, options?: RunOptions): PTYProcess;
|
|
104
|
+
/**
|
|
105
|
+
* Initialize terminal session (recording or non-recording)
|
|
106
|
+
*/
|
|
107
|
+
private initializeSession;
|
|
108
|
+
/**
|
|
109
|
+
* Wait for shell to be ready (detect shell prompt)
|
|
110
|
+
*/
|
|
111
|
+
private waitForShellReady;
|
|
112
|
+
/**
|
|
113
|
+
* Wait for tmux to be ready (detect shell prompt)
|
|
114
|
+
*/
|
|
115
|
+
private waitForTmuxReady;
|
|
116
|
+
/**
|
|
117
|
+
* Send text to the terminal
|
|
118
|
+
*/
|
|
119
|
+
send(text: string): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* Wait for text to appear in terminal output
|
|
122
|
+
* In recording mode with multi-pane, uses tmux capture-pane for isolation
|
|
123
|
+
*/
|
|
124
|
+
waitForText(text: string, options?: WaitOptions): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Get snapshot of current terminal output
|
|
127
|
+
* In recording mode, returns current pane's output (stripped of ANSI)
|
|
128
|
+
*/
|
|
129
|
+
snapshot(): Promise<string>;
|
|
130
|
+
/**
|
|
131
|
+
* Get all output (session + non-interactive commands)
|
|
132
|
+
*/
|
|
133
|
+
private getAllOutput;
|
|
134
|
+
/**
|
|
135
|
+
* Capture output from current pane using tmux capture-pane
|
|
136
|
+
* Used in recording mode for per-pane output isolation
|
|
137
|
+
*/
|
|
138
|
+
private capturePaneOutput;
|
|
139
|
+
/**
|
|
140
|
+
* Execute a tmux command and return its output
|
|
141
|
+
*/
|
|
142
|
+
private runTmuxCommand;
|
|
143
|
+
/**
|
|
144
|
+
* Strip ANSI escape sequences from text
|
|
145
|
+
*/
|
|
146
|
+
private stripAnsi;
|
|
147
|
+
/**
|
|
148
|
+
* Append output from non-interactive command (internal use)
|
|
149
|
+
*/
|
|
150
|
+
appendNonInteractiveOutput(output: string): void;
|
|
151
|
+
/**
|
|
152
|
+
* Record a command execution result for failure diagnostics
|
|
153
|
+
*/
|
|
154
|
+
appendCommandLog(log: CommandLog): void;
|
|
155
|
+
/**
|
|
156
|
+
* Get command logs captured during the current test
|
|
157
|
+
*/
|
|
158
|
+
getCommandLogs(): CommandLog[];
|
|
159
|
+
/**
|
|
160
|
+
* 设置插件工厂(用于 create() 自动注入插件)
|
|
161
|
+
* @internal 由插件系统调用
|
|
162
|
+
*/
|
|
163
|
+
setPluginFactory<TPlugins>(factory: PluginFactory<TPlugins>): void;
|
|
164
|
+
/**
|
|
165
|
+
* Create a new terminal instance (for multi-terminal tests)
|
|
166
|
+
* - Recording mode: splits tmux window (tmux already started via asciinema --command)
|
|
167
|
+
* - Non-recording mode: creates independent terminal
|
|
168
|
+
* - If pluginFactory is set, new terminal will have plugins property
|
|
169
|
+
*/
|
|
170
|
+
create<TPlugins = Record<string, unknown>>(): Promise<TerminalWithPlugins<TPlugins>>;
|
|
171
|
+
/**
|
|
172
|
+
* Close the terminal
|
|
173
|
+
*/
|
|
174
|
+
close(): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Clean up tmux session after recording ends
|
|
177
|
+
*/
|
|
178
|
+
private cleanupTmuxSession;
|
|
179
|
+
/**
|
|
180
|
+
* Check if terminal is active
|
|
181
|
+
*/
|
|
182
|
+
isActive(): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Check if terminal is in recording mode
|
|
185
|
+
*/
|
|
186
|
+
isRecording(): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* 是否使用 PTY 模式(录制或 pty-only)
|
|
189
|
+
* PTY 模式支持交互式命令,但打字效果仅在 recording 模式下启用
|
|
190
|
+
*/
|
|
191
|
+
isPtyMode(): boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Get pane index (for tmux commands)
|
|
194
|
+
*/
|
|
195
|
+
getPaneIndex(): number | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* Get session output (for non-recording PTY mode)
|
|
198
|
+
*/
|
|
199
|
+
getSessionOutput(): string;
|
|
200
|
+
/**
|
|
201
|
+
* Get output length at current moment (for range capture)
|
|
202
|
+
*/
|
|
203
|
+
getOutputLength(): number;
|
|
204
|
+
/**
|
|
205
|
+
* Get the state recorded before sending Enter (for output capture)
|
|
206
|
+
*/
|
|
207
|
+
getBeforeEnterState(): {
|
|
208
|
+
historySize: number;
|
|
209
|
+
cursorY: number;
|
|
210
|
+
commandLineCount: number;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* Record state before sending Enter (internal use)
|
|
214
|
+
* 使用单次 tmux 查询原子获取 history_size 和 cursor_y,避免竞态条件
|
|
215
|
+
*/
|
|
216
|
+
private recordBeforeEnterState;
|
|
217
|
+
/**
|
|
218
|
+
* 在录制开始前检测提示符相关信息
|
|
219
|
+
* - 提示符占用的行数
|
|
220
|
+
* - 提示符匹配 pattern
|
|
221
|
+
* 通过创建临时 tmux session 来测量,检测过程不会出现在录制中
|
|
222
|
+
*/
|
|
223
|
+
private detectPromptBeforeRecording;
|
|
224
|
+
/**
|
|
225
|
+
* 分析提示符行,生成匹配正则
|
|
226
|
+
*/
|
|
227
|
+
private analyzePromptLine;
|
|
228
|
+
/**
|
|
229
|
+
* 获取检测到的提示符行数
|
|
230
|
+
*/
|
|
231
|
+
getPromptLineCount(): number;
|
|
232
|
+
/**
|
|
233
|
+
* 获取检测到的提示符匹配 pattern
|
|
234
|
+
*/
|
|
235
|
+
getDetectedPromptPattern(): RegExp | undefined;
|
|
236
|
+
/**
|
|
237
|
+
* Type text with human-like delays (for recording mode)
|
|
238
|
+
* @param text - 要打字的文本
|
|
239
|
+
* @param speed - 每字符延迟 (ms),默认 80ms
|
|
240
|
+
* @param variableSpeed - 是否使用变速模式(更自然)
|
|
241
|
+
*/
|
|
242
|
+
private typeWithDelay;
|
|
243
|
+
/**
|
|
244
|
+
* 在录制中显示步骤标题
|
|
245
|
+
*/
|
|
246
|
+
private displayStepTitle;
|
|
247
|
+
/**
|
|
248
|
+
* Wait for command to complete
|
|
249
|
+
* Uses prompt detection only
|
|
250
|
+
*/
|
|
251
|
+
private waitForOutputStable;
|
|
252
|
+
/**
|
|
253
|
+
* Sleep utility
|
|
254
|
+
*/
|
|
255
|
+
private sleep;
|
|
256
|
+
/**
|
|
257
|
+
* Wait for output to stabilize (public, for PTYProcessImpl)
|
|
258
|
+
*/
|
|
259
|
+
waitForOutputStablePublic(timeout?: number): Promise<void>;
|
|
260
|
+
/**
|
|
261
|
+
* Execute command in PTY (internal, for PTYProcessImpl)
|
|
262
|
+
*/
|
|
263
|
+
executeInPty(command: string, options?: {
|
|
264
|
+
typingSpeed?: number;
|
|
265
|
+
pauseBefore?: number;
|
|
266
|
+
showStepTitle?: boolean;
|
|
267
|
+
stepName?: string;
|
|
268
|
+
}): Promise<void>;
|
|
269
|
+
/**
|
|
270
|
+
* 使用 Bracketed Paste Mode 粘贴多行命令
|
|
271
|
+
* 避免 shell 显示续行提示符(如 quote>、pipe heredoc>)
|
|
272
|
+
*
|
|
273
|
+
* Bracketed Paste Mode 使用转义序列包裹粘贴内容:
|
|
274
|
+
* - \x1b[200~ 标记粘贴开始
|
|
275
|
+
* - \x1b[201~ 标记粘贴结束
|
|
276
|
+
* Shell 会将整个内容作为单个输入块处理,不显示续行提示符
|
|
277
|
+
*/
|
|
278
|
+
private pasteWithTmux;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Create a new Terminal instance
|
|
282
|
+
*/
|
|
283
|
+
export declare function createTerminal(config?: TerminalConfig): Terminal;
|
|
284
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/terminal/terminal.ts"],"names":[],"mappings":"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"}
|