@carlesandres/house 0.4.13 → 0.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/CHANGELOG.md +32 -2
- package/README.md +10 -8
- package/dist/bin.js +92 -0
- package/dist/index.js +10005 -0
- package/package.json +15 -3
- package/src/Browser.tsx +0 -1210
- package/src/CommandPalette.tsx +0 -214
- package/src/Footer.tsx +0 -258
- package/src/Header.tsx +0 -71
- package/src/PromptRow.tsx +0 -51
- package/src/Spinner.tsx +0 -39
- package/src/StatusIndicator.tsx +0 -55
- package/src/StatusPopover.tsx +0 -166
- package/src/brand.ts +0 -7
- package/src/cli/argv.ts +0 -179
- package/src/commands/buildCommands.ts +0 -98
- package/src/commands/paletteOnlyCommands.ts +0 -27
- package/src/commands/score.ts +0 -78
- package/src/commands/types.ts +0 -26
- package/src/config/load.ts +0 -381
- package/src/config/save.ts +0 -95
- package/src/discovery/filter.ts +0 -148
- package/src/discovery/show.ts +0 -48
- package/src/discovery/walk.ts +0 -209
- package/src/index.tsx +0 -464
- package/src/io/clipboard.ts +0 -53
- package/src/io/editor.ts +0 -162
- package/src/io/readFile.ts +0 -14
- package/src/keymap/browser.ts +0 -335
- package/src/keymap/displayKey.ts +0 -17
- package/src/keymap/keymap.ts +0 -95
- package/src/layout/resolve.ts +0 -52
- package/src/layout/sidebarEmptyState.ts +0 -7
- package/src/layout/sidebarRow.ts +0 -69
- package/src/markdown/frontmatter.ts +0 -62
- package/src/serve/css.ts +0 -120
- package/src/serve/openBrowser.ts +0 -19
- package/src/serve/render.ts +0 -56
- package/src/serve/server.ts +0 -166
- package/src/theme/atom.ts +0 -23
- package/src/theme/colors.ts +0 -86
- package/src/theme/loader.ts +0 -110
- package/src/theme/registry.ts +0 -12
- package/src/theme/resolve.ts +0 -168
- package/src/theme/themes/aura.json +0 -58
- package/src/theme/themes/ayu.json +0 -69
- package/src/theme/themes/carbonfox.json +0 -201
- package/src/theme/themes/catppuccin-frappe.json +0 -186
- package/src/theme/themes/catppuccin-macchiato.json +0 -186
- package/src/theme/themes/catppuccin.json +0 -212
- package/src/theme/themes/cobalt2.json +0 -181
- package/src/theme/themes/cursor.json +0 -202
- package/src/theme/themes/dracula.json +0 -172
- package/src/theme/themes/everforest.json +0 -194
- package/src/theme/themes/flexoki.json +0 -190
- package/src/theme/themes/github.json +0 -186
- package/src/theme/themes/gruvbox.json +0 -195
- package/src/theme/themes/kanagawa.json +0 -180
- package/src/theme/themes/lucent-orng.json +0 -186
- package/src/theme/themes/material.json +0 -188
- package/src/theme/themes/matrix.json +0 -180
- package/src/theme/themes/mercury.json +0 -198
- package/src/theme/themes/monokai.json +0 -174
- package/src/theme/themes/nightowl.json +0 -174
- package/src/theme/themes/nord.json +0 -176
- package/src/theme/themes/one-dark.json +0 -184
- package/src/theme/themes/opencode.json +0 -198
- package/src/theme/themes/orng.json +0 -202
- package/src/theme/themes/osaka-jade.json +0 -193
- package/src/theme/themes/palenight.json +0 -175
- package/src/theme/themes/rosepine.json +0 -187
- package/src/theme/themes/solarized.json +0 -180
- package/src/theme/themes/synthwave84.json +0 -179
- package/src/theme/themes/tokyonight.json +0 -196
- package/src/theme/themes/vercel.json +0 -198
- package/src/theme/themes/vesper.json +0 -171
- package/src/theme/themes/zenburn.json +0 -176
- package/src/theme/types.ts +0 -115
- package/src/tips.ts +0 -88
- package/src/ui/middleTruncate.ts +0 -27
- package/src/update/cache.ts +0 -77
- package/src/update/check.ts +0 -165
- package/src/update/compare.ts +0 -41
- package/src/update/notice.ts +0 -29
- package/src/update/runtime.ts +0 -48
- package/src/update/useUpdateNotice.ts +0 -24
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"defs": {
|
|
3
|
-
"vesperBg": "#101010",
|
|
4
|
-
"vesperFg": "#FFF",
|
|
5
|
-
"vesperComment": "#8b8b8b",
|
|
6
|
-
"vesperKeyword": "#A0A0A0",
|
|
7
|
-
"vesperFunction": "#FFC799",
|
|
8
|
-
"vesperString": "#99FFE4",
|
|
9
|
-
"vesperNumber": "#FFC799",
|
|
10
|
-
"vesperError": "#FF8080",
|
|
11
|
-
"vesperWarning": "#FFC799",
|
|
12
|
-
"vesperSuccess": "#99FFE4",
|
|
13
|
-
"vesperMuted": "#A0A0A0"
|
|
14
|
-
},
|
|
15
|
-
"theme": {
|
|
16
|
-
"primary": {
|
|
17
|
-
"dark": "#FFC799",
|
|
18
|
-
"light": "#FFC799"
|
|
19
|
-
},
|
|
20
|
-
"secondary": {
|
|
21
|
-
"dark": "#99FFE4",
|
|
22
|
-
"light": "#99FFE4"
|
|
23
|
-
},
|
|
24
|
-
"accent": {
|
|
25
|
-
"dark": "#FFC799",
|
|
26
|
-
"light": "#FFC799"
|
|
27
|
-
},
|
|
28
|
-
"error": {
|
|
29
|
-
"dark": "vesperError",
|
|
30
|
-
"light": "vesperError"
|
|
31
|
-
},
|
|
32
|
-
"warning": {
|
|
33
|
-
"dark": "vesperWarning",
|
|
34
|
-
"light": "vesperWarning"
|
|
35
|
-
},
|
|
36
|
-
"success": {
|
|
37
|
-
"dark": "vesperSuccess",
|
|
38
|
-
"light": "vesperSuccess"
|
|
39
|
-
},
|
|
40
|
-
"info": {
|
|
41
|
-
"dark": "#FFC799",
|
|
42
|
-
"light": "#FFC799"
|
|
43
|
-
},
|
|
44
|
-
"text": {
|
|
45
|
-
"dark": "vesperFg",
|
|
46
|
-
"light": "vesperBg"
|
|
47
|
-
},
|
|
48
|
-
"textMuted": {
|
|
49
|
-
"dark": "vesperMuted",
|
|
50
|
-
"light": "vesperMuted"
|
|
51
|
-
},
|
|
52
|
-
"background": {
|
|
53
|
-
"dark": "vesperBg",
|
|
54
|
-
"light": "#FFF"
|
|
55
|
-
},
|
|
56
|
-
"backgroundPanel": {
|
|
57
|
-
"dark": "#151515",
|
|
58
|
-
"light": "#F0F0F0"
|
|
59
|
-
},
|
|
60
|
-
"backgroundElement": {
|
|
61
|
-
"dark": "#282828",
|
|
62
|
-
"light": "#E0E0E0"
|
|
63
|
-
},
|
|
64
|
-
"border": {
|
|
65
|
-
"dark": "#282828",
|
|
66
|
-
"light": "#D0D0D0"
|
|
67
|
-
},
|
|
68
|
-
"borderActive": {
|
|
69
|
-
"dark": "#FFC799",
|
|
70
|
-
"light": "#FFC799"
|
|
71
|
-
},
|
|
72
|
-
"borderSubtle": {
|
|
73
|
-
"dark": "#1C1C1C",
|
|
74
|
-
"light": "#E8E8E8"
|
|
75
|
-
},
|
|
76
|
-
"markdownText": {
|
|
77
|
-
"dark": "vesperFg",
|
|
78
|
-
"light": "vesperBg"
|
|
79
|
-
},
|
|
80
|
-
"markdownHeading": {
|
|
81
|
-
"dark": "#FFC799",
|
|
82
|
-
"light": "#FFC799"
|
|
83
|
-
},
|
|
84
|
-
"markdownLink": {
|
|
85
|
-
"dark": "#FFC799",
|
|
86
|
-
"light": "#FFC799"
|
|
87
|
-
},
|
|
88
|
-
"markdownLinkText": {
|
|
89
|
-
"dark": "vesperMuted",
|
|
90
|
-
"light": "vesperMuted"
|
|
91
|
-
},
|
|
92
|
-
"markdownCode": {
|
|
93
|
-
"dark": "vesperMuted",
|
|
94
|
-
"light": "vesperMuted"
|
|
95
|
-
},
|
|
96
|
-
"markdownBlockQuote": {
|
|
97
|
-
"dark": "vesperFg",
|
|
98
|
-
"light": "vesperBg"
|
|
99
|
-
},
|
|
100
|
-
"markdownEmph": {
|
|
101
|
-
"dark": "vesperFg",
|
|
102
|
-
"light": "vesperBg"
|
|
103
|
-
},
|
|
104
|
-
"markdownStrong": {
|
|
105
|
-
"dark": "vesperFg",
|
|
106
|
-
"light": "vesperBg"
|
|
107
|
-
},
|
|
108
|
-
"markdownHorizontalRule": {
|
|
109
|
-
"dark": "#65737E",
|
|
110
|
-
"light": "#65737E"
|
|
111
|
-
},
|
|
112
|
-
"markdownListItem": {
|
|
113
|
-
"dark": "vesperFg",
|
|
114
|
-
"light": "vesperBg"
|
|
115
|
-
},
|
|
116
|
-
"markdownListEnumeration": {
|
|
117
|
-
"dark": "vesperFg",
|
|
118
|
-
"light": "vesperBg"
|
|
119
|
-
},
|
|
120
|
-
"markdownImage": {
|
|
121
|
-
"dark": "#FFC799",
|
|
122
|
-
"light": "#FFC799"
|
|
123
|
-
},
|
|
124
|
-
"markdownImageText": {
|
|
125
|
-
"dark": "vesperMuted",
|
|
126
|
-
"light": "vesperMuted"
|
|
127
|
-
},
|
|
128
|
-
"markdownCodeBlock": {
|
|
129
|
-
"dark": "vesperFg",
|
|
130
|
-
"light": "vesperBg"
|
|
131
|
-
},
|
|
132
|
-
"syntaxComment": {
|
|
133
|
-
"dark": "vesperComment",
|
|
134
|
-
"light": "vesperComment"
|
|
135
|
-
},
|
|
136
|
-
"syntaxKeyword": {
|
|
137
|
-
"dark": "vesperKeyword",
|
|
138
|
-
"light": "vesperKeyword"
|
|
139
|
-
},
|
|
140
|
-
"syntaxFunction": {
|
|
141
|
-
"dark": "vesperFunction",
|
|
142
|
-
"light": "vesperFunction"
|
|
143
|
-
},
|
|
144
|
-
"syntaxVariable": {
|
|
145
|
-
"dark": "vesperFg",
|
|
146
|
-
"light": "vesperBg"
|
|
147
|
-
},
|
|
148
|
-
"syntaxString": {
|
|
149
|
-
"dark": "vesperString",
|
|
150
|
-
"light": "vesperString"
|
|
151
|
-
},
|
|
152
|
-
"syntaxNumber": {
|
|
153
|
-
"dark": "vesperNumber",
|
|
154
|
-
"light": "vesperNumber"
|
|
155
|
-
},
|
|
156
|
-
"syntaxType": {
|
|
157
|
-
"dark": "vesperFunction",
|
|
158
|
-
"light": "vesperFunction"
|
|
159
|
-
},
|
|
160
|
-
"syntaxOperator": {
|
|
161
|
-
"dark": "vesperKeyword",
|
|
162
|
-
"light": "vesperKeyword"
|
|
163
|
-
},
|
|
164
|
-
"syntaxPunctuation": {
|
|
165
|
-
"dark": "vesperFg",
|
|
166
|
-
"light": "vesperBg"
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
"name": "Vesper",
|
|
170
|
-
"$schema": "../../../schema/house-theme.schema.json"
|
|
171
|
-
}
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"defs": {
|
|
3
|
-
"bg": "#3f3f3f",
|
|
4
|
-
"bgAlt": "#4f4f4f",
|
|
5
|
-
"bgPanel": "#5f5f5f",
|
|
6
|
-
"fg": "#dcdccc",
|
|
7
|
-
"fgMuted": "#9f9f9f",
|
|
8
|
-
"red": "#cc9393",
|
|
9
|
-
"redBright": "#dca3a3",
|
|
10
|
-
"green": "#7f9f7f",
|
|
11
|
-
"greenBright": "#8fb28f",
|
|
12
|
-
"yellow": "#f0dfaf",
|
|
13
|
-
"yellowDim": "#e0cf9f",
|
|
14
|
-
"blue": "#8cd0d3",
|
|
15
|
-
"blueDim": "#7cb8bb",
|
|
16
|
-
"magenta": "#dc8cc3",
|
|
17
|
-
"cyan": "#93e0e3",
|
|
18
|
-
"orange": "#dfaf8f"
|
|
19
|
-
},
|
|
20
|
-
"theme": {
|
|
21
|
-
"primary": {
|
|
22
|
-
"dark": "blue",
|
|
23
|
-
"light": "#5f7f8f"
|
|
24
|
-
},
|
|
25
|
-
"secondary": {
|
|
26
|
-
"dark": "magenta",
|
|
27
|
-
"light": "#8f5f8f"
|
|
28
|
-
},
|
|
29
|
-
"accent": {
|
|
30
|
-
"dark": "cyan",
|
|
31
|
-
"light": "#5f8f8f"
|
|
32
|
-
},
|
|
33
|
-
"error": {
|
|
34
|
-
"dark": "red",
|
|
35
|
-
"light": "#8f5f5f"
|
|
36
|
-
},
|
|
37
|
-
"warning": {
|
|
38
|
-
"dark": "yellow",
|
|
39
|
-
"light": "#8f8f5f"
|
|
40
|
-
},
|
|
41
|
-
"success": {
|
|
42
|
-
"dark": "green",
|
|
43
|
-
"light": "#5f8f5f"
|
|
44
|
-
},
|
|
45
|
-
"info": {
|
|
46
|
-
"dark": "orange",
|
|
47
|
-
"light": "#8f7f5f"
|
|
48
|
-
},
|
|
49
|
-
"text": {
|
|
50
|
-
"dark": "fg",
|
|
51
|
-
"light": "#3f3f3f"
|
|
52
|
-
},
|
|
53
|
-
"textMuted": {
|
|
54
|
-
"dark": "fgMuted",
|
|
55
|
-
"light": "#6f6f6f"
|
|
56
|
-
},
|
|
57
|
-
"background": {
|
|
58
|
-
"dark": "bg",
|
|
59
|
-
"light": "#ffffef"
|
|
60
|
-
},
|
|
61
|
-
"backgroundPanel": {
|
|
62
|
-
"dark": "bgAlt",
|
|
63
|
-
"light": "#f5f5e5"
|
|
64
|
-
},
|
|
65
|
-
"backgroundElement": {
|
|
66
|
-
"dark": "bgPanel",
|
|
67
|
-
"light": "#ebebdb"
|
|
68
|
-
},
|
|
69
|
-
"border": {
|
|
70
|
-
"dark": "#5f5f5f",
|
|
71
|
-
"light": "#d0d0c0"
|
|
72
|
-
},
|
|
73
|
-
"borderActive": {
|
|
74
|
-
"dark": "blue",
|
|
75
|
-
"light": "#5f7f8f"
|
|
76
|
-
},
|
|
77
|
-
"borderSubtle": {
|
|
78
|
-
"dark": "#4f4f4f",
|
|
79
|
-
"light": "#e0e0d0"
|
|
80
|
-
},
|
|
81
|
-
"markdownText": {
|
|
82
|
-
"dark": "fg",
|
|
83
|
-
"light": "#3f3f3f"
|
|
84
|
-
},
|
|
85
|
-
"markdownHeading": {
|
|
86
|
-
"dark": "yellow",
|
|
87
|
-
"light": "#8f8f5f"
|
|
88
|
-
},
|
|
89
|
-
"markdownLink": {
|
|
90
|
-
"dark": "blue",
|
|
91
|
-
"light": "#5f7f8f"
|
|
92
|
-
},
|
|
93
|
-
"markdownLinkText": {
|
|
94
|
-
"dark": "cyan",
|
|
95
|
-
"light": "#5f8f8f"
|
|
96
|
-
},
|
|
97
|
-
"markdownCode": {
|
|
98
|
-
"dark": "green",
|
|
99
|
-
"light": "#5f8f5f"
|
|
100
|
-
},
|
|
101
|
-
"markdownBlockQuote": {
|
|
102
|
-
"dark": "fgMuted",
|
|
103
|
-
"light": "#6f6f6f"
|
|
104
|
-
},
|
|
105
|
-
"markdownEmph": {
|
|
106
|
-
"dark": "yellowDim",
|
|
107
|
-
"light": "#8f8f5f"
|
|
108
|
-
},
|
|
109
|
-
"markdownStrong": {
|
|
110
|
-
"dark": "orange",
|
|
111
|
-
"light": "#8f7f5f"
|
|
112
|
-
},
|
|
113
|
-
"markdownHorizontalRule": {
|
|
114
|
-
"dark": "fgMuted",
|
|
115
|
-
"light": "#6f6f6f"
|
|
116
|
-
},
|
|
117
|
-
"markdownListItem": {
|
|
118
|
-
"dark": "blue",
|
|
119
|
-
"light": "#5f7f8f"
|
|
120
|
-
},
|
|
121
|
-
"markdownListEnumeration": {
|
|
122
|
-
"dark": "cyan",
|
|
123
|
-
"light": "#5f8f8f"
|
|
124
|
-
},
|
|
125
|
-
"markdownImage": {
|
|
126
|
-
"dark": "blue",
|
|
127
|
-
"light": "#5f7f8f"
|
|
128
|
-
},
|
|
129
|
-
"markdownImageText": {
|
|
130
|
-
"dark": "cyan",
|
|
131
|
-
"light": "#5f8f8f"
|
|
132
|
-
},
|
|
133
|
-
"markdownCodeBlock": {
|
|
134
|
-
"dark": "fg",
|
|
135
|
-
"light": "#3f3f3f"
|
|
136
|
-
},
|
|
137
|
-
"syntaxComment": {
|
|
138
|
-
"dark": "#7f9f7f",
|
|
139
|
-
"light": "#5f7f5f"
|
|
140
|
-
},
|
|
141
|
-
"syntaxKeyword": {
|
|
142
|
-
"dark": "yellow",
|
|
143
|
-
"light": "#8f8f5f"
|
|
144
|
-
},
|
|
145
|
-
"syntaxFunction": {
|
|
146
|
-
"dark": "blue",
|
|
147
|
-
"light": "#5f7f8f"
|
|
148
|
-
},
|
|
149
|
-
"syntaxVariable": {
|
|
150
|
-
"dark": "fg",
|
|
151
|
-
"light": "#3f3f3f"
|
|
152
|
-
},
|
|
153
|
-
"syntaxString": {
|
|
154
|
-
"dark": "red",
|
|
155
|
-
"light": "#8f5f5f"
|
|
156
|
-
},
|
|
157
|
-
"syntaxNumber": {
|
|
158
|
-
"dark": "greenBright",
|
|
159
|
-
"light": "#5f8f5f"
|
|
160
|
-
},
|
|
161
|
-
"syntaxType": {
|
|
162
|
-
"dark": "cyan",
|
|
163
|
-
"light": "#5f8f8f"
|
|
164
|
-
},
|
|
165
|
-
"syntaxOperator": {
|
|
166
|
-
"dark": "yellow",
|
|
167
|
-
"light": "#8f8f5f"
|
|
168
|
-
},
|
|
169
|
-
"syntaxPunctuation": {
|
|
170
|
-
"dark": "fg",
|
|
171
|
-
"light": "#3f3f3f"
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
"name": "Zenburn",
|
|
175
|
-
"$schema": "../../../schema/house-theme.schema.json"
|
|
176
|
-
}
|
package/src/theme/types.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import type { StyleDefinitionInput } from "@opentui/core"
|
|
2
|
-
|
|
3
|
-
export type HexColor = `#${string}`
|
|
4
|
-
export type RefName = string
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* A token's value. Either a literal hex (`"#abcdef"`), a reference to an
|
|
8
|
-
* entry in the theme's `defs` block (`"nord8"`), or a `{dark, light}`
|
|
9
|
-
* variant where each side is itself a hex or a defs ref.
|
|
10
|
-
*/
|
|
11
|
-
export type ColorValue = HexColor | RefName | { readonly dark: string; readonly light: string }
|
|
12
|
-
|
|
13
|
-
/** Light or dark mode selector. Each theme JSON pairs both. */
|
|
14
|
-
export type Tone = "dark" | "light"
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* The complete house token surface. Adapted from opencode's TUI theme
|
|
18
|
-
* (see reference/opencode/.../tui/context/theme/) by dropping the `diff*`
|
|
19
|
-
* cluster, `backgroundMenu`, and `thinkingOpacity` (none of which are
|
|
20
|
-
* reachable in a markdown reader).
|
|
21
|
-
*/
|
|
22
|
-
export interface ThemeTokens {
|
|
23
|
-
// UI semantics
|
|
24
|
-
readonly primary: ColorValue
|
|
25
|
-
readonly secondary: ColorValue
|
|
26
|
-
readonly accent: ColorValue
|
|
27
|
-
readonly error: ColorValue
|
|
28
|
-
readonly warning: ColorValue
|
|
29
|
-
readonly success: ColorValue
|
|
30
|
-
readonly info: ColorValue
|
|
31
|
-
readonly text: ColorValue
|
|
32
|
-
readonly textMuted: ColorValue
|
|
33
|
-
readonly selectedListItemText?: ColorValue
|
|
34
|
-
readonly background: ColorValue
|
|
35
|
-
readonly backgroundPanel: ColorValue
|
|
36
|
-
readonly backgroundElement: ColorValue
|
|
37
|
-
readonly border: ColorValue
|
|
38
|
-
readonly borderActive: ColorValue
|
|
39
|
-
readonly borderSubtle: ColorValue
|
|
40
|
-
// Markdown rendering
|
|
41
|
-
readonly markdownText: ColorValue
|
|
42
|
-
readonly markdownHeading: ColorValue
|
|
43
|
-
readonly markdownLink: ColorValue
|
|
44
|
-
readonly markdownLinkText: ColorValue
|
|
45
|
-
readonly markdownCode: ColorValue
|
|
46
|
-
readonly markdownBlockQuote: ColorValue
|
|
47
|
-
readonly markdownEmph: ColorValue
|
|
48
|
-
readonly markdownStrong: ColorValue
|
|
49
|
-
readonly markdownHorizontalRule: ColorValue
|
|
50
|
-
readonly markdownListItem: ColorValue
|
|
51
|
-
readonly markdownListEnumeration: ColorValue
|
|
52
|
-
readonly markdownImage: ColorValue
|
|
53
|
-
readonly markdownImageText: ColorValue
|
|
54
|
-
readonly markdownCodeBlock: ColorValue
|
|
55
|
-
// Fenced-code syntax
|
|
56
|
-
readonly syntaxComment: ColorValue
|
|
57
|
-
readonly syntaxKeyword: ColorValue
|
|
58
|
-
readonly syntaxFunction: ColorValue
|
|
59
|
-
readonly syntaxVariable: ColorValue
|
|
60
|
-
readonly syntaxString: ColorValue
|
|
61
|
-
readonly syntaxNumber: ColorValue
|
|
62
|
-
readonly syntaxType: ColorValue
|
|
63
|
-
readonly syntaxOperator: ColorValue
|
|
64
|
-
readonly syntaxPunctuation: ColorValue
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/** Raw on-disk shape for a theme JSON file. */
|
|
68
|
-
export interface ThemeJson {
|
|
69
|
-
readonly $schema?: string
|
|
70
|
-
readonly name?: string
|
|
71
|
-
readonly defs?: Record<string, string>
|
|
72
|
-
readonly theme: Partial<ThemeTokens>
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/** Token names that consumers may reference. */
|
|
76
|
-
export type TokenName = keyof ThemeTokens
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Flat record after `resolveTheme`: every token has a concrete `#rrggbb`
|
|
80
|
-
* value with the requested tone applied and defs refs resolved.
|
|
81
|
-
*/
|
|
82
|
-
export type ResolvedTheme = Readonly<Record<TokenName, HexColor>>
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* The flat color object consumed by Browser/HelpOverlay/index. Uses the
|
|
86
|
-
* OpenCode-aligned UI token names directly (`background`, `backgroundPanel`,
|
|
87
|
-
* `backgroundElement`, `borderSubtle`, `primary`, `secondary`, …). Values
|
|
88
|
-
* come from `colors.ts`'s adapter, which maps `ResolvedTheme` → this shape.
|
|
89
|
-
*/
|
|
90
|
-
export interface ColorPalette {
|
|
91
|
-
readonly background: string
|
|
92
|
-
readonly backgroundPanel: string
|
|
93
|
-
readonly backgroundElement: string
|
|
94
|
-
readonly text: string
|
|
95
|
-
readonly textMuted: string
|
|
96
|
-
readonly border: string
|
|
97
|
-
readonly borderActive: string
|
|
98
|
-
readonly borderSubtle: string
|
|
99
|
-
readonly selectedListItemText: string
|
|
100
|
-
readonly primary: string
|
|
101
|
-
readonly secondary: string
|
|
102
|
-
readonly accent: string
|
|
103
|
-
readonly error: string
|
|
104
|
-
readonly warning: string
|
|
105
|
-
readonly success: string
|
|
106
|
-
readonly info: string
|
|
107
|
-
readonly syntax: Record<string, StyleDefinitionInput>
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** Registry entry for a theme; what the loader returns. */
|
|
111
|
-
export interface ThemeDefinition {
|
|
112
|
-
readonly id: string
|
|
113
|
-
readonly name: string
|
|
114
|
-
readonly source: ThemeJson
|
|
115
|
-
}
|
package/src/tips.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { BrowserCtx } from "./keymap/browser.ts"
|
|
2
|
-
import type { KeyBinding } from "./keymap/keymap.ts"
|
|
3
|
-
import { displayKey } from "./keymap/displayKey.ts"
|
|
4
|
-
|
|
5
|
-
export interface TipLine {
|
|
6
|
-
readonly id: string
|
|
7
|
-
readonly text: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface TipDefinition {
|
|
11
|
-
readonly id: string
|
|
12
|
-
readonly bindingId?: string
|
|
13
|
-
readonly render: (parts: { readonly key: string | null }) => string
|
|
14
|
-
readonly when?: (ctx: BrowserCtx) => boolean
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const tipDefinitions: readonly TipDefinition[] = [
|
|
18
|
-
{
|
|
19
|
-
id: "filter.start",
|
|
20
|
-
bindingId: "filter.open",
|
|
21
|
-
render: ({ key }) => `Press ${key ?? "/"} to start filtering files by path.`,
|
|
22
|
-
when: (ctx) => ctx.filterQuery.length === 0 && !ctx.filterOpen,
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
id: "filter.resume",
|
|
26
|
-
bindingId: "filter.open",
|
|
27
|
-
render: ({ key }) => `Press ${key ?? "/"} to reopen the current filter and keep refining it.`,
|
|
28
|
-
when: (ctx) => ctx.filterQuery.length > 0 && !ctx.filterOpen,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
id: "filter.commit",
|
|
32
|
-
bindingId: "filter.open",
|
|
33
|
-
render: () => "Press Enter in the filter to open the selected match in the reader.",
|
|
34
|
-
when: (ctx) => ctx.filterQuery.length === 0,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
id: "filter.clear",
|
|
38
|
-
bindingId: "filter.clearOrOpen",
|
|
39
|
-
render: ({ key }) => `Press ${key ?? "ctrl+\\"} to clear the current filter and start over.`,
|
|
40
|
-
when: (ctx) => ctx.filterQuery.length > 0,
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
id: "filtered-navigation",
|
|
44
|
-
render: () => "Use [ and ] to move through files while the current filter stays applied.",
|
|
45
|
-
when: (ctx) => ctx.filterQuery.length > 0,
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: "focus.toggle",
|
|
49
|
-
bindingId: "focus.toggle",
|
|
50
|
-
render: ({ key }) => `Press ${key ?? "tab"} to switch between the sidebar and reader.`,
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
id: "sidebar.toggle",
|
|
54
|
-
bindingId: "sidebar.toggle",
|
|
55
|
-
render: ({ key }) =>
|
|
56
|
-
`Press ${key ?? "s"} to hide or show the sidebar without losing your place.`,
|
|
57
|
-
},
|
|
58
|
-
]
|
|
59
|
-
|
|
60
|
-
const firstKeyByBindingId = <C>(bindings: readonly KeyBinding<C>[]): ReadonlyMap<string, string> =>
|
|
61
|
-
new Map(
|
|
62
|
-
bindings.flatMap((binding) => {
|
|
63
|
-
const firstKey = binding.keys[0]
|
|
64
|
-
return firstKey ? [[binding.id, displayKey(firstKey)] as const] : []
|
|
65
|
-
}),
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
export const buildReaderEmptyStateTips = (
|
|
69
|
-
bindings: readonly KeyBinding<BrowserCtx>[],
|
|
70
|
-
ctx: BrowserCtx,
|
|
71
|
-
): readonly TipLine[] => {
|
|
72
|
-
const keyByBindingId = firstKeyByBindingId(bindings)
|
|
73
|
-
|
|
74
|
-
return tipDefinitions
|
|
75
|
-
.filter((tip) => !tip.when || tip.when(ctx))
|
|
76
|
-
.map((tip) => ({
|
|
77
|
-
id: tip.id,
|
|
78
|
-
text: `Tip: ${tip.render({ key: tip.bindingId ? (keyByBindingId.get(tip.bindingId) ?? null) : null })}`,
|
|
79
|
-
}))
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export const pickTipByRotation = (
|
|
83
|
-
tips: readonly TipLine[],
|
|
84
|
-
rotationIndex: number,
|
|
85
|
-
): TipLine | null => {
|
|
86
|
-
if (tips.length === 0) return null
|
|
87
|
-
return tips[((rotationIndex % tips.length) + tips.length) % tips.length] ?? null
|
|
88
|
-
}
|
package/src/ui/middleTruncate.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Middle truncation for technical strings.
|
|
3
|
-
*
|
|
4
|
-
* Keeps the start and end of a string visible while compressing the middle
|
|
5
|
-
* to a single ellipsis glyph (`…`). Use for paths, IDs, branch names, and
|
|
6
|
-
* other values whose head and tail both matter.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
export interface MiddleTruncateOptions {
|
|
10
|
-
readonly ellipsis?: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const middleTruncate = (
|
|
14
|
-
value: string,
|
|
15
|
-
width: number,
|
|
16
|
-
options: MiddleTruncateOptions = {},
|
|
17
|
-
): string => {
|
|
18
|
-
const ellipsis = options.ellipsis ?? "…"
|
|
19
|
-
if (width <= 0) return ""
|
|
20
|
-
if (value.length <= width) return value
|
|
21
|
-
if (width <= ellipsis.length) return value.slice(0, width)
|
|
22
|
-
|
|
23
|
-
const available = width - ellipsis.length
|
|
24
|
-
const left = Math.ceil(available / 2)
|
|
25
|
-
const right = Math.floor(available / 2)
|
|
26
|
-
return value.slice(0, left) + ellipsis + value.slice(value.length - right)
|
|
27
|
-
}
|
package/src/update/cache.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Update-check cache. Stores the last npm-registry probe result on disk so
|
|
3
|
-
* we hit the registry at most once per TTL window.
|
|
4
|
-
*
|
|
5
|
-
* Layout: `$XDG_CACHE_HOME/house/update-check.json` (fallback
|
|
6
|
-
* `~/.cache/house/update-check.json`). All IO failures are non-fatal — a
|
|
7
|
-
* missing or unparseable cache simply forces a fresh probe.
|
|
8
|
-
*
|
|
9
|
-
* Schema is intentionally minimal. `tarballOk` distinguishes "we saw the
|
|
10
|
-
* version and confirmed the tarball is downloadable" from "we saw the
|
|
11
|
-
* version but the CDN HEAD failed" — only the former gates the notice. A
|
|
12
|
-
* `false` entry forces a retry on the next launch rather than waiting out
|
|
13
|
-
* the TTL.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { dirname, join } from "node:path"
|
|
17
|
-
import { homedir } from "node:os"
|
|
18
|
-
import { mkdir, readFile, rename, unlink, writeFile } from "node:fs/promises"
|
|
19
|
-
|
|
20
|
-
export interface UpdateCacheRecord {
|
|
21
|
-
readonly checkedAt: number
|
|
22
|
-
readonly latestVersion: string
|
|
23
|
-
readonly tarballOk: boolean
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const cacheDir = (): string => {
|
|
27
|
-
const xdg = process.env.XDG_CACHE_HOME
|
|
28
|
-
if (xdg && xdg.length > 0) return join(xdg, "house")
|
|
29
|
-
return join(homedir(), ".cache", "house")
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const cachePath = (): string => join(cacheDir(), "update-check.json")
|
|
33
|
-
|
|
34
|
-
export const readCache = async (path = cachePath()): Promise<UpdateCacheRecord | null> => {
|
|
35
|
-
try {
|
|
36
|
-
const raw = await readFile(path, "utf8")
|
|
37
|
-
const parsed = JSON.parse(raw) as unknown
|
|
38
|
-
if (typeof parsed !== "object" || parsed === null) return null
|
|
39
|
-
const r = parsed as Record<string, unknown>
|
|
40
|
-
if (
|
|
41
|
-
typeof r.checkedAt !== "number" ||
|
|
42
|
-
typeof r.latestVersion !== "string" ||
|
|
43
|
-
typeof r.tarballOk !== "boolean"
|
|
44
|
-
) {
|
|
45
|
-
return null
|
|
46
|
-
}
|
|
47
|
-
return {
|
|
48
|
-
checkedAt: r.checkedAt,
|
|
49
|
-
latestVersion: r.latestVersion,
|
|
50
|
-
tarballOk: r.tarballOk,
|
|
51
|
-
}
|
|
52
|
-
} catch {
|
|
53
|
-
return null
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export const writeCache = async (record: UpdateCacheRecord, path = cachePath()): Promise<void> => {
|
|
58
|
-
// Atomic write: writeFile to a sibling tmp path, then rename. Rename is
|
|
59
|
-
// atomic on POSIX, so a process.exit() racing the writer either leaves
|
|
60
|
-
// the prior file intact or installs the new one fully — never a partial
|
|
61
|
-
// JSON blob that readCache would have to ignore.
|
|
62
|
-
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`
|
|
63
|
-
try {
|
|
64
|
-
await mkdir(dirname(path), { recursive: true })
|
|
65
|
-
await writeFile(tmp, JSON.stringify(record), "utf8")
|
|
66
|
-
await rename(tmp, path)
|
|
67
|
-
} catch {
|
|
68
|
-
// Cache writes are best-effort. A read-only HOME or full disk should
|
|
69
|
-
// not break the app; we'll just re-probe on the next launch. Clean up
|
|
70
|
-
// the tmp file if writeFile partially succeeded but rename did not.
|
|
71
|
-
try {
|
|
72
|
-
await unlink(tmp)
|
|
73
|
-
} catch {
|
|
74
|
-
// best-effort
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|