@bopen-io/tortuga-plugin 0.0.6 → 0.0.8

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/dist/ui/index.js CHANGED
@@ -306,7 +306,7 @@ function FleetStatusWidget({ context }) {
306
306
  companyId: companyId ?? void 0
307
307
  });
308
308
  const agents = useMemo(() => {
309
- const base = overview?.agents ?? [];
309
+ const base = overview?.fleet ?? [];
310
310
  if (fleetStream.events.length === 0) return base;
311
311
  const latestStatus = /* @__PURE__ */ new Map();
312
312
  for (const event of fleetStream.events) {
@@ -316,7 +316,7 @@ function FleetStatusWidget({ context }) {
316
316
  const liveStatus = latestStatus.get(agent.id);
317
317
  return liveStatus ? { ...agent, status: liveStatus } : agent;
318
318
  });
319
- }, [overview?.agents, fleetStream.events]);
319
+ }, [overview?.fleet, fleetStream.events]);
320
320
  if (loading) return /* @__PURE__ */ jsx(LoadingIndicator, { message: "Loading fleet status..." });
321
321
  if (error) return /* @__PURE__ */ jsx(ErrorBanner, { message: error.message });
322
322
  const totalAgents = agents.length;
@@ -670,7 +670,7 @@ function FleetMonitorPage({ context }) {
670
670
  const [detailView, setDetailView] = useState(null);
671
671
  const [actionLoading, setActionLoading] = useState(false);
672
672
  const agents = useMemo(() => {
673
- const base = overview?.agents ?? [];
673
+ const base = overview?.fleet ?? [];
674
674
  if (fleetStream.events.length === 0) return base;
675
675
  const latestStatus = /* @__PURE__ */ new Map();
676
676
  for (const event of fleetStream.events) {
@@ -680,7 +680,7 @@ function FleetMonitorPage({ context }) {
680
680
  const liveStatus = latestStatus.get(agent.id);
681
681
  return liveStatus ? { ...agent, status: liveStatus } : agent;
682
682
  });
683
- }, [overview?.agents, fleetStream.events]);
683
+ }, [overview?.fleet, fleetStream.events]);
684
684
  const filteredAgents = useMemo(() => {
685
685
  if (statusFilter === "all") return agents;
686
686
  return agents.filter((a) => a.status === statusFilter);
@@ -779,7 +779,7 @@ function FleetMonitorPage({ context }) {
779
779
  children: [
780
780
  /* @__PURE__ */ jsxs("div", { children: [
781
781
  /* @__PURE__ */ jsx("h1", { style: { fontSize: "18px", fontWeight: 700, margin: 0 }, children: "Fleet Monitor" }),
782
- /* @__PURE__ */ jsx("div", { style: mutedTextStyle, children: overview ? `${overview.total} agent${overview.total === 1 ? "" : "s"} registered. Last health check: ${relativeTime(overview.lastHealthCheck)}` : "Loading fleet data..." })
782
+ /* @__PURE__ */ jsx("div", { style: mutedTextStyle, children: overview ? `${overview.totalAgents} agent${overview.totalAgents === 1 ? "" : "s"} registered. Last health check: ${relativeTime(overview.lastHealthCheckAt)}` : "Loading fleet data..." })
783
783
  ] }),
784
784
  /* @__PURE__ */ jsxs("div", { style: rowStyle, children: [
785
785
  fleetStream.connected ? /* @__PURE__ */ jsxs(
@@ -849,7 +849,7 @@ function TortugaSidebarLink({ context }) {
849
849
  );
850
850
  const href = pluginPagePath(context.companyPrefix);
851
851
  const isActive = typeof window !== "undefined" && window.location.pathname === href;
852
- const agentCount = overview?.total ?? 0;
852
+ const agentCount = overview?.totalAgents ?? 0;
853
853
  return /* @__PURE__ */ jsxs(
854
854
  "a",
855
855
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ui/index.tsx"],
4
- "sourcesContent": ["import { useMemo, useState, type CSSProperties, type ReactNode } from \"react\";\nimport {\n usePluginAction,\n usePluginData,\n usePluginStream,\n usePluginToast,\n} from \"@paperclipai/plugin-sdk/ui\";\nimport type {\n PluginPageProps,\n PluginSidebarProps,\n PluginWidgetProps,\n} from \"@paperclipai/plugin-sdk/ui\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype AgentStatus = \"running\" | \"idle\" | \"error\" | \"paused\" | \"offline\";\n\ntype FleetAgent = {\n id: string;\n name: string;\n role: string | null;\n status: AgentStatus;\n lastHeartbeat: string | null;\n adapterType: string | null;\n lastRunAt: string | null;\n lastRunDurationMs: number | null;\n lastRunResult: string | null;\n};\n\ntype FleetOverview = {\n agents: FleetAgent[];\n total: number;\n lastHealthCheck: string | null;\n};\n\ntype AgentDetailData = {\n agent: FleetAgent;\n recentRuns: {\n id: string;\n startedAt: string;\n durationMs: number;\n result: string;\n prompt: string | null;\n }[];\n};\n\ntype FleetStatusEvent = {\n agentId: string;\n status: AgentStatus;\n timestamp: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared inline styles (following ClawNet kitchen-sink pattern)\n// ---------------------------------------------------------------------------\n\nconst PAGE_ROUTE = \"tortuga\";\n\nconst layoutStack: CSSProperties = {\n display: \"grid\",\n gap: \"12px\",\n};\n\nconst cardStyle: CSSProperties = {\n border: \"1px solid var(--border)\",\n borderRadius: \"12px\",\n padding: \"14px\",\n background: \"var(--card, transparent)\",\n};\n\nconst subtleCardStyle: CSSProperties = {\n border: \"1px solid color-mix(in srgb, var(--border) 75%, transparent)\",\n borderRadius: \"10px\",\n padding: \"12px\",\n};\n\nconst rowStyle: CSSProperties = {\n display: \"flex\",\n flexWrap: \"wrap\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nconst buttonStyle: CSSProperties = {\n appearance: \"none\",\n border: \"1px solid var(--border)\",\n borderRadius: \"999px\",\n background: \"transparent\",\n color: \"inherit\",\n padding: \"6px 12px\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n};\n\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: \"var(--foreground)\",\n color: \"var(--background)\",\n borderColor: \"var(--foreground)\",\n};\n\nconst dangerButtonStyle: CSSProperties = {\n ...buttonStyle,\n color: \"var(--destructive, #dc2626)\",\n borderColor: \"color-mix(in srgb, var(--destructive, #dc2626) 50%, var(--border))\",\n};\n\nconst inputStyle: CSSProperties = {\n width: \"100%\",\n border: \"1px solid var(--border)\",\n borderRadius: \"8px\",\n padding: \"8px 10px\",\n background: \"transparent\",\n color: \"inherit\",\n fontSize: \"12px\",\n};\n\nconst mutedTextStyle: CSSProperties = {\n fontSize: \"12px\",\n opacity: 0.72,\n lineHeight: 1.45,\n};\n\nconst eyebrowStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.65,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n};\n\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n marginBottom: \"10px\",\n};\n\nconst statValueStyle: CSSProperties = {\n fontSize: \"24px\",\n fontWeight: 700,\n lineHeight: 1,\n};\n\nconst statLabelStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.6,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n marginTop: \"4px\",\n};\n\n// ---------------------------------------------------------------------------\n// Utility helpers\n// ---------------------------------------------------------------------------\n\nfunction hostPath(companyPrefix: string | null | undefined, suffix: string): string {\n return companyPrefix ? `/${companyPrefix}${suffix}` : suffix;\n}\n\nfunction pluginPagePath(companyPrefix: string | null | undefined): string {\n return hostPath(companyPrefix, `/${PAGE_ROUTE}`);\n}\n\nfunction relativeTime(isoString: string | null): string {\n if (!isoString) return \"never\";\n const then = new Date(isoString).getTime();\n if (Number.isNaN(then)) return \"unknown\";\n const diffMs = Date.now() - then;\n if (diffMs < 0) return \"just now\";\n const seconds = Math.floor(diffMs / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction formatDuration(ms: number | null): string {\n if (ms === null) return \"--\";\n if (ms < 1000) return `${ms}ms`;\n const seconds = Math.round(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainder = seconds % 60;\n return `${minutes}m ${remainder}s`;\n}\n\n// ---------------------------------------------------------------------------\n// Small shared primitives\n// ---------------------------------------------------------------------------\n\nfunction Pill({ label, color }: { label: string; color?: string }) {\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n borderRadius: \"999px\",\n border: \"1px solid var(--border)\",\n padding: \"2px 8px\",\n fontSize: \"11px\",\n background: color\n ? `color-mix(in srgb, ${color} 14%, transparent)`\n : undefined,\n borderColor: color\n ? `color-mix(in srgb, ${color} 40%, var(--border))`\n : undefined,\n }}\n >\n {label}\n </span>\n );\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n running: \"#2563eb\",\n idle: \"#d97706\",\n error: \"#dc2626\",\n paused: \"#6b7280\",\n offline: \"#6b7280\",\n online: \"#16a34a\",\n};\n\nfunction StatusDot({ status }: { status: string }) {\n const dotColor = STATUS_COLORS[status.toLowerCase()] ?? \"#6b7280\";\n return (\n <span\n style={{\n display: \"inline-block\",\n width: \"7px\",\n height: \"7px\",\n borderRadius: \"50%\",\n background: dotColor,\n flexShrink: 0,\n }}\n aria-label={status}\n />\n );\n}\n\nfunction EmptyState({ message }: { message: string }) {\n return (\n <div\n style={{\n padding: \"32px 16px\",\n textAlign: \"center\",\n fontSize: \"13px\",\n opacity: 0.55,\n }}\n >\n {message}\n </div>\n );\n}\n\nfunction LoadingIndicator({ message }: { message?: string }) {\n return (\n <div\n style={{\n padding: \"24px 16px\",\n textAlign: \"center\",\n fontSize: \"12px\",\n opacity: 0.6,\n }}\n >\n {message ?? \"Loading...\"}\n </div>\n );\n}\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div\n style={{\n ...subtleCardStyle,\n borderColor: \"color-mix(in srgb, #dc2626 45%, var(--border))\",\n fontSize: \"12px\",\n color: \"var(--destructive, #dc2626)\",\n }}\n >\n {message}\n </div>\n );\n}\n\nfunction Section({\n title,\n action,\n children,\n}: {\n title: string;\n action?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>{title}</strong>\n {action}\n </div>\n <div style={layoutStack}>{children}</div>\n </section>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Fleet-specific helpers\n// ---------------------------------------------------------------------------\n\nfunction statusCounts(agents: FleetAgent[]): Record<AgentStatus, number> {\n const counts: Record<AgentStatus, number> = {\n running: 0,\n idle: 0,\n error: 0,\n paused: 0,\n offline: 0,\n };\n for (const agent of agents) {\n const s = agent.status as AgentStatus;\n if (s in counts) {\n counts[s]++;\n }\n }\n return counts;\n}\n\nfunction StatusBreakdown({ agents }: { agents: FleetAgent[] }) {\n const counts = statusCounts(agents);\n const entries: { status: AgentStatus; label: string }[] = [\n { status: \"running\", label: \"Running\" },\n { status: \"idle\", label: \"Idle\" },\n { status: \"error\", label: \"Error\" },\n { status: \"paused\", label: \"Paused\" },\n ];\n\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"10px\" }}>\n {entries.map(({ status, label }) => (\n <div\n key={status}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n fontSize: \"12px\",\n }}\n >\n <StatusDot status={status} />\n <span style={{ opacity: 0.8 }}>\n {counts[status]} {label}\n </span>\n </div>\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Anchor icon (fleet/ship-wheel inspired)\n// ---------------------------------------------------------------------------\n\nfunction FleetIcon({ size = 16 }: { size?: number }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.9\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n >\n {/* Helm / ship wheel */}\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <path d=\"M12 6v-3\" />\n <path d=\"M12 21v-3\" />\n <path d=\"M6 12H3\" />\n <path d=\"M21 12h-3\" />\n <path d=\"M7.76 7.76L5.64 5.64\" />\n <path d=\"M18.36 18.36l-2.12-2.12\" />\n <path d=\"M16.24 7.76l2.12-2.12\" />\n <path d=\"M5.64 18.36l2.12-2.12\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 1. FleetStatusWidget\n// ---------------------------------------------------------------------------\n\n/**\n * Compact dashboard widget showing fleet health at a glance.\n *\n * Displays total agent count, status breakdown (running/idle/error/paused),\n * last health check timestamp, and a live indicator when streaming.\n */\nexport function FleetStatusWidget({ context }: PluginWidgetProps) {\n const companyId = context.companyId;\n\n const overviewParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: overview, loading, error } = usePluginData<FleetOverview>(\n \"fleet-overview\",\n overviewParams,\n );\n\n const fleetStream = usePluginStream<FleetStatusEvent>(\"fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n // Apply live status updates on top of fetched data\n const agents = useMemo(() => {\n const base = overview?.agents ?? [];\n if (fleetStream.events.length === 0) return base;\n\n // Build latest status map from stream events\n const latestStatus = new Map<string, AgentStatus>();\n for (const event of fleetStream.events) {\n latestStatus.set(event.agentId, event.status);\n }\n\n return base.map((agent) => {\n const liveStatus = latestStatus.get(agent.id);\n return liveStatus ? { ...agent, status: liveStatus } : agent;\n });\n }, [overview?.agents, fleetStream.events]);\n\n if (loading) return <LoadingIndicator message=\"Loading fleet status...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n\n const totalAgents = agents.length;\n\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <strong>Fleet Status</strong>\n {fleetStream.connected ? <StatusDot status=\"online\" /> : null}\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: \"8px\",\n }}\n >\n <div>\n <div style={statValueStyle}>{totalAgents}</div>\n <div style={statLabelStyle}>Agents</div>\n </div>\n <div>\n <div style={statValueStyle}>\n {statusCounts(agents).running}\n </div>\n <div style={statLabelStyle}>Running</div>\n </div>\n </div>\n\n <StatusBreakdown agents={agents} />\n\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n Last health check: {relativeTime(overview?.lastHealthCheck ?? null)}\n </div>\n\n <a\n href={pluginPagePath(context.companyPrefix)}\n style={{ fontSize: \"12px\", color: \"inherit\" }}\n >\n Open fleet monitor\n </a>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 2. FleetMonitorPage\n// ---------------------------------------------------------------------------\n\ntype StatusFilter = \"all\" | AgentStatus;\ntype AgentDetailView = { agentId: string } | null;\n\nfunction StatusFilterBar({\n active,\n onChange,\n counts,\n}: {\n active: StatusFilter;\n onChange: (filter: StatusFilter) => void;\n counts: Record<AgentStatus, number>;\n}) {\n const filters: { key: StatusFilter; label: string }[] = [\n { key: \"all\", label: \"All\" },\n { key: \"running\", label: \"Running\" },\n { key: \"idle\", label: \"Idle\" },\n { key: \"error\", label: \"Error\" },\n { key: \"paused\", label: \"Paused\" },\n ];\n\n return (\n <div style={{ display: \"flex\", gap: \"0\", borderBottom: \"1px solid var(--border)\" }}>\n {filters.map((filter) => {\n const count = filter.key === \"all\"\n ? Object.values(counts).reduce((a, b) => a + b, 0)\n : counts[filter.key];\n return (\n <button\n key={filter.key}\n type=\"button\"\n onClick={() => onChange(filter.key)}\n style={{\n appearance: \"none\",\n background: \"transparent\",\n border: \"none\",\n borderBottom:\n active === filter.key\n ? \"2px solid var(--foreground)\"\n : \"2px solid transparent\",\n color:\n active === filter.key\n ? \"var(--foreground)\"\n : \"var(--muted-foreground, inherit)\",\n padding: \"10px 16px\",\n fontSize: \"13px\",\n fontWeight: active === filter.key ? 600 : 400,\n cursor: \"pointer\",\n transition: \"color 0.15s, border-color 0.15s\",\n }}\n >\n {filter.label}\n <span style={{ marginLeft: \"6px\", fontSize: \"11px\", opacity: 0.6 }}>\n {count}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction AgentRow({\n agent,\n onSelect,\n onPause,\n onResume,\n onInvoke,\n actionLoading,\n}: {\n agent: FleetAgent;\n onSelect: () => void;\n onPause: () => void;\n onResume: () => void;\n onInvoke: () => void;\n actionLoading: boolean;\n}) {\n return (\n <div\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: \"10px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n transition: \"border-color 0.15s\",\n }}\n onClick={onSelect}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect();\n }\n }}\n role=\"button\"\n tabIndex={0}\n >\n {/* Left: agent info */}\n <div style={{ display: \"grid\", gap: \"6px\", minWidth: 0 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <StatusDot status={agent.status} />\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {agent.name}\n </span>\n {agent.role ? <Pill label={agent.role} /> : null}\n {agent.adapterType ? (\n <Pill label={agent.adapterType} color=\"#6366f1\" />\n ) : null}\n </div>\n <div style={mutedTextStyle}>\n Last heartbeat: {relativeTime(agent.lastHeartbeat)}\n {agent.lastRunResult ? ` \\u00b7 Last run: ${agent.lastRunResult}` : \"\"}\n </div>\n </div>\n\n {/* Right: action buttons */}\n <div\n style={{ display: \"flex\", gap: \"6px\", flexShrink: 0 }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n {agent.status === \"running\" || agent.status === \"idle\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={onPause}\n disabled={actionLoading}\n title=\"Pause agent\"\n >\n Pause\n </button>\n ) : null}\n {agent.status === \"paused\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={onResume}\n disabled={actionLoading}\n title=\"Resume agent\"\n >\n Resume\n </button>\n ) : null}\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={onInvoke}\n disabled={actionLoading || agent.status === \"paused\"}\n title=\"Invoke agent\"\n >\n Invoke\n </button>\n </div>\n </div>\n );\n}\n\nfunction AgentDetailPanel({\n agentId,\n companyId,\n onBack,\n onPause,\n onResume,\n onInvoke,\n}: {\n agentId: string;\n companyId: string;\n onBack: () => void;\n onPause: (agentId: string) => void;\n onResume: (agentId: string) => void;\n onInvoke: (agentId: string, prompt: string) => void;\n}) {\n const detailParams = useMemo(\n () => ({ companyId, agentId }),\n [companyId, agentId],\n );\n const { data: detail, loading, error } = usePluginData<AgentDetailData>(\n \"agent-detail\",\n detailParams,\n );\n\n const [invokePrompt, setInvokePrompt] = useState(\"\");\n\n if (loading) return <LoadingIndicator message=\"Loading agent details...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n if (!detail) return <EmptyState message=\"Agent not found.\" />;\n\n const { agent, recentRuns } = detail;\n\n return (\n <div style={layoutStack}>\n {/* Back + header */}\n <div style={rowStyle}>\n <button type=\"button\" style={buttonStyle} onClick={onBack}>\n Back\n </button>\n <StatusDot status={agent.status} />\n <strong style={{ fontSize: \"16px\" }}>{agent.name}</strong>\n <Pill label={agent.status} color={STATUS_COLORS[agent.status]} />\n </div>\n\n {/* Stats grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(160px, 1fr))\",\n gap: \"12px\",\n }}\n >\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Role</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.role ?? \"Not assigned\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Adapter</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.adapterType ?? \"Default\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Last Heartbeat</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {relativeTime(agent.lastHeartbeat)}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Last Run Duration</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {formatDuration(agent.lastRunDurationMs)}\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div style={rowStyle}>\n {agent.status === \"running\" || agent.status === \"idle\" ? (\n <button\n type=\"button\"\n style={dangerButtonStyle}\n onClick={() => onPause(agent.id)}\n >\n Pause Agent\n </button>\n ) : null}\n {agent.status === \"paused\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => onResume(agent.id)}\n >\n Resume Agent\n </button>\n ) : null}\n </div>\n\n {/* Invoke prompt */}\n <Section title=\"Invoke Agent\">\n <div style={{ display: \"flex\", gap: \"8px\" }}>\n <input\n type=\"text\"\n value={invokePrompt}\n onChange={(e) => setInvokePrompt(e.target.value)}\n placeholder=\"Enter prompt to invoke agent...\"\n style={{ ...inputStyle, flex: 1 }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && invokePrompt.trim()) {\n onInvoke(agent.id, invokePrompt.trim());\n setInvokePrompt(\"\");\n }\n }}\n />\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={() => {\n if (invokePrompt.trim()) {\n onInvoke(agent.id, invokePrompt.trim());\n setInvokePrompt(\"\");\n }\n }}\n disabled={!invokePrompt.trim() || agent.status === \"paused\"}\n >\n Send\n </button>\n </div>\n </Section>\n\n {/* Recent runs */}\n <Section title=\"Recent Runs\">\n {recentRuns.length === 0 ? (\n <EmptyState message=\"No recent runs recorded.\" />\n ) : (\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {recentRuns.map((run) => (\n <div\n key={run.id}\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: \"6px\",\n alignItems: \"start\",\n }}\n >\n <div style={{ display: \"grid\", gap: \"4px\", minWidth: 0 }}>\n <div style={{ fontSize: \"12px\", fontWeight: 600 }}>\n {run.result}\n </div>\n {run.prompt ? (\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n {run.prompt}\n </div>\n ) : null}\n </div>\n <div\n style={{\n display: \"grid\",\n gap: \"2px\",\n textAlign: \"right\",\n flexShrink: 0,\n }}\n >\n <div style={{ fontSize: \"11px\", opacity: 0.6 }}>\n {relativeTime(run.startedAt)}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.5 }}>\n {formatDuration(run.durationMs)}\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </Section>\n </div>\n );\n}\n\n/**\n * Full fleet monitoring page.\n *\n * Shows an agent grid with status filter, per-agent pause/resume/invoke\n * actions, a live stream indicator, and agent detail panel on click.\n */\nexport function FleetMonitorPage({ context }: PluginPageProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n // Fleet data\n const overviewParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const {\n data: overview,\n loading,\n error,\n refresh,\n } = usePluginData<FleetOverview>(\"fleet-overview\", overviewParams);\n\n // Stream\n const fleetStream = usePluginStream<FleetStatusEvent>(\"fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n // Actions\n const pauseAgent = usePluginAction(\"pause-agent\");\n const resumeAgent = usePluginAction(\"resume-agent\");\n const invokeAgent = usePluginAction(\"invoke-agent\");\n\n // UI state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(\"all\");\n const [detailView, setDetailView] = useState<AgentDetailView>(null);\n const [actionLoading, setActionLoading] = useState(false);\n\n // Apply live status updates\n const agents = useMemo(() => {\n const base = overview?.agents ?? [];\n if (fleetStream.events.length === 0) return base;\n\n const latestStatus = new Map<string, AgentStatus>();\n for (const event of fleetStream.events) {\n latestStatus.set(event.agentId, event.status);\n }\n\n return base.map((agent) => {\n const liveStatus = latestStatus.get(agent.id);\n return liveStatus ? { ...agent, status: liveStatus } : agent;\n });\n }, [overview?.agents, fleetStream.events]);\n\n // Filter\n const filteredAgents = useMemo(() => {\n if (statusFilter === \"all\") return agents;\n return agents.filter((a) => a.status === statusFilter);\n }, [agents, statusFilter]);\n\n const counts = useMemo(() => statusCounts(agents), [agents]);\n\n // Action handlers\n async function handlePause(agentId: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await pauseAgent({ companyId, agentId });\n refresh();\n toast({\n title: \"Agent paused\",\n body: \"The agent has been paused and will not execute until resumed.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to pause agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n async function handleResume(agentId: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await resumeAgent({ companyId, agentId });\n refresh();\n toast({\n title: \"Agent resumed\",\n body: \"The agent is now active and ready to process work.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to resume agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n async function handleInvoke(agentId: string, prompt?: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await invokeAgent({ companyId, agentId, prompt: prompt ?? undefined });\n refresh();\n toast({\n title: \"Agent invoked\",\n body: prompt\n ? `Agent invoked with prompt: \"${prompt}\"`\n : \"Agent has been invoked.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to invoke agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n // Detail view\n if (detailView && companyId) {\n return (\n <div style={{ ...layoutStack, maxWidth: \"800px\" }}>\n <AgentDetailPanel\n agentId={detailView.agentId}\n companyId={companyId}\n onBack={() => setDetailView(null)}\n onPause={(id) => void handlePause(id)}\n onResume={(id) => void handleResume(id)}\n onInvoke={(id, prompt) => void handleInvoke(id, prompt)}\n />\n </div>\n );\n }\n\n // No company selected\n if (!companyId) {\n return (\n <div style={layoutStack}>\n <Section title=\"Fleet Monitor\">\n <EmptyState message=\"Select a company to view your agent fleet.\" />\n </Section>\n </div>\n );\n }\n\n return (\n <div style={layoutStack}>\n {/* Page header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"12px\",\n flexWrap: \"wrap\",\n }}\n >\n <div>\n <h1 style={{ fontSize: \"18px\", fontWeight: 700, margin: 0 }}>\n Fleet Monitor\n </h1>\n <div style={mutedTextStyle}>\n {overview\n ? `${overview.total} agent${overview.total === 1 ? \"\" : \"s\"} registered. Last health check: ${relativeTime(overview.lastHealthCheck)}`\n : \"Loading fleet data...\"}\n </div>\n </div>\n <div style={rowStyle}>\n {fleetStream.connected ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n fontSize: \"11px\",\n opacity: 0.7,\n }}\n >\n <StatusDot status=\"online\" />\n Live\n </div>\n ) : null}\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => refresh()}\n >\n Refresh\n </button>\n </div>\n </div>\n\n {/* Status filter tabs */}\n <StatusFilterBar\n active={statusFilter}\n onChange={setStatusFilter}\n counts={counts}\n />\n\n {/* Agent list */}\n {loading && agents.length === 0 ? (\n <LoadingIndicator message=\"Loading fleet agents...\" />\n ) : error ? (\n <ErrorBanner message={error.message} />\n ) : filteredAgents.length === 0 ? (\n <EmptyState\n message={\n statusFilter !== \"all\"\n ? `No agents with status \"${statusFilter}\".`\n : \"No agents registered in this fleet.\"\n }\n />\n ) : (\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {filteredAgents.map((agent) => (\n <AgentRow\n key={agent.id}\n agent={agent}\n onSelect={() => setDetailView({ agentId: agent.id })}\n onPause={() => void handlePause(agent.id)}\n onResume={() => void handleResume(agent.id)}\n onInvoke={() => void handleInvoke(agent.id)}\n actionLoading={actionLoading}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 3. TortugaSidebarLink\n// ---------------------------------------------------------------------------\n\n/**\n * Sidebar navigation link to the fleet monitor page.\n * Shows a helm icon and an agent count badge from fleet overview.\n */\nexport function TortugaSidebarLink({ context }: PluginSidebarProps) {\n const overviewParams = useMemo(\n () => (context.companyId ? { companyId: context.companyId } : {}),\n [context.companyId],\n );\n const { data: overview } = usePluginData<FleetOverview>(\n \"fleet-overview\",\n overviewParams,\n );\n\n const href = pluginPagePath(context.companyPrefix);\n const isActive =\n typeof window !== \"undefined\" && window.location.pathname === href;\n\n const agentCount = overview?.total ?? 0;\n\n return (\n <a\n href={href}\n aria-current={isActive ? \"page\" : undefined}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n fontWeight: isActive ? 600 : 400,\n textDecoration: \"none\",\n color: isActive\n ? \"var(--foreground)\"\n : \"color-mix(in srgb, var(--foreground) 80%, transparent)\",\n background: isActive\n ? \"color-mix(in srgb, var(--accent, var(--muted)) 60%, transparent)\"\n : \"transparent\",\n borderRadius: \"6px\",\n transition: \"background 0.15s, color 0.15s\",\n cursor: \"pointer\",\n }}\n >\n <FleetIcon size={16} />\n\n <span style={{ flex: 1 }}>Tortuga</span>\n\n {/* Agent count badge */}\n {agentCount > 0 ? (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: \"20px\",\n height: \"18px\",\n borderRadius: \"999px\",\n background:\n \"color-mix(in srgb, var(--foreground) 12%, transparent)\",\n fontSize: \"10px\",\n fontWeight: 600,\n padding: \"0 5px\",\n flexShrink: 0,\n }}\n >\n {agentCount}\n </span>\n ) : null}\n </a>\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useMemo, useState, type CSSProperties, type ReactNode } from \"react\";\nimport {\n usePluginAction,\n usePluginData,\n usePluginStream,\n usePluginToast,\n} from \"@paperclipai/plugin-sdk/ui\";\nimport type {\n PluginPageProps,\n PluginSidebarProps,\n PluginWidgetProps,\n} from \"@paperclipai/plugin-sdk/ui\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype AgentStatus = \"running\" | \"idle\" | \"error\" | \"paused\" | \"offline\";\n\ntype FleetAgent = {\n id: string;\n name: string;\n role: string | null;\n status: AgentStatus;\n lastHeartbeat: string | null;\n adapterType: string | null;\n lastRunAt: string | null;\n lastRunDurationMs: number | null;\n lastRunResult: string | null;\n};\n\ntype FleetOverview = {\n fleet: FleetAgent[];\n totalAgents: number;\n healthy: number;\n degraded: number;\n error: number;\n lastHealthCheckAt: string | null;\n};\n\ntype AgentDetailData = {\n agent: FleetAgent;\n recentRuns: {\n id: string;\n startedAt: string;\n durationMs: number;\n result: string;\n prompt: string | null;\n }[];\n};\n\ntype FleetStatusEvent = {\n agentId: string;\n status: AgentStatus;\n timestamp: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared inline styles (following ClawNet kitchen-sink pattern)\n// ---------------------------------------------------------------------------\n\nconst PAGE_ROUTE = \"tortuga\";\n\nconst layoutStack: CSSProperties = {\n display: \"grid\",\n gap: \"12px\",\n};\n\nconst cardStyle: CSSProperties = {\n border: \"1px solid var(--border)\",\n borderRadius: \"12px\",\n padding: \"14px\",\n background: \"var(--card, transparent)\",\n};\n\nconst subtleCardStyle: CSSProperties = {\n border: \"1px solid color-mix(in srgb, var(--border) 75%, transparent)\",\n borderRadius: \"10px\",\n padding: \"12px\",\n};\n\nconst rowStyle: CSSProperties = {\n display: \"flex\",\n flexWrap: \"wrap\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nconst buttonStyle: CSSProperties = {\n appearance: \"none\",\n border: \"1px solid var(--border)\",\n borderRadius: \"999px\",\n background: \"transparent\",\n color: \"inherit\",\n padding: \"6px 12px\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n};\n\nconst primaryButtonStyle: CSSProperties = {\n ...buttonStyle,\n background: \"var(--foreground)\",\n color: \"var(--background)\",\n borderColor: \"var(--foreground)\",\n};\n\nconst dangerButtonStyle: CSSProperties = {\n ...buttonStyle,\n color: \"var(--destructive, #dc2626)\",\n borderColor: \"color-mix(in srgb, var(--destructive, #dc2626) 50%, var(--border))\",\n};\n\nconst inputStyle: CSSProperties = {\n width: \"100%\",\n border: \"1px solid var(--border)\",\n borderRadius: \"8px\",\n padding: \"8px 10px\",\n background: \"transparent\",\n color: \"inherit\",\n fontSize: \"12px\",\n};\n\nconst mutedTextStyle: CSSProperties = {\n fontSize: \"12px\",\n opacity: 0.72,\n lineHeight: 1.45,\n};\n\nconst eyebrowStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.65,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n};\n\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n marginBottom: \"10px\",\n};\n\nconst statValueStyle: CSSProperties = {\n fontSize: \"24px\",\n fontWeight: 700,\n lineHeight: 1,\n};\n\nconst statLabelStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.6,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n marginTop: \"4px\",\n};\n\n// ---------------------------------------------------------------------------\n// Utility helpers\n// ---------------------------------------------------------------------------\n\nfunction hostPath(companyPrefix: string | null | undefined, suffix: string): string {\n return companyPrefix ? `/${companyPrefix}${suffix}` : suffix;\n}\n\nfunction pluginPagePath(companyPrefix: string | null | undefined): string {\n return hostPath(companyPrefix, `/${PAGE_ROUTE}`);\n}\n\nfunction relativeTime(isoString: string | null): string {\n if (!isoString) return \"never\";\n const then = new Date(isoString).getTime();\n if (Number.isNaN(then)) return \"unknown\";\n const diffMs = Date.now() - then;\n if (diffMs < 0) return \"just now\";\n const seconds = Math.floor(diffMs / 1000);\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n const days = Math.floor(hours / 24);\n return `${days}d ago`;\n}\n\nfunction formatDuration(ms: number | null): string {\n if (ms === null) return \"--\";\n if (ms < 1000) return `${ms}ms`;\n const seconds = Math.round(ms / 1000);\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.floor(seconds / 60);\n const remainder = seconds % 60;\n return `${minutes}m ${remainder}s`;\n}\n\n// ---------------------------------------------------------------------------\n// Small shared primitives\n// ---------------------------------------------------------------------------\n\nfunction Pill({ label, color }: { label: string; color?: string }) {\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n borderRadius: \"999px\",\n border: \"1px solid var(--border)\",\n padding: \"2px 8px\",\n fontSize: \"11px\",\n background: color\n ? `color-mix(in srgb, ${color} 14%, transparent)`\n : undefined,\n borderColor: color\n ? `color-mix(in srgb, ${color} 40%, var(--border))`\n : undefined,\n }}\n >\n {label}\n </span>\n );\n}\n\nconst STATUS_COLORS: Record<string, string> = {\n running: \"#2563eb\",\n idle: \"#d97706\",\n error: \"#dc2626\",\n paused: \"#6b7280\",\n offline: \"#6b7280\",\n online: \"#16a34a\",\n};\n\nfunction StatusDot({ status }: { status: string }) {\n const dotColor = STATUS_COLORS[status.toLowerCase()] ?? \"#6b7280\";\n return (\n <span\n style={{\n display: \"inline-block\",\n width: \"7px\",\n height: \"7px\",\n borderRadius: \"50%\",\n background: dotColor,\n flexShrink: 0,\n }}\n aria-label={status}\n />\n );\n}\n\nfunction EmptyState({ message }: { message: string }) {\n return (\n <div\n style={{\n padding: \"32px 16px\",\n textAlign: \"center\",\n fontSize: \"13px\",\n opacity: 0.55,\n }}\n >\n {message}\n </div>\n );\n}\n\nfunction LoadingIndicator({ message }: { message?: string }) {\n return (\n <div\n style={{\n padding: \"24px 16px\",\n textAlign: \"center\",\n fontSize: \"12px\",\n opacity: 0.6,\n }}\n >\n {message ?? \"Loading...\"}\n </div>\n );\n}\n\nfunction ErrorBanner({ message }: { message: string }) {\n return (\n <div\n style={{\n ...subtleCardStyle,\n borderColor: \"color-mix(in srgb, #dc2626 45%, var(--border))\",\n fontSize: \"12px\",\n color: \"var(--destructive, #dc2626)\",\n }}\n >\n {message}\n </div>\n );\n}\n\nfunction Section({\n title,\n action,\n children,\n}: {\n title: string;\n action?: ReactNode;\n children: ReactNode;\n}) {\n return (\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>{title}</strong>\n {action}\n </div>\n <div style={layoutStack}>{children}</div>\n </section>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Fleet-specific helpers\n// ---------------------------------------------------------------------------\n\nfunction statusCounts(agents: FleetAgent[]): Record<AgentStatus, number> {\n const counts: Record<AgentStatus, number> = {\n running: 0,\n idle: 0,\n error: 0,\n paused: 0,\n offline: 0,\n };\n for (const agent of agents) {\n const s = agent.status as AgentStatus;\n if (s in counts) {\n counts[s]++;\n }\n }\n return counts;\n}\n\nfunction StatusBreakdown({ agents }: { agents: FleetAgent[] }) {\n const counts = statusCounts(agents);\n const entries: { status: AgentStatus; label: string }[] = [\n { status: \"running\", label: \"Running\" },\n { status: \"idle\", label: \"Idle\" },\n { status: \"error\", label: \"Error\" },\n { status: \"paused\", label: \"Paused\" },\n ];\n\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"10px\" }}>\n {entries.map(({ status, label }) => (\n <div\n key={status}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n fontSize: \"12px\",\n }}\n >\n <StatusDot status={status} />\n <span style={{ opacity: 0.8 }}>\n {counts[status]} {label}\n </span>\n </div>\n ))}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Anchor icon (fleet/ship-wheel inspired)\n// ---------------------------------------------------------------------------\n\nfunction FleetIcon({ size = 16 }: { size?: number }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.9\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{ flexShrink: 0 }}\n >\n {/* Helm / ship wheel */}\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <path d=\"M12 6v-3\" />\n <path d=\"M12 21v-3\" />\n <path d=\"M6 12H3\" />\n <path d=\"M21 12h-3\" />\n <path d=\"M7.76 7.76L5.64 5.64\" />\n <path d=\"M18.36 18.36l-2.12-2.12\" />\n <path d=\"M16.24 7.76l2.12-2.12\" />\n <path d=\"M5.64 18.36l2.12-2.12\" />\n </svg>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 1. FleetStatusWidget\n// ---------------------------------------------------------------------------\n\n/**\n * Compact dashboard widget showing fleet health at a glance.\n *\n * Displays total agent count, status breakdown (running/idle/error/paused),\n * last health check timestamp, and a live indicator when streaming.\n */\nexport function FleetStatusWidget({ context }: PluginWidgetProps) {\n const companyId = context.companyId;\n\n const overviewParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: overview, loading, error } = usePluginData<FleetOverview>(\n \"fleet-overview\",\n overviewParams,\n );\n\n const fleetStream = usePluginStream<FleetStatusEvent>(\"fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n // Apply live status updates on top of fetched data\n const agents = useMemo(() => {\n const base = overview?.fleet ?? [];\n if (fleetStream.events.length === 0) return base;\n\n // Build latest status map from stream events\n const latestStatus = new Map<string, AgentStatus>();\n for (const event of fleetStream.events) {\n latestStatus.set(event.agentId, event.status);\n }\n\n return base.map((agent) => {\n const liveStatus = latestStatus.get(agent.id);\n return liveStatus ? { ...agent, status: liveStatus } : agent;\n });\n }, [overview?.fleet, fleetStream.events]);\n\n if (loading) return <LoadingIndicator message=\"Loading fleet status...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n\n const totalAgents = agents.length;\n\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <strong>Fleet Status</strong>\n {fleetStream.connected ? <StatusDot status=\"online\" /> : null}\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: \"8px\",\n }}\n >\n <div>\n <div style={statValueStyle}>{totalAgents}</div>\n <div style={statLabelStyle}>Agents</div>\n </div>\n <div>\n <div style={statValueStyle}>\n {statusCounts(agents).running}\n </div>\n <div style={statLabelStyle}>Running</div>\n </div>\n </div>\n\n <StatusBreakdown agents={agents} />\n\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n Last health check: {relativeTime(overview?.lastHealthCheck ?? null)}\n </div>\n\n <a\n href={pluginPagePath(context.companyPrefix)}\n style={{ fontSize: \"12px\", color: \"inherit\" }}\n >\n Open fleet monitor\n </a>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 2. FleetMonitorPage\n// ---------------------------------------------------------------------------\n\ntype StatusFilter = \"all\" | AgentStatus;\ntype AgentDetailView = { agentId: string } | null;\n\nfunction StatusFilterBar({\n active,\n onChange,\n counts,\n}: {\n active: StatusFilter;\n onChange: (filter: StatusFilter) => void;\n counts: Record<AgentStatus, number>;\n}) {\n const filters: { key: StatusFilter; label: string }[] = [\n { key: \"all\", label: \"All\" },\n { key: \"running\", label: \"Running\" },\n { key: \"idle\", label: \"Idle\" },\n { key: \"error\", label: \"Error\" },\n { key: \"paused\", label: \"Paused\" },\n ];\n\n return (\n <div style={{ display: \"flex\", gap: \"0\", borderBottom: \"1px solid var(--border)\" }}>\n {filters.map((filter) => {\n const count = filter.key === \"all\"\n ? Object.values(counts).reduce((a, b) => a + b, 0)\n : counts[filter.key];\n return (\n <button\n key={filter.key}\n type=\"button\"\n onClick={() => onChange(filter.key)}\n style={{\n appearance: \"none\",\n background: \"transparent\",\n border: \"none\",\n borderBottom:\n active === filter.key\n ? \"2px solid var(--foreground)\"\n : \"2px solid transparent\",\n color:\n active === filter.key\n ? \"var(--foreground)\"\n : \"var(--muted-foreground, inherit)\",\n padding: \"10px 16px\",\n fontSize: \"13px\",\n fontWeight: active === filter.key ? 600 : 400,\n cursor: \"pointer\",\n transition: \"color 0.15s, border-color 0.15s\",\n }}\n >\n {filter.label}\n <span style={{ marginLeft: \"6px\", fontSize: \"11px\", opacity: 0.6 }}>\n {count}\n </span>\n </button>\n );\n })}\n </div>\n );\n}\n\nfunction AgentRow({\n agent,\n onSelect,\n onPause,\n onResume,\n onInvoke,\n actionLoading,\n}: {\n agent: FleetAgent;\n onSelect: () => void;\n onPause: () => void;\n onResume: () => void;\n onInvoke: () => void;\n actionLoading: boolean;\n}) {\n return (\n <div\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: \"10px\",\n alignItems: \"center\",\n cursor: \"pointer\",\n transition: \"border-color 0.15s\",\n }}\n onClick={onSelect}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onSelect();\n }\n }}\n role=\"button\"\n tabIndex={0}\n >\n {/* Left: agent info */}\n <div style={{ display: \"grid\", gap: \"6px\", minWidth: 0 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <StatusDot status={agent.status} />\n <span\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {agent.name}\n </span>\n {agent.role ? <Pill label={agent.role} /> : null}\n {agent.adapterType ? (\n <Pill label={agent.adapterType} color=\"#6366f1\" />\n ) : null}\n </div>\n <div style={mutedTextStyle}>\n Last heartbeat: {relativeTime(agent.lastHeartbeat)}\n {agent.lastRunResult ? ` \\u00b7 Last run: ${agent.lastRunResult}` : \"\"}\n </div>\n </div>\n\n {/* Right: action buttons */}\n <div\n style={{ display: \"flex\", gap: \"6px\", flexShrink: 0 }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n >\n {agent.status === \"running\" || agent.status === \"idle\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={onPause}\n disabled={actionLoading}\n title=\"Pause agent\"\n >\n Pause\n </button>\n ) : null}\n {agent.status === \"paused\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={onResume}\n disabled={actionLoading}\n title=\"Resume agent\"\n >\n Resume\n </button>\n ) : null}\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={onInvoke}\n disabled={actionLoading || agent.status === \"paused\"}\n title=\"Invoke agent\"\n >\n Invoke\n </button>\n </div>\n </div>\n );\n}\n\nfunction AgentDetailPanel({\n agentId,\n companyId,\n onBack,\n onPause,\n onResume,\n onInvoke,\n}: {\n agentId: string;\n companyId: string;\n onBack: () => void;\n onPause: (agentId: string) => void;\n onResume: (agentId: string) => void;\n onInvoke: (agentId: string, prompt: string) => void;\n}) {\n const detailParams = useMemo(\n () => ({ companyId, agentId }),\n [companyId, agentId],\n );\n const { data: detail, loading, error } = usePluginData<AgentDetailData>(\n \"agent-detail\",\n detailParams,\n );\n\n const [invokePrompt, setInvokePrompt] = useState(\"\");\n\n if (loading) return <LoadingIndicator message=\"Loading agent details...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n if (!detail) return <EmptyState message=\"Agent not found.\" />;\n\n const { agent, recentRuns } = detail;\n\n return (\n <div style={layoutStack}>\n {/* Back + header */}\n <div style={rowStyle}>\n <button type=\"button\" style={buttonStyle} onClick={onBack}>\n Back\n </button>\n <StatusDot status={agent.status} />\n <strong style={{ fontSize: \"16px\" }}>{agent.name}</strong>\n <Pill label={agent.status} color={STATUS_COLORS[agent.status]} />\n </div>\n\n {/* Stats grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(160px, 1fr))\",\n gap: \"12px\",\n }}\n >\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Role</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.role ?? \"Not assigned\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Adapter</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.adapterType ?? \"Default\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Last Heartbeat</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {relativeTime(agent.lastHeartbeat)}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Last Run Duration</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {formatDuration(agent.lastRunDurationMs)}\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div style={rowStyle}>\n {agent.status === \"running\" || agent.status === \"idle\" ? (\n <button\n type=\"button\"\n style={dangerButtonStyle}\n onClick={() => onPause(agent.id)}\n >\n Pause Agent\n </button>\n ) : null}\n {agent.status === \"paused\" ? (\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => onResume(agent.id)}\n >\n Resume Agent\n </button>\n ) : null}\n </div>\n\n {/* Invoke prompt */}\n <Section title=\"Invoke Agent\">\n <div style={{ display: \"flex\", gap: \"8px\" }}>\n <input\n type=\"text\"\n value={invokePrompt}\n onChange={(e) => setInvokePrompt(e.target.value)}\n placeholder=\"Enter prompt to invoke agent...\"\n style={{ ...inputStyle, flex: 1 }}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && invokePrompt.trim()) {\n onInvoke(agent.id, invokePrompt.trim());\n setInvokePrompt(\"\");\n }\n }}\n />\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={() => {\n if (invokePrompt.trim()) {\n onInvoke(agent.id, invokePrompt.trim());\n setInvokePrompt(\"\");\n }\n }}\n disabled={!invokePrompt.trim() || agent.status === \"paused\"}\n >\n Send\n </button>\n </div>\n </Section>\n\n {/* Recent runs */}\n <Section title=\"Recent Runs\">\n {recentRuns.length === 0 ? (\n <EmptyState message=\"No recent runs recorded.\" />\n ) : (\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {recentRuns.map((run) => (\n <div\n key={run.id}\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gridTemplateColumns: \"1fr auto\",\n gap: \"6px\",\n alignItems: \"start\",\n }}\n >\n <div style={{ display: \"grid\", gap: \"4px\", minWidth: 0 }}>\n <div style={{ fontSize: \"12px\", fontWeight: 600 }}>\n {run.result}\n </div>\n {run.prompt ? (\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n {run.prompt}\n </div>\n ) : null}\n </div>\n <div\n style={{\n display: \"grid\",\n gap: \"2px\",\n textAlign: \"right\",\n flexShrink: 0,\n }}\n >\n <div style={{ fontSize: \"11px\", opacity: 0.6 }}>\n {relativeTime(run.startedAt)}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.5 }}>\n {formatDuration(run.durationMs)}\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </Section>\n </div>\n );\n}\n\n/**\n * Full fleet monitoring page.\n *\n * Shows an agent grid with status filter, per-agent pause/resume/invoke\n * actions, a live stream indicator, and agent detail panel on click.\n */\nexport function FleetMonitorPage({ context }: PluginPageProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n // Fleet data\n const overviewParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const {\n data: overview,\n loading,\n error,\n refresh,\n } = usePluginData<FleetOverview>(\"fleet-overview\", overviewParams);\n\n // Stream\n const fleetStream = usePluginStream<FleetStatusEvent>(\"fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n // Actions\n const pauseAgent = usePluginAction(\"pause-agent\");\n const resumeAgent = usePluginAction(\"resume-agent\");\n const invokeAgent = usePluginAction(\"invoke-agent\");\n\n // UI state\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(\"all\");\n const [detailView, setDetailView] = useState<AgentDetailView>(null);\n const [actionLoading, setActionLoading] = useState(false);\n\n // Apply live status updates\n const agents = useMemo(() => {\n const base = overview?.fleet ?? [];\n if (fleetStream.events.length === 0) return base;\n\n const latestStatus = new Map<string, AgentStatus>();\n for (const event of fleetStream.events) {\n latestStatus.set(event.agentId, event.status);\n }\n\n return base.map((agent) => {\n const liveStatus = latestStatus.get(agent.id);\n return liveStatus ? { ...agent, status: liveStatus } : agent;\n });\n }, [overview?.fleet, fleetStream.events]);\n\n // Filter\n const filteredAgents = useMemo(() => {\n if (statusFilter === \"all\") return agents;\n return agents.filter((a) => a.status === statusFilter);\n }, [agents, statusFilter]);\n\n const counts = useMemo(() => statusCounts(agents), [agents]);\n\n // Action handlers\n async function handlePause(agentId: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await pauseAgent({ companyId, agentId });\n refresh();\n toast({\n title: \"Agent paused\",\n body: \"The agent has been paused and will not execute until resumed.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to pause agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n async function handleResume(agentId: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await resumeAgent({ companyId, agentId });\n refresh();\n toast({\n title: \"Agent resumed\",\n body: \"The agent is now active and ready to process work.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to resume agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n async function handleInvoke(agentId: string, prompt?: string) {\n if (!companyId || actionLoading) return;\n setActionLoading(true);\n try {\n await invokeAgent({ companyId, agentId, prompt: prompt ?? undefined });\n refresh();\n toast({\n title: \"Agent invoked\",\n body: prompt\n ? `Agent invoked with prompt: \"${prompt}\"`\n : \"Agent has been invoked.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Failed to invoke agent\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setActionLoading(false);\n }\n }\n\n // Detail view\n if (detailView && companyId) {\n return (\n <div style={{ ...layoutStack, maxWidth: \"800px\" }}>\n <AgentDetailPanel\n agentId={detailView.agentId}\n companyId={companyId}\n onBack={() => setDetailView(null)}\n onPause={(id) => void handlePause(id)}\n onResume={(id) => void handleResume(id)}\n onInvoke={(id, prompt) => void handleInvoke(id, prompt)}\n />\n </div>\n );\n }\n\n // No company selected\n if (!companyId) {\n return (\n <div style={layoutStack}>\n <Section title=\"Fleet Monitor\">\n <EmptyState message=\"Select a company to view your agent fleet.\" />\n </Section>\n </div>\n );\n }\n\n return (\n <div style={layoutStack}>\n {/* Page header */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"12px\",\n flexWrap: \"wrap\",\n }}\n >\n <div>\n <h1 style={{ fontSize: \"18px\", fontWeight: 700, margin: 0 }}>\n Fleet Monitor\n </h1>\n <div style={mutedTextStyle}>\n {overview\n ? `${overview.totalAgents} agent${overview.totalAgents === 1 ? \"\" : \"s\"} registered. Last health check: ${relativeTime(overview.lastHealthCheckAt)}`\n : \"Loading fleet data...\"}\n </div>\n </div>\n <div style={rowStyle}>\n {fleetStream.connected ? (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n fontSize: \"11px\",\n opacity: 0.7,\n }}\n >\n <StatusDot status=\"online\" />\n Live\n </div>\n ) : null}\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => refresh()}\n >\n Refresh\n </button>\n </div>\n </div>\n\n {/* Status filter tabs */}\n <StatusFilterBar\n active={statusFilter}\n onChange={setStatusFilter}\n counts={counts}\n />\n\n {/* Agent list */}\n {loading && agents.length === 0 ? (\n <LoadingIndicator message=\"Loading fleet agents...\" />\n ) : error ? (\n <ErrorBanner message={error.message} />\n ) : filteredAgents.length === 0 ? (\n <EmptyState\n message={\n statusFilter !== \"all\"\n ? `No agents with status \"${statusFilter}\".`\n : \"No agents registered in this fleet.\"\n }\n />\n ) : (\n <div style={{ display: \"grid\", gap: \"8px\" }}>\n {filteredAgents.map((agent) => (\n <AgentRow\n key={agent.id}\n agent={agent}\n onSelect={() => setDetailView({ agentId: agent.id })}\n onPause={() => void handlePause(agent.id)}\n onResume={() => void handleResume(agent.id)}\n onInvoke={() => void handleInvoke(agent.id)}\n actionLoading={actionLoading}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 3. TortugaSidebarLink\n// ---------------------------------------------------------------------------\n\n/**\n * Sidebar navigation link to the fleet monitor page.\n * Shows a helm icon and an agent count badge from fleet overview.\n */\nexport function TortugaSidebarLink({ context }: PluginSidebarProps) {\n const overviewParams = useMemo(\n () => (context.companyId ? { companyId: context.companyId } : {}),\n [context.companyId],\n );\n const { data: overview } = usePluginData<FleetOverview>(\n \"fleet-overview\",\n overviewParams,\n );\n\n const href = pluginPagePath(context.companyPrefix);\n const isActive =\n typeof window !== \"undefined\" && window.location.pathname === href;\n\n const agentCount = overview?.totalAgents ?? 0;\n\n return (\n <a\n href={href}\n aria-current={isActive ? \"page\" : undefined}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n padding: \"8px 12px\",\n fontSize: \"13px\",\n fontWeight: isActive ? 600 : 400,\n textDecoration: \"none\",\n color: isActive\n ? \"var(--foreground)\"\n : \"color-mix(in srgb, var(--foreground) 80%, transparent)\",\n background: isActive\n ? \"color-mix(in srgb, var(--accent, var(--muted)) 60%, transparent)\"\n : \"transparent\",\n borderRadius: \"6px\",\n transition: \"background 0.15s, color 0.15s\",\n cursor: \"pointer\",\n }}\n >\n <FleetIcon size={16} />\n\n <span style={{ flex: 1 }}>Tortuga</span>\n\n {/* Agent count badge */}\n {agentCount > 0 ? (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minWidth: \"20px\",\n height: \"18px\",\n borderRadius: \"999px\",\n background:\n \"color-mix(in srgb, var(--foreground) 12%, transparent)\",\n fontSize: \"10px\",\n fontWeight: 600,\n padding: \"0 5px\",\n flexShrink: 0,\n }}\n >\n {agentCount}\n </span>\n ) : null}\n </a>\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bopen-io/tortuga-plugin",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "description": "bOpen agent fleet bridge: syncs agents from ClawNet registry, exposes skills as tools, fleet monitoring, webhook integrations",