mirror of
https://github.com/0xWheatyz/handler.git
synced 2026-09-06 23:46:24 +00:00
Turn the Claude Login page into a full Claude management page
The dashboard's Claude page now manages the whole Claude Code install agents run on, not just the account login: - Skills: operator-authored SKILL.md rows, synced to each worker's user-level ~/.claude/skills at every launch. Managed dirs carry a .handler-managed marker so deletions in the UI propagate while hand-installed skills survive. - Connectors: MCP servers (stdio/http/sse) written per-launch as .claude/mcp-servers.json and passed to claude via --mcp-config, so nothing lands in the managed repo's tracked tree. - Plugins: marketplace-pinned plugins folded into generated settings as extraKnownMarketplaces + enabledPlugins, installing on boot of headless runs. - Permissions: defaultMode override plus allow/deny/ask rules merged over the env baseline into every generated settings.json. All of it is plain DB state (new claude_skills / claude_connectors / claude_plugins / claude_config tables, migration 0010) edited through the new admin-gated /claude/* API routes and applied by the control container at spawn and resume — changes reach the next launch of every agent with no redeploy. The login flow moved into the page's Account tab unchanged; /login redirects to /claude for old bookmarks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019f42XmjtVsc3zQ9Dhn6DqZ
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
/* Claude Login — drive the bundled `claude /login` OAuth flow on the host from the web UI.
|
||||
/* Claude account login panel (the Account tab of the Claude page) — drives the bundled
|
||||
* `claude /login` OAuth flow on the host from the web UI.
|
||||
*
|
||||
* Click "Log in to Claude" → a small OAuth-style popup window opens (like "Sign in with
|
||||
* Google") and the worker drives `claude /login` in the control container, selecting the
|
||||
@@ -27,7 +28,7 @@ function openLoginPopup(url: string): Window | null {
|
||||
);
|
||||
}
|
||||
|
||||
export function LoginSection() {
|
||||
export function ClaudeLoginPanel() {
|
||||
const s = useDashboard();
|
||||
const { status, url, message } = s.claudeLogin;
|
||||
const [code, setCode] = useState("");
|
||||
@@ -66,16 +67,13 @@ export function LoginSection() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="section-head">
|
||||
<div className="section-title">Claude Login</div>
|
||||
<div className="section-desc">
|
||||
Log Claude Code in on the host so agents can run. This drives{" "}
|
||||
<span className="mono">claude /login</span> in the control container and picks the
|
||||
Claude account with a subscription.
|
||||
</div>
|
||||
<div className="faint" style={{ fontSize: "var(--text-sm)" }}>
|
||||
Log Claude Code in on the host so agents can run. This drives{" "}
|
||||
<span className="mono">claude /login</span> in the control container and picks the
|
||||
Claude account with a subscription.
|
||||
</div>
|
||||
|
||||
<div className="section-body" style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: 16, marginTop: 14 }}>
|
||||
{message && (
|
||||
<Callout tone={status === "error" ? "danger" : status === "done" ? "success" : "info"}>
|
||||
{message}
|
||||
|
||||
Reference in New Issue
Block a user