claude-highlight 1.0.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.
@@ -0,0 +1,19 @@
1
+ // @bun
2
+ // src/pty-read-worker.ts
3
+ import { dlopen, FFIType } from "bun:ffi";
4
+ var lib = dlopen(process.platform === "darwin" ? "/usr/lib/libSystem.dylib" : "libc.so.6", {
5
+ read: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 }
6
+ });
7
+ self.onmessage = (event) => {
8
+ const fd = event.data.fd;
9
+ const buf = new Uint8Array(65536);
10
+ try {
11
+ for (;; ) {
12
+ const n = Number(lib.symbols.read(fd, buf, buf.length));
13
+ if (n <= 0)
14
+ break;
15
+ self.postMessage(buf.subarray(0, n));
16
+ }
17
+ } catch {}
18
+ self.postMessage(null);
19
+ };
@@ -0,0 +1,18 @@
1
+ // @bun
2
+ // src/pty-write-worker.ts
3
+ import { dlopen, FFIType } from "bun:ffi";
4
+ var lib = dlopen(process.platform === "darwin" ? "/usr/lib/libSystem.dylib" : "libc.so.6", {
5
+ write: { args: [FFIType.i32, FFIType.ptr, FFIType.u64], returns: FFIType.i64 }
6
+ });
7
+ function writeAll(fd, data) {
8
+ let off = 0;
9
+ while (off < data.length) {
10
+ const n = Number(lib.symbols.write(fd, data.subarray(off), data.length - off));
11
+ if (n <= 0)
12
+ return;
13
+ off += n;
14
+ }
15
+ }
16
+ self.onmessage = (event) => {
17
+ writeAll(event.data.fd, event.data.data);
18
+ };
@@ -0,0 +1,145 @@
1
+ .TH CLAUDE\-HIGHLIGHT 1 "2026-09-04" "claude-highlight 1.0.0" "User Commands"
2
+ .SH NAME
3
+ claude\-highlight \- run Claude Code behind a PTY that colors epistemic markers
4
+ .SH SYNOPSIS
5
+ .B claude\-highlight
6
+ .RI [ options ]
7
+ .RI [ "claude args" ...]
8
+ .SH DESCRIPTION
9
+ .B claude\-highlight
10
+ spawns the real
11
+ .B claude
12
+ on a pseudo\-terminal and forwards bytes both ways, injecting SGR color around
13
+ words that mark a claim as unverified \(em hedges, admitted gaps, assumptions,
14
+ impressions, unearned certainty.
15
+ .PP
16
+ Because SGR is zero\-width, the child's layout math is untouched: the wrapper
17
+ never adds, removes or moves a cell, so wrapping, cursor addressing and the
18
+ child's own repaint diff all behave exactly as they would without it. Arguments
19
+ it does not recognise are passed straight through to
20
+ .BR claude .
21
+ .PP
22
+ A highlight can also be taken back. Claude Code repaints with a cell\-level
23
+ diff, so a cell it skips would otherwise keep a color the word that earned it
24
+ no longer justifies; the wrapper mirrors the screen and rewrites those cells at
25
+ the end of the frame that stranded them.
26
+ .PP
27
+ What you type is left alone. The input box is found on screen \(em the band
28
+ between the last two full\-width rules \(em and nothing inside it is ever
29
+ painted.
30
+ .SH OPTIONS
31
+ .TP
32
+ .B \-\-hl\-help
33
+ Print a short usage summary and exit.
34
+ .TP
35
+ .B \-\-hl\-selftest
36
+ Push sample text through the real filter and print it, then list the
37
+ categories and any config words that were rejected. The prose lines should
38
+ show color and the code and user\-message lines should not. Run this first when
39
+ a session looks unhighlighted.
40
+ .TP
41
+ .B \-\-hl\-menu
42
+ Print the plugin panel as it would be drawn, without starting a session.
43
+ .TP
44
+ .BR \-\-hl\-palette " [" all ]
45
+ Print the colors worth considering, painted in the terminal that has to show
46
+ them, with the code to put in the config beside each.
47
+ .B all
48
+ adds the full 256\-color ramp.
49
+ .TP
50
+ .BI \-\-hl\-record " PATH"
51
+ Tee both sides of the session to
52
+ .IB PATH .raw
53
+ (what Claude Code emitted) and
54
+ .IB PATH .out
55
+ (what was handed to the terminal). Replaying the former through the filter
56
+ reproduces the latter exactly, which is how a rendering oddity gets settled
57
+ after the fact.
58
+ .SH PLUGIN MENU
59
+ .B F9
60
+ opens a panel over the bottom of the screen for toggling categories live;
61
+ terminals that cannot send F9 can be bound to emit its sequence,
62
+ .BR "ESC [ 20 ~" .
63
+ .PP
64
+ .RS
65
+ .PD 0
66
+ .TP 14
67
+ .BR Up ", " Down
68
+ move the selection
69
+ .TP
70
+ .BR Space ", " Enter
71
+ toggle the selected category
72
+ .TP
73
+ .BR q ", " Esc ", " F9
74
+ close the panel and save
75
+ .PD
76
+ .RE
77
+ .PP
78
+ Toggles are written to the config file, so they persist and are shared across
79
+ every workspace. A paste that arrives while the panel is open closes it and is
80
+ delivered to the child rather than eaten as menu keys.
81
+ .SH CONFIGURATION
82
+ .I ~/.config/claude-highlight/config.json
83
+ is created on first run and re\-read whenever it changes, so an edit takes
84
+ effect on the next line Claude Code prints. It holds a
85
+ .B categories
86
+ map \(em each with
87
+ .BR color ", " on ", " desc " and an " add
88
+ list of extra words \(em plus
89
+ .BR custom ", " annotations ", " prose_only " and " idle_repaint .
90
+ .PP
91
+ Added words are matched literally, so punctuation needs no escaping and a typo
92
+ cannot be a broken regex that takes the session down. Prefix a word with
93
+ .B re:
94
+ to opt into a raw pattern; anything that will not compile is dropped and
95
+ listed by
96
+ .BR \-\-hl\-selftest .
97
+ .SH ENVIRONMENT
98
+ .TP
99
+ .B XDG_CONFIG_HOME
100
+ Base directory for the config file. Defaults to
101
+ .IR ~/.config .
102
+ .TP
103
+ .B CLAUDE_HIGHLIGHT_CMD
104
+ Program to run instead of
105
+ .BR claude .
106
+ Exists so the wrapper can be exercised against a stand\-in child without
107
+ launching a session.
108
+ .TP
109
+ .B COLORTERM
110
+ .B truecolor
111
+ or
112
+ .B 24bit
113
+ selects the panel's truecolor palette; anything else falls back to 256\-color.
114
+ .TP
115
+ .BR LC_ALL ", " LC_CTYPE ", " LANG
116
+ A UTF\-8 locale selects box\-drawing glyphs for the panel; otherwise it is drawn
117
+ in ASCII. Row widths are identical either way.
118
+ .TP
119
+ .B COLUMNS
120
+ Width used by
121
+ .B \-\-hl\-menu
122
+ and
123
+ .B \-\-hl\-palette
124
+ when standard output is not a terminal.
125
+ .SH FILES
126
+ .TP
127
+ .I ~/.config/claude-highlight/config.json
128
+ Category toggles, colors and added words.
129
+ .SH EXIT STATUS
130
+ The child's exit status, or 128 plus the signal number if the child was
131
+ killed by a signal.
132
+ .SH NOTES
133
+ Requires Bun 1.4 or newer: the pty is built on
134
+ .BR openpty (3)
135
+ through
136
+ .BR bun:ffi ,
137
+ with the blocking reads and writes on worker threads.
138
+ .PP
139
+ Unix only. The winsize ioctls and termios have no Windows equivalent, and a
140
+ port there means ConPTY.
141
+ .SH SEE ALSO
142
+ .BR claude (1),
143
+ .BR openpty (3),
144
+ .BR termios (4),
145
+ .BR pty (7)
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "claude-highlight",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "Colors epistemic markers in Claude Code's output, live, in the terminal",
6
+ "keywords": [
7
+ "claude",
8
+ "claude-code",
9
+ "cli",
10
+ "pty",
11
+ "terminal",
12
+ "ansi",
13
+ "highlight",
14
+ "hedging",
15
+ "epistemic",
16
+ "uncertainty",
17
+ "bun"
18
+ ],
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/NoahBPeterson/claude-highlight.git"
23
+ },
24
+ "bugs": {
25
+ "url": "https://github.com/NoahBPeterson/claude-highlight/issues"
26
+ },
27
+ "homepage": "https://github.com/NoahBPeterson/claude-highlight#readme",
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "bin": {
32
+ "claude-highlight": "./dist/claude-highlight.js"
33
+ },
34
+ "man": [
35
+ "./man/claude-highlight.1"
36
+ ],
37
+ "engines": {
38
+ "bun": ">=1.4.0"
39
+ },
40
+ "os": [
41
+ "darwin",
42
+ "linux"
43
+ ],
44
+ "scripts": {
45
+ "build": "rm -rf dist && bun build src/claude-highlight.ts src/pty-read-worker.ts src/pty-write-worker.ts --target=bun --outdir=dist",
46
+ "prepack": "bun run build",
47
+ "typecheck": "tsc -p tsconfig.json",
48
+ "test:pty": "bun run test/pty-smoke.ts",
49
+ "test:filter": "bun run test/test_filter.ts",
50
+ "test:screen": "bun run test/test_screen.ts",
51
+ "test:integration": "bun run test/test_integration.ts",
52
+ "test:wrapper": "bun run test/test_wrapper.ts",
53
+ "test:paste": "bun run test/test_paste.ts",
54
+ "test:miners": "bun run test/test_miners.ts",
55
+ "test:all": "bun run test/run_all.ts",
56
+ "test:dist": "bun run build && CLAUDE_HIGHLIGHT_BIN=\"$PWD/dist/claude-highlight.js\" bun run test/run_all.ts"
57
+ },
58
+ "devDependencies": {
59
+ "@types/bun": "^1.4.0",
60
+ "bun-types": "^1.4.1",
61
+ "typescript": "^5.9.0"
62
+ }
63
+ }