claude-face 0.1.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/README.md +72 -0
- package/dist/bin/cli.d.ts +2 -0
- package/dist/bin/cli.js +128 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/src/config.d.ts +24 -0
- package/dist/src/config.js +32 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/face.d.ts +60 -0
- package/dist/src/face.js +472 -0
- package/dist/src/face.js.map +1 -0
- package/dist/src/frames.d.ts +1 -0
- package/dist/src/frames.js +3 -0
- package/dist/src/frames.js.map +1 -0
- package/dist/src/ipc.d.ts +27 -0
- package/dist/src/ipc.js +136 -0
- package/dist/src/ipc.js.map +1 -0
- package/dist/src/loader.d.ts +2 -0
- package/dist/src/loader.js +87 -0
- package/dist/src/loader.js.map +1 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.js +201 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/patterns.d.ts +6 -0
- package/dist/src/patterns.js +14 -0
- package/dist/src/patterns.js.map +1 -0
- package/dist/src/pty.d.ts +17 -0
- package/dist/src/pty.js +84 -0
- package/dist/src/pty.js.map +1 -0
- package/dist/src/scroll.d.ts +36 -0
- package/dist/src/scroll.js +56 -0
- package/dist/src/scroll.js.map +1 -0
- package/dist/src/state.d.ts +35 -0
- package/dist/src/state.js +158 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/theme.d.ts +15 -0
- package/dist/src/theme.js +51 -0
- package/dist/src/theme.js.map +1 -0
- package/dist/src/types.d.ts +58 -0
- package/dist/src/types.js +3 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils.d.ts +14 -0
- package/dist/src/utils.js +26 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# claude-face
|
|
2
|
+
|
|
3
|
+
Animated ASCII face for Claude Code — reacts to AI state in real-time.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g claude-face
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Two terminals: Claude runs in one, the face renders in the other. They talk over a Unix socket.
|
|
14
|
+
|
|
15
|
+
**Terminal 1** — launch Claude with the face server:
|
|
16
|
+
```bash
|
|
17
|
+
claude-face
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Terminal 2** — open the face renderer:
|
|
21
|
+
```bash
|
|
22
|
+
claude-face --face-only
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Options
|
|
26
|
+
|
|
27
|
+
| Flag | Description |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `--face <path>` | Load a custom face definition |
|
|
30
|
+
| `--face-only` | Run only the face renderer |
|
|
31
|
+
| `--theme dark\|light\|auto` | Color theme (default: `auto`) |
|
|
32
|
+
| `--no-face` | Plain passthrough, no face server |
|
|
33
|
+
| `--debug` | Print diagnostics before launching |
|
|
34
|
+
|
|
35
|
+
## Custom faces
|
|
36
|
+
|
|
37
|
+
Export a `FaceDefinition` from a TypeScript file:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { FaceDefinition } from 'claude-face/src/types';
|
|
41
|
+
|
|
42
|
+
const myFace: FaceDefinition = {
|
|
43
|
+
name: 'robot',
|
|
44
|
+
width: 16,
|
|
45
|
+
height: 5,
|
|
46
|
+
expressions: {
|
|
47
|
+
idle: { name: 'idle', frames: [{ art: [/* ... */] }] },
|
|
48
|
+
typing: { /* ... */ },
|
|
49
|
+
thinking: { /* ... */ },
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default myFace;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
claude-face --face ./my-face.ts
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Local development
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npm install
|
|
64
|
+
npm run build
|
|
65
|
+
npm test
|
|
66
|
+
npx tsx bin/cli.ts # run wrapper
|
|
67
|
+
npx tsx bin/cli.ts --face-only # run face renderer
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## License
|
|
71
|
+
|
|
72
|
+
MIT
|
package/dist/bin/cli.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { run } from '../src/main.js';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
// ── Argument parsing ────────────────────────────────────────────────
|
|
5
|
+
function parseArgs(argv) {
|
|
6
|
+
const options = {
|
|
7
|
+
theme: 'auto',
|
|
8
|
+
noFace: false,
|
|
9
|
+
faceOnly: false,
|
|
10
|
+
debug: false,
|
|
11
|
+
help: false,
|
|
12
|
+
version: false,
|
|
13
|
+
};
|
|
14
|
+
const args = argv.slice(2); // skip node and script path
|
|
15
|
+
for (let i = 0; i < args.length; i++) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
if (arg === '--help' || arg === '-h') {
|
|
18
|
+
options.help = true;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (arg === '--version' || arg === '-v') {
|
|
22
|
+
options.version = true;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (arg === '--no-face') {
|
|
26
|
+
options.noFace = true;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (arg === '--face-only') {
|
|
30
|
+
options.faceOnly = true;
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (arg === '--debug') {
|
|
34
|
+
options.debug = true;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (arg === '--face') {
|
|
38
|
+
i++;
|
|
39
|
+
if (i >= args.length) {
|
|
40
|
+
console.error('Error: --face requires a path argument.');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
options.facePath = args[i];
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (arg.startsWith('--face=')) {
|
|
47
|
+
options.facePath = arg.slice('--face='.length);
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (arg === '--theme') {
|
|
51
|
+
i++;
|
|
52
|
+
if (i >= args.length) {
|
|
53
|
+
console.error('Error: --theme requires a value (dark, light, or auto).');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const value = args[i];
|
|
57
|
+
if (value !== 'dark' && value !== 'light' && value !== 'auto') {
|
|
58
|
+
console.error(`Error: invalid theme "${value}". Must be dark, light, or auto.`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
options.theme = value;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (arg.startsWith('--theme=')) {
|
|
65
|
+
const value = arg.slice('--theme='.length);
|
|
66
|
+
if (value !== 'dark' && value !== 'light' && value !== 'auto') {
|
|
67
|
+
console.error(`Error: invalid theme "${value}". Must be dark, light, or auto.`);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
options.theme = value;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
console.error(`Error: unknown option "${arg}".`);
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
return options;
|
|
77
|
+
}
|
|
78
|
+
// ── Help text ───────────────────────────────────────────────────────
|
|
79
|
+
const HELP_TEXT = `\
|
|
80
|
+
claude-face — Animated ASCII face for Claude Code
|
|
81
|
+
|
|
82
|
+
Usage: claude-face [options]
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
--face <path> Load a custom face definition
|
|
86
|
+
--face-only Run only the face renderer (connect to running wrapper)
|
|
87
|
+
--theme dark|light|auto Color theme (default: auto)
|
|
88
|
+
--no-face Run Claude without the face overlay
|
|
89
|
+
--debug Print diagnostic info before launching
|
|
90
|
+
-h, --help Show this help
|
|
91
|
+
-v, --version Show version`;
|
|
92
|
+
// ── Main ────────────────────────────────────────────────────────────
|
|
93
|
+
const options = parseArgs(process.argv);
|
|
94
|
+
if (options.help) {
|
|
95
|
+
console.log(HELP_TEXT);
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
if (options.version) {
|
|
99
|
+
const require = createRequire(import.meta.url);
|
|
100
|
+
const pkg = require('../package.json');
|
|
101
|
+
console.log(pkg.version);
|
|
102
|
+
process.exit(0);
|
|
103
|
+
}
|
|
104
|
+
async function main() {
|
|
105
|
+
if (options.debug) {
|
|
106
|
+
const { findClaude, resolveSymlink } = await import('../src/pty.js');
|
|
107
|
+
try {
|
|
108
|
+
const claudePath = findClaude();
|
|
109
|
+
const target = resolveSymlink(claudePath);
|
|
110
|
+
console.error(`[debug] claude path: ${claudePath}${target ? ` -> ${target} (symlink)` : ''}`);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
console.error(`[debug] claude path: NOT FOUND (${err instanceof Error ? err.message : err})`);
|
|
114
|
+
}
|
|
115
|
+
const cols = process.stdout.columns ?? '?';
|
|
116
|
+
const rows = process.stdout.rows ?? '?';
|
|
117
|
+
console.error(`[debug] terminal: ${cols}x${rows}`);
|
|
118
|
+
console.error(`[debug] node: ${process.version}, platform: ${process.platform} ${process.arch}`);
|
|
119
|
+
console.error(`[debug] cwd: ${process.cwd()}`);
|
|
120
|
+
}
|
|
121
|
+
await run(options);
|
|
122
|
+
}
|
|
123
|
+
main().catch((err) => {
|
|
124
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
125
|
+
console.error(`claude-face: ${message}`);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../bin/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const config: {
|
|
2
|
+
/** Minimum ms between normal animation frames (~6 fps). */
|
|
3
|
+
minRenderIntervalMs: number;
|
|
4
|
+
/** Total duration of the per-character flip transition (ms). */
|
|
5
|
+
transitionDurationMs: number;
|
|
6
|
+
/** Render interval during a transition (~30 fps). */
|
|
7
|
+
transitionTickMs: number;
|
|
8
|
+
/** Logistic steepness — higher = sharper sigmoid S-curve. */
|
|
9
|
+
sigmoidSteepness: number;
|
|
10
|
+
/** No PTY activity for this long → idle. */
|
|
11
|
+
idleTimeoutMs: number;
|
|
12
|
+
/** Debounce window before committing a state change. */
|
|
13
|
+
debounceMs: number;
|
|
14
|
+
/** How often accumulated PTY data is processed (ms). */
|
|
15
|
+
feedSampleIntervalMs: number;
|
|
16
|
+
/** Minimum printable chars in a PTY chunk to trigger 'typing'. */
|
|
17
|
+
minPrintableLen: number;
|
|
18
|
+
/** After a thinking pattern, suppress typing transitions for this long. */
|
|
19
|
+
thinkingCooldownMs: number;
|
|
20
|
+
/** Inactivity timeout before leaving 'listening' state. */
|
|
21
|
+
listeningTimeoutMs: number;
|
|
22
|
+
/** Delay before retrying a failed IPC connection (ms). */
|
|
23
|
+
ipcRetryMs: number;
|
|
24
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// ── Tunable constants ───────────────────────────────────────────────
|
|
2
|
+
//
|
|
3
|
+
// All timing, rendering, and state-detection knobs in one place.
|
|
4
|
+
export const config = {
|
|
5
|
+
// ── Rendering ───────────────────────────────────────────────────
|
|
6
|
+
/** Minimum ms between normal animation frames (~6 fps). */
|
|
7
|
+
minRenderIntervalMs: 166,
|
|
8
|
+
// ── Transitions ─────────────────────────────────────────────────
|
|
9
|
+
/** Total duration of the per-character flip transition (ms). */
|
|
10
|
+
transitionDurationMs: 80,
|
|
11
|
+
/** Render interval during a transition (~30 fps). */
|
|
12
|
+
transitionTickMs: 33,
|
|
13
|
+
/** Logistic steepness — higher = sharper sigmoid S-curve. */
|
|
14
|
+
sigmoidSteepness: 7,
|
|
15
|
+
// ── State detection ─────────────────────────────────────────────
|
|
16
|
+
/** No PTY activity for this long → idle. */
|
|
17
|
+
idleTimeoutMs: 500,
|
|
18
|
+
/** Debounce window before committing a state change. */
|
|
19
|
+
debounceMs: 100,
|
|
20
|
+
/** How often accumulated PTY data is processed (ms). */
|
|
21
|
+
feedSampleIntervalMs: 50,
|
|
22
|
+
/** Minimum printable chars in a PTY chunk to trigger 'typing'. */
|
|
23
|
+
minPrintableLen: 3,
|
|
24
|
+
/** After a thinking pattern, suppress typing transitions for this long. */
|
|
25
|
+
thinkingCooldownMs: 400,
|
|
26
|
+
/** Inactivity timeout before leaving 'listening' state. */
|
|
27
|
+
listeningTimeoutMs: 1000,
|
|
28
|
+
// ── IPC ─────────────────────────────────────────────────────────
|
|
29
|
+
/** Delay before retrying a failed IPC connection (ms). */
|
|
30
|
+
ipcRetryMs: 1000,
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,iEAAiE;AAEjE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,mEAAmE;IACnE,2DAA2D;IAC3D,mBAAmB,EAAE,GAAG;IAExB,mEAAmE;IACnE,gEAAgE;IAChE,oBAAoB,EAAE,EAAE;IACxB,qDAAqD;IACrD,gBAAgB,EAAE,EAAE;IACpB,6DAA6D;IAC7D,gBAAgB,EAAE,CAAC;IAEnB,mEAAmE;IACnE,4CAA4C;IAC5C,aAAa,EAAE,GAAG;IAClB,wDAAwD;IACxD,UAAU,EAAE,GAAG;IACf,wDAAwD;IACxD,oBAAoB,EAAE,EAAE;IACxB,kEAAkE;IAClE,eAAe,EAAE,CAAC;IAClB,2EAA2E;IAC3E,kBAAkB,EAAE,GAAG;IACvB,2DAA2D;IAC3D,kBAAkB,EAAE,IAAI;IAExB,mEAAmE;IACnE,0DAA0D;IAC1D,UAAU,EAAE,IAAI;CACjB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { FaceDefinition, FaceState, ColorSpan } from './types.js';
|
|
2
|
+
import { ThemeColors } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render a single art row with ANSI color spans applied.
|
|
5
|
+
* Accepts pre-sorted spans for this specific row only.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderRow(art: string, rowSpans: ColorSpan[], theme: ThemeColors): string;
|
|
8
|
+
export declare class FaceRenderer {
|
|
9
|
+
private face;
|
|
10
|
+
private theme;
|
|
11
|
+
private currentState;
|
|
12
|
+
private currentFrameIndex;
|
|
13
|
+
private animationTimer;
|
|
14
|
+
private cycleStartTime;
|
|
15
|
+
private animCycleDuration;
|
|
16
|
+
private animForwardDuration;
|
|
17
|
+
private animFrameDuration;
|
|
18
|
+
private animFrameCount;
|
|
19
|
+
private animHasReverse;
|
|
20
|
+
private animGapMin;
|
|
21
|
+
private animGapMax;
|
|
22
|
+
private animTickMs;
|
|
23
|
+
private stdoutDraining;
|
|
24
|
+
private hasRenderedOnce;
|
|
25
|
+
private lastRenderedState;
|
|
26
|
+
private lastRenderedFrame;
|
|
27
|
+
private frameCache;
|
|
28
|
+
private clearScreenBuf;
|
|
29
|
+
private cachedCols;
|
|
30
|
+
private cachedRows;
|
|
31
|
+
private transitioning;
|
|
32
|
+
private transitionTimer;
|
|
33
|
+
private transitionStartTime;
|
|
34
|
+
private transitionFlipTimes;
|
|
35
|
+
private transitionOldArt;
|
|
36
|
+
private transitionNewArt;
|
|
37
|
+
private transitionOldRoles;
|
|
38
|
+
private transitionNewRoles;
|
|
39
|
+
private transitionNewState;
|
|
40
|
+
constructor(face: FaceDefinition, theme: ThemeColors);
|
|
41
|
+
private rebuildFrameCache;
|
|
42
|
+
setState(state: FaceState): void;
|
|
43
|
+
invalidateCache(): void;
|
|
44
|
+
showMessage(msg: string): void;
|
|
45
|
+
destroy(): void;
|
|
46
|
+
private buildRoleGrid;
|
|
47
|
+
private generateFlipTimes;
|
|
48
|
+
private beginTransition;
|
|
49
|
+
private scheduleTransitionTick;
|
|
50
|
+
private transitionTick;
|
|
51
|
+
private finishTransition;
|
|
52
|
+
private stopTransition;
|
|
53
|
+
private renderTransitionFrame;
|
|
54
|
+
private startAnimation;
|
|
55
|
+
private startNewCycle;
|
|
56
|
+
private scheduleNextTick;
|
|
57
|
+
private animationTick;
|
|
58
|
+
private stopAnimation;
|
|
59
|
+
private renderNow;
|
|
60
|
+
}
|