forked from replayableio/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrecorder.js
More file actions
85 lines (71 loc) · 2.46 KB
/
recorder.js
File metadata and controls
85 lines (71 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
const fs = require("fs");
const pty = require("@homebridge/node-pty-prebuilt-multiarch");
const process = require("process");
const find = require("find-process");
class Recorder {
#ptyProcess = null;
#logFile = null;
#silent = false;
constructor(logFile, silent) {
// This way we don't run the recording script recursively, especially
// if it's inside bash/zsh configs
this.#silent = silent;
if (process.env.DASHCAM_TERMINAL_RECORDING) {
if (!this.#silent)
console.log("The current terminal is already being recorded");
process.exit(0);
}
this.#logFile = logFile;
}
#onInput(data) {
this.#ptyProcess.write(data);
}
#onData(data) {
process.stdout.write(data);
fs.appendFileSync(this.#logFile, data, "utf-8");
}
async start() {
if (!this.#silent) {
console.log("This session is being recorded by Dashcam");
console.log("Type `exit` to stop recording");
}
// TODO: Find a way to consistently get the current shell this is running from
// instead of using the default user shell (Maybe use parent processId to find
// the process filepath)
const shell = (
process.env.SHELL ||
(await find("pid", process.ppid).then((arr) => arr[0].bin)) ||
""
).trim();
if (!shell) throw new Error("Could not detect the current shell");
const args = [];
if (!shell.toLowerCase().includes("powershell")) args.push("-l");
this.#ptyProcess = pty.spawn(shell, args, {
// Inject a terminal variable to let the child processes know
// of the active recording so they we don't record recursively
env: { ...process.env, DASHCAM_TERMINAL_RECORDING: "TRUE" },
cols: process.stdout.columns,
rows: process.stdout.rows,
cwd: process.cwd(),
});
process.stdout.on("resize", () =>
this.#ptyProcess.resize(process.stdout.columns, process.stdout.rows)
);
process.stdin.on("data", this.#onInput.bind(this));
this.#ptyProcess.on("data", this.#onData.bind(this));
this.#ptyProcess.on("exit", this.stop.bind(this));
process.stdout.setDefaultEncoding("utf8");
process.stdin.setEncoding("utf8");
process.stdin.setRawMode(true);
process.stdin.resume();
}
stop() {
process.stdin.removeListener("data", this.#onInput.bind(this));
process.stdin.setRawMode(false);
process.stdin.pause();
console.clear();
process.kill(process.ppid, "SIGTERM");
process.exit();
}
}
module.exports = Recorder;