Skip to content

Commit 4b9bece

Browse files
committed
feat(plugin-studio): add 4-panel layout shell (#5)
1 parent fa37700 commit 4b9bece

21 files changed

Lines changed: 1525 additions & 45 deletions

plugins/plugin-studio/app/dist/assets/index-DWwaG842.js

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/plugin-studio/app/dist/assets/index-PSM6mDDY.css

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/plugin-studio/app/dist/index.html

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,10 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Plugin Studio</title>
7-
<style>
8-
* { box-sizing: border-box; margin: 0; padding: 0; }
9-
body {
10-
min-height: 100vh;
11-
background: #030712;
12-
color: #f9fafb;
13-
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
14-
display: flex;
15-
align-items: center;
16-
justify-content: center;
17-
}
18-
.container { text-align: center; padding: 2rem; }
19-
h1 { font-size: 2.5rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: 1rem; }
20-
p { color: #9ca3af; margin-bottom: 0.5rem; }
21-
small { color: #6b7280; font-size: 0.875rem; }
22-
.badge {
23-
display: inline-block;
24-
margin-top: 1.5rem;
25-
padding: 0.25rem 0.75rem;
26-
border: 1px solid #374151;
27-
border-radius: 9999px;
28-
font-size: 0.75rem;
29-
color: #6b7280;
30-
}
31-
</style>
7+
<script type="module" crossorigin src="/assets/index-DWwaG842.js"></script>
8+
<link rel="stylesheet" crossorigin href="/assets/index-PSM6mDDY.css">
329
</head>
3310
<body>
34-
<div class="container">
35-
<h1>Plugin Studio</h1>
36-
<p>Visual dashboard for Claude Code plugins</p>
37-
<small>Run <code>pnpm build</code> inside <code>app/</code> to generate the full UI.</small>
38-
<br />
39-
<span class="badge">pre-built placeholder · v0.1.0</span>
40-
</div>
11+
<div id="root"></div>
4112
</body>
4213
</html>

plugins/plugin-studio/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"react-dom": "^18.3.1"
1414
},
1515
"devDependencies": {
16+
"@types/node": "^22.10.2",
1617
"@types/react": "^18.3.12",
1718
"@types/react-dom": "^18.3.1",
1819
"@vitejs/plugin-react": "^4.3.4",
Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
1+
import { PluginStudioShell } from './components/shell/PluginStudioShell.tsx';
2+
13
export default function App() {
2-
return (
3-
<div className="min-h-screen bg-gray-950 text-gray-100 flex items-center justify-center">
4-
<div className="text-center space-y-4">
5-
<h1 className="text-4xl font-bold tracking-tight">Plugin Studio</h1>
6-
<p className="text-gray-400 text-lg">
7-
Visual dashboard for Claude Code plugins
8-
</p>
9-
<p className="text-gray-500 text-sm">
10-
UI implementation coming in v0.2 — server is live.
11-
</p>
12-
</div>
13-
</div>
14-
);
4+
return <PluginStudioShell />;
155
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import type { ReactNode } from 'react';
2+
3+
type PanelTone = 'amber' | 'cyan' | 'olive' | 'slate';
4+
5+
interface PanelFrameProps {
6+
title: string;
7+
subtitle?: string;
8+
badge?: string;
9+
tone?: PanelTone;
10+
actions?: ReactNode;
11+
children: ReactNode;
12+
className?: string;
13+
bodyClassName?: string;
14+
}
15+
16+
function joinClasses(...classes: Array<string | undefined>) {
17+
return classes.filter(Boolean).join(' ');
18+
}
19+
20+
export function PanelFrame({
21+
title,
22+
subtitle,
23+
badge,
24+
tone = 'slate',
25+
actions,
26+
children,
27+
className,
28+
bodyClassName,
29+
}: PanelFrameProps) {
30+
return (
31+
<section
32+
data-tone={tone}
33+
className={joinClasses(
34+
'studio-panel flex h-full min-h-0 flex-col overflow-hidden',
35+
className,
36+
)}
37+
>
38+
<header className="studio-panel-header flex items-start justify-between gap-3">
39+
<div className="min-w-0">
40+
<div className="flex items-center gap-2">
41+
<span className="studio-panel-dot" aria-hidden="true" />
42+
<h2 className="truncate text-sm font-semibold uppercase tracking-[0.22em] text-slate-100">
43+
{title}
44+
</h2>
45+
{badge ? <span className="studio-badge">{badge}</span> : null}
46+
</div>
47+
{subtitle ? (
48+
<p className="mt-2 text-sm text-slate-400">
49+
{subtitle}
50+
</p>
51+
) : null}
52+
</div>
53+
{actions ? <div className="shrink-0">{actions}</div> : null}
54+
</header>
55+
<div className={joinClasses('min-h-0 flex-1', bodyClassName)}>
56+
{children}
57+
</div>
58+
</section>
59+
);
60+
}

0 commit comments

Comments
 (0)