@usechain/chain-hub 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +209 -2
- package/dist/index.d.ts +9 -0
- package/dist/index.js +32318 -0
- package/dist/web/apple-touch-icon.png +0 -0
- package/dist/web/assets/CatalogPage-DH4aZzR2.js +1 -0
- package/dist/web/assets/CatalogPage-M8VZyfIe.js +1 -0
- package/dist/web/assets/HealthPage-C2uKV9FU.js +1 -0
- package/dist/web/assets/HealthPage-DUbZiwpY.js +1 -0
- package/dist/web/assets/IntegrationsPage-BziKwfEq.js +1 -0
- package/dist/web/assets/IntegrationsPage-rJcPXOty.js +1 -0
- package/dist/web/assets/LearningsPage-DBJ9M7V5.js +2 -0
- package/dist/web/assets/LearningsPage-Da6i4TeB.js +2 -0
- package/dist/web/assets/LibraryPage-BP6IKKuN.js +4 -0
- package/dist/web/assets/LibraryPage-C9uf78JX.js +4 -0
- package/dist/web/assets/MarkdownSourceEditor-CV1ZTZzI.js +39 -0
- package/dist/web/assets/MarkdownSourceEditor-Xh-yr_Pu.js +39 -0
- package/dist/web/assets/OverviewPage-DeApcxoJ.js +1 -0
- package/dist/web/assets/OverviewPage-DhNIr7N8.js +1 -0
- package/dist/web/assets/SettingsPage-BCoxInUI.js +1 -0
- package/dist/web/assets/SettingsPage-BmRmIO3z.js +1 -0
- package/dist/web/assets/SetupPage-BUmmsWEo.js +1 -0
- package/dist/web/assets/SetupPage-CmXMvqM5.js +1 -0
- package/dist/web/assets/SkillRelinkDialog-C5PU7vKu.js +1 -0
- package/dist/web/assets/SkillRelinkDialog-DEY3IqVA.js +1 -0
- package/dist/web/assets/alert-Mr-ofzoN.js +1 -0
- package/dist/web/assets/alert-YumgHBdn.js +1 -0
- package/dist/web/assets/badge-C2BSIZMN.js +1 -0
- package/dist/web/assets/badge-CcASMiB4.js +1 -0
- package/dist/web/assets/format-time-D8VGlAcs.js +1 -0
- package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/web/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/web/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/web/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/web/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/web/assets/index-D3L-4LuU.css +1 -0
- package/dist/web/assets/index-ltESF1KS.js +172 -0
- package/dist/web/assets/index-mFc_WQtU.css +1 -0
- package/dist/web/assets/index-ommOzjM4.js +172 -0
- package/dist/web/assets/libesm-CHGPMFhL.js +6 -0
- package/dist/web/assets/select-DJSrFTH0.js +1 -0
- package/dist/web/assets/tabs-B9fkoXIl.js +1 -0
- package/dist/web/assets/utils-BEATUXr4.js +1 -0
- package/dist/web/assets/vendor-react-BgntYnUn.js +12 -0
- package/dist/web/assets/vendor-ui-qVCZmmA-.js +41 -0
- package/dist/web/favicon-32.png +0 -0
- package/dist/web/favicon.svg +2 -0
- package/dist/web/icon-192.png +0 -0
- package/dist/web/icon-512.png +0 -0
- package/dist/web/icon-maskable-512.png +0 -0
- package/dist/web/index.html +37 -0
- package/dist/web/logo.svg +2 -0
- package/dist/web/site.webmanifest +25 -0
- package/package.json +42 -4
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,U as r,V as i,W as a,Z as o,q as s,z as c}from"./vendor-react-BgntYnUn.js";import{J as l,Q as u,S as d,V as f,ft as p,h as m,q as h,v as g,w as _,y as v}from"./vendor-ui-qVCZmmA-.js";import{A as y,C as b,J as x,Q as S,Z as C,a as w,ct as T,dt as E,gt as D,h as O,i as k,lt as ee,n as A,o as te,pt as j,r as M,st as N,t as ne,ut as P,v as F}from"./index-ltESF1KS.js";import{n as re,r as I,t as ie}from"./alert-Mr-ofzoN.js";import{t as L}from"./badge-CcASMiB4.js";import{t as R}from"./select-DJSrFTH0.js";import{n as z,r as B,t as V}from"./tabs-B9fkoXIl.js";var H=e(o(),1),U={"code-quality":`Code quality`,design:`Design`,docs:`Docs`,testing:`Testing`,devops:`DevOps`,research:`Research`,writing:`Writing`,productivity:`Productivity`,"editor-integration":`Editor integration`,other:`Other`};function ae(e){return S.includes(e??``)?e:`__all__`}function oe(e){return C.includes(e??``)?e:`__all__`}function W(e){return`${e.id}@${e.sourceId}`}function se(e,t){let n=t.query.trim().toLowerCase();return e.filter(e=>t.kind!==`__all__`&&e.kind!==t.kind||t.category!==`__all__`&&e.category!==t.category||t.tag!==`__all__`&&!e.tags.includes(t.tag)?!1:!n||[e.id,e.name,e.description,e.author??``,...e.tags].some(e=>e.toLowerCase().includes(n)))}function ce(e){let t=new Map;for(let n of e)t.set(n.kind,[...t.get(n.kind)??[],n]);let n=S,r=e=>n.includes(e)?n.indexOf(e):n.length;return Array.from(t.entries()).sort(([e],[t])=>r(e)-r(t))}function G(e){let t=e.trim().match(/^(?:https?:\/\/(?:www\.)?github\.com\/|git@github\.com:)([^/\s]+)\/([^/\s#?]+?)(?:\.git)?\/?$/i);return!t?.[1]||!t[2]?null:`${t[1]}/${t[2]}`}function K(e){let t=G(e.repo);if(t){let n=`https://github.com/${t}`;return e.subdir?`${n}/tree/${e.ref??`HEAD`}/${e.subdir.replace(/^\/+/,``)}`:n}return/^https?:\/\//i.test(e.repo)?e.repo:null}async function q(e){try{let t=await fetch(`https://api.github.com/repos/${e}`,{headers:{Accept:`application/vnd.github+json`}});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==`number`?n.stargazers_count:null}catch{return null}}function J(e){if(e<1e3)return String(e);let t=e/1e3;return`${t>=10?Math.round(t):t.toFixed(1).replace(/\.0$/,``)}k`}function le(e){return!e||e.length===0?null:e.map(e=>`${e.sourceId}: ${e.error}`).join(` · `)}var Y=[`relevance`,`stars`,`newest`,`active`],X={relevance:`Relevance`,stars:`Most starred`,newest:`Recently added`,active:`Recently updated`};function ue(e){return Y.includes(e??``)?e:`relevance`}function de(e){return e&&e.trim()?e.trim():`__all__`}function fe(e){let t=new Set;for(let n of e)for(let e of n.tags)t.add(e);return Array.from(t).sort((e,t)=>e.localeCompare(t))}function pe(e,t,n){if(t===`relevance`)return e;let r=e=>{switch(t){case`stars`:{let t=G(e.source.repo);return(t===null?void 0:n.get(t))??e.stats?.stars??null}case`newest`:return e.addedAt?Date.parse(e.addedAt):null;case`active`:return e.stats?.pushedAt?Date.parse(e.stats.pushedAt):null}};return[...e].sort((e,t)=>(r(t)??-1)-(r(e)??-1))}var Z=36e5;function me(e){let t=G(e);return a({queryKey:O.githubStars(t??``),queryFn:()=>q(t??``),enabled:t!==null,staleTime:Z,gcTime:24*Z,retry:!1,refetchOnWindowFocus:!1}).data??null}function he(e){let t=(0,H.useMemo)(()=>Array.from(new Set(e.map(G).filter(e=>e!==null))).sort(),[e]);return a({queryKey:O.githubStars(`map:${t.join(`,`)}`),queryFn:async()=>{let e=new Map;return await Promise.all(t.map(async t=>{let n=await q(t);n!==null&&e.set(t,n)})),e},enabled:t.length>0,staleTime:Z,gcTime:24*Z,retry:!1,refetchOnWindowFocus:!1}).data??new Map}var Q=n();function ge({entry:e,updateAvailable:n,isInstalling:i,onBack:a,onInstall:o,onOpenInLibrary:c}){let u=x(e.kind),d=me(e.source.repo),_=K(e.source),y=e.source.subdir?`${e.source.repo}/${e.source.subdir}`:e.source.repo,b=s(),S=r({mutationFn:()=>F.scan({sourceId:e.sourceId,entryId:e.id}),onSuccess:e=>{b.invalidateQueries({queryKey:O.catalog});let t=e.scan.findings.length;D.success(`Security scan: ${e.scan.verdict}${t?` (${t} finding${t===1?``:`s`})`:``}`)},onError:e=>D.error(e.message)}),C=e.securityScan?.verdict??null;return(0,Q.jsxs)(A,{"aria-label":`${e.name} details`,className:t(`fixed inset-0 z-40 flex min-w-0 flex-col overflow-hidden rounded-none border-0 bg-card`,`xl:static xl:z-auto xl:rounded-xl xl:border xl:border-border xl:bg-card`),role:`region`,children:[(0,Q.jsxs)(k,{children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-start gap-3`,children:[(0,Q.jsxs)(j,{className:`xl:hidden`,onClick:a,size:`icon-sm`,type:`button`,variant:`ghost`,children:[(0,Q.jsx)(p,{className:`size-4`}),(0,Q.jsx)(`span`,{className:`sr-only`,children:`Back to catalog`})]}),(0,Q.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1`,children:[(0,Q.jsx)(w,{className:`truncate`,children:e.name}),(0,Q.jsxs)(`p`,{className:`truncate font-mono text-xs text-muted-foreground`,children:[e.kind,`/`,e.id]}),e.author?(0,Q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`by `,e.author]}):null]})]}),(0,Q.jsx)(L,{variant:`accent`,children:u.label})]}),(0,Q.jsxs)(M,{className:`grid flex-1 content-start gap-5 overflow-y-auto`,children:[(0,Q.jsx)(`p`,{className:`max-w-prose text-sm leading-6 text-foreground`,children:e.description}),e.hasScripts?(0,Q.jsxs)(ie,{variant:`warning`,children:[(0,Q.jsx)(I,{children:(0,Q.jsx)(v,{})}),(0,Q.jsxs)(re,{children:[`This `,u.label.toLowerCase(),` bundles executable scripts. Review them in the source before using it; Chain Hub never runs scripts on install.`]})]}):null,(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[C===`pass`?(0,Q.jsxs)(L,{variant:`success`,children:[(0,Q.jsx)(g,{"aria-hidden":`true`,className:`size-3`}),` Security: pass`]}):C===`warn`?(0,Q.jsxs)(L,{variant:`warning`,children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: warn`]}):C===`fail`?(0,Q.jsxs)(L,{variant:`destructive`,children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: fail`]}):(0,Q.jsxs)(L,{children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: not scanned`]}),C===`pass`?null:(0,Q.jsx)(j,{loading:S.isPending,onClick:()=>S.mutate(),size:`sm`,type:`button`,variant:`outline`,children:`Scan source`})]}),C===`fail`?(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`The scan found high-severity issues — installing this entry is blocked unless you explicitly override.`}):null,(0,Q.jsxs)(`dl`,{className:`grid gap-3 text-sm sm:grid-cols-[auto_minmax(0,1fr)] sm:gap-x-6`,children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Source`}),(0,Q.jsx)(`dd`,{className:`min-w-0`,children:_?(0,Q.jsxs)(`a`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-sm font-mono text-xs text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`,href:_,rel:`noreferrer`,target:`_blank`,children:[(0,Q.jsx)(`span`,{className:`truncate`,children:y}),(0,Q.jsx)(h,{"aria-hidden":`true`,className:`size-3 shrink-0`})]}):(0,Q.jsx)(`span`,{className:`break-all font-mono text-xs text-foreground`,children:y})}),e.source.ref?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Ref`}),(0,Q.jsx)(`dd`,{className:`font-mono text-xs text-foreground`,children:e.source.ref})]}):null,(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`License`}),(0,Q.jsx)(`dd`,{className:`text-foreground`,children:e.license??`Not specified`}),(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Category`}),(0,Q.jsx)(`dd`,{className:`text-foreground`,children:U[e.category]}),d===null?null:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Stars`}),(0,Q.jsxs)(`dd`,{className:`inline-flex items-center gap-1 tabular-nums text-foreground`,children:[(0,Q.jsx)(m,{"aria-hidden":`true`,className:`size-3.5 text-muted-foreground`}),J(d)]})]}),(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Catalog`}),(0,Q.jsx)(`dd`,{className:`font-mono text-xs text-foreground`,children:e.sourceId})]}),e.tags.length>0?(0,Q.jsxs)(`div`,{className:`grid gap-2`,children:[(0,Q.jsx)(`p`,{className:`text-xs font-medium text-muted-foreground`,children:`Tags`}),(0,Q.jsx)(`ul`,{"aria-label":`Tags`,className:`flex flex-wrap gap-1.5`,children:e.tags.map(e=>(0,Q.jsx)(`li`,{children:(0,Q.jsx)(L,{children:e})},e))})]}):null]}),(0,Q.jsx)(`div`,{className:`flex flex-wrap items-center gap-3 border-t border-border px-4 py-3`,children:e.installed?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(L,{variant:`success`,children:`Installed`}),n?(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`An upstream update is available; update it from Library.`}):null,(0,Q.jsxs)(j,{className:`ml-auto`,onClick:c,size:`sm`,type:`button`,variant:`outline`,children:[(0,Q.jsx)(f,{className:`size-4`}),`Open in Library`]})]}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Installs into your hub from the upstream source and records its provenance.`}),(0,Q.jsxs)(j,{className:`ml-auto`,loading:i,onClick:o,size:`sm`,type:`button`,children:[(0,Q.jsx)(l,{className:`size-4`}),`Install`]})]})})]})}function _e({entry:e,selected:n,compact:r=!1,updateAvailable:i=!1,onSelect:a}){let o=x(e.kind),s=o.icon,c=me(e.source.repo);return(0,Q.jsx)(`button`,{"aria-pressed":n,className:t(`group relative grid w-full min-w-0 rounded-xl border border-border bg-card text-left shadow-card transition-colors`,`hover:bg-accent/60`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background`,n&&`border-foreground/20 bg-accent`,r?`gap-2 p-3`:`gap-3 p-4`),onClick:a,type:`button`,children:(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[(0,Q.jsx)(s,{"aria-hidden":`true`,className:t(`mt-0.5 size-4 shrink-0 transition-colors`,n?`text-foreground`:`text-muted-foreground`)}),(0,Q.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1 overflow-hidden`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-foreground`,children:e.name}),(0,Q.jsx)(L,{variant:`accent`,children:o.label}),e.installed?(0,Q.jsx)(L,{variant:`success`,children:`Installed`}):null,i?(0,Q.jsx)(L,{variant:`accent`,children:`Update available`}):null]}),(0,Q.jsx)(`p`,{className:t(`text-xs text-muted-foreground`,r?`truncate`:`line-clamp-2`),children:e.description}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground`,children:[(0,Q.jsx)(`span`,{children:U[e.category]}),e.author?(0,Q.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`by `,e.author]}):null,c===null?null:(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1 tabular-nums`,children:[(0,Q.jsx)(m,{"aria-hidden":`true`,className:`size-3`}),J(c),(0,Q.jsx)(`span`,{className:`sr-only`,children:` GitHub stars`})]})]})]})]})})}function ve({groupKind:e,entries:n,limit:r,compact:i,selectedKey:a,onSelect:o,onShowMore:s,hasUpdate:c,pageSize:l}){let u=n.length-r;return(0,Q.jsxs)(`section`,{"aria-label":`${x(e).label} entries`,className:`grid min-w-0 gap-3`,children:[(0,Q.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground`,children:[x(e).label,`s (`,n.length,`)`]}),(0,Q.jsx)(`div`,{className:t(`grid min-w-0 gap-3`,i?`grid-cols-1`:`sm:grid-cols-2 2xl:grid-cols-3`),children:n.slice(0,r).map(e=>{let t=W(e);return(0,Q.jsx)(_e,{compact:i,entry:e,onSelect:()=>o(t),selected:t===a,updateAvailable:c(e)},t)})}),u>0?(0,Q.jsxs)(j,{className:`justify-self-start`,onClick:()=>s(e),size:`sm`,variant:`secondary`,children:[`Show `,Math.min(u,l),` more`]}):null]})}function ye({entryCount:e,isCompact:n,kind:r,category:i,tag:a,tags:o,sort:s,searchQuery:c,isRefreshing:l,onKindChange:u,onCategoryChange:f,onTagChange:p,onSortChange:m,onSearchQueryChange:h,onRefresh:g}){return(0,Q.jsxs)(`div`,{className:`grid min-w-0 shrink-0 gap-3 pb-4`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Q.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Catalog`}),(0,Q.jsx)(L,{variant:`default`,children:e})]}),(0,Q.jsx)(P,{children:(0,Q.jsxs)(T,{children:[(0,Q.jsx)(E,{render:(0,Q.jsx)(j,{"aria-label":l?`Refreshing catalog`:`Refresh catalog`,disabled:l,onClick:g,size:`icon-sm`,variant:`secondary`,children:(0,Q.jsx)(_,{className:t(`size-4`,l&&`animate-spin`)})})}),(0,Q.jsx)(ee,{children:l?`Refreshing…`:`Refresh catalog`})]})})]}),(0,Q.jsxs)(`div`,{className:t(`flex min-w-0 flex-col gap-3`,!n&&`lg:flex-row lg:items-center`),children:[(0,Q.jsxs)(`div`,{className:`relative min-w-0 flex-1`,children:[(0,Q.jsx)(d,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,Q.jsx)(N,{"aria-label":`Search catalog`,className:`h-9 pl-9`,onChange:e=>h(e.target.value),placeholder:`Search name, description, author, or tag`,value:c})]}),(0,Q.jsxs)(`div`,{className:t(`flex min-w-0 flex-col gap-3`,!n&&`sm:flex-row sm:items-center`),children:[(0,Q.jsx)(V,{className:t(`shrink-0 gap-0`,n?`w-full`:`w-full sm:w-auto`),onValueChange:e=>u(ae(typeof e==`string`?e:null)),value:r,children:(0,Q.jsxs)(z,{"aria-label":`Filter by kind`,className:t(n?`w-full`:`w-full sm:w-auto`),children:[(0,Q.jsx)(B,{value:`__all__`,children:`All`}),(0,Q.jsx)(B,{value:`skills`,children:`Skills`}),(0,Q.jsx)(B,{value:`agents`,children:`Agents`}),(0,Q.jsx)(B,{value:`workflows`,children:`Workflows`})]})}),(0,Q.jsxs)(R,{"aria-label":`Filter by category`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-48`),onChange:e=>f(oe(e.target.value)),value:i,children:[(0,Q.jsx)(`option`,{value:`__all__`,children:`All categories`}),C.map(e=>(0,Q.jsx)(`option`,{value:e,children:U[e]},e))]}),(0,Q.jsxs)(R,{"aria-label":`Filter by tag`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-44`),onChange:e=>p(e.target.value||`__all__`),value:a,children:[(0,Q.jsx)(`option`,{value:`__all__`,children:`All tags`}),o.map(e=>(0,Q.jsx)(`option`,{value:e,children:e},e))]}),(0,Q.jsx)(R,{"aria-label":`Sort catalog`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-44`),onChange:e=>m(ue(e.target.value)),value:s,children:Y.map(e=>(0,Q.jsx)(`option`,{value:e,children:X[e]},e))})]})]})]})}var $=`flex h-[calc(100vh-2rem)] min-w-0 flex-col -mb-4 sm:-mb-6 sm:h-[calc(100vh-3rem)]`;function be(){let e=s(),n=c(),[o,l]=i(),d=ae(o.get(`kind`)),f=oe(o.get(`category`)),p=de(o.get(`tag`)),m=ue(o.get(`sort`)),[h,g]=(0,H.useState)(``),[_,v]=(0,H.useState)(null),x=(0,H.useRef)(null),[S,C]=(0,H.useState)({top:!1,bottom:!1}),w=a({queryKey:O.catalog,queryFn:()=>F.getAll()}),T=(0,H.useMemo)(()=>w.data?.entries??[],[w.data]),E=T.some(e=>e.kind===`skills`&&e.installed),k=a({queryKey:O.skillUpdates,queryFn:()=>b.checkSkillUpdates(),enabled:E,staleTime:3e5}),ee=(0,H.useMemo)(()=>new Set((k.data?.results??[]).filter(e=>e.status===`update_available`).map(e=>e.name)),[k.data]),A=e=>e.installed&&e.kind===`skills`&&ee.has(e.installedName??e.id),M=r({mutationFn:()=>F.getAll({refresh:!0}),onSuccess:t=>{e.setQueryData(O.catalog,t),t.stale?D.warning(`Could not reach every catalog source`,{description:le(t.failures)??`Showing the last cached index.`}):D.success(`Catalog refreshed`)},onError:e=>{D.error(y(e,`Unable to refresh catalog`))}}),N=r({mutationFn:e=>F.install({sourceId:e.sourceId,entryId:e.id}),onSuccess:async(t,n)=>{D.success(`Installed ${t.asset.kind}/${t.asset.name}`),t.scriptsDetected&&!n.hasScripts&&D.warning(`This asset bundles undeclared scripts`,{description:`Review them in Library before use. Chain Hub never runs scripts on install.`}),await Promise.all([e.invalidateQueries({queryKey:O.catalog}),e.invalidateQueries({queryKey:O.library}),e.invalidateQueries({queryKey:O.overview})])},onError:e=>{D.error(y(e,`Unable to install catalog entry`))}}),P=he((0,H.useMemo)(()=>T.map(e=>e.source.repo),[T])),L=(0,H.useMemo)(()=>fe(T),[T]),R=(0,H.useMemo)(()=>se(T,{kind:d,category:f,tag:p,query:h}),[T,d,f,p,h]),z=(0,H.useMemo)(()=>pe(R,m,P),[R,m,P]),B=(0,H.useMemo)(()=>ce(z),[z]),V=`${d}|${f}|${p}|${m}|${h}`,[U,G]=(0,H.useState)({signature:V,limits:{}}),K=e=>(U.signature===V?U.limits[e]:void 0)??60,q=e=>G({signature:V,limits:{...U.signature===V?U.limits:{},[e]:K(e)+60}}),J=T.find(e=>W(e)===_)??null,Y=(e,t)=>{let n=new URLSearchParams(o);t===`__all__`||e===`sort`&&t===`relevance`?n.delete(e):n.set(e,t),l(n,{replace:!0})};(0,H.useEffect)(()=>{let e=x.current;if(!e)return;let t=()=>{C({top:e.scrollTop>0,bottom:e.scrollTop+e.clientHeight<e.scrollHeight-1})};t(),e.addEventListener(`scroll`,t,{passive:!0});let n=typeof ResizeObserver>`u`?null:new ResizeObserver(t);return n?.observe(e),()=>{e.removeEventListener(`scroll`,t),n?.disconnect()}},[R.length,J,w.isLoading]);let X=(0,Q.jsx)(ye,{category:f,entryCount:R.length,isCompact:J!==null,isRefreshing:M.isPending,kind:d,onCategoryChange:e=>Y(`category`,e),onKindChange:e=>Y(`kind`,e),onRefresh:()=>M.mutate(),onSearchQueryChange:g,onSortChange:e=>Y(`sort`,e),onTagChange:e=>Y(`tag`,e),searchQuery:h,sort:m,tag:p,tags:L});if(w.isLoading)return(0,Q.jsxs)(`div`,{className:$,children:[X,(0,Q.jsx)(te,{className:`min-h-0 flex-1`,variant:`workspace`})]});if(w.isError)return(0,Q.jsxs)(`div`,{className:$,children:[X,(0,Q.jsx)(ne,{description:`The catalog index is temporarily unavailable.`,title:`Unable to load catalog`})]});let Z=le(w.data?.failures);return(0,Q.jsx)(`div`,{className:$,children:(0,Q.jsxs)(`section`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[w.data?.stale?(0,Q.jsx)(`div`,{className:`min-w-0 shrink-0 pb-3`,children:(0,Q.jsxs)(ie,{className:`items-center`,variant:`warning`,children:[(0,Q.jsx)(I,{children:(0,Q.jsx)(u,{})}),(0,Q.jsxs)(re,{children:[(0,Q.jsx)(`p`,{children:T.length>0?`Showing the last cached catalog. Some sources could not be refreshed.`:Z?`The catalog could not be fetched.`:`The catalog has not been fetched yet. Check your connection and refresh.`}),Z?(0,Q.jsx)(`p`,{className:`mt-1 break-words text-xs opacity-80`,children:Z}):null]}),(0,Q.jsx)(j,{className:`ml-auto shrink-0`,loading:M.isPending,onClick:()=>M.mutate(),size:`sm`,variant:`secondary`,children:`Retry`})]})}):null,(0,Q.jsxs)(`div`,{className:t(`grid min-h-0 min-w-0 flex-1 gap-4`,J?`xl:grid-cols-[minmax(0,22rem)_minmax(0,1fr)]`:`grid-cols-1`),children:[(0,Q.jsxs)(`div`,{className:t(`flex min-h-0 min-w-0 flex-col`,J&&`hidden xl:flex`),children:[X,(0,Q.jsx)(`div`,{className:`relative min-h-0 min-w-0 flex-1`,children:(0,Q.jsx)(`div`,{className:t(`h-full min-w-0 overflow-y-auto pb-4 pr-1`,S.top&&`fade-top`,S.bottom&&`fade-bottom`),ref:x,children:R.length===0?(0,Q.jsx)(`div`,{className:`rounded-xl border border-dashed border-border p-6 text-sm text-muted-foreground`,children:T.length===0?`No catalog entries yet. Refresh once you are online.`:`No catalog entries match the current search and filters.`}):(0,Q.jsx)(`div`,{className:`grid min-w-0 gap-6`,children:B.map(([e,t])=>(0,Q.jsx)(ve,{compact:J!==null,entries:t,groupKind:e,hasUpdate:A,limit:K(e),onSelect:v,onShowMore:q,pageSize:60,selectedKey:_},e))})})})]}),J?(0,Q.jsx)(ge,{entry:J,isInstalling:N.isPending&&N.variables===J,onBack:()=>v(null),onInstall:()=>N.mutate(J),onOpenInLibrary:()=>n(`/library?kind=${encodeURIComponent(J.kind)}&asset=${encodeURIComponent(J.installedName??J.id)}`),updateAvailable:A(J)}):null]})]})})}export{be as CatalogPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,U as r,V as i,W as a,Z as o,q as s,z as c}from"./vendor-react-BgntYnUn.js";import{J as l,Q as u,S as d,V as f,ft as p,h as m,q as h,v as g,w as _,y as v}from"./vendor-ui-qVCZmmA-.js";import{A as y,C as b,J as x,Q as S,Z as C,a as w,ct as T,dt as E,gt as D,h as O,i as k,lt as ee,n as A,o as te,pt as j,r as M,st as N,t as ne,ut as P,v as F}from"./index-ommOzjM4.js";import{n as re,r as I,t as ie}from"./alert-YumgHBdn.js";import{t as L}from"./badge-C2BSIZMN.js";import{t as R}from"./select-DJSrFTH0.js";import{n as z,r as B,t as V}from"./tabs-B9fkoXIl.js";var H=e(o(),1),U={"code-quality":`Code quality`,design:`Design`,docs:`Docs`,testing:`Testing`,devops:`DevOps`,research:`Research`,writing:`Writing`,productivity:`Productivity`,"editor-integration":`Editor integration`,other:`Other`};function ae(e){return S.includes(e??``)?e:`__all__`}function oe(e){return C.includes(e??``)?e:`__all__`}function W(e){return`${e.id}@${e.sourceId}`}function se(e,t){let n=t.query.trim().toLowerCase();return e.filter(e=>t.kind!==`__all__`&&e.kind!==t.kind||t.category!==`__all__`&&e.category!==t.category||t.tag!==`__all__`&&!e.tags.includes(t.tag)?!1:!n||[e.id,e.name,e.description,e.author??``,...e.tags].some(e=>e.toLowerCase().includes(n)))}function ce(e){let t=new Map;for(let n of e)t.set(n.kind,[...t.get(n.kind)??[],n]);let n=S,r=e=>n.includes(e)?n.indexOf(e):n.length;return Array.from(t.entries()).sort(([e],[t])=>r(e)-r(t))}function G(e){let t=e.trim().match(/^(?:https?:\/\/(?:www\.)?github\.com\/|git@github\.com:)([^/\s]+)\/([^/\s#?]+?)(?:\.git)?\/?$/i);return!t?.[1]||!t[2]?null:`${t[1]}/${t[2]}`}function K(e){let t=G(e.repo);if(t){let n=`https://github.com/${t}`;return e.subdir?`${n}/tree/${e.ref??`HEAD`}/${e.subdir.replace(/^\/+/,``)}`:n}return/^https?:\/\//i.test(e.repo)?e.repo:null}async function q(e){try{let t=await fetch(`https://api.github.com/repos/${e}`,{headers:{Accept:`application/vnd.github+json`}});if(!t.ok)return null;let n=await t.json();return typeof n.stargazers_count==`number`?n.stargazers_count:null}catch{return null}}function J(e){if(e<1e3)return String(e);let t=e/1e3;return`${t>=10?Math.round(t):t.toFixed(1).replace(/\.0$/,``)}k`}function le(e){return!e||e.length===0?null:e.map(e=>`${e.sourceId}: ${e.error}`).join(` · `)}var Y=[`relevance`,`stars`,`newest`,`active`],X={relevance:`Relevance`,stars:`Most starred`,newest:`Recently added`,active:`Recently updated`};function ue(e){return Y.includes(e??``)?e:`relevance`}function de(e){return e&&e.trim()?e.trim():`__all__`}function fe(e){let t=new Set;for(let n of e)for(let e of n.tags)t.add(e);return Array.from(t).sort((e,t)=>e.localeCompare(t))}function pe(e,t,n){if(t===`relevance`)return e;let r=e=>{switch(t){case`stars`:{let t=G(e.source.repo);return(t===null?void 0:n.get(t))??e.stats?.stars??null}case`newest`:return e.addedAt?Date.parse(e.addedAt):null;case`active`:return e.stats?.pushedAt?Date.parse(e.stats.pushedAt):null}};return[...e].sort((e,t)=>(r(t)??-1)-(r(e)??-1))}var Z=36e5;function me(e){let t=G(e);return a({queryKey:O.githubStars(t??``),queryFn:()=>q(t??``),enabled:t!==null,staleTime:Z,gcTime:24*Z,retry:!1,refetchOnWindowFocus:!1}).data??null}function he(e){let t=(0,H.useMemo)(()=>Array.from(new Set(e.map(G).filter(e=>e!==null))).sort(),[e]);return a({queryKey:O.githubStars(`map:${t.join(`,`)}`),queryFn:async()=>{let e=new Map;return await Promise.all(t.map(async t=>{let n=await q(t);n!==null&&e.set(t,n)})),e},enabled:t.length>0,staleTime:Z,gcTime:24*Z,retry:!1,refetchOnWindowFocus:!1}).data??new Map}var Q=n();function ge({entry:e,updateAvailable:n,isInstalling:i,onBack:a,onInstall:o,onOpenInLibrary:c}){let u=x(e.kind),d=me(e.source.repo),_=K(e.source),y=e.source.subdir?`${e.source.repo}/${e.source.subdir}`:e.source.repo,b=s(),S=r({mutationFn:()=>F.scan({sourceId:e.sourceId,entryId:e.id}),onSuccess:e=>{b.invalidateQueries({queryKey:O.catalog});let t=e.scan.findings.length;D.success(`Security scan: ${e.scan.verdict}${t?` (${t} finding${t===1?``:`s`})`:``}`)},onError:e=>D.error(e.message)}),C=e.securityScan?.verdict??null;return(0,Q.jsxs)(A,{"aria-label":`${e.name} details`,className:t(`fixed inset-0 z-40 flex min-w-0 flex-col overflow-hidden rounded-none border-0 bg-card`,`xl:static xl:z-auto xl:rounded-xl xl:border xl:border-border xl:bg-card`),role:`region`,children:[(0,Q.jsxs)(k,{children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-start gap-3`,children:[(0,Q.jsxs)(j,{className:`xl:hidden`,onClick:a,size:`icon-sm`,type:`button`,variant:`ghost`,children:[(0,Q.jsx)(p,{className:`size-4`}),(0,Q.jsx)(`span`,{className:`sr-only`,children:`Back to catalog`})]}),(0,Q.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1`,children:[(0,Q.jsx)(w,{className:`truncate`,children:e.name}),(0,Q.jsxs)(`p`,{className:`truncate font-mono text-xs text-muted-foreground`,children:[e.kind,`/`,e.id]}),e.author?(0,Q.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`by `,e.author]}):null]})]}),(0,Q.jsx)(L,{variant:`accent`,children:u.label})]}),(0,Q.jsxs)(M,{className:`grid flex-1 content-start gap-5 overflow-y-auto`,children:[(0,Q.jsx)(`p`,{className:`max-w-prose text-sm leading-6 text-foreground`,children:e.description}),e.hasScripts?(0,Q.jsxs)(ie,{variant:`warning`,children:[(0,Q.jsx)(I,{children:(0,Q.jsx)(v,{})}),(0,Q.jsxs)(re,{children:[`This `,u.label.toLowerCase(),` bundles executable scripts. Review them in the source before using it; Chain Hub never runs scripts on install.`]})]}):null,(0,Q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[C===`pass`?(0,Q.jsxs)(L,{variant:`success`,children:[(0,Q.jsx)(g,{"aria-hidden":`true`,className:`size-3`}),` Security: pass`]}):C===`warn`?(0,Q.jsxs)(L,{variant:`warning`,children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: warn`]}):C===`fail`?(0,Q.jsxs)(L,{variant:`destructive`,children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: fail`]}):(0,Q.jsxs)(L,{children:[(0,Q.jsx)(v,{"aria-hidden":`true`,className:`size-3`}),` Security: not scanned`]}),C===`pass`?null:(0,Q.jsx)(j,{loading:S.isPending,onClick:()=>S.mutate(),size:`sm`,type:`button`,variant:`outline`,children:`Scan source`})]}),C===`fail`?(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`The scan found high-severity issues — installing this entry is blocked unless you explicitly override.`}):null,(0,Q.jsxs)(`dl`,{className:`grid gap-3 text-sm sm:grid-cols-[auto_minmax(0,1fr)] sm:gap-x-6`,children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Source`}),(0,Q.jsx)(`dd`,{className:`min-w-0`,children:_?(0,Q.jsxs)(`a`,{className:`inline-flex max-w-full items-center gap-1.5 rounded-sm font-mono text-xs text-foreground underline-offset-4 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`,href:_,rel:`noreferrer`,target:`_blank`,children:[(0,Q.jsx)(`span`,{className:`truncate`,children:y}),(0,Q.jsx)(h,{"aria-hidden":`true`,className:`size-3 shrink-0`})]}):(0,Q.jsx)(`span`,{className:`break-all font-mono text-xs text-foreground`,children:y})}),e.source.ref?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Ref`}),(0,Q.jsx)(`dd`,{className:`font-mono text-xs text-foreground`,children:e.source.ref})]}):null,(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`License`}),(0,Q.jsx)(`dd`,{className:`text-foreground`,children:e.license??`Not specified`}),(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Category`}),(0,Q.jsx)(`dd`,{className:`text-foreground`,children:U[e.category]}),d===null?null:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Stars`}),(0,Q.jsxs)(`dd`,{className:`inline-flex items-center gap-1 tabular-nums text-foreground`,children:[(0,Q.jsx)(m,{"aria-hidden":`true`,className:`size-3.5 text-muted-foreground`}),J(d)]})]}),(0,Q.jsx)(`dt`,{className:`text-xs font-medium text-muted-foreground`,children:`Catalog`}),(0,Q.jsx)(`dd`,{className:`font-mono text-xs text-foreground`,children:e.sourceId})]}),e.tags.length>0?(0,Q.jsxs)(`div`,{className:`grid gap-2`,children:[(0,Q.jsx)(`p`,{className:`text-xs font-medium text-muted-foreground`,children:`Tags`}),(0,Q.jsx)(`ul`,{"aria-label":`Tags`,className:`flex flex-wrap gap-1.5`,children:e.tags.map(e=>(0,Q.jsx)(`li`,{children:(0,Q.jsx)(L,{children:e})},e))})]}):null]}),(0,Q.jsx)(`div`,{className:`flex flex-wrap items-center gap-3 border-t border-border px-4 py-3`,children:e.installed?(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(L,{variant:`success`,children:`Installed`}),n?(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`An upstream update is available; update it from Library.`}):null,(0,Q.jsxs)(j,{className:`ml-auto`,onClick:c,size:`sm`,type:`button`,variant:`outline`,children:[(0,Q.jsx)(f,{className:`size-4`}),`Open in Library`]})]}):(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Installs into your hub from the upstream source and records its provenance.`}),(0,Q.jsxs)(j,{className:`ml-auto`,loading:i,onClick:o,size:`sm`,type:`button`,children:[(0,Q.jsx)(l,{className:`size-4`}),`Install`]})]})})]})}function _e({entry:e,selected:n,compact:r=!1,updateAvailable:i=!1,onSelect:a}){let o=x(e.kind),s=o.icon,c=me(e.source.repo);return(0,Q.jsx)(`button`,{"aria-pressed":n,className:t(`group relative grid w-full min-w-0 rounded-xl border border-border bg-card text-left shadow-card transition-colors`,`hover:bg-accent/60`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background`,n&&`border-foreground/20 bg-accent`,r?`gap-2 p-3`:`gap-3 p-4`),onClick:a,type:`button`,children:(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[(0,Q.jsx)(s,{"aria-hidden":`true`,className:t(`mt-0.5 size-4 shrink-0 transition-colors`,n?`text-foreground`:`text-muted-foreground`)}),(0,Q.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1 overflow-hidden`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-foreground`,children:e.name}),(0,Q.jsx)(L,{variant:`accent`,children:o.label}),e.installed?(0,Q.jsx)(L,{variant:`success`,children:`Installed`}):null,i?(0,Q.jsx)(L,{variant:`accent`,children:`Update available`}):null]}),(0,Q.jsx)(`p`,{className:t(`text-xs text-muted-foreground`,r?`truncate`:`line-clamp-2`),children:e.description}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground`,children:[(0,Q.jsx)(`span`,{children:U[e.category]}),e.author?(0,Q.jsxs)(`span`,{className:`min-w-0 truncate`,children:[`by `,e.author]}):null,c===null?null:(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1 tabular-nums`,children:[(0,Q.jsx)(m,{"aria-hidden":`true`,className:`size-3`}),J(c),(0,Q.jsx)(`span`,{className:`sr-only`,children:` GitHub stars`})]})]})]})]})})}function ve({groupKind:e,entries:n,limit:r,compact:i,selectedKey:a,onSelect:o,onShowMore:s,hasUpdate:c,pageSize:l}){let u=n.length-r;return(0,Q.jsxs)(`section`,{"aria-label":`${x(e).label} entries`,className:`grid min-w-0 gap-3`,children:[(0,Q.jsxs)(`h2`,{className:`text-xs font-medium text-muted-foreground`,children:[x(e).label,`s (`,n.length,`)`]}),(0,Q.jsx)(`div`,{className:t(`grid min-w-0 gap-3`,i?`grid-cols-1`:`sm:grid-cols-2 2xl:grid-cols-3`),children:n.slice(0,r).map(e=>{let t=W(e);return(0,Q.jsx)(_e,{compact:i,entry:e,onSelect:()=>o(t),selected:t===a,updateAvailable:c(e)},t)})}),u>0?(0,Q.jsxs)(j,{className:`justify-self-start`,onClick:()=>s(e),size:`sm`,variant:`secondary`,children:[`Show `,Math.min(u,l),` more`]}):null]})}function ye({entryCount:e,isCompact:n,kind:r,category:i,tag:a,tags:o,sort:s,searchQuery:c,isRefreshing:l,onKindChange:u,onCategoryChange:f,onTagChange:p,onSortChange:m,onSearchQueryChange:h,onRefresh:g}){return(0,Q.jsxs)(`div`,{className:`grid min-w-0 shrink-0 gap-3 pb-4`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,Q.jsx)(`h1`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Catalog`}),(0,Q.jsx)(L,{variant:`default`,children:e})]}),(0,Q.jsx)(P,{children:(0,Q.jsxs)(T,{children:[(0,Q.jsx)(E,{render:(0,Q.jsx)(j,{"aria-label":l?`Refreshing catalog`:`Refresh catalog`,disabled:l,onClick:g,size:`icon-sm`,variant:`secondary`,children:(0,Q.jsx)(_,{className:t(`size-4`,l&&`animate-spin`)})})}),(0,Q.jsx)(ee,{children:l?`Refreshing…`:`Refresh catalog`})]})})]}),(0,Q.jsxs)(`div`,{className:t(`flex min-w-0 flex-col gap-3`,!n&&`lg:flex-row lg:items-center`),children:[(0,Q.jsxs)(`div`,{className:`relative min-w-0 flex-1`,children:[(0,Q.jsx)(d,{className:`pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground`}),(0,Q.jsx)(N,{"aria-label":`Search catalog`,className:`h-9 pl-9`,onChange:e=>h(e.target.value),placeholder:`Search name, description, author, or tag`,value:c})]}),(0,Q.jsxs)(`div`,{className:t(`flex min-w-0 flex-col gap-3`,!n&&`sm:flex-row sm:items-center`),children:[(0,Q.jsx)(V,{className:t(`shrink-0 gap-0`,n?`w-full`:`w-full sm:w-auto`),onValueChange:e=>u(ae(typeof e==`string`?e:null)),value:r,children:(0,Q.jsxs)(z,{"aria-label":`Filter by kind`,className:t(n?`w-full`:`w-full sm:w-auto`),children:[(0,Q.jsx)(B,{value:`__all__`,children:`All`}),(0,Q.jsx)(B,{value:`skills`,children:`Skills`}),(0,Q.jsx)(B,{value:`agents`,children:`Agents`}),(0,Q.jsx)(B,{value:`workflows`,children:`Workflows`})]})}),(0,Q.jsxs)(R,{"aria-label":`Filter by category`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-48`),onChange:e=>f(oe(e.target.value)),value:i,children:[(0,Q.jsx)(`option`,{value:`__all__`,children:`All categories`}),C.map(e=>(0,Q.jsx)(`option`,{value:e,children:U[e]},e))]}),(0,Q.jsxs)(R,{"aria-label":`Filter by tag`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-44`),onChange:e=>p(e.target.value||`__all__`),value:a,children:[(0,Q.jsx)(`option`,{value:`__all__`,children:`All tags`}),o.map(e=>(0,Q.jsx)(`option`,{value:e,children:e},e))]}),(0,Q.jsx)(R,{"aria-label":`Sort catalog`,className:t(`shrink-0`,n?`w-full`:`w-full sm:w-44`),onChange:e=>m(ue(e.target.value)),value:s,children:Y.map(e=>(0,Q.jsx)(`option`,{value:e,children:X[e]},e))})]})]})]})}var $=`flex h-[calc(100vh-2rem)] min-w-0 flex-col -mb-4 sm:-mb-6 sm:h-[calc(100vh-3rem)]`;function be(){let e=s(),n=c(),[o,l]=i(),d=ae(o.get(`kind`)),f=oe(o.get(`category`)),p=de(o.get(`tag`)),m=ue(o.get(`sort`)),[h,g]=(0,H.useState)(``),[_,v]=(0,H.useState)(null),x=(0,H.useRef)(null),[S,C]=(0,H.useState)({top:!1,bottom:!1}),w=a({queryKey:O.catalog,queryFn:()=>F.getAll()}),T=(0,H.useMemo)(()=>w.data?.entries??[],[w.data]),E=T.some(e=>e.kind===`skills`&&e.installed),k=a({queryKey:O.skillUpdates,queryFn:()=>b.checkSkillUpdates(),enabled:E,staleTime:3e5}),ee=(0,H.useMemo)(()=>new Set((k.data?.results??[]).filter(e=>e.status===`update_available`).map(e=>e.name)),[k.data]),A=e=>e.installed&&e.kind===`skills`&&ee.has(e.installedName??e.id),M=r({mutationFn:()=>F.getAll({refresh:!0}),onSuccess:t=>{e.setQueryData(O.catalog,t),t.stale?D.warning(`Could not reach every catalog source`,{description:le(t.failures)??`Showing the last cached index.`}):D.success(`Catalog refreshed`)},onError:e=>{D.error(y(e,`Unable to refresh catalog`))}}),N=r({mutationFn:e=>F.install({sourceId:e.sourceId,entryId:e.id}),onSuccess:async(t,n)=>{D.success(`Installed ${t.asset.kind}/${t.asset.name}`),t.scriptsDetected&&!n.hasScripts&&D.warning(`This asset bundles undeclared scripts`,{description:`Review them in Library before use. Chain Hub never runs scripts on install.`}),await Promise.all([e.invalidateQueries({queryKey:O.catalog}),e.invalidateQueries({queryKey:O.library}),e.invalidateQueries({queryKey:O.overview})])},onError:e=>{D.error(y(e,`Unable to install catalog entry`))}}),P=he((0,H.useMemo)(()=>T.map(e=>e.source.repo),[T])),L=(0,H.useMemo)(()=>fe(T),[T]),R=(0,H.useMemo)(()=>se(T,{kind:d,category:f,tag:p,query:h}),[T,d,f,p,h]),z=(0,H.useMemo)(()=>pe(R,m,P),[R,m,P]),B=(0,H.useMemo)(()=>ce(z),[z]),V=`${d}|${f}|${p}|${m}|${h}`,[U,G]=(0,H.useState)({signature:V,limits:{}}),K=e=>(U.signature===V?U.limits[e]:void 0)??60,q=e=>G({signature:V,limits:{...U.signature===V?U.limits:{},[e]:K(e)+60}}),J=T.find(e=>W(e)===_)??null,Y=(e,t)=>{let n=new URLSearchParams(o);t===`__all__`||e===`sort`&&t===`relevance`?n.delete(e):n.set(e,t),l(n,{replace:!0})};(0,H.useEffect)(()=>{let e=x.current;if(!e)return;let t=()=>{C({top:e.scrollTop>0,bottom:e.scrollTop+e.clientHeight<e.scrollHeight-1})};t(),e.addEventListener(`scroll`,t,{passive:!0});let n=typeof ResizeObserver>`u`?null:new ResizeObserver(t);return n?.observe(e),()=>{e.removeEventListener(`scroll`,t),n?.disconnect()}},[R.length,J,w.isLoading]);let X=(0,Q.jsx)(ye,{category:f,entryCount:R.length,isCompact:J!==null,isRefreshing:M.isPending,kind:d,onCategoryChange:e=>Y(`category`,e),onKindChange:e=>Y(`kind`,e),onRefresh:()=>M.mutate(),onSearchQueryChange:g,onSortChange:e=>Y(`sort`,e),onTagChange:e=>Y(`tag`,e),searchQuery:h,sort:m,tag:p,tags:L});if(w.isLoading)return(0,Q.jsxs)(`div`,{className:$,children:[X,(0,Q.jsx)(te,{className:`min-h-0 flex-1`,variant:`workspace`})]});if(w.isError)return(0,Q.jsxs)(`div`,{className:$,children:[X,(0,Q.jsx)(ne,{description:`The catalog index is temporarily unavailable.`,title:`Unable to load catalog`})]});let Z=le(w.data?.failures);return(0,Q.jsx)(`div`,{className:$,children:(0,Q.jsxs)(`section`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[w.data?.stale?(0,Q.jsx)(`div`,{className:`min-w-0 shrink-0 pb-3`,children:(0,Q.jsxs)(ie,{className:`items-center`,variant:`warning`,children:[(0,Q.jsx)(I,{children:(0,Q.jsx)(u,{})}),(0,Q.jsxs)(re,{children:[(0,Q.jsx)(`p`,{children:T.length>0?`Showing the last cached catalog. Some sources could not be refreshed.`:Z?`The catalog could not be fetched.`:`The catalog has not been fetched yet. Check your connection and refresh.`}),Z?(0,Q.jsx)(`p`,{className:`mt-1 break-words text-xs opacity-80`,children:Z}):null]}),(0,Q.jsx)(j,{className:`ml-auto shrink-0`,loading:M.isPending,onClick:()=>M.mutate(),size:`sm`,variant:`secondary`,children:`Retry`})]})}):null,(0,Q.jsxs)(`div`,{className:t(`grid min-h-0 min-w-0 flex-1 gap-4`,J?`xl:grid-cols-[minmax(0,22rem)_minmax(0,1fr)]`:`grid-cols-1`),children:[(0,Q.jsxs)(`div`,{className:t(`flex min-h-0 min-w-0 flex-col`,J&&`hidden xl:flex`),children:[X,(0,Q.jsx)(`div`,{className:`relative min-h-0 min-w-0 flex-1`,children:(0,Q.jsx)(`div`,{className:t(`h-full min-w-0 overflow-y-auto pb-4 pr-1`,S.top&&`fade-top`,S.bottom&&`fade-bottom`),ref:x,children:R.length===0?(0,Q.jsx)(`div`,{className:`rounded-xl border border-dashed border-border p-6 text-sm text-muted-foreground`,children:T.length===0?`No catalog entries yet. Refresh once you are online.`:`No catalog entries match the current search and filters.`}):(0,Q.jsx)(`div`,{className:`grid min-w-0 gap-6`,children:B.map(([e,t])=>(0,Q.jsx)(ve,{compact:J!==null,entries:t,groupKind:e,hasUpdate:A,limit:K(e),onSelect:v,onShowMore:q,pageSize:60,selectedKey:_},e))})})})]}),J?(0,Q.jsx)(ge,{entry:J,isInstalling:N.isPending&&N.variables===J,onBack:()=>v(null),onInstall:()=>N.mutate(J),onOpenInLibrary:()=>n(`/library?kind=${encodeURIComponent(J.kind)}&asset=${encodeURIComponent(J.installedName??J.id)}`),updateAvailable:A(J)}):null]})]})})}export{be as CatalogPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,M as r,U as i,W as a,Z as o,q as s}from"./vendor-react-BgntYnUn.js";import{O as c,Z as l,ct as u,j as d,lt as f,rt as p,u as m,v as h}from"./vendor-ui-qVCZmmA-.js";import{A as g,C as _,T as v,gt as y,h as b,mt as x,o as S,pt as C,t as w,y as T}from"./index-ommOzjM4.js";import{t as E}from"./badge-C2BSIZMN.js";import{t as D}from"./format-time-D8VGlAcs.js";import{t as O}from"./SkillRelinkDialog-C5PU7vKu.js";var k=e(o(),1),A=n();function j({issue:e,action:n,retryCheck:i,retryUpdate:a,unlinkSkill:o,importAgentsSkills:s,removeScan:c,onRelink:l}){let u=e.assetName??``;switch(n){case`remove-scan`:return e.assetKind&&e.assetName?(0,A.jsx)(C,{loading:c.isPending,onClick:()=>c.mutate({kind:e.assetKind,name:e.assetName}),size:`sm`,type:`button`,variant:`secondary`,children:`Remove record`},n):null;case`retry-check`:return(0,A.jsx)(C,{loading:i.isPending&&i.variables===u,onClick:()=>i.mutate(u),size:`sm`,type:`button`,variant:`secondary`,children:`Retry check`},n);case`retry-update`:return(0,A.jsx)(C,{loading:a.isPending&&a.variables===u,onClick:()=>a.mutate(u),size:`sm`,type:`button`,variant:`secondary`,children:`Retry update`},n);case`relink`:return(0,A.jsx)(C,{onClick:()=>l(u),size:`sm`,type:`button`,variant:`secondary`,children:`Relink…`},n);case`unlink`:return(0,A.jsx)(C,{loading:o.isPending&&o.variables===u,onClick:()=>o.mutate(u),size:`sm`,type:`button`,variant:`ghost`,children:`Unlink`},n);case`open-asset`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/library?kind=${e.assetKind}&asset=${encodeURIComponent(u)}`,children:`Open in Library`},n);case`import-agents`:return(0,A.jsx)(C,{loading:s.isPending,onClick:()=>s.mutate(),size:`sm`,type:`button`,variant:`secondary`,children:`Import into Hub`},n);case`open-setup`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/setup`,children:`Open setup`},n);case`open-integrations`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/integrations`,children:`Open backup settings`},n);default:return null}}function M({issues:e,title:t=`Issues`,...n}){return(0,A.jsxs)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:[(0,A.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border px-4 py-3`,children:[(0,A.jsx)(`h3`,{className:`text-sm font-semibold tracking-tight text-foreground`,children:t}),(0,A.jsx)(E,{variant:`warning`,children:e.length})]}),(0,A.jsx)(`ul`,{className:`grid items-start gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3`,children:e.map(e=>(0,A.jsx)(`li`,{className:`h-full rounded-lg bg-muted/40 px-3 py-3`,children:(0,A.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[e.severity===`error`?(0,A.jsx)(p,{className:`mt-0.5 size-4 shrink-0 text-destructive`}):(0,A.jsx)(m,{className:`mt-0.5 size-4 shrink-0 text-warning-foreground`}),(0,A.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,A.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:e.title}),e.detail?(0,A.jsx)(`p`,{className:`mt-0.5 text-xs leading-5 text-muted-foreground`,children:e.detail}):null,e.actions.length>0?(0,A.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,children:e.actions.map(t=>(0,A.jsx)(j,{action:t,issue:e,...n},t))}):null]})]})},e.id))})]})}var N={structure:{icon:u,linkTo:`/setup`,linkLabel:`Open setup`},skills:{icon:c,linkTo:`/library`,linkLabel:`Open Library`},editors:{icon:d,linkTo:`/integrations`,linkLabel:`Open Integrations`},sync:{icon:l,linkTo:`/integrations`,linkLabel:`Open backup settings`},security:{icon:h,linkTo:`/library`,linkLabel:`Open Library`},ai:{icon:f,linkTo:`/settings`,linkLabel:`Open Settings`}},P={healthy:{variant:`success`,label:`Healthy`},warning:{variant:`warning`,label:`Warning`},error:{variant:`destructive`,label:`Error`},inactive:{variant:`default`,label:`Not set up`}};function F({subsystem:e}){let n=N[e.id],i=P[e.status],a=n.icon;return(0,A.jsxs)(`li`,{className:`flex items-start gap-3 px-4 py-3`,children:[(0,A.jsx)(a,{className:`mt-0.5 size-4 shrink-0 text-muted-foreground`,"aria-hidden":!0}),(0,A.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1`,children:[(0,A.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,A.jsx)(`h3`,{className:`min-w-0 truncate text-sm font-semibold tracking-tight text-foreground`,children:e.label}),(0,A.jsx)(E,{variant:i.variant,children:i.label})]}),(0,A.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:e.summary}),(0,A.jsxs)(`dl`,{className:`flex flex-wrap gap-x-4 gap-y-0.5`,children:[e.metrics.map(e=>(0,A.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,A.jsx)(`dt`,{className:`text-2xs text-muted-foreground`,children:e.label}),(0,A.jsx)(`dd`,{className:`truncate text-xs font-medium tabular-nums text-foreground`,title:e.value,children:e.value})]},e.label)),e.lastActivityAt?(0,A.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,A.jsx)(`dt`,{className:`text-2xs text-muted-foreground`,children:`Last activity`}),(0,A.jsx)(`dd`,{className:`truncate text-xs font-medium tabular-nums text-foreground`,title:new Date(e.lastActivityAt).toLocaleString(),children:D(e.lastActivityAt)})]}):null]})]}),(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`}),`shrink-0 self-center`),to:n.linkTo,children:n.linkLabel})]})}function I(){let e=s(),[t,n]=(0,k.useState)(null),r=a({queryKey:b.health,queryFn:()=>T.get()});function o(){e.invalidateQueries({queryKey:b.health}),e.invalidateQueries({queryKey:b.overview}),e.invalidateQueries({queryKey:b.issues}),e.invalidateQueries({queryKey:b.library}),e.invalidateQueries({queryKey:b.skillUpdates})}let c=i({mutationFn:async()=>_.migrateAgentsSkills({}),onSuccess:e=>{let t=e.results.filter(e=>e.status===`migrated`).length,n=e.results.filter(e=>e.status===`skipped`).length,r=e.results.filter(e=>e.status===`failed`).length;o(),y.success(`Imported from ~/.agents: ${t} migrated, ${n} skipped, ${r} failed`)},onError:()=>{y.error(`Unable to import from ~/.agents/.skill-lock.json`)}}),l=i({mutationFn:async e=>_.checkSkillUpdates({name:e,force:!0}),onSuccess:(e,t)=>{o();let n=e.results.find(e=>e.name===t);n?.status===`failed`?y.warning(`Check still failing for ${t}: ${n.error??`unknown error`}`):y.success(n?.status===`update_available`?`Update available for ${t}`:`${t} is up to date`)},onError:e=>{y.error(g(e,`Unable to check skill`))}}),u=i({mutationFn:async e=>_.updateSkills({name:e}),onSuccess:(e,t)=>{o();let n=e.results.find(e=>e.name===t);n?.status===`failed`?y.warning(`Update still failing for ${t}: ${n.error??`unknown error`}`):y.success(n?.status===`updated`?`Updated ${t}`:`${t} is up to date`)},onError:e=>{y.error(g(e,`Unable to update skill`))}}),d=i({mutationFn:async e=>_.unlinkSkill(e),onSuccess:(e,t)=>{o(),y.success(`${t} is now a local, editable skill`)},onError:e=>{y.error(g(e,`Unable to unlink skill`))}}),f=i({mutationFn:async({kind:e,name:t})=>v.removeScan(e,t),onSuccess:(e,{kind:t,name:n})=>{o(),y.success(`Removed stale scan record for ${t}/${n}`)},onError:e=>{y.error(g(e,`Unable to remove scan record`))}});if(r.isLoading)return(0,A.jsx)(S,{variant:`dashboard`});if(r.isError||!r.data)return(0,A.jsx)(w,{description:`The health report is temporarily unavailable.`,title:`Unable to load health`});let p=r.data,m=P[p.status],h=p.subsystems.filter(e=>e.issues.length>0);return(0,A.jsxs)(`section`,{className:`mx-auto grid w-full max-w-5xl gap-8`,children:[(0,A.jsxs)(`header`,{className:`grid gap-2`,children:[(0,A.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,A.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Health`}),(0,A.jsx)(E,{variant:m.variant,children:m.label}),(0,A.jsx)(C,{"aria-label":`Re-check all subsystems`,className:`ml-auto`,loading:r.isFetching,onClick:()=>void r.refetch(),size:`sm`,type:`button`,variant:`secondary`,children:`Re-check`})]}),(0,A.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Status of every hub subsystem, grouped per area. Spot problems early and jump straight to where they are fixed.`})]}),(0,A.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:(0,A.jsx)(`ul`,{className:`divide-y divide-border`,children:p.subsystems.map(e=>(0,A.jsx)(F,{subsystem:e},e.id))})}),h.length===0?(0,A.jsx)(`p`,{className:`rounded-2xl border border-border bg-card px-4 py-6 text-center text-sm text-muted-foreground shadow-card`,children:`No open issues; every subsystem is in good shape.`}):h.map(e=>(0,A.jsx)(M,{importAgentsSkills:c,issues:e.issues,onRelink:n,removeScan:f,retryCheck:l,retryUpdate:u,title:`Open issues: ${e.label}`,unlinkSkill:d},e.id)),(0,A.jsx)(O,{onOpenChange:e=>{e||n(null)},skillName:t})]})}export{I as HealthPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,M as r,U as i,W as a,Z as o,q as s}from"./vendor-react-BgntYnUn.js";import{O as c,Z as l,ct as u,j as d,lt as f,rt as p,u as m,v as h}from"./vendor-ui-qVCZmmA-.js";import{A as g,C as _,T as v,gt as y,h as b,mt as x,o as S,pt as C,t as w,y as T}from"./index-ltESF1KS.js";import{t as E}from"./badge-CcASMiB4.js";import{t as D}from"./format-time-D8VGlAcs.js";import{t as O}from"./SkillRelinkDialog-DEY3IqVA.js";var k=e(o(),1),A=n();function j({issue:e,action:n,retryCheck:i,retryUpdate:a,unlinkSkill:o,importAgentsSkills:s,removeScan:c,onRelink:l}){let u=e.assetName??``;switch(n){case`remove-scan`:return e.assetKind&&e.assetName?(0,A.jsx)(C,{loading:c.isPending,onClick:()=>c.mutate({kind:e.assetKind,name:e.assetName}),size:`sm`,type:`button`,variant:`secondary`,children:`Remove record`},n):null;case`retry-check`:return(0,A.jsx)(C,{loading:i.isPending&&i.variables===u,onClick:()=>i.mutate(u),size:`sm`,type:`button`,variant:`secondary`,children:`Retry check`},n);case`retry-update`:return(0,A.jsx)(C,{loading:a.isPending&&a.variables===u,onClick:()=>a.mutate(u),size:`sm`,type:`button`,variant:`secondary`,children:`Retry update`},n);case`relink`:return(0,A.jsx)(C,{onClick:()=>l(u),size:`sm`,type:`button`,variant:`secondary`,children:`Relink…`},n);case`unlink`:return(0,A.jsx)(C,{loading:o.isPending&&o.variables===u,onClick:()=>o.mutate(u),size:`sm`,type:`button`,variant:`ghost`,children:`Unlink`},n);case`open-asset`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/library?kind=${e.assetKind}&asset=${encodeURIComponent(u)}`,children:`Open in Library`},n);case`import-agents`:return(0,A.jsx)(C,{loading:s.isPending,onClick:()=>s.mutate(),size:`sm`,type:`button`,variant:`secondary`,children:`Import into Hub`},n);case`open-setup`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/setup`,children:`Open setup`},n);case`open-integrations`:return(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`})),to:`/integrations`,children:`Open backup settings`},n);default:return null}}function M({issues:e,title:t=`Issues`,...n}){return(0,A.jsxs)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:[(0,A.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border px-4 py-3`,children:[(0,A.jsx)(`h3`,{className:`text-sm font-semibold tracking-tight text-foreground`,children:t}),(0,A.jsx)(E,{variant:`warning`,children:e.length})]}),(0,A.jsx)(`ul`,{className:`grid items-start gap-3 p-4 sm:grid-cols-2 xl:grid-cols-3`,children:e.map(e=>(0,A.jsx)(`li`,{className:`h-full rounded-lg bg-muted/40 px-3 py-3`,children:(0,A.jsxs)(`div`,{className:`flex min-w-0 items-start gap-3`,children:[e.severity===`error`?(0,A.jsx)(p,{className:`mt-0.5 size-4 shrink-0 text-destructive`}):(0,A.jsx)(m,{className:`mt-0.5 size-4 shrink-0 text-warning-foreground`}),(0,A.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,A.jsx)(`p`,{className:`text-sm font-medium text-foreground`,children:e.title}),e.detail?(0,A.jsx)(`p`,{className:`mt-0.5 text-xs leading-5 text-muted-foreground`,children:e.detail}):null,e.actions.length>0?(0,A.jsx)(`div`,{className:`mt-2 flex flex-wrap gap-2`,children:e.actions.map(t=>(0,A.jsx)(j,{action:t,issue:e,...n},t))}):null]})]})},e.id))})]})}var N={structure:{icon:u,linkTo:`/setup`,linkLabel:`Open setup`},skills:{icon:c,linkTo:`/library`,linkLabel:`Open Library`},editors:{icon:d,linkTo:`/integrations`,linkLabel:`Open Integrations`},sync:{icon:l,linkTo:`/integrations`,linkLabel:`Open backup settings`},security:{icon:h,linkTo:`/library`,linkLabel:`Open Library`},ai:{icon:f,linkTo:`/settings`,linkLabel:`Open Settings`}},P={healthy:{variant:`success`,label:`Healthy`},warning:{variant:`warning`,label:`Warning`},error:{variant:`destructive`,label:`Error`},inactive:{variant:`default`,label:`Not set up`}};function F({subsystem:e}){let n=N[e.id],i=P[e.status],a=n.icon;return(0,A.jsxs)(`li`,{className:`flex items-start gap-3 px-4 py-3`,children:[(0,A.jsx)(a,{className:`mt-0.5 size-4 shrink-0 text-muted-foreground`,"aria-hidden":!0}),(0,A.jsxs)(`div`,{className:`grid min-w-0 flex-1 gap-1`,children:[(0,A.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,A.jsx)(`h3`,{className:`min-w-0 truncate text-sm font-semibold tracking-tight text-foreground`,children:e.label}),(0,A.jsx)(E,{variant:i.variant,children:i.label})]}),(0,A.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:e.summary}),(0,A.jsxs)(`dl`,{className:`flex flex-wrap gap-x-4 gap-y-0.5`,children:[e.metrics.map(e=>(0,A.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,A.jsx)(`dt`,{className:`text-2xs text-muted-foreground`,children:e.label}),(0,A.jsx)(`dd`,{className:`truncate text-xs font-medium tabular-nums text-foreground`,title:e.value,children:e.value})]},e.label)),e.lastActivityAt?(0,A.jsxs)(`div`,{className:`flex items-baseline gap-1.5`,children:[(0,A.jsx)(`dt`,{className:`text-2xs text-muted-foreground`,children:`Last activity`}),(0,A.jsx)(`dd`,{className:`truncate text-xs font-medium tabular-nums text-foreground`,title:new Date(e.lastActivityAt).toLocaleString(),children:D(e.lastActivityAt)})]}):null]})]}),(0,A.jsx)(r,{className:t(x({size:`sm`,variant:`secondary`}),`shrink-0 self-center`),to:n.linkTo,children:n.linkLabel})]})}function I(){let e=s(),[t,n]=(0,k.useState)(null),r=a({queryKey:b.health,queryFn:()=>T.get()});function o(){e.invalidateQueries({queryKey:b.health}),e.invalidateQueries({queryKey:b.overview}),e.invalidateQueries({queryKey:b.issues}),e.invalidateQueries({queryKey:b.library}),e.invalidateQueries({queryKey:b.skillUpdates})}let c=i({mutationFn:async()=>_.migrateAgentsSkills({}),onSuccess:e=>{let t=e.results.filter(e=>e.status===`migrated`).length,n=e.results.filter(e=>e.status===`skipped`).length,r=e.results.filter(e=>e.status===`failed`).length;o(),y.success(`Imported from ~/.agents: ${t} migrated, ${n} skipped, ${r} failed`)},onError:()=>{y.error(`Unable to import from ~/.agents/.skill-lock.json`)}}),l=i({mutationFn:async e=>_.checkSkillUpdates({name:e,force:!0}),onSuccess:(e,t)=>{o();let n=e.results.find(e=>e.name===t);n?.status===`failed`?y.warning(`Check still failing for ${t}: ${n.error??`unknown error`}`):y.success(n?.status===`update_available`?`Update available for ${t}`:`${t} is up to date`)},onError:e=>{y.error(g(e,`Unable to check skill`))}}),u=i({mutationFn:async e=>_.updateSkills({name:e}),onSuccess:(e,t)=>{o();let n=e.results.find(e=>e.name===t);n?.status===`failed`?y.warning(`Update still failing for ${t}: ${n.error??`unknown error`}`):y.success(n?.status===`updated`?`Updated ${t}`:`${t} is up to date`)},onError:e=>{y.error(g(e,`Unable to update skill`))}}),d=i({mutationFn:async e=>_.unlinkSkill(e),onSuccess:(e,t)=>{o(),y.success(`${t} is now a local, editable skill`)},onError:e=>{y.error(g(e,`Unable to unlink skill`))}}),f=i({mutationFn:async({kind:e,name:t})=>v.removeScan(e,t),onSuccess:(e,{kind:t,name:n})=>{o(),y.success(`Removed stale scan record for ${t}/${n}`)},onError:e=>{y.error(g(e,`Unable to remove scan record`))}});if(r.isLoading)return(0,A.jsx)(S,{variant:`dashboard`});if(r.isError||!r.data)return(0,A.jsx)(w,{description:`The health report is temporarily unavailable.`,title:`Unable to load health`});let p=r.data,m=P[p.status],h=p.subsystems.filter(e=>e.issues.length>0);return(0,A.jsxs)(`section`,{className:`mx-auto grid w-full max-w-5xl gap-8`,children:[(0,A.jsxs)(`header`,{className:`grid gap-2`,children:[(0,A.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,A.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Health`}),(0,A.jsx)(E,{variant:m.variant,children:m.label}),(0,A.jsx)(C,{"aria-label":`Re-check all subsystems`,className:`ml-auto`,loading:r.isFetching,onClick:()=>void r.refetch(),size:`sm`,type:`button`,variant:`secondary`,children:`Re-check`})]}),(0,A.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Status of every hub subsystem, grouped per area. Spot problems early and jump straight to where they are fixed.`})]}),(0,A.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:(0,A.jsx)(`ul`,{className:`divide-y divide-border`,children:p.subsystems.map(e=>(0,A.jsx)(F,{subsystem:e},e.id))})}),h.length===0?(0,A.jsx)(`p`,{className:`rounded-2xl border border-border bg-card px-4 py-6 text-center text-sm text-muted-foreground shadow-card`,children:`No open issues; every subsystem is in good shape.`}):h.map(e=>(0,A.jsx)(M,{importAgentsSkills:c,issues:e.issues,onRelink:n,removeScan:f,retryCheck:l,retryUpdate:u,title:`Open issues: ${e.label}`,unlinkSkill:d},e.id)),(0,A.jsx)(O,{onOpenChange:e=>{e||n(null)},skillName:t})]})}export{I as HealthPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,U as r,W as i,Z as a,q as o}from"./vendor-react-BgntYnUn.js";import{Q as s,X as c,st as l,u}from"./vendor-ui-qVCZmmA-.js";import{A as d,D as f,b as p,c as m,d as h,f as g,gt as _,h as v,l as y,m as b,o as x,p as S,pt as C,s as w,st as T,t as E,u as D}from"./index-ltESF1KS.js";import{t as O}from"./badge-CcASMiB4.js";import{t as k}from"./select-DJSrFTH0.js";import{n as A,t as j}from"./format-time-D8VGlAcs.js";var M=e(a(),1),N=n();function P({status:e}){let t=o(),[n,i]=(0,M.useState)({}),a=r({mutationFn:e=>f.resolve(e),onSuccess:e=>{t.invalidateQueries({queryKey:v.syncStatus}),_.success(`Merge finished and pushed`),e.conflicts.length>0&&_.info(`${e.conflicts.length} conflict(s) left`)},onError:e=>{_.error(d(e,`Unable to resolve conflicts`))}}),s=e.conflicts.filter(e=>!n[e.path]);return(0,N.jsxs)(`div`,{className:`grid gap-3 rounded-lg border border-border bg-background p-3`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(u,{"aria-hidden":`true`,className:`size-4 text-muted-foreground`}),(0,N.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:`The same files changed on two machines. Pick a version per file, or edit the files yourself and choose “I edited it”.`})]}),(0,N.jsx)(`ul`,{className:`grid gap-2`,children:e.conflicts.map(e=>{let t=n[e.path];return(0,N.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,N.jsx)(`code`,{className:`break-all font-mono text-xs text-foreground`,children:e.path}),(0,N.jsx)(`div`,{className:`flex items-center gap-1.5`,children:[`local`,`remote`,`manual`].map(n=>(0,N.jsx)(C,{onClick:()=>i(t=>({...t,[e.path]:n})),size:`sm`,type:`button`,variant:t===n?`secondary`:`ghost`,children:n===`local`?`Keep local`:n===`remote`?`Keep remote`:`I edited it`},n))})]},e.path)})}),(0,N.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,role:`status`,children:s.length>0?`${s.length} file(s) still need a choice`:`Ready to finish the merge`}),(0,N.jsx)(C,{loading:a.isPending,onClick:()=>a.mutate({resolutions:e.conflicts.map(e=>({path:e.path,strategy:n[e.path]??`local`}))}),disabled:s.length>0,size:`sm`,children:a.isPending?`Finishing…`:`Finish merge`})]})]})}function F({open:e,onOpenChange:t}){let n=o(),[i,a]=(0,M.useState)(`gh`),[s,c]=(0,M.useState)(``),[l,u]=(0,M.useState)(``),[p,b]=(0,M.useState)(null),x=r({mutationFn:e=>f.connect(e),onSuccess:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(e.conflicts.length>0?`Connected — resolve the listed conflicts to finish`:`Connected to ${e.remote?.repo??`GitHub`}`),t(!1)},onError:e=>{let t=d(e,`Unable to connect`);/adopt/i.test(t)?b(t):_.error(t)}}),E=(e=!1)=>{x.mutate({method:i,repo:s.trim()||void 0,token:i===`pat`?l.trim():void 0,adopt:e||void 0})};return(0,N.jsx)(w,{onOpenChange:t,open:e,children:(0,N.jsxs)(y,{className:`max-w-md`,children:[(0,N.jsxs)(g,{children:[(0,N.jsx)(S,{children:`Connect GitHub backup`}),(0,N.jsx)(D,{children:`Your hub syncs to a private GitHub repo. Secrets and logs never leave this machine.`})]}),(0,N.jsxs)(m,{className:`grid gap-4`,children:[(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsx)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-method`,children:`Sign in with`}),(0,N.jsxs)(k,{id:`sync-method`,onChange:e=>a(e.target.value),value:i,children:[(0,N.jsx)(`option`,{value:`gh`,children:`GitHub CLI (gh) — recommended`}),(0,N.jsx)(`option`,{value:`pat`,children:`Personal access token`})]})]}),i===`pat`?(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsx)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-token`,children:`Fine-grained access token`}),(0,N.jsx)(T,{autoComplete:`off`,id:`sync-token`,onChange:e=>u(e.target.value),placeholder:`github_pat_…`,type:`password`,value:l}),(0,N.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:`Needs Contents: read/write on the sync repo, plus Administration: write so Chain Hub can create it.`})]}):(0,N.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:"Uses the token `gh` already stores on this machine. Run `gh auth login` first if it isn’t signed in."}),(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsxs)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-repo`,children:[`Repo name `,(0,N.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:`(optional)`})]}),(0,N.jsx)(T,{id:`sync-repo`,onChange:e=>c(e.target.value),placeholder:`chain-hub-sync`,value:s})]}),p?(0,N.jsxs)(`div`,{className:`grid gap-2 rounded-lg border border-border bg-background p-3`,role:`alert`,children:[(0,N.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:p}),(0,N.jsx)(C,{loading:x.isPending,onClick:()=>E(!0),size:`sm`,type:`button`,variant:`secondary`,children:`Take over this repo`})]}):null]}),(0,N.jsxs)(h,{children:[(0,N.jsx)(C,{onClick:()=>t(!1),type:`button`,variant:`ghost`,children:`Cancel`}),(0,N.jsx)(C,{disabled:i===`pat`&&!l.trim(),loading:x.isPending,onClick:()=>E(),type:`button`,children:x.isPending?`Connecting…`:`Connect`})]})]})})}function I(){let[e,t]=(0,M.useState)(!1),n=o(),i=b(),a=r({mutationFn:()=>f.now(),onSuccess:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(e.conflicts.length>0?`Merge conflict — pick a version per file below`:`Hub synced to GitHub`)},onError:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.error(d(e,`Sync failed`))}}),u=r({mutationFn:()=>f.disconnect(),onSuccess:()=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(`Disconnected — local files and history were kept`)},onError:e=>{_.error(d(e,`Unable to disconnect`))}}),p=i.data,m=(p?.conflicts.length??0)>0;return(0,N.jsxs)(`section`,{className:`grid gap-4`,"aria-labelledby":`cloud-backup-heading`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,id:`cloud-backup-heading`,children:`Cloud backup`}),p?.connected?(0,N.jsxs)(O,{className:`gap-1`,variant:`success`,children:[(0,N.jsx)(l,{"aria-hidden":`true`,className:`size-3`}),`Connected`]}):(0,N.jsx)(O,{variant:`default`,children:`Not connected`})]}),(0,N.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Back up skills, agents, workflows, rules and prompts to a private GitHub repo, and restore them on another machine.`}),(0,N.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card p-4 shadow-card`,children:i.isLoading?null:p?.connected?(0,N.jsxs)(`div`,{className:`grid gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,N.jsxs)(`div`,{className:`grid min-w-0 gap-1`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,N.jsx)(c,{"aria-hidden":`true`,className:`size-4 text-muted-foreground`}),(0,N.jsx)(`code`,{className:`break-all font-mono text-sm text-foreground`,children:p.remote?.repo})]}),(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,title:p.lastSyncAt?A(p.lastSyncAt):void 0,children:[`Last sync: `,j(p.lastSyncAt),p.authMethod?`, via ${p.authMethod===`gh`?`GitHub CLI`:`token`}`:``,p.autoSync?`, auto-sync on`:`, auto-sync off`]}),p.lastSyncError?(0,N.jsx)(`p`,{className:`text-xs text-destructive`,role:`alert`,children:p.lastSyncError}):null]}),(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p.uncommitted+p.ahead+p.behind>0?(0,N.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[p.uncommitted>0?(0,N.jsxs)(O,{variant:`warning`,children:[p.uncommitted,` unsynced`]}):null,p.ahead>0?(0,N.jsxs)(O,{variant:`warning`,children:[`↑ `,p.ahead]}):null,p.behind>0?(0,N.jsxs)(O,{variant:`warning`,children:[`↓ `,p.behind]}):null]}):null,(0,N.jsx)(C,{className:`whitespace-nowrap`,loading:a.isPending,onClick:()=>a.mutate(),size:`sm`,variant:m?`secondary`:`default`,children:a.isPending?`Syncing…`:`Sync now`}),(0,N.jsx)(C,{loading:u.isPending,onClick:()=>u.mutate(),size:`sm`,variant:`ghost`,children:`Disconnect`})]})]}),m?(0,N.jsx)(P,{status:p}):null]}):(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,N.jsx)(s,{"aria-hidden":`true`,className:`size-5 text-muted-foreground`}),(0,N.jsx)(`p`,{className:`text-sm leading-5 text-muted-foreground`,children:`No backup configured. Connect GitHub to start syncing.`})]}),(0,N.jsx)(C,{onClick:()=>t(!0),size:`sm`,children:`Connect GitHub`})]})}),(0,N.jsx)(F,{onOpenChange:t,open:e})]})}function L(){let e=o(),n=i({queryKey:[`integrations`],queryFn:()=>p.getAll()}),a=r({mutationFn:async()=>p.setup(),onSuccess:()=>{e.invalidateQueries({queryKey:[`integrations`]}),e.invalidateQueries({queryKey:[`setup`]}),_.success(`Editors connected`)},onError:()=>{_.error(`Unable to setup integrations`)}});if(n.isLoading)return(0,N.jsx)(x,{variant:`checklist`});if(n.isError)return(0,N.jsx)(E,{description:`Integration status is temporarily unavailable.`,title:`Unable to load integrations`});if(!n.data)return(0,N.jsx)(E,{description:`There is no integration data to show yet.`,title:`Integrations unavailable`});let s=n.data.filter(e=>e.installed),c=s.filter(e=>e.connected).length;return(0,N.jsxs)(`section`,{className:`mx-auto grid w-full max-w-3xl gap-8`,children:[(0,N.jsxs)(`header`,{className:`flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between`,children:[(0,N.jsxs)(`div`,{className:`grid gap-2`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Linked editors`}),(0,N.jsxs)(O,{variant:`default`,children:[c,`/`,s.length]})]}),(0,N.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Link each supported editor on this machine to the hub so they all stay in sync.`})]}),(0,N.jsx)(C,{className:`w-fit shrink-0`,loading:a.isPending,onClick:()=>a.mutate(),children:a.isPending?`Connecting…`:`Connect editors`})]}),(0,N.jsx)(`ul`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:n.data.map(e=>(0,N.jsx)(`li`,{className:t(`grid gap-3 border-b border-border p-4 last:border-b-0`,`sm:grid-cols-[minmax(0,1fr)_auto] sm:items-start`),children:(0,N.jsxs)(`div`,{className:`grid min-w-0 gap-2`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:e.label}),e.installed?e.connected?(0,N.jsxs)(O,{className:t(`gap-1`,a.isSuccess&&`animate-[icon-in_200ms_ease-out]`),variant:`success`,children:[(0,N.jsx)(l,{"aria-hidden":`true`,className:`size-3`}),`Connected`]}):(0,N.jsx)(O,{className:t(a.isPending&&`animate-pulse`),variant:`warning`,children:`Not connected`}):(0,N.jsx)(O,{variant:`default`,children:`Not installed`})]}),(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Mode: `,e.mode]}),(0,N.jsx)(`div`,{className:`grid gap-1`,children:e.targetPaths.map(e=>(0,N.jsx)(`code`,{className:`break-all font-mono text-xs text-muted-foreground`,children:e},e))}),(0,N.jsxs)(`div`,{className:`flex flex-wrap gap-1.5 pt-1`,children:[e.supportedKinds.map(e=>(0,N.jsx)(O,{variant:`accent`,children:e},e)),e.unsupportedKinds.map(e=>(0,N.jsxs)(O,{className:`opacity-60 line-through`,variant:`default`,children:[e,(0,N.jsx)(`span`,{className:`sr-only`,children:` (not supported by this editor)`})]},e))]})]})},e.id))}),(0,N.jsx)(I,{})]})}export{L as IntegrationsPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,U as r,W as i,Z as a,q as o}from"./vendor-react-BgntYnUn.js";import{Q as s,X as c,st as l,u}from"./vendor-ui-qVCZmmA-.js";import{A as d,D as f,b as p,c as m,d as h,f as g,gt as _,h as v,l as y,m as b,o as x,p as S,pt as C,s as w,st as T,t as E,u as D}from"./index-ommOzjM4.js";import{t as O}from"./badge-C2BSIZMN.js";import{t as k}from"./select-DJSrFTH0.js";import{n as A,t as j}from"./format-time-D8VGlAcs.js";var M=e(a(),1),N=n();function P({status:e}){let t=o(),[n,i]=(0,M.useState)({}),a=r({mutationFn:e=>f.resolve(e),onSuccess:e=>{t.invalidateQueries({queryKey:v.syncStatus}),_.success(`Merge finished and pushed`),e.conflicts.length>0&&_.info(`${e.conflicts.length} conflict(s) left`)},onError:e=>{_.error(d(e,`Unable to resolve conflicts`))}}),s=e.conflicts.filter(e=>!n[e.path]);return(0,N.jsxs)(`div`,{className:`grid gap-3 rounded-lg border border-border bg-background p-3`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(u,{"aria-hidden":`true`,className:`size-4 text-muted-foreground`}),(0,N.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:`The same files changed on two machines. Pick a version per file, or edit the files yourself and choose “I edited it”.`})]}),(0,N.jsx)(`ul`,{className:`grid gap-2`,children:e.conflicts.map(e=>{let t=n[e.path];return(0,N.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,N.jsx)(`code`,{className:`break-all font-mono text-xs text-foreground`,children:e.path}),(0,N.jsx)(`div`,{className:`flex items-center gap-1.5`,children:[`local`,`remote`,`manual`].map(n=>(0,N.jsx)(C,{onClick:()=>i(t=>({...t,[e.path]:n})),size:`sm`,type:`button`,variant:t===n?`secondary`:`ghost`,children:n===`local`?`Keep local`:n===`remote`?`Keep remote`:`I edited it`},n))})]},e.path)})}),(0,N.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,role:`status`,children:s.length>0?`${s.length} file(s) still need a choice`:`Ready to finish the merge`}),(0,N.jsx)(C,{loading:a.isPending,onClick:()=>a.mutate({resolutions:e.conflicts.map(e=>({path:e.path,strategy:n[e.path]??`local`}))}),disabled:s.length>0,size:`sm`,children:a.isPending?`Finishing…`:`Finish merge`})]})]})}function F({open:e,onOpenChange:t}){let n=o(),[i,a]=(0,M.useState)(`gh`),[s,c]=(0,M.useState)(``),[l,u]=(0,M.useState)(``),[p,b]=(0,M.useState)(null),x=r({mutationFn:e=>f.connect(e),onSuccess:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(e.conflicts.length>0?`Connected — resolve the listed conflicts to finish`:`Connected to ${e.remote?.repo??`GitHub`}`),t(!1)},onError:e=>{let t=d(e,`Unable to connect`);/adopt/i.test(t)?b(t):_.error(t)}}),E=(e=!1)=>{x.mutate({method:i,repo:s.trim()||void 0,token:i===`pat`?l.trim():void 0,adopt:e||void 0})};return(0,N.jsx)(w,{onOpenChange:t,open:e,children:(0,N.jsxs)(y,{className:`max-w-md`,children:[(0,N.jsxs)(g,{children:[(0,N.jsx)(S,{children:`Connect GitHub backup`}),(0,N.jsx)(D,{children:`Your hub syncs to a private GitHub repo. Secrets and logs never leave this machine.`})]}),(0,N.jsxs)(m,{className:`grid gap-4`,children:[(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsx)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-method`,children:`Sign in with`}),(0,N.jsxs)(k,{id:`sync-method`,onChange:e=>a(e.target.value),value:i,children:[(0,N.jsx)(`option`,{value:`gh`,children:`GitHub CLI (gh) — recommended`}),(0,N.jsx)(`option`,{value:`pat`,children:`Personal access token`})]})]}),i===`pat`?(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsx)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-token`,children:`Fine-grained access token`}),(0,N.jsx)(T,{autoComplete:`off`,id:`sync-token`,onChange:e=>u(e.target.value),placeholder:`github_pat_…`,type:`password`,value:l}),(0,N.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:`Needs Contents: read/write on the sync repo, plus Administration: write so Chain Hub can create it.`})]}):(0,N.jsx)(`p`,{className:`text-xs leading-5 text-muted-foreground`,children:"Uses the token `gh` already stores on this machine. Run `gh auth login` first if it isn’t signed in."}),(0,N.jsxs)(`div`,{className:`grid gap-1.5`,children:[(0,N.jsxs)(`label`,{className:`text-sm font-medium text-foreground`,htmlFor:`sync-repo`,children:[`Repo name `,(0,N.jsx)(`span`,{className:`font-normal text-muted-foreground`,children:`(optional)`})]}),(0,N.jsx)(T,{id:`sync-repo`,onChange:e=>c(e.target.value),placeholder:`chain-hub-sync`,value:s})]}),p?(0,N.jsxs)(`div`,{className:`grid gap-2 rounded-lg border border-border bg-background p-3`,role:`alert`,children:[(0,N.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:p}),(0,N.jsx)(C,{loading:x.isPending,onClick:()=>E(!0),size:`sm`,type:`button`,variant:`secondary`,children:`Take over this repo`})]}):null]}),(0,N.jsxs)(h,{children:[(0,N.jsx)(C,{onClick:()=>t(!1),type:`button`,variant:`ghost`,children:`Cancel`}),(0,N.jsx)(C,{disabled:i===`pat`&&!l.trim(),loading:x.isPending,onClick:()=>E(),type:`button`,children:x.isPending?`Connecting…`:`Connect`})]})]})})}function I(){let[e,t]=(0,M.useState)(!1),n=o(),i=b(),a=r({mutationFn:()=>f.now(),onSuccess:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(e.conflicts.length>0?`Merge conflict — pick a version per file below`:`Hub synced to GitHub`)},onError:e=>{n.invalidateQueries({queryKey:v.syncStatus}),_.error(d(e,`Sync failed`))}}),u=r({mutationFn:()=>f.disconnect(),onSuccess:()=>{n.invalidateQueries({queryKey:v.syncStatus}),_.success(`Disconnected — local files and history were kept`)},onError:e=>{_.error(d(e,`Unable to disconnect`))}}),p=i.data,m=(p?.conflicts.length??0)>0;return(0,N.jsxs)(`section`,{className:`grid gap-4`,"aria-labelledby":`cloud-backup-heading`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,id:`cloud-backup-heading`,children:`Cloud backup`}),p?.connected?(0,N.jsxs)(O,{className:`gap-1`,variant:`success`,children:[(0,N.jsx)(l,{"aria-hidden":`true`,className:`size-3`}),`Connected`]}):(0,N.jsx)(O,{variant:`default`,children:`Not connected`})]}),(0,N.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Back up skills, agents, workflows, rules and prompts to a private GitHub repo, and restore them on another machine.`}),(0,N.jsx)(`div`,{className:`overflow-hidden rounded-2xl border border-border bg-card p-4 shadow-card`,children:i.isLoading?null:p?.connected?(0,N.jsxs)(`div`,{className:`grid gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,N.jsxs)(`div`,{className:`grid min-w-0 gap-1`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,N.jsx)(c,{"aria-hidden":`true`,className:`size-4 text-muted-foreground`}),(0,N.jsx)(`code`,{className:`break-all font-mono text-sm text-foreground`,children:p.remote?.repo})]}),(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,title:p.lastSyncAt?A(p.lastSyncAt):void 0,children:[`Last sync: `,j(p.lastSyncAt),p.authMethod?`, via ${p.authMethod===`gh`?`GitHub CLI`:`token`}`:``,p.autoSync?`, auto-sync on`:`, auto-sync off`]}),p.lastSyncError?(0,N.jsx)(`p`,{className:`text-xs text-destructive`,role:`alert`,children:p.lastSyncError}):null]}),(0,N.jsxs)(`div`,{className:`flex items-center gap-2`,children:[p.uncommitted+p.ahead+p.behind>0?(0,N.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[p.uncommitted>0?(0,N.jsxs)(O,{variant:`warning`,children:[p.uncommitted,` unsynced`]}):null,p.ahead>0?(0,N.jsxs)(O,{variant:`warning`,children:[`↑ `,p.ahead]}):null,p.behind>0?(0,N.jsxs)(O,{variant:`warning`,children:[`↓ `,p.behind]}):null]}):null,(0,N.jsx)(C,{className:`whitespace-nowrap`,loading:a.isPending,onClick:()=>a.mutate(),size:`sm`,variant:m?`secondary`:`default`,children:a.isPending?`Syncing…`:`Sync now`}),(0,N.jsx)(C,{loading:u.isPending,onClick:()=>u.mutate(),size:`sm`,variant:`ghost`,children:`Disconnect`})]})]}),m?(0,N.jsx)(P,{status:p}):null]}):(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,N.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,N.jsx)(s,{"aria-hidden":`true`,className:`size-5 text-muted-foreground`}),(0,N.jsx)(`p`,{className:`text-sm leading-5 text-muted-foreground`,children:`No backup configured. Connect GitHub to start syncing.`})]}),(0,N.jsx)(C,{onClick:()=>t(!0),size:`sm`,children:`Connect GitHub`})]})}),(0,N.jsx)(F,{onOpenChange:t,open:e})]})}function L(){let e=o(),n=i({queryKey:[`integrations`],queryFn:()=>p.getAll()}),a=r({mutationFn:async()=>p.setup(),onSuccess:()=>{e.invalidateQueries({queryKey:[`integrations`]}),e.invalidateQueries({queryKey:[`setup`]}),_.success(`Editors connected`)},onError:()=>{_.error(`Unable to setup integrations`)}});if(n.isLoading)return(0,N.jsx)(x,{variant:`checklist`});if(n.isError)return(0,N.jsx)(E,{description:`Integration status is temporarily unavailable.`,title:`Unable to load integrations`});if(!n.data)return(0,N.jsx)(E,{description:`There is no integration data to show yet.`,title:`Integrations unavailable`});let s=n.data.filter(e=>e.installed),c=s.filter(e=>e.connected).length;return(0,N.jsxs)(`section`,{className:`mx-auto grid w-full max-w-3xl gap-8`,children:[(0,N.jsxs)(`header`,{className:`flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between`,children:[(0,N.jsxs)(`div`,{className:`grid gap-2`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Linked editors`}),(0,N.jsxs)(O,{variant:`default`,children:[c,`/`,s.length]})]}),(0,N.jsx)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:`Link each supported editor on this machine to the hub so they all stay in sync.`})]}),(0,N.jsx)(C,{className:`w-fit shrink-0`,loading:a.isPending,onClick:()=>a.mutate(),children:a.isPending?`Connecting…`:`Connect editors`})]}),(0,N.jsx)(`ul`,{className:`overflow-hidden rounded-2xl border border-border bg-card shadow-card`,children:n.data.map(e=>(0,N.jsx)(`li`,{className:t(`grid gap-3 border-b border-border p-4 last:border-b-0`,`sm:grid-cols-[minmax(0,1fr)_auto] sm:items-start`),children:(0,N.jsxs)(`div`,{className:`grid min-w-0 gap-2`,children:[(0,N.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,N.jsx)(`h3`,{className:`text-sm font-medium text-foreground`,children:e.label}),e.installed?e.connected?(0,N.jsxs)(O,{className:t(`gap-1`,a.isSuccess&&`animate-[icon-in_200ms_ease-out]`),variant:`success`,children:[(0,N.jsx)(l,{"aria-hidden":`true`,className:`size-3`}),`Connected`]}):(0,N.jsx)(O,{className:t(a.isPending&&`animate-pulse`),variant:`warning`,children:`Not connected`}):(0,N.jsx)(O,{variant:`default`,children:`Not installed`})]}),(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Mode: `,e.mode]}),(0,N.jsx)(`div`,{className:`grid gap-1`,children:e.targetPaths.map(e=>(0,N.jsx)(`code`,{className:`break-all font-mono text-xs text-muted-foreground`,children:e},e))}),(0,N.jsxs)(`div`,{className:`flex flex-wrap gap-1.5 pt-1`,children:[e.supportedKinds.map(e=>(0,N.jsx)(O,{variant:`accent`,children:e},e)),e.unsupportedKinds.map(e=>(0,N.jsxs)(O,{className:`opacity-60 line-through`,variant:`default`,children:[e,(0,N.jsx)(`span`,{className:`sr-only`,children:` (not supported by this editor)`})]},e))]})]})},e.id))}),(0,N.jsx)(I,{})]})}export{L as IntegrationsPage};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,M as r,U as i,W as a,Z as o,q as s}from"./vendor-react-BgntYnUn.js";import{it as c,ot as l}from"./vendor-ui-qVCZmmA-.js";import{A as u,C as d,S as f,a as p,c as m,ct as h,d as g,dt as _,f as v,gt as y,h as b,i as x,l as S,lt as C,mt as w,n as T,o as E,p as D,pt as O,r as k,s as A,st as j,t as M,u as N,ut as P}from"./index-ommOzjM4.js";import{n as F,t as I}from"./badge-C2BSIZMN.js";import{t as L}from"./select-DJSrFTH0.js";import{n as R,t as z}from"./libesm-CHGPMFhL.js";var B=e(o(),1);function V(e,t){let n=(e,t)=>(t.type===`correction`||t.type===`failure`)&&(!e.resolvedAt||t.capturedAt>e.resolvedAt);return e.filter(e=>e.openCorrectionCount+e.openFailureCount>0).map(e=>({skill:e.skill,correctionCount:e.openCorrectionCount,failureCount:e.openFailureCount,latestIssue:e.recentEvents.find(t=>n(e,t))??null,inHub:t.has(e.skill)})).sort((e,t)=>t.correctionCount+t.failureCount-(e.correctionCount+e.failureCount)||e.skill.localeCompare(t.skill))}function H(e,t){let n=new URLSearchParams({kind:`skills`,asset:e});return t?.audit&&n.set(`audit`,`1`),`/library?${n.toString()}`}function U(e){return e.openCorrectionCount+e.openFailureCount+e.openNoteCount}function W(e){return{open:e.filter(e=>U(e)>0).sort((e,t)=>U(t)-U(e)||t.lastSeen.localeCompare(e.lastSeen)),quiet:e.filter(e=>U(e)===0)}}var G=new Set([`correction`,`failure`,`note`]);function K(e,t){return e.filter(e=>e.skill===t.skill&&G.has(e.type)&&(!t.resolvedAt||e.capturedAt>t.resolvedAt))}function q(e,t){let n=new URLSearchParams({create:`1`,kind:`skills`,name:e});if(t.length>0){let r=t.map(e=>`- [${e.type}] ${e.summary}`).join(`
|
|
2
|
+
`);n.set(`intent`,`New skill "${e}" distilled from these captured field reports:\n${r}`)}return`/library?${n.toString()}`}var J=[`success`,`failure`,`correction`,`note`],Y={improving:{label:`↑ improving`,variant:`success`,description:`More successes than corrections and failures captured. No action needed.`},struggling:{label:`↓ struggling`,variant:`destructive`,description:`More corrections and failures than successes. Audit the skill to fold the field reports in.`},stable:{label:`→ stable`,variant:`default`,description:`Successes and corrections/failures are in balance. No action needed.`},new:{label:`★ new`,variant:`accent`,description:`Only one event captured so far, so there is no trend yet.`},collecting:{label:`• collecting`,variant:`default`,description:`Only notes captured so far. They feed the next audit as field reports.`}};function X(e){let t=[];return e.correctionCount>0&&t.push(`${e.correctionCount} correction${e.correctionCount===1?``:`s`}`),e.failureCount>0&&t.push(`${e.failureCount} failure${e.failureCount===1?``:`s`}`),e.noteCount&&t.push(`${e.noteCount} note${e.noteCount===1?``:`s`}`),t.join(` · `)}var Z=n(),Q=8,ee={applied:`accent`,"reviewed-clean":`success`,"upstream-proposal":`warning`,"to-source":`warning`,"findings-only":`warning`,orphan:`default`,failed:`destructive`};function te(){let[e,n]=(0,B.useState)(null),[r,i]=(0,B.useState)(!1),o=a({queryKey:b.learningsFolds,queryFn:()=>f.getFolds()}),s=a({queryKey:[...b.learningsFolds,e?.date,e?.skill],queryFn:()=>f.getFold(e.date,e.skill),enabled:e!==null}),c=o.data??[];if(o.isLoading||c.length===0)return null;let u=c.length>Q,d=r?c:c.slice(0,Q);return(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsx)(p,{children:`Fold history`}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Audit trail of applied folds — findings, folded reports and before/after per skill. Read-only; revert by copying the Before block back into the skill.`})]})}),(0,Z.jsx)(k,{children:(0,Z.jsxs)(`div`,{className:`grid gap-2`,children:[(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:d.map(e=>(0,Z.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border px-3 py-2`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:ee[e.outcome]??`default`,children:e.outcome}),(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.date}),e.writtenTo?(0,Z.jsxs)(`span`,{className:`truncate text-xs text-muted-foreground`,children:[`→ `,e.writtenTo]}):null]}),(0,Z.jsx)(O,{onClick:()=>n(e),size:`sm`,variant:`ghost`,children:`View`})]},`${e.date}/${e.skill}`))}),u?(0,Z.jsxs)(O,{"aria-expanded":r,className:`w-full`,onClick:()=>i(e=>!e),size:`sm`,variant:`ghost`,children:[r?`Show fewer`:`Show all ${c.length} folds`,(0,Z.jsx)(l,{"aria-hidden":`true`,className:t(`size-3.5 transition-transform`,r?`rotate-180`:``)})]}):null]})}),(0,Z.jsx)(A,{onOpenChange:e=>!e&&n(null),open:e!==null,children:(0,Z.jsxs)(S,{className:`max-w-3xl`,children:[(0,Z.jsxs)(v,{children:[(0,Z.jsxs)(D,{children:[e?.skill,` · `,e?.date]}),(0,Z.jsx)(N,{children:`Fold artifact, read-only review.`})]}),(0,Z.jsx)(m,{children:s.isLoading?(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Loading…`}):s.isError?(0,Z.jsx)(`p`,{className:`text-sm text-destructive-foreground`,children:`Unable to load the artifact.`}):(0,Z.jsx)(`pre`,{className:`max-h-[60vh] overflow-y-auto rounded-xl border border-border bg-muted/40 p-3 font-mono text-xs leading-5 whitespace-pre-wrap`,children:s.data?.content})})]})})]})}var ne={applied:{label:`Will be rewritten`,variant:`accent`,hint:`Apply writes the proposed SKILL.md in place.`},"reviewed-clean":{label:`Nothing actionable`,variant:`success`,hint:`Audit reviewed the reports; applying marks them addressed.`},"upstream-proposal":{label:`Upstream-locked`,variant:`warning`,hint:`Apply records the rewrite as a proposal under memory/learnings/folds.`},"to-source":{label:`Writes to source`,variant:`warning`,hint:`Apply writes back into the upstream path source.`},"findings-only":{label:`Too large to rewrite`,variant:`warning`,hint:`Skill exceeds the AI improve limit; findings are kept as an artifact.`},orphan:{label:`Not in your hub`,variant:`default`,hint:`No skill exists for this slug — reports can only be marked addressed.`},failed:{label:`Failed`,variant:`destructive`,hint:``}};function re({before:e,after:n}){let r=z(e,n);return r.some(e=>e.added||e.removed)?(0,Z.jsx)(`pre`,{className:`max-h-72 overflow-y-auto rounded-xl border border-border bg-muted/40 p-3 font-mono text-xs leading-5 whitespace-pre-wrap`,children:r.map((e,n)=>(0,Z.jsx)(`span`,{className:t(`block`,e.added&&`bg-success/10 text-success-foreground`,e.removed&&`bg-destructive/10 text-destructive-foreground line-through`),children:e.value},n))}):(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No changes; the AI returned the same content.`})}function ie({item:e,done:t,applying:n,onApply:r,onMarkAddressed:i}){let[a,o]=(0,B.useState)(!1),s=ne[e.outcome],u=!t&&e.outcome!==`orphan`&&e.outcome!==`failed`,d=!!(e.currentContent&&e.proposedContent);return(0,Z.jsxs)(`li`,{className:`grid gap-2 rounded-lg border border-border px-3 py-2.5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:s.variant,children:s.label}),e.findingCount>0?(0,Z.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.findingCount,` finding`,e.findingCount===1?``:`s`]}):null]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[d?(0,Z.jsxs)(O,{"aria-expanded":a,onClick:()=>o(e=>!e),size:`sm`,variant:`ghost`,children:[a?(0,Z.jsx)(l,{"aria-hidden":!0}):(0,Z.jsx)(c,{"aria-hidden":!0}),`Diff`]}):null,e.outcome===`orphan`&&!t?(0,Z.jsx)(O,{disabled:n,onClick:()=>i(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`}):null,u?(0,Z.jsx)(O,{disabled:n,onClick:()=>r(e.skill),size:`sm`,variant:`secondary`,children:`Apply`}):null,t?(0,Z.jsx)(`span`,{className:`text-xs font-medium text-success-foreground`,children:`Done`}):null]})]}),s.hint&&!t?(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:s.hint}):null,e.error?(0,Z.jsx)(`p`,{className:`text-xs text-destructive-foreground`,children:e.error}):null,e.findings.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-0.5`,children:e.findings.map((e,t)=>(0,Z.jsxs)(`li`,{className:`text-xs leading-5 text-muted-foreground`,children:[(0,Z.jsxs)(`span`,{className:`font-mono text-2xs text-foreground`,children:[`[`,e.severity,`]`]}),` `,e.title,`: `,e.detail]},t))}):null,a&&d?(0,Z.jsx)(re,{after:e.proposedContent,before:e.currentContent}):null]})}function ae({open:e,onOpenChange:t,preview:n,doneSkills:r,applying:i,onApplySkill:a,onApplyAll:o,onMarkAddressed:s}){let c=(n?.results??[]).filter(e=>!r.has(e.skill)).filter(e=>e.outcome!==`orphan`&&e.outcome!==`failed`);return(0,Z.jsx)(A,{onOpenChange:t,open:e,children:(0,Z.jsxs)(S,{className:`max-w-3xl`,children:[(0,Z.jsxs)(v,{children:[(0,Z.jsx)(D,{children:`Fold field reports into skills`}),(0,Z.jsx)(N,{children:`Dry-run preview; nothing is written yet. Apply rewrites the skill, records a fold artifact under memory/learnings/folds, and marks the reports addressed.`})]}),(0,Z.jsx)(m,{children:n&&n.results.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:n.results.map(e=>(0,Z.jsx)(ie,{applying:i,done:r.has(e.skill),item:e,onApply:a,onMarkAddressed:s},e.skill))}):(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No open field reports; nothing to fold.`})}),(0,Z.jsxs)(g,{children:[(0,Z.jsx)(O,{onClick:()=>t(!1),variant:`secondary`,children:`Close`}),(0,Z.jsxs)(O,{disabled:c.length===0||i,loading:i,onClick:o,children:[`Apply all (`,c.length,`)`]})]})]})})}function oe(e){let t=new Map;for(let n of e.results)t.set(n.outcome,(t.get(n.outcome)??0)+1);let n=[];return t.get(`applied`)&&n.push(`${t.get(`applied`)} improved`),t.get(`reviewed-clean`)&&n.push(`${t.get(`reviewed-clean`)} reviewed clean`),t.get(`upstream-proposal`)&&n.push(`${t.get(`upstream-proposal`)} proposal artifact`),t.get(`to-source`)&&n.push(`${t.get(`to-source`)} written to source`),t.get(`findings-only`)&&n.push(`${t.get(`findings-only`)} findings-only`),t.get(`orphan`)&&n.push(`${t.get(`orphan`)} not in hub`),t.get(`failed`)&&n.push(`${t.get(`failed`)} failed`),n.join(` · `)}function se(){let e=s();return{preview:i({mutationFn:()=>f.fold({dryRun:!0}),onError:e=>{y.error(u(e,`Unable to preview the fold`))}}),apply:i({mutationFn:(e={})=>f.fold({...e,dryRun:!1}),onSuccess:t=>{e.invalidateQueries({queryKey:b.learningsReflect}),e.invalidateQueries({queryKey:b.library}),t.results.length===0?y.success(`Nothing to fold — no open field reports`):t.results.every(e=>e.outcome===`failed`)?y.error(t.results[0]?.error??`Fold failed`):y.success(`Fold done · ${oe(t)}`)},onError:e=>{y.error(u(e,`Unable to fold learnings`))}})}}function $(){let e=s();return i({mutationFn:e=>f.resolveSkill({skill:e}),onSuccess:()=>{e.invalidateQueries({queryKey:b.learningsReflect}),y.success(`Marked as addressed`)},onError:e=>{y.error(u(e,`Unable to mark as addressed`))}})}function ce({items:e}){let t=$(),n=se(),[i,a]=(0,B.useState)(!1),[o,s]=(0,B.useState)(null),[c,l]=(0,B.useState)(new Set);return(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsx)(p,{children:`Needs attention`}),(0,Z.jsx)(O,{loading:n.preview.isPending,onClick:()=>{n.preview.mutate(void 0,{onSuccess:e=>{s(e),l(new Set),a(!0)}})},size:`sm`,variant:`secondary`,children:`Fold into skills`})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Fold into skills previews the audit findings and proposed rewrite per skill before anything is written; apply folds the reports into the skill itself. Marking addressed clears the reports without changes.`})]})}),(0,Z.jsx)(k,{children:(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:e.map(e=>(0,Z.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border px-3 py-2`,children:[(0,Z.jsxs)(`div`,{className:`grid min-w-0 gap-0.5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:`warning`,children:X(e)})]}),e.latestIssue?(0,Z.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:e.latestIssue.summary}):null]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[e.inHub?(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:H(e.skill,{audit:!0}),children:`Audit skill`}):(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Not in your hub`}),(0,Z.jsx)(O,{disabled:t.isPending,loading:t.isPending&&t.variables===e.skill,onClick:()=>t.mutate(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`})]})]},e.skill))})}),(0,Z.jsx)(ae,{applying:n.apply.isPending,doneSkills:c,onApplyAll:()=>{n.apply.mutate({},{onSuccess:()=>a(!1)})},onApplySkill:e=>{n.apply.mutate({skill:e},{onSuccess:()=>l(t=>new Set(t).add(e))})},onMarkAddressed:e=>{t.mutate(e,{onSuccess:()=>l(t=>new Set(t).add(e))})},onOpenChange:a,open:i,preview:o})]})}function le({open:e,quiet:n,hubSkills:r,activeSkill:i,onSelect:a}){let[o,s]=(0,B.useState)(!1),c=o||e.length===0,u=e=>{let n=U(e),o=e.skill===i,s=r.has(e.skill);return(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{"aria-current":o||void 0,className:t(`flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm transition-colors`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset`,o?`bg-muted font-medium text-foreground`:`text-muted-foreground hover:bg-muted/50 hover:text-foreground`),onClick:()=>a(e.skill),type:`button`,children:[(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.skill}),s?null:(0,Z.jsx)(I,{variant:`default`,children:`no skill`}),n>0?(0,Z.jsxs)(I,{variant:`warning`,children:[n,` open`]}):null]})},e.skill)};return(0,Z.jsx)(`div`,{className:`max-h-[70vh] overflow-y-auto rounded-2xl border border-border bg-card shadow-card`,children:(0,Z.jsxs)(`ul`,{className:`divide-y divide-border`,children:[e.length>0?(0,Z.jsxs)(`li`,{className:`sticky top-0 z-10 bg-card px-3 py-2 text-xs font-medium text-muted-foreground`,children:[`Open reports · `,e.length]}):null,e.map(u),n.length>0?(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{"aria-expanded":c,className:t(`flex w-full items-center justify-between gap-2 bg-card px-3 py-2 text-left text-xs font-medium transition-colors`,`text-muted-foreground hover:text-foreground`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset`,c?`sticky top-0 z-10`:``),onClick:()=>s(e=>!e),type:`button`,children:[`Quiet · `,n.length,(0,Z.jsx)(l,{"aria-hidden":`true`,className:t(`size-3.5 transition-transform`,c?`rotate-180`:``)})]})}):null,c?n.map(u):null]})})}function ue({skill:e,inHub:n,openReports:i}){let a=$(),o=Y[e.trend],s=e.openCorrectionCount+e.openFailureCount+e.openNoteCount>0,c=X({correctionCount:e.openCorrectionCount,failureCount:e.openFailureCount,noteCount:e.openNoteCount}),l=n?`${c} open. The next audit folds them into the skill, or mark them addressed once handled.`:`${c} open, but no skill named "${e.skill}" exists in the hub. Create it to fold the reports in, or mark them addressed.`;return(0,Z.jsxs)(T,{children:[(0,Z.jsxs)(x,{children:[(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsx)(p,{children:e.skill}),(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e.totalEvents,` event`,e.totalEvents===1?``:`s`,`: `,e.successCount,` success,`,` `,e.failureCount,` failure, `,e.correctionCount,` correction, `,e.noteCount,` note`]})]}),(0,Z.jsx)(P,{children:(0,Z.jsxs)(h,{children:[(0,Z.jsx)(_,{className:t(F({variant:o.variant}),`cursor-help`),type:`button`,children:o.label}),(0,Z.jsx)(C,{children:o.description})]})})]}),e.recentEvents.length>0||s?(0,Z.jsxs)(k,{className:`grid gap-3`,children:[e.recentEvents.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-1.5`,children:e.recentEvents.map(e=>(0,Z.jsxs)(`li`,{className:`text-xs leading-5 text-muted-foreground`,children:[(0,Z.jsxs)(`span`,{className:`font-mono text-2xs text-foreground`,children:[`[`,e.type,`]`]}),` `,e.summary]},e.id))}):null,s?(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-border pt-3`,children:[(0,Z.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:l}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[n?(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:H(e.skill,{audit:!0}),children:`Audit skill`}):(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:q(e.skill,i),children:`Create skill`}),(0,Z.jsx)(O,{disabled:a.isPending,loading:a.isPending,onClick:()=>a.mutate(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`})]})]}):null]}):null]})}function de(){let e=s(),[t,n]=(0,B.useState)(`note`),[r,o]=(0,B.useState)(``),[c,l]=(0,B.useState)(``),[m,h]=(0,B.useState)(null),g=a({queryKey:b.learningsReflect,queryFn:()=>f.getReflection()}),_=a({queryKey:b.library,queryFn:()=>d.getAll()}),v=a({queryKey:b.learningsTimeline,queryFn:()=>f.getTimeline()}),S=(0,B.useMemo)(()=>new Set((_.data??[]).filter(e=>e.kind===`skills`).map(e=>e.name)),[_.data]),C=(0,B.useMemo)(()=>V(g.data?.skills??[],S),[S,g.data]),w=(0,B.useMemo)(()=>{let e=v.data?.events??[],t=new Map;for(let n of g.data?.skills??[])t.set(n.skill,K(e,n));return t},[v.data,g.data]),D=(0,B.useMemo)(()=>W(g.data?.skills??[]),[g.data]),A=i({mutationFn:async()=>f.capture({type:t,skill:r.trim(),summary:c.trim()}),onSuccess:()=>{o(``),l(``),e.invalidateQueries({queryKey:b.learningsReflect}),e.invalidateQueries({queryKey:b.learningsTimeline}),y.success(`Event logged`)},onError:e=>{y.error(u(e,`Unable to log event`))}});if(g.isLoading)return(0,Z.jsx)(E,{variant:`dashboard`});if(g.isError)return(0,Z.jsx)(M,{description:`Learnings are temporarily unavailable.`,title:`Unable to load learnings`});let N=g.data,P=N?.totalEvents??0;return(0,Z.jsxs)(`section`,{className:`mx-auto grid w-full max-w-5xl gap-8`,children:[(0,Z.jsxs)(`header`,{className:`grid gap-2`,children:[(0,Z.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Skill reflections`}),(0,Z.jsxs)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:[`Per-skill trend from captured events. Events populate automatically once the seeded`,` `,(0,Z.jsx)(`code`,{className:`font-mono text-xs text-muted-foreground`,children:`chain-hub-learnings`}),` rule reaches a connected editor, or log one manually below.`]})]}),C.length>0?(0,Z.jsx)(ce,{items:C}):null,P===0?(0,Z.jsx)(M,{description:`No events captured yet. Log one manually below, or run chain capture --event <type> --skill <slug> --summary ‘<text>’ from a terminal.`,title:`No learnings yet`}):(()=>{let e=N.skills,t=e.find(e=>e.skill===m)??D.open[0]??e[0];return(0,Z.jsxs)(`div`,{className:`grid gap-4 lg:grid-cols-[16rem_minmax(0,1fr)] lg:items-start`,children:[(0,Z.jsx)(le,{open:D.open,quiet:D.quiet,hubSkills:S,activeSkill:t.skill,onSelect:h}),(0,Z.jsx)(ue,{skill:t,inHub:S.has(t.skill),openReports:w.get(t.skill)??[]})]})})(),(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsx)(p,{children:`Log an event`})}),(0,Z.jsx)(k,{children:(0,Z.jsxs)(`form`,{className:`grid gap-3 sm:grid-cols-[8rem_1fr_auto] sm:items-start`,onSubmit:e=>{e.preventDefault(),r.trim()&&c.trim()&&A.mutate()},children:[(0,Z.jsx)(L,{"aria-label":`Event type`,onChange:e=>n(e.target.value),value:t,children:J.map(e=>(0,Z.jsx)(`option`,{value:e,children:e},e))}),(0,Z.jsx)(j,{"aria-label":`Skill slug`,onChange:e=>o(e.target.value),placeholder:`skill slug`,value:r}),(0,Z.jsx)(O,{className:`sm:row-span-2`,loading:A.isPending,type:`submit`,children:A.isPending?`Logging…`:`Log event`}),(0,Z.jsx)(R,{"aria-label":`Event summary`,className:`sm:col-span-2`,onChange:e=>l(e.target.value),placeholder:`One-line summary of what happened`,value:c})]})})]}),(0,Z.jsx)(te,{})]})}export{de as LearningsPage};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e,t}from"./utils-BEATUXr4.js";import{J as n,M as r,U as i,W as a,Z as o,q as s}from"./vendor-react-BgntYnUn.js";import{it as c,ot as l}from"./vendor-ui-qVCZmmA-.js";import{A as u,C as d,S as f,a as p,c as m,ct as h,d as g,dt as _,f as v,gt as y,h as b,i as x,l as S,lt as C,mt as w,n as T,o as E,p as D,pt as O,r as k,s as A,st as j,t as M,u as N,ut as P}from"./index-ltESF1KS.js";import{n as F,t as I}from"./badge-CcASMiB4.js";import{t as L}from"./select-DJSrFTH0.js";import{n as R,t as z}from"./libesm-CHGPMFhL.js";var B=e(o(),1);function V(e,t){let n=(e,t)=>(t.type===`correction`||t.type===`failure`)&&(!e.resolvedAt||t.capturedAt>e.resolvedAt);return e.filter(e=>e.openCorrectionCount+e.openFailureCount>0).map(e=>({skill:e.skill,correctionCount:e.openCorrectionCount,failureCount:e.openFailureCount,latestIssue:e.recentEvents.find(t=>n(e,t))??null,inHub:t.has(e.skill)})).sort((e,t)=>t.correctionCount+t.failureCount-(e.correctionCount+e.failureCount)||e.skill.localeCompare(t.skill))}function H(e,t){let n=new URLSearchParams({kind:`skills`,asset:e});return t?.audit&&n.set(`audit`,`1`),`/library?${n.toString()}`}function U(e){return e.openCorrectionCount+e.openFailureCount+e.openNoteCount}function W(e){return{open:e.filter(e=>U(e)>0).sort((e,t)=>U(t)-U(e)||t.lastSeen.localeCompare(e.lastSeen)),quiet:e.filter(e=>U(e)===0)}}var G=new Set([`correction`,`failure`,`note`]);function K(e,t){return e.filter(e=>e.skill===t.skill&&G.has(e.type)&&(!t.resolvedAt||e.capturedAt>t.resolvedAt))}function q(e,t){let n=new URLSearchParams({create:`1`,kind:`skills`,name:e});if(t.length>0){let r=t.map(e=>`- [${e.type}] ${e.summary}`).join(`
|
|
2
|
+
`);n.set(`intent`,`New skill "${e}" distilled from these captured field reports:\n${r}`)}return`/library?${n.toString()}`}var J=[`success`,`failure`,`correction`,`note`],Y={improving:{label:`↑ improving`,variant:`success`,description:`More successes than corrections and failures captured. No action needed.`},struggling:{label:`↓ struggling`,variant:`destructive`,description:`More corrections and failures than successes. Audit the skill to fold the field reports in.`},stable:{label:`→ stable`,variant:`default`,description:`Successes and corrections/failures are in balance. No action needed.`},new:{label:`★ new`,variant:`accent`,description:`Only one event captured so far, so there is no trend yet.`},collecting:{label:`• collecting`,variant:`default`,description:`Only notes captured so far. They feed the next audit as field reports.`}};function X(e){let t=[];return e.correctionCount>0&&t.push(`${e.correctionCount} correction${e.correctionCount===1?``:`s`}`),e.failureCount>0&&t.push(`${e.failureCount} failure${e.failureCount===1?``:`s`}`),e.noteCount&&t.push(`${e.noteCount} note${e.noteCount===1?``:`s`}`),t.join(` · `)}var Z=n(),Q=8,ee={applied:`accent`,"reviewed-clean":`success`,"upstream-proposal":`warning`,"to-source":`warning`,"findings-only":`warning`,orphan:`default`,failed:`destructive`};function te(){let[e,n]=(0,B.useState)(null),[r,i]=(0,B.useState)(!1),o=a({queryKey:b.learningsFolds,queryFn:()=>f.getFolds()}),s=a({queryKey:[...b.learningsFolds,e?.date,e?.skill],queryFn:()=>f.getFold(e.date,e.skill),enabled:e!==null}),c=o.data??[];if(o.isLoading||c.length===0)return null;let u=c.length>Q,d=r?c:c.slice(0,Q);return(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsx)(p,{children:`Fold history`}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Audit trail of applied folds — findings, folded reports and before/after per skill. Read-only; revert by copying the Before block back into the skill.`})]})}),(0,Z.jsx)(k,{children:(0,Z.jsxs)(`div`,{className:`grid gap-2`,children:[(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:d.map(e=>(0,Z.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border px-3 py-2`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:ee[e.outcome]??`default`,children:e.outcome}),(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.date}),e.writtenTo?(0,Z.jsxs)(`span`,{className:`truncate text-xs text-muted-foreground`,children:[`→ `,e.writtenTo]}):null]}),(0,Z.jsx)(O,{onClick:()=>n(e),size:`sm`,variant:`ghost`,children:`View`})]},`${e.date}/${e.skill}`))}),u?(0,Z.jsxs)(O,{"aria-expanded":r,className:`w-full`,onClick:()=>i(e=>!e),size:`sm`,variant:`ghost`,children:[r?`Show fewer`:`Show all ${c.length} folds`,(0,Z.jsx)(l,{"aria-hidden":`true`,className:t(`size-3.5 transition-transform`,r?`rotate-180`:``)})]}):null]})}),(0,Z.jsx)(A,{onOpenChange:e=>!e&&n(null),open:e!==null,children:(0,Z.jsxs)(S,{className:`max-w-3xl`,children:[(0,Z.jsxs)(v,{children:[(0,Z.jsxs)(D,{children:[e?.skill,` · `,e?.date]}),(0,Z.jsx)(N,{children:`Fold artifact, read-only review.`})]}),(0,Z.jsx)(m,{children:s.isLoading?(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Loading…`}):s.isError?(0,Z.jsx)(`p`,{className:`text-sm text-destructive-foreground`,children:`Unable to load the artifact.`}):(0,Z.jsx)(`pre`,{className:`max-h-[60vh] overflow-y-auto rounded-xl border border-border bg-muted/40 p-3 font-mono text-xs leading-5 whitespace-pre-wrap`,children:s.data?.content})})]})})]})}var ne={applied:{label:`Will be rewritten`,variant:`accent`,hint:`Apply writes the proposed SKILL.md in place.`},"reviewed-clean":{label:`Nothing actionable`,variant:`success`,hint:`Audit reviewed the reports; applying marks them addressed.`},"upstream-proposal":{label:`Upstream-locked`,variant:`warning`,hint:`Apply records the rewrite as a proposal under memory/learnings/folds.`},"to-source":{label:`Writes to source`,variant:`warning`,hint:`Apply writes back into the upstream path source.`},"findings-only":{label:`Too large to rewrite`,variant:`warning`,hint:`Skill exceeds the AI improve limit; findings are kept as an artifact.`},orphan:{label:`Not in your hub`,variant:`default`,hint:`No skill exists for this slug — reports can only be marked addressed.`},failed:{label:`Failed`,variant:`destructive`,hint:``}};function re({before:e,after:n}){let r=z(e,n);return r.some(e=>e.added||e.removed)?(0,Z.jsx)(`pre`,{className:`max-h-72 overflow-y-auto rounded-xl border border-border bg-muted/40 p-3 font-mono text-xs leading-5 whitespace-pre-wrap`,children:r.map((e,n)=>(0,Z.jsx)(`span`,{className:t(`block`,e.added&&`bg-success/10 text-success-foreground`,e.removed&&`bg-destructive/10 text-destructive-foreground line-through`),children:e.value},n))}):(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No changes; the AI returned the same content.`})}function ie({item:e,done:t,applying:n,onApply:r,onMarkAddressed:i}){let[a,o]=(0,B.useState)(!1),s=ne[e.outcome],u=!t&&e.outcome!==`orphan`&&e.outcome!==`failed`,d=!!(e.currentContent&&e.proposedContent);return(0,Z.jsxs)(`li`,{className:`grid gap-2 rounded-lg border border-border px-3 py-2.5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:s.variant,children:s.label}),e.findingCount>0?(0,Z.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[e.findingCount,` finding`,e.findingCount===1?``:`s`]}):null]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[d?(0,Z.jsxs)(O,{"aria-expanded":a,onClick:()=>o(e=>!e),size:`sm`,variant:`ghost`,children:[a?(0,Z.jsx)(l,{"aria-hidden":!0}):(0,Z.jsx)(c,{"aria-hidden":!0}),`Diff`]}):null,e.outcome===`orphan`&&!t?(0,Z.jsx)(O,{disabled:n,onClick:()=>i(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`}):null,u?(0,Z.jsx)(O,{disabled:n,onClick:()=>r(e.skill),size:`sm`,variant:`secondary`,children:`Apply`}):null,t?(0,Z.jsx)(`span`,{className:`text-xs font-medium text-success-foreground`,children:`Done`}):null]})]}),s.hint&&!t?(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:s.hint}):null,e.error?(0,Z.jsx)(`p`,{className:`text-xs text-destructive-foreground`,children:e.error}):null,e.findings.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-0.5`,children:e.findings.map((e,t)=>(0,Z.jsxs)(`li`,{className:`text-xs leading-5 text-muted-foreground`,children:[(0,Z.jsxs)(`span`,{className:`font-mono text-2xs text-foreground`,children:[`[`,e.severity,`]`]}),` `,e.title,`: `,e.detail]},t))}):null,a&&d?(0,Z.jsx)(re,{after:e.proposedContent,before:e.currentContent}):null]})}function ae({open:e,onOpenChange:t,preview:n,doneSkills:r,applying:i,onApplySkill:a,onApplyAll:o,onMarkAddressed:s}){let c=(n?.results??[]).filter(e=>!r.has(e.skill)).filter(e=>e.outcome!==`orphan`&&e.outcome!==`failed`);return(0,Z.jsx)(A,{onOpenChange:t,open:e,children:(0,Z.jsxs)(S,{className:`max-w-3xl`,children:[(0,Z.jsxs)(v,{children:[(0,Z.jsx)(D,{children:`Fold field reports into skills`}),(0,Z.jsx)(N,{children:`Dry-run preview; nothing is written yet. Apply rewrites the skill, records a fold artifact under memory/learnings/folds, and marks the reports addressed.`})]}),(0,Z.jsx)(m,{children:n&&n.results.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:n.results.map(e=>(0,Z.jsx)(ie,{applying:i,done:r.has(e.skill),item:e,onApply:a,onMarkAddressed:s},e.skill))}):(0,Z.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`No open field reports; nothing to fold.`})}),(0,Z.jsxs)(g,{children:[(0,Z.jsx)(O,{onClick:()=>t(!1),variant:`secondary`,children:`Close`}),(0,Z.jsxs)(O,{disabled:c.length===0||i,loading:i,onClick:o,children:[`Apply all (`,c.length,`)`]})]})]})})}function oe(e){let t=new Map;for(let n of e.results)t.set(n.outcome,(t.get(n.outcome)??0)+1);let n=[];return t.get(`applied`)&&n.push(`${t.get(`applied`)} improved`),t.get(`reviewed-clean`)&&n.push(`${t.get(`reviewed-clean`)} reviewed clean`),t.get(`upstream-proposal`)&&n.push(`${t.get(`upstream-proposal`)} proposal artifact`),t.get(`to-source`)&&n.push(`${t.get(`to-source`)} written to source`),t.get(`findings-only`)&&n.push(`${t.get(`findings-only`)} findings-only`),t.get(`orphan`)&&n.push(`${t.get(`orphan`)} not in hub`),t.get(`failed`)&&n.push(`${t.get(`failed`)} failed`),n.join(` · `)}function se(){let e=s();return{preview:i({mutationFn:()=>f.fold({dryRun:!0}),onError:e=>{y.error(u(e,`Unable to preview the fold`))}}),apply:i({mutationFn:(e={})=>f.fold({...e,dryRun:!1}),onSuccess:t=>{e.invalidateQueries({queryKey:b.learningsReflect}),e.invalidateQueries({queryKey:b.library}),t.results.length===0?y.success(`Nothing to fold — no open field reports`):t.results.every(e=>e.outcome===`failed`)?y.error(t.results[0]?.error??`Fold failed`):y.success(`Fold done · ${oe(t)}`)},onError:e=>{y.error(u(e,`Unable to fold learnings`))}})}}function $(){let e=s();return i({mutationFn:e=>f.resolveSkill({skill:e}),onSuccess:()=>{e.invalidateQueries({queryKey:b.learningsReflect}),y.success(`Marked as addressed`)},onError:e=>{y.error(u(e,`Unable to mark as addressed`))}})}function ce({items:e}){let t=$(),n=se(),[i,a]=(0,B.useState)(!1),[o,s]=(0,B.useState)(null),[c,l]=(0,B.useState)(new Set);return(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsx)(p,{children:`Needs attention`}),(0,Z.jsx)(O,{loading:n.preview.isPending,onClick:()=>{n.preview.mutate(void 0,{onSuccess:e=>{s(e),l(new Set),a(!0)}})},size:`sm`,variant:`secondary`,children:`Fold into skills`})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Fold into skills previews the audit findings and proposed rewrite per skill before anything is written; apply folds the reports into the skill itself. Marking addressed clears the reports without changes.`})]})}),(0,Z.jsx)(k,{children:(0,Z.jsx)(`ul`,{className:`grid gap-2`,children:e.map(e=>(0,Z.jsxs)(`li`,{className:`flex flex-wrap items-center justify-between gap-3 rounded-lg border border-border px-3 py-2`,children:[(0,Z.jsxs)(`div`,{className:`grid min-w-0 gap-0.5`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,Z.jsx)(`span`,{className:`text-sm font-medium text-foreground`,children:e.skill}),(0,Z.jsx)(I,{variant:`warning`,children:X(e)})]}),e.latestIssue?(0,Z.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:e.latestIssue.summary}):null]}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[e.inHub?(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:H(e.skill,{audit:!0}),children:`Audit skill`}):(0,Z.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Not in your hub`}),(0,Z.jsx)(O,{disabled:t.isPending,loading:t.isPending&&t.variables===e.skill,onClick:()=>t.mutate(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`})]})]},e.skill))})}),(0,Z.jsx)(ae,{applying:n.apply.isPending,doneSkills:c,onApplyAll:()=>{n.apply.mutate({},{onSuccess:()=>a(!1)})},onApplySkill:e=>{n.apply.mutate({skill:e},{onSuccess:()=>l(t=>new Set(t).add(e))})},onMarkAddressed:e=>{t.mutate(e,{onSuccess:()=>l(t=>new Set(t).add(e))})},onOpenChange:a,open:i,preview:o})]})}function le({open:e,quiet:n,hubSkills:r,activeSkill:i,onSelect:a}){let[o,s]=(0,B.useState)(!1),c=o||e.length===0,u=e=>{let n=U(e),o=e.skill===i,s=r.has(e.skill);return(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{"aria-current":o||void 0,className:t(`flex w-full items-center gap-2 px-3 py-2.5 text-left text-sm transition-colors`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset`,o?`bg-muted font-medium text-foreground`:`text-muted-foreground hover:bg-muted/50 hover:text-foreground`),onClick:()=>a(e.skill),type:`button`,children:[(0,Z.jsx)(`span`,{className:`min-w-0 flex-1 truncate`,children:e.skill}),s?null:(0,Z.jsx)(I,{variant:`default`,children:`no skill`}),n>0?(0,Z.jsxs)(I,{variant:`warning`,children:[n,` open`]}):null]})},e.skill)};return(0,Z.jsx)(`div`,{className:`max-h-[70vh] overflow-y-auto rounded-2xl border border-border bg-card shadow-card`,children:(0,Z.jsxs)(`ul`,{className:`divide-y divide-border`,children:[e.length>0?(0,Z.jsxs)(`li`,{className:`sticky top-0 z-10 bg-card px-3 py-2 text-xs font-medium text-muted-foreground`,children:[`Open reports · `,e.length]}):null,e.map(u),n.length>0?(0,Z.jsx)(`li`,{children:(0,Z.jsxs)(`button`,{"aria-expanded":c,className:t(`flex w-full items-center justify-between gap-2 bg-card px-3 py-2 text-left text-xs font-medium transition-colors`,`text-muted-foreground hover:text-foreground`,`focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset`,c?`sticky top-0 z-10`:``),onClick:()=>s(e=>!e),type:`button`,children:[`Quiet · `,n.length,(0,Z.jsx)(l,{"aria-hidden":`true`,className:t(`size-3.5 transition-transform`,c?`rotate-180`:``)})]})}):null,c?n.map(u):null]})})}function ue({skill:e,inHub:n,openReports:i}){let a=$(),o=Y[e.trend],s=e.openCorrectionCount+e.openFailureCount+e.openNoteCount>0,c=X({correctionCount:e.openCorrectionCount,failureCount:e.openFailureCount,noteCount:e.openNoteCount}),l=n?`${c} open. The next audit folds them into the skill, or mark them addressed once handled.`:`${c} open, but no skill named "${e.skill}" exists in the hub. Create it to fold the reports in, or mark them addressed.`;return(0,Z.jsxs)(T,{children:[(0,Z.jsxs)(x,{children:[(0,Z.jsxs)(`div`,{className:`grid gap-1`,children:[(0,Z.jsx)(p,{children:e.skill}),(0,Z.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e.totalEvents,` event`,e.totalEvents===1?``:`s`,`: `,e.successCount,` success,`,` `,e.failureCount,` failure, `,e.correctionCount,` correction, `,e.noteCount,` note`]})]}),(0,Z.jsx)(P,{children:(0,Z.jsxs)(h,{children:[(0,Z.jsx)(_,{className:t(F({variant:o.variant}),`cursor-help`),type:`button`,children:o.label}),(0,Z.jsx)(C,{children:o.description})]})})]}),e.recentEvents.length>0||s?(0,Z.jsxs)(k,{className:`grid gap-3`,children:[e.recentEvents.length>0?(0,Z.jsx)(`ul`,{className:`grid gap-1.5`,children:e.recentEvents.map(e=>(0,Z.jsxs)(`li`,{className:`text-xs leading-5 text-muted-foreground`,children:[(0,Z.jsxs)(`span`,{className:`font-mono text-2xs text-foreground`,children:[`[`,e.type,`]`]}),` `,e.summary]},e.id))}):null,s?(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2 border-t border-border pt-3`,children:[(0,Z.jsx)(`p`,{className:`text-xs leading-5 text-pretty text-muted-foreground`,children:l}),(0,Z.jsxs)(`div`,{className:`flex shrink-0 items-center gap-2`,children:[n?(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:H(e.skill,{audit:!0}),children:`Audit skill`}):(0,Z.jsx)(r,{className:w({size:`sm`,variant:`secondary`}),to:q(e.skill,i),children:`Create skill`}),(0,Z.jsx)(O,{disabled:a.isPending,loading:a.isPending,onClick:()=>a.mutate(e.skill),size:`sm`,variant:`ghost`,children:`Mark addressed`})]})]}):null]}):null]})}function de(){let e=s(),[t,n]=(0,B.useState)(`note`),[r,o]=(0,B.useState)(``),[c,l]=(0,B.useState)(``),[m,h]=(0,B.useState)(null),g=a({queryKey:b.learningsReflect,queryFn:()=>f.getReflection()}),_=a({queryKey:b.library,queryFn:()=>d.getAll()}),v=a({queryKey:b.learningsTimeline,queryFn:()=>f.getTimeline()}),S=(0,B.useMemo)(()=>new Set((_.data??[]).filter(e=>e.kind===`skills`).map(e=>e.name)),[_.data]),C=(0,B.useMemo)(()=>V(g.data?.skills??[],S),[S,g.data]),w=(0,B.useMemo)(()=>{let e=v.data?.events??[],t=new Map;for(let n of g.data?.skills??[])t.set(n.skill,K(e,n));return t},[v.data,g.data]),D=(0,B.useMemo)(()=>W(g.data?.skills??[]),[g.data]),A=i({mutationFn:async()=>f.capture({type:t,skill:r.trim(),summary:c.trim()}),onSuccess:()=>{o(``),l(``),e.invalidateQueries({queryKey:b.learningsReflect}),e.invalidateQueries({queryKey:b.learningsTimeline}),y.success(`Event logged`)},onError:e=>{y.error(u(e,`Unable to log event`))}});if(g.isLoading)return(0,Z.jsx)(E,{variant:`dashboard`});if(g.isError)return(0,Z.jsx)(M,{description:`Learnings are temporarily unavailable.`,title:`Unable to load learnings`});let N=g.data,P=N?.totalEvents??0;return(0,Z.jsxs)(`section`,{className:`mx-auto grid w-full max-w-5xl gap-8`,children:[(0,Z.jsxs)(`header`,{className:`grid gap-2`,children:[(0,Z.jsx)(`h2`,{className:`text-xl font-semibold tracking-tight text-foreground`,children:`Skill reflections`}),(0,Z.jsxs)(`p`,{className:`max-w-2xl text-sm leading-5 text-muted-foreground`,children:[`Per-skill trend from captured events. Events populate automatically once the seeded`,` `,(0,Z.jsx)(`code`,{className:`font-mono text-xs text-muted-foreground`,children:`chain-hub-learnings`}),` rule reaches a connected editor, or log one manually below.`]})]}),C.length>0?(0,Z.jsx)(ce,{items:C}):null,P===0?(0,Z.jsx)(M,{description:`No events captured yet. Log one manually below, or run chain capture --event <type> --skill <slug> --summary ‘<text>’ from a terminal.`,title:`No learnings yet`}):(()=>{let e=N.skills,t=e.find(e=>e.skill===m)??D.open[0]??e[0];return(0,Z.jsxs)(`div`,{className:`grid gap-4 lg:grid-cols-[16rem_minmax(0,1fr)] lg:items-start`,children:[(0,Z.jsx)(le,{open:D.open,quiet:D.quiet,hubSkills:S,activeSkill:t.skill,onSelect:h}),(0,Z.jsx)(ue,{skill:t,inHub:S.has(t.skill),openReports:w.get(t.skill)??[]})]})})(),(0,Z.jsxs)(T,{children:[(0,Z.jsx)(x,{children:(0,Z.jsx)(p,{children:`Log an event`})}),(0,Z.jsx)(k,{children:(0,Z.jsxs)(`form`,{className:`grid gap-3 sm:grid-cols-[8rem_1fr_auto] sm:items-start`,onSubmit:e=>{e.preventDefault(),r.trim()&&c.trim()&&A.mutate()},children:[(0,Z.jsx)(L,{"aria-label":`Event type`,onChange:e=>n(e.target.value),value:t,children:J.map(e=>(0,Z.jsx)(`option`,{value:e,children:e},e))}),(0,Z.jsx)(j,{"aria-label":`Skill slug`,onChange:e=>o(e.target.value),placeholder:`skill slug`,value:r}),(0,Z.jsx)(O,{className:`sm:row-span-2`,loading:A.isPending,type:`submit`,children:A.isPending?`Logging…`:`Log event`}),(0,Z.jsx)(R,{"aria-label":`Event summary`,className:`sm:col-span-2`,onChange:e=>l(e.target.value),placeholder:`One-line summary of what happened`,value:c})]})})]}),(0,Z.jsx)(te,{})]})}export{de as LearningsPage};
|