@wkoutre/teamwork-os 1.0.3 → 1.0.5

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.
Files changed (41) hide show
  1. package/README.md +0 -10
  2. package/cli.js +14 -2
  3. package/cli.jsc +0 -0
  4. package/dist/assets/AnalyticsPage-C24BvG1R.js +1 -0
  5. package/dist/assets/{BriefsPage-BsBjNIJT.js → BriefsPage-DrMSESEG.js} +1 -1
  6. package/dist/assets/{ChatPanel-BUNJ-rXp.js → ChatPanel-CC0ta99_.js} +1 -1
  7. package/dist/assets/{ContinuousImprovementPage-F6fizSUr.js → ContinuousImprovementPage-DyTwV7gP.js} +1 -1
  8. package/dist/assets/{HeartbeatPanel-q7mW5VDk.js → HeartbeatPanel-Dk6plplc.js} +1 -1
  9. package/dist/assets/IdeasContainer-DeZZF8d9.js +3 -0
  10. package/dist/assets/{MemoryExplore-wFiVBkXu.js → MemoryExplore-DS4IYHl2.js} +1 -1
  11. package/dist/assets/{MemoryHygiene-C_lFMujk.js → MemoryHygiene-DxUcjusq.js} +2 -2
  12. package/dist/assets/{MemoryInjections-F6D1_uAX.js → MemoryInjections-BO_kUrBn.js} +1 -1
  13. package/dist/assets/{MemoryPage-DS6LWMdS.js → MemoryPage-C2hIk5fW.js} +2 -2
  14. package/dist/assets/{MemoryWiki-cypT6R3l.js → MemoryWiki-Dh1MtBZV.js} +2 -2
  15. package/dist/assets/OrgPage-BAbdwx53.js +33 -0
  16. package/dist/assets/{SessionHistory-DwX-i9Io.js → SessionHistory-DXsOaHFV.js} +1 -1
  17. package/dist/assets/{SettingsPage-C6Xq22uB.js → SettingsPage-C1QRyGEh.js} +2 -2
  18. package/dist/assets/SupervisorDashboardPage-5IZyxfvh.css +1 -0
  19. package/dist/assets/SupervisorDashboardPage-Cnd1zMt9.js +1 -0
  20. package/dist/assets/{UsagePage-Cm8NsPw7.js → UsagePage-BcK454ym.js} +2 -2
  21. package/dist/assets/{events-CCBP4a9s.js → events-BK5ucyUu.js} +1 -1
  22. package/dist/assets/index-CiIY3MTP.css +1 -0
  23. package/dist/assets/index-DzJsiq8q.js +93 -0
  24. package/dist/assets/{lib-osArdP58.js → lib-CncUdc6D.js} +4 -4
  25. package/dist/assets/{types-CNhs8RVF.js → types-BeZJlDCI.js} +1 -1
  26. package/dist/assets/ui-DvNuX5MF.js +1 -0
  27. package/dist/index.html +5 -5
  28. package/gateway.jsc +0 -0
  29. package/onboarding-plugin/.claude-plugin/plugin.json +5 -0
  30. package/onboarding-plugin/skills/onboarding/SKILL.md +54 -0
  31. package/package.json +2 -1
  32. package/dist/assets/AnalyticsPage-BoafbdRY.js +0 -1
  33. package/dist/assets/IdeasContainer-DDhsyl1f.js +0 -3
  34. package/dist/assets/OrgPage-DP2-hcbf.js +0 -33
  35. package/dist/assets/SupervisorDashboardPage-BEuElLHE.css +0 -1
  36. package/dist/assets/SupervisorDashboardPage-CrsOGBZ8.js +0 -1
  37. package/dist/assets/index-C57L9wdB.css +0 -1
  38. package/dist/assets/index-tOLuwPW6.js +0 -93
  39. package/dist/assets/ui-Bx41p7g8.js +0 -1
  40. /package/dist/assets/{Button-xBBZQ0ie.js → Button-DTO6bgnL.js} +0 -0
  41. /package/dist/assets/{Input-HhV6M0tu.js → Input-iymdcwsf.js} +0 -0
package/README.md CHANGED
@@ -62,16 +62,6 @@ teamos update --rollback # revert to the previously installed version
62
62
 
63
63
  Alternatively: `npm install -g @wkoutre/teamwork-os@latest` followed by `teamos restart`.
64
64
 
65
- ## Provenance verification
66
-
67
- All publishes use `--provenance`. You can verify that the package was built by the official CI pipeline (not from a stolen npm token) by running:
68
-
69
- ```bash
70
- npm audit signatures @wkoutre/teamwork-os
71
- ```
72
-
73
- This is optional. It confirms the supply-chain attestation attached to the release.
74
-
75
65
  ## Uninstalling
76
66
 
