claude-smart 0.2.23 → 0.2.24
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/.agents/plugins/marketplace.json +20 -0
- package/README.md +69 -27
- package/bin/claude-smart.js +296 -11
- package/package.json +11 -1
- package/plugin/.claude-plugin/plugin.json +17 -0
- package/plugin/.codex-plugin/plugin.json +35 -0
- package/plugin/LICENSE +202 -0
- package/plugin/README.md +37 -0
- package/plugin/bin/cs-cite +77 -0
- package/plugin/commands/clear-all.md +8 -0
- package/plugin/commands/dashboard.md +8 -0
- package/plugin/commands/learn.md +12 -0
- package/plugin/commands/restart.md +8 -0
- package/plugin/commands/show.md +8 -0
- package/plugin/dashboard/AGENTS.md +6 -0
- package/plugin/dashboard/app/api/claude-settings/route.ts +19 -0
- package/plugin/dashboard/app/api/config/route.ts +16 -0
- package/plugin/dashboard/app/api/health/route.ts +10 -0
- package/plugin/dashboard/app/api/reflexio/[...path]/route.ts +63 -0
- package/plugin/dashboard/app/api/sessions/[id]/route.ts +28 -0
- package/plugin/dashboard/app/api/sessions/route.ts +14 -0
- package/plugin/dashboard/app/configure/env/page.tsx +318 -0
- package/plugin/dashboard/app/configure/layout.tsx +47 -0
- package/plugin/dashboard/app/configure/page.tsx +5 -0
- package/plugin/dashboard/app/configure/server/page.tsx +258 -0
- package/plugin/dashboard/app/dashboard/page.tsx +227 -0
- package/plugin/dashboard/app/globals.css +129 -0
- package/plugin/dashboard/app/icon.png +0 -0
- package/plugin/dashboard/app/layout.tsx +40 -0
- package/plugin/dashboard/app/page.tsx +5 -0
- package/plugin/dashboard/app/preferences/[id]/page.tsx +531 -0
- package/plugin/dashboard/app/preferences/page.tsx +126 -0
- package/plugin/dashboard/app/providers.tsx +12 -0
- package/plugin/dashboard/app/sessions/[sessionId]/page.tsx +321 -0
- package/plugin/dashboard/app/sessions/page.tsx +186 -0
- package/plugin/dashboard/app/skills/page.tsx +362 -0
- package/plugin/dashboard/app/skills/project/[id]/page.tsx +597 -0
- package/plugin/dashboard/app/skills/shared/[id]/page.tsx +830 -0
- package/plugin/dashboard/components/common/delete-all-button.tsx +45 -0
- package/plugin/dashboard/components/common/empty-state.tsx +34 -0
- package/plugin/dashboard/components/common/learnings-badge.tsx +34 -0
- package/plugin/dashboard/components/common/page-header.tsx +34 -0
- package/plugin/dashboard/components/common/page-tabs.tsx +115 -0
- package/plugin/dashboard/components/common/stat-card.tsx +38 -0
- package/plugin/dashboard/components/layout/nav-items.ts +22 -0
- package/plugin/dashboard/components/layout/sidebar.tsx +45 -0
- package/plugin/dashboard/components/layout/top-bar.tsx +64 -0
- package/plugin/dashboard/components/stall-banner.tsx +53 -0
- package/plugin/dashboard/components/ui/badge.tsx +52 -0
- package/plugin/dashboard/components/ui/button.tsx +60 -0
- package/plugin/dashboard/components/ui/collapsible.tsx +21 -0
- package/plugin/dashboard/components/ui/input.tsx +20 -0
- package/plugin/dashboard/components/ui/label.tsx +20 -0
- package/plugin/dashboard/components/ui/scroll-area.tsx +55 -0
- package/plugin/dashboard/components/ui/select.tsx +201 -0
- package/plugin/dashboard/components/ui/separator.tsx +25 -0
- package/plugin/dashboard/components/ui/sheet.tsx +135 -0
- package/plugin/dashboard/components/ui/switch.tsx +32 -0
- package/plugin/dashboard/components.json +25 -0
- package/plugin/dashboard/eslint.config.mjs +16 -0
- package/plugin/dashboard/hooks/use-settings.tsx +88 -0
- package/plugin/dashboard/hooks/use-stall-state.ts +59 -0
- package/plugin/dashboard/lib/claude-settings-file.ts +114 -0
- package/plugin/dashboard/lib/config-file.ts +131 -0
- package/plugin/dashboard/lib/format.ts +58 -0
- package/plugin/dashboard/lib/reflexio-client.ts +238 -0
- package/plugin/dashboard/lib/reflexio-url.ts +17 -0
- package/plugin/dashboard/lib/session-reader.ts +245 -0
- package/plugin/dashboard/lib/status.ts +24 -0
- package/plugin/dashboard/lib/types.ts +145 -0
- package/plugin/dashboard/lib/utils.ts +6 -0
- package/plugin/dashboard/next.config.ts +7 -0
- package/plugin/dashboard/package-lock.json +10275 -0
- package/plugin/dashboard/package.json +37 -0
- package/plugin/dashboard/postcss.config.mjs +7 -0
- package/plugin/dashboard/public/claude-smart-icon.png +0 -0
- package/plugin/dashboard/tsconfig.json +34 -0
- package/plugin/hooks/codex-hooks.json +67 -0
- package/plugin/hooks/hooks.json +111 -0
- package/plugin/pyproject.toml +49 -0
- package/plugin/scripts/_codex_env.sh +27 -0
- package/plugin/scripts/_lib.sh +325 -0
- package/plugin/scripts/backend-service.sh +208 -0
- package/plugin/scripts/cli.sh +40 -0
- package/plugin/scripts/dashboard-build.sh +139 -0
- package/plugin/scripts/dashboard-open.sh +107 -0
- package/plugin/scripts/dashboard-service.sh +195 -0
- package/plugin/scripts/ensure-plugin-root.sh +84 -0
- package/plugin/scripts/hook_entry.sh +70 -0
- package/plugin/scripts/smart-install.sh +411 -0
- package/plugin/src/claude_smart/__init__.py +3 -0
- package/plugin/src/claude_smart/cli.py +1273 -0
- package/plugin/src/claude_smart/context_format.py +277 -0
- package/plugin/src/claude_smart/context_inject.py +92 -0
- package/plugin/src/claude_smart/cs_cite.py +236 -0
- package/plugin/src/claude_smart/events/__init__.py +1 -0
- package/plugin/src/claude_smart/events/post_tool.py +148 -0
- package/plugin/src/claude_smart/events/pre_tool.py +52 -0
- package/plugin/src/claude_smart/events/session_end.py +20 -0
- package/plugin/src/claude_smart/events/session_start.py +119 -0
- package/plugin/src/claude_smart/events/stop.py +393 -0
- package/plugin/src/claude_smart/events/user_prompt.py +73 -0
- package/plugin/src/claude_smart/hook.py +114 -0
- package/plugin/src/claude_smart/ids.py +56 -0
- package/plugin/src/claude_smart/internal_call.py +89 -0
- package/plugin/src/claude_smart/optimizer_assistant.py +203 -0
- package/plugin/src/claude_smart/publish.py +71 -0
- package/plugin/src/claude_smart/query_compose.py +51 -0
- package/plugin/src/claude_smart/reflexio_adapter.py +403 -0
- package/plugin/src/claude_smart/runtime.py +52 -0
- package/plugin/src/claude_smart/stall_banner.py +61 -0
- package/plugin/src/claude_smart/state.py +276 -0
- package/plugin/uv.lock +3720 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
import Link from "next/link";
|
|
5
|
+
import {
|
|
6
|
+
BookOpen,
|
|
7
|
+
MessageSquare,
|
|
8
|
+
Sparkles,
|
|
9
|
+
Activity,
|
|
10
|
+
ExternalLink,
|
|
11
|
+
} from "lucide-react";
|
|
12
|
+
import { LearningsBadge } from "@/components/common/learnings-badge";
|
|
13
|
+
import { PageHeader } from "@/components/common/page-header";
|
|
14
|
+
import { StatCard } from "@/components/common/stat-card";
|
|
15
|
+
import { EmptyState } from "@/components/common/empty-state";
|
|
16
|
+
import { Badge } from "@/components/ui/badge";
|
|
17
|
+
import { reflexio } from "@/lib/reflexio-client";
|
|
18
|
+
import { useSettings } from "@/hooks/use-settings";
|
|
19
|
+
import { formatRelative, truncateId } from "@/lib/format";
|
|
20
|
+
import { agentPlaybookStatusLabel } from "@/lib/status";
|
|
21
|
+
import type { AgentPlaybook, SessionSummary, UserPlaybook } from "@/lib/types";
|
|
22
|
+
|
|
23
|
+
export default function DashboardPage() {
|
|
24
|
+
const { reflexioUrl } = useSettings();
|
|
25
|
+
const [sessions, setSessions] = useState<SessionSummary[] | null>(null);
|
|
26
|
+
const [projectSkills, setProjectSkills] = useState<UserPlaybook[] | null>(null);
|
|
27
|
+
const [sharedSkills, setSharedSkills] = useState<AgentPlaybook[] | null>(null);
|
|
28
|
+
const [error, setError] = useState<string | null>(null);
|
|
29
|
+
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
let cancelled = false;
|
|
32
|
+
async function load() {
|
|
33
|
+
setError(null);
|
|
34
|
+
try {
|
|
35
|
+
const [sRes, projectRes, sharedRes] = await Promise.all([
|
|
36
|
+
fetch("/api/sessions", { cache: "no-store" }).then((r) => r.json()),
|
|
37
|
+
reflexio
|
|
38
|
+
.getUserPlaybooks({ reflexioUrl })
|
|
39
|
+
.catch(() => ({ user_playbooks: [] as UserPlaybook[] })),
|
|
40
|
+
reflexio
|
|
41
|
+
.getAgentPlaybooks({ reflexioUrl })
|
|
42
|
+
.catch(() => ({ agent_playbooks: [] as AgentPlaybook[] })),
|
|
43
|
+
]);
|
|
44
|
+
if (cancelled) return;
|
|
45
|
+
setSessions(sRes.sessions ?? []);
|
|
46
|
+
setProjectSkills(projectRes.user_playbooks ?? []);
|
|
47
|
+
setSharedSkills(sharedRes.agent_playbooks ?? []);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
if (!cancelled)
|
|
50
|
+
setError(e instanceof Error ? e.message : "failed to load");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
load();
|
|
54
|
+
return () => {
|
|
55
|
+
cancelled = true;
|
|
56
|
+
};
|
|
57
|
+
}, [reflexioUrl]);
|
|
58
|
+
|
|
59
|
+
// CURRENT project-specific skills arrive as `status: null` (response_model_exclude_none
|
|
60
|
+
// strips the field). Anything else (e.g. "archived", "pending") is excluded.
|
|
61
|
+
const currentProjectSkills = (projectSkills ?? []).filter((p) => p.status == null);
|
|
62
|
+
const approvedSharedSkills = (sharedSkills ?? []).filter(
|
|
63
|
+
(p) => agentPlaybookStatusLabel(p) === "APPROVED",
|
|
64
|
+
);
|
|
65
|
+
const learningInteractionTotal = (sessions ?? []).reduce(
|
|
66
|
+
(acc, s) => acc + s.learning_interaction_count,
|
|
67
|
+
0,
|
|
68
|
+
);
|
|
69
|
+
return (
|
|
70
|
+
<div className="flex-1 overflow-auto">
|
|
71
|
+
<PageHeader
|
|
72
|
+
title="Dashboard"
|
|
73
|
+
description="Overview of claude-smart learning across sessions and projects."
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
<div className="p-6 space-y-6">
|
|
77
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3">
|
|
78
|
+
<StatCard
|
|
79
|
+
label="Sessions recorded"
|
|
80
|
+
value={sessions?.length ?? "—"}
|
|
81
|
+
hint="JSONL buffers on disk"
|
|
82
|
+
icon={Activity}
|
|
83
|
+
/>
|
|
84
|
+
<StatCard
|
|
85
|
+
label="Project-specific skills"
|
|
86
|
+
value={currentProjectSkills.length || "—"}
|
|
87
|
+
hint="current project-specific rules"
|
|
88
|
+
icon={BookOpen}
|
|
89
|
+
/>
|
|
90
|
+
<StatCard
|
|
91
|
+
label="Shared skills"
|
|
92
|
+
value={approvedSharedSkills.length || "—"}
|
|
93
|
+
hint="approved shared rules"
|
|
94
|
+
icon={BookOpen}
|
|
95
|
+
/>
|
|
96
|
+
<StatCard
|
|
97
|
+
label="Interactions with learnings applied"
|
|
98
|
+
value={learningInteractionTotal}
|
|
99
|
+
hint="turns where a skill or preference was cited"
|
|
100
|
+
icon={Sparkles}
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
{error && (
|
|
105
|
+
<div className="rounded-lg border border-destructive/30 bg-destructive/5 text-destructive px-4 py-3 text-sm">
|
|
106
|
+
{error}
|
|
107
|
+
</div>
|
|
108
|
+
)}
|
|
109
|
+
|
|
110
|
+
<section>
|
|
111
|
+
<div className="flex items-center justify-between mb-3">
|
|
112
|
+
<h2 className="text-sm font-semibold">Recent sessions</h2>
|
|
113
|
+
<Link
|
|
114
|
+
href="/sessions"
|
|
115
|
+
className="text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1"
|
|
116
|
+
>
|
|
117
|
+
View all <ExternalLink className="h-3 w-3" />
|
|
118
|
+
</Link>
|
|
119
|
+
</div>
|
|
120
|
+
{sessions && sessions.length > 0 ? (
|
|
121
|
+
<div className="rounded-xl border border-border divide-y divide-border bg-card">
|
|
122
|
+
{sessions.slice(0, 5).map((s) => (
|
|
123
|
+
<Link
|
|
124
|
+
key={s.session_id}
|
|
125
|
+
href={`/sessions/${s.session_id}`}
|
|
126
|
+
className="flex items-center justify-between px-4 py-3 hover:bg-accent/40 transition-colors"
|
|
127
|
+
>
|
|
128
|
+
<div className="min-w-0 flex items-center gap-3">
|
|
129
|
+
<MessageSquare className="h-4 w-4 text-muted-foreground shrink-0" />
|
|
130
|
+
<code className="font-mono text-xs truncate">
|
|
131
|
+
{truncateId(s.session_id, 10, 6)}
|
|
132
|
+
</code>
|
|
133
|
+
<LearningsBadge count={s.learning_interaction_count} />
|
|
134
|
+
</div>
|
|
135
|
+
<div className="flex items-center gap-4 text-xs text-muted-foreground shrink-0">
|
|
136
|
+
<span>{s.turn_count} turns</span>
|
|
137
|
+
<span>{formatRelative(s.last_activity)}</span>
|
|
138
|
+
</div>
|
|
139
|
+
</Link>
|
|
140
|
+
))}
|
|
141
|
+
</div>
|
|
142
|
+
) : (
|
|
143
|
+
<EmptyState
|
|
144
|
+
icon={MessageSquare}
|
|
145
|
+
title="No sessions yet"
|
|
146
|
+
description="Run Claude Code with claude-smart enabled — sessions will appear here."
|
|
147
|
+
/>
|
|
148
|
+
)}
|
|
149
|
+
</section>
|
|
150
|
+
|
|
151
|
+
<section>
|
|
152
|
+
<div className="flex items-center justify-between mb-3">
|
|
153
|
+
<h2 className="text-sm font-semibold">Recent skills</h2>
|
|
154
|
+
<Link
|
|
155
|
+
href="/skills"
|
|
156
|
+
className="text-xs text-muted-foreground hover:text-foreground inline-flex items-center gap-1"
|
|
157
|
+
>
|
|
158
|
+
View all <ExternalLink className="h-3 w-3" />
|
|
159
|
+
</Link>
|
|
160
|
+
</div>
|
|
161
|
+
{currentProjectSkills.length > 0 || approvedSharedSkills.length > 0 ? (
|
|
162
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
163
|
+
{currentProjectSkills.slice(0, 2).map((p) => (
|
|
164
|
+
<Link
|
|
165
|
+
key={`project:${p.user_playbook_id}`}
|
|
166
|
+
href={`/skills/project/${p.user_playbook_id}`}
|
|
167
|
+
className="block rounded-xl border border-border bg-card p-4 hover:bg-accent/40 transition-colors"
|
|
168
|
+
>
|
|
169
|
+
<div className="flex items-center justify-between gap-2 mb-2">
|
|
170
|
+
<Badge variant="outline" className="font-mono text-[10px]">
|
|
171
|
+
{p.agent_version || "default"}
|
|
172
|
+
</Badge>
|
|
173
|
+
<Badge variant="secondary" className="text-[10px]">
|
|
174
|
+
project-specific
|
|
175
|
+
</Badge>
|
|
176
|
+
<span className="text-[11px] text-muted-foreground">
|
|
177
|
+
{formatRelative(p.created_at)}
|
|
178
|
+
</span>
|
|
179
|
+
</div>
|
|
180
|
+
<p className="text-sm line-clamp-3">{p.content}</p>
|
|
181
|
+
{p.trigger && (
|
|
182
|
+
<p className="text-xs text-muted-foreground mt-2 line-clamp-1">
|
|
183
|
+
<span className="font-medium">trigger:</span> {p.trigger}
|
|
184
|
+
</p>
|
|
185
|
+
)}
|
|
186
|
+
</Link>
|
|
187
|
+
))}
|
|
188
|
+
{approvedSharedSkills.slice(0, 2).map((p) => (
|
|
189
|
+
<Link
|
|
190
|
+
key={`shared:${p.agent_playbook_id}`}
|
|
191
|
+
href={`/skills/shared/${p.agent_playbook_id}`}
|
|
192
|
+
className="block rounded-xl border border-border bg-card p-4 hover:bg-accent/40 transition-colors"
|
|
193
|
+
>
|
|
194
|
+
<div className="flex items-center justify-between gap-2 mb-2">
|
|
195
|
+
<div className="flex items-center gap-2">
|
|
196
|
+
<Badge variant="outline" className="font-mono text-[10px]">
|
|
197
|
+
{p.agent_version || "default"}
|
|
198
|
+
</Badge>
|
|
199
|
+
<Badge variant="secondary" className="text-[10px]">
|
|
200
|
+
shared
|
|
201
|
+
</Badge>
|
|
202
|
+
</div>
|
|
203
|
+
<span className="text-[11px] text-muted-foreground">
|
|
204
|
+
{formatRelative(p.created_at)}
|
|
205
|
+
</span>
|
|
206
|
+
</div>
|
|
207
|
+
<p className="text-sm line-clamp-3">{p.content}</p>
|
|
208
|
+
{p.trigger && (
|
|
209
|
+
<p className="text-xs text-muted-foreground mt-2 line-clamp-1">
|
|
210
|
+
<span className="font-medium">trigger:</span> {p.trigger}
|
|
211
|
+
</p>
|
|
212
|
+
)}
|
|
213
|
+
</Link>
|
|
214
|
+
))}
|
|
215
|
+
</div>
|
|
216
|
+
) : (
|
|
217
|
+
<EmptyState
|
|
218
|
+
icon={BookOpen}
|
|
219
|
+
title="No skills yet"
|
|
220
|
+
description="Keep using Claude with claude-smart enabled. Skills are extracted automatically when patterns emerge."
|
|
221
|
+
/>
|
|
222
|
+
)}
|
|
223
|
+
</section>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
2
|
+
@import "tw-animate-css";
|
|
3
|
+
@import "shadcn/tailwind.css";
|
|
4
|
+
|
|
5
|
+
@custom-variant dark (&:is(.dark *));
|
|
6
|
+
|
|
7
|
+
@theme inline {
|
|
8
|
+
--color-background: var(--background);
|
|
9
|
+
--color-foreground: var(--foreground);
|
|
10
|
+
--font-sans: var(--font-sans);
|
|
11
|
+
--font-mono: var(--font-geist-mono);
|
|
12
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
13
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
14
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
15
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
16
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
17
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
18
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
19
|
+
--color-sidebar: var(--sidebar);
|
|
20
|
+
--color-chart-5: var(--chart-5);
|
|
21
|
+
--color-chart-4: var(--chart-4);
|
|
22
|
+
--color-chart-3: var(--chart-3);
|
|
23
|
+
--color-chart-2: var(--chart-2);
|
|
24
|
+
--color-chart-1: var(--chart-1);
|
|
25
|
+
--color-ring: var(--ring);
|
|
26
|
+
--color-input: var(--input);
|
|
27
|
+
--color-border: var(--border);
|
|
28
|
+
--color-destructive: var(--destructive);
|
|
29
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
30
|
+
--color-accent: var(--accent);
|
|
31
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
32
|
+
--color-muted: var(--muted);
|
|
33
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
34
|
+
--color-secondary: var(--secondary);
|
|
35
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
36
|
+
--color-primary: var(--primary);
|
|
37
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
38
|
+
--color-popover: var(--popover);
|
|
39
|
+
--color-card-foreground: var(--card-foreground);
|
|
40
|
+
--color-card: var(--card);
|
|
41
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
42
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
43
|
+
--radius-lg: var(--radius);
|
|
44
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
45
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
46
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
47
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
:root {
|
|
51
|
+
--background: oklch(1 0 0);
|
|
52
|
+
--foreground: oklch(0.145 0 0);
|
|
53
|
+
--card: oklch(1 0 0);
|
|
54
|
+
--card-foreground: oklch(0.145 0 0);
|
|
55
|
+
--popover: oklch(1 0 0);
|
|
56
|
+
--popover-foreground: oklch(0.145 0 0);
|
|
57
|
+
--primary: oklch(0.205 0 0);
|
|
58
|
+
--primary-foreground: oklch(0.985 0 0);
|
|
59
|
+
--secondary: oklch(0.97 0 0);
|
|
60
|
+
--secondary-foreground: oklch(0.205 0 0);
|
|
61
|
+
--muted: oklch(0.97 0 0);
|
|
62
|
+
--muted-foreground: oklch(0.556 0 0);
|
|
63
|
+
--accent: oklch(0.97 0 0);
|
|
64
|
+
--accent-foreground: oklch(0.205 0 0);
|
|
65
|
+
--destructive: oklch(0.577 0.245 27.325);
|
|
66
|
+
--border: oklch(0.922 0 0);
|
|
67
|
+
--input: oklch(0.922 0 0);
|
|
68
|
+
--ring: oklch(0.708 0 0);
|
|
69
|
+
--chart-1: oklch(0.809 0.105 251.813);
|
|
70
|
+
--chart-2: oklch(0.623 0.214 259.815);
|
|
71
|
+
--chart-3: oklch(0.546 0.245 262.881);
|
|
72
|
+
--chart-4: oklch(0.488 0.243 264.376);
|
|
73
|
+
--chart-5: oklch(0.424 0.199 265.638);
|
|
74
|
+
--radius: 0.625rem;
|
|
75
|
+
--sidebar: oklch(0.985 0 0);
|
|
76
|
+
--sidebar-foreground: oklch(0.145 0 0);
|
|
77
|
+
--sidebar-primary: oklch(0.205 0 0);
|
|
78
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
79
|
+
--sidebar-accent: oklch(0.97 0 0);
|
|
80
|
+
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
81
|
+
--sidebar-border: oklch(0.922 0 0);
|
|
82
|
+
--sidebar-ring: oklch(0.708 0 0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.dark {
|
|
86
|
+
--background: oklch(0.145 0 0);
|
|
87
|
+
--foreground: oklch(0.985 0 0);
|
|
88
|
+
--card: oklch(0.205 0 0);
|
|
89
|
+
--card-foreground: oklch(0.985 0 0);
|
|
90
|
+
--popover: oklch(0.205 0 0);
|
|
91
|
+
--popover-foreground: oklch(0.985 0 0);
|
|
92
|
+
--primary: oklch(0.922 0 0);
|
|
93
|
+
--primary-foreground: oklch(0.205 0 0);
|
|
94
|
+
--secondary: oklch(0.269 0 0);
|
|
95
|
+
--secondary-foreground: oklch(0.985 0 0);
|
|
96
|
+
--muted: oklch(0.269 0 0);
|
|
97
|
+
--muted-foreground: oklch(0.708 0 0);
|
|
98
|
+
--accent: oklch(0.269 0 0);
|
|
99
|
+
--accent-foreground: oklch(0.985 0 0);
|
|
100
|
+
--destructive: oklch(0.704 0.191 22.216);
|
|
101
|
+
--border: oklch(1 0 0 / 10%);
|
|
102
|
+
--input: oklch(1 0 0 / 15%);
|
|
103
|
+
--ring: oklch(0.556 0 0);
|
|
104
|
+
--chart-1: oklch(0.809 0.105 251.813);
|
|
105
|
+
--chart-2: oklch(0.623 0.214 259.815);
|
|
106
|
+
--chart-3: oklch(0.546 0.245 262.881);
|
|
107
|
+
--chart-4: oklch(0.488 0.243 264.376);
|
|
108
|
+
--chart-5: oklch(0.424 0.199 265.638);
|
|
109
|
+
--sidebar: oklch(0.205 0 0);
|
|
110
|
+
--sidebar-foreground: oklch(0.985 0 0);
|
|
111
|
+
--sidebar-primary: oklch(0.488 0.243 264.376);
|
|
112
|
+
--sidebar-primary-foreground: oklch(0.985 0 0);
|
|
113
|
+
--sidebar-accent: oklch(0.269 0 0);
|
|
114
|
+
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
115
|
+
--sidebar-border: oklch(1 0 0 / 10%);
|
|
116
|
+
--sidebar-ring: oklch(0.556 0 0);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@layer base {
|
|
120
|
+
* {
|
|
121
|
+
@apply border-border outline-ring/50;
|
|
122
|
+
}
|
|
123
|
+
body {
|
|
124
|
+
@apply bg-background text-foreground;
|
|
125
|
+
}
|
|
126
|
+
html {
|
|
127
|
+
@apply font-sans;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Inter } from "next/font/google";
|
|
3
|
+
import "./globals.css";
|
|
4
|
+
import { Providers } from "./providers";
|
|
5
|
+
import { Sidebar } from "@/components/layout/sidebar";
|
|
6
|
+
import { TopBar } from "@/components/layout/top-bar";
|
|
7
|
+
import { StallBanner } from "@/components/stall-banner";
|
|
8
|
+
|
|
9
|
+
const inter = Inter({
|
|
10
|
+
variable: "--font-sans",
|
|
11
|
+
subsets: ["latin"],
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const metadata: Metadata = {
|
|
15
|
+
title: "Claude-Smart Dashboard",
|
|
16
|
+
description: "Manage sessions, preferences, skills, and configuration",
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default function RootLayout({
|
|
20
|
+
children,
|
|
21
|
+
}: Readonly<{
|
|
22
|
+
children: React.ReactNode;
|
|
23
|
+
}>) {
|
|
24
|
+
return (
|
|
25
|
+
<html lang="en" className={`${inter.variable} h-full`} suppressHydrationWarning>
|
|
26
|
+
<body className="h-full flex flex-col antialiased font-sans">
|
|
27
|
+
<Providers>
|
|
28
|
+
<StallBanner />
|
|
29
|
+
<TopBar />
|
|
30
|
+
<div className="flex flex-1 min-h-0">
|
|
31
|
+
<aside className="hidden lg:block w-60 border-r border-border shrink-0">
|
|
32
|
+
<Sidebar />
|
|
33
|
+
</aside>
|
|
34
|
+
<main className="flex-1 min-w-0 flex flex-col">{children}</main>
|
|
35
|
+
</div>
|
|
36
|
+
</Providers>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
);
|
|
40
|
+
}
|