Initial curated ITWorx_MCP_Hub source from 368fba691ea8d23403b4d56b53b5ec670d7c5020

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:36:21 +02:00
commit cb5be898ea
663 files changed
+82674

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
export function Brand({ compact = false }: { compact?: boolean }) {
return (
<span className={compact ? "brand preauth-brand" : "brand"}>
<span className="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" width="18" height="18" fill="none">
<path d="M5.8 9.5 12 5.9l6.2 3.6v7L12 20.1l-6.2-3.6v-7Z" stroke="currentColor" strokeWidth="1.5" />
<circle cx="12" cy="13" r="2.7" fill="currentColor" />
<path d="M12 6v4.2M6 9.7l3.7 2.1M18 9.7l-3.7 2.1" stroke="currentColor" strokeWidth="1.4" />
</svg>
</span>
<span><strong>ITWorx</strong><small>MCP Hub</small></span>
</span>
);
}
+4
View File
@@ -0,0 +1,4 @@
import { routeTitle } from "../contracts";
import { basePath } from "../routing";
export function Breadcrumbs({ path, navigate }: { path: string; navigate: (next: string) => void }) { return <nav className="breadcrumbs" aria-label="Breadcrumb"><a href="/" onClick={(event) => { event.preventDefault(); navigate("/"); }}>Overview</a><span aria-hidden="true">/</span><strong>{routeTitle(basePath(path))}</strong></nav>; }
+66
View File
@@ -0,0 +1,66 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { availableNavigation } from "../navigation";
import { Icon } from "./Icon";
import { Modal } from "./Modal";
export function CommandMenu({
open,
canReadAudit,
navigate,
onClose,
}: {
open: boolean;
canReadAudit: boolean;
navigate: (next: string) => void;
onClose: () => void;
}) {
const [query, setQuery] = useState("");
const inputRef = useRef<HTMLInputElement>(null);
const items = useMemo(() => availableNavigation(canReadAudit), [canReadAudit]);
const results = useMemo(() => {
const needle = query.trim().toLowerCase();
if (!needle) return items;
return items.filter((item) => `${item.label} ${item.description}`.toLowerCase().includes(needle));
}, [items, query]);
useEffect(() => {
if (!open) return;
setQuery("");
const focusTimer = window.setTimeout(() => inputRef.current?.focus(), 0);
return () => window.clearTimeout(focusTimer);
}, [open]);
const select = (href: string) => {
onClose();
navigate(href);
};
return (
<Modal open={open} title="Quick jump" onClose={onClose} className="command-modal">
<label className="command-search">
<span className="sr-only">Find a workspace</span>
<Icon name="search" size={17} />
<input
ref={inputRef}
value={query}
onChange={(event) => setQuery(event.target.value)}
placeholder="Find projects, catalog, policies…"
autoComplete="off"
/>
<kbd>Esc</kbd>
</label>
<div className="command-results" aria-live="polite">
{results.length ? results.map((item) => (
<button type="button" className="command-result" key={item.href} onClick={() => select(item.href)}>
<span className="command-result-icon"><Icon name={item.icon} /></span>
<span><strong>{item.label}</strong><small>{item.description}</small></span>
<Icon name="arrow" size={16} />
</button>
)) : (
<div className="command-empty"><strong>No workspace found</strong><span>Try a broader name or capability.</span></div>
)}
</div>
<p className="command-hint">Navigate without leaving the keyboard. Access-controlled destinations remain hidden.</p>
</Modal>
);
}
+96
View File
@@ -0,0 +1,96 @@
import { Fragment, useState } from "react";
import type { ResourceKind, ResourcePage, ResourceRecord } from "../contracts";
import { Modal } from "./Modal";
import { StatusPill } from "./StatusPill";
export type Density = "comfortable" | "compact";
export type ColumnKey = "name" | "status" | "project" | "summary" | "risk" | "decision" | "actions";
const ALL_COLUMNS: Record<ResourceKind, ColumnKey[]> = {
projects: ["name", "status", "project", "summary"],
servers: ["name", "status", "project", "summary"],
tools: ["name", "status", "project", "summary", "risk", "actions"],
connectors: ["name", "status", "project", "summary"],
clients: ["name", "status", "project", "summary", "actions"],
policies: ["name", "status", "project", "summary"],
audit: ["name", "status", "project", "summary", "decision"],
};
export function columnsFor(kind: ResourceKind): ColumnKey[] { return ALL_COLUMNS[kind]; }
export function DataTable({
data, kind, density, visibleColumns, onClientAction, onConfig, onTest,
}: {
data: ResourcePage;
kind: ResourceKind;
density: Density;
visibleColumns: ColumnKey[];
onClientAction: (id: string, action: "disable" | "revoke") => void;
onConfig: (id: string) => void;
onTest: (row: ResourceRecord) => void;
}) {
const show = (column: ColumnKey) => visibleColumns.includes(column);
const [confirmingAction, setConfirmingAction] = useState<{ id: string; action: "disable" | "revoke"; name: string } | null>(null);
const actions = (row: ResourceRecord) => {
if (kind === "clients" && show("actions")) return <div className="inline-actions"><button className="button button-small" onClick={() => setConfirmingAction({ id: row.id, action: "disable", name: row.name })} disabled={row.status !== "healthy"}>Disable</button><button className="button button-small button-danger" onClick={() => setConfirmingAction({ id: row.id, action: "revoke", name: row.name })} disabled={row.status === "unavailable"}>Revoke</button><button className="button button-small button-secondary" onClick={() => onConfig(row.id)}>Config</button></div>;
if (kind === "tools" && show("actions")) return <div className="inline-actions"><button className="button button-small button-secondary" onClick={() => onTest(row)}>Readiness</button></div>;
return null;
};
return (
<Fragment>
<div className={`table-wrap desktop-data-table table-kind-${kind} density-${density}`} role="region" tabIndex={0} aria-label={`${kind} records table`}>
<table>
<caption className="sr-only">{kind} records</caption>
<thead>
<tr>
{show("name") && <th>Name</th>}
{show("status") && <th>Status</th>}
{show("project") && <th>Project</th>}
{show("summary") && <th>Summary</th>}
{kind === "tools" && show("risk") && <th>Risk</th>}
{kind === "audit" && show("decision") && <th>Decision / trace</th>}
{(kind === "clients" || kind === "tools") && show("actions") && <th>Actions</th>}
</tr>
</thead>
<tbody>
{data.rows.map((row) => (
<tr key={row.id}>
{show("name") && <td><strong className="long-name">{row.name}</strong><small>{row.id}</small></td>}
{show("status") && <td><StatusPill value={row.status} /></td>}
{show("project") && <td>{row.project ?? "—"}</td>}
{show("summary") && <td>{row.summary}</td>}
{kind === "tools" && show("risk") && <td>{row.risk ?? "R0"}</td>}
{kind === "audit" && show("decision") && <td>{row.decision ?? "unknown"}{row.traceId && <small>{row.traceId}</small>}</td>}
{(kind === "clients" || kind === "tools") && show("actions") && <td>{actions(row)}</td>}
</tr>
))}
</tbody>
</table>
</div>
<div className="mobile-record-list" aria-label={`${kind} records`}>
{data.rows.map((row) => <article className="mobile-record" key={row.id}><div className="mobile-record-heading"><div><strong>{row.name}</strong><small>{row.id}</small></div>{show("status") && <StatusPill value={row.status} />}</div><dl>{show("project") && <><dt>Project</dt><dd>{row.project ?? "—"}</dd></>}{show("summary") && <><dt>Summary</dt><dd>{row.summary}</dd></>}{kind === "tools" && show("risk") && <><dt>Risk</dt><dd><span className="risk-label" title="Risk classification">{row.risk ?? "R0"}</span></dd></>}{kind === "audit" && show("decision") && <><dt>Decision / trace</dt><dd>{row.decision ?? "unknown"}{row.traceId && <small>{row.traceId}</small>}</dd></>}</dl>{actions(row)}</article>)}
</div>
<Modal
open={confirmingAction !== null}
title={`${confirmingAction?.action === "disable" ? "Disable" : "Revoke"} ${confirmingAction?.name}?`}
onClose={() => setConfirmingAction(null)}
>
<p>This action is logged and takes effect immediately.</p>
<div className="state-actions">
<button
className="button"
data-testid="confirm-action"
onClick={() => {
if (!confirmingAction) return;
onClientAction(confirmingAction.id, confirmingAction.action);
setConfirmingAction(null);
}}
>
Confirm
</button>
<button className="button button-secondary" onClick={() => setConfirmingAction(null)}>Cancel</button>
</div>
</Modal>
</Fragment>
);
}
+12
View File
@@ -0,0 +1,12 @@
import { Icon } from "./Icon";
export function ErrorPanel({ message, expired, retry }: { message: string; expired?: boolean; retry: () => void }) {
return <section className="panel state-panel error-state" role="alert">
<div className="state-icon" aria-hidden="true">!</div>
<p className="eyebrow">Recoverable interruption</p>
<h2>{expired ? "Session expired" : "Management data unavailable"}</h2>
<p>{message}</p>
<div className="state-actions"><button className="button" onClick={retry}><Icon name="refresh" size={14} />{expired ? "Check session again" : "Retry connection"}</button>{expired ? <a className="button button-secondary" href="/auth/login">Re-authenticate</a> : null}</div>
<small className="state-footnote">No cached management data is shown while the control-plane response is untrusted.</small>
</section>;
}
+49
View File
@@ -0,0 +1,49 @@
import type { ReactNode } from "react";
export type IconName =
| "overview"
| "projects"
| "servers"
| "catalog"
| "connectors"
| "clients"
| "policies"
| "audit"
| "operations"
| "settings"
| "search"
| "refresh"
| "arrow";
const paths: Record<IconName, ReactNode> = {
overview: <><path d="M4 13h6V4H4v9Zm0 7h6v-4H4v4Zm10 0h6v-9h-6v9Zm0-16v4h6V4h-6Z" /></>,
projects: <><path d="M3.5 7.5h6l1.8 2H20.5v8.8a1.7 1.7 0 0 1-1.7 1.7H5.2a1.7 1.7 0 0 1-1.7-1.7V7.5Z" /><path d="M5.5 7.5V5.7A1.7 1.7 0 0 1 7.2 4h4.2l1.7 2h4.7a1.7 1.7 0 0 1 1.7 1.7v1.8" /></>,
servers: <><rect x="4" y="4" width="16" height="6" rx="1.5" /><rect x="4" y="14" width="16" height="6" rx="1.5" /><path d="M8 7h.01M8 17h.01M12 7h5M12 17h5" /></>,
catalog: <><path d="M4 5.5A1.5 1.5 0 0 1 5.5 4H10v16H5.5A1.5 1.5 0 0 1 4 18.5v-13ZM14 4h4.5A1.5 1.5 0 0 1 20 5.5v13a1.5 1.5 0 0 1-1.5 1.5H14V4Z" /><path d="M7 8h1M16 8h1" /></>,
connectors: <><circle cx="6" cy="12" r="2.5" /><circle cx="18" cy="6" r="2.5" /><circle cx="18" cy="18" r="2.5" /><path d="m8.2 10.9 7.6-3.8M8.2 13.1l7.6 3.8" /></>,
clients: <><circle cx="9" cy="8" r="3" /><path d="M3.8 19c.5-3.4 2.2-5 5.2-5s4.7 1.6 5.2 5M16 10h4M18 8v4" /></>,
policies: <><path d="M12 3.5 19 6v5.2c0 4.4-2.3 7.4-7 9.3-4.7-1.9-7-4.9-7-9.3V6l7-2.5Z" /><path d="m8.5 12 2.2 2.2 4.8-5" /></>,
audit: <><path d="M6 3.5h9L19 7v13.5H6V3.5Z" /><path d="M15 3.5V7h4M9 11h6M9 15h6" /><circle cx="6" cy="18" r="2.5" /></>,
operations: <><path d="M4 17.5h3l2.2-5 3.1 7 2.5-11 2 6H20" /></>,
settings: <><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.9l.1.1-2.8 2.8-.1-.1a1.7 1.7 0 0 0-1.9-.3 1.7 1.7 0 0 0-1 1.6v.2h-4v-.2a1.7 1.7 0 0 0-1-1.6 1.7 1.7 0 0 0-1.9.3l-.1.1L4.2 17l.1-.1a1.7 1.7 0 0 0 .3-1.9A1.7 1.7 0 0 0 3 14H2.8v-4H3a1.7 1.7 0 0 0 1.6-1 1.7 1.7 0 0 0-.3-1.9L4.2 7 7 4.2l.1.1a1.7 1.7 0 0 0 1.9.3 1.7 1.7 0 0 0 1-1.6v-.2h4V3a1.7 1.7 0 0 0 1 1.6 1.7 1.7 0 0 0 1.9-.3l.1-.1L19.8 7l-.1.1a1.7 1.7 0 0 0-.3 1.9 1.7 1.7 0 0 0 1.6 1h.2v4H21a1.7 1.7 0 0 0-1.6 1Z" /></>,
search: <><circle cx="10.5" cy="10.5" r="6" /><path d="m15 15 5 5" /></>,
refresh: <><path d="M20 6v5h-5M4 18v-5h5" /><path d="M18.2 9A7 7 0 0 0 6.1 6.2L4 11M5.8 15A7 7 0 0 0 17.9 17.8L20 13" /></>,
arrow: <><path d="M5 12h14M14 7l5 5-5 5" /></>,
};
export function Icon({ name, size = 18 }: { name: IconName; size?: number }) {
return (
<svg
aria-hidden="true"
className="icon"
fill="none"
height={size}
viewBox="0 0 24 24"
width={size}
>
<g stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.6">
{paths[name]}
</g>
</svg>
);
}
+7
View File
@@ -0,0 +1,7 @@
export function LoadingPanel() {
return <section className="panel state-panel loading-state" aria-live="polite" aria-busy="true">
<div className="state-orbit" aria-hidden="true"><span /><span /><span /></div>
<div><p className="eyebrow">Synchronizing control plane</p><h2>Loading operational data</h2><p>Checking the authenticated session and refreshing bounded management views.</p></div>
<div className="loading-skeleton" aria-hidden="true"><span /><span /><span /></div>
</section>;
}
+135
View File
@@ -0,0 +1,135 @@
import type { Health } from "../contracts";
type TopologyProps = {
hub?: Health;
gateway?: Health;
connectors?: Array<{ name: string; state: Health }>;
compact?: boolean;
};
const labels: Record<Health, string> = {
healthy: "healthy",
degraded: "degraded",
unavailable: "unavailable",
unknown: "unknown",
};
function shortConnectorName(name: string): string {
const normalized = name.toLowerCase();
if (normalized.includes("gitea")) return "Gitea";
if (normalized.includes("unraid")) return "Unraid";
if (normalized.includes("knowledge")) return "Knowledge";
if (normalized.includes("mobility")) return "Mobility";
return name.length > 13 ? `${name.slice(0, 12)}…` : name;
}
export function McpTopology({ hub = "healthy", gateway = "healthy", connectors = [], compact = false }: TopologyProps) {
const targets = connectors.length
? connectors.slice(0, 3).map((connector) => ({ label: shortConnectorName(connector.name), state: connector.state }))
: [
{ label: "Gitea", state: "healthy" as const },
{ label: "Knowledge", state: "healthy" as const },
{ label: "Unraid", state: "healthy" as const },
];
const hiddenTargets = Math.max(0, connectors.length - targets.length);
const description = `Client requests pass through a ${labels[hub]} policy boundary and a ${labels[gateway]} MCP gateway to ${connectors.length || 3} scoped connector${(connectors.length || 3) === 1 ? "" : "s"}.`;
return (
<figure className={compact ? "topology topology-compact" : "topology"} aria-label="Governed MCP request path">
<div className="topology-head">
<span><span className={`signal-dot signal-${hub}`} aria-hidden="true" />Governed request path</span>
<small>{connectors.length ? `${connectors.length} live routes` : "Deny by default"}</small>
</div>
<div className="topology-canvas" aria-hidden="true">
<svg viewBox="0 0 620 244" preserveAspectRatio="xMidYMid meet">
<defs>
<linearGradient id="flow-gradient" x1="0" x2="1">
<stop offset="0" stopColor="currentColor" stopOpacity="0.18" />
<stop offset="0.5" stopColor="currentColor" stopOpacity="0.9" />
<stop offset="1" stopColor="currentColor" stopOpacity="0.18" />
</linearGradient>
</defs>
<g className="topology-links">
<path d="M118 122H202" />
<path d="M318 122H390" />
<path d="M494 122H524V48H542" />
<path d="M494 122H542" />
<path d="M494 122H524V196H542" />
</g>
<g className="topology-flow">
<path d="M118 122H202" />
<path d="M318 122H390" />
<path d="M494 122H524V48H542" />
<path d="M494 122H542" />
<path d="M494 122H524V196H542" />
</g>
<g className="topology-node topology-node-client">
<rect x="20" y="92" width="98" height="60" rx="10" />
<circle cx="45" cy="115" r="8" />
<path d="M34 140c2-8 6-11 11-11s9 3 11 11" />
<text x="67" y="116">Client</text>
<text className="topology-sub" x="67" y="135">Codex / MCP</text>
</g>
<g className={`topology-node topology-node-${hub}`}>
<rect x="202" y="84" width="116" height="76" rx="10" />
<path d="M228 105.5 240 110v9c0 8-4 13-12 17-8-4-12-9-12-17v-9l12-4.5Z" />
<path d="m222 120 4 4 8-9" />
<text x="250" y="112">Policy gate</text>
<text className="topology-sub" x="250" y="132">Scope + identity</text>
<circle className="topology-state" cx="300" cy="99" r="4" />
</g>
<g className={`topology-node topology-node-${gateway}`}>
<rect x="390" y="84" width="104" height="76" rx="10" />
<circle cx="416" cy="122" r="13" />
<circle cx="416" cy="122" r="4" />
<text x="438" y="116">Gateway</text>
<text className="topology-sub" x="438" y="136">ContextForge</text>
<circle className="topology-state" cx="476" cy="99" r="4" />
</g>
{targets.map((target, index) => {
const y = [28, 102, 176][index] ?? 102;
return (
<g className={`topology-target topology-node-${target.state}`} key={`${target.label}-${index}`}>
<rect x="542" y={y} width="70" height="40" rx="8" />
<circle className="topology-state" cx="555" cy={y + 20} r="4" />
<text x="565" y={y + 24}>{target.label}</text>
</g>
);
})}
</svg>
</div>
<div className="topology-mobile-flow" aria-hidden="true">
<div className="topology-mobile-node">
<span className="topology-mobile-mark">C</span>
<span><strong>Client</strong><small>Codex / MCP</small></span>
</div>
<span className="topology-mobile-link" />
<div className={`topology-mobile-node topology-node-${hub}`}>
<span className="topology-mobile-mark">P</span>
<span><strong>Policy gate</strong><small>Scope + identity</small></span>
<i className="topology-state" />
</div>
<span className="topology-mobile-link" />
<div className={`topology-mobile-node topology-node-${gateway}`}>
<span className="topology-mobile-mark">G</span>
<span><strong>Gateway</strong><small>ContextForge</small></span>
<i className="topology-state" />
</div>
<span className="topology-mobile-link" />
<div className="topology-mobile-targets">
{targets.map((target, index) => <span className={`topology-node-${target.state}`} key={`${target.label}-mobile-${index}`}><i className="topology-state" />{target.label}</span>)}
{hiddenTargets > 0 ? <span>+{hiddenTargets} routes</span> : null}
</div>
</div>
<figcaption>
<span>{description}</span>
{hiddenTargets > 0 ? <small>+{hiddenTargets} additional scoped route{hiddenTargets === 1 ? "" : "s"}</small> : null}
</figcaption>
</figure>
);
}
+4
View File
@@ -0,0 +1,4 @@
import type { Health } from "../contracts";
import { StatusPill } from "./StatusPill";
export function MetricCard({ label, value, detail, status }: { label: string; value: string; detail: string; status?: Health }) { return <article className="metric-card"><div className="metric-heading"><span>{label}</span>{status && <StatusPill value={status} />}</div><strong>{value}</strong><p>{detail}</p></article>; }
+77
View File
@@ -0,0 +1,77 @@
import { useEffect, useId, useRef, type ReactNode } from "react";
export function Modal({ open, title, onClose, children, className = "" }: { open: boolean; title: string; onClose: () => void; children: ReactNode; className?: string }) {
const dialogRef = useRef<HTMLDivElement>(null);
const onCloseRef = useRef(onClose);
const titleId = useId();
onCloseRef.current = onClose;
useEffect(() => {
if (!open) return;
// Kept in its own effect, keyed only on `open` (not `onClose`): if this
// ran on every `onClose` identity change (callers commonly pass a fresh
// inline arrow each render), it would re-capture document.activeElement
// after focus had already moved into the dialog, overwriting the real
// trigger element with the dialog itself.
const previouslyFocused = document.activeElement as HTMLElement | null;
const previousOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
dialogRef.current?.focus();
return () => {
document.body.style.overflow = previousOverflow;
previouslyFocused?.focus();
};
}, [open]);
useEffect(() => {
if (!open) return;
const onKeyDown = (event: KeyboardEvent) => {
if (event.key === "Escape") {
event.preventDefault();
onCloseRef.current();
return;
}
if (event.key !== "Tab" || !dialogRef.current) return;
const focusable = Array.from(dialogRef.current.querySelectorAll<HTMLElement>(
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])',
)).filter((element) => !element.hasAttribute("hidden"));
if (!focusable.length) {
event.preventDefault();
dialogRef.current.focus();
return;
}
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last?.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first?.focus();
}
};
document.addEventListener("keydown", onKeyDown);
return () => document.removeEventListener("keydown", onKeyDown);
}, [open]);
if (!open) return null;
return (
<div className="modal-overlay" onClick={onClose}>
<div
className={`modal ${className}`.trim()}
role="dialog"
aria-modal="true"
aria-labelledby={titleId}
tabIndex={-1}
ref={dialogRef}
onClick={(event) => event.stopPropagation()}
>
<div className="modal-heading">
<h2 id={titleId}>{title}</h2>
<button className="modal-close" onClick={onClose} aria-label="Close dialog">×</button>
</div>
<div className="modal-body">{children}</div>
</div>
</div>
);
}
+21
View File
@@ -0,0 +1,21 @@
import { useState } from "react";
import { logoutSession, safeApiMessage } from "../api";
import type { ManagementRole } from "../contracts";
export function SessionMenu({ subject, roles }: { subject: string | null; roles: ManagementRole[] }) {
const [busy, setBusy] = useState(false);
const [error, setError] = useState("");
const initial = subject?.trim().charAt(0).toUpperCase() || "•";
const signOut = async () => {
setBusy(true);
setError("");
try {
await logoutSession();
window.location.assign("/");
} catch (caught) {
setError(safeApiMessage(caught));
setBusy(false);
}
};
return <div className="session-menu"><span className="tag">Authenticated</span><div className="session-identity"><span className="avatar" aria-hidden="true">{initial}</span><span><strong>{subject ?? "Authenticated user"}</strong><small>{roles.join(" · ") || "management"}</small></span></div><button className="button button-small button-secondary" type="button" disabled={busy} onClick={() => void signOut()}>{busy ? "Signing out…" : "Sign out"}</button>{error ? <span className="session-error" role="alert">{error}</span> : null}</div>;
}
+4
View File
@@ -0,0 +1,4 @@
import type { Health } from "../contracts";
import { healthLabel } from "../format";
export function StatusPill({ value }: { value: Health }) { return <span className={`status status-${value}`} aria-label={`Status: ${healthLabel(value)}`}><span aria-hidden="true" />{healthLabel(value)}</span>; }