terminfo.dev 0.6.0 → 0.7.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +39 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "terminfo.dev",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Test your terminal's feature support and contribute to terminfo.dev",
5
5
  "keywords": [
6
6
  "ansi",
package/src/index.ts CHANGED
@@ -13,11 +13,42 @@
13
13
  * ```
14
14
  */
15
15
 
16
+ import { readFileSync } from "node:fs"
17
+ import { dirname, join } from "node:path"
18
+ import { fileURLToPath } from "node:url"
16
19
  import { detectTerminal } from "./detect.ts"
17
20
  import { ALL_PROBES } from "./probes/index.ts"
18
21
  import { withRawMode } from "./tty.ts"
19
22
  import { submitResults } from "./submit.ts"
20
23
 
24
+ const __dirname = dirname(fileURLToPath(import.meta.url))
25
+
26
+ /** Load feature slugs from features.json for OSC 8 hyperlinks */
27
+ function loadFeatureSlugs(): Record<string, string> {
28
+ // Try repo-local path first, then npm-installed path
29
+ const candidates = [
30
+ join(__dirname, "..", "..", "features.json"), // repo: cli/src/ -> features.json
31
+ join(__dirname, "..", "..", "..", "features.json"), // npm: node_modules/terminfo.dev/src/ -> features.json
32
+ ]
33
+ for (const path of candidates) {
34
+ try {
35
+ const raw = JSON.parse(readFileSync(path, "utf-8"))
36
+ delete raw.$comment
37
+ const slugs: Record<string, string> = {}
38
+ for (const [id, entry] of Object.entries(raw) as [string, any][]) {
39
+ slugs[id] = entry.slug ?? id.replaceAll(".", "-")
40
+ }
41
+ return slugs
42
+ } catch {}
43
+ }
44
+ return {} // fallback: featureSlug() will use id.replaceAll(".", "-")
45
+ }
46
+
47
+ /** OSC 8 hyperlink — clickable link in supporting terminals */
48
+ function link(url: string, text: string): string {
49
+ return `\x1b]8;;${url}\x07${text}\x1b]8;;\x07`
50
+ }
51
+
21
52
  interface ResultEntry {
22
53
  terminal: string
23
54
  terminalVersion: string
@@ -106,7 +137,8 @@ async function main() {
106
137
  // Display results
107
138
  console.log(`\n\x1b[1mResults: ${passed}/${total} (${pct}%)\x1b[0m\n`)
108
139
 
109
- // Show categories
140
+ // Show categories with OSC 8 hyperlinks
141
+ const slugs = loadFeatureSlugs()
110
142
  const categories = new Map<string, Array<{ id: string; name: string; pass: boolean; note?: string }>>()
111
143
  for (const probe of ALL_PROBES) {
112
144
  const cat = probe.id.split(".")[0]!
@@ -122,11 +154,15 @@ async function main() {
122
154
  for (const [cat, probes] of categories) {
123
155
  const catPassed = probes.filter((p) => p.pass).length
124
156
  const color = catPassed === probes.length ? "\x1b[32m" : catPassed > 0 ? "\x1b[33m" : "\x1b[31m"
125
- console.log(`${color}${cat}\x1b[0m (${catPassed}/${probes.length})`)
157
+ const catLink = link(`https://terminfo.dev/${cat}`, cat)
158
+ console.log(`${color}${catLink}\x1b[0m (${catPassed}/${probes.length})`)
126
159
  for (const p of probes) {
127
160
  const icon = p.pass ? "\x1b[32m✓\x1b[0m" : "\x1b[31m✗\x1b[0m"
128
161
  const note = p.note ? ` \x1b[2m— ${p.note}\x1b[0m` : ""
129
- console.log(` ${icon} ${p.name}${note}`)
162
+ const slug = slugs[p.id] ?? p.id.replaceAll(".", "-")
163
+ const cat = p.id.split(".")[0]!
164
+ const featureLink = link(`https://terminfo.dev/${cat}/${slug}`, p.name)
165
+ console.log(` ${icon} ${featureLink}${note}`)
130
166
  }
131
167
  }
132
168