termcut 0.2.2 → 0.3.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/src/themes.ts CHANGED
@@ -1,6 +1,11 @@
1
+ import generatedJson from "./themes.generated.json";
1
2
  import type { Theme, ThemeName } from "./types";
2
3
 
3
- export const themes: Record<ThemeName, Theme> = {
4
+ /**
5
+ * Hand-maintained themes. These stay byte-stable across releases (demos rendered with them must not drift),
6
+ * and take precedence over the generated bundle when names collide.
7
+ */
8
+ export const builtinThemes = {
4
9
  "catppuccin-mocha": {
5
10
  name: "catppuccin-mocha",
6
11
  background: "#1e1e2e",
@@ -121,16 +126,40 @@ export const themes: Record<ThemeName, Theme> = {
121
126
  brightCyan: "#56b6c2",
122
127
  brightWhite: "#ffffff",
123
128
  },
124
- };
129
+ } satisfies Record<string, Theme>;
125
130
 
126
- export const themeNames = Object.keys(themes) as ThemeName[];
131
+ export type BuiltinThemeName = keyof typeof builtinThemes;
132
+
133
+ /** The Ghostty theme collection (mbadolato/iTerm2-Color-Schemes, MIT), generated by scripts/build-themes.ts. */
134
+ const generated = generatedJson as Record<string, Theme>;
135
+
136
+ /** All themes by slug: the generated bundle, with the built-ins overriding colliding names. */
137
+ export const themes: Record<string, Theme> = { ...generated, ...builtinThemes };
138
+
139
+ export const themeNames: string[] = Object.keys(themes).sort();
140
+
141
+ /** "Catppuccin Mocha" → "catppuccin-mocha" (also accepts slugs, spaces, underscores, any case). */
142
+ export function themeSlug(name: string): string {
143
+ return name
144
+ .toLowerCase()
145
+ .replace(/[^a-z0-9]+/g, "-")
146
+ .replace(/^-+|-+$/g, "");
147
+ }
148
+
149
+ export function findThemes(query: string): string[] {
150
+ const q = themeSlug(query);
151
+ return themeNames.filter((n) => n.includes(q));
152
+ }
127
153
 
128
154
  export function resolveTheme(theme: ThemeName | Theme | undefined): Theme {
129
- if (!theme) return themes["catppuccin-mocha"];
155
+ if (!theme) return builtinThemes["catppuccin-mocha"];
130
156
  if (typeof theme === "string") {
131
- const found = themes[theme];
157
+ const found = themes[themeSlug(theme)];
132
158
  if (!found) {
133
- throw new Error(`Unknown theme "${theme}". Available: ${themeNames.join(", ")}`);
159
+ const near = findThemes(theme.split(/[\s-]+/)[0] ?? theme).slice(0, 5);
160
+ throw new Error(
161
+ `Unknown theme "${theme}". ${near.length ? `Did you mean: ${near.join(", ")}?` : ""} Run \`tcut themes [query]\` to list all ${themeNames.length}.`.trim(),
162
+ );
134
163
  }
135
164
  return found;
136
165
  }
package/src/types.ts CHANGED
@@ -23,12 +23,11 @@ export interface Theme {
23
23
  brightWhite: string;
24
24
  }
25
25
 
26
- export type ThemeName =
27
- | "catppuccin-mocha"
28
- | "dracula"
29
- | "github-dark"
30
- | "tokyo-night"
31
- | "one-dark";
26
+ /**
27
+ * A theme name: one of the built-ins (autocompleted) or any of the ~600 Ghostty themes, matched case- and
28
+ * punctuation-insensitively ("Catppuccin Mocha", "catppuccin-mocha", "GitHub Dark" …). `tcut themes` lists them.
29
+ */
30
+ export type ThemeName = "catppuccin-mocha" | "dracula" | "github-dark" | "tokyo-night" | "one-dark" | (string & {});
32
31
 
33
32
  export type ShellName = "bash" | "zsh" | "fish" | "sh";
34
33
  /** Terminal emulator core: libghostty (full VT, answers queries) or wterm's lite Zig core (faster, fewer features). */