Terminal capability detection library for Tinky applications. Provides React hooks and utilities for detecting terminal features like background color, Kitty keyboard protocol support, and modifyOtherKeys mode.
- 🎨 Background Color Detection - Detect terminal theme (light/dark) via OSC 11
- 📝 Terminal Identification - Get terminal name and version (xterm, kitty, WezTerm, etc.)
- ⌨️ Kitty Keyboard Protocol - Detect enhanced keyboard input support
- 🔧 modifyOtherKeys - Detect key sequence disambiguation (Ctrl+I vs Tab)
- ⚛️ React Integration - Seamless hooks and context provider for Tinky apps
This project is based on the terminal capability detection implementation from gemini-cli.
npm install tinky-termcapPeer Dependencies:
tinky>= 1.0.0
Wrap your application in TermcapProvider and use the useTermcap hook to access terminal capabilities.
import { render, Box, Text } from "tinky";
import { TermcapProvider, useTermcap } from "tinky-termcap";
function App() {
const { isReady, backgroundColor, terminalName, kittyProtocol } =
useTermcap();
if (!isReady) {
return <Text>Detecting terminal capabilities...</Text>;
}
return (
<Box flexDirection="column">
<Text>Terminal: {terminalName ?? "Unknown"}</Text>
<Text>Background: {backgroundColor ?? "Unknown"}</Text>
<Text>
Kitty Protocol: {kittyProtocol ? "Supported" : "Not supported"}
</Text>
</Box>
);
}
render(
<TermcapProvider>
<App />
</TermcapProvider>,
);import { useTermcap } from "tinky-termcap";
import { useMemo } from "react";
function ThemedComponent() {
const { backgroundColor } = useTermcap();
const isDarkTheme = useMemo(() => {
if (!backgroundColor) return true; // Assume dark if unknown
const hex = backgroundColor.slice(1);
const r = parseInt(hex.slice(0, 2), 16);
const g = parseInt(hex.slice(2, 4), 16);
const b = parseInt(hex.slice(4, 6), 16);
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
return luminance < 0.5;
}, [backgroundColor]);
return (
<Box borderStyle="round" borderColor={isDarkTheme ? "white" : "black"}>
<Text color={isDarkTheme ? "cyan" : "blue"}>Adaptive content</Text>
</Box>
);
}import { detectTermcap } from "tinky-termcap";
async function main() {
// Enable raw mode for reading terminal responses
process.stdin.setRawMode(true);
const caps = await detectTermcap(process.stdin, process.stdout, 1000);
console.log("Detection complete:");
console.log(" Terminal:", caps.terminalName ?? "Unknown");
console.log(" Background:", caps.backgroundColor ?? "Unknown");
console.log(" Kitty Protocol:", caps.kittyProtocol ? "Yes" : "No");
console.log(" modifyOtherKeys:", caps.modifyOtherKeys ? "Yes" : "No");
process.stdin.setRawMode(false);
process.exit(0);
}
main();React context provider that performs terminal capability detection.
| Prop | Type | Default | Description |
|---|---|---|---|
children |
React.ReactNode |
- | Child components |
timeout |
number |
1000 |
Detection timeout in milliseconds |
initialCapabilities |
TermcapInfo |
- | Skip detection and use provided values (for testing) |
<TermcapProvider timeout={500}>
<App />
</TermcapProvider><TermcapProvider
initialCapabilities={{
isReady: true,
backgroundColor: "#1a1a1a",
terminalName: "xterm-256color",
kittyProtocol: true,
modifyOtherKeys: true,
}}
>
<ComponentUnderTest />
</TermcapProvider>React hook to access terminal capabilities. Must be used within TermcapProvider.
| Property | Type | Description |
|---|---|---|
isReady |
boolean |
Whether detection has completed |
backgroundColor |
string | undefined |
Background color in #rrggbb format |
terminalName |
string | undefined |
Terminal name/version string |
kittyProtocol |
boolean |
Kitty keyboard protocol support |
modifyOtherKeys |
boolean |
modifyOtherKeys (level ≥ 2) support |
function MyComponent() {
const { isReady, backgroundColor, kittyProtocol, modifyOtherKeys } =
useTermcap();
if (!isReady) {
return <Text>Loading...</Text>;
}
return (
<Box flexDirection="column">
<Text>Background: {backgroundColor ?? "unknown"}</Text>
<Text>
Enhanced keyboard: {kittyProtocol || modifyOtherKeys ? "✓" : "✗"}
</Text>
</Box>
);
}Low-level function for direct terminal capability detection.
function detectTermcap(
stdin?: IOReadStream,
stdout?: IOWriteStream,
timeout?: number,
): Promise<TermcapInfo>;| Parameter | Type | Description |
|---|---|---|
stdin |
ReadStream |
Input stream (e.g., process.stdin) |
stdout |
WriteStream |
Output stream (e.g., process.stdout) |
timeout |
number |
Detection timeout in milliseconds |
import { detectTermcap } from "tinky-termcap";
const caps = await detectTermcap(process.stdin, process.stdout, 1000);The library exports feature definitions for advanced use cases:
import {
KittyFeature,
Osc11Feature,
TerminalNameFeature,
DeviceAttributesFeature,
ModifyOtherKeysFeature,
type TermFeature,
} from "tinky-termcap/utils/term-features";
// Each feature has:
// - query: ANSI escape sequence to send
// - responseRegex: Pattern to match the response
// Example: Custom detection
process.stdout.write(KittyFeature.query);
// Listen for response matching KittyFeature.responseRegex- On Mount:
TermcapProviderenables raw mode and sends detection queries - Query Sequence: Sends escape sequences for each feature:
- Kitty keyboard protocol query
- OSC 11 (background color)
- XTVERSION (terminal name)
- modifyOtherKeys query
- Device Attributes (sentinel)
- Response Parsing: Parses terminal responses as they arrive
- Completion: Detection completes when either:
- Device Attributes response received (indicates all responses sent)
- Timeout reached
Tested with:
- xterm - Full OSC 11 and XTVERSION support
- kitty - Kitty protocol, XTVERSION, OSC 11
- WezTerm - Full feature support
- iTerm2 - OSC 11, XTVERSION
- Alacritty - OSC 11
- macOS Terminal - Basic support
- VS Code Terminal - OSC 11
# Install dependencies
npm install
# Build
npm run build
# Run tests
bun test
# Generate docs
npm run docsApache-2.0
See LICENSE for details.