@bopen-io/clawnet-plugin 0.0.1 → 0.0.3

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.
@@ -0,0 +1,72 @@
1
+ const PLUGIN_ID = "bopen-io.clawnet-plugin";
2
+ const PLUGIN_VERSION = "0.0.1";
3
+ const PAGE_ROUTE = "clawnet";
4
+ const SLOT_IDS = {
5
+ dashboardWidget: "clawnet-dashboard-widget",
6
+ page: "clawnet-page",
7
+ sidebar: "clawnet-sidebar-link",
8
+ settingsPage: "clawnet-settings-page"
9
+ };
10
+ const EXPORT_NAMES = {
11
+ dashboardWidget: "ClawNetFleetWidget",
12
+ page: "ClawNetMarketplacePage",
13
+ sidebar: "ClawNetSidebarLink",
14
+ settingsPage: "ClawNetSettingsPage"
15
+ };
16
+ const JOB_KEYS = {
17
+ sync: "clawnet-sync"
18
+ };
19
+ const TOOL_NAMES = {
20
+ agentLookup: "agent-lookup",
21
+ skillSearch: "skill-search",
22
+ fleetOverview: "fleet-overview"
23
+ };
24
+ const STREAM_CHANNELS = {
25
+ fleetStatus: "clawnet:fleet-status",
26
+ syncProgress: "clawnet:sync-progress"
27
+ };
28
+ const ENTITY_TYPES = {
29
+ agent: "clawnet-agent",
30
+ skill: "clawnet-skill"
31
+ };
32
+ const DATA_KEYS = {
33
+ clawnetAgents: "clawnet-agents",
34
+ clawnetSkills: "clawnet-skills",
35
+ syncStatus: "sync-status",
36
+ fleetSummary: "fleet-summary"
37
+ };
38
+ const ACTION_KEYS = {
39
+ triggerSync: "trigger-sync",
40
+ linkAgent: "link-agent",
41
+ validateConfig: "validate-config"
42
+ };
43
+ const EVENT_TYPES = {
44
+ agentStatusChanged: "agent.status_changed",
45
+ agentCreated: "agent.created"
46
+ };
47
+ const STATE_KEYS = {
48
+ syncCursor: "clawnet-sync-cursor",
49
+ clawnetLink: "clawnet-link"
50
+ };
51
+ const DEFAULT_CONFIG = {
52
+ clawnetApiUrl: "https://clawnet.sh",
53
+ clawnetApiKey: "",
54
+ syncIntervalMinutes: 15
55
+ };
56
+ export {
57
+ ACTION_KEYS,
58
+ DATA_KEYS,
59
+ DEFAULT_CONFIG,
60
+ ENTITY_TYPES,
61
+ EVENT_TYPES,
62
+ EXPORT_NAMES,
63
+ JOB_KEYS,
64
+ PAGE_ROUTE,
65
+ PLUGIN_ID,
66
+ PLUGIN_VERSION,
67
+ SLOT_IDS,
68
+ STATE_KEYS,
69
+ STREAM_CHANNELS,
70
+ TOOL_NAMES
71
+ };
72
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/constants.ts"],
4
+ "sourcesContent": ["// ---------------------------------------------------------------------------\n// Stable identifiers for the ClawNet plugin.\n//\n// All IDs, keys, export names, and route segments live here so they can be\n// referenced from both the manifest and the worker/UI without risk of drift.\n// ---------------------------------------------------------------------------\n\nexport const PLUGIN_ID = \"bopen-io.clawnet-plugin\";\nexport const PLUGIN_VERSION = \"0.0.1\";\nexport const PAGE_ROUTE = \"clawnet\";\n\n// ---------------------------------------------------------------------------\n// UI slot IDs (must be unique within this plugin)\n// ---------------------------------------------------------------------------\n\nexport const SLOT_IDS = {\n dashboardWidget: \"clawnet-dashboard-widget\",\n page: \"clawnet-page\",\n sidebar: \"clawnet-sidebar-link\",\n settingsPage: \"clawnet-settings-page\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// React component export names (must match the named exports in the UI bundle)\n// ---------------------------------------------------------------------------\n\nexport const EXPORT_NAMES = {\n dashboardWidget: \"ClawNetFleetWidget\",\n page: \"ClawNetMarketplacePage\",\n sidebar: \"ClawNetSidebarLink\",\n settingsPage: \"ClawNetSettingsPage\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Scheduled job keys\n// ---------------------------------------------------------------------------\n\nexport const JOB_KEYS = {\n sync: \"clawnet-sync\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Agent tool names (kebab-case, namespaced at runtime by the host)\n// ---------------------------------------------------------------------------\n\nexport const TOOL_NAMES = {\n agentLookup: \"agent-lookup\",\n skillSearch: \"skill-search\",\n fleetOverview: \"fleet-overview\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Stream channel names\n// ---------------------------------------------------------------------------\n\nexport const STREAM_CHANNELS = {\n fleetStatus: \"clawnet:fleet-status\",\n syncProgress: \"clawnet:sync-progress\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Entity types (for ctx.entities)\n// ---------------------------------------------------------------------------\n\nexport const ENTITY_TYPES = {\n agent: \"clawnet-agent\",\n skill: \"clawnet-skill\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Data handler keys (for ctx.data.register / usePluginData)\n// ---------------------------------------------------------------------------\n\nexport const DATA_KEYS = {\n clawnetAgents: \"clawnet-agents\",\n clawnetSkills: \"clawnet-skills\",\n syncStatus: \"sync-status\",\n fleetSummary: \"fleet-summary\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Action handler keys (for ctx.actions.register / usePluginAction)\n// ---------------------------------------------------------------------------\n\nexport const ACTION_KEYS = {\n triggerSync: \"trigger-sync\",\n linkAgent: \"link-agent\",\n validateConfig: \"validate-config\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Event types we subscribe to\n// ---------------------------------------------------------------------------\n\nexport const EVENT_TYPES = {\n agentStatusChanged: \"agent.status_changed\",\n agentCreated: \"agent.created\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// State keys (for ctx.state)\n// ---------------------------------------------------------------------------\n\nexport const STATE_KEYS = {\n syncCursor: \"clawnet-sync-cursor\",\n clawnetLink: \"clawnet-link\",\n} as const;\n\n// ---------------------------------------------------------------------------\n// Default instance configuration values\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_CONFIG = {\n clawnetApiUrl: \"https://clawnet.sh\",\n clawnetApiKey: \"\",\n syncIntervalMinutes: 15,\n} as const;\n"],
5
+ "mappings": "AAOO,MAAM,YAAY;AAClB,MAAM,iBAAiB;AACvB,MAAM,aAAa;AAMnB,MAAM,WAAW;AAAA,EACtB,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,cAAc;AAChB;AAMO,MAAM,eAAe;AAAA,EAC1B,iBAAiB;AAAA,EACjB,MAAM;AAAA,EACN,SAAS;AAAA,EACT,cAAc;AAChB;AAMO,MAAM,WAAW;AAAA,EACtB,MAAM;AACR;AAMO,MAAM,aAAa;AAAA,EACxB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,eAAe;AACjB;AAMO,MAAM,kBAAkB;AAAA,EAC7B,aAAa;AAAA,EACb,cAAc;AAChB;AAMO,MAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,OAAO;AACT;AAMO,MAAM,YAAY;AAAA,EACvB,eAAe;AAAA,EACf,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,cAAc;AAChB;AAMO,MAAM,cAAc;AAAA,EACzB,aAAa;AAAA,EACb,WAAW;AAAA,EACX,gBAAgB;AAClB;AAMO,MAAM,cAAc;AAAA,EACzB,oBAAoB;AAAA,EACpB,cAAc;AAChB;AAMO,MAAM,aAAa;AAAA,EACxB,YAAY;AAAA,EACZ,aAAa;AACf;AAMO,MAAM,iBAAiB;AAAA,EAC5B,eAAe;AAAA,EACf,eAAe;AAAA,EACf,qBAAqB;AACvB;",
6
+ "names": []
7
+ }
package/dist/ui/index.js CHANGED
@@ -651,9 +651,12 @@ function ClawNetFleetWidget({ context }) {
651
651
  "sync-status",
652
652
  syncParams
653
653
  );
654
- const fleetStream = usePluginStream("fleet-status", {
655
- companyId: companyId ?? void 0
656
- });
654
+ const fleetStream = (
655
+ // TODO(M4): import STREAM_CHANNELS from constants once UI bundle resolution is verified
656
+ usePluginStream("clawnet:fleet-status", {
657
+ companyId: companyId ?? void 0
658
+ })
659
+ );
657
660
  const triggerSync = usePluginAction2("trigger-sync");
658
661
  const [syncing, setSyncing] = useState2(false);
