kittyhtml 0.3.0 → 0.3.2
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/examples/demo.png +0 -0
- package/package.json +4 -4
- package/skill/kittyhtml/SKILL.md +24 -23
- package/src/cli.js +30 -4
package/examples/demo.png
CHANGED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kittyhtml",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Render HTML to an image and display it inline in Kitty/iTerm2-capable terminals. No browser — Rust + Blitz layout, headless CPU rasterization.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"node": ">=20"
|
|
26
26
|
},
|
|
27
27
|
"optionalDependencies": {
|
|
28
|
-
"kittyhtml-darwin-arm64": "0.3.
|
|
29
|
-
"kittyhtml-darwin-x64": "0.3.
|
|
30
|
-
"kittyhtml-linux-x64-gnu": "0.3.
|
|
28
|
+
"kittyhtml-darwin-arm64": "0.3.2",
|
|
29
|
+
"kittyhtml-darwin-x64": "0.3.2",
|
|
30
|
+
"kittyhtml-linux-x64-gnu": "0.3.2"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"demo": "node src/cli.js --demo",
|
package/skill/kittyhtml/SKILL.md
CHANGED
|
@@ -5,48 +5,44 @@ description: Render output as an inline terminal image using the `kittyhtml` CLI
|
|
|
5
5
|
|
|
6
6
|
# kittyhtml output format
|
|
7
7
|
|
|
8
|
-
The user has asked for output as **kittyhtml** or **khtml** — they want the result rendered as a styled HTML page and displayed inline in their terminal as an image
|
|
8
|
+
The user has asked for output as **kittyhtml** or **khtml** — they want the result rendered as a styled HTML page and displayed inline in their terminal as an image.
|
|
9
9
|
|
|
10
10
|
## What to do
|
|
11
11
|
|
|
12
12
|
1. **Verify the tool is installed**: `command -v kittyhtml`. If missing, tell the user `npm install -g kittyhtml` and stop.
|
|
13
13
|
|
|
14
|
-
2. **Generate HTML** that represents the content
|
|
14
|
+
2. **Generate HTML** that represents the content. Be liberal with CSS — Blitz handles flexbox, grid, `<style>` blocks, class selectors, web fonts, and `<img>` tags. Treat it like a real browser with the caveats listed below.
|
|
15
15
|
|
|
16
|
-
3. **Pipe
|
|
16
|
+
3. **Pipe through the CLI**:
|
|
17
17
|
```sh
|
|
18
|
-
cat <<'HTML' | kittyhtml --
|
|
18
|
+
cat <<'HTML' | kittyhtml --scale 2
|
|
19
19
|
<!DOCTYPE html>
|
|
20
20
|
<html><body>...</body></html>
|
|
21
21
|
HTML
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
- `--width 700`–`800` for full pages and reports
|
|
26
|
-
- `--width 500` for cards and summaries
|
|
27
|
-
- `--width 400` for compact, just-a-snippet output
|
|
24
|
+
Don't pass `--width` unless the user asks for a specific size — the default adapts to their terminal width. Always pass `--scale 2` for sharper text on HiDPI displays.
|
|
28
25
|
|
|
29
26
|
4. After piping, write a one-line confirmation (e.g. "Rendered above."). The image is the deliverable; don't restate its contents in text.
|
|
30
27
|
|
|
31
28
|
## CSS — what works
|
|
32
29
|
|
|
33
|
-
kittyhtml v0.3+ uses Blitz (Stylo + Taffy + Parley + Vello).
|
|
30
|
+
kittyhtml v0.3+ uses Blitz (Stylo + Taffy + Parley + Vello CPU). Treat it like a modern browser:
|
|
34
31
|
|
|
35
|
-
-
|
|
36
|
-
- CSS Grid
|
|
37
|
-
- `
|
|
38
|
-
-
|
|
39
|
-
- `
|
|
40
|
-
- Native `<ul>` / `<ol>` bullets
|
|
41
|
-
- `<img>` tags (with absolute URLs; HTTPS works)
|
|
42
|
-
- `position: relative` / `absolute`
|
|
43
|
-
- Web fonts via `@font-face`
|
|
32
|
+
- **Full `<style>` blocks and class selectors work.** Use them.
|
|
33
|
+
- Flexbox, CSS Grid, `border-radius`, `box-shadow`, `opacity`, web fonts via `@font-face`, `<img>` tags with HTTPS URLs.
|
|
34
|
+
- `max-width`, `min-width`, `width`, `height` all work in any units.
|
|
35
|
+
- `<ul>` / `<ol>` render native bullets/numbers.
|
|
36
|
+
- `position: relative` and (limited) `absolute`.
|
|
44
37
|
|
|
45
|
-
|
|
38
|
+
## Caveats (Blitz pre-alpha)
|
|
39
|
+
|
|
40
|
+
- **`<thead>` rows render the background but lose text content.** Workaround: put header rows in `<tbody>` and style the row with `font-weight: 700` instead of wrapping in `<thead>`, or apply inline `style="font-weight:700"` directly on each `<th>`.
|
|
41
|
+
- **Fixed widths bigger than `--width` overflow the canvas.** Stick to percentages (`width: 100%`) or `max-width` on tables and large containers. The canvas dimension is `--width * --scale` pixels.
|
|
46
42
|
|
|
47
43
|
## Fonts
|
|
48
44
|
|
|
49
|
-
Two are baked
|
|
45
|
+
Two are baked into the binary and reliable:
|
|
50
46
|
- `'Noto Sans'` (regular, bold, italic, bold-italic)
|
|
51
47
|
- `'Noto Sans Mono'` for code
|
|
52
48
|
|
|
@@ -63,9 +59,14 @@ Other fonts will fall back to system defaults or fail to render predictably.
|
|
|
63
59
|
```html
|
|
64
60
|
<!DOCTYPE html>
|
|
65
61
|
<html>
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
<head><style>
|
|
63
|
+
body { font-family: 'Noto Sans', sans-serif; margin: 0; padding: 0; background: #f4f4f5; color: #18181b; }
|
|
64
|
+
.wrap { max-width: 720px; margin: 0 auto; padding: 32px 24px; }
|
|
65
|
+
.card { background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); padding: 28px 32px; }
|
|
66
|
+
</style></head>
|
|
67
|
+
<body>
|
|
68
|
+
<div class="wrap">
|
|
69
|
+
<div class="card">
|
|
69
70
|
<!-- content here -->
|
|
70
71
|
</div>
|
|
71
72
|
</div>
|
package/src/cli.js
CHANGED
|
@@ -13,9 +13,11 @@ USAGE
|
|
|
13
13
|
kittyhtml --demo
|
|
14
14
|
|
|
15
15
|
OPTIONS
|
|
16
|
-
--width N Viewport width in CSS px (default
|
|
16
|
+
--width N Viewport width in CSS px (default: terminal width when
|
|
17
|
+
rendered to a TTY, else 1200).
|
|
17
18
|
--height N Fixed canvas height; omit to auto-fit content.
|
|
18
|
-
--scale N Pixel ratio for crisper output (default
|
|
19
|
+
--scale N Pixel ratio for crisper output (default: 2 when piping
|
|
20
|
+
to a graphics-capable terminal, 1 when writing to file).
|
|
19
21
|
--background CSS Fill canvas background before painting (e.g. "#fff").
|
|
20
22
|
--format FMT Output protocol: auto | kitty | iterm2 (default auto).
|
|
21
23
|
--out, -o PATH Write PNG to PATH instead of stdout. ("-" = stdout PNG)
|
|
@@ -28,11 +30,25 @@ EXAMPLES
|
|
|
28
30
|
kittyhtml report.html --scale 2 -o report.png
|
|
29
31
|
`;
|
|
30
32
|
|
|
33
|
+
// When stdout is a terminal, estimate its visible width in pixels so the
|
|
34
|
+
// rendered image fits the terminal at 1:1 instead of looking small. The
|
|
35
|
+
// estimate is `columns * 9` — a rough cell-width assumption that's close
|
|
36
|
+
// enough on macOS terminals at default zoom. Clamped so we don't render
|
|
37
|
+
// a wallpaper for someone with a 400-column tmux pane.
|
|
38
|
+
function defaultWidth() {
|
|
39
|
+
if (process.stdout.isTTY && typeof process.stdout.columns === 'number') {
|
|
40
|
+
const cols = process.stdout.columns;
|
|
41
|
+
return Math.max(400, Math.min(2400, cols * 9));
|
|
42
|
+
}
|
|
43
|
+
return 1200;
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
function parseArgs(argv) {
|
|
32
47
|
const opts = {
|
|
33
|
-
width:
|
|
48
|
+
width: defaultWidth(),
|
|
34
49
|
height: null,
|
|
35
|
-
|
|
50
|
+
// null sentinel: filled in after arg parse based on output destination.
|
|
51
|
+
scale: null,
|
|
36
52
|
background: null,
|
|
37
53
|
format: 'auto',
|
|
38
54
|
out: null,
|
|
@@ -72,6 +88,16 @@ function parseArgs(argv) {
|
|
|
72
88
|
process.exit(2);
|
|
73
89
|
}
|
|
74
90
|
if (positional[0]) opts.file = positional[0];
|
|
91
|
+
|
|
92
|
+
if (opts.scale == null) {
|
|
93
|
+
// Going to a graphics-capable terminal → assume HiDPI (every modern
|
|
94
|
+
// mac and most linux laptops). The terminal will downscale the larger
|
|
95
|
+
// PNG to fill the same on-screen area, giving retina-sharp text. File
|
|
96
|
+
// output stays at 1:1 since the user knows they want the literal pixel
|
|
97
|
+
// count they asked for.
|
|
98
|
+
opts.scale = opts.out == null && process.stdout.isTTY ? 2 : 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
75
101
|
return opts;
|
|
76
102
|
}
|
|
77
103
|
|