@carlesandres/house 0.4.7 → 0.4.8
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 +27 -3
- package/README.md +21 -9
- package/package.json +1 -1
- package/src/Browser.tsx +235 -160
- package/src/CommandPalette.tsx +78 -14
- package/src/Footer.tsx +41 -33
- package/src/Header.tsx +4 -1
- package/src/StatusPopover.tsx +189 -0
- package/src/cli/argv.ts +12 -5
- package/src/commands/buildCommands.ts +22 -33
- package/src/commands/score.ts +1 -1
- package/src/discovery/walk.ts +20 -3
- package/src/index.tsx +120 -155
- package/src/keymap/browser.ts +14 -20
- package/src/keymap/keymap.ts +4 -4
- package/src/layout/sidebarEmptyState.ts +7 -0
- package/src/markdown/frontmatter.ts +62 -0
- package/src/theme/resolve.ts +1 -1
- package/src/theme/themes/aura.json +1 -1
- package/src/theme/themes/carbonfox.json +1 -1
- package/src/theme/themes/lucent-orng.json +4 -4
- package/src/theme/themes/nightowl.json +2 -2
- package/src/theme/themes/orng.json +2 -2
- package/src/theme/themes/solarized.json +6 -2
- package/src/theme/themes/vesper.json +2 -2
- package/src/tips.ts +0 -5
- package/src/update/check.ts +1 -1
- package/src/update/runtime.ts +1 -1
- package/src/HelpOverlay.tsx +0 -148
package/src/theme/resolve.ts
CHANGED
|
@@ -82,7 +82,7 @@ const HARD_FALLBACK: Readonly<Record<TokenName, HexColor>> = Object.fromEntries(
|
|
|
82
82
|
* the theme omits them. Mirrors opencode's resolve behavior.
|
|
83
83
|
*/
|
|
84
84
|
const TOKEN_FALLBACK: Partial<Record<TokenName, TokenName>> = {
|
|
85
|
-
selectedListItemText: "
|
|
85
|
+
selectedListItemText: "text",
|
|
86
86
|
markdownText: "text",
|
|
87
87
|
markdownCodeBlock: "text",
|
|
88
88
|
borderSubtle: "border",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"textMuted": "darkFgMuted",
|
|
26
26
|
"background": "darkBg",
|
|
27
27
|
"backgroundPanel": "darkBgPanel",
|
|
28
|
-
"backgroundElement": "
|
|
28
|
+
"backgroundElement": "darkBorder",
|
|
29
29
|
"border": "darkBorder",
|
|
30
30
|
"borderActive": "darkFgMuted",
|
|
31
31
|
"borderSubtle": "darkBorder",
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"light": "lightStep11"
|
|
62
62
|
},
|
|
63
63
|
"selectedListItemText": {
|
|
64
|
-
"dark": "
|
|
65
|
-
"light": "
|
|
64
|
+
"dark": "darkStep12",
|
|
65
|
+
"light": "lightStep12"
|
|
66
66
|
},
|
|
67
67
|
"background": {
|
|
68
68
|
"dark": "transparent",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"light": "transparent"
|
|
74
74
|
},
|
|
75
75
|
"backgroundElement": {
|
|
76
|
-
"dark": "
|
|
77
|
-
"light": "
|
|
76
|
+
"dark": "darkStep6",
|
|
77
|
+
"light": "lightStep6"
|
|
78
78
|
},
|
|
79
79
|
"border": {
|
|
80
80
|
"dark": "darkOrange",
|
|
@@ -54,6 +54,10 @@
|
|
|
54
54
|
"dark": "base01",
|
|
55
55
|
"light": "base1"
|
|
56
56
|
},
|
|
57
|
+
"selectedListItemText": {
|
|
58
|
+
"dark": "base3",
|
|
59
|
+
"light": "base03"
|
|
60
|
+
},
|
|
57
61
|
"background": {
|
|
58
62
|
"dark": "base03",
|
|
59
63
|
"light": "base3"
|
|
@@ -63,8 +67,8 @@
|
|
|
63
67
|
"light": "base2"
|
|
64
68
|
},
|
|
65
69
|
"backgroundElement": {
|
|
66
|
-
"dark": "
|
|
67
|
-
"light": "
|
|
70
|
+
"dark": "base01",
|
|
71
|
+
"light": "base1"
|
|
68
72
|
},
|
|
69
73
|
"border": {
|
|
70
74
|
"dark": "base02",
|
package/src/tips.ts
CHANGED
|
@@ -55,11 +55,6 @@ const tipDefinitions: readonly TipDefinition[] = [
|
|
|
55
55
|
render: ({ key }) =>
|
|
56
56
|
`Press ${key ?? "s"} to hide or show the sidebar without losing your place.`,
|
|
57
57
|
},
|
|
58
|
-
{
|
|
59
|
-
id: "help.open",
|
|
60
|
-
bindingId: "help.toggle",
|
|
61
|
-
render: ({ key }) => `Press ${key ?? "?"} to open the full keyboard help at any time.`,
|
|
62
|
-
},
|
|
63
58
|
]
|
|
64
59
|
|
|
65
60
|
const firstKeyByBindingId = <C>(bindings: readonly KeyBinding<C>[]): ReadonlyMap<string, string> =>
|
package/src/update/check.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import { isNewer } from "./compare.ts"
|
|
16
16
|
import { readCache, writeCache, type UpdateCacheRecord } from "./cache.ts"
|
|
17
17
|
|
|
18
|
-
export const TTL_MS =
|
|
18
|
+
export const TTL_MS = 60 * 60 * 1000
|
|
19
19
|
const FETCH_TIMEOUT_MS = 3000
|
|
20
20
|
const REGISTRY_URL = (pkgName: string) => `https://registry.npmjs.org/${pkgName}/latest`
|
|
21
21
|
|
package/src/update/runtime.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* The probe runs at most once per process. The result lands in a module
|
|
5
5
|
* variable so:
|
|
6
|
-
* - any UI surface
|
|
6
|
+
* - any UI surface can subscribe and re-render when
|
|
7
7
|
* it resolves, without each one issuing its own request;
|
|
8
8
|
* - the `process.on("exit")` hook can synchronously read the result and
|
|
9
9
|
* print the quit-time notice (async work can't run during 'exit').
|
package/src/HelpOverlay.tsx
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HelpOverlay — modal panel listing the keymap.
|
|
3
|
-
*
|
|
4
|
-
* Renders absolute-positioned over the rest of the UI. Iterates the
|
|
5
|
-
* KeyBinding[] array directly; there is no separate hand-written list of
|
|
6
|
-
* keys — the dispatcher and the help text are the same source of truth.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { RGBA } from "@opentui/core"
|
|
10
|
-
import type { KeyBinding } from "./keymap/keymap.ts"
|
|
11
|
-
import { colors } from "./theme/colors.ts"
|
|
12
|
-
|
|
13
|
-
// See CommandPalette.tsx for the scrim rationale.
|
|
14
|
-
const SCRIM = RGBA.fromInts(0, 0, 0, 150)
|
|
15
|
-
|
|
16
|
-
export interface HelpOverlayProps<C> {
|
|
17
|
-
readonly bindings: readonly KeyBinding<C>[]
|
|
18
|
-
readonly viewportWidth: number
|
|
19
|
-
readonly viewportHeight: number
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const formatKeys = (keys: readonly string[]): string => keys.join(", ")
|
|
23
|
-
|
|
24
|
-
interface Row {
|
|
25
|
-
readonly key: string
|
|
26
|
-
readonly text: string
|
|
27
|
-
readonly kind: "header" | "binding" | "spacer" | "footer"
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const buildRows = <C,>(bindings: readonly KeyBinding<C>[]): Row[] => {
|
|
31
|
-
const order: string[] = []
|
|
32
|
-
const grouped = new Map<string, KeyBinding<C>[]>()
|
|
33
|
-
for (const b of bindings) {
|
|
34
|
-
if (!b.group) continue
|
|
35
|
-
if (!grouped.has(b.group)) {
|
|
36
|
-
grouped.set(b.group, [])
|
|
37
|
-
order.push(b.group)
|
|
38
|
-
}
|
|
39
|
-
grouped.get(b.group)!.push(b)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Width of the keys column: longest formatted-keys string across all
|
|
43
|
-
// shown bindings, plus a small gap before descriptions.
|
|
44
|
-
let keyColumn = 0
|
|
45
|
-
for (const list of grouped.values()) {
|
|
46
|
-
for (const b of list) keyColumn = Math.max(keyColumn, formatKeys(b.keys).length)
|
|
47
|
-
}
|
|
48
|
-
const gap = 2
|
|
49
|
-
const padTo = keyColumn + gap
|
|
50
|
-
|
|
51
|
-
const rows: Row[] = []
|
|
52
|
-
for (let i = 0; i < order.length; i++) {
|
|
53
|
-
const group = order[i]!
|
|
54
|
-
// A spacer before *every* group, including the first. Without one
|
|
55
|
-
// before the first, opentui collapses the header onto the first
|
|
56
|
-
// binding row — appears to be an interaction between the title
|
|
57
|
-
// border and the first child of a padded column.
|
|
58
|
-
rows.push({ key: `spacer-before-${group}`, text: " ", kind: "spacer" })
|
|
59
|
-
rows.push({ key: `header-${group}`, text: group, kind: "header" })
|
|
60
|
-
for (const b of grouped.get(group)!) {
|
|
61
|
-
rows.push({
|
|
62
|
-
key: `binding-${b.id}`,
|
|
63
|
-
text: ` ${formatKeys(b.keys).padEnd(padTo)}${b.description}`,
|
|
64
|
-
kind: "binding",
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
rows.push({ key: "spacer-footer", text: " ", kind: "spacer" })
|
|
69
|
-
rows.push({ key: "footer", text: "press ? or esc to dismiss", kind: "footer" })
|
|
70
|
-
return rows
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export const HelpOverlay = <C,>({
|
|
74
|
-
bindings,
|
|
75
|
-
viewportWidth,
|
|
76
|
-
viewportHeight,
|
|
77
|
-
}: HelpOverlayProps<C>) => {
|
|
78
|
-
const rows = buildRows(bindings)
|
|
79
|
-
|
|
80
|
-
const overlayWidth = Math.min(viewportWidth - 4, 64)
|
|
81
|
-
const desiredHeight = rows.length + 2 // border top + bottom
|
|
82
|
-
const overlayHeight = Math.min(viewportHeight - 4, desiredHeight + 2) // +2 for vertical padding
|
|
83
|
-
const left = Math.max(0, Math.floor((viewportWidth - overlayWidth) / 2))
|
|
84
|
-
const top = Math.max(0, Math.floor((viewportHeight - overlayHeight) / 2))
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
<box
|
|
88
|
-
position="absolute"
|
|
89
|
-
left={0}
|
|
90
|
-
top={0}
|
|
91
|
-
width={viewportWidth}
|
|
92
|
-
height={viewportHeight}
|
|
93
|
-
zIndex={10}
|
|
94
|
-
style={{ backgroundColor: SCRIM }}
|
|
95
|
-
>
|
|
96
|
-
<box
|
|
97
|
-
position="absolute"
|
|
98
|
-
left={left}
|
|
99
|
-
top={top}
|
|
100
|
-
width={overlayWidth}
|
|
101
|
-
height={overlayHeight}
|
|
102
|
-
title=" Help "
|
|
103
|
-
titleAlignment="left"
|
|
104
|
-
style={{
|
|
105
|
-
border: true,
|
|
106
|
-
borderColor: colors.textMuted,
|
|
107
|
-
padding: 1,
|
|
108
|
-
flexDirection: "column",
|
|
109
|
-
backgroundColor: colors.backgroundPanel,
|
|
110
|
-
}}
|
|
111
|
-
>
|
|
112
|
-
{rows.map((row) => {
|
|
113
|
-
switch (row.kind) {
|
|
114
|
-
case "header":
|
|
115
|
-
return (
|
|
116
|
-
<text
|
|
117
|
-
key={row.key}
|
|
118
|
-
wrapMode="none"
|
|
119
|
-
content={row.text}
|
|
120
|
-
style={{ fg: colors.borderActive, attributes: 1 /* bold */ }}
|
|
121
|
-
/>
|
|
122
|
-
)
|
|
123
|
-
case "footer":
|
|
124
|
-
return (
|
|
125
|
-
<text
|
|
126
|
-
key={row.key}
|
|
127
|
-
wrapMode="none"
|
|
128
|
-
content={row.text}
|
|
129
|
-
style={{ fg: colors.textMuted }}
|
|
130
|
-
/>
|
|
131
|
-
)
|
|
132
|
-
case "spacer":
|
|
133
|
-
return <text key={row.key} content=" " />
|
|
134
|
-
case "binding":
|
|
135
|
-
return (
|
|
136
|
-
<text
|
|
137
|
-
key={row.key}
|
|
138
|
-
wrapMode="none"
|
|
139
|
-
content={row.text}
|
|
140
|
-
style={{ fg: colors.text }}
|
|
141
|
-
/>
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
})}
|
|
145
|
-
</box>
|
|
146
|
-
</box>
|
|
147
|
-
)
|
|
148
|
-
}
|