659
662
  async function handleSync() {
@@ -1048,9 +1051,12 @@ function SkillCard({ skill }) {
1048
1051
  function SyncProgressBar({
1049
1052
  companyId
1050
1053
  }) {
1051
- const syncProgress = usePluginStream("sync-progress", {
1052
- companyId: companyId ?? void 0
1053
- });
1054
+ const syncProgress = (
1055
+ // TODO(M4): import STREAM_CHANNELS from constants once UI bundle resolution is verified
1056
+ usePluginStream("clawnet:sync-progress", {
1057
+ companyId: companyId ?? void 0
1058
+ })
1059
+ );
1054
1060
  const latest = syncProgress.lastEvent;
1055
1061
  if (!latest || !syncProgress.connected) return null;
1056
1062
  const pct = Math.min(100, Math.max(0, latest.progress));
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/ui/index.tsx", "../../src/ui/settings.tsx"],
4
- "sourcesContent": ["import { useEffect, 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 SyncStatus = {\n lastSyncAt: string | null;\n agentCount: number;\n skillCount: number;\n};\n\ntype ClawNetAgent = {\n id: string;\n slug: string;\n displayName: string;\n description: string | null;\n model: string | null;\n color: string | null;\n starCount: number;\n trustScore: number | null;\n attestations: string[];\n skills: string[];\n createdAt: string;\n};\n\ntype ClawNetSkill = {\n id: string;\n slug: string;\n displayName: string;\n description: string | null;\n category: string | null;\n starCount: number;\n};\n\ntype AgentListResponse = {\n agents: ClawNetAgent[];\n total: number;\n page: number;\n limit: number;\n};\n\ntype SkillListResponse = {\n skills: ClawNetSkill[];\n total: number;\n};\n\ntype FleetStatusEvent = {\n agentId: string;\n status: string;\n timestamp: string;\n};\n\ntype SyncProgressEvent = {\n phase: string;\n progress: number;\n message: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared inline styles (following kitchen sink pattern)\n// ---------------------------------------------------------------------------\n\nconst PAGE_ROUTE = \"clawnet\";\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 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 truncateText(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return `${text.slice(0, maxLen - 1)}...`;\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\nfunction StatusDot({ status }: { status: string }) {\n const colorMap: Record<string, string> = {\n online: \"#16a34a\",\n idle: \"#d97706\",\n offline: \"#6b7280\",\n error: \"#dc2626\",\n running: \"#2563eb\",\n };\n const dotColor = colorMap[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 StarCount({ count }: { count: number }) {\n if (count <= 0) return null;\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: \"3px\", fontSize: \"11px\", opacity: 0.7 }}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\">\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n {count}\n </span>\n );\n}\n\nfunction TrustBadge({ score }: { score: number | null }) {\n if (score === null || score === undefined) return null;\n const level =\n score >= 80 ? \"high\" : score >= 50 ? \"medium\" : \"low\";\n const colorMap = { high: \"#16a34a\", medium: \"#d97706\", low: \"#dc2626\" };\n const labelMap = { high: \"Trusted\", medium: \"Verified\", low: \"Unverified\" };\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n fontSize: \"10px\",\n fontWeight: 600,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: colorMap[level],\n }}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\">\n <path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z\" />\n </svg>\n {labelMap[level]}\n </span>\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// 1. DashboardWidget\n// ---------------------------------------------------------------------------\n\n/**\n * Compact fleet status widget for the main Paperclip dashboard.\n *\n * Shows agent count, skill count, online count, and last sync time.\n * Subscribes to fleet-status for live status updates.\n * Provides a manual \"Sync Now\" button with toast feedback.\n */\nexport function ClawNetFleetWidget({ context }: PluginWidgetProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n const syncParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: syncStatus, loading, error, refresh } = usePluginData<SyncStatus>(\n \"sync-status\",\n syncParams,\n );\n\n const fleetStream = usePluginStream<FleetStatusEvent>(\"fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n const triggerSync = usePluginAction(\"trigger-sync\");\n const [syncing, setSyncing] = useState(false);\n\n async function handleSync() {\n if (!companyId || syncing) return;\n setSyncing(true);\n try {\n await triggerSync({ companyId });\n refresh();\n toast({\n title: \"ClawNet sync started\",\n body: \"Agents and skills are being refreshed from the registry.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n // Derive live online count from the fleet stream event history\n const onlineCount = useMemo(() => {\n const latestByAgent = new Map<string, string>();\n for (const event of fleetStream.events) {\n latestByAgent.set(event.agentId, event.status);\n }\n let count = 0;\n for (const status of latestByAgent.values()) {\n if (status === \"online\" || status === \"running\") count++;\n }\n return count;\n }, [fleetStream.events]);\n\n if (loading) return <LoadingIndicator message=\"Loading fleet status...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <strong>ClawNet Fleet</strong>\n {fleetStream.connected ? (\n <StatusDot status=\"online\" />\n ) : null}\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr 1fr\",\n gap: \"8px\",\n }}\n >\n <div>\n <div style={statValueStyle}>{syncStatus?.agentCount ?? 0}</div>\n <div style={statLabelStyle}>Agents</div>\n </div>\n <div>\n <div style={statValueStyle}>{syncStatus?.skillCount ?? 0}</div>\n <div style={statLabelStyle}>Skills</div>\n </div>\n <div>\n <div style={statValueStyle}>{onlineCount}</div>\n <div style={statLabelStyle}>Online</div>\n </div>\n </div>\n\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n Last sync: {relativeTime(syncStatus?.lastSyncAt ?? null)}\n </div>\n\n <div style={rowStyle}>\n <a\n href={pluginPagePath(context.companyPrefix)}\n style={{ fontSize: \"12px\", color: \"inherit\" }}\n >\n Browse marketplace\n </a>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => void handleSync()}\n disabled={syncing}\n >\n {syncing ? \"Syncing...\" : \"Sync Now\"}\n </button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 2. MarketplacePage\n// ---------------------------------------------------------------------------\n\nconst AGENTS_PER_PAGE = 20;\n\ntype MarketplaceTab = \"agents\" | \"skills\";\ntype AgentDetailView = { agent: ClawNetAgent } | null;\n\nfunction TabBar({\n active,\n onChange,\n}: {\n active: MarketplaceTab;\n onChange: (tab: MarketplaceTab) => void;\n}) {\n const tabs: { key: MarketplaceTab; label: string }[] = [\n { key: \"agents\", label: \"Agents\" },\n { key: \"skills\", label: \"Skills\" },\n ];\n\n return (\n <div\n style={{\n display: \"flex\",\n gap: \"0\",\n borderBottom: \"1px solid var(--border)\",\n }}\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => onChange(tab.key)}\n style={{\n appearance: \"none\",\n background: \"transparent\",\n border: \"none\",\n borderBottom:\n active === tab.key\n ? \"2px solid var(--foreground)\"\n : \"2px solid transparent\",\n color: active === tab.key ? \"var(--foreground)\" : \"var(--muted-foreground, inherit)\",\n padding: \"10px 16px\",\n fontSize: \"13px\",\n fontWeight: active === tab.key ? 600 : 400,\n cursor: \"pointer\",\n transition: \"color 0.15s, border-color 0.15s\",\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n );\n}\n\nfunction SearchBar({\n value,\n onChange,\n placeholder,\n}: {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n}) {\n return (\n <div style={{ position: \"relative\" }}>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: \"10px\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n opacity: 0.45,\n }}\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"M21 21l-4.35-4.35\" />\n </svg>\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n style={{\n ...inputStyle,\n paddingLeft: \"30px\",\n }}\n />\n </div>\n );\n}\n\nfunction AgentCard({\n agent,\n onSelect,\n onHire,\n}: {\n agent: ClawNetAgent;\n onSelect: () => void;\n onHire: () => void;\n}) {\n const colorIndicator = agent.color ?? \"var(--muted-foreground)\";\n\n return (\n <div\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gap: \"10px\",\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 {/* Header: color dot, name, slug, stars, trust */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <span\n style={{\n display: \"inline-block\",\n width: \"10px\",\n height: \"10px\",\n borderRadius: \"3px\",\n background: colorIndicator,\n flexShrink: 0,\n }}\n />\n <div style={{ minWidth: 0, flex: 1 }}>\n <div\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {agent.displayName}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.55 }}>\n {agent.slug}\n </div>\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n flexShrink: 0,\n }}\n >\n <StarCount count={agent.starCount} />\n <TrustBadge score={agent.trustScore} />\n </div>\n </div>\n\n {/* Description */}\n {agent.description ? (\n <div style={mutedTextStyle}>\n {truncateText(agent.description, 120)}\n </div>\n ) : null}\n\n {/* Footer: pills + hire button */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n }}\n >\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"4px\" }}>\n {agent.model ? <Pill label={agent.model} /> : null}\n {agent.attestations.slice(0, 2).map((att) => (\n <Pill key={att} label={att} color=\"#2563eb\" />\n ))}\n {agent.skills.length > 0 ? (\n <Pill\n label={`${agent.skills.length} skill${agent.skills.length === 1 ? \"\" : \"s\"}`}\n />\n ) : null}\n </div>\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={(e) => {\n e.stopPropagation();\n onHire();\n }}\n >\n Hire Agent\n </button>\n </div>\n </div>\n );\n}\n\nfunction AgentDetail({\n agent,\n onBack,\n onHire,\n}: {\n agent: ClawNetAgent;\n onBack: () => void;\n onHire: () => void;\n}) {\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <button type=\"button\" style={buttonStyle} onClick={onBack}>\n Back\n </button>\n <strong style={{ fontSize: \"16px\" }}>{agent.displayName}</strong>\n <Pill label={agent.slug} />\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(180px, 1fr))\",\n gap: \"12px\",\n }}\n >\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Model</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.model ?? \"Not specified\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Stars</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.starCount}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Trust Score</div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\", marginTop: \"4px\" }}>\n <span style={{ fontSize: \"13px\" }}>\n {agent.trustScore !== null ? `${agent.trustScore}/100` : \"N/A\"}\n </span>\n <TrustBadge score={agent.trustScore} />\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Created</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {relativeTime(agent.createdAt)}\n </div>\n </div>\n </div>\n\n {agent.description ? (\n <Section title=\"Description\">\n <div style={{ fontSize: \"13px\", lineHeight: 1.55 }}>\n {agent.description}\n </div>\n </Section>\n ) : null}\n\n {agent.attestations.length > 0 ? (\n <Section title=\"Attestations\">\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"6px\" }}>\n {agent.attestations.map((att) => (\n <Pill key={att} label={att} color=\"#2563eb\" />\n ))}\n </div>\n </Section>\n ) : null}\n\n {agent.skills.length > 0 ? (\n <Section title=\"Skills\">\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"6px\" }}>\n {agent.skills.map((skill) => (\n <Pill key={skill} label={skill} />\n ))}\n </div>\n </Section>\n ) : null}\n\n {agent.color ? (\n <Section title=\"Theme Color\">\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <span\n style={{\n display: \"inline-block\",\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"4px\",\n background: agent.color,\n border: \"1px solid var(--border)\",\n }}\n />\n <span style={{ fontSize: \"12px\", fontFamily: \"monospace\" }}>\n {agent.color}\n </span>\n </div>\n </Section>\n ) : null}\n\n <div>\n <button type=\"button\" style={primaryButtonStyle} onClick={onHire}>\n Hire This Agent\n </button>\n </div>\n </div>\n );\n}\n\nfunction SkillCard({ skill }: { skill: ClawNetSkill }) {\n return (\n <div style={{ ...subtleCardStyle, display: \"grid\", gap: \"8px\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {skill.displayName}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.55 }}>{skill.slug}</div>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\", flexShrink: 0 }}>\n {skill.category ? <Pill label={skill.category} /> : null}\n <StarCount count={skill.starCount} />\n </div>\n </div>\n {skill.description ? (\n <div style={mutedTextStyle}>\n {truncateText(skill.description, 140)}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction SyncProgressBar({\n companyId,\n}: {\n companyId: string | null;\n}) {\n const syncProgress = usePluginStream<SyncProgressEvent>(\"sync-progress\", {\n companyId: companyId ?? undefined,\n });\n\n const latest = syncProgress.lastEvent;\n if (!latest || !syncProgress.connected) return null;\n\n const pct = Math.min(100, Math.max(0, latest.progress));\n\n return (\n <div style={{ ...subtleCardStyle, display: \"grid\", gap: \"6px\" }}>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <span style={eyebrowStyle}>{latest.phase}</span>\n <span style={{ fontSize: \"11px\", opacity: 0.6 }}>{pct}%</span>\n </div>\n <div\n style={{\n height: \"4px\",\n borderRadius: \"2px\",\n background: \"color-mix(in srgb, var(--border) 50%, transparent)\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${pct}%`,\n borderRadius: \"2px\",\n background: \"var(--foreground)\",\n transition: \"width 0.3s ease\",\n }}\n />\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.6 }}>{latest.message}</div>\n </div>\n );\n}\n\n/**\n * Full marketplace page for browsing ClawNet agents and skills.\n *\n * - Tab bar to switch between Agents and Skills views\n * - Search bar with 300ms debounce\n * - Agent cards with color, model badge, star count, trust indicators\n * - Agent detail view on click\n * - \"Hire Agent\" button with toast guidance to Paperclip agent creation\n * - Skill cards with category and star count\n * - Pagination via \"Load more\" button\n * - Live sync progress bar during registry refresh\n */\nexport function ClawNetMarketplacePage({ context }: PluginPageProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n // Tab state\n const [activeTab, setActiveTab] = useState<MarketplaceTab>(\"agents\");\n const [search, setSearch] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [page, setPage] = useState(1);\n const [detailView, setDetailView] = useState<AgentDetailView>(null);\n\n // Debounce search input\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedSearch(search);\n setPage(1);\n }, 300);\n return () => clearTimeout(timer);\n }, [search]);\n\n // Agent data\n const agentParams = useMemo(\n () =>\n companyId\n ? {\n companyId,\n search: debouncedSearch || undefined,\n page,\n limit: AGENTS_PER_PAGE,\n }\n : {},\n [companyId, debouncedSearch, page],\n );\n const {\n data: agentData,\n loading: agentsLoading,\n error: agentsError,\n } = usePluginData<AgentListResponse>(\"clawnet-agents\", agentParams);\n\n // Skill data\n const skillParams = useMemo(\n () =>\n companyId\n ? { companyId, search: debouncedSearch || undefined }\n : {},\n [companyId, debouncedSearch],\n );\n const {\n data: skillData,\n loading: skillsLoading,\n error: skillsError,\n } = usePluginData<SkillListResponse>(\"clawnet-skills\", skillParams);\n\n // Sync status header\n const syncParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: syncStatus, refresh: refreshSync } = usePluginData<SyncStatus>(\n \"sync-status\",\n syncParams,\n );\n\n // Manual sync action\n const triggerSync = usePluginAction(\"trigger-sync\");\n const [syncing, setSyncing] = useState(false);\n\n async function handleSync() {\n if (!companyId || syncing) return;\n setSyncing(true);\n try {\n await triggerSync({ companyId });\n refreshSync();\n toast({\n title: \"Sync started\",\n body: \"Refreshing agent and skill data from ClawNet registry.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n function handleHireAgent(agent: ClawNetAgent) {\n toast({\n title: `Ready to hire: ${agent.displayName}`,\n body: \"Go to the Agents page and create a new agent. The template data from this ClawNet agent is ready to use.\",\n tone: \"info\",\n ttlMs: 8000,\n action: {\n label: \"Go to Agents\",\n href: hostPath(context.companyPrefix, \"/agents\"),\n },\n });\n }\n\n // Agent detail view\n if (detailView) {\n return (\n <div style={{ ...layoutStack, maxWidth: \"800px\" }}>\n <AgentDetail\n agent={detailView.agent}\n onBack={() => setDetailView(null)}\n onHire={() => handleHireAgent(detailView.agent)}\n />\n </div>\n );\n }\n\n // No company selected\n if (!companyId) {\n return (\n <div style={layoutStack}>\n <Section title=\"ClawNet Marketplace\">\n <EmptyState message=\"Select a company to browse the agent marketplace.\" />\n </Section>\n </div>\n );\n }\n\n const agents = agentData?.agents ?? [];\n const agentTotal = agentData?.total ?? 0;\n const hasMoreAgents = agents.length < agentTotal && page * AGENTS_PER_PAGE < agentTotal;\n\n const skills = skillData?.skills ?? [];\n const skillTotal = skillData?.total ?? 0;\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 ClawNet Marketplace\n </h1>\n <div style={mutedTextStyle}>\n {syncStatus\n ? `${syncStatus.agentCount} agents, ${syncStatus.skillCount} skills available. Last sync: ${relativeTime(syncStatus.lastSyncAt)}`\n : \"Loading registry status...\"}\n </div>\n </div>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => void handleSync()}\n disabled={syncing}\n >\n {syncing ? \"Syncing...\" : \"Refresh Registry\"}\n </button>\n </div>\n\n {/* Sync progress indicator */}\n <SyncProgressBar companyId={companyId} />\n\n {/* Search */}\n <SearchBar\n value={search}\n onChange={setSearch}\n placeholder={\n activeTab === \"agents\"\n ? \"Search agents by name, skill, or model...\"\n : \"Search skills by name or category...\"\n }\n />\n\n {/* Tab bar */}\n <TabBar\n active={activeTab}\n onChange={(tab) => {\n setActiveTab(tab);\n setSearch(\"\");\n setPage(1);\n }}\n />\n\n {/* Agents tab content */}\n {activeTab === \"agents\" ? (\n <div style={layoutStack}>\n {agentsLoading && agents.length === 0 ? (\n <LoadingIndicator message=\"Loading agents from registry...\" />\n ) : agentsError ? (\n <ErrorBanner message={agentsError.message} />\n ) : agents.length === 0 ? (\n <EmptyState\n message={\n debouncedSearch\n ? `No agents found matching \"${debouncedSearch}\".`\n : \"No agents available. Try syncing the registry.\"\n }\n />\n ) : (\n <>\n <div style={{ fontSize: \"12px\", opacity: 0.6 }}>\n Showing {agents.length} of {agentTotal} agent{agentTotal === 1 ? \"\" : \"s\"}\n {debouncedSearch ? ` matching \"${debouncedSearch}\"` : \"\"}\n </div>\n <div style={{ display: \"grid\", gap: \"10px\" }}>\n {agents.map((agent) => (\n <AgentCard\n key={agent.id}\n agent={agent}\n onSelect={() => setDetailView({ agent })}\n onHire={() => handleHireAgent(agent)}\n />\n ))}\n </div>\n {hasMoreAgents ? (\n <div style={{ display: \"flex\", justifyContent: \"center\", paddingTop: \"8px\" }}>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => setPage((p) => p + 1)}\n disabled={agentsLoading}\n >\n {agentsLoading ? \"Loading...\" : `Load more (${agentTotal - agents.length} remaining)`}\n </button>\n </div>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {/* Skills tab content */}\n {activeTab === \"skills\" ? (\n <div style={layoutStack}>\n {skillsLoading ? (\n <LoadingIndicator message=\"Loading skills...\" />\n ) : skillsError ? (\n <ErrorBanner message={skillsError.message} />\n ) : skills.length === 0 ? (\n <EmptyState\n message={\n debouncedSearch\n ? `No skills found matching \"${debouncedSearch}\".`\n : \"No skills available. Try syncing the registry.\"\n }\n />\n ) : (\n <>\n <div style={{ fontSize: \"12px\", opacity: 0.6 }}>\n {skillTotal} skill{skillTotal === 1 ? \"\" : \"s\"} available\n {debouncedSearch ? ` matching \"${debouncedSearch}\"` : \"\"}\n </div>\n <div style={{ display: \"grid\", gap: \"10px\" }}>\n {skills.map((skill) => (\n <SkillCard key={skill.id} skill={skill} />\n ))}\n </div>\n </>\n )}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 3. SidebarEntry\n// ---------------------------------------------------------------------------\n\n/**\n * Sidebar navigation link to the ClawNet marketplace page.\n * Shows a network icon and an agent count badge from sync status.\n */\nexport function ClawNetSidebarLink({ context }: PluginSidebarProps) {\n const syncParams = useMemo(\n () => (context.companyId ? { companyId: context.companyId } : {}),\n [context.companyId],\n );\n const { data: syncStatus } = usePluginData<SyncStatus>(\"sync-status\", syncParams);\n\n const href = pluginPagePath(context.companyPrefix);\n const isActive =\n typeof window !== \"undefined\" && window.location.pathname === href;\n\n const agentCount = syncStatus?.agentCount ?? 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 ? \"var(--foreground)\" : \"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 {/* Network/nodes icon */}\n <svg\n width=\"16\"\n height=\"16\"\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 <circle cx=\"12\" cy=\"5\" r=\"2.5\" />\n <circle cx=\"5\" cy=\"19\" r=\"2.5\" />\n <circle cx=\"19\" cy=\"19\" r=\"2.5\" />\n <path d=\"M12 7.5v4\" />\n <path d=\"M7.5 17.5l3-6\" />\n <path d=\"M16.5 17.5l-3-6\" />\n </svg>\n\n <span style={{ flex: 1 }}>ClawNet</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: \"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\n// ---------------------------------------------------------------------------\n// 4. Settings page (re-export from separate module)\n// ---------------------------------------------------------------------------\n\nexport { ClawNetSettingsPage } from \"./settings.js\";\n", "import { useState, useEffect, type CSSProperties, type FormEvent } from \"react\";\nimport {\n usePluginData,\n usePluginAction,\n usePluginToast,\n type PluginSettingsPageProps,\n} from \"@paperclipai/plugin-sdk/ui\";\n\n// ---------------------------------------------------------------------------\n// Plugin identity \u2014 must match manifest.id\n// ---------------------------------------------------------------------------\n\nconst PLUGIN_ID = \"bopen-io.clawnet-plugin\";\n\n// ---------------------------------------------------------------------------\n// Config types\n// ---------------------------------------------------------------------------\n\ntype ClawNetConfig = {\n clawnetApiUrl: string;\n clawnetApiKey: string;\n syncIntervalMinutes: number;\n};\n\ntype SyncStatusData = {\n lastSyncAt: string | null;\n agentCount: number;\n skillCount: number;\n status: \"idle\" | \"syncing\" | \"error\";\n error: string | null;\n};\n\nconst DEFAULT_CONFIG: ClawNetConfig = {\n clawnetApiUrl: \"https://clawnet.sh\",\n clawnetApiKey: \"\",\n syncIntervalMinutes: 15,\n};\n\n// ---------------------------------------------------------------------------\n// Styles (host CSS variable tokens, matching kitchen sink patterns)\n// ---------------------------------------------------------------------------\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 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 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 boxSizing: \"border-box\",\n};\n\nconst labelStyle: CSSProperties = {\n display: \"grid\",\n gap: \"6px\",\n};\n\nconst labelTextStyle: CSSProperties = {\n fontSize: \"12px\",\n fontWeight: 500,\n};\n\nconst helpTextStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.65,\n lineHeight: 1.45,\n};\n\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n marginBottom: \"10px\",\n};\n\nconst statusDotStyle = (color: string): CSSProperties => ({\n display: \"inline-block\",\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: color,\n flexShrink: 0,\n});\n\n// ---------------------------------------------------------------------------\n// Config fetch helper (direct REST, outside the bridge \u2014 see PLUGIN_SPEC.md)\n// ---------------------------------------------------------------------------\n\nfunction hostFetchJson<T>(path: string, init?: RequestInit): Promise<T> {\n return fetch(path, {\n credentials: \"include\",\n headers: {\n \"content-type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n ...init,\n }).then(async (response) => {\n if (!response.ok) {\n const text = await response.text();\n throw new Error(text || `Request failed: ${response.status}`);\n }\n return (await response.json()) as T;\n });\n}\n\n// ---------------------------------------------------------------------------\n// useSettingsConfig \u2014 load/save config via operator REST endpoint\n// ---------------------------------------------------------------------------\n\nfunction useSettingsConfig() {\n const [config, setConfig] = useState<ClawNetConfig>({ ...DEFAULT_CONFIG });\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n hostFetchJson<{ configJson?: Record<string, unknown> | null } | null>(\n `/api/plugins/${PLUGIN_ID}/config`,\n )\n .then((result) => {\n if (cancelled) return;\n const raw = result?.configJson ?? {};\n setConfig({\n clawnetApiUrl:\n typeof raw.clawnetApiUrl === \"string\"\n ? raw.clawnetApiUrl\n : DEFAULT_CONFIG.clawnetApiUrl,\n clawnetApiKey:\n typeof raw.clawnetApiKey === \"string\"\n ? raw.clawnetApiKey\n : DEFAULT_CONFIG.clawnetApiKey,\n syncIntervalMinutes:\n typeof raw.syncIntervalMinutes === \"number\" &&\n Number.isFinite(raw.syncIntervalMinutes)\n ? raw.syncIntervalMinutes\n : DEFAULT_CONFIG.syncIntervalMinutes,\n });\n setError(null);\n })\n .catch((nextError) => {\n if (cancelled) return;\n setError(\n nextError instanceof Error ? nextError.message : String(nextError),\n );\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n async function save(nextConfig: ClawNetConfig) {\n setSaving(true);\n try {\n await hostFetchJson(`/api/plugins/${PLUGIN_ID}/config`, {\n method: \"POST\",\n body: JSON.stringify({ configJson: nextConfig }),\n });\n setConfig(nextConfig);\n setError(null);\n } catch (nextError) {\n setError(\n nextError instanceof Error ? nextError.message : String(nextError),\n );\n throw nextError;\n } finally {\n setSaving(false);\n }\n }\n\n return { config, setConfig, loading, saving, error, save };\n}\n\n// ---------------------------------------------------------------------------\n// ClawNetSettingsPage\n// ---------------------------------------------------------------------------\n\nexport function ClawNetSettingsPage({ context }: PluginSettingsPageProps) {\n const { config, setConfig, loading, saving, error, save } =\n useSettingsConfig();\n const toast = usePluginToast();\n\n // Sync status from the worker via the bridge\n const syncStatus = usePluginData<SyncStatusData>(\"sync-status\", {\n companyId: context.companyId,\n });\n\n // Actions via the bridge\n const validateConfig = usePluginAction(\"validate-config\");\n const triggerSync = usePluginAction(\"trigger-sync\");\n\n // Local UI state\n const [testing, setTesting] = useState(false);\n const [syncing, setSyncing] = useState(false);\n\n function setField<K extends keyof ClawNetConfig>(\n key: K,\n value: ClawNetConfig[K],\n ) {\n setConfig((current) => ({ ...current, [key]: value }));\n }\n\n async function onSubmit(event: FormEvent) {\n event.preventDefault();\n try {\n await save(config);\n toast({ title: \"Settings saved\", tone: \"success\" });\n } catch {\n toast({\n title: \"Failed to save settings\",\n body: error ?? \"Unknown error\",\n tone: \"error\",\n });\n }\n }\n\n async function handleTestConnection() {\n setTesting(true);\n try {\n const result = (await validateConfig({\n clawnetApiUrl: config.clawnetApiUrl,\n clawnetApiKey: config.clawnetApiKey,\n })) as { ok: boolean; message?: string };\n if (result.ok) {\n toast({ title: \"Connection successful\", tone: \"success\" });\n } else {\n toast({\n title: \"Connection failed\",\n body: result.message ?? \"ClawNet API did not respond\",\n tone: \"error\",\n });\n }\n } catch (err) {\n toast({\n title: \"Connection test failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setTesting(false);\n }\n }\n\n async function handleManualSync() {\n setSyncing(true);\n try {\n await triggerSync({ companyId: context.companyId });\n toast({ title: \"Sync started\", tone: \"info\" });\n // Refresh sync status after a brief delay to let the worker start\n setTimeout(() => syncStatus.refresh(), 2000);\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n if (loading) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n Loading ClawNet configuration...\n </div>\n );\n }\n\n return (\n <div style={{ display: \"grid\", gap: \"18px\" }}>\n {/* Connection Settings */}\n <form onSubmit={onSubmit} style={layoutStack}>\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>ClawNet Connection</strong>\n </div>\n <div style={layoutStack}>\n <label style={labelStyle}>\n <span style={labelTextStyle}>ClawNet API URL</span>\n <input\n style={inputStyle}\n type=\"url\"\n value={config.clawnetApiUrl}\n onChange={(e) => setField(\"clawnetApiUrl\", e.target.value)}\n placeholder=\"https://clawnet.sh\"\n />\n <span style={helpTextStyle}>\n The base URL for the ClawNet registry API.\n </span>\n </label>\n\n <label style={labelStyle}>\n <span style={labelTextStyle}>ClawNet API Key (secret ref)</span>\n <input\n style={inputStyle}\n type=\"text\"\n value={config.clawnetApiKey}\n onChange={(e) => setField(\"clawnetApiKey\", e.target.value)}\n placeholder=\"e.g. clawnet-api-key\"\n />\n <span style={helpTextStyle}>\n This is a reference name for a Paperclip secret, not the API key\n itself. Create the secret in Paperclip Settings and enter its\n reference name here. The worker resolves the actual value at\n runtime via ctx.secrets.resolve().\n </span>\n </label>\n\n <label style={labelStyle}>\n <span style={labelTextStyle}>Sync Interval (minutes)</span>\n <input\n style={{ ...inputStyle, maxWidth: \"120px\" }}\n type=\"number\"\n min={1}\n max={1440}\n value={config.syncIntervalMinutes}\n onChange={(e) => {\n const val = Number.parseInt(e.target.value, 10);\n if (Number.isFinite(val) && val > 0) {\n setField(\"syncIntervalMinutes\", val);\n }\n }}\n />\n <span style={helpTextStyle}>\n How often to sync agents and skills from the ClawNet registry.\n Default: 15 minutes.\n </span>\n </label>\n </div>\n </section>\n\n {error ? (\n <div\n style={{\n color: \"var(--destructive, #c00)\",\n fontSize: \"12px\",\n }}\n >\n {error}\n </div>\n ) : null}\n\n <div style={rowStyle}>\n <button type=\"submit\" style={primaryButtonStyle} disabled={saving}>\n {saving ? \"Saving...\" : \"Save settings\"}\n </button>\n <button\n type=\"button\"\n style={buttonStyle}\n disabled={testing || !config.clawnetApiUrl}\n onClick={handleTestConnection}\n >\n {testing ? \"Testing...\" : \"Test connection\"}\n </button>\n </div>\n </form>\n\n {/* Sync Status */}\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>Sync Status</strong>\n <button\n type=\"button\"\n style={buttonStyle}\n disabled={syncing}\n onClick={handleManualSync}\n >\n {syncing ? \"Syncing...\" : \"Sync now\"}\n </button>\n </div>\n <SyncStatusDisplay\n data={syncStatus.data}\n loading={syncStatus.loading}\n error={syncStatus.error?.message ?? null}\n />\n </section>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// SyncStatusDisplay sub-component\n// ---------------------------------------------------------------------------\n\nfunction SyncStatusDisplay({\n data,\n loading,\n error,\n}: {\n data: SyncStatusData | null;\n loading: boolean;\n error: string | null;\n}) {\n if (loading) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n Loading sync status...\n </div>\n );\n }\n\n if (error) {\n return (\n <div style={{ fontSize: \"12px\", color: \"var(--destructive, #c00)\" }}>\n Failed to load sync status: {error}\n </div>\n );\n }\n\n if (!data) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n No sync data available. Run a sync to populate.\n </div>\n );\n }\n\n const statusColor =\n data.status === \"idle\"\n ? \"#16a34a\"\n : data.status === \"syncing\"\n ? \"#2563eb\"\n : \"#dc2626\";\n\n const statusLabel =\n data.status === \"idle\"\n ? \"Idle\"\n : data.status === \"syncing\"\n ? \"Syncing...\"\n : \"Error\";\n\n return (\n <div style={{ display: \"grid\", gap: \"10px\", fontSize: \"12px\" }}>\n <div style={rowStyle}>\n <span style={statusDotStyle(statusColor)} />\n <span>{statusLabel}</span>\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(140px, 1fr))\",\n gap: \"10px\",\n }}\n >\n <StatBlock label=\"Last sync\" value={formatTimestamp(data.lastSyncAt)} />\n <StatBlock label=\"Agents\" value={String(data.agentCount)} />\n <StatBlock label=\"Skills\" value={String(data.skillCount)} />\n </div>\n\n {data.error ? (\n <div style={{ color: \"var(--destructive, #c00)\" }}>\n Last error: {data.error}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// StatBlock sub-component\n// ---------------------------------------------------------------------------\n\nfunction StatBlock({ label, value }: { label: string; value: string }) {\n return (\n <div style={{ display: \"grid\", gap: \"2px\" }}>\n <span\n style={{\n fontSize: \"11px\",\n opacity: 0.65,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n }}\n >\n {label}\n </span>\n <span style={{ fontSize: \"13px\", fontWeight: 500 }}>{value}</span>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatTimestamp(iso: string | null): string {\n if (!iso) return \"Never\";\n try {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return \"Invalid date\";\n return date.toLocaleString();\n } catch {\n return iso;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { useEffect, 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 SyncStatus = {\n lastSyncAt: string | null;\n agentCount: number;\n skillCount: number;\n};\n\ntype ClawNetAgent = {\n id: string;\n slug: string;\n displayName: string;\n description: string | null;\n model: string | null;\n color: string | null;\n starCount: number;\n trustScore: number | null;\n attestations: string[];\n skills: string[];\n createdAt: string;\n};\n\ntype ClawNetSkill = {\n id: string;\n slug: string;\n displayName: string;\n description: string | null;\n category: string | null;\n starCount: number;\n};\n\ntype AgentListResponse = {\n agents: ClawNetAgent[];\n total: number;\n page: number;\n limit: number;\n};\n\ntype SkillListResponse = {\n skills: ClawNetSkill[];\n total: number;\n};\n\ntype FleetStatusEvent = {\n agentId: string;\n status: string;\n timestamp: string;\n};\n\ntype SyncProgressEvent = {\n phase: string;\n progress: number;\n message: string;\n};\n\n// ---------------------------------------------------------------------------\n// Shared inline styles (following kitchen sink pattern)\n// ---------------------------------------------------------------------------\n\nconst PAGE_ROUTE = \"clawnet\";\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 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 truncateText(text: string, maxLen: number): string {\n if (text.length <= maxLen) return text;\n return `${text.slice(0, maxLen - 1)}...`;\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\nfunction StatusDot({ status }: { status: string }) {\n const colorMap: Record<string, string> = {\n online: \"#16a34a\",\n idle: \"#d97706\",\n offline: \"#6b7280\",\n error: \"#dc2626\",\n running: \"#2563eb\",\n };\n const dotColor = colorMap[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 StarCount({ count }: { count: number }) {\n if (count <= 0) return null;\n return (\n <span style={{ display: \"inline-flex\", alignItems: \"center\", gap: \"3px\", fontSize: \"11px\", opacity: 0.7 }}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\">\n <path d=\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\" />\n </svg>\n {count}\n </span>\n );\n}\n\nfunction TrustBadge({ score }: { score: number | null }) {\n if (score === null || score === undefined) return null;\n const level =\n score >= 80 ? \"high\" : score >= 50 ? \"medium\" : \"low\";\n const colorMap = { high: \"#16a34a\", medium: \"#d97706\", low: \"#dc2626\" };\n const labelMap = { high: \"Trusted\", medium: \"Verified\", low: \"Unverified\" };\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: \"4px\",\n fontSize: \"10px\",\n fontWeight: 600,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: colorMap[level],\n }}\n >\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\" aria-hidden=\"true\">\n <path d=\"M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4z\" />\n </svg>\n {labelMap[level]}\n </span>\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// 1. DashboardWidget\n// ---------------------------------------------------------------------------\n\n/**\n * Compact fleet status widget for the main Paperclip dashboard.\n *\n * Shows agent count, skill count, online count, and last sync time.\n * Subscribes to fleet-status for live status updates.\n * Provides a manual \"Sync Now\" button with toast feedback.\n */\nexport function ClawNetFleetWidget({ context }: PluginWidgetProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n const syncParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: syncStatus, loading, error, refresh } = usePluginData<SyncStatus>(\n \"sync-status\",\n syncParams,\n );\n\n const fleetStream = // TODO(M4): import STREAM_CHANNELS from constants once UI bundle resolution is verified\n usePluginStream<FleetStatusEvent>(\"clawnet:fleet-status\", {\n companyId: companyId ?? undefined,\n });\n\n const triggerSync = usePluginAction(\"trigger-sync\");\n const [syncing, setSyncing] = useState(false);\n\n async function handleSync() {\n if (!companyId || syncing) return;\n setSyncing(true);\n try {\n await triggerSync({ companyId });\n refresh();\n toast({\n title: \"ClawNet sync started\",\n body: \"Agents and skills are being refreshed from the registry.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n // Derive live online count from the fleet stream event history\n const onlineCount = useMemo(() => {\n const latestByAgent = new Map<string, string>();\n for (const event of fleetStream.events) {\n latestByAgent.set(event.agentId, event.status);\n }\n let count = 0;\n for (const status of latestByAgent.values()) {\n if (status === \"online\" || status === \"running\") count++;\n }\n return count;\n }, [fleetStream.events]);\n\n if (loading) return <LoadingIndicator message=\"Loading fleet status...\" />;\n if (error) return <ErrorBanner message={error.message} />;\n\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <strong>ClawNet Fleet</strong>\n {fleetStream.connected ? (\n <StatusDot status=\"online\" />\n ) : null}\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr 1fr\",\n gap: \"8px\",\n }}\n >\n <div>\n <div style={statValueStyle}>{syncStatus?.agentCount ?? 0}</div>\n <div style={statLabelStyle}>Agents</div>\n </div>\n <div>\n <div style={statValueStyle}>{syncStatus?.skillCount ?? 0}</div>\n <div style={statLabelStyle}>Skills</div>\n </div>\n <div>\n <div style={statValueStyle}>{onlineCount}</div>\n <div style={statLabelStyle}>Online</div>\n </div>\n </div>\n\n <div style={{ ...mutedTextStyle, fontSize: \"11px\" }}>\n Last sync: {relativeTime(syncStatus?.lastSyncAt ?? null)}\n </div>\n\n <div style={rowStyle}>\n <a\n href={pluginPagePath(context.companyPrefix)}\n style={{ fontSize: \"12px\", color: \"inherit\" }}\n >\n Browse marketplace\n </a>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => void handleSync()}\n disabled={syncing}\n >\n {syncing ? \"Syncing...\" : \"Sync Now\"}\n </button>\n </div>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 2. MarketplacePage\n// ---------------------------------------------------------------------------\n\nconst AGENTS_PER_PAGE = 20;\n\ntype MarketplaceTab = \"agents\" | \"skills\";\ntype AgentDetailView = { agent: ClawNetAgent } | null;\n\nfunction TabBar({\n active,\n onChange,\n}: {\n active: MarketplaceTab;\n onChange: (tab: MarketplaceTab) => void;\n}) {\n const tabs: { key: MarketplaceTab; label: string }[] = [\n { key: \"agents\", label: \"Agents\" },\n { key: \"skills\", label: \"Skills\" },\n ];\n\n return (\n <div\n style={{\n display: \"flex\",\n gap: \"0\",\n borderBottom: \"1px solid var(--border)\",\n }}\n >\n {tabs.map((tab) => (\n <button\n key={tab.key}\n type=\"button\"\n onClick={() => onChange(tab.key)}\n style={{\n appearance: \"none\",\n background: \"transparent\",\n border: \"none\",\n borderBottom:\n active === tab.key\n ? \"2px solid var(--foreground)\"\n : \"2px solid transparent\",\n color: active === tab.key ? \"var(--foreground)\" : \"var(--muted-foreground, inherit)\",\n padding: \"10px 16px\",\n fontSize: \"13px\",\n fontWeight: active === tab.key ? 600 : 400,\n cursor: \"pointer\",\n transition: \"color 0.15s, border-color 0.15s\",\n }}\n >\n {tab.label}\n </button>\n ))}\n </div>\n );\n}\n\nfunction SearchBar({\n value,\n onChange,\n placeholder,\n}: {\n value: string;\n onChange: (v: string) => void;\n placeholder: string;\n}) {\n return (\n <div style={{ position: \"relative\" }}>\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n style={{\n position: \"absolute\",\n left: \"10px\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n opacity: 0.45,\n }}\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"M21 21l-4.35-4.35\" />\n </svg>\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n style={{\n ...inputStyle,\n paddingLeft: \"30px\",\n }}\n />\n </div>\n );\n}\n\nfunction AgentCard({\n agent,\n onSelect,\n onHire,\n}: {\n agent: ClawNetAgent;\n onSelect: () => void;\n onHire: () => void;\n}) {\n const colorIndicator = agent.color ?? \"var(--muted-foreground)\";\n\n return (\n <div\n style={{\n ...subtleCardStyle,\n display: \"grid\",\n gap: \"10px\",\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 {/* Header: color dot, name, slug, stars, trust */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"10px\",\n }}\n >\n <span\n style={{\n display: \"inline-block\",\n width: \"10px\",\n height: \"10px\",\n borderRadius: \"3px\",\n background: colorIndicator,\n flexShrink: 0,\n }}\n />\n <div style={{ minWidth: 0, flex: 1 }}>\n <div\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {agent.displayName}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.55 }}>\n {agent.slug}\n </div>\n </div>\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n flexShrink: 0,\n }}\n >\n <StarCount count={agent.starCount} />\n <TrustBadge score={agent.trustScore} />\n </div>\n </div>\n\n {/* Description */}\n {agent.description ? (\n <div style={mutedTextStyle}>\n {truncateText(agent.description, 120)}\n </div>\n ) : null}\n\n {/* Footer: pills + hire button */}\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n }}\n >\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"4px\" }}>\n {agent.model ? <Pill label={agent.model} /> : null}\n {agent.attestations.slice(0, 2).map((att) => (\n <Pill key={att} label={att} color=\"#2563eb\" />\n ))}\n {agent.skills.length > 0 ? (\n <Pill\n label={`${agent.skills.length} skill${agent.skills.length === 1 ? \"\" : \"s\"}`}\n />\n ) : null}\n </div>\n <button\n type=\"button\"\n style={primaryButtonStyle}\n onClick={(e) => {\n e.stopPropagation();\n onHire();\n }}\n >\n Hire Agent\n </button>\n </div>\n </div>\n );\n}\n\nfunction AgentDetail({\n agent,\n onBack,\n onHire,\n}: {\n agent: ClawNetAgent;\n onBack: () => void;\n onHire: () => void;\n}) {\n return (\n <div style={layoutStack}>\n <div style={rowStyle}>\n <button type=\"button\" style={buttonStyle} onClick={onBack}>\n Back\n </button>\n <strong style={{ fontSize: \"16px\" }}>{agent.displayName}</strong>\n <Pill label={agent.slug} />\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(180px, 1fr))\",\n gap: \"12px\",\n }}\n >\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Model</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.model ?? \"Not specified\"}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Stars</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {agent.starCount}\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Trust Score</div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\", marginTop: \"4px\" }}>\n <span style={{ fontSize: \"13px\" }}>\n {agent.trustScore !== null ? `${agent.trustScore}/100` : \"N/A\"}\n </span>\n <TrustBadge score={agent.trustScore} />\n </div>\n </div>\n <div style={subtleCardStyle}>\n <div style={eyebrowStyle}>Created</div>\n <div style={{ fontSize: \"13px\", marginTop: \"4px\" }}>\n {relativeTime(agent.createdAt)}\n </div>\n </div>\n </div>\n\n {agent.description ? (\n <Section title=\"Description\">\n <div style={{ fontSize: \"13px\", lineHeight: 1.55 }}>\n {agent.description}\n </div>\n </Section>\n ) : null}\n\n {agent.attestations.length > 0 ? (\n <Section title=\"Attestations\">\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"6px\" }}>\n {agent.attestations.map((att) => (\n <Pill key={att} label={att} color=\"#2563eb\" />\n ))}\n </div>\n </Section>\n ) : null}\n\n {agent.skills.length > 0 ? (\n <Section title=\"Skills\">\n <div style={{ display: \"flex\", flexWrap: \"wrap\", gap: \"6px\" }}>\n {agent.skills.map((skill) => (\n <Pill key={skill} label={skill} />\n ))}\n </div>\n </Section>\n ) : null}\n\n {agent.color ? (\n <Section title=\"Theme Color\">\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <span\n style={{\n display: \"inline-block\",\n width: \"20px\",\n height: \"20px\",\n borderRadius: \"4px\",\n background: agent.color,\n border: \"1px solid var(--border)\",\n }}\n />\n <span style={{ fontSize: \"12px\", fontFamily: \"monospace\" }}>\n {agent.color}\n </span>\n </div>\n </Section>\n ) : null}\n\n <div>\n <button type=\"button\" style={primaryButtonStyle} onClick={onHire}>\n Hire This Agent\n </button>\n </div>\n </div>\n );\n}\n\nfunction SkillCard({ skill }: { skill: ClawNetSkill }) {\n return (\n <div style={{ ...subtleCardStyle, display: \"grid\", gap: \"8px\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div\n style={{\n fontSize: \"13px\",\n fontWeight: 600,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {skill.displayName}\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.55 }}>{skill.slug}</div>\n </div>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\", flexShrink: 0 }}>\n {skill.category ? <Pill label={skill.category} /> : null}\n <StarCount count={skill.starCount} />\n </div>\n </div>\n {skill.description ? (\n <div style={mutedTextStyle}>\n {truncateText(skill.description, 140)}\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction SyncProgressBar({\n companyId,\n}: {\n companyId: string | null;\n}) {\n const syncProgress = // TODO(M4): import STREAM_CHANNELS from constants once UI bundle resolution is verified\n usePluginStream<SyncProgressEvent>(\"clawnet:sync-progress\", {\n companyId: companyId ?? undefined,\n });\n\n const latest = syncProgress.lastEvent;\n if (!latest || !syncProgress.connected) return null;\n\n const pct = Math.min(100, Math.max(0, latest.progress));\n\n return (\n <div style={{ ...subtleCardStyle, display: \"grid\", gap: \"6px\" }}>\n <div style={{ display: \"flex\", justifyContent: \"space-between\", alignItems: \"center\" }}>\n <span style={eyebrowStyle}>{latest.phase}</span>\n <span style={{ fontSize: \"11px\", opacity: 0.6 }}>{pct}%</span>\n </div>\n <div\n style={{\n height: \"4px\",\n borderRadius: \"2px\",\n background: \"color-mix(in srgb, var(--border) 50%, transparent)\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n height: \"100%\",\n width: `${pct}%`,\n borderRadius: \"2px\",\n background: \"var(--foreground)\",\n transition: \"width 0.3s ease\",\n }}\n />\n </div>\n <div style={{ fontSize: \"11px\", opacity: 0.6 }}>{latest.message}</div>\n </div>\n );\n}\n\n/**\n * Full marketplace page for browsing ClawNet agents and skills.\n *\n * - Tab bar to switch between Agents and Skills views\n * - Search bar with 300ms debounce\n * - Agent cards with color, model badge, star count, trust indicators\n * - Agent detail view on click\n * - \"Hire Agent\" button with toast guidance to Paperclip agent creation\n * - Skill cards with category and star count\n * - Pagination via \"Load more\" button\n * - Live sync progress bar during registry refresh\n */\nexport function ClawNetMarketplacePage({ context }: PluginPageProps) {\n const companyId = context.companyId;\n const toast = usePluginToast();\n\n // Tab state\n const [activeTab, setActiveTab] = useState<MarketplaceTab>(\"agents\");\n const [search, setSearch] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const [page, setPage] = useState(1);\n const [detailView, setDetailView] = useState<AgentDetailView>(null);\n\n // Debounce search input\n useEffect(() => {\n const timer = setTimeout(() => {\n setDebouncedSearch(search);\n setPage(1);\n }, 300);\n return () => clearTimeout(timer);\n }, [search]);\n\n // Agent data\n const agentParams = useMemo(\n () =>\n companyId\n ? {\n companyId,\n search: debouncedSearch || undefined,\n page,\n limit: AGENTS_PER_PAGE,\n }\n : {},\n [companyId, debouncedSearch, page],\n );\n const {\n data: agentData,\n loading: agentsLoading,\n error: agentsError,\n } = usePluginData<AgentListResponse>(\"clawnet-agents\", agentParams);\n\n // Skill data\n const skillParams = useMemo(\n () =>\n companyId\n ? { companyId, search: debouncedSearch || undefined }\n : {},\n [companyId, debouncedSearch],\n );\n const {\n data: skillData,\n loading: skillsLoading,\n error: skillsError,\n } = usePluginData<SkillListResponse>(\"clawnet-skills\", skillParams);\n\n // Sync status header\n const syncParams = useMemo(\n () => (companyId ? { companyId } : {}),\n [companyId],\n );\n const { data: syncStatus, refresh: refreshSync } = usePluginData<SyncStatus>(\n \"sync-status\",\n syncParams,\n );\n\n // Manual sync action\n const triggerSync = usePluginAction(\"trigger-sync\");\n const [syncing, setSyncing] = useState(false);\n\n async function handleSync() {\n if (!companyId || syncing) return;\n setSyncing(true);\n try {\n await triggerSync({ companyId });\n refreshSync();\n toast({\n title: \"Sync started\",\n body: \"Refreshing agent and skill data from ClawNet registry.\",\n tone: \"success\",\n });\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n function handleHireAgent(agent: ClawNetAgent) {\n toast({\n title: `Ready to hire: ${agent.displayName}`,\n body: \"Go to the Agents page and create a new agent. The template data from this ClawNet agent is ready to use.\",\n tone: \"info\",\n ttlMs: 8000,\n action: {\n label: \"Go to Agents\",\n href: hostPath(context.companyPrefix, \"/agents\"),\n },\n });\n }\n\n // Agent detail view\n if (detailView) {\n return (\n <div style={{ ...layoutStack, maxWidth: \"800px\" }}>\n <AgentDetail\n agent={detailView.agent}\n onBack={() => setDetailView(null)}\n onHire={() => handleHireAgent(detailView.agent)}\n />\n </div>\n );\n }\n\n // No company selected\n if (!companyId) {\n return (\n <div style={layoutStack}>\n <Section title=\"ClawNet Marketplace\">\n <EmptyState message=\"Select a company to browse the agent marketplace.\" />\n </Section>\n </div>\n );\n }\n\n const agents = agentData?.agents ?? [];\n const agentTotal = agentData?.total ?? 0;\n const hasMoreAgents = agents.length < agentTotal && page * AGENTS_PER_PAGE < agentTotal;\n\n const skills = skillData?.skills ?? [];\n const skillTotal = skillData?.total ?? 0;\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 ClawNet Marketplace\n </h1>\n <div style={mutedTextStyle}>\n {syncStatus\n ? `${syncStatus.agentCount} agents, ${syncStatus.skillCount} skills available. Last sync: ${relativeTime(syncStatus.lastSyncAt)}`\n : \"Loading registry status...\"}\n </div>\n </div>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => void handleSync()}\n disabled={syncing}\n >\n {syncing ? \"Syncing...\" : \"Refresh Registry\"}\n </button>\n </div>\n\n {/* Sync progress indicator */}\n <SyncProgressBar companyId={companyId} />\n\n {/* Search */}\n <SearchBar\n value={search}\n onChange={setSearch}\n placeholder={\n activeTab === \"agents\"\n ? \"Search agents by name, skill, or model...\"\n : \"Search skills by name or category...\"\n }\n />\n\n {/* Tab bar */}\n <TabBar\n active={activeTab}\n onChange={(tab) => {\n setActiveTab(tab);\n setSearch(\"\");\n setPage(1);\n }}\n />\n\n {/* Agents tab content */}\n {activeTab === \"agents\" ? (\n <div style={layoutStack}>\n {agentsLoading && agents.length === 0 ? (\n <LoadingIndicator message=\"Loading agents from registry...\" />\n ) : agentsError ? (\n <ErrorBanner message={agentsError.message} />\n ) : agents.length === 0 ? (\n <EmptyState\n message={\n debouncedSearch\n ? `No agents found matching \"${debouncedSearch}\".`\n : \"No agents available. Try syncing the registry.\"\n }\n />\n ) : (\n <>\n <div style={{ fontSize: \"12px\", opacity: 0.6 }}>\n Showing {agents.length} of {agentTotal} agent{agentTotal === 1 ? \"\" : \"s\"}\n {debouncedSearch ? ` matching \"${debouncedSearch}\"` : \"\"}\n </div>\n <div style={{ display: \"grid\", gap: \"10px\" }}>\n {agents.map((agent) => (\n <AgentCard\n key={agent.id}\n agent={agent}\n onSelect={() => setDetailView({ agent })}\n onHire={() => handleHireAgent(agent)}\n />\n ))}\n </div>\n {hasMoreAgents ? (\n <div style={{ display: \"flex\", justifyContent: \"center\", paddingTop: \"8px\" }}>\n <button\n type=\"button\"\n style={buttonStyle}\n onClick={() => setPage((p) => p + 1)}\n disabled={agentsLoading}\n >\n {agentsLoading ? \"Loading...\" : `Load more (${agentTotal - agents.length} remaining)`}\n </button>\n </div>\n ) : null}\n </>\n )}\n </div>\n ) : null}\n\n {/* Skills tab content */}\n {activeTab === \"skills\" ? (\n <div style={layoutStack}>\n {skillsLoading ? (\n <LoadingIndicator message=\"Loading skills...\" />\n ) : skillsError ? (\n <ErrorBanner message={skillsError.message} />\n ) : skills.length === 0 ? (\n <EmptyState\n message={\n debouncedSearch\n ? `No skills found matching \"${debouncedSearch}\".`\n : \"No skills available. Try syncing the registry.\"\n }\n />\n ) : (\n <>\n <div style={{ fontSize: \"12px\", opacity: 0.6 }}>\n {skillTotal} skill{skillTotal === 1 ? \"\" : \"s\"} available\n {debouncedSearch ? ` matching \"${debouncedSearch}\"` : \"\"}\n </div>\n <div style={{ display: \"grid\", gap: \"10px\" }}>\n {skills.map((skill) => (\n <SkillCard key={skill.id} skill={skill} />\n ))}\n </div>\n </>\n )}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// 3. SidebarEntry\n// ---------------------------------------------------------------------------\n\n/**\n * Sidebar navigation link to the ClawNet marketplace page.\n * Shows a network icon and an agent count badge from sync status.\n */\nexport function ClawNetSidebarLink({ context }: PluginSidebarProps) {\n const syncParams = useMemo(\n () => (context.companyId ? { companyId: context.companyId } : {}),\n [context.companyId],\n );\n const { data: syncStatus } = usePluginData<SyncStatus>(\"sync-status\", syncParams);\n\n const href = pluginPagePath(context.companyPrefix);\n const isActive =\n typeof window !== \"undefined\" && window.location.pathname === href;\n\n const agentCount = syncStatus?.agentCount ?? 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 ? \"var(--foreground)\" : \"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 {/* Network/nodes icon */}\n <svg\n width=\"16\"\n height=\"16\"\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 <circle cx=\"12\" cy=\"5\" r=\"2.5\" />\n <circle cx=\"5\" cy=\"19\" r=\"2.5\" />\n <circle cx=\"19\" cy=\"19\" r=\"2.5\" />\n <path d=\"M12 7.5v4\" />\n <path d=\"M7.5 17.5l3-6\" />\n <path d=\"M16.5 17.5l-3-6\" />\n </svg>\n\n <span style={{ flex: 1 }}>ClawNet</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: \"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\n// ---------------------------------------------------------------------------\n// 4. Settings page (re-export from separate module)\n// ---------------------------------------------------------------------------\n\nexport { ClawNetSettingsPage } from \"./settings.js\";\n", "import { useState, useEffect, type CSSProperties, type FormEvent } from \"react\";\nimport {\n usePluginData,\n usePluginAction,\n usePluginToast,\n type PluginSettingsPageProps,\n} from \"@paperclipai/plugin-sdk/ui\";\n\n// ---------------------------------------------------------------------------\n// Plugin identity \u2014 must match manifest.id\n// ---------------------------------------------------------------------------\n\nconst PLUGIN_ID = \"bopen-io.clawnet-plugin\";\n\n// ---------------------------------------------------------------------------\n// Config types\n// ---------------------------------------------------------------------------\n\ntype ClawNetConfig = {\n clawnetApiUrl: string;\n clawnetApiKey: string;\n syncIntervalMinutes: number;\n};\n\ntype SyncStatusData = {\n lastSyncAt: string | null;\n agentCount: number;\n skillCount: number;\n status: \"idle\" | \"syncing\" | \"error\";\n error: string | null;\n};\n\nconst DEFAULT_CONFIG: ClawNetConfig = {\n clawnetApiUrl: \"https://clawnet.sh\",\n clawnetApiKey: \"\",\n syncIntervalMinutes: 15,\n};\n\n// ---------------------------------------------------------------------------\n// Styles (host CSS variable tokens, matching kitchen sink patterns)\n// ---------------------------------------------------------------------------\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 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 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 boxSizing: \"border-box\",\n};\n\nconst labelStyle: CSSProperties = {\n display: \"grid\",\n gap: \"6px\",\n};\n\nconst labelTextStyle: CSSProperties = {\n fontSize: \"12px\",\n fontWeight: 500,\n};\n\nconst helpTextStyle: CSSProperties = {\n fontSize: \"11px\",\n opacity: 0.65,\n lineHeight: 1.45,\n};\n\nconst sectionHeaderStyle: CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n marginBottom: \"10px\",\n};\n\nconst statusDotStyle = (color: string): CSSProperties => ({\n display: \"inline-block\",\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: color,\n flexShrink: 0,\n});\n\n// ---------------------------------------------------------------------------\n// Config fetch helper (direct REST, outside the bridge \u2014 see PLUGIN_SPEC.md)\n// ---------------------------------------------------------------------------\n\nfunction hostFetchJson<T>(path: string, init?: RequestInit): Promise<T> {\n return fetch(path, {\n credentials: \"include\",\n headers: {\n \"content-type\": \"application/json\",\n ...(init?.headers ?? {}),\n },\n ...init,\n }).then(async (response) => {\n if (!response.ok) {\n const text = await response.text();\n throw new Error(text || `Request failed: ${response.status}`);\n }\n return (await response.json()) as T;\n });\n}\n\n// ---------------------------------------------------------------------------\n// useSettingsConfig \u2014 load/save config via operator REST endpoint\n// ---------------------------------------------------------------------------\n\nfunction useSettingsConfig() {\n const [config, setConfig] = useState<ClawNetConfig>({ ...DEFAULT_CONFIG });\n const [loading, setLoading] = useState(true);\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n hostFetchJson<{ configJson?: Record<string, unknown> | null } | null>(\n `/api/plugins/${PLUGIN_ID}/config`,\n )\n .then((result) => {\n if (cancelled) return;\n const raw = result?.configJson ?? {};\n setConfig({\n clawnetApiUrl:\n typeof raw.clawnetApiUrl === \"string\"\n ? raw.clawnetApiUrl\n : DEFAULT_CONFIG.clawnetApiUrl,\n clawnetApiKey:\n typeof raw.clawnetApiKey === \"string\"\n ? raw.clawnetApiKey\n : DEFAULT_CONFIG.clawnetApiKey,\n syncIntervalMinutes:\n typeof raw.syncIntervalMinutes === \"number\" &&\n Number.isFinite(raw.syncIntervalMinutes)\n ? raw.syncIntervalMinutes\n : DEFAULT_CONFIG.syncIntervalMinutes,\n });\n setError(null);\n })\n .catch((nextError) => {\n if (cancelled) return;\n setError(\n nextError instanceof Error ? nextError.message : String(nextError),\n );\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n return () => {\n cancelled = true;\n };\n }, []);\n\n async function save(nextConfig: ClawNetConfig) {\n setSaving(true);\n try {\n await hostFetchJson(`/api/plugins/${PLUGIN_ID}/config`, {\n method: \"POST\",\n body: JSON.stringify({ configJson: nextConfig }),\n });\n setConfig(nextConfig);\n setError(null);\n } catch (nextError) {\n setError(\n nextError instanceof Error ? nextError.message : String(nextError),\n );\n throw nextError;\n } finally {\n setSaving(false);\n }\n }\n\n return { config, setConfig, loading, saving, error, save };\n}\n\n// ---------------------------------------------------------------------------\n// ClawNetSettingsPage\n// ---------------------------------------------------------------------------\n\nexport function ClawNetSettingsPage({ context }: PluginSettingsPageProps) {\n const { config, setConfig, loading, saving, error, save } =\n useSettingsConfig();\n const toast = usePluginToast();\n\n // Sync status from the worker via the bridge\n const syncStatus = usePluginData<SyncStatusData>(\"sync-status\", {\n companyId: context.companyId,\n });\n\n // Actions via the bridge\n const validateConfig = usePluginAction(\"validate-config\");\n const triggerSync = usePluginAction(\"trigger-sync\");\n\n // Local UI state\n const [testing, setTesting] = useState(false);\n const [syncing, setSyncing] = useState(false);\n\n function setField<K extends keyof ClawNetConfig>(\n key: K,\n value: ClawNetConfig[K],\n ) {\n setConfig((current) => ({ ...current, [key]: value }));\n }\n\n async function onSubmit(event: FormEvent) {\n event.preventDefault();\n try {\n await save(config);\n toast({ title: \"Settings saved\", tone: \"success\" });\n } catch {\n toast({\n title: \"Failed to save settings\",\n body: error ?? \"Unknown error\",\n tone: \"error\",\n });\n }\n }\n\n async function handleTestConnection() {\n setTesting(true);\n try {\n const result = (await validateConfig({\n clawnetApiUrl: config.clawnetApiUrl,\n clawnetApiKey: config.clawnetApiKey,\n })) as { ok: boolean; message?: string };\n if (result.ok) {\n toast({ title: \"Connection successful\", tone: \"success\" });\n } else {\n toast({\n title: \"Connection failed\",\n body: result.message ?? \"ClawNet API did not respond\",\n tone: \"error\",\n });\n }\n } catch (err) {\n toast({\n title: \"Connection test failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setTesting(false);\n }\n }\n\n async function handleManualSync() {\n setSyncing(true);\n try {\n await triggerSync({ companyId: context.companyId });\n toast({ title: \"Sync started\", tone: \"info\" });\n // Refresh sync status after a brief delay to let the worker start\n setTimeout(() => syncStatus.refresh(), 2000);\n } catch (err) {\n toast({\n title: \"Sync failed\",\n body: err instanceof Error ? err.message : String(err),\n tone: \"error\",\n });\n } finally {\n setSyncing(false);\n }\n }\n\n if (loading) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n Loading ClawNet configuration...\n </div>\n );\n }\n\n return (\n <div style={{ display: \"grid\", gap: \"18px\" }}>\n {/* Connection Settings */}\n <form onSubmit={onSubmit} style={layoutStack}>\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>ClawNet Connection</strong>\n </div>\n <div style={layoutStack}>\n <label style={labelStyle}>\n <span style={labelTextStyle}>ClawNet API URL</span>\n <input\n style={inputStyle}\n type=\"url\"\n value={config.clawnetApiUrl}\n onChange={(e) => setField(\"clawnetApiUrl\", e.target.value)}\n placeholder=\"https://clawnet.sh\"\n />\n <span style={helpTextStyle}>\n The base URL for the ClawNet registry API.\n </span>\n </label>\n\n <label style={labelStyle}>\n <span style={labelTextStyle}>ClawNet API Key (secret ref)</span>\n <input\n style={inputStyle}\n type=\"text\"\n value={config.clawnetApiKey}\n onChange={(e) => setField(\"clawnetApiKey\", e.target.value)}\n placeholder=\"e.g. clawnet-api-key\"\n />\n <span style={helpTextStyle}>\n This is a reference name for a Paperclip secret, not the API key\n itself. Create the secret in Paperclip Settings and enter its\n reference name here. The worker resolves the actual value at\n runtime via ctx.secrets.resolve().\n </span>\n </label>\n\n <label style={labelStyle}>\n <span style={labelTextStyle}>Sync Interval (minutes)</span>\n <input\n style={{ ...inputStyle, maxWidth: \"120px\" }}\n type=\"number\"\n min={1}\n max={1440}\n value={config.syncIntervalMinutes}\n onChange={(e) => {\n const val = Number.parseInt(e.target.value, 10);\n if (Number.isFinite(val) && val > 0) {\n setField(\"syncIntervalMinutes\", val);\n }\n }}\n />\n <span style={helpTextStyle}>\n How often to sync agents and skills from the ClawNet registry.\n Default: 15 minutes.\n </span>\n </label>\n </div>\n </section>\n\n {error ? (\n <div\n style={{\n color: \"var(--destructive, #c00)\",\n fontSize: \"12px\",\n }}\n >\n {error}\n </div>\n ) : null}\n\n <div style={rowStyle}>\n <button type=\"submit\" style={primaryButtonStyle} disabled={saving}>\n {saving ? \"Saving...\" : \"Save settings\"}\n </button>\n <button\n type=\"button\"\n style={buttonStyle}\n disabled={testing || !config.clawnetApiUrl}\n onClick={handleTestConnection}\n >\n {testing ? \"Testing...\" : \"Test connection\"}\n </button>\n </div>\n </form>\n\n {/* Sync Status */}\n <section style={cardStyle}>\n <div style={sectionHeaderStyle}>\n <strong>Sync Status</strong>\n <button\n type=\"button\"\n style={buttonStyle}\n disabled={syncing}\n onClick={handleManualSync}\n >\n {syncing ? \"Syncing...\" : \"Sync now\"}\n </button>\n </div>\n <SyncStatusDisplay\n data={syncStatus.data}\n loading={syncStatus.loading}\n error={syncStatus.error?.message ?? null}\n />\n </section>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// SyncStatusDisplay sub-component\n// ---------------------------------------------------------------------------\n\nfunction SyncStatusDisplay({\n data,\n loading,\n error,\n}: {\n data: SyncStatusData | null;\n loading: boolean;\n error: string | null;\n}) {\n if (loading) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n Loading sync status...\n </div>\n );\n }\n\n if (error) {\n return (\n <div style={{ fontSize: \"12px\", color: \"var(--destructive, #c00)\" }}>\n Failed to load sync status: {error}\n </div>\n );\n }\n\n if (!data) {\n return (\n <div style={{ fontSize: \"12px\", opacity: 0.7 }}>\n No sync data available. Run a sync to populate.\n </div>\n );\n }\n\n const statusColor =\n data.status === \"idle\"\n ? \"#16a34a\"\n : data.status === \"syncing\"\n ? \"#2563eb\"\n : \"#dc2626\";\n\n const statusLabel =\n data.status === \"idle\"\n ? \"Idle\"\n : data.status === \"syncing\"\n ? \"Syncing...\"\n : \"Error\";\n\n return (\n <div style={{ display: \"grid\", gap: \"10px\", fontSize: \"12px\" }}>\n <div style={rowStyle}>\n <span style={statusDotStyle(statusColor)} />\n <span>{statusLabel}</span>\n </div>\n\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"repeat(auto-fit, minmax(140px, 1fr))\",\n gap: \"10px\",\n }}\n >\n <StatBlock label=\"Last sync\" value={formatTimestamp(data.lastSyncAt)} />\n <StatBlock label=\"Agents\" value={String(data.agentCount)} />\n <StatBlock label=\"Skills\" value={String(data.skillCount)} />\n </div>\n\n {data.error ? (\n <div style={{ color: \"var(--destructive, #c00)\" }}>\n Last error: {data.error}\n </div>\n ) : null}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// StatBlock sub-component\n// ---------------------------------------------------------------------------\n\nfunction StatBlock({ label, value }: { label: string; value: string }) {\n return (\n <div style={{ display: \"grid\", gap: \"2px\" }}>\n <span\n style={{\n fontSize: \"11px\",\n opacity: 0.65,\n textTransform: \"uppercase\",\n letterSpacing: \"0.06em\",\n }}\n >\n {label}\n </span>\n <span style={{ fontSize: \"13px\", fontWeight: 500 }}>{value}</span>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatTimestamp(iso: string | null): string {\n if (!iso) return \"Never\";\n try {\n const date = new Date(iso);\n if (Number.isNaN(date.getTime())) return \"Invalid date\";\n return date.toLocaleString();\n } catch {\n return iso;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["useEffect", "useState", "usePluginAction", "usePluginData", "usePluginToast", "jsx", "jsxs", "layoutStack", "cardStyle", "rowStyle", "buttonStyle", "primaryButtonStyle", "inputStyle", "sectionHeaderStyle", "usePluginToast", "usePluginData", "usePluginAction", "useState", "useEffect"]
7
7
  }