77
67
  ```bash
package/cli.js CHANGED
@@ -1,3 +1,15 @@
1
1
  #!/usr/bin/env node
2
- require('bytenode')
3
- require('./cli.jsc')
2
+ 'use strict';
3
+ // Node-version preflight: cli.jsc is V8 bytecode locked to Node 25.
4
+ var major = parseInt(process.versions.node.split('.')[0], 10);
5
+ if (major !== 25) {
6
+ process.stderr.write(
7
+ '\nTeamwork OS requires Node 25.x (you have ' + process.version + ').\n' +
8
+ 'The CLI ships precompiled bytecode locked to Node 25.\n\n' +
9
+ ' nvm install 25 && nvm use 25\n' +
10
+ ' https://github.com/nvm-sh/nvm\n\n'
11
+ );
12
+ process.exit(1);
13
+ }
14
+ require('bytenode');
15
+ require('./cli.jsc');
package/cli.jsc CHANGED
Binary file
@@ -0,0 +1 @@
1
+ import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{n as r}from"./styles-Ds5gMQAQ.js";import{en as i,l as a}from"./index-DzJsiq8q.js";import{t as o}from"./KpiTile-pXTBj77S.js";var s=t(e(),1),c=n();function l(){let{metrics:e,loading:t}=a(),{employees:n}=i(),l=(0,s.useMemo)(()=>{let e=new Map;for(let t of n)e.set(t.name,t);return e},[n]),d=(0,s.useMemo)(()=>{let t=Object.values(e);if(t.length===0)return null;let n=t.reduce((e,t)=>e+t.totalSessions,0),r=t.reduce((e,t)=>e+t.totalCostUsd,0),i=t.reduce((e,t)=>e+t.completedSessions,0),a=t.reduce((e,t)=>e+t.errorSessions,0),o=i+a;return{totalSessions:n,totalCost:r,avgSuccessRate:o>0?i/o:null,totalCompleted:i,totalErrors:a,agentCount:t.length}},[e]),f=(0,s.useMemo)(()=>Object.entries(e).sort((e,t)=>t[1].totalSessions-e[1].totalSessions),[e]);if(t)return(0,c.jsxs)(`div`,{className:`page-content-frame`,style:{padding:`32px 48px`},children:[(0,c.jsx)(`h1`,{style:{fontSize:22,fontWeight:600,marginBottom:8},children:`Analytics`}),(0,c.jsx)(`p`,{style:{color:r.muted,fontSize:14},children:`Loading metrics...`})]});if(!d)return(0,c.jsxs)(`div`,{className:`page-content-frame`,style:{padding:`32px 48px`},children:[(0,c.jsx)(`h1`,{style:{fontSize:22,fontWeight:600,marginBottom:8},children:`Analytics`}),(0,c.jsxs)(`div`,{style:{marginTop:32,padding:40,textAlign:`center`,color:r.muted,border:`1px dashed ${r.border}`,borderRadius:12},children:[(0,c.jsx)(`div`,{style:{fontSize:48,marginBottom:16,opacity:.4},children:`📊`}),(0,c.jsx)(`p`,{style:{fontSize:13},children:`No session data yet. Run some agent sessions to see metrics here.`})]})]});let p=d.avgSuccessRate===null?null:Math.round(d.avgSuccessRate*100);return(0,c.jsxs)(`div`,{className:`page-content-frame`,style:{padding:`32px 48px`,maxWidth:1100},children:[(0,c.jsx)(`h1`,{style:{fontSize:22,fontWeight:600,marginBottom:24},children:`Analytics`}),(0,c.jsxs)(`div`,{style:{display:`grid`,gridTemplateColumns:`repeat(auto-fit, minmax(180px, 1fr))`,gap:12,marginBottom:32},children:[(0,c.jsx)(o,{label:`Total Sessions`,value:String(d.totalSessions)}),(0,c.jsx)(o,{label:`Active Agents`,value:String(d.agentCount)}),(0,c.jsx)(o,{label:`Avg Success Rate`,value:p===null?`N/A`:`${p}%`,color:p===null?r.muted:p>=80?r.green:p>=50?`var(--color-warning)`:r.red}),(0,c.jsx)(o,{label:`Total Cost`,value:`$${d.totalCost.toFixed(2)}`})]}),(0,c.jsx)(`h2`,{style:{fontSize:16,fontWeight:600,marginBottom:16},children:`Per-Agent Breakdown`}),(0,c.jsx)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:8},children:f.map(([e,t])=>(0,c.jsx)(u,{name:e,metrics:t,employee:l.get(e)},e))})]})}function u({name:e,metrics:t,employee:n}){let i=t.successRate===null?null:Math.round(t.successRate*100),a=i===null?r.muted:i>=80?r.green:i>=50?`var(--color-warning)`:r.red;return(0,c.jsxs)(`div`,{style:{background:r.cardBg,border:`1px solid ${r.border}`,borderRadius:8,padding:`14px 18px`,display:`grid`,gridTemplateColumns:`200px 1fr`,gap:16,alignItems:`center`},children:[(0,c.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:10},children:[(0,c.jsx)(`span`,{style:{fontSize:22},children:n?.emoji||`👤`}),(0,c.jsxs)(`div`,{children:[(0,c.jsx)(`div`,{style:{fontSize:14,fontWeight:600,color:`var(--color-text)`},children:n?.displayName||e}),(0,c.jsxs)(`div`,{style:{fontSize:11,color:r.muted},children:[n?.department||`unassigned`,` · `,n?.rank||`employee`]})]})]}),(0,c.jsxs)(`div`,{style:{display:`flex`,gap:24,alignItems:`center`,flexWrap:`wrap`},children:[(0,c.jsx)(d,{label:`Sessions`,value:String(t.totalSessions)}),(0,c.jsx)(d,{label:`Success`,value:i===null?`N/A`:`${i}%`,color:a}),(0,c.jsx)(d,{label:`Cost`,value:`$${t.totalCostUsd.toFixed(2)}`}),(0,c.jsx)(d,{label:`Avg Duration`,value:f(t.avgDurationMs)}),(0,c.jsx)(`div`,{style:{flex:1,minWidth:100},children:(0,c.jsxs)(`div`,{style:{height:6,borderRadius:3,overflow:`hidden`,background:`${r.border}`,display:`flex`},children:[t.completedSessions>0&&(0,c.jsx)(`div`,{style:{width:`${t.completedSessions/t.totalSessions*100}%`,background:r.green}}),t.errorSessions>0&&(0,c.jsx)(`div`,{style:{width:`${t.errorSessions/t.totalSessions*100}%`,background:r.red}})]})})]})]})}function d({label:e,value:t,color:n}){return(0,c.jsxs)(`div`,{style:{textAlign:`center`,minWidth:64},children:[(0,c.jsx)(`div`,{style:{fontSize:13,fontWeight:600,color:n||`var(--color-text)`},children:t}),(0,c.jsx)(`div`,{style:{fontSize:10,color:r.muted,textTransform:`uppercase`,letterSpacing:.3},children:e})]})}function f(e){if(e===0)return`N/A`;if(e<1e3)return`${Math.round(e)}ms`;let t=e/1e3;return t<60?`${t.toFixed(1)}s`:`${Math.floor(t/60)}m ${Math.round(t%60)}s`}export{l as AnalyticsPage};
@@ -1 +1 @@
1
- import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{t as r}from"./react-dom-Cnw6SoYl.js";import{r as i}from"./useWebSocket-Hg3RO6sx.js";import{C as a,D as o,E as s,T as c,w as l}from"./index-tOLuwPW6.js";var u=t(e(),1),d=1e3;function f(e){let t=new URLSearchParams;return t.set(`sort`,e.sort),e.platform&&e.platform!==`all`&&t.set(`platform`,e.platform),e.q&&t.set(`q`,e.q),`/api/briefs?${t.toString()}`}function p(e){let[t,n]=(0,u.useState)([]),[r,a]=(0,u.useState)(!0),[o,s]=(0,u.useState)(null),[c,l]=(0,u.useState)(()=>new Set),[p,m]=(0,u.useState)(()=>new Map),h=(0,u.useRef)(new Map),[,g]=(0,u.useState)(()=>new Set),_=(0,u.useRef)(new Set),v=(0,u.useRef)(null),{sort:y,platform:b,q:x}=e,S=(0,u.useCallback)(()=>{v.current?.abort();let e=new AbortController;v.current=e,a(!0),s(null),fetch(f({sort:y,platform:b,q:x}),{signal:e.signal}).then(e=>e.ok?e.json():Promise.reject(Error(`HTTP ${e.status}`))).then(t=>{e.signal.aborted||n(t.briefs)}).catch(e=>{e instanceof Error&&e.name===`AbortError`||s(e instanceof Error?e.message:String(e))}).finally(()=>{e.signal.aborted||a(!1)})},[y,b,x]);return(0,u.useEffect)(()=>(S(),()=>v.current?.abort()),[S]),i(`brief:updated`,(0,u.useCallback)(e=>{let t=e?.brief;if(!t?.url||_.current.has(t.url)||t.hidden)return;n(e=>{let n=e.findIndex(e=>e.url===t.url);if(n>=0){let r=e.slice();return r[n]=t,r}return[t,...e]}),l(e=>{let n=new Set(e);return n.add(t.url),n}),m(e=>{let n=new Map(e);return n.set(t.url,(e.get(t.url)??0)+1),n});let r=h.current.get(t.url);r&&clearTimeout(r);let i=setTimeout(()=>{h.current.delete(t.url),l(e=>{if(!e.has(t.url))return e;let n=new Set(e);return n.delete(t.url),n})},d);h.current.set(t.url,i)},[])),(0,u.useEffect)(()=>{let e=h.current;return()=>{for(let t of e.values())clearTimeout(t);e.clear()}},[]),i(`brief:deleted`,(0,u.useCallback)(e=>{let t=e?.url;t&&n(e=>e.filter(e=>e.url!==t))},[])),i(`ws:reconnected`,(0,u.useCallback)(()=>{S()},[S])),{briefs:t,loading:r,error:o,recentlyUpdatedUrls:c,pulseTokens:p,refetch:S,patchTitle:(0,u.useCallback)(async(e,t)=>{let n=await fetch(`/api/briefs/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"content-type":`application/json`},body:JSON.stringify({user_title:t})});if(!n.ok)throw Error(`PATCH failed: ${n.status}`);S()},[S]),removeLocal:(0,u.useCallback)(e=>{n(t=>t.filter(t=>t.url!==e))},[]),removeNetwork:(0,u.useCallback)(async e=>{let t=await fetch(`/api/briefs/${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok&&t.status!==404)throw Error(`DELETE failed: ${t.status}`)},[]),restore:(0,u.useCallback)(async e=>{let t=await fetch(`/api/briefs/${encodeURIComponent(e)}/restore`,{method:`POST`});if(!t.ok)throw Error(`restore failed: ${t.status}`);S()},[S]),suppressUrl:(0,u.useCallback)(e=>{if(_.current.has(e))return;let t=new Set(_.current);t.add(e),_.current=t,g(t)},[]),unsuppressUrl:(0,u.useCallback)(e=>{if(!_.current.has(e))return;let t=new Set(_.current);t.delete(e),_.current=t,g(t)},[])}}var m={page:`_page_mkrqf_10`,light:`_light_mkrqf_25`,header:`_header_mkrqf_42`,title:`_title_mkrqf_51`,subtitle:`_subtitle_mkrqf_58`,controls:`_controls_mkrqf_72`,sortToggle:`_sortToggle_mkrqf_81`,sortBtn:`_sortBtn_mkrqf_91`,sortBtnActive:`_sortBtnActive_mkrqf_119`,search:`_search_mkrqf_130`,searchIcon:`_searchIcon_mkrqf_151`,searchInput:`_searchInput_mkrqf_156`,chipRow:`_chipRow_mkrqf_173`,filter:`_filter_mkrqf_180`,filterActive:`_filterActive_mkrqf_209`,filterLabel:`_filterLabel_mkrqf_224`,filterCount:`_filterCount_mkrqf_228`,glyph:`_glyph_mkrqf_241`,glyphSm:`_glyphSm_mkrqf_254`,glyphMd:`_glyphMd_mkrqf_260`,list:`_list_mkrqf_268`,card:`_card_mkrqf_282`,"brief-card-in":`_brief-card-in_mkrqf_1`,cardPulse:`_cardPulse_mkrqf_312`,"brief-pulse":`_brief-pulse_mkrqf_1`,cardGlyph:`_cardGlyph_mkrqf_316`,cardBody:`_cardBody_mkrqf_320`,cardTitle:`_cardTitle_mkrqf_324`,cardTitleLink:`_cardTitleLink_mkrqf_333`,cardTitleFallback:`_cardTitleFallback_mkrqf_350`,cardMeta:`_cardMeta_mkrqf_355`,cardHost:`_cardHost_mkrqf_366`,cardWrites:`_cardWrites_mkrqf_372`,cardRefs:`_cardRefs_mkrqf_378`,cardJobLink:`_cardJobLink_mkrqf_382`,cardJobName:`_cardJobName_mkrqf_407`,cardDot:`_cardDot_mkrqf_416`,cardTime:`_cardTime_mkrqf_421`,cardOverflow:`_cardOverflow_mkrqf_434`,cardOverflowBtn:`_cardOverflowBtn_mkrqf_439`,cardTitleEditor:`_cardTitleEditor_mkrqf_481`,cardTitleInput:`_cardTitleInput_mkrqf_488`,cardResetTitle:`_cardResetTitle_mkrqf_508`,errorBanner:`_errorBanner_mkrqf_536`,errorRetry:`_errorRetry_mkrqf_550`,empty:`_empty_mkrqf_575`,emptyHeadline:`_emptyHeadline_mkrqf_583`,emptyBody:`_emptyBody_mkrqf_590`,skeletonCard:`_skeletonCard_mkrqf_600`,skeletonGlyph:`_skeletonGlyph_mkrqf_614`,"brief-shimmer":`_brief-shimmer_mkrqf_1`,skeletonBody:`_skeletonBody_mkrqf_628`,skeletonTitle:`_skeletonTitle_mkrqf_635`,skeletonMeta:`_skeletonMeta_mkrqf_649`,skeletonTime:`_skeletonTime_mkrqf_663`,srOnly:`_srOnly_mkrqf_672`},h=n(),g={notion:{letter:`N`,label:`Notion`,tintVar:`--p-notion`},linear:{letter:`L`,label:`Linear`,tintVar:`--p-linear`},"slack-canvas":{letter:`S`,label:`Slack canvas`,tintVar:`--p-slack`},"google-docs":{letter:`G`,label:`Google Docs`,tintVar:`--p-gdocs`},"github-wiki":{letter:`W`,label:`GitHub wiki`,tintVar:`--p-wiki`},other:{letter:`·`,label:`Other`,tintVar:`--p-other`}};function _({platform:e,size:t=`sm`}){let n=g[e];return(0,h.jsx)(`span`,{className:[m.glyph,t===`md`?m.glyphMd:m.glyphSm].join(` `),style:{"--glyph-tint":`var(${n.tintVar})`},"aria-label":n.label,title:n.label,children:(0,h.jsx)(`span`,{"aria-hidden":`true`,children:n.letter})})}function v({platform:e,active:t,count:n,onClick:r}){let i=e===`all`?`All`:g[e].label,a=e===`all`?`--p-all`:g[e].tintVar;return(0,h.jsxs)(`button`,{type:`button`,className:`${m.filter} ${t?m.filterActive:``}`,onClick:r,"aria-pressed":t,style:{"--filter-tint":`var(${a})`},children:[e!==`all`&&(0,h.jsx)(_,{platform:e,size:`sm`}),(0,h.jsx)(`span`,{className:m.filterLabel,children:i}),typeof n==`number`&&n>0&&(0,h.jsx)(`span`,{className:m.filterCount,children:n})]})}var y=t(r(),1),b={menu:`_menu_d9qv0_6`,item:`_item_d9qv0_18`,danger:`_danger_d9qv0_43`};function x({open:e,onEdit:t,onDelete:n,onCopy:r,onClose:i,triggerRef:d}){let{refs:f,floatingStyles:p}=s({open:e,placement:`bottom-end`,whileElementsMounted:o,middleware:[l(4),a({padding:8}),c({padding:8})]});return(0,u.useEffect)(()=>{f.setReference(d.current??null)},[f,d]),(0,u.useEffect)(()=>{if(!e)return;let t=e=>{let t=e.target;if(d.current?.contains(t))return;let n=f.floating.current;n&&!n.contains(t)&&i()},n=e=>{e.key===`Escape`&&i()};return document.addEventListener(`mousedown`,t),document.addEventListener(`keydown`,n),()=>{document.removeEventListener(`mousedown`,t),document.removeEventListener(`keydown`,n)}},[e,i,d,f.floating]),e?(0,y.createPortal)((0,h.jsxs)(`ul`,{ref:f.setFloating,role:`menu`,className:b.menu,style:p,children:[(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:t,className:b.item,children:`Edit title`})}),(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:n,className:`${b.item} ${b.danger}`,children:`Delete`})}),(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:r,className:b.item,children:`Copy link`})})]}),document.body):null}function S(e){if(!e)return`never`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Date.now()-t,r=Math.round(n/6e4);if(r<1)return`just now`;if(r<60)return`${r}m`;let i=Math.round(r/60);if(i<24)return`${i}h`;let a=Math.round(i/24);if(a<7)return`${a}d`;let o=Math.round(a/7);if(o<5)return`${o}w`;let s=Math.round(a/30);return s<12?`${s}mo`:`${Math.round(s/12)}y`}function C(e){try{return new URL(e).hostname.replace(/^www\./,``)}catch{return``}}function w(e){let t=e?.trim();return!t||/^#?\d+\s*-\s*cd\s+\//.test(t)||/^cd\s+\//.test(t)||/^\//.test(t)?null:t}var T=(0,u.memo)(function({brief:e,pulseToken:t,index:n,onEdit:r,onDelete:i}){let a=e.title.trim()||C(e.url)||e.url,o=!e.userTitle?.trim(),s=g[e.platform],[c,l]=(0,u.useState)(!1),d=(0,u.useRef)(void 0);(0,u.useEffect)(()=>{if(t===void 0||t===d.current)return;d.current=t,l(!0);let e=setTimeout(()=>l(!1),900);return()=>clearTimeout(e)},[t]);let[f,p]=(0,u.useState)(!1),[v,y]=(0,u.useState)(!1),b=(0,u.useRef)(null),T=/^https?:\/\//i.test(e.url),D=T?e.url:`#`,O=e.writeCount,k=e.referenceCount,A=O===1?`write`:`writes`,j=w(e.lastWriteJob),M=e.lastWriteAt,N=M??e.lastReferenceAt,P=N?new Date(N).toLocaleString():`No activity yet`,F=M?`Never written`:`Never referenced`;return(0,h.jsxs)(`li`,{className:[m.card,c?m.cardPulse:``].filter(Boolean).join(` `),style:{animationDelay:`${Math.min(n,12)*28}ms`,"--card-tint":`var(${s.tintVar})`},children:[(0,h.jsx)(`div`,{className:m.cardGlyph,"aria-hidden":`true`,children:(0,h.jsx)(_,{platform:e.platform,size:`md`})}),(0,h.jsxs)(`div`,{className:m.cardBody,children:[v?(0,h.jsx)(E,{brief:e,onSave:async t=>{y(!1),await r(e.url,t)},onCancel:()=>y(!1)}):(0,h.jsx)(`h2`,{className:m.cardTitle,children:(0,h.jsx)(`a`,{href:D,target:`_blank`,rel:`noopener noreferrer`,onClick:T?void 0:e=>e.preventDefault(),className:[m.cardTitleLink,o?m.cardTitleFallback:``].filter(Boolean).join(` `),children:a})}),(0,h.jsxs)(`p`,{className:m.cardMeta,children:[(0,h.jsx)(`span`,{className:m.cardHost,children:C(e.url)}),(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsxs)(`span`,{className:m.cardWrites,children:[(0,h.jsx)(`strong`,{children:O}),` `,A]}),k>0&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsxs)(`span`,{className:m.cardRefs,children:[k,` ref`,k===1?``:`s`]})]}),j&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsx)(`span`,{className:m.cardJobName,title:j,children:j})]})]})]}),(0,h.jsxs)(`div`,{className:m.cardTime,children:[N?(0,h.jsx)(`time`,{dateTime:N,title:P,children:S(N)}):(0,h.jsx)(`span`,{title:P,"aria-label":F,children:`—`}),(0,h.jsxs)(`span`,{className:m.cardOverflow,children:[(0,h.jsx)(`button`,{ref:b,type:`button`,className:m.cardOverflowBtn,"aria-label":`Brief actions`,"aria-haspopup":`menu`,"aria-expanded":f,onClick:()=>p(e=>!e),children:`⋮`}),(0,h.jsx)(x,{open:f,triggerRef:b,onEdit:()=>{p(!1),y(!0)},onDelete:()=>{p(!1),i(e)},onCopy:()=>{if(p(!1),typeof navigator>`u`||!navigator.clipboard){console.warn(`[briefs] clipboard unavailable; user can cmd-click the link`);return}navigator.clipboard.writeText(e.url).catch(e=>{console.warn(`[briefs] clipboard write failed`,e)})},onClose:()=>p(!1)})]})]})]})});function E({brief:e,onSave:t,onCancel:n}){let[r,i]=(0,u.useState)(e.userTitle??e.autoTitle??e.title),a=(0,u.useRef)(!1);return(0,h.jsxs)(`div`,{className:m.cardTitleEditor,children:[(0,h.jsx)(`input`,{type:`text`,className:m.cardTitleInput,value:r,onChange:e=>i(e.target.value),autoFocus:!0,"aria-label":`Edit brief title`,onKeyDown:e=>{if(e.key===`Enter`){e.preventDefault();let n=r.trim();a.current=!0,t(n.length===0?null:n)}else e.key===`Escape`&&(e.preventDefault(),n())},onBlur:()=>{a.current||n()}}),e.userTitle&&(0,h.jsx)(`button`,{type:`button`,className:m.cardResetTitle,onMouseDown:e=>{e.preventDefault(),a.current=!0,t(null)},children:`Reset to auto`})]})}var D={toast:`_toast_1kfii_1`,"toast-in":`_toast-in_1kfii_1`,undo:`_undo_1kfii_30`,progress:`_progress_1kfii_54`};function O({message:e,onUndo:t,onDismiss:n,durationMs:r=5e3}){let[i,a]=(0,u.useState)(100),o=(0,u.useRef)(!1);(0,u.useEffect)(()=>{o.current=!1;let e=Date.now(),t=window.setInterval(()=>{let i=Date.now()-e,s=Math.max(0,100-i/r*100);a(s),s<=0&&(window.clearInterval(t),o.current||n())},50);return()=>{o.current=!0,window.clearInterval(t)}},[r,n]);function s(){o.current=!0,t()}return(0,h.jsxs)(`div`,{role:`status`,"aria-live":`polite`,className:D.toast,children:[(0,h.jsx)(`span`,{children:e}),(0,h.jsx)(`button`,{type:`button`,onClick:s,className:D.undo,children:`Undo`}),(0,h.jsx)(`span`,{"aria-hidden":!0,className:D.progress,style:{width:`${i}%`}})]})}var k=[`all`,`notion`,`linear`,`slack-canvas`,`google-docs`,`github-wiki`,`other`];function A(){let[e,t]=(0,u.useState)(`recency`),[n,r]=(0,u.useState)(`all`),[i,a]=(0,u.useState)(``),o=(0,u.useDeferredValue)(i),{briefs:s,loading:c,error:l,refetch:d,patchTitle:f,removeLocal:g,removeNetwork:_,restore:y,suppressUrl:b,unsuppressUrl:x,pulseTokens:S}=p({sort:e,platform:n,q:o.trim()||void 0}),[C,w]=(0,u.useState)(null),[E,D]=(0,u.useState)(null),A=(0,u.useCallback)(async(e,t)=>{try{D(null),await f(e,t)}catch(e){D(e instanceof Error?e.message:String(e))}},[f]);(0,u.useEffect)(()=>{if(!E)return;let e=setTimeout(()=>D(null),5e3);return()=>clearTimeout(e)},[E]);let N=(0,u.useCallback)(e=>{g(e.url),b(e.url),w({url:e.url,brief:e}),_(e.url).catch(t=>{console.warn(`[briefs] DELETE failed; refetching to recover state`,t),x(e.url),w(null),d()})},[g,_,d,b,x]),P=(0,u.useCallback)(async()=>{if(!C)return;let e=C.url;w(null),x(e);try{await y(e)}catch(e){console.warn(`[briefs] restore failed`,e),d()}},[C,d,y,x]),F=(0,u.useCallback)(()=>{C&&(x(C.url),w(null))},[C,x]),I=(0,u.useMemo)(()=>{let e={all:s.length,notion:0,linear:0,"slack-canvas":0,"google-docs":0,"github-wiki":0,other:0};for(let t of s)e[t.platform]+=1;return e},[s]),[L,R]=(0,u.useState)(``);return(0,u.useEffect)(()=>{let e=setTimeout(()=>{R(s.length===0?`No briefs match the current filters.`:`Reading list, ${s.length} ${s.length===1?`brief`:`briefs`} shown.`)},400);return()=>clearTimeout(e)},[e,n,o,s.length]),(0,h.jsxs)(`div`,{className:`page-content-frame ${m.page}`,children:[(0,h.jsx)(`div`,{className:m.header,children:(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`h1`,{className:m.title,children:`Briefs`}),(0,h.jsx)(`p`,{className:m.subtitle,children:`External docs your scheduled agents have written to. Notion pages, Linear issues, Slack canvases, and shared docs, in reverse chronology.`})]})}),(0,h.jsxs)(`div`,{className:m.controls,children:[(0,h.jsxs)(`div`,{className:m.sortToggle,role:`group`,"aria-label":`Sort briefs`,children:[(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`recency`?m.sortBtnActive:``}`,"aria-pressed":e===`recency`,onClick:()=>t(`recency`),children:`Recent`}),(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`frequency`?m.sortBtnActive:``}`,"aria-pressed":e===`frequency`,onClick:()=>t(`frequency`),children:`Frequent`}),(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`mentioned`?m.sortBtnActive:``}`,"aria-pressed":e===`mentioned`,onClick:()=>t(`mentioned`),children:`Mentioned`})]}),(0,h.jsxs)(`label`,{className:m.search,children:[(0,h.jsx)(`span`,{className:m.srOnly,children:`Search briefs`}),(0,h.jsxs)(`svg`,{className:m.searchIcon,viewBox:`0 0 20 20`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,"aria-hidden":`true`,children:[(0,h.jsx)(`circle`,{cx:`9`,cy:`9`,r:`6`}),(0,h.jsx)(`path`,{d:`m17 17-3.5-3.5`,strokeLinecap:`round`})]}),(0,h.jsx)(`input`,{type:`search`,value:i,onChange:e=>a(e.target.value),placeholder:`Search title or domain`,className:m.searchInput})]})]}),(0,h.jsx)(`div`,{className:m.chipRow,role:`group`,"aria-label":`Filter by platform`,children:k.map(e=>{let t=n===e;return(0,h.jsx)(v,{platform:e,active:t,count:e===`all`||t||n===`all`?I[e]:void 0,onClick:()=>r(e)},e)})}),(0,h.jsx)(`div`,{className:m.srOnly,role:`status`,"aria-live":`polite`,children:L}),l&&!c&&(0,h.jsxs)(`div`,{role:`status`,className:m.errorBanner,children:[(0,h.jsxs)(`span`,{children:[`Couldn't load briefs: `,l]}),(0,h.jsx)(`button`,{type:`button`,onClick:d,className:m.errorRetry,children:`Retry`})]}),E&&(0,h.jsxs)(`div`,{role:`status`,className:m.errorBanner,children:[(0,h.jsx)(`span`,{children:`Couldn't save title — try again.`}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>D(null),className:m.errorRetry,children:`Dismiss`})]}),c&&s.length===0?(0,h.jsx)(M,{}):s.length===0?(0,h.jsx)(j,{query:i,platform:n}):(0,h.jsx)(`ol`,{className:m.list,"aria-label":`Briefs`,children:s.map((e,t)=>(0,h.jsx)(T,{brief:e,index:t,onEdit:A,onDelete:N,pulseToken:S.get(e.url)},e.url))}),C&&(0,h.jsx)(O,{message:`Brief hidden`,onUndo:P,onDismiss:F,durationMs:5e3},C.url)]})}function j({query:e,platform:t}){let n=e.trim().length>0||t!==`all`,r=t===`all`?null:g[t].label;return(0,h.jsxs)(`div`,{className:m.empty,children:[(0,h.jsx)(`p`,{className:m.emptyHeadline,children:n?`No briefs match.`:`Nothing on the shelf yet.`}),(0,h.jsx)(`p`,{className:m.emptyBody,children:n?`Try clearing the search${r?` or the ${r} filter`:``}.`:`Once your scheduled agents publish to Notion, Linear, Slack canvases, Docs, or wikis, those entries will collect here as a reading list.`})]})}function M(){return(0,h.jsx)(`ol`,{className:m.list,"aria-label":`Loading briefs`,children:Array.from({length:6}).map((e,t)=>(0,h.jsxs)(`li`,{className:m.skeletonCard,style:{animationDelay:`${t*60}ms`},children:[(0,h.jsx)(`span`,{className:m.skeletonGlyph}),(0,h.jsxs)(`span`,{className:m.skeletonBody,children:[(0,h.jsx)(`span`,{className:m.skeletonTitle}),(0,h.jsx)(`span`,{className:m.skeletonMeta})]}),(0,h.jsx)(`span`,{className:m.skeletonTime})]},t))})}export{A as BriefsPage};
1
+ import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{t as r}from"./react-dom-Cnw6SoYl.js";import{r as i}from"./useWebSocket-Hg3RO6sx.js";import{C as a,E as o,S as s,T as c,w as l}from"./index-DzJsiq8q.js";var u=t(e(),1),d=1e3;function f(e){let t=new URLSearchParams;return t.set(`sort`,e.sort),e.platform&&e.platform!==`all`&&t.set(`platform`,e.platform),e.q&&t.set(`q`,e.q),`/api/briefs?${t.toString()}`}function p(e){let[t,n]=(0,u.useState)([]),[r,a]=(0,u.useState)(!0),[o,s]=(0,u.useState)(null),[c,l]=(0,u.useState)(()=>new Set),[p,m]=(0,u.useState)(()=>new Map),h=(0,u.useRef)(new Map),[,g]=(0,u.useState)(()=>new Set),_=(0,u.useRef)(new Set),v=(0,u.useRef)(null),{sort:y,platform:b,q:x}=e,S=(0,u.useCallback)(()=>{v.current?.abort();let e=new AbortController;v.current=e,a(!0),s(null),fetch(f({sort:y,platform:b,q:x}),{signal:e.signal}).then(e=>e.ok?e.json():Promise.reject(Error(`HTTP ${e.status}`))).then(t=>{e.signal.aborted||n(t.briefs)}).catch(e=>{e instanceof Error&&e.name===`AbortError`||s(e instanceof Error?e.message:String(e))}).finally(()=>{e.signal.aborted||a(!1)})},[y,b,x]);return(0,u.useEffect)(()=>(S(),()=>v.current?.abort()),[S]),i(`brief:updated`,(0,u.useCallback)(e=>{let t=e?.brief;if(!t?.url||_.current.has(t.url)||t.hidden)return;n(e=>{let n=e.findIndex(e=>e.url===t.url);if(n>=0){let r=e.slice();return r[n]=t,r}return[t,...e]}),l(e=>{let n=new Set(e);return n.add(t.url),n}),m(e=>{let n=new Map(e);return n.set(t.url,(e.get(t.url)??0)+1),n});let r=h.current.get(t.url);r&&clearTimeout(r);let i=setTimeout(()=>{h.current.delete(t.url),l(e=>{if(!e.has(t.url))return e;let n=new Set(e);return n.delete(t.url),n})},d);h.current.set(t.url,i)},[])),(0,u.useEffect)(()=>{let e=h.current;return()=>{for(let t of e.values())clearTimeout(t);e.clear()}},[]),i(`brief:deleted`,(0,u.useCallback)(e=>{let t=e?.url;t&&n(e=>e.filter(e=>e.url!==t))},[])),i(`ws:reconnected`,(0,u.useCallback)(()=>{S()},[S])),{briefs:t,loading:r,error:o,recentlyUpdatedUrls:c,pulseTokens:p,refetch:S,patchTitle:(0,u.useCallback)(async(e,t)=>{let n=await fetch(`/api/briefs/${encodeURIComponent(e)}`,{method:`PATCH`,headers:{"content-type":`application/json`},body:JSON.stringify({user_title:t})});if(!n.ok)throw Error(`PATCH failed: ${n.status}`);S()},[S]),removeLocal:(0,u.useCallback)(e=>{n(t=>t.filter(t=>t.url!==e))},[]),removeNetwork:(0,u.useCallback)(async e=>{let t=await fetch(`/api/briefs/${encodeURIComponent(e)}`,{method:`DELETE`});if(!t.ok&&t.status!==404)throw Error(`DELETE failed: ${t.status}`)},[]),restore:(0,u.useCallback)(async e=>{let t=await fetch(`/api/briefs/${encodeURIComponent(e)}/restore`,{method:`POST`});if(!t.ok)throw Error(`restore failed: ${t.status}`);S()},[S]),suppressUrl:(0,u.useCallback)(e=>{if(_.current.has(e))return;let t=new Set(_.current);t.add(e),_.current=t,g(t)},[]),unsuppressUrl:(0,u.useCallback)(e=>{if(!_.current.has(e))return;let t=new Set(_.current);t.delete(e),_.current=t,g(t)},[])}}var m={page:`_page_mkrqf_10`,light:`_light_mkrqf_25`,header:`_header_mkrqf_42`,title:`_title_mkrqf_51`,subtitle:`_subtitle_mkrqf_58`,controls:`_controls_mkrqf_72`,sortToggle:`_sortToggle_mkrqf_81`,sortBtn:`_sortBtn_mkrqf_91`,sortBtnActive:`_sortBtnActive_mkrqf_119`,search:`_search_mkrqf_130`,searchIcon:`_searchIcon_mkrqf_151`,searchInput:`_searchInput_mkrqf_156`,chipRow:`_chipRow_mkrqf_173`,filter:`_filter_mkrqf_180`,filterActive:`_filterActive_mkrqf_209`,filterLabel:`_filterLabel_mkrqf_224`,filterCount:`_filterCount_mkrqf_228`,glyph:`_glyph_mkrqf_241`,glyphSm:`_glyphSm_mkrqf_254`,glyphMd:`_glyphMd_mkrqf_260`,list:`_list_mkrqf_268`,card:`_card_mkrqf_282`,"brief-card-in":`_brief-card-in_mkrqf_1`,cardPulse:`_cardPulse_mkrqf_312`,"brief-pulse":`_brief-pulse_mkrqf_1`,cardGlyph:`_cardGlyph_mkrqf_316`,cardBody:`_cardBody_mkrqf_320`,cardTitle:`_cardTitle_mkrqf_324`,cardTitleLink:`_cardTitleLink_mkrqf_333`,cardTitleFallback:`_cardTitleFallback_mkrqf_350`,cardMeta:`_cardMeta_mkrqf_355`,cardHost:`_cardHost_mkrqf_366`,cardWrites:`_cardWrites_mkrqf_372`,cardRefs:`_cardRefs_mkrqf_378`,cardJobLink:`_cardJobLink_mkrqf_382`,cardJobName:`_cardJobName_mkrqf_407`,cardDot:`_cardDot_mkrqf_416`,cardTime:`_cardTime_mkrqf_421`,cardOverflow:`_cardOverflow_mkrqf_434`,cardOverflowBtn:`_cardOverflowBtn_mkrqf_439`,cardTitleEditor:`_cardTitleEditor_mkrqf_481`,cardTitleInput:`_cardTitleInput_mkrqf_488`,cardResetTitle:`_cardResetTitle_mkrqf_508`,errorBanner:`_errorBanner_mkrqf_536`,errorRetry:`_errorRetry_mkrqf_550`,empty:`_empty_mkrqf_575`,emptyHeadline:`_emptyHeadline_mkrqf_583`,emptyBody:`_emptyBody_mkrqf_590`,skeletonCard:`_skeletonCard_mkrqf_600`,skeletonGlyph:`_skeletonGlyph_mkrqf_614`,"brief-shimmer":`_brief-shimmer_mkrqf_1`,skeletonBody:`_skeletonBody_mkrqf_628`,skeletonTitle:`_skeletonTitle_mkrqf_635`,skeletonMeta:`_skeletonMeta_mkrqf_649`,skeletonTime:`_skeletonTime_mkrqf_663`,srOnly:`_srOnly_mkrqf_672`},h=n(),g={notion:{letter:`N`,label:`Notion`,tintVar:`--p-notion`},linear:{letter:`L`,label:`Linear`,tintVar:`--p-linear`},"slack-canvas":{letter:`S`,label:`Slack canvas`,tintVar:`--p-slack`},"google-docs":{letter:`G`,label:`Google Docs`,tintVar:`--p-gdocs`},"github-wiki":{letter:`W`,label:`GitHub wiki`,tintVar:`--p-wiki`},other:{letter:`·`,label:`Other`,tintVar:`--p-other`}};function _({platform:e,size:t=`sm`}){let n=g[e];return(0,h.jsx)(`span`,{className:[m.glyph,t===`md`?m.glyphMd:m.glyphSm].join(` `),style:{"--glyph-tint":`var(${n.tintVar})`},"aria-label":n.label,title:n.label,children:(0,h.jsx)(`span`,{"aria-hidden":`true`,children:n.letter})})}function v({platform:e,active:t,count:n,onClick:r}){let i=e===`all`?`All`:g[e].label,a=e===`all`?`--p-all`:g[e].tintVar;return(0,h.jsxs)(`button`,{type:`button`,className:`${m.filter} ${t?m.filterActive:``}`,onClick:r,"aria-pressed":t,style:{"--filter-tint":`var(${a})`},children:[e!==`all`&&(0,h.jsx)(_,{platform:e,size:`sm`}),(0,h.jsx)(`span`,{className:m.filterLabel,children:i}),typeof n==`number`&&n>0&&(0,h.jsx)(`span`,{className:m.filterCount,children:n})]})}var y=t(r(),1),b={menu:`_menu_d9qv0_6`,item:`_item_d9qv0_18`,danger:`_danger_d9qv0_43`};function x({open:e,onEdit:t,onDelete:n,onCopy:r,onClose:i,triggerRef:d}){let{refs:f,floatingStyles:p}=c({open:e,placement:`bottom-end`,whileElementsMounted:o,middleware:[a(4),s({padding:8}),l({padding:8})]});return(0,u.useEffect)(()=>{f.setReference(d.current??null)},[f,d]),(0,u.useEffect)(()=>{if(!e)return;let t=e=>{let t=e.target;if(d.current?.contains(t))return;let n=f.floating.current;n&&!n.contains(t)&&i()},n=e=>{e.key===`Escape`&&i()};return document.addEventListener(`mousedown`,t),document.addEventListener(`keydown`,n),()=>{document.removeEventListener(`mousedown`,t),document.removeEventListener(`keydown`,n)}},[e,i,d,f.floating]),e?(0,y.createPortal)((0,h.jsxs)(`ul`,{ref:f.setFloating,role:`menu`,className:b.menu,style:p,children:[(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:t,className:b.item,children:`Edit title`})}),(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:n,className:`${b.item} ${b.danger}`,children:`Delete`})}),(0,h.jsx)(`li`,{children:(0,h.jsx)(`button`,{type:`button`,role:`menuitem`,onClick:r,className:b.item,children:`Copy link`})})]}),document.body):null}function S(e){if(!e)return`never`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Date.now()-t,r=Math.round(n/6e4);if(r<1)return`just now`;if(r<60)return`${r}m`;let i=Math.round(r/60);if(i<24)return`${i}h`;let a=Math.round(i/24);if(a<7)return`${a}d`;let o=Math.round(a/7);if(o<5)return`${o}w`;let s=Math.round(a/30);return s<12?`${s}mo`:`${Math.round(s/12)}y`}function C(e){try{return new URL(e).hostname.replace(/^www\./,``)}catch{return``}}function w(e){let t=e?.trim();return!t||/^#?\d+\s*-\s*cd\s+\//.test(t)||/^cd\s+\//.test(t)||/^\//.test(t)?null:t}var T=(0,u.memo)(function({brief:e,pulseToken:t,index:n,onEdit:r,onDelete:i}){let a=e.title.trim()||C(e.url)||e.url,o=!e.userTitle?.trim(),s=g[e.platform],[c,l]=(0,u.useState)(!1),d=(0,u.useRef)(void 0);(0,u.useEffect)(()=>{if(t===void 0||t===d.current)return;d.current=t,l(!0);let e=setTimeout(()=>l(!1),900);return()=>clearTimeout(e)},[t]);let[f,p]=(0,u.useState)(!1),[v,y]=(0,u.useState)(!1),b=(0,u.useRef)(null),T=/^https?:\/\//i.test(e.url),D=T?e.url:`#`,O=e.writeCount,k=e.referenceCount,A=O===1?`write`:`writes`,j=w(e.lastWriteJob),M=e.lastWriteAt,N=M??e.lastReferenceAt,P=N?new Date(N).toLocaleString():`No activity yet`,F=M?`Never written`:`Never referenced`;return(0,h.jsxs)(`li`,{className:[m.card,c?m.cardPulse:``].filter(Boolean).join(` `),style:{animationDelay:`${Math.min(n,12)*28}ms`,"--card-tint":`var(${s.tintVar})`},children:[(0,h.jsx)(`div`,{className:m.cardGlyph,"aria-hidden":`true`,children:(0,h.jsx)(_,{platform:e.platform,size:`md`})}),(0,h.jsxs)(`div`,{className:m.cardBody,children:[v?(0,h.jsx)(E,{brief:e,onSave:async t=>{y(!1),await r(e.url,t)},onCancel:()=>y(!1)}):(0,h.jsx)(`h2`,{className:m.cardTitle,children:(0,h.jsx)(`a`,{href:D,target:`_blank`,rel:`noopener noreferrer`,onClick:T?void 0:e=>e.preventDefault(),className:[m.cardTitleLink,o?m.cardTitleFallback:``].filter(Boolean).join(` `),children:a})}),(0,h.jsxs)(`p`,{className:m.cardMeta,children:[(0,h.jsx)(`span`,{className:m.cardHost,children:C(e.url)}),(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsxs)(`span`,{className:m.cardWrites,children:[(0,h.jsx)(`strong`,{children:O}),` `,A]}),k>0&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsxs)(`span`,{className:m.cardRefs,children:[k,` ref`,k===1?``:`s`]})]}),j&&(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(`span`,{className:m.cardDot,"aria-hidden":`true`,children:`·`}),(0,h.jsx)(`span`,{className:m.cardJobName,title:j,children:j})]})]})]}),(0,h.jsxs)(`div`,{className:m.cardTime,children:[N?(0,h.jsx)(`time`,{dateTime:N,title:P,children:S(N)}):(0,h.jsx)(`span`,{title:P,"aria-label":F,children:`—`}),(0,h.jsxs)(`span`,{className:m.cardOverflow,children:[(0,h.jsx)(`button`,{ref:b,type:`button`,className:m.cardOverflowBtn,"aria-label":`Brief actions`,"aria-haspopup":`menu`,"aria-expanded":f,onClick:()=>p(e=>!e),children:`⋮`}),(0,h.jsx)(x,{open:f,triggerRef:b,onEdit:()=>{p(!1),y(!0)},onDelete:()=>{p(!1),i(e)},onCopy:()=>{if(p(!1),typeof navigator>`u`||!navigator.clipboard){console.warn(`[briefs] clipboard unavailable; user can cmd-click the link`);return}navigator.clipboard.writeText(e.url).catch(e=>{console.warn(`[briefs] clipboard write failed`,e)})},onClose:()=>p(!1)})]})]})]})});function E({brief:e,onSave:t,onCancel:n}){let[r,i]=(0,u.useState)(e.userTitle??e.autoTitle??e.title),a=(0,u.useRef)(!1);return(0,h.jsxs)(`div`,{className:m.cardTitleEditor,children:[(0,h.jsx)(`input`,{type:`text`,className:m.cardTitleInput,value:r,onChange:e=>i(e.target.value),autoFocus:!0,"aria-label":`Edit brief title`,onKeyDown:e=>{if(e.key===`Enter`){e.preventDefault();let n=r.trim();a.current=!0,t(n.length===0?null:n)}else e.key===`Escape`&&(e.preventDefault(),n())},onBlur:()=>{a.current||n()}}),e.userTitle&&(0,h.jsx)(`button`,{type:`button`,className:m.cardResetTitle,onMouseDown:e=>{e.preventDefault(),a.current=!0,t(null)},children:`Reset to auto`})]})}var D={toast:`_toast_1kfii_1`,"toast-in":`_toast-in_1kfii_1`,undo:`_undo_1kfii_30`,progress:`_progress_1kfii_54`};function O({message:e,onUndo:t,onDismiss:n,durationMs:r=5e3}){let[i,a]=(0,u.useState)(100),o=(0,u.useRef)(!1);(0,u.useEffect)(()=>{o.current=!1;let e=Date.now(),t=window.setInterval(()=>{let i=Date.now()-e,s=Math.max(0,100-i/r*100);a(s),s<=0&&(window.clearInterval(t),o.current||n())},50);return()=>{o.current=!0,window.clearInterval(t)}},[r,n]);function s(){o.current=!0,t()}return(0,h.jsxs)(`div`,{role:`status`,"aria-live":`polite`,className:D.toast,children:[(0,h.jsx)(`span`,{children:e}),(0,h.jsx)(`button`,{type:`button`,onClick:s,className:D.undo,children:`Undo`}),(0,h.jsx)(`span`,{"aria-hidden":!0,className:D.progress,style:{width:`${i}%`}})]})}var k=[`all`,`notion`,`linear`,`slack-canvas`,`google-docs`,`github-wiki`,`other`];function A(){let[e,t]=(0,u.useState)(`recency`),[n,r]=(0,u.useState)(`all`),[i,a]=(0,u.useState)(``),o=(0,u.useDeferredValue)(i),{briefs:s,loading:c,error:l,refetch:d,patchTitle:f,removeLocal:g,removeNetwork:_,restore:y,suppressUrl:b,unsuppressUrl:x,pulseTokens:S}=p({sort:e,platform:n,q:o.trim()||void 0}),[C,w]=(0,u.useState)(null),[E,D]=(0,u.useState)(null),A=(0,u.useCallback)(async(e,t)=>{try{D(null),await f(e,t)}catch(e){D(e instanceof Error?e.message:String(e))}},[f]);(0,u.useEffect)(()=>{if(!E)return;let e=setTimeout(()=>D(null),5e3);return()=>clearTimeout(e)},[E]);let N=(0,u.useCallback)(e=>{g(e.url),b(e.url),w({url:e.url,brief:e}),_(e.url).catch(t=>{console.warn(`[briefs] DELETE failed; refetching to recover state`,t),x(e.url),w(null),d()})},[g,_,d,b,x]),P=(0,u.useCallback)(async()=>{if(!C)return;let e=C.url;w(null),x(e);try{await y(e)}catch(e){console.warn(`[briefs] restore failed`,e),d()}},[C,d,y,x]),F=(0,u.useCallback)(()=>{C&&(x(C.url),w(null))},[C,x]),I=(0,u.useMemo)(()=>{let e={all:s.length,notion:0,linear:0,"slack-canvas":0,"google-docs":0,"github-wiki":0,other:0};for(let t of s)e[t.platform]+=1;return e},[s]),[L,R]=(0,u.useState)(``);return(0,u.useEffect)(()=>{let e=setTimeout(()=>{R(s.length===0?`No briefs match the current filters.`:`Reading list, ${s.length} ${s.length===1?`brief`:`briefs`} shown.`)},400);return()=>clearTimeout(e)},[e,n,o,s.length]),(0,h.jsxs)(`div`,{className:`page-content-frame ${m.page}`,children:[(0,h.jsx)(`div`,{className:m.header,children:(0,h.jsxs)(`div`,{children:[(0,h.jsx)(`h1`,{className:m.title,children:`Briefs`}),(0,h.jsx)(`p`,{className:m.subtitle,children:`External docs your scheduled agents have written to. Notion pages, Linear issues, Slack canvases, and shared docs, in reverse chronology.`})]})}),(0,h.jsxs)(`div`,{className:m.controls,children:[(0,h.jsxs)(`div`,{className:m.sortToggle,role:`group`,"aria-label":`Sort briefs`,children:[(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`recency`?m.sortBtnActive:``}`,"aria-pressed":e===`recency`,onClick:()=>t(`recency`),children:`Recent`}),(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`frequency`?m.sortBtnActive:``}`,"aria-pressed":e===`frequency`,onClick:()=>t(`frequency`),children:`Frequent`}),(0,h.jsx)(`button`,{type:`button`,className:`${m.sortBtn} ${e===`mentioned`?m.sortBtnActive:``}`,"aria-pressed":e===`mentioned`,onClick:()=>t(`mentioned`),children:`Mentioned`})]}),(0,h.jsxs)(`label`,{className:m.search,children:[(0,h.jsx)(`span`,{className:m.srOnly,children:`Search briefs`}),(0,h.jsxs)(`svg`,{className:m.searchIcon,viewBox:`0 0 20 20`,width:`14`,height:`14`,fill:`none`,stroke:`currentColor`,strokeWidth:`1.5`,"aria-hidden":`true`,children:[(0,h.jsx)(`circle`,{cx:`9`,cy:`9`,r:`6`}),(0,h.jsx)(`path`,{d:`m17 17-3.5-3.5`,strokeLinecap:`round`})]}),(0,h.jsx)(`input`,{type:`search`,value:i,onChange:e=>a(e.target.value),placeholder:`Search title or domain`,className:m.searchInput})]})]}),(0,h.jsx)(`div`,{className:m.chipRow,role:`group`,"aria-label":`Filter by platform`,children:k.map(e=>{let t=n===e;return(0,h.jsx)(v,{platform:e,active:t,count:e===`all`||t||n===`all`?I[e]:void 0,onClick:()=>r(e)},e)})}),(0,h.jsx)(`div`,{className:m.srOnly,role:`status`,"aria-live":`polite`,children:L}),l&&!c&&(0,h.jsxs)(`div`,{role:`status`,className:m.errorBanner,children:[(0,h.jsxs)(`span`,{children:[`Couldn't load briefs: `,l]}),(0,h.jsx)(`button`,{type:`button`,onClick:d,className:m.errorRetry,children:`Retry`})]}),E&&(0,h.jsxs)(`div`,{role:`status`,className:m.errorBanner,children:[(0,h.jsx)(`span`,{children:`Couldn't save title — try again.`}),(0,h.jsx)(`button`,{type:`button`,onClick:()=>D(null),className:m.errorRetry,children:`Dismiss`})]}),c&&s.length===0?(0,h.jsx)(M,{}):s.length===0?(0,h.jsx)(j,{query:i,platform:n}):(0,h.jsx)(`ol`,{className:m.list,"aria-label":`Briefs`,children:s.map((e,t)=>(0,h.jsx)(T,{brief:e,index:t,onEdit:A,onDelete:N,pulseToken:S.get(e.url)},e.url))}),C&&(0,h.jsx)(O,{message:`Brief hidden`,onUndo:P,onDismiss:F,durationMs:5e3},C.url)]})}function j({query:e,platform:t}){let n=e.trim().length>0||t!==`all`,r=t===`all`?null:g[t].label;return(0,h.jsxs)(`div`,{className:m.empty,children:[(0,h.jsx)(`p`,{className:m.emptyHeadline,children:n?`No briefs match.`:`Nothing on the shelf yet.`}),(0,h.jsx)(`p`,{className:m.emptyBody,children:n?`Try clearing the search${r?` or the ${r} filter`:``}.`:`Once your scheduled agents publish to Notion, Linear, Slack canvases, Docs, or wikis, those entries will collect here as a reading list.`})]})}function M(){return(0,h.jsx)(`ol`,{className:m.list,"aria-label":`Loading briefs`,children:Array.from({length:6}).map((e,t)=>(0,h.jsxs)(`li`,{className:m.skeletonCard,style:{animationDelay:`${t*60}ms`},children:[(0,h.jsx)(`span`,{className:m.skeletonGlyph}),(0,h.jsxs)(`span`,{className:m.skeletonBody,children:[(0,h.jsx)(`span`,{className:m.skeletonTitle}),(0,h.jsx)(`span`,{className:m.skeletonMeta})]}),(0,h.jsx)(`span`,{className:m.skeletonTime})]},t))})}export{A as BriefsPage};
@@ -1,4 +1,4 @@
1
- import{n as e,r as t,s as n,t as r}from"./jsx-runtime-Bq3x7umQ.js";import{r as i,t as a}from"./useWebSocket-Hg3RO6sx.js";import{c as o,n as s}from"./styles-Ds5gMQAQ.js";import{_ as c,v as l,y as u}from"./events-CCBP4a9s.js";import{n as d}from"./Input-HhV6M0tu.js";import{It as f,Nt as p,Pt as m,en as h}from"./index-tOLuwPW6.js";import{n as g,t as _}from"./lib-osArdP58.js";var v=n(e(),1);function y(e,t){return(t?[...e,t]:e).filter(Boolean).join(`
1
+ import{n as e,r as t,s as n,t as r}from"./jsx-runtime-Bq3x7umQ.js";import{r as i,t as a}from"./useWebSocket-Hg3RO6sx.js";import{c as o,n as s}from"./styles-Ds5gMQAQ.js";import{_ as c,v as l,y as u}from"./events-BK5ucyUu.js";import{n as d}from"./Input-iymdcwsf.js";import{Ft as f,Mt as p,Nt as m,tn as h}from"./index-DzJsiq8q.js";import{n as g,t as _}from"./lib-CncUdc6D.js";var v=n(e(),1);function y(e,t){return(t?[...e,t]:e).filter(Boolean).join(`
2
2
 
3
3
  `)}function b(e){let[t,n]=(0,v.useState)(``),[r,a]=(0,v.useState)([]),[o,s]=(0,v.useState)(!1),c=(0,v.useRef)([]),l=(0,v.useRef)(``);return(0,v.useEffect)(()=>{n(``),a([]),s(!1),c.current=[],l.current=``},[e]),i(`session:delta`,(0,v.useCallback)(t=>{let r=t;!e||r.sessionId!==e||(s(!0),a(e=>[...e,r]),r.type===`text`?(l.current+=r.content,n(y(c.current,l.current))):r.type===`text_snapshot`&&(r.content&&(c.current=[...c.current,r.content]),l.current=``,n(y(c.current,``))))},[e])),i(`session:completed`,(0,v.useCallback)(t=>{e&&t.sessionId===e&&s(!1)},[e])),i(`session:error`,(0,v.useCallback)(t=>{e&&t.sessionId===e&&s(!1)},[e])),i(`session:stopped`,(0,v.useCallback)(t=>{e&&t.sessionId===e&&s(!1)},[e])),{text:t,events:r,isActive:o,clear:(0,v.useCallback)(()=>{n(``),a([]),c.current=[],l.current=``},[])}}function x(e){let[t,n]=(0,v.useState)([]),[r,a]=(0,v.useState)(0),[o,s]=(0,v.useState)(!1),u=(0,v.useRef)(null);return u.current=e,(0,v.useEffect)(()=>{let t=!1;if(n([]),a(0),e)return s(!0),fetch(`/api/sessions/${e}/jsonl`).then(e=>e.ok?e.json():Promise.reject(Error(`HTTP ${e.status}`))).then(r=>{t||u.current!==e||(n(r.events??[]),a(r.nextOffset??0))}).catch(()=>{}).finally(()=>{t||s(!1)}),()=>{t=!0}},[e]),i(c,(0,v.useCallback)(e=>{let t=e;!u.current||t.sessionId!==u.current||!Array.isArray(t.events)||t.events.length===0||(n(e=>[...e,...t.events??[]]),typeof t.nextOffset==`number`&&a(t.nextOffset))},[])),i(l,(0,v.useCallback)(e=>{let t=e,r=u.current;!r||t.sessionId!==r||(n([]),a(0),fetch(`/api/sessions/${r}/jsonl`).then(e=>e.ok?e.json():Promise.reject(Error(`HTTP ${e.status}`))).then(e=>{u.current===r&&(n(e.events??[]),a(e.nextOffset??0))}).catch(()=>{}))},[])),i(`ws:reconnected`,(0,v.useCallback)(()=>{let e=u.current;e&&fetch(`/api/sessions/${e}/jsonl`).then(e=>e.ok?e.json():Promise.reject(Error(`HTTP ${e.status}`))).then(t=>{u.current===e&&(n(t.events??[]),a(t.nextOffset??0))}).catch(()=>{})},[])),{events:t,loading:o,nextOffset:r}}var S=new Set([`INPUT`,`TEXTAREA`]);function C(e){(0,v.useEffect)(()=>{if(typeof window>`u`)return;let t=window.visualViewport??null,n=()=>{let n=document.querySelector(`.tw-chat-page`);if(!n||n.offsetParent===null)return;let r=t?Math.max(0,window.innerHeight-t.height-t.offsetTop):0,i=document.activeElement,a=!!i&&n.contains(i)&&S.has(i.tagName),o=r>0||a;document.documentElement.style.setProperty(`--tw-keyboard-inset`,`${r}px`),o?document.body.setAttribute(`data-keyboard-up`,`true`):document.body.removeAttribute(`data-keyboard-up`);let s=e.current;s&&s.scrollHeight-s.clientHeight-s.scrollTop<200&&(s.scrollTop=s.scrollHeight)};return t&&(t.addEventListener(`resize`,n),t.addEventListener(`scroll`,n)),document.addEventListener(`focusin`,n),document.addEventListener(`focusout`,n),n(),()=>{t&&(t.removeEventListener(`resize`,n),t.removeEventListener(`scroll`,n)),document.removeEventListener(`focusin`,n),document.removeEventListener(`focusout`,n),document.documentElement.style.setProperty(`--tw-keyboard-inset`,`0px`),document.body.removeAttribute(`data-keyboard-up`)}},[e])}function w(e,t,n){(0,v.useEffect)(()=>{if(e.length===0||t.length===0)return;let r=[];for(let e of t)e.kind===`user-text`&&!e.sidechain&&r.push(e.text);if(r.length===0)return;let i=new Map;for(let e of r)i.set(e,(i.get(e)??0)+1);let a=[];for(let t of e){let e=i.get(t.content)??0;e>0?i.set(t.content,e-1):a.push(t)}a.length<e.length&&n(a)},[t,e,n])}function T(){let[e,t]=(0,v.useState)(`normal`);return{mode:e,toNormal:(0,v.useCallback)(()=>t(`normal`),[]),toScroll:(0,v.useCallback)(()=>t(`scroll`),[]),toPassthrough:(0,v.useCallback)(()=>t(`passthrough`),[])}}var E=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r){setTimeout(function(){r(e)},0);return}else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,h=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let h=c&&c.oldPos+1<o;if(!u&&!h){d[r]=void 0;continue}if(s=!h||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);h()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=h();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}};new class extends E{};function D(e,t){let n;for(n=0;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function O(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function k(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function A(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function j(e,t){return k(e,t,``)}function M(e,t){return A(e,t,``)}function N(e,t){return t.slice(0,P(e,t))}function P(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function F(e,t){let n=[];for(let r of Array.from(t.segment(e))){let e=r.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}return n}function I(e,t){if(t)return R(e,t)[1];let n;for(n=e.length-1;n>=0&&e[n].match(/\s/);n--);return e.substring(n+1)}function L(e,t){if(t)return R(e,t)[0];let n=e.match(/^\s*/);return n?n[0]:``}function R(e,t){if(!t)return[L(e),I(e)];if(t.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);let n=F(e,t),r=n[0],i=n[n.length-1];return[/\s/.test(r)?r:``,/\s/.test(i)?i:``]}var z=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,ee=RegExp(`[${z}]+|\\s+|[^${z}]`,`ug`);new class extends E{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=F(e,r)}else n=e.match(ee)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&te(n,i,r,e,t.intlSegmenter),n=e,r=null,i=null)}),(r||i)&&te(n,i,r,null,t.intlSegmenter),e}};function te(e,t,n,r,i){if(t&&n){let[a,o]=R(t.value,i),[s,c]=R(n.value,i);if(e){let r=D(a,s);e.value=A(e.value,s,r),t.value=j(t.value,r),n.value=j(n.value,r)}if(r){let e=O(o,c);r.value=k(r.value,c,e),t.value=M(t.value,e),n.value=M(n.value,e)}}else if(n){if(e){let e=L(n.value,i);n.value=n.value.substring(e.length)}if(r){let e=L(r.value,i);r.value=r.value.substring(e.length)}}else if(e&&r){let n=L(r.value,i),[a,o]=R(t.value,i),s=D(n,a);t.value=j(t.value,s);let c=O(j(n,s),o);t.value=M(t.value,c),r.value=k(r.value,n,c),e.value=A(e.value,n,n.slice(0,n.length-c.length))}else if(r){let e=L(r.value,i),n=N(I(t.value,i),e);t.value=M(t.value,n)}else if(e){let n=N(I(e.value,i),L(t.value,i));t.value=j(t.value,n)}}new class extends E{tokenize(e){let t=RegExp(`(\\r?\\n)|[${z}]+|[^\\S\\n\\r]+|[^${z}]`,`ug`);return e.match(t)||[]}};var ne=new class extends E{constructor(){super(...arguments),this.tokenize=B}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
4
4
  `))&&(e=e.trim()),(!n.newlineIsToken||!t.includes(`
@@ -1 +1 @@
1
- import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{r}from"./useWebSocket-Hg3RO6sx.js";import{a as i,c as a,i as o,n as s,o as c,r as l,s as u}from"./events-CCBP4a9s.js";import{t as d}from"./Card-u29day7d.js";import{r as f,t as p}from"./Input-HhV6M0tu.js";import{t as m}from"./Button-xBBZQ0ie.js";import{gt as h}from"./index-tOLuwPW6.js";var g=t(e(),1);function _(){let[e,t]=(0,g.useState)(null),[n,d]=(0,g.useState)(!0),[f,p]=(0,g.useState)(null),m=(0,g.useCallback)(async()=>{d(!0);try{let e=await fetch(`/api/continuous-improvement`);if(!e.ok)throw Error(`HTTP ${e.status}`);t(await e.json()),p(null)}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[]);(0,g.useEffect)(()=>{m()},[m]);let h=(0,g.useCallback)(()=>{m()},[m]);return r(s,h),r(o,h),r(c,h),r(i,h),r(u,h),r(l,h),r(a,h),{status:e,loading:n,error:f,refresh:m,runNow:(0,g.useCallback)(async(e,t)=>{await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}/run`,{method:`POST`}),await m()},[m]),setEnabled:(0,g.useCallback)(async(e,t,n)=>{await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:n})}),await m()},[m])}}var v={modal:`_modal_e9k39_1`,title:`_title_e9k39_14`,form:`_form_e9k39_15`,field:`_field_e9k39_16`,label:`_label_e9k39_17`,hint:`_hint_e9k39_18`,error:`_error_e9k39_19`,buttons:`_buttons_e9k39_20`},y=n();function b({categoryId:e,status:t,onClose:n,onSave:r}){let{config:i}=t,a=i.invocation?.kind===`rawPrompt`?i.invocation.prompt:``,[o,s]=(0,g.useState)(i.schedule),[c,l]=(0,g.useState)(a),[u,d]=(0,g.useState)(!1),[_,b]=(0,g.useState)(null);async function x(e){e.preventDefault(),d(!0),b(null);try{let e={};o!==i.schedule&&(e.schedule=o),c!==a&&c.length>0&&(e.invocation={kind:`rawPrompt`,prompt:c}),await r(e),n()}catch(e){b(e instanceof Error?e.message:String(e))}finally{d(!1)}}return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(h,{onClick:n}),(0,y.jsxs)(`div`,{className:v.modal,role:`dialog`,"aria-modal":`true`,"aria-label":`Edit ${e}`,children:[(0,y.jsxs)(`h2`,{className:v.title,children:[`Edit category: `,e]}),(0,y.jsxs)(`form`,{onSubmit:e=>void x(e),className:v.form,children:[(0,y.jsxs)(`label`,{className:v.field,children:[(0,y.jsx)(`span`,{className:v.label,children:`Cron schedule`}),(0,y.jsx)(p,{value:o,onChange:e=>s(e.target.value),placeholder:`0 */6 * * *`,required:!0}),(0,y.jsx)(`span`,{className:v.hint,children:`Standard cron expression (5 fields)`})]}),(0,y.jsxs)(`label`,{className:v.field,children:[(0,y.jsx)(`span`,{className:v.label,children:`Extra prompt (optional)`}),(0,y.jsx)(f,{value:c,onChange:e=>l(e.target.value),placeholder:`Additional instructions to include in the improvement prompt...`,rows:4})]}),_&&(0,y.jsx)(`p`,{className:v.error,children:_}),(0,y.jsxs)(`div`,{className:v.buttons,children:[(0,y.jsx)(m,{type:`button`,variant:`ghost`,onClick:n,children:`Cancel`}),(0,y.jsx)(m,{type:`submit`,variant:`primary`,disabled:u,children:u?`Saving...`:`Save`})]})]})]})]})}var x={card:`_card_1h4sl_1`,header:`_header_1h4sl_2`,categoryId:`_categoryId_1h4sl_3`,actions:`_actions_1h4sl_4`,inFlightBadge:`_inFlightBadge_1h4sl_5`,meta:`_meta_1h4sl_10`,metaItem:`_metaItem_1h4sl_11`};function S({categoryId:e,status:t,onToggle:n,onRunNow:r,onSave:i}){let{config:a,state:o}=t,[s,c]=(0,g.useState)(!1),l=o.lastRunAt?new Date(o.lastRunAt).toLocaleString():`never`,u=o.trustState;return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(d,{padding:`sm`,variant:`sunken`,className:x.card,children:[(0,y.jsxs)(`div`,{className:x.header,children:[(0,y.jsx)(`span`,{className:x.categoryId,children:e}),(0,y.jsxs)(`div`,{className:x.actions,children:[o.inFlight&&(0,y.jsxs)(`a`,{href:o.inFlight.prUrl,target:`_blank`,rel:`noreferrer`,className:x.inFlightBadge,children:[`PR #`,o.inFlight.prNumber,` open`]}),(0,y.jsx)(m,{size:`sm`,variant:a.enabled?`default`:`ghost`,onClick:()=>void n(!a.enabled),children:a.enabled?`Enabled`:`Disabled`}),(0,y.jsx)(m,{size:`sm`,variant:`ghost`,onClick:()=>c(!0),children:`Edit`}),(0,y.jsx)(m,{size:`sm`,variant:`primary`,onClick:()=>void r(),disabled:!!o.inFlight,children:`Run now`})]})]}),(0,y.jsxs)(`div`,{className:x.meta,children:[(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Schedule: `,a.scheduleHuman??a.schedule]}),(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Last run: `,l]}),(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Clean PRs: `,u.consecutiveCleanPRs,` \xA0|\xA0 Merged: `,u.totalMerged,` \xA0|\xA0 Rejected: `,u.totalRejected]})]})]}),s&&(0,y.jsx)(b,{categoryId:e,status:t,onClose:()=>c(!1),onSave:i})]})}var C={card:`_card_1e41q_1`,header:`_header_1e41q_2`,projectInfo:`_projectInfo_1e41q_3`,projectName:`_projectName_1e41q_4`,projectPath:`_projectPath_1e41q_5`,projectBranch:`_projectBranch_1e41q_6`,categories:`_categories_1e41q_7`,empty:`_empty_1e41q_8`};function w({projectId:e,status:t,onToggleCategory:n,onRunCategory:r,onSaveCategory:i,onRemove:a}){let{config:o,categories:s}=t,c=Object.entries(s);return(0,y.jsxs)(d,{padding:`md`,className:C.card,children:[(0,y.jsxs)(`div`,{className:C.header,children:[(0,y.jsxs)(`div`,{className:C.projectInfo,children:[(0,y.jsx)(`span`,{className:C.projectName,children:o.name}),(0,y.jsx)(`span`,{className:C.projectPath,children:o.path}),(0,y.jsxs)(`span`,{className:C.projectBranch,children:[`branch: `,o.mainBranch]})]}),(0,y.jsx)(m,{size:`sm`,variant:`danger`,onClick:()=>void a(),children:`Remove`})]}),c.length===0?(0,y.jsxs)(`p`,{className:C.empty,children:[`No categories configured. Enable one with: `,(0,y.jsxs)(`code`,{children:[`teamos ci enable `,e,` <category>`]})]}):(0,y.jsx)(`div`,{className:C.categories,children:c.map(([t,a])=>(0,y.jsx)(S,{projectId:e,categoryId:t,status:a,onToggle:e=>n(t,e),onRunNow:()=>r(t),onSave:e=>i(t,e)},t))})]})}var T={modal:`_modal_1oevh_1`,title:`_title_1oevh_14`,form:`_form_1oevh_15`,field:`_field_1oevh_16`,label:`_label_1oevh_17`,error:`_error_1oevh_18`,buttons:`_buttons_1oevh_19`};function E({onClose:e,onAdd:t}){let[n,r]=(0,g.useState)(``),[i,a]=(0,g.useState)(``),[o,s]=(0,g.useState)(`main`),[c,l]=(0,g.useState)(!1),[u,d]=(0,g.useState)(null);async function f(r){if(r.preventDefault(),n.trim()){l(!0),d(null);try{await t(n.trim(),i.trim(),o.trim()||`main`),e()}catch(e){d(e instanceof Error?e.message:String(e))}finally{l(!1)}}}return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(h,{onClick:e}),(0,y.jsxs)(`div`,{className:T.modal,role:`dialog`,"aria-modal":`true`,"aria-label":`Add project`,children:[(0,y.jsx)(`h2`,{className:T.title,children:`Add project`}),(0,y.jsxs)(`form`,{onSubmit:e=>void f(e),className:T.form,children:[(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Absolute path`}),(0,y.jsx)(p,{value:n,onChange:e=>r(e.target.value),placeholder:`/Users/me/Projects/my-app`,required:!0})]}),(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Name (optional)`}),(0,y.jsx)(p,{value:i,onChange:e=>a(e.target.value),placeholder:`my-app`})]}),(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Main branch`}),(0,y.jsx)(p,{value:o,onChange:e=>s(e.target.value),placeholder:`main`})]}),u&&(0,y.jsx)(`p`,{className:T.error,children:u}),(0,y.jsxs)(`div`,{className:T.buttons,children:[(0,y.jsx)(m,{type:`button`,variant:`ghost`,onClick:e,children:`Cancel`}),(0,y.jsx)(m,{type:`submit`,variant:`primary`,disabled:c||!n.trim(),children:c?`Adding...`:`Add project`})]})]})]})]})}var D={page:`_page_1hl41_1`,header:`_header_1hl41_2`,h1:`_h1_1hl41_3`,headerActions:`_headerActions_1hl41_4`,error:`_error_1hl41_5`,empty:`_empty_1hl41_6`,emptyHint:`_emptyHint_1hl41_7`,projects:`_projects_1hl41_8`};function O(){let{status:e,loading:t,error:n,refresh:r,runNow:i,setEnabled:a}=_(),[o,s]=(0,g.useState)(!1),c=e?.projects??{},l=Object.entries(c);async function u(e,t,n){let i=await fetch(`/api/continuous-improvement/projects`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t,path:e,mainBranch:n})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await r()}async function d(e){await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}`,{method:`DELETE`}),await r()}async function f(e,t,n){let i=await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await r()}return(0,y.jsxs)(`div`,{className:D.page,children:[(0,y.jsxs)(`div`,{className:D.header,children:[(0,y.jsx)(`h1`,{className:D.h1,children:`Continuous Improvement`}),(0,y.jsxs)(`div`,{className:D.headerActions,children:[(0,y.jsx)(m,{size:`sm`,variant:`ghost`,onClick:()=>void r(),disabled:t,children:t?`Loading...`:`Refresh`}),(0,y.jsx)(m,{size:`sm`,variant:`primary`,onClick:()=>s(!0),children:`Add project`})]})]}),n&&(0,y.jsxs)(`div`,{className:D.error,children:[`Failed to load: `,n]}),!t&&l.length===0&&(0,y.jsxs)(`div`,{className:D.empty,children:[(0,y.jsx)(`p`,{children:`No projects configured.`}),(0,y.jsx)(`p`,{className:D.emptyHint,children:`Add a project to start automatically opening improvement PRs on a schedule.`}),(0,y.jsx)(m,{variant:`primary`,onClick:()=>s(!0),children:`Add project`})]}),l.length>0&&(0,y.jsx)(`div`,{className:D.projects,children:l.map(([e,t])=>(0,y.jsx)(w,{projectId:e,status:t,onToggleCategory:(t,n)=>a(e,t,n),onRunCategory:t=>i(e,t),onSaveCategory:(t,n)=>f(e,t,n),onRemove:()=>d(e)},e))}),o&&(0,y.jsx)(E,{onClose:()=>s(!1),onAdd:u})]})}export{O as ContinuousImprovementPage};
1
+ import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{r}from"./useWebSocket-Hg3RO6sx.js";import{a as i,c as a,i as o,n as s,o as c,r as l,s as u}from"./events-BK5ucyUu.js";import{t as d}from"./Card-u29day7d.js";import{t as f}from"./Button-DTO6bgnL.js";import{r as p,t as m}from"./Input-iymdcwsf.js";import{ft as h}from"./index-DzJsiq8q.js";var g=t(e(),1);function _(){let[e,t]=(0,g.useState)(null),[n,d]=(0,g.useState)(!0),[f,p]=(0,g.useState)(null),m=(0,g.useCallback)(async()=>{d(!0);try{let e=await fetch(`/api/continuous-improvement`);if(!e.ok)throw Error(`HTTP ${e.status}`);t(await e.json()),p(null)}catch(e){p(e instanceof Error?e.message:String(e))}finally{d(!1)}},[]);(0,g.useEffect)(()=>{m()},[m]);let h=(0,g.useCallback)(()=>{m()},[m]);return r(s,h),r(o,h),r(c,h),r(i,h),r(u,h),r(l,h),r(a,h),{status:e,loading:n,error:f,refresh:m,runNow:(0,g.useCallback)(async(e,t)=>{await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}/run`,{method:`POST`}),await m()},[m]),setEnabled:(0,g.useCallback)(async(e,t,n)=>{await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({enabled:n})}),await m()},[m])}}var v={modal:`_modal_e9k39_1`,title:`_title_e9k39_14`,form:`_form_e9k39_15`,field:`_field_e9k39_16`,label:`_label_e9k39_17`,hint:`_hint_e9k39_18`,error:`_error_e9k39_19`,buttons:`_buttons_e9k39_20`},y=n();function b({categoryId:e,status:t,onClose:n,onSave:r}){let{config:i}=t,a=i.invocation?.kind===`rawPrompt`?i.invocation.prompt:``,[o,s]=(0,g.useState)(i.schedule),[c,l]=(0,g.useState)(a),[u,d]=(0,g.useState)(!1),[_,b]=(0,g.useState)(null);async function x(e){e.preventDefault(),d(!0),b(null);try{let e={};o!==i.schedule&&(e.schedule=o),c!==a&&c.length>0&&(e.invocation={kind:`rawPrompt`,prompt:c}),await r(e),n()}catch(e){b(e instanceof Error?e.message:String(e))}finally{d(!1)}}return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(h,{onClick:n}),(0,y.jsxs)(`div`,{className:v.modal,role:`dialog`,"aria-modal":`true`,"aria-label":`Edit ${e}`,children:[(0,y.jsxs)(`h2`,{className:v.title,children:[`Edit category: `,e]}),(0,y.jsxs)(`form`,{onSubmit:e=>void x(e),className:v.form,children:[(0,y.jsxs)(`label`,{className:v.field,children:[(0,y.jsx)(`span`,{className:v.label,children:`Cron schedule`}),(0,y.jsx)(m,{value:o,onChange:e=>s(e.target.value),placeholder:`0 */6 * * *`,required:!0}),(0,y.jsx)(`span`,{className:v.hint,children:`Standard cron expression (5 fields)`})]}),(0,y.jsxs)(`label`,{className:v.field,children:[(0,y.jsx)(`span`,{className:v.label,children:`Extra prompt (optional)`}),(0,y.jsx)(p,{value:c,onChange:e=>l(e.target.value),placeholder:`Additional instructions to include in the improvement prompt...`,rows:4})]}),_&&(0,y.jsx)(`p`,{className:v.error,children:_}),(0,y.jsxs)(`div`,{className:v.buttons,children:[(0,y.jsx)(f,{type:`button`,variant:`ghost`,onClick:n,children:`Cancel`}),(0,y.jsx)(f,{type:`submit`,variant:`primary`,disabled:u,children:u?`Saving...`:`Save`})]})]})]})]})}var x={card:`_card_1h4sl_1`,header:`_header_1h4sl_2`,categoryId:`_categoryId_1h4sl_3`,actions:`_actions_1h4sl_4`,inFlightBadge:`_inFlightBadge_1h4sl_5`,meta:`_meta_1h4sl_10`,metaItem:`_metaItem_1h4sl_11`};function S({categoryId:e,status:t,onToggle:n,onRunNow:r,onSave:i}){let{config:a,state:o}=t,[s,c]=(0,g.useState)(!1),l=o.lastRunAt?new Date(o.lastRunAt).toLocaleString():`never`,u=o.trustState;return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(d,{padding:`sm`,variant:`sunken`,className:x.card,children:[(0,y.jsxs)(`div`,{className:x.header,children:[(0,y.jsx)(`span`,{className:x.categoryId,children:e}),(0,y.jsxs)(`div`,{className:x.actions,children:[o.inFlight&&(0,y.jsxs)(`a`,{href:o.inFlight.prUrl,target:`_blank`,rel:`noreferrer`,className:x.inFlightBadge,children:[`PR #`,o.inFlight.prNumber,` open`]}),(0,y.jsx)(f,{size:`sm`,variant:a.enabled?`default`:`ghost`,onClick:()=>void n(!a.enabled),children:a.enabled?`Enabled`:`Disabled`}),(0,y.jsx)(f,{size:`sm`,variant:`ghost`,onClick:()=>c(!0),children:`Edit`}),(0,y.jsx)(f,{size:`sm`,variant:`primary`,onClick:()=>void r(),disabled:!!o.inFlight,children:`Run now`})]})]}),(0,y.jsxs)(`div`,{className:x.meta,children:[(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Schedule: `,a.scheduleHuman??a.schedule]}),(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Last run: `,l]}),(0,y.jsxs)(`span`,{className:x.metaItem,children:[`Clean PRs: `,u.consecutiveCleanPRs,` \xA0|\xA0 Merged: `,u.totalMerged,` \xA0|\xA0 Rejected: `,u.totalRejected]})]})]}),s&&(0,y.jsx)(b,{categoryId:e,status:t,onClose:()=>c(!1),onSave:i})]})}var C={card:`_card_1e41q_1`,header:`_header_1e41q_2`,projectInfo:`_projectInfo_1e41q_3`,projectName:`_projectName_1e41q_4`,projectPath:`_projectPath_1e41q_5`,projectBranch:`_projectBranch_1e41q_6`,categories:`_categories_1e41q_7`,empty:`_empty_1e41q_8`};function w({projectId:e,status:t,onToggleCategory:n,onRunCategory:r,onSaveCategory:i,onRemove:a}){let{config:o,categories:s}=t,c=Object.entries(s);return(0,y.jsxs)(d,{padding:`md`,className:C.card,children:[(0,y.jsxs)(`div`,{className:C.header,children:[(0,y.jsxs)(`div`,{className:C.projectInfo,children:[(0,y.jsx)(`span`,{className:C.projectName,children:o.name}),(0,y.jsx)(`span`,{className:C.projectPath,children:o.path}),(0,y.jsxs)(`span`,{className:C.projectBranch,children:[`branch: `,o.mainBranch]})]}),(0,y.jsx)(f,{size:`sm`,variant:`danger`,onClick:()=>void a(),children:`Remove`})]}),c.length===0?(0,y.jsxs)(`p`,{className:C.empty,children:[`No categories configured. Enable one with: `,(0,y.jsxs)(`code`,{children:[`teamos ci enable `,e,` <category>`]})]}):(0,y.jsx)(`div`,{className:C.categories,children:c.map(([t,a])=>(0,y.jsx)(S,{projectId:e,categoryId:t,status:a,onToggle:e=>n(t,e),onRunNow:()=>r(t),onSave:e=>i(t,e)},t))})]})}var T={modal:`_modal_1oevh_1`,title:`_title_1oevh_14`,form:`_form_1oevh_15`,field:`_field_1oevh_16`,label:`_label_1oevh_17`,error:`_error_1oevh_18`,buttons:`_buttons_1oevh_19`};function E({onClose:e,onAdd:t}){let[n,r]=(0,g.useState)(``),[i,a]=(0,g.useState)(``),[o,s]=(0,g.useState)(`main`),[c,l]=(0,g.useState)(!1),[u,d]=(0,g.useState)(null);async function p(r){if(r.preventDefault(),n.trim()){l(!0),d(null);try{await t(n.trim(),i.trim(),o.trim()||`main`),e()}catch(e){d(e instanceof Error?e.message:String(e))}finally{l(!1)}}}return(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(h,{onClick:e}),(0,y.jsxs)(`div`,{className:T.modal,role:`dialog`,"aria-modal":`true`,"aria-label":`Add project`,children:[(0,y.jsx)(`h2`,{className:T.title,children:`Add project`}),(0,y.jsxs)(`form`,{onSubmit:e=>void p(e),className:T.form,children:[(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Absolute path`}),(0,y.jsx)(m,{value:n,onChange:e=>r(e.target.value),placeholder:`/Users/me/Projects/my-app`,required:!0})]}),(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Name (optional)`}),(0,y.jsx)(m,{value:i,onChange:e=>a(e.target.value),placeholder:`my-app`})]}),(0,y.jsxs)(`label`,{className:T.field,children:[(0,y.jsx)(`span`,{className:T.label,children:`Main branch`}),(0,y.jsx)(m,{value:o,onChange:e=>s(e.target.value),placeholder:`main`})]}),u&&(0,y.jsx)(`p`,{className:T.error,children:u}),(0,y.jsxs)(`div`,{className:T.buttons,children:[(0,y.jsx)(f,{type:`button`,variant:`ghost`,onClick:e,children:`Cancel`}),(0,y.jsx)(f,{type:`submit`,variant:`primary`,disabled:c||!n.trim(),children:c?`Adding...`:`Add project`})]})]})]})]})}var D={page:`_page_1hl41_1`,header:`_header_1hl41_2`,h1:`_h1_1hl41_3`,headerActions:`_headerActions_1hl41_4`,error:`_error_1hl41_5`,empty:`_empty_1hl41_6`,emptyHint:`_emptyHint_1hl41_7`,projects:`_projects_1hl41_8`};function O(){let{status:e,loading:t,error:n,refresh:r,runNow:i,setEnabled:a}=_(),[o,s]=(0,g.useState)(!1),c=e?.projects??{},l=Object.entries(c);async function u(e,t,n){let i=await fetch(`/api/continuous-improvement/projects`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({name:t,path:e,mainBranch:n})});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await r()}async function d(e){await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}`,{method:`DELETE`}),await r()}async function p(e,t,n){let i=await fetch(`/api/continuous-improvement/${encodeURIComponent(e)}/categories/${encodeURIComponent(t)}`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(n)});if(!i.ok){let e=await i.json().catch(()=>({}));throw Error(e.error??`HTTP ${i.status}`)}await r()}return(0,y.jsxs)(`div`,{className:D.page,children:[(0,y.jsxs)(`div`,{className:D.header,children:[(0,y.jsx)(`h1`,{className:D.h1,children:`Continuous Improvement`}),(0,y.jsxs)(`div`,{className:D.headerActions,children:[(0,y.jsx)(f,{size:`sm`,variant:`ghost`,onClick:()=>void r(),disabled:t,children:t?`Loading...`:`Refresh`}),(0,y.jsx)(f,{size:`sm`,variant:`primary`,onClick:()=>s(!0),children:`Add project`})]})]}),n&&(0,y.jsxs)(`div`,{className:D.error,children:[`Failed to load: `,n]}),!t&&l.length===0&&(0,y.jsxs)(`div`,{className:D.empty,children:[(0,y.jsx)(`p`,{children:`No projects configured.`}),(0,y.jsx)(`p`,{className:D.emptyHint,children:`Add a project to start automatically opening improvement PRs on a schedule.`}),(0,y.jsx)(f,{variant:`primary`,onClick:()=>s(!0),children:`Add project`})]}),l.length>0&&(0,y.jsx)(`div`,{className:D.projects,children:l.map(([e,t])=>(0,y.jsx)(w,{projectId:e,status:t,onToggleCategory:(t,n)=>a(e,t,n),onRunCategory:t=>i(e,t),onSaveCategory:(t,n)=>p(e,t,n),onRemove:()=>d(e)},e))}),o&&(0,y.jsx)(E,{onClose:()=>s(!1),onAdd:u})]})}export{O as ContinuousImprovementPage};
@@ -1 +1 @@
1
- import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{r}from"./useWebSocket-Hg3RO6sx.js";import{d as i,u as a}from"./events-CCBP4a9s.js";import{t as o}from"./Card-u29day7d.js";import{t as s}from"./Input-HhV6M0tu.js";import{t as c}from"./Button-xBBZQ0ie.js";import{At as l,P as u,j as d}from"./index-tOLuwPW6.js";var f=t(e(),1),p={header:`_header_1mqah_1`,headerActions:`_headerActions_1mqah_9`,badge:`_badge_1mqah_18`,badgeActive:`_badgeActive_1mqah_26`,badgeIdle:`_badgeIdle_1mqah_31`,pauseBanner:`_pauseBanner_1mqah_37`,tableWrap:`_tableWrap_1mqah_47`,table:`_table_1mqah_47`,nameCell:`_nameCell_1mqah_78`,candidateName:`_candidateName_1mqah_84`,candidateDesc:`_candidateDesc_1mqah_91`,tier:`_tier_1mqah_96`,actionsCell:`_actionsCell_1mqah_102`,outcome:`_outcome_1mqah_110`,outcome_success:`_outcome_success_1mqah_117`,outcome_failure:`_outcome_failure_1mqah_122`,outcome_timeout:`_outcome_timeout_1mqah_127`,outcome_skipped:`_outcome_skipped_1mqah_132`,pausedBadge:`_pausedBadge_1mqah_137`,activeBadge:`_activeBadge_1mqah_145`,logWrap:`_logWrap_1mqah_154`,logRow:`_logRow_1mqah_164`,logTime:`_logTime_1mqah_173`,logEvent:`_logEvent_1mqah_179`,logEvent_tick_complete:`_logEvent_tick_complete_1mqah_185`,logEvent_tick_skipped:`_logEvent_tick_skipped_1mqah_189`,logEvent_run_now:`_logEvent_run_now_1mqah_193`,logName:`_logName_1mqah_197`,logDetail:`_logDetail_1mqah_202`,settingsGrid:`_settingsGrid_1mqah_210`,settingsLabel:`_settingsLabel_1mqah_217`,settingsLabelFull:`_settingsLabelFull_1mqah_226`,settingsInput:`_settingsInput_1mqah_233`,settingsInputRow:`_settingsInputRow_1mqah_238`,settingsUnit:`_settingsUnit_1mqah_244`,settingsActions:`_settingsActions_1mqah_250`,saveMsg:`_saveMsg_1mqah_256`,muted:`_muted_1mqah_262`,errorText:`_errorText_1mqah_268`},m=n();function h(e){return e<6e4?`${Math.round(e/1e3)}s`:e<36e5?`${Math.round(e/6e4)}m`:`${Math.round(e/36e5)}h`}function g(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}var _=0;function v(){return++_}function y(){let[e,t]=(0,f.useState)(null),[n,_]=(0,f.useState)([]),[y,b]=(0,f.useState)([]),[x,S]=(0,f.useState)(!0),[C,w]=(0,f.useState)(null),[T,E]=(0,f.useState)(null),[D,O]=(0,f.useState)(!1),[k,A]=(0,f.useState)(null),[j,M]=(0,f.useState)({}),N=(0,f.useCallback)(async e=>{try{let[n,r]=await Promise.all([fetch(`/api/heartbeat/status`,{signal:e}),fetch(`/api/heartbeat/candidates`,{signal:e})]);if(!n.ok)throw Error(`status ${n.status}`);if(!r.ok)throw Error(`candidates ${r.status}`);let[i,a]=await Promise.all([n.json(),r.json()]);t(i),_(a.candidates??[]),E(e=>{if(e)return e;let t=i.settings;return{tickIntervalMs:t.tickIntervalMs,maxCandidatesPerTick:t.maxCandidatesPerTick,tickBudgetMs:t.tickBudgetMs,paused:t.paused}}),w(null)}catch(e){if(e.name===`AbortError`)return;w(e.message)}finally{S(!1)}},[]);(0,f.useEffect)(()=>{let e=new AbortController;return N(e.signal),()=>e.abort()},[N]);let P=(0,f.useCallback)(e=>{b(t=>[e,...t].slice(0,50))},[]);r(a,e=>{let t=e,n=t.outcomes?Object.entries(t.outcomes):[],r=n.length>0?`${t.candidatesRun??0} ran (${n.map(([e,t])=>`${e}:${t}`).join(`, `)})`:`${t.candidatesRun??0} ran, ${t.candidatesSkipped??0} skipped`;P({id:v(),ts:t.at??Date.now(),event:`tick:complete`,detail:r}),N()}),r(i,e=>{let t=e;P({id:v(),ts:t.at??Date.now(),event:`tick:skipped`,detail:`reason: ${t.reason??`?`}`})});let F=(e,t)=>M(n=>({...n,[e]:t})),I=(0,f.useCallback)(async(e,t,n,r)=>{let i=r??`__global__`;F(i,!0);try{let i=await fetch(t,{method:`POST`,body:JSON.stringify(n),headers:{"Content-Type":`application/json`}});if(!i.ok){let t=(await i.json().catch(()=>({}))).error??`HTTP ${i.status}`;return P({id:v(),ts:Date.now(),event:e,name:r,detail:`error: ${t}`}),!1}return await N(),!0}catch(t){let n=t instanceof Error?t.message:String(t);return P({id:v(),ts:Date.now(),event:e,name:r,detail:`error: ${n}`}),!1}finally{F(i,!1)}},[P,N]),L=()=>I(`pause`,`/api/heartbeat/pause`,{}),R=()=>I(`resume`,`/api/heartbeat/resume`,{}),z=e=>I(`pause`,`/api/heartbeat/pause`,{candidate:e},e),B=e=>I(`resume`,`/api/heartbeat/resume`,{candidate:e},e);async function V(e){await I(`run-now`,`/api/heartbeat/run-now`,{candidate:e},e)&&P({id:v(),ts:Date.now(),event:`run-now`,name:e,detail:`triggered`})}let H=(0,f.useRef)(null);(0,f.useEffect)(()=>()=>{H.current&&=(clearTimeout(H.current),null)},[]);async function U(){if(T){O(!0);try{let e=await fetch(`/api/settings`,{method:`PUT`,body:JSON.stringify({heartbeat:T}),headers:{"Content-Type":`application/json`}});if(!e.ok)throw Error(`HTTP ${e.status}`);await N(),A(`Saved`)}catch(e){A(`Error: ${e.message}`)}finally{O(!1),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>A(null),3e3)}}}if(x)return(0,m.jsxs)(`div`,{className:`page-content-frame ${l.pageContainer}`,children:[(0,m.jsx)(`h1`,{className:l.pageH1,children:`Heartbeat`}),(0,m.jsx)(`p`,{className:p.muted,children:`Loading...`})]});if(C)return(0,m.jsxs)(`div`,{className:`page-content-frame ${l.pageContainer}`,children:[(0,m.jsx)(`h1`,{className:l.pageH1,children:`Heartbeat`}),(0,m.jsx)(`p`,{className:p.errorText,children:C}),(0,m.jsx)(c,{size:`sm`,onClick:()=>N(),children:`Retry`})]});let W=e?.settings.paused??!1,G=j.__global__??!1;return(0,m.jsxs)(`div`,{className:`page-content-frame ${l.pageContainer}`,children:[(0,m.jsxs)(`div`,{className:p.header,children:[(0,m.jsx)(`h1`,{className:l.pageH1,children:`Heartbeat`}),(0,m.jsxs)(`div`,{className:p.headerActions,children:[e&&(0,m.jsx)(`span`,{className:`${p.badge} ${e.activeTick?p.badgeActive:p.badgeIdle}`,children:e.activeTick?`Tick running`:`Idle`}),W?(0,m.jsx)(c,{size:`sm`,variant:`default`,disabled:G,onClick:R,children:G?`...`:`Resume all`}):(0,m.jsx)(c,{size:`sm`,variant:`default`,disabled:G,onClick:L,children:G?`...`:`Pause all`}),(0,m.jsx)(c,{size:`sm`,variant:`default`,onClick:()=>N(),children:`Refresh`})]})]}),W&&(0,m.jsx)(`div`,{className:p.pauseBanner,children:`Heartbeat is globally paused.`}),(0,m.jsx)(d,{title:`Candidates`,badge:n.length,persistKey:`heartbeat.candidates`,defaultExpanded:!0,children:n.length===0?(0,m.jsx)(`p`,{className:p.muted,children:`No candidates registered.`}):(0,m.jsx)(`div`,{className:p.tableWrap,children:(0,m.jsxs)(`table`,{className:p.table,children:[(0,m.jsx)(`thead`,{children:(0,m.jsxs)(`tr`,{children:[(0,m.jsx)(`th`,{children:`Name`}),(0,m.jsx)(`th`,{children:`Tier`}),(0,m.jsx)(`th`,{children:`Priority`}),(0,m.jsx)(`th`,{children:`Staleness`}),(0,m.jsx)(`th`,{children:`Last outcome`}),(0,m.jsx)(`th`,{children:`Failures`}),(0,m.jsx)(`th`,{children:`Status`}),(0,m.jsx)(`th`,{children:`Actions`})]})}),(0,m.jsx)(`tbody`,{children:n.map(t=>{let n=e?.state.candidates[t.name],r=j[t.name]??!1,i=n?.paused??!1;return(0,m.jsxs)(`tr`,{children:[(0,m.jsxs)(`td`,{className:p.nameCell,children:[(0,m.jsx)(`span`,{className:p.candidateName,children:t.name}),(0,m.jsx)(`span`,{className:p.candidateDesc,children:t.description})]}),(0,m.jsx)(`td`,{children:(0,m.jsx)(`span`,{className:p.tier,children:t.tier})}),(0,m.jsx)(`td`,{children:t.basePriority.toFixed(1)}),(0,m.jsx)(`td`,{children:h(t.stalenessThresholdMs)}),(0,m.jsx)(`td`,{children:n?.lastOutcome?(0,m.jsx)(`span`,{className:`${p.outcome} ${p[`outcome_${n.lastOutcome}`]}`,children:n.lastOutcome}):(0,m.jsx)(`span`,{className:p.muted,children:`--`})}),(0,m.jsx)(`td`,{children:n?.consecutiveFailures??0}),(0,m.jsx)(`td`,{children:i?(0,m.jsx)(`span`,{className:p.pausedBadge,children:`paused`}):(0,m.jsx)(`span`,{className:p.activeBadge,children:`active`})}),(0,m.jsxs)(`td`,{className:p.actionsCell,children:[i?(0,m.jsx)(c,{size:`sm`,variant:`default`,disabled:r,onClick:()=>B(t.name),children:r?`...`:`Resume`}):(0,m.jsx)(c,{size:`sm`,variant:`default`,disabled:r,onClick:()=>z(t.name),children:r?`...`:`Pause`}),(0,m.jsx)(c,{size:`sm`,variant:`default`,disabled:r||(e?.activeTick??!1),onClick:()=>V(t.name),children:r?`...`:`Run now`})]})]},t.name)})})]})})}),(0,m.jsx)(d,{title:`Live tick log`,badge:y.length>0?y.length:void 0,persistKey:`heartbeat.ticklog`,defaultExpanded:!0,children:y.length===0?(0,m.jsx)(`p`,{className:p.muted,children:`No events yet. Events will appear here as ticks fire.`}):(0,m.jsx)(`div`,{className:p.logWrap,children:y.map(e=>(0,m.jsxs)(`div`,{className:p.logRow,children:[(0,m.jsx)(`span`,{className:p.logTime,children:g(e.ts)}),(0,m.jsx)(`span`,{className:`${p.logEvent} ${p[`logEvent_${e.event.replace(/[:.]/g,`_`)}`]}`,children:e.event}),e.name&&(0,m.jsx)(`span`,{className:p.logName,children:e.name}),(0,m.jsx)(`span`,{className:p.logDetail,children:e.detail})]},e.id))})}),(0,m.jsx)(d,{title:`Settings`,persistKey:`heartbeat.settings`,defaultExpanded:!1,children:T&&(0,m.jsxs)(o,{padding:`sm`,variant:`sunken`,children:[(0,m.jsxs)(`div`,{className:p.settingsGrid,children:[(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Tick interval`,(0,m.jsxs)(`div`,{className:p.settingsInputRow,children:[(0,m.jsx)(s,{type:`number`,className:p.settingsInput,value:Math.round(T.tickIntervalMs/1e3),min:60,max:3600,onChange:e=>E(t=>t&&{...t,tickIntervalMs:Number(e.target.value)*1e3})}),(0,m.jsx)(`span`,{className:p.settingsUnit,children:`s`})]})]}),(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Max per tick`,(0,m.jsx)(s,{type:`number`,className:p.settingsInput,value:T.maxCandidatesPerTick,min:1,max:10,onChange:e=>E(t=>t&&{...t,maxCandidatesPerTick:Number(e.target.value)})})]}),(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Tick budget`,(0,m.jsxs)(`div`,{className:p.settingsInputRow,children:[(0,m.jsx)(s,{type:`number`,className:p.settingsInput,value:Math.round(T.tickBudgetMs/1e3),min:5,max:300,onChange:e=>E(t=>t&&{...t,tickBudgetMs:Number(e.target.value)*1e3})}),(0,m.jsx)(`span`,{className:p.settingsUnit,children:`s`})]})]}),(0,m.jsxs)(`label`,{className:`${p.settingsLabel} ${p.settingsLabelFull}`,children:[(0,m.jsx)(`span`,{children:`Global pause`}),(0,m.jsx)(u,{checked:T.paused,onChange:e=>E(t=>t&&{...t,paused:e})})]})]}),(0,m.jsxs)(`div`,{className:p.settingsActions,children:[(0,m.jsx)(c,{size:`sm`,disabled:D,onClick:U,children:D?`Saving...`:`Save`}),k&&(0,m.jsx)(`span`,{className:p.saveMsg,children:k})]})]})})]})}export{y as HeartbeatPanel};
1
+ import{n as e,s as t,t as n}from"./jsx-runtime-Bq3x7umQ.js";import{r}from"./useWebSocket-Hg3RO6sx.js";import{d as i,u as a}from"./events-BK5ucyUu.js";import{t as o}from"./Card-u29day7d.js";import{t as s}from"./Button-DTO6bgnL.js";import{t as c}from"./Input-iymdcwsf.js";import{A as l,k as u,kt as d}from"./index-DzJsiq8q.js";var f=t(e(),1),p={header:`_header_1mqah_1`,headerActions:`_headerActions_1mqah_9`,badge:`_badge_1mqah_18`,badgeActive:`_badgeActive_1mqah_26`,badgeIdle:`_badgeIdle_1mqah_31`,pauseBanner:`_pauseBanner_1mqah_37`,tableWrap:`_tableWrap_1mqah_47`,table:`_table_1mqah_47`,nameCell:`_nameCell_1mqah_78`,candidateName:`_candidateName_1mqah_84`,candidateDesc:`_candidateDesc_1mqah_91`,tier:`_tier_1mqah_96`,actionsCell:`_actionsCell_1mqah_102`,outcome:`_outcome_1mqah_110`,outcome_success:`_outcome_success_1mqah_117`,outcome_failure:`_outcome_failure_1mqah_122`,outcome_timeout:`_outcome_timeout_1mqah_127`,outcome_skipped:`_outcome_skipped_1mqah_132`,pausedBadge:`_pausedBadge_1mqah_137`,activeBadge:`_activeBadge_1mqah_145`,logWrap:`_logWrap_1mqah_154`,logRow:`_logRow_1mqah_164`,logTime:`_logTime_1mqah_173`,logEvent:`_logEvent_1mqah_179`,logEvent_tick_complete:`_logEvent_tick_complete_1mqah_185`,logEvent_tick_skipped:`_logEvent_tick_skipped_1mqah_189`,logEvent_run_now:`_logEvent_run_now_1mqah_193`,logName:`_logName_1mqah_197`,logDetail:`_logDetail_1mqah_202`,settingsGrid:`_settingsGrid_1mqah_210`,settingsLabel:`_settingsLabel_1mqah_217`,settingsLabelFull:`_settingsLabelFull_1mqah_226`,settingsInput:`_settingsInput_1mqah_233`,settingsInputRow:`_settingsInputRow_1mqah_238`,settingsUnit:`_settingsUnit_1mqah_244`,settingsActions:`_settingsActions_1mqah_250`,saveMsg:`_saveMsg_1mqah_256`,muted:`_muted_1mqah_262`,errorText:`_errorText_1mqah_268`},m=n();function h(e){return e<6e4?`${Math.round(e/1e3)}s`:e<36e5?`${Math.round(e/6e4)}m`:`${Math.round(e/36e5)}h`}function g(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`,second:`2-digit`})}var _=0;function v(){return++_}function y(){let[e,t]=(0,f.useState)(null),[n,_]=(0,f.useState)([]),[y,b]=(0,f.useState)([]),[x,S]=(0,f.useState)(!0),[C,w]=(0,f.useState)(null),[T,E]=(0,f.useState)(null),[D,O]=(0,f.useState)(!1),[k,A]=(0,f.useState)(null),[j,M]=(0,f.useState)({}),N=(0,f.useCallback)(async e=>{try{let[n,r]=await Promise.all([fetch(`/api/heartbeat/status`,{signal:e}),fetch(`/api/heartbeat/candidates`,{signal:e})]);if(!n.ok)throw Error(`status ${n.status}`);if(!r.ok)throw Error(`candidates ${r.status}`);let[i,a]=await Promise.all([n.json(),r.json()]);t(i),_(a.candidates??[]),E(e=>{if(e)return e;let t=i.settings;return{tickIntervalMs:t.tickIntervalMs,maxCandidatesPerTick:t.maxCandidatesPerTick,tickBudgetMs:t.tickBudgetMs,paused:t.paused}}),w(null)}catch(e){if(e.name===`AbortError`)return;w(e.message)}finally{S(!1)}},[]);(0,f.useEffect)(()=>{let e=new AbortController;return N(e.signal),()=>e.abort()},[N]);let P=(0,f.useCallback)(e=>{b(t=>[e,...t].slice(0,50))},[]);r(a,e=>{let t=e,n=t.outcomes?Object.entries(t.outcomes):[],r=n.length>0?`${t.candidatesRun??0} ran (${n.map(([e,t])=>`${e}:${t}`).join(`, `)})`:`${t.candidatesRun??0} ran, ${t.candidatesSkipped??0} skipped`;P({id:v(),ts:t.at??Date.now(),event:`tick:complete`,detail:r}),N()}),r(i,e=>{let t=e;P({id:v(),ts:t.at??Date.now(),event:`tick:skipped`,detail:`reason: ${t.reason??`?`}`})});let F=(e,t)=>M(n=>({...n,[e]:t})),I=(0,f.useCallback)(async(e,t,n,r)=>{let i=r??`__global__`;F(i,!0);try{let i=await fetch(t,{method:`POST`,body:JSON.stringify(n),headers:{"Content-Type":`application/json`}});if(!i.ok){let t=(await i.json().catch(()=>({}))).error??`HTTP ${i.status}`;return P({id:v(),ts:Date.now(),event:e,name:r,detail:`error: ${t}`}),!1}return await N(),!0}catch(t){let n=t instanceof Error?t.message:String(t);return P({id:v(),ts:Date.now(),event:e,name:r,detail:`error: ${n}`}),!1}finally{F(i,!1)}},[P,N]),L=()=>I(`pause`,`/api/heartbeat/pause`,{}),R=()=>I(`resume`,`/api/heartbeat/resume`,{}),z=e=>I(`pause`,`/api/heartbeat/pause`,{candidate:e},e),B=e=>I(`resume`,`/api/heartbeat/resume`,{candidate:e},e);async function V(e){await I(`run-now`,`/api/heartbeat/run-now`,{candidate:e},e)&&P({id:v(),ts:Date.now(),event:`run-now`,name:e,detail:`triggered`})}let H=(0,f.useRef)(null);(0,f.useEffect)(()=>()=>{H.current&&=(clearTimeout(H.current),null)},[]);async function U(){if(T){O(!0);try{let e=await fetch(`/api/settings`,{method:`PUT`,body:JSON.stringify({heartbeat:T}),headers:{"Content-Type":`application/json`}});if(!e.ok)throw Error(`HTTP ${e.status}`);await N(),A(`Saved`)}catch(e){A(`Error: ${e.message}`)}finally{O(!1),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>A(null),3e3)}}}if(x)return(0,m.jsxs)(`div`,{className:`page-content-frame ${d.pageContainer}`,children:[(0,m.jsx)(`h1`,{className:d.pageH1,children:`Heartbeat`}),(0,m.jsx)(`p`,{className:p.muted,children:`Loading...`})]});if(C)return(0,m.jsxs)(`div`,{className:`page-content-frame ${d.pageContainer}`,children:[(0,m.jsx)(`h1`,{className:d.pageH1,children:`Heartbeat`}),(0,m.jsx)(`p`,{className:p.errorText,children:C}),(0,m.jsx)(s,{size:`sm`,onClick:()=>N(),children:`Retry`})]});let W=e?.settings.paused??!1,G=j.__global__??!1;return(0,m.jsxs)(`div`,{className:`page-content-frame ${d.pageContainer}`,children:[(0,m.jsxs)(`div`,{className:p.header,children:[(0,m.jsx)(`h1`,{className:d.pageH1,children:`Heartbeat`}),(0,m.jsxs)(`div`,{className:p.headerActions,children:[e&&(0,m.jsx)(`span`,{className:`${p.badge} ${e.activeTick?p.badgeActive:p.badgeIdle}`,children:e.activeTick?`Tick running`:`Idle`}),W?(0,m.jsx)(s,{size:`sm`,variant:`default`,disabled:G,onClick:R,children:G?`...`:`Resume all`}):(0,m.jsx)(s,{size:`sm`,variant:`default`,disabled:G,onClick:L,children:G?`...`:`Pause all`}),(0,m.jsx)(s,{size:`sm`,variant:`default`,onClick:()=>N(),children:`Refresh`})]})]}),W&&(0,m.jsx)(`div`,{className:p.pauseBanner,children:`Heartbeat is globally paused.`}),(0,m.jsx)(u,{title:`Candidates`,badge:n.length,persistKey:`heartbeat.candidates`,defaultExpanded:!0,children:n.length===0?(0,m.jsx)(`p`,{className:p.muted,children:`No candidates registered.`}):(0,m.jsx)(`div`,{className:p.tableWrap,children:(0,m.jsxs)(`table`,{className:p.table,children:[(0,m.jsx)(`thead`,{children:(0,m.jsxs)(`tr`,{children:[(0,m.jsx)(`th`,{children:`Name`}),(0,m.jsx)(`th`,{children:`Tier`}),(0,m.jsx)(`th`,{children:`Priority`}),(0,m.jsx)(`th`,{children:`Staleness`}),(0,m.jsx)(`th`,{children:`Last outcome`}),(0,m.jsx)(`th`,{children:`Failures`}),(0,m.jsx)(`th`,{children:`Status`}),(0,m.jsx)(`th`,{children:`Actions`})]})}),(0,m.jsx)(`tbody`,{children:n.map(t=>{let n=e?.state.candidates[t.name],r=j[t.name]??!1,i=n?.paused??!1;return(0,m.jsxs)(`tr`,{children:[(0,m.jsxs)(`td`,{className:p.nameCell,children:[(0,m.jsx)(`span`,{className:p.candidateName,children:t.name}),(0,m.jsx)(`span`,{className:p.candidateDesc,children:t.description})]}),(0,m.jsx)(`td`,{children:(0,m.jsx)(`span`,{className:p.tier,children:t.tier})}),(0,m.jsx)(`td`,{children:t.basePriority.toFixed(1)}),(0,m.jsx)(`td`,{children:h(t.stalenessThresholdMs)}),(0,m.jsx)(`td`,{children:n?.lastOutcome?(0,m.jsx)(`span`,{className:`${p.outcome} ${p[`outcome_${n.lastOutcome}`]}`,children:n.lastOutcome}):(0,m.jsx)(`span`,{className:p.muted,children:`--`})}),(0,m.jsx)(`td`,{children:n?.consecutiveFailures??0}),(0,m.jsx)(`td`,{children:i?(0,m.jsx)(`span`,{className:p.pausedBadge,children:`paused`}):(0,m.jsx)(`span`,{className:p.activeBadge,children:`active`})}),(0,m.jsxs)(`td`,{className:p.actionsCell,children:[i?(0,m.jsx)(s,{size:`sm`,variant:`default`,disabled:r,onClick:()=>B(t.name),children:r?`...`:`Resume`}):(0,m.jsx)(s,{size:`sm`,variant:`default`,disabled:r,onClick:()=>z(t.name),children:r?`...`:`Pause`}),(0,m.jsx)(s,{size:`sm`,variant:`default`,disabled:r||(e?.activeTick??!1),onClick:()=>V(t.name),children:r?`...`:`Run now`})]})]},t.name)})})]})})}),(0,m.jsx)(u,{title:`Live tick log`,badge:y.length>0?y.length:void 0,persistKey:`heartbeat.ticklog`,defaultExpanded:!0,children:y.length===0?(0,m.jsx)(`p`,{className:p.muted,children:`No events yet. Events will appear here as ticks fire.`}):(0,m.jsx)(`div`,{className:p.logWrap,children:y.map(e=>(0,m.jsxs)(`div`,{className:p.logRow,children:[(0,m.jsx)(`span`,{className:p.logTime,children:g(e.ts)}),(0,m.jsx)(`span`,{className:`${p.logEvent} ${p[`logEvent_${e.event.replace(/[:.]/g,`_`)}`]}`,children:e.event}),e.name&&(0,m.jsx)(`span`,{className:p.logName,children:e.name}),(0,m.jsx)(`span`,{className:p.logDetail,children:e.detail})]},e.id))})}),(0,m.jsx)(u,{title:`Settings`,persistKey:`heartbeat.settings`,defaultExpanded:!1,children:T&&(0,m.jsxs)(o,{padding:`sm`,variant:`sunken`,children:[(0,m.jsxs)(`div`,{className:p.settingsGrid,children:[(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Tick interval`,(0,m.jsxs)(`div`,{className:p.settingsInputRow,children:[(0,m.jsx)(c,{type:`number`,className:p.settingsInput,value:Math.round(T.tickIntervalMs/1e3),min:60,max:3600,onChange:e=>E(t=>t&&{...t,tickIntervalMs:Number(e.target.value)*1e3})}),(0,m.jsx)(`span`,{className:p.settingsUnit,children:`s`})]})]}),(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Max per tick`,(0,m.jsx)(c,{type:`number`,className:p.settingsInput,value:T.maxCandidatesPerTick,min:1,max:10,onChange:e=>E(t=>t&&{...t,maxCandidatesPerTick:Number(e.target.value)})})]}),(0,m.jsxs)(`label`,{className:p.settingsLabel,children:[`Tick budget`,(0,m.jsxs)(`div`,{className:p.settingsInputRow,children:[(0,m.jsx)(c,{type:`number`,className:p.settingsInput,value:Math.round(T.tickBudgetMs/1e3),min:5,max:300,onChange:e=>E(t=>t&&{...t,tickBudgetMs:Number(e.target.value)*1e3})}),(0,m.jsx)(`span`,{className:p.settingsUnit,children:`s`})]})]}),(0,m.jsxs)(`label`,{className:`${p.settingsLabel} ${p.settingsLabelFull}`,children:[(0,m.jsx)(`span`,{children:`Global pause`}),(0,m.jsx)(l,{checked:T.paused,onChange:e=>E(t=>t&&{...t,paused:e})})]})]}),(0,m.jsxs)(`div`,{className:p.settingsActions,children:[(0,m.jsx)(s,{size:`sm`,disabled:D,onClick:U,children:D?`Saving...`:`Save`}),k&&(0,m.jsx)(`span`,{className:p.saveMsg,children:k})]})]})})]})}export{y as HeartbeatPanel};