termcut 0.5.0 → 0.5.1
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/package.json +3 -2
- package/src/live.ts +1 -1
- package/src/recorder.ts +27 -0
- package/src/types.ts +8 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "termcut",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Script terminal sessions in TypeScript, render them to reproducible MP4/GIF/WebM/SVG/HTML with Bun.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Aman Varshney",
|
|
@@ -56,7 +56,8 @@
|
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@wterm/core": "^0.3.4",
|
|
58
58
|
"@wterm/dom": "^0.3.4",
|
|
59
|
-
"@wterm/ghostty": "^0.3.4"
|
|
59
|
+
"@wterm/ghostty": "^0.3.4",
|
|
60
|
+
"@wterm/markdown": "^0.3.4"
|
|
60
61
|
},
|
|
61
62
|
"devDependencies": {
|
|
62
63
|
"@types/bun": "latest"
|
package/src/live.ts
CHANGED
|
@@ -98,7 +98,7 @@ export async function recordLive(config: ResolvedConfig, opts: LiveOptions = {})
|
|
|
98
98
|
await Promise.race([exitedPromise, proc.exited]);
|
|
99
99
|
push("m", MARKER.end);
|
|
100
100
|
} finally {
|
|
101
|
-
process.off("SIGWINCH", onResize);
|
|
101
|
+
(process as unknown as { off(event: string, fn: () => void): void }).off("SIGWINCH", onResize); // newer @types/bun drop the signal overload on off()
|
|
102
102
|
if (stdin) {
|
|
103
103
|
stdin.off("data", onData);
|
|
104
104
|
if (isTTY) stdin.setRawMode(false);
|
package/src/recorder.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MarkdownRenderer } from "@wterm/markdown";
|
|
1
2
|
import { MARKER } from "./cast";
|
|
2
3
|
import { WINDOW_BAR_HEIGHT, estimateCell } from "./config";
|
|
3
4
|
import { formatMs, toMs } from "./duration";
|
|
@@ -269,6 +270,30 @@ export async function record(config: ResolvedConfig, script: Script, opts: Recor
|
|
|
269
270
|
push("i", typeof data === "string" ? data : decoder.decode(data));
|
|
270
271
|
};
|
|
271
272
|
|
|
273
|
+
/** Put text on screen as if the terminal had printed it: into the cast and the screen model, not the PTY. */
|
|
274
|
+
const inject = (data: string): void => {
|
|
275
|
+
push("o", data);
|
|
276
|
+
screen.write(data);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
const renderMarkdown = (markdown: string): string => {
|
|
280
|
+
const renderer = new MarkdownRenderer({ width: Math.max(20, cols - 2) });
|
|
281
|
+
return renderer.push(markdown.endsWith("\n") ? markdown : markdown + "\n") + renderer.flush();
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const print = async (markdown: string): Promise<void> => {
|
|
285
|
+
await screen.settle();
|
|
286
|
+
// Clear the prompt line, show the caption, then ask the shell for a fresh prompt on the next line.
|
|
287
|
+
inject(`\r\x1b[K${renderMarkdown(markdown)}`);
|
|
288
|
+
await raw("\r");
|
|
289
|
+
await waitFor(`prompt ${promptPattern} after print()`, promptVisible, config.waitTimeout);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
const title = async (text: string, titleOpts: { pause?: Duration } = {}): Promise<void> => {
|
|
293
|
+
await print(`# ${text}\n\n---`);
|
|
294
|
+
await sleep(titleOpts.pause ?? "1.5s");
|
|
295
|
+
};
|
|
296
|
+
|
|
272
297
|
const typingDelay = (base: number): number => {
|
|
273
298
|
if (config.typingJitter === 0) return base;
|
|
274
299
|
const factor = 1 + (rand() * 2 - 1) * config.typingJitter;
|
|
@@ -435,6 +460,8 @@ export async function record(config: ResolvedConfig, script: Script, opts: Recor
|
|
|
435
460
|
await screen.settle();
|
|
436
461
|
},
|
|
437
462
|
clear: () => run("clear"),
|
|
463
|
+
print,
|
|
464
|
+
title,
|
|
438
465
|
get browser(): BrowserSession {
|
|
439
466
|
if (!browserSession) throw new Error("t.browser needs `browser: { url }` in the video config.");
|
|
440
467
|
return browserSession;
|
package/src/types.ts
CHANGED
|
@@ -278,6 +278,14 @@ export interface TerminalSession {
|
|
|
278
278
|
resize(cols: number, rows: number): Promise<void>;
|
|
279
279
|
/** Shorthand for `run("clear")`. */
|
|
280
280
|
clear(): Promise<void>;
|
|
281
|
+
/**
|
|
282
|
+
* Show Markdown in the terminal as a caption (rendered to ANSI by @wterm/markdown). It is written into the
|
|
283
|
+
* recording and the screen model only, never sent to the shell; afterwards the shell is asked for a fresh prompt.
|
|
284
|
+
* Use at a shell prompt, not inside a full-screen program.
|
|
285
|
+
*/
|
|
286
|
+
print(markdown: string): Promise<void>;
|
|
287
|
+
/** A title card: big heading + rule, then a pause (default "1.5s"). */
|
|
288
|
+
title(text: string, opts?: { pause?: Duration }): Promise<void>;
|
|
281
289
|
/** The recorded browser window; throws if `browser` is not configured. */
|
|
282
290
|
readonly browser: BrowserSession;
|
|
283
291
|
/** Overlay layout: bring the terminal or the browser window to the front (recorded as a marker). */
|