@mohou/panel 1.0.20
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/README.md +8 -0
- package/lib/types/chrome/hue.d.ts +3 -0
- package/lib/types/chrome/hue.d.ts.map +1 -0
- package/lib/types/gallery/card-style.d.ts +8 -0
- package/lib/types/gallery/card-style.d.ts.map +1 -0
- package/lib/types/gallery/client.d.ts +20 -0
- package/lib/types/gallery/client.d.ts.map +1 -0
- package/lib/types/gallery/desk.d.ts +16 -0
- package/lib/types/gallery/desk.d.ts.map +1 -0
- package/lib/types/gallery/list.d.ts +37 -0
- package/lib/types/gallery/list.d.ts.map +1 -0
- package/lib/types/gallery/sort.d.ts +24 -0
- package/lib/types/gallery/sort.d.ts.map +1 -0
- package/lib/types/gallery/state.d.ts +90 -0
- package/lib/types/gallery/state.d.ts.map +1 -0
- package/lib/types/gallery/tabs.d.ts +45 -0
- package/lib/types/gallery/tabs.d.ts.map +1 -0
- package/lib/types/gallery/view.d.ts +57 -0
- package/lib/types/gallery/view.d.ts.map +1 -0
- package/lib/types/history/client.d.ts +25 -0
- package/lib/types/history/client.d.ts.map +1 -0
- package/lib/types/history/state.d.ts +39 -0
- package/lib/types/history/state.d.ts.map +1 -0
- package/lib/types/history/view.d.ts +15 -0
- package/lib/types/history/view.d.ts.map +1 -0
- package/lib/types/index.d.ts +24 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/labels.d.ts +267 -0
- package/lib/types/labels.d.ts.map +1 -0
- package/lib/types/settings/author-mcp-view.d.ts +15 -0
- package/lib/types/settings/author-mcp-view.d.ts.map +1 -0
- package/lib/types/settings/author-mcp.d.ts +4 -0
- package/lib/types/settings/author-mcp.d.ts.map +1 -0
- package/lib/types/settings/client.d.ts +198 -0
- package/lib/types/settings/client.d.ts.map +1 -0
- package/lib/types/settings/credentials-view.d.ts +15 -0
- package/lib/types/settings/credentials-view.d.ts.map +1 -0
- package/lib/types/settings/form.d.ts +27 -0
- package/lib/types/settings/form.d.ts.map +1 -0
- package/lib/types/settings/install-row.d.ts +10 -0
- package/lib/types/settings/install-row.d.ts.map +1 -0
- package/lib/types/settings/mcp-view.d.ts +14 -0
- package/lib/types/settings/mcp-view.d.ts.map +1 -0
- package/lib/types/settings/skill-dirs.d.ts +6 -0
- package/lib/types/settings/skill-dirs.d.ts.map +1 -0
- package/lib/types/settings/skill-install.d.ts +13 -0
- package/lib/types/settings/skill-install.d.ts.map +1 -0
- package/lib/types/settings/state.d.ts +94 -0
- package/lib/types/settings/state.d.ts.map +1 -0
- package/lib/types/settings/update-dialog.d.ts +56 -0
- package/lib/types/settings/update-dialog.d.ts.map +1 -0
- package/lib/types/settings/view.d.ts +26 -0
- package/lib/types/settings/view.d.ts.map +1 -0
- package/lib/types/storage/client.d.ts +15 -0
- package/lib/types/storage/client.d.ts.map +1 -0
- package/lib/types/storage/state.d.ts +42 -0
- package/lib/types/storage/state.d.ts.map +1 -0
- package/lib/types/storage/view.d.ts +16 -0
- package/lib/types/storage/view.d.ts.map +1 -0
- package/lib/types/surface/state.d.ts +42 -0
- package/lib/types/surface/state.d.ts.map +1 -0
- package/lib/types/surface/view.d.ts +34 -0
- package/lib/types/surface/view.d.ts.map +1 -0
- package/lib/types/theme/client.d.ts +45 -0
- package/lib/types/theme/client.d.ts.map +1 -0
- package/lib/types/theme/menu.d.ts +25 -0
- package/lib/types/theme/menu.d.ts.map +1 -0
- package/lib/types/theme/state.d.ts +46 -0
- package/lib/types/theme/state.d.ts.map +1 -0
- package/lib/types/theme/view.d.ts +16 -0
- package/lib/types/theme/view.d.ts.map +1 -0
- package/lib/types/ui/dialog.d.ts +12 -0
- package/lib/types/ui/dialog.d.ts.map +1 -0
- package/lib/types/ui/tooltip.d.ts +12 -0
- package/lib/types/ui/tooltip.d.ts.map +1 -0
- package/package.json +38 -0
- package/src/chrome/hue.ts +6 -0
- package/src/gallery/card-style.ts +27 -0
- package/src/gallery/client.ts +26 -0
- package/src/gallery/desk.tsx +54 -0
- package/src/gallery/list.ts +54 -0
- package/src/gallery/sort.ts +72 -0
- package/src/gallery/state.ts +229 -0
- package/src/gallery/tabs.ts +85 -0
- package/src/gallery/view.tsx +501 -0
- package/src/history/client.ts +27 -0
- package/src/history/state.ts +90 -0
- package/src/history/view.tsx +131 -0
- package/src/index.ts +61 -0
- package/src/labels.ts +536 -0
- package/src/settings/author-mcp-view.tsx +154 -0
- package/src/settings/author-mcp.ts +24 -0
- package/src/settings/client.ts +205 -0
- package/src/settings/credentials-view.tsx +195 -0
- package/src/settings/form.ts +27 -0
- package/src/settings/install-row.tsx +35 -0
- package/src/settings/mcp-view.tsx +793 -0
- package/src/settings/skill-dirs.ts +41 -0
- package/src/settings/skill-install.tsx +134 -0
- package/src/settings/state.ts +225 -0
- package/src/settings/update-dialog.tsx +207 -0
- package/src/settings/view.tsx +722 -0
- package/src/storage/client.ts +16 -0
- package/src/storage/state.ts +94 -0
- package/src/storage/view.tsx +190 -0
- package/src/surface/state.ts +72 -0
- package/src/surface/view.tsx +255 -0
- package/src/theme/client.ts +34 -0
- package/src/theme/menu.tsx +286 -0
- package/src/theme/state.ts +113 -0
- package/src/theme/view.tsx +73 -0
- package/src/ui/dialog.tsx +25 -0
- package/src/ui/tooltip.tsx +19 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { useEffect, useReducer, type ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
import { panelText, type PanelLabelMode, type PanelLocale } from '../labels.ts'
|
|
4
|
+
import type { HistoryClient, HistoryCommit, HistoryFile } from './client.ts'
|
|
5
|
+
import { Tooltip } from '../ui/tooltip.tsx'
|
|
6
|
+
import { historyState, loadCommit, loadHistory, reduceHistory } from './state.ts'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read-only history. Hidden when Host exposes no history client. No route string lives here.
|
|
10
|
+
* @param props - client, app, chrome locale, and the pane close control
|
|
11
|
+
*/
|
|
12
|
+
export function PanelHistory(props: {
|
|
13
|
+
readonly client?: HistoryClient
|
|
14
|
+
readonly appId: string
|
|
15
|
+
readonly locale: PanelLocale
|
|
16
|
+
readonly mode: PanelLabelMode
|
|
17
|
+
readonly onClose?: () => void
|
|
18
|
+
}): ReactNode {
|
|
19
|
+
const [state, dispatch] = useReducer(reduceHistory, undefined, historyState)
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (props.client === undefined) return
|
|
22
|
+
void loadHistory(props.client, props.appId, dispatch)
|
|
23
|
+
}, [props.client, props.appId])
|
|
24
|
+
if (props.client === undefined) return null
|
|
25
|
+
const label = (key: string) => panelText(props.locale, key, props.mode)
|
|
26
|
+
const client = props.client
|
|
27
|
+
return (
|
|
28
|
+
<section className="flex min-h-0 flex-1 flex-col bg-background text-foreground">
|
|
29
|
+
<header className="flex items-center justify-between gap-3 border-b bg-card px-4 py-3">
|
|
30
|
+
<h3 className="text-[15px] font-semibold">{label('history')}</h3>
|
|
31
|
+
<PaneClose label={label('pane-close')} onClose={props.onClose} />
|
|
32
|
+
</header>
|
|
33
|
+
<div className="grid min-h-0 flex-1 grid-cols-1 min-[720px]:grid-cols-[17rem_minmax(0,1fr)]">
|
|
34
|
+
<div className="min-h-0 overflow-auto border-b p-3 min-[720px]:border-r min-[720px]:border-b-0">
|
|
35
|
+
{state.failed ? <p className="text-sm text-destructive">{state.error !== undefined && state.error.length > 0 ? state.error : label('history-failed')}</p> : null}
|
|
36
|
+
{!state.failed && state.commits.length === 0 ? <p className="text-sm text-muted-foreground">{label('history-empty')}</p> : null}
|
|
37
|
+
<ul className="flex flex-col gap-2">
|
|
38
|
+
{state.commits.map(commit => (
|
|
39
|
+
<li key={commit.id}>
|
|
40
|
+
<CommitRow
|
|
41
|
+
commit={commit}
|
|
42
|
+
pressed={state.selected === commit.id}
|
|
43
|
+
onSelect={() => { void loadCommit(client, props.appId, commit.id, dispatch) }}
|
|
44
|
+
/>
|
|
45
|
+
</li>
|
|
46
|
+
))}
|
|
47
|
+
</ul>
|
|
48
|
+
</div>
|
|
49
|
+
<div className="min-h-0 overflow-auto p-4">
|
|
50
|
+
{state.detailFailed ? <p className="text-sm text-destructive">{state.detailError !== undefined && state.detailError.length > 0 ? state.detailError : label('history-failed')}</p> : null}
|
|
51
|
+
{state.detail === undefined ? <p className="text-sm text-muted-foreground">{label('history-pick')}</p> : (
|
|
52
|
+
<div className="flex flex-col gap-3">
|
|
53
|
+
<div>
|
|
54
|
+
<h4 className="text-sm font-semibold">{state.detail.message}</h4>
|
|
55
|
+
<p className="mt-1 font-mono text-[11px] text-muted-foreground">{state.selected}</p>
|
|
56
|
+
<time className="mt-1 block text-[11px] text-muted-foreground">{clock(state.detail.time)}</time>
|
|
57
|
+
</div>
|
|
58
|
+
{state.detail.files.map(file => (
|
|
59
|
+
<FilePreview key={file.path} file={file} />
|
|
60
|
+
))}
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
</section>
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function CommitRow(props: {
|
|
70
|
+
readonly commit: HistoryCommit
|
|
71
|
+
readonly pressed: boolean
|
|
72
|
+
readonly onSelect: () => void
|
|
73
|
+
}): ReactNode {
|
|
74
|
+
return (
|
|
75
|
+
<Tooltip text={props.commit.id} className="w-full">
|
|
76
|
+
<button
|
|
77
|
+
type="button"
|
|
78
|
+
className="w-full rounded-xl border bg-card px-3 py-2.5 text-left data-[on=1]:border-primary"
|
|
79
|
+
aria-pressed={props.pressed}
|
|
80
|
+
data-on={props.pressed ? '1' : '0'}
|
|
81
|
+
data-commit={props.commit.id}
|
|
82
|
+
onClick={props.onSelect}
|
|
83
|
+
>
|
|
84
|
+
<span className="flex items-baseline justify-between gap-2">
|
|
85
|
+
<span className="min-w-0 truncate text-sm font-semibold">{props.commit.message.length > 0 ? props.commit.message : props.commit.id.slice(0, 7)}</span>
|
|
86
|
+
<time className="shrink-0 text-[11px] text-muted-foreground">{clock(props.commit.time)}</time>
|
|
87
|
+
</span>
|
|
88
|
+
<span className="mt-1 block font-mono text-[11px] text-muted-foreground">{props.commit.id.slice(0, 7)}</span>
|
|
89
|
+
</button>
|
|
90
|
+
</Tooltip>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function FilePreview(props: { readonly file: HistoryFile }): ReactNode {
|
|
95
|
+
const lines = props.file.preview.length === 0 ? [] : props.file.preview.split('\n')
|
|
96
|
+
return (
|
|
97
|
+
<article className="overflow-hidden rounded-xl border bg-card">
|
|
98
|
+
<header className="flex items-center justify-between gap-3 border-b px-3 py-2">
|
|
99
|
+
<span className="min-w-0 truncate font-mono text-xs">{props.file.path}</span>
|
|
100
|
+
<span className="shrink-0 font-mono text-[11px] text-muted-foreground">{`+${props.file.add} −${props.file.del}`}</span>
|
|
101
|
+
</header>
|
|
102
|
+
{lines.length === 0 ? null : (
|
|
103
|
+
<pre className="max-h-80 overflow-auto p-3 font-mono text-[12px] leading-5">
|
|
104
|
+
{lines.map((line, index) => (
|
|
105
|
+
<span key={`${props.file.path}:${index}`} className={lineClass(line)}>{line.length === 0 ? ' ' : line}</span>
|
|
106
|
+
))}
|
|
107
|
+
</pre>
|
|
108
|
+
)}
|
|
109
|
+
</article>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function PaneClose(props: { readonly label: string; readonly onClose?: (() => void) | undefined }): ReactNode {
|
|
114
|
+
if (props.onClose === undefined) return null
|
|
115
|
+
return (
|
|
116
|
+
<button type="button" className="h-8 rounded-lg border bg-background px-3 text-sm hover:bg-muted" onClick={props.onClose}>{props.label}</button>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function lineClass(line: string): string {
|
|
121
|
+
if (line.startsWith('+')) return 'block text-primary'
|
|
122
|
+
if (line.startsWith('-')) return 'block text-destructive'
|
|
123
|
+
return 'block text-muted-foreground'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function clock(iso: string): string {
|
|
127
|
+
const date = new Date(iso)
|
|
128
|
+
if (Number.isNaN(date.getTime())) return iso
|
|
129
|
+
const pad = (value: number) => String(value).padStart(2, '0')
|
|
130
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}`
|
|
131
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** Panel chrome labels. Not the app's own strings. @module @mohou/panel */
|
|
2
|
+
|
|
3
|
+
export const packageId = '@mohou/panel' as const
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
isPanelLocale,
|
|
7
|
+
panelLocales,
|
|
8
|
+
panelText,
|
|
9
|
+
type PanelLabelKey,
|
|
10
|
+
type PanelLabelMode,
|
|
11
|
+
type PanelLocale,
|
|
12
|
+
} from './labels.ts'
|
|
13
|
+
export { admitPanelPort, panelLanguageFields, panelPortBound, type PanelPortResult } from './settings/form.ts'
|
|
14
|
+
export {
|
|
15
|
+
filterGallery,
|
|
16
|
+
galleryCardStyles,
|
|
17
|
+
galleryKind,
|
|
18
|
+
isGalleryCardStyle,
|
|
19
|
+
type GalleryApp,
|
|
20
|
+
type GalleryCardStyle,
|
|
21
|
+
type GalleryKind,
|
|
22
|
+
} from './gallery/list.ts'
|
|
23
|
+
export {
|
|
24
|
+
closeTab,
|
|
25
|
+
deletePrompt,
|
|
26
|
+
initialTabs,
|
|
27
|
+
openAppTab,
|
|
28
|
+
switchTab,
|
|
29
|
+
type AppTab,
|
|
30
|
+
type DeletePrompt,
|
|
31
|
+
type PanelTab,
|
|
32
|
+
type PanelTabs,
|
|
33
|
+
type TabChange,
|
|
34
|
+
} from './gallery/tabs.ts'
|
|
35
|
+
export { PanelClientError, type PanelClient } from './gallery/client.ts'
|
|
36
|
+
export {
|
|
37
|
+
loadGallery,
|
|
38
|
+
loadTrash,
|
|
39
|
+
galleryState,
|
|
40
|
+
reduceGallery,
|
|
41
|
+
viewKind,
|
|
42
|
+
visibleApps,
|
|
43
|
+
type GalleryAction,
|
|
44
|
+
type PanelShell,
|
|
45
|
+
type GalleryState,
|
|
46
|
+
} from './gallery/state.ts'
|
|
47
|
+
export { PanelGallery } from './gallery/view.tsx'
|
|
48
|
+
export { panelUpdateFailureCodes, type McpCheckResult, type McpServerDraft, type PanelAbout, type PanelCredential, type PanelCredentials, type PanelMcpFailure, type PanelMcpList, type PanelAuthorMcpAgent, type PanelAuthorMcpStatus, type PanelPolicy, type PanelPolicyWrite, type PanelProbe, type PanelRuntime, type PanelSettingsClient, type PanelSkillAgent, type PanelSkillStatus, type PanelUpdateAttempt, type PanelUpdateCheck, type PanelUpdateFailureCode } from './settings/client.ts'
|
|
49
|
+
export { loadSettings, reduceSettings, settingsDraft, settingsState, type SettingsAction, type SettingsState } from './settings/state.ts'
|
|
50
|
+
export { PanelSettings } from './settings/view.tsx'
|
|
51
|
+
export type { HistoryClient, HistoryCommit, HistoryDetail, HistoryFile } from './history/client.ts'
|
|
52
|
+
export { historyState, loadCommit, loadHistory, reduceHistory, type HistoryAction, type HistoryState } from './history/state.ts'
|
|
53
|
+
export { PanelHistory } from './history/view.tsx'
|
|
54
|
+
export type { StorageClient, StorageSummary, StorageTable } from './storage/client.ts'
|
|
55
|
+
export { loadStorage, loadTable, reduceStorage, storageState, type StorageAction, type StorageState } from './storage/state.ts'
|
|
56
|
+
export { PanelStorage } from './storage/view.tsx'
|
|
57
|
+
export type { IgnoredPalette, PaletteChip, ThemeClient, ThemePin } from './theme/client.ts'
|
|
58
|
+
export { loadPalettes, reduceTheme, savePin, themeState, type ThemeAction, type ThemeState } from './theme/state.ts'
|
|
59
|
+
export { PanelTheme } from './theme/view.tsx'
|
|
60
|
+
export { reduceSurface, surfaceState, panelSections, type PanelSection, type SurfaceAction, type SurfaceState } from './surface/state.ts'
|
|
61
|
+
export { PanelSurface, type PanelControls } from './surface/view.tsx'
|