@hekonsek/scriptz 0.4.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Henryk Konsek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # Scriptz: record your terminal sessions with script
2
+
3
+ This project provides a Node.js + TypeScript CLI for working with terminal session recordings created by the Unix `script` command.
4
+
5
+ ## How it works
6
+
7
+ - Recordings are stored in `~/.cache/script`.
8
+ - `record` starts a new `script` session and writes output to a timestamped `.log` file.
9
+ - `clean` removes recordings older than 15 minutes so only recent session data stays on disk.
10
+
11
+ ## Commands
12
+
13
+ - `scriptz version` prints the package version.
14
+ - `scriptz record` starts a new recording session.
15
+ - `scriptz prompt` prints a Bash `PS1` assignment with a random terminal title.
16
+ - `scriptz clean` removes recordings older than 15 minutes.
17
+ - `scriptz clean --quiet` removes old recordings without output.
18
+
19
+ Apply the generated prompt to the current shell:
20
+
21
+ ```bash
22
+ eval "$(scriptz prompt)"
23
+ ```
24
+
25
+ ## Local development
26
+
27
+ Install the published CLI:
28
+
29
+ ```bash
30
+ npm install -g @hekonsek/scriptz
31
+ ```
32
+
33
+ Install dependencies:
34
+
35
+ ```bash
36
+ npm install
37
+ ```
38
+
39
+ Run tests:
40
+
41
+ ```bash
42
+ npm test
43
+ ```
44
+
45
+ Run the CLI during development:
46
+
47
+ ```bash
48
+ npm run dev -- version
49
+ ```
50
+
51
+ Build distributable files:
52
+
53
+ ```bash
54
+ npm run build
55
+ ```
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ export interface CliDependencies {
4
+ readonly homeDirectory: string;
5
+ readonly writeOut: (line: string) => void;
6
+ readonly writeErr: (line: string) => void;
7
+ readonly setExitCode: (code: number) => void;
8
+ readVersion: () => Promise<string>;
9
+ }
10
+ export declare function createCli(deps?: CliDependencies): Command;
11
+ export declare function runCli(argv?: string[]): Promise<void>;
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import chalk from "chalk";
6
+ import { Command } from "commander";
7
+ import { ScriptCommandNotFoundError, TerminalScripts, } from "../core/terminal-scripts.js";
8
+ import { buildPromptAssignment } from "../core/shell-prompt.js";
9
+ const defaultDependencies = {
10
+ homeDirectory: homedir(),
11
+ writeOut: (line) => {
12
+ process.stdout.write(`${line}\n`);
13
+ },
14
+ writeErr: (line) => {
15
+ process.stderr.write(`${line}\n`);
16
+ },
17
+ setExitCode: (code) => {
18
+ process.exitCode = code;
19
+ },
20
+ readVersion,
21
+ };
22
+ export function createCli(deps = defaultDependencies) {
23
+ const program = new Command();
24
+ program
25
+ .name("scriptz")
26
+ .description("Record terminal sessions and clean up old script logs.")
27
+ .showHelpAfterError();
28
+ program
29
+ .command("version")
30
+ .description("Display the installed package version.")
31
+ .action(async () => {
32
+ deps.writeOut(await deps.readVersion());
33
+ });
34
+ program
35
+ .command("record")
36
+ .description("Start a script(1) recording session.")
37
+ .action(async () => {
38
+ const scripts = new TerminalScripts(join(deps.homeDirectory, ".cache", "script"));
39
+ try {
40
+ deps.setExitCode(await scripts.record());
41
+ }
42
+ catch (error) {
43
+ if (error instanceof ScriptCommandNotFoundError) {
44
+ deps.writeErr(chalk.red("The 'script' command is not available. Install util-linux to enable recording."));
45
+ deps.setExitCode(127);
46
+ return;
47
+ }
48
+ throw error;
49
+ }
50
+ });
51
+ program
52
+ .command("prompt")
53
+ .description("Print a Bash prompt assignment with a random terminal title.")
54
+ .action(() => {
55
+ deps.writeOut(buildPromptAssignment());
56
+ });
57
+ program
58
+ .command("clean")
59
+ .description("Remove script logs that haven't been touched in the last 15 minutes.")
60
+ .option("-q, --quiet", "Suppress command output.", false)
61
+ .action(async (options) => {
62
+ const listener = buildCleanListener(options.quiet, deps);
63
+ const scripts = new TerminalScripts(join(deps.homeDirectory, ".cache", "script"), listener);
64
+ const result = await scripts.clean(15);
65
+ if (options.quiet) {
66
+ return;
67
+ }
68
+ if (!result.directoryExists) {
69
+ deps.writeOut("No script logs directory found.");
70
+ return;
71
+ }
72
+ if (result.removed > 0) {
73
+ deps.writeOut(`Removed ${result.removed} log${result.removed === 1 ? "" : "s"} older than 15 minutes.`);
74
+ return;
75
+ }
76
+ deps.writeOut("No logs older than 15 minutes were found.");
77
+ });
78
+ return program;
79
+ }
80
+ export async function runCli(argv = process.argv) {
81
+ const program = createCli();
82
+ if (argv.length <= 2) {
83
+ program.outputHelp();
84
+ return;
85
+ }
86
+ await program.parseAsync(argv);
87
+ }
88
+ async function readVersion() {
89
+ const packageJsonPath = new URL("../../package.json", import.meta.url);
90
+ const packageJsonRaw = await readFile(packageJsonPath, "utf8");
91
+ const packageJson = JSON.parse(packageJsonRaw);
92
+ return packageJson.version ?? "0.0.0";
93
+ }
94
+ function buildCleanListener(quiet, deps) {
95
+ if (quiet) {
96
+ return { onEvent: () => undefined };
97
+ }
98
+ return {
99
+ onEvent(event) {
100
+ if (event.type === "entry_skipped") {
101
+ deps.writeErr(chalk.yellow(`Skipping ${event.entryName}: ${event.reason}`));
102
+ }
103
+ if (event.type === "entry_remove_failed") {
104
+ deps.writeErr(chalk.red(`Failed to remove ${event.entryName}: ${event.reason}`));
105
+ }
106
+ },
107
+ };
108
+ }
109
+ if (import.meta.main) {
110
+ await runCli();
111
+ }
112
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EACL,0BAA0B,EAC1B,eAAe,GAChB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAchE,MAAM,mBAAmB,GAAoB;IAC3C,aAAa,EAAE,OAAO,EAAE;IACxB,QAAQ,EAAE,CAAC,IAAY,EAAQ,EAAE;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,QAAQ,EAAE,CAAC,IAAY,EAAQ,EAAE;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,WAAW,EAAE,CAAC,IAAY,EAAQ,EAAE;QAClC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC;IACD,WAAW;CACZ,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,OAAwB,mBAAmB;IACnE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CAAC,wDAAwD,CAAC;SACrE,kBAAkB,EAAE,CAAC;IAExB,OAAO;SACJ,OAAO,CAAC,SAAS,CAAC;SAClB,WAAW,CAAC,wCAAwC,CAAC;SACrD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,OAAO,GAAG,IAAI,eAAe,CACjC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAC7C,CAAC;QAEF,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,CAAC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,0BAA0B,EAAE,CAAC;gBAChD,IAAI,CAAC,QAAQ,CACX,KAAK,CAAC,GAAG,CACP,gFAAgF,CACjF,CACF,CAAC;gBACF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACtB,OAAO;YACT,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,8DAA8D,CAAC;SAC3E,MAAM,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,sEAAsE,CAAC;SACnF,MAAM,CAAC,aAAa,EAAE,0BAA0B,EAAE,KAAK,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,OAA2B,EAAE,EAAE;QAC5C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,IAAI,eAAe,CACjC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAC5C,QAAQ,CACT,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACvC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAC5B,IAAI,CAAC,QAAQ,CAAC,iCAAiC,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QAED,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,QAAQ,CACX,WAAW,MAAM,CAAC,OAAO,OAAO,MAAM,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,yBAAyB,CACzF,CAAC;YACF,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,2CAA2C,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAiB,OAAO,CAAC,IAAI;IACxD,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,CAAC,UAAU,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,KAAK,UAAU,WAAW;IACxB,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvE,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAyB,CAAC;IAEvE,OAAO,WAAW,CAAC,OAAO,IAAI,OAAO,CAAC;AACxC,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAc,EACd,IAAqB;IAErB,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IACtC,CAAC;IAED,OAAO;QACL,OAAO,CAAC,KAA2B;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBACnC,IAAI,CAAC,QAAQ,CACX,KAAK,CAAC,MAAM,CAAC,YAAY,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAC7D,CAAC;YACJ,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;gBACzC,IAAI,CAAC,QAAQ,CACX,KAAK,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAClE,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrB,MAAM,MAAM,EAAE,CAAC;AACjB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function buildPromptAssignment(name?: string): string;
@@ -0,0 +1,30 @@
1
+ import { randomInt } from "node:crypto";
2
+ const promptNames = [
3
+ "amber",
4
+ "atlas",
5
+ "cedar",
6
+ "delta",
7
+ "ember",
8
+ "falcon",
9
+ "harbor",
10
+ "iris",
11
+ "juno",
12
+ "kepler",
13
+ "lumen",
14
+ "nova",
15
+ "onyx",
16
+ "orbit",
17
+ "pixel",
18
+ "quartz",
19
+ "raven",
20
+ "summit",
21
+ "terra",
22
+ "vector",
23
+ ];
24
+ export function buildPromptAssignment(name = randomPromptName()) {
25
+ return `PS1='\\[\\e]0;\\u@${name}: \\w\\a\\]\${debian_chroot:+($debian_chroot)}\\[\\033[01;32m\\]\\u@${name}\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '`;
26
+ }
27
+ function randomPromptName() {
28
+ return promptNames[randomInt(promptNames.length)];
29
+ }
30
+ //# sourceMappingURL=shell-prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-prompt.js","sourceRoot":"","sources":["../../src/core/shell-prompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,WAAW,GAAG;IAClB,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,MAAM;IACN,MAAM;IACN,QAAQ;IACR,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;CACT,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,IAAI,GAAG,gBAAgB,EAAE;IAC7D,OAAO,qBAAqB,IAAI,uEAAuE,IAAI,2DAA2D,CAAC;AACzK,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,WAAW,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type TerminalScriptsEvent = {
2
+ type: "record_started";
3
+ logPath: string;
4
+ } | {
5
+ type: "entry_skipped";
6
+ entryName: string;
7
+ reason: string;
8
+ } | {
9
+ type: "entry_remove_failed";
10
+ entryName: string;
11
+ reason: string;
12
+ };
13
+ export interface TerminalScriptsListener {
14
+ onEvent(event: TerminalScriptsEvent): void;
15
+ }
16
+ export declare const noopTerminalScriptsListener: TerminalScriptsListener;
@@ -0,0 +1,6 @@
1
+ export const noopTerminalScriptsListener = {
2
+ onEvent() {
3
+ // intentionally empty
4
+ },
5
+ };
6
+ //# sourceMappingURL=terminal-scripts-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-scripts-listener.js","sourceRoot":"","sources":["../../src/core/terminal-scripts-listener.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,2BAA2B,GAA4B;IAClE,OAAO;QACL,sBAAsB;IACxB,CAAC;CACF,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { type TerminalScriptsListener } from "./terminal-scripts-listener.js";
2
+ export interface RecordProcessRunner {
3
+ run(logPath: string): Promise<number>;
4
+ }
5
+ export interface CleanResult {
6
+ directoryExists: boolean;
7
+ removed: number;
8
+ }
9
+ export declare class ScriptCommandNotFoundError extends Error {
10
+ constructor();
11
+ }
12
+ export declare class ScriptProcessRunner implements RecordProcessRunner {
13
+ run(logPath: string): Promise<number>;
14
+ }
15
+ export declare class TerminalScripts {
16
+ private readonly directory;
17
+ private readonly listener;
18
+ private readonly processRunner;
19
+ constructor(directory: string, listener?: TerminalScriptsListener, processRunner?: RecordProcessRunner);
20
+ record(): Promise<number>;
21
+ clean(maxAgeMinutes?: number): Promise<CleanResult>;
22
+ }
@@ -0,0 +1,122 @@
1
+ import { mkdir, readdir, stat, unlink } from "node:fs/promises";
2
+ import { spawn } from "node:child_process";
3
+ import { join } from "node:path";
4
+ import { noopTerminalScriptsListener, } from "./terminal-scripts-listener.js";
5
+ export class ScriptCommandNotFoundError extends Error {
6
+ constructor() {
7
+ super("The 'script' command is not available.");
8
+ this.name = "ScriptCommandNotFoundError";
9
+ }
10
+ }
11
+ export class ScriptProcessRunner {
12
+ async run(logPath) {
13
+ return new Promise((resolve, reject) => {
14
+ const child = spawn("script", ["-q", "-f", logPath], {
15
+ stdio: "inherit",
16
+ });
17
+ child.once("error", (error) => {
18
+ if (error.code === "ENOENT") {
19
+ reject(new ScriptCommandNotFoundError());
20
+ return;
21
+ }
22
+ reject(error);
23
+ });
24
+ child.once("close", (code) => {
25
+ resolve(code ?? 1);
26
+ });
27
+ });
28
+ }
29
+ }
30
+ export class TerminalScripts {
31
+ directory;
32
+ listener;
33
+ processRunner;
34
+ constructor(directory, listener = noopTerminalScriptsListener, processRunner = new ScriptProcessRunner()) {
35
+ this.directory = directory;
36
+ this.listener = listener;
37
+ this.processRunner = processRunner;
38
+ }
39
+ async record() {
40
+ await mkdir(this.directory, { recursive: true });
41
+ const logPath = join(this.directory, `${buildTimestamp()}.log`);
42
+ this.listener.onEvent({ type: "record_started", logPath });
43
+ return this.processRunner.run(logPath);
44
+ }
45
+ async clean(maxAgeMinutes = 15) {
46
+ try {
47
+ const directoryStat = await stat(this.directory);
48
+ if (!directoryStat.isDirectory()) {
49
+ return { directoryExists: false, removed: 0 };
50
+ }
51
+ }
52
+ catch (error) {
53
+ const typedError = error;
54
+ if (typedError.code === "ENOENT") {
55
+ return { directoryExists: false, removed: 0 };
56
+ }
57
+ throw error;
58
+ }
59
+ const entries = await readdir(this.directory, { withFileTypes: true });
60
+ const cutoff = Date.now() - maxAgeMinutes * 60 * 1000;
61
+ let removed = 0;
62
+ for (const entry of entries) {
63
+ if (!entry.isFile()) {
64
+ continue;
65
+ }
66
+ const filePath = join(this.directory, entry.name);
67
+ let modifiedAtMs;
68
+ try {
69
+ const fileStat = await stat(filePath);
70
+ modifiedAtMs = fileStat.mtimeMs;
71
+ }
72
+ catch (error) {
73
+ const reason = toErrorMessage(error);
74
+ this.listener.onEvent({
75
+ type: "entry_skipped",
76
+ entryName: entry.name,
77
+ reason,
78
+ });
79
+ continue;
80
+ }
81
+ if (modifiedAtMs >= cutoff) {
82
+ continue;
83
+ }
84
+ try {
85
+ await unlink(filePath);
86
+ removed += 1;
87
+ }
88
+ catch (error) {
89
+ const typedError = error;
90
+ if (typedError.code === "ENOENT") {
91
+ continue;
92
+ }
93
+ const reason = toErrorMessage(error);
94
+ this.listener.onEvent({
95
+ type: "entry_remove_failed",
96
+ entryName: entry.name,
97
+ reason,
98
+ });
99
+ }
100
+ }
101
+ return { directoryExists: true, removed };
102
+ }
103
+ }
104
+ function buildTimestamp(now = new Date()) {
105
+ const year = now.getFullYear();
106
+ const month = twoDigits(now.getMonth() + 1);
107
+ const day = twoDigits(now.getDate());
108
+ const hours = twoDigits(now.getHours());
109
+ const minutes = twoDigits(now.getMinutes());
110
+ const seconds = twoDigits(now.getSeconds());
111
+ return `${year}-${month}-${day}-${hours}-${minutes}-${seconds}`;
112
+ }
113
+ function twoDigits(value) {
114
+ return value.toString().padStart(2, "0");
115
+ }
116
+ function toErrorMessage(error) {
117
+ if (error instanceof Error) {
118
+ return error.message;
119
+ }
120
+ return String(error);
121
+ }
122
+ //# sourceMappingURL=terminal-scripts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-scripts.js","sourceRoot":"","sources":["../../src/core/terminal-scripts.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@hekonsek/scriptz",
3
+ "version": "0.4.0",
4
+ "description": "CLI utilities for recording terminal sessions",
5
+ "type": "module",
6
+ "bin": {
7
+ "scriptz": "dist/cli/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json && chmod +x dist/cli/cli.js",
17
+ "clean": "rm -rf dist",
18
+ "dev": "tsx src/cli/cli.ts",
19
+ "test": "vitest run",
20
+ "typecheck": "tsc --noEmit",
21
+ "release": "npm version minor && git push --follow-tags",
22
+ "install-latest": "npm install -g https://github.com/hekonsek/scriptz/archive/refs/tags/v${npm_package_version}.tar.gz"
23
+ },
24
+ "engines": {
25
+ "node": ">=20.0.0"
26
+ },
27
+ "dependencies": {
28
+ "chalk": "^5.4.1",
29
+ "commander": "^13.1.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/node": "^22.13.14",
33
+ "tsx": "^4.19.3",
34
+ "typescript": "^5.8.2",
35
+ "vitest": "^3.0.9"
36
+ }
37
+ }