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.
- package/LICENSE +21 -0
- package/README.md +417 -0
- package/dist/claude-highlight.js +2282 -0
- package/dist/pty-read-worker.js +19 -0
- package/dist/pty-write-worker.js +18 -0
- package/man/claude-highlight.1 +145 -0
- package/package.json +63 -0
|
@@ -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
|
+
}
|