tinky-termcap 1.0.0 → 1.0.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/lib/contexts/TermcapContext.js +16 -37
- package/lib/hooks/use-termcap.js +4 -7
- package/lib/index.js +4 -11
- package/lib/utils/detect-termcap.js +99 -146
- package/lib/utils/term-features.js +16 -19
- package/package.json +6 -2
|
@@ -1,27 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var i = m.call(o), r, ar = [], e;
|
|
6
|
-
try {
|
|
7
|
-
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
8
|
-
}
|
|
9
|
-
catch (error) { e = { error: error }; }
|
|
10
|
-
finally {
|
|
11
|
-
try {
|
|
12
|
-
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
13
|
-
}
|
|
14
|
-
finally { if (e) throw e.error; }
|
|
15
|
-
}
|
|
16
|
-
return ar;
|
|
17
|
-
};
|
|
18
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.TermcapContext = void 0;
|
|
20
|
-
exports.TermcapProvider = TermcapProvider;
|
|
21
|
-
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
22
|
-
var react_1 = require("react");
|
|
23
|
-
var tinky_1 = require("tinky");
|
|
24
|
-
var detect_termcap_js_1 = require("../utils/detect-termcap.js");
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { useStdin, useStdout } from "tinky";
|
|
4
|
+
import { detectTermcap, DEFAULT_DETECTION_TIMEOUT, } from "../utils/detect-termcap.js";
|
|
25
5
|
/**
|
|
26
6
|
* Default termcap info before detection completes.
|
|
27
7
|
*
|
|
@@ -31,7 +11,7 @@ var detect_termcap_js_1 = require("../utils/detect-termcap.js");
|
|
|
31
11
|
*
|
|
32
12
|
* @internal
|
|
33
13
|
*/
|
|
34
|
-
|
|
14
|
+
const defaultTermcapInfo = {
|
|
35
15
|
isReady: false,
|
|
36
16
|
backgroundColor: undefined,
|
|
37
17
|
terminalName: undefined,
|
|
@@ -58,7 +38,7 @@ var defaultTermcapInfo = {
|
|
|
58
38
|
*
|
|
59
39
|
* @see {@link useTermcap} - The recommended way to access capabilities
|
|
60
40
|
*/
|
|
61
|
-
|
|
41
|
+
export const TermcapContext = createContext(undefined);
|
|
62
42
|
/**
|
|
63
43
|
* Provider component that detects and provides terminal capabilities.
|
|
64
44
|
*
|
|
@@ -128,30 +108,29 @@ exports.TermcapContext = (0, react_1.createContext)(undefined);
|
|
|
128
108
|
* @see {@link TermcapProviderProps} - Available props
|
|
129
109
|
* @see {@link TermcapInfo} - Shape of the provided capabilities
|
|
130
110
|
*/
|
|
131
|
-
function TermcapProvider(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
(0, react_1.useEffect)(function () {
|
|
111
|
+
export function TermcapProvider({ children, timeout = DEFAULT_DETECTION_TIMEOUT, initialCapabilities, }) {
|
|
112
|
+
const [capabilities, setCapabilities] = useState(initialCapabilities ?? defaultTermcapInfo);
|
|
113
|
+
const { stdin, setRawMode } = useStdin();
|
|
114
|
+
const { stdout } = useStdout();
|
|
115
|
+
useEffect(() => {
|
|
137
116
|
// Skip detection if initial capabilities provided
|
|
138
117
|
if (initialCapabilities) {
|
|
139
118
|
return;
|
|
140
119
|
}
|
|
141
|
-
|
|
120
|
+
let mounted = true;
|
|
142
121
|
// Enable raw mode for detection
|
|
143
122
|
setRawMode(true);
|
|
144
|
-
|
|
123
|
+
detectTermcap(stdin, stdout, timeout).then((result) => {
|
|
145
124
|
if (mounted) {
|
|
146
125
|
setCapabilities(result);
|
|
147
126
|
// We don't disable raw mode here as Tinky applications usually need it.
|
|
148
127
|
// If necessary, the consumer can manage raw mode.
|
|
149
128
|
}
|
|
150
129
|
});
|
|
151
|
-
return
|
|
130
|
+
return () => {
|
|
152
131
|
mounted = false;
|
|
153
132
|
};
|
|
154
133
|
}, [timeout, initialCapabilities, stdin, stdout, setRawMode]);
|
|
155
|
-
|
|
156
|
-
return ((
|
|
134
|
+
const value = useMemo(() => capabilities, [capabilities]);
|
|
135
|
+
return (_jsx(TermcapContext.Provider, { value: value, children: children }));
|
|
157
136
|
}
|
package/lib/hooks/use-termcap.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @fileoverview React hook for accessing terminal capability information.
|
|
4
3
|
*
|
|
@@ -35,10 +34,8 @@
|
|
|
35
34
|
*
|
|
36
35
|
* @packageDocumentation
|
|
37
36
|
*/
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
var react_1 = require("react");
|
|
41
|
-
var TermcapContext_js_1 = require("../contexts/TermcapContext.js");
|
|
37
|
+
import { useContext } from "react";
|
|
38
|
+
import { TermcapContext } from "../contexts/TermcapContext.js";
|
|
42
39
|
/**
|
|
43
40
|
* React hook to access terminal capability information.
|
|
44
41
|
*
|
|
@@ -152,8 +149,8 @@ var TermcapContext_js_1 = require("../contexts/TermcapContext.js");
|
|
|
152
149
|
* @see {@link TermcapProvider} - The provider component that must wrap components using this hook
|
|
153
150
|
* @see {@link TermcapInfo} - The type definition for the returned capabilities object
|
|
154
151
|
*/
|
|
155
|
-
function useTermcap() {
|
|
156
|
-
|
|
152
|
+
export function useTermcap() {
|
|
153
|
+
const context = useContext(TermcapContext);
|
|
157
154
|
if (!context) {
|
|
158
155
|
throw new Error("useTermcap must be used within a TermcapProvider");
|
|
159
156
|
}
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* tinky-termcap - Terminal capability detection for Tinky applications.
|
|
4
3
|
*
|
|
@@ -54,8 +53,6 @@
|
|
|
54
53
|
*
|
|
55
54
|
* @packageDocumentation
|
|
56
55
|
*/
|
|
57
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
-
exports.DEFAULT_DETECTION_TIMEOUT = exports.detectTermcap = exports.useTermcap = exports.TermcapProvider = void 0;
|
|
59
56
|
/**
|
|
60
57
|
* React context provider for terminal capability detection.
|
|
61
58
|
*
|
|
@@ -65,8 +62,7 @@ exports.DEFAULT_DETECTION_TIMEOUT = exports.detectTermcap = exports.useTermcap =
|
|
|
65
62
|
*
|
|
66
63
|
* @see {@link TermcapProviderProps} for configuration options
|
|
67
64
|
*/
|
|
68
|
-
|
|
69
|
-
Object.defineProperty(exports, "TermcapProvider", { enumerable: true, get: function () { return TermcapContext_js_1.TermcapProvider; } });
|
|
65
|
+
export { TermcapProvider, } from "./contexts/TermcapContext.js";
|
|
70
66
|
/**
|
|
71
67
|
* React hook for accessing terminal capabilities.
|
|
72
68
|
*
|
|
@@ -75,18 +71,15 @@ Object.defineProperty(exports, "TermcapProvider", { enumerable: true, get: funct
|
|
|
75
71
|
*
|
|
76
72
|
* @see {@link TermcapInfo} for the shape of returned data
|
|
77
73
|
*/
|
|
78
|
-
|
|
79
|
-
Object.defineProperty(exports, "useTermcap", { enumerable: true, get: function () { return use_termcap_js_1.useTermcap; } });
|
|
74
|
+
export { useTermcap } from "./hooks/use-termcap.js";
|
|
80
75
|
/**
|
|
81
76
|
* Low-level terminal capability detection function.
|
|
82
77
|
*
|
|
83
78
|
* Use this directly when you need capability detection outside of React,
|
|
84
79
|
* or when you need more control over the detection process.
|
|
85
80
|
*/
|
|
86
|
-
|
|
87
|
-
Object.defineProperty(exports, "detectTermcap", { enumerable: true, get: function () { return detect_termcap_js_1.detectTermcap; } });
|
|
81
|
+
export { detectTermcap } from "./utils/detect-termcap.js";
|
|
88
82
|
/**
|
|
89
83
|
* Re-export additional types and constants for advanced usage.
|
|
90
84
|
*/
|
|
91
|
-
|
|
92
|
-
Object.defineProperty(exports, "DEFAULT_DETECTION_TIMEOUT", { enumerable: true, get: function () { return detect_termcap_js_2.DEFAULT_DETECTION_TIMEOUT; } });
|
|
85
|
+
export { DEFAULT_DETECTION_TIMEOUT } from "./utils/detect-termcap.js";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @fileoverview Terminal capability detection utilities.
|
|
4
3
|
*
|
|
@@ -46,47 +45,7 @@
|
|
|
46
45
|
*
|
|
47
46
|
* @packageDocumentation
|
|
48
47
|
*/
|
|
49
|
-
|
|
50
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
51
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
52
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
53
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
54
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
55
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
56
|
-
});
|
|
57
|
-
};
|
|
58
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
59
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
60
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
61
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
62
|
-
function step(op) {
|
|
63
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
64
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
65
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
66
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
67
|
-
switch (op[0]) {
|
|
68
|
-
case 0: case 1: t = op; break;
|
|
69
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
70
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
71
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
72
|
-
default:
|
|
73
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
74
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
75
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
76
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
77
|
-
if (t[2]) _.ops.pop();
|
|
78
|
-
_.trys.pop(); continue;
|
|
79
|
-
}
|
|
80
|
-
op = body.call(thisArg, _);
|
|
81
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
82
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
86
|
-
exports.DEFAULT_DETECTION_TIMEOUT = void 0;
|
|
87
|
-
exports.detectTermcap = detectTermcap;
|
|
88
|
-
exports.resetForTesting = resetForTesting;
|
|
89
|
-
var term_features_js_1 = require("./term-features.js");
|
|
48
|
+
import { DeviceAttributesFeature, KittyFeature, ModifyOtherKeysFeature, Osc11Feature, TerminalNameFeature, } from "./term-features.js";
|
|
90
49
|
/**
|
|
91
50
|
* Parse RGB color from hex components to #rrggbb format.
|
|
92
51
|
*
|
|
@@ -113,8 +72,8 @@ var term_features_js_1 = require("./term-features.js");
|
|
|
113
72
|
* @internal
|
|
114
73
|
*/
|
|
115
74
|
function parseColor(rHex, gHex, bHex) {
|
|
116
|
-
|
|
117
|
-
|
|
75
|
+
const parseComponent = (hex) => {
|
|
76
|
+
const val = parseInt(hex, 16);
|
|
118
77
|
if (hex.length === 1)
|
|
119
78
|
return (val / 15) * 255;
|
|
120
79
|
if (hex.length === 2)
|
|
@@ -125,11 +84,11 @@ function parseColor(rHex, gHex, bHex) {
|
|
|
125
84
|
return (val / 65535) * 255;
|
|
126
85
|
return val;
|
|
127
86
|
};
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
return
|
|
87
|
+
const r = parseComponent(rHex);
|
|
88
|
+
const g = parseComponent(gHex);
|
|
89
|
+
const b = parseComponent(bHex);
|
|
90
|
+
const toHex = (c) => Math.round(c).toString(16).padStart(2, "0");
|
|
91
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
133
92
|
}
|
|
134
93
|
/**
|
|
135
94
|
* Default timeout for capability detection in milliseconds.
|
|
@@ -149,7 +108,7 @@ function parseColor(rHex, gHex, bHex) {
|
|
|
149
108
|
* const caps = await detectTermcap(stdin, stdout, DEFAULT_DETECTION_TIMEOUT * 2);
|
|
150
109
|
* ```
|
|
151
110
|
*/
|
|
152
|
-
|
|
111
|
+
export const DEFAULT_DETECTION_TIMEOUT = 1000;
|
|
153
112
|
/**
|
|
154
113
|
* Detect terminal capabilities by querying the terminal.
|
|
155
114
|
*
|
|
@@ -243,103 +202,97 @@ exports.DEFAULT_DETECTION_TIMEOUT = 1000;
|
|
|
243
202
|
* const caps = await detectTermcap(mockStdin, mockStdout, 100);
|
|
244
203
|
* ```
|
|
245
204
|
*/
|
|
246
|
-
function detectTermcap(stdin, stdout, timeout) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
205
|
+
export async function detectTermcap(stdin, stdout, timeout) {
|
|
206
|
+
// Default result for non-TTY environments
|
|
207
|
+
const defaultResult = {
|
|
208
|
+
isReady: true,
|
|
209
|
+
backgroundColor: undefined,
|
|
210
|
+
terminalName: undefined,
|
|
211
|
+
kittyProtocol: false,
|
|
212
|
+
modifyOtherKeys: false,
|
|
213
|
+
};
|
|
214
|
+
// Skip detection if not TTY
|
|
215
|
+
if (stdin?.isTTY === false) {
|
|
216
|
+
return defaultResult;
|
|
217
|
+
}
|
|
218
|
+
return new Promise((resolve) => {
|
|
219
|
+
// Assumption: Caller handles raw mode (e.g. via Tinky useStdin)
|
|
220
|
+
let buffer = "";
|
|
221
|
+
let backgroundColor;
|
|
222
|
+
let terminalName;
|
|
223
|
+
let kittyProtocol = false;
|
|
224
|
+
let modifyOtherKeys = false;
|
|
225
|
+
let bgReceived = false;
|
|
226
|
+
let kittyReceived = false;
|
|
227
|
+
let terminalNameReceived = false;
|
|
228
|
+
let modifyOtherKeysReceived = false;
|
|
229
|
+
let deviceAttributesReceived = false;
|
|
230
|
+
const cleanup = () => {
|
|
231
|
+
if (timeoutId) {
|
|
232
|
+
clearTimeout(timeoutId);
|
|
233
|
+
}
|
|
234
|
+
stdin?.off?.("data", onData);
|
|
235
|
+
resolve({
|
|
251
236
|
isReady: true,
|
|
252
|
-
backgroundColor
|
|
253
|
-
terminalName
|
|
254
|
-
kittyProtocol
|
|
255
|
-
modifyOtherKeys
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
237
|
+
backgroundColor,
|
|
238
|
+
terminalName,
|
|
239
|
+
kittyProtocol,
|
|
240
|
+
modifyOtherKeys,
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
const timeoutId = setTimeout(cleanup, timeout);
|
|
244
|
+
const onData = (data) => {
|
|
245
|
+
buffer += data.toString();
|
|
246
|
+
// Check for background color (OSC 11 response)
|
|
247
|
+
if (!bgReceived) {
|
|
248
|
+
const match = buffer.match(Osc11Feature.responseRegex);
|
|
249
|
+
if (match) {
|
|
250
|
+
bgReceived = true;
|
|
251
|
+
backgroundColor = parseColor(match[1], match[2], match[3]);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Check for Kitty keyboard protocol support
|
|
255
|
+
if (!kittyReceived && KittyFeature.responseRegex.test(buffer)) {
|
|
256
|
+
kittyReceived = true;
|
|
257
|
+
kittyProtocol = true;
|
|
258
|
+
}
|
|
259
|
+
// Check for modifyOtherKeys support
|
|
260
|
+
if (!modifyOtherKeysReceived) {
|
|
261
|
+
const match = buffer.match(ModifyOtherKeysFeature.responseRegex);
|
|
262
|
+
if (match) {
|
|
263
|
+
modifyOtherKeysReceived = true;
|
|
264
|
+
const level = parseInt(match[1], 10);
|
|
265
|
+
modifyOtherKeys = level >= 2;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// Check for terminal name/version
|
|
269
|
+
if (!terminalNameReceived) {
|
|
270
|
+
const match = buffer.match(TerminalNameFeature.responseRegex);
|
|
271
|
+
if (match) {
|
|
272
|
+
terminalNameReceived = true;
|
|
273
|
+
terminalName = match[1];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Device Attributes response acts as sentinel - finish when received
|
|
277
|
+
if (!deviceAttributesReceived) {
|
|
278
|
+
const match = buffer.match(DeviceAttributesFeature.responseRegex);
|
|
279
|
+
if (match) {
|
|
280
|
+
deviceAttributesReceived = true;
|
|
281
|
+
cleanup();
|
|
282
|
+
}
|
|
260
283
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
var deviceAttributesReceived = false;
|
|
274
|
-
var cleanup = function () {
|
|
275
|
-
var _a;
|
|
276
|
-
if (timeoutId) {
|
|
277
|
-
clearTimeout(timeoutId);
|
|
278
|
-
}
|
|
279
|
-
(_a = stdin === null || stdin === void 0 ? void 0 : stdin.off) === null || _a === void 0 ? void 0 : _a.call(stdin, "data", onData);
|
|
280
|
-
resolve({
|
|
281
|
-
isReady: true,
|
|
282
|
-
backgroundColor: backgroundColor,
|
|
283
|
-
terminalName: terminalName,
|
|
284
|
-
kittyProtocol: kittyProtocol,
|
|
285
|
-
modifyOtherKeys: modifyOtherKeys,
|
|
286
|
-
});
|
|
287
|
-
};
|
|
288
|
-
var timeoutId = setTimeout(cleanup, timeout);
|
|
289
|
-
var onData = function (data) {
|
|
290
|
-
buffer += data.toString();
|
|
291
|
-
// Check for background color (OSC 11 response)
|
|
292
|
-
if (!bgReceived) {
|
|
293
|
-
var match = buffer.match(term_features_js_1.Osc11Feature.responseRegex);
|
|
294
|
-
if (match) {
|
|
295
|
-
bgReceived = true;
|
|
296
|
-
backgroundColor = parseColor(match[1], match[2], match[3]);
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
// Check for Kitty keyboard protocol support
|
|
300
|
-
if (!kittyReceived && term_features_js_1.KittyFeature.responseRegex.test(buffer)) {
|
|
301
|
-
kittyReceived = true;
|
|
302
|
-
kittyProtocol = true;
|
|
303
|
-
}
|
|
304
|
-
// Check for modifyOtherKeys support
|
|
305
|
-
if (!modifyOtherKeysReceived) {
|
|
306
|
-
var match = buffer.match(term_features_js_1.ModifyOtherKeysFeature.responseRegex);
|
|
307
|
-
if (match) {
|
|
308
|
-
modifyOtherKeysReceived = true;
|
|
309
|
-
var level = parseInt(match[1], 10);
|
|
310
|
-
modifyOtherKeys = level >= 2;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
// Check for terminal name/version
|
|
314
|
-
if (!terminalNameReceived) {
|
|
315
|
-
var match = buffer.match(term_features_js_1.TerminalNameFeature.responseRegex);
|
|
316
|
-
if (match) {
|
|
317
|
-
terminalNameReceived = true;
|
|
318
|
-
terminalName = match[1];
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
// Device Attributes response acts as sentinel - finish when received
|
|
322
|
-
if (!deviceAttributesReceived) {
|
|
323
|
-
var match = buffer.match(term_features_js_1.DeviceAttributesFeature.responseRegex);
|
|
324
|
-
if (match) {
|
|
325
|
-
deviceAttributesReceived = true;
|
|
326
|
-
cleanup();
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
(_a = stdin === null || stdin === void 0 ? void 0 : stdin.on) === null || _a === void 0 ? void 0 : _a.call(stdin, "data", onData);
|
|
331
|
-
try {
|
|
332
|
-
stdout === null || stdout === void 0 ? void 0 : stdout.write(term_features_js_1.KittyFeature.query +
|
|
333
|
-
term_features_js_1.Osc11Feature.query +
|
|
334
|
-
term_features_js_1.TerminalNameFeature.query +
|
|
335
|
-
term_features_js_1.ModifyOtherKeysFeature.query +
|
|
336
|
-
term_features_js_1.DeviceAttributesFeature.query);
|
|
337
|
-
}
|
|
338
|
-
catch (_b) {
|
|
339
|
-
cleanup();
|
|
340
|
-
}
|
|
341
|
-
})];
|
|
342
|
-
});
|
|
284
|
+
};
|
|
285
|
+
stdin?.on?.("data", onData);
|
|
286
|
+
try {
|
|
287
|
+
stdout?.write(KittyFeature.query +
|
|
288
|
+
Osc11Feature.query +
|
|
289
|
+
TerminalNameFeature.query +
|
|
290
|
+
ModifyOtherKeysFeature.query +
|
|
291
|
+
DeviceAttributesFeature.query);
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
cleanup();
|
|
295
|
+
}
|
|
343
296
|
});
|
|
344
297
|
}
|
|
345
298
|
/**
|
|
@@ -360,6 +313,6 @@ function detectTermcap(stdin, stdout, timeout) {
|
|
|
360
313
|
*
|
|
361
314
|
* @internal
|
|
362
315
|
*/
|
|
363
|
-
function resetForTesting() {
|
|
316
|
+
export function resetForTesting() {
|
|
364
317
|
// No module-level state to reset in the new design
|
|
365
318
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* @fileoverview Terminal feature query definitions for capability detection.
|
|
4
3
|
*
|
|
@@ -23,13 +22,11 @@
|
|
|
23
22
|
*
|
|
24
23
|
* @packageDocumentation
|
|
25
24
|
*/
|
|
26
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
-
exports.ModifyOtherKeysFeature = exports.DeviceAttributesFeature = exports.TerminalNameFeature = exports.Osc11Feature = exports.KittyFeature = void 0;
|
|
28
25
|
/**
|
|
29
26
|
* Escape character constant used in ANSI escape sequences.
|
|
30
27
|
* @internal
|
|
31
28
|
*/
|
|
32
|
-
|
|
29
|
+
const ESC = "\x1b";
|
|
33
30
|
/**
|
|
34
31
|
* Kitty Keyboard Protocol feature definition.
|
|
35
32
|
*
|
|
@@ -60,9 +57,9 @@ var ESC = "\x1b";
|
|
|
60
57
|
*
|
|
61
58
|
* @see https://sw.kovidgoyal.net/kitty/keyboard-protocol/
|
|
62
59
|
*/
|
|
63
|
-
|
|
64
|
-
query:
|
|
65
|
-
responseRegex: new RegExp(
|
|
60
|
+
export const KittyFeature = {
|
|
61
|
+
query: `${ESC}[?u`,
|
|
62
|
+
responseRegex: new RegExp(`${ESC}\\[\\?(\\d+)u`),
|
|
66
63
|
};
|
|
67
64
|
/**
|
|
68
65
|
* Background Color detection feature (OSC 11).
|
|
@@ -95,9 +92,9 @@ exports.KittyFeature = {
|
|
|
95
92
|
*
|
|
96
93
|
* @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands
|
|
97
94
|
*/
|
|
98
|
-
|
|
99
|
-
query:
|
|
100
|
-
responseRegex: new RegExp(
|
|
95
|
+
export const Osc11Feature = {
|
|
96
|
+
query: `${ESC}]11;?${ESC}\\`,
|
|
97
|
+
responseRegex: new RegExp(`${ESC}\\]11;rgb:([0-9a-fA-F]{1,4})\\/([0-9a-fA-F]{1,4})\\/([0-9a-fA-F]{1,4})(${ESC}\\\\|\\x07)?`),
|
|
101
98
|
};
|
|
102
99
|
/**
|
|
103
100
|
* Terminal Name detection feature (XTVERSION).
|
|
@@ -130,9 +127,9 @@ exports.Osc11Feature = {
|
|
|
130
127
|
*
|
|
131
128
|
* @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-PC-Style-Function-Keys
|
|
132
129
|
*/
|
|
133
|
-
|
|
134
|
-
query:
|
|
135
|
-
responseRegex: new RegExp(
|
|
130
|
+
export const TerminalNameFeature = {
|
|
131
|
+
query: `${ESC}[>q`,
|
|
132
|
+
responseRegex: new RegExp(`${ESC}P>\\|(.+?)(${ESC}\\\\|\\x07)`),
|
|
136
133
|
};
|
|
137
134
|
/**
|
|
138
135
|
* Device Attributes detection feature (Primary DA).
|
|
@@ -162,9 +159,9 @@ exports.TerminalNameFeature = {
|
|
|
162
159
|
*
|
|
163
160
|
* @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Device-Status-Report
|
|
164
161
|
*/
|
|
165
|
-
|
|
166
|
-
query:
|
|
167
|
-
responseRegex: new RegExp(
|
|
162
|
+
export const DeviceAttributesFeature = {
|
|
163
|
+
query: `${ESC}[c`,
|
|
164
|
+
responseRegex: new RegExp(`${ESC}\\[\\?(\\d+)(;\\d+)*c`),
|
|
168
165
|
};
|
|
169
166
|
/**
|
|
170
167
|
* Modify Other Keys feature detection.
|
|
@@ -202,7 +199,7 @@ exports.DeviceAttributesFeature = {
|
|
|
202
199
|
*
|
|
203
200
|
* @see https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-Desktop-Notification
|
|
204
201
|
*/
|
|
205
|
-
|
|
206
|
-
query:
|
|
207
|
-
responseRegex: new RegExp(
|
|
202
|
+
export const ModifyOtherKeysFeature = {
|
|
203
|
+
query: `${ESC}[>4;?m`,
|
|
204
|
+
responseRegex: new RegExp(`${ESC}\\[>4;(\\d+)m`),
|
|
208
205
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinky-termcap",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Terminal capability detection for Tinky - React hooks for Kitty protocol, background color, terminal name detection",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"terminal",
|
|
@@ -44,10 +44,13 @@
|
|
|
44
44
|
"@commitlint/cli": "^20.3.0",
|
|
45
45
|
"@commitlint/config-conventional": "^20.3.0",
|
|
46
46
|
"@semantic-release/changelog": "^6.0.3",
|
|
47
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
47
48
|
"@semantic-release/git": "^10.0.1",
|
|
48
|
-
"@semantic-release/github": "^12.0.
|
|
49
|
+
"@semantic-release/github": "^12.0.2",
|
|
49
50
|
"@semantic-release/npm": "^13.1.3",
|
|
51
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
50
52
|
"@types/bun": "^1.3.6",
|
|
53
|
+
"conventional-changelog-conventionalcommits": "^9.1.0",
|
|
51
54
|
"@types/react": "^19.2.8",
|
|
52
55
|
"@types/react-dom": "^19.2.3",
|
|
53
56
|
"eslint": "^9.39.2",
|
|
@@ -57,6 +60,7 @@
|
|
|
57
60
|
"lint-staged": "^16.2.7",
|
|
58
61
|
"prettier": "^3.7.4",
|
|
59
62
|
"react": "^19.2.3",
|
|
63
|
+
"semantic-release": "^25.0.2",
|
|
60
64
|
"react-dom": "^19.2.3",
|
|
61
65
|
"typedoc": "^0.28.16",
|
|
62
66
|
"typedoc-plugin-markdown": "^4.9.0",
|