terminfo.dev 1.4.0 → 1.5.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/package.json +1 -1
- package/src/detect.ts +20 -6
- package/src/index.ts +4 -14
- package/src/tty.ts +22 -0
package/package.json
CHANGED
package/src/detect.ts
CHANGED
|
@@ -52,15 +52,19 @@ export function detectTerminal(): TerminalInfo {
|
|
|
52
52
|
let name = "unknown"
|
|
53
53
|
let version = ""
|
|
54
54
|
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
break
|
|
55
|
+
// On macOS, __CFBundleIdentifier is the most reliable — set by the actual running app
|
|
56
|
+
const bundleId = process.env.__CFBundleIdentifier
|
|
57
|
+
if (bundleId && os === "macos") {
|
|
58
|
+
for (const [termName, bid] of Object.entries(BUNDLE_IDS)) {
|
|
59
|
+
if (bundleId === bid) { name = termName; break }
|
|
60
|
+
}
|
|
61
|
+
// If bundle ID didn't match known terminals, use it as-is
|
|
62
|
+
if (name === "unknown" && bundleId) {
|
|
63
|
+
name = bundleId.split(".").pop() ?? bundleId
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
// Check $TERM_PROGRAM
|
|
67
|
+
// Check $TERM_PROGRAM (more reliable than env var detectors for cross-app scenarios)
|
|
64
68
|
if (name === "unknown") {
|
|
65
69
|
const termProgram = process.env.TERM_PROGRAM
|
|
66
70
|
if (termProgram) {
|
|
@@ -69,6 +73,16 @@ export function detectTerminal(): TerminalInfo {
|
|
|
69
73
|
}
|
|
70
74
|
}
|
|
71
75
|
|
|
76
|
+
// Check specific env vars (may be inherited from parent, so lower priority)
|
|
77
|
+
if (name === "unknown") {
|
|
78
|
+
for (const { env, name: n } of ENV_DETECTORS) {
|
|
79
|
+
if (process.env[env]) {
|
|
80
|
+
name = n
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
72
86
|
// Check $TERMINAL_EMULATOR (Linux)
|
|
73
87
|
if (name === "unknown") {
|
|
74
88
|
const termEmu = process.env.TERMINAL_EMULATOR
|
package/src/index.ts
CHANGED
|
@@ -18,7 +18,7 @@ import { dirname, join } from "node:path"
|
|
|
18
18
|
import { fileURLToPath } from "node:url"
|
|
19
19
|
import { detectTerminal } from "./detect.ts"
|
|
20
20
|
import { ALL_PROBES } from "./probes/index.ts"
|
|
21
|
-
import { withRawMode } from "./tty.ts"
|
|
21
|
+
import { withRawMode, drainStdin } from "./tty.ts"
|
|
22
22
|
import { submitResults } from "./submit.ts"
|
|
23
23
|
|
|
24
24
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
@@ -76,21 +76,11 @@ async function runProbes(): Promise<ProbeResults> {
|
|
|
76
76
|
notes[probe.id] = `error: ${err instanceof Error ? err.message : String(err)}`
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
// Drain all pending responses before exiting alt screen (still in raw mode)
|
|
80
|
+
await drainStdin(500)
|
|
79
81
|
process.stdout.write("\x1b[?1049l")
|
|
80
82
|
})
|
|
81
83
|
|
|
82
|
-
// Drain any late-arriving escape sequence responses before output
|
|
83
|
-
await new Promise<void>((resolve) => {
|
|
84
|
-
process.stdin.resume()
|
|
85
|
-
const timer = setTimeout(() => {
|
|
86
|
-
process.stdin.pause()
|
|
87
|
-
process.stdin.removeAllListeners("readable")
|
|
88
|
-
resolve()
|
|
89
|
-
}, 100)
|
|
90
|
-
process.stdin.on("readable", () => { while (process.stdin.read() !== null) {} })
|
|
91
|
-
timer.unref()
|
|
92
|
-
})
|
|
93
|
-
|
|
94
84
|
return { terminal, results, notes, responses, passed, total: ALL_PROBES.length }
|
|
95
85
|
}
|
|
96
86
|
|
|
@@ -197,7 +187,7 @@ program
|
|
|
197
187
|
notes: data.notes,
|
|
198
188
|
responses: data.responses,
|
|
199
189
|
generated: new Date().toISOString(),
|
|
200
|
-
cliVersion: "1.
|
|
190
|
+
cliVersion: "1.5.0",
|
|
201
191
|
probeCount: ALL_PROBES.length,
|
|
202
192
|
})
|
|
203
193
|
if (url) {
|
package/src/tty.ts
CHANGED
|
@@ -89,6 +89,28 @@ export async function queryMode(modeNumber: number): Promise<"set" | "reset" | "
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Drain all pending bytes from stdin (late-arriving escape sequence responses).
|
|
94
|
+
* Waits up to `ms` milliseconds for bytes to stop arriving.
|
|
95
|
+
*/
|
|
96
|
+
export async function drainStdin(ms = 300): Promise<void> {
|
|
97
|
+
return new Promise((resolve) => {
|
|
98
|
+
if (!process.stdin.readable) { resolve(); return }
|
|
99
|
+
process.stdin.resume()
|
|
100
|
+
let timer = setTimeout(done, ms)
|
|
101
|
+
function onData() {
|
|
102
|
+
while (process.stdin.read() !== null) {} // discard
|
|
103
|
+
clearTimeout(timer)
|
|
104
|
+
timer = setTimeout(done, ms) // reset timer on each new data
|
|
105
|
+
}
|
|
106
|
+
function done() {
|
|
107
|
+
process.stdin.removeListener("readable", onData)
|
|
108
|
+
resolve()
|
|
109
|
+
}
|
|
110
|
+
process.stdin.on("readable", onData)
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
92
114
|
/**
|
|
93
115
|
* Run a function with stdin in raw mode.
|
|
94
116
|
* Restores original mode on exit.
|