@timurtekb/tekjobs 0.35.2 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  Every release, newest first. Written by semantic-release from the commit messages.
4
4
 
5
+ ## 0.37.0 (2026-10-07)
6
+
7
+ * feat(scan): the run reports what the hard exclusions dropped ([58cfb62](https://github.com/Timurtek/tekjobs/commit/58cfb62))
8
+
9
+ ## 0.36.0 (2026-10-07)
10
+
11
+ * feat(cli): tekjobs init --sample, company exclusions, and the rest of the first-run notes ([a0b88b0](https://github.com/Timurtek/tekjobs/commit/a0b88b0))
12
+
5
13
  ## <small>0.35.2 (2026-10-07)</small>
6
14
 
7
15
  * fix(app): first-run fixes from a new-user test of the site, init and app ([ae0bc44](https://github.com/Timurtek/tekjobs/commit/ae0bc44))
package/README.md CHANGED
@@ -74,11 +74,11 @@ About twenty-five minutes end to end on a fresh machine, most of it the intervie
74
74
  `samples/vault` is a complete, fictional profile folder: Jordan Example, a design engineer three weeks into a search, with fourteen postings at companies that do not exist, one application in interview, a rejection, two passes, a closed listing, three people on the threads, two scan logs and the dashboard. Every note in it was written by the product's own code (`npm run sample` rebuilds it with today's dates), so it is always in the shape the app expects.
75
75
 
76
76
  ```
77
- TEKJOBS_PROFILE=$PWD/samples/vault npm run serve
78
- cd app && npm run dev
77
+ npx @timurtekb/tekjobs init --sample # copies it to ~/.tekjobs/sample and points the app there
78
+ tekjobs up
79
79
  ```
80
80
 
81
- Point the API at it and the app shows a search in progress instead of an empty folder. Nothing in it is a real person, company or posting.
81
+ The app shows a search in progress instead of an empty folder. `tekjobs init` afterwards starts your own profile and leaves the sample where it is. From a clone, `TEKJOBS_PROFILE=$PWD/samples/vault npm run serve` reads it in place. Nothing in it is a real person, company or posting.
82
82
 
83
83
  ## Bring your LinkedIn history
84
84
 
@@ -57,7 +57,7 @@ Defaulting to \`null\`.`}md(Ad,`getInvalidValueError`);var jd=xd,Md=Cd;(0,b.forw
57
57
  `)});continue}let a=/^(#{1,6})\s+(.*)$/.exec(e);if(a){n.push({kind:`heading`,level:a[1].length,children:ug(a[2])}),r++;continue}if(/^(-{3,}|\*{3,}|_{3,})\s*$/.test(e)){n.push({kind:`rule`}),r++;continue}if(sg(e)&&r+1<t.length&&cg(t[r+1])){let i=og(e).map(ug);r+=2;let a=[];for(;r<t.length&&sg(t[r]);)a.push(og(t[r++]).map(ug));n.push({kind:`table`,header:i,rows:a});continue}if(/^>\s?/.test(e)){let e=[];for(;r<t.length&&/^>\s?/.test(t[r]);)e.push(t[r++].replace(/^>\s?/,``));n.push({kind:`quote`,children:ug(e.join(` `))});continue}let o=/^\s*([-*+]|\d+[.)])\s+/.exec(e);if(o){let e=/\d/.test(o[1]),i=[];for(;r<t.length;){let e=/^\s*([-*+]|\d+[.)])\s+(.*)$/.exec(t[r]);if(!e)break;let n=e[2];for(r++;r<t.length&&/^\s{2,}\S/.test(t[r])&&!/^\s*([-*+]|\d+[.)])\s+/.test(t[r]);)n+=` `+t[r++].trim();i.push(ug(n))}n.push({kind:`list`,ordered:e,items:i});continue}let s=[];for(;r<t.length&&t[r].trim()!==``&&!/^```/.test(t[r])&&!/^(#{1,6})\s/.test(t[r])&&!/^\s*([-*+]|\d+[.)])\s+/.test(t[r])&&!/^>\s?/.test(t[r])&&!(sg(t[r])&&r+1<t.length&&cg(t[r+1]));)s.push(t[r++].trim());n.push({kind:`paragraph`,children:ug(s.join(` `))})}return n}function ug(e){let t=[],n=e,r=e=>{let n=t[t.length-1];e.kind===`text`&&n?.kind===`text`?n.text+=e.text:t.push(e)};for(;n.length;){let e=/^`([^`]+)`/.exec(n);if(e){r({kind:`code`,text:e[1]}),n=n.slice(e[0].length);continue}let t=/^\[([^\]]+)\]\((https?:\/\/[^\s)]+|\/[^\s)]*|#[^\s)]*)\)/.exec(n);if(t){r({kind:`link`,href:t[2],children:ug(t[1])}),n=n.slice(t[0].length);continue}let i=/^(\*\*|__)(.+?)\1/.exec(n);if(i){r({kind:`strong`,children:ug(i[2])}),n=n.slice(i[0].length);continue}let a=/^(\*|_)([^*_]+?)\1/.exec(n);if(a){r({kind:`em`,children:ug(a[2])}),n=n.slice(a[0].length);continue}let o=n.slice(1).search(/[`*_[]/),s=o===-1?n.length:o+1;r({kind:`text`,text:n.slice(0,s)}),n=n.slice(s)}return t}var dg=(0,b.forwardRef)(function({text:e,streaming:t=!1,className:n,...r},i){let a=lg(e);return(0,x.jsxs)(`div`,{ref:i,className:R(`z-markdown`,n),"data-streaming":t||void 0,...r,children:[a.map((e,n)=>(0,x.jsx)(fg,{block:e,last:n===a.length-1,streaming:t},n)),t&&a.length===0&&(0,x.jsx)(`span`,{className:`z-markdown__cursor`,"aria-hidden":`true`})]})});function fg({block:e,last:t,streaming:n}){let r=t&&n?(0,x.jsx)(`span`,{className:`z-markdown__cursor`,"aria-hidden":`true`}):null;switch(e.kind){case`paragraph`:return(0,x.jsxs)(`p`,{children:[(0,x.jsx)(pg,{nodes:e.children}),r]});case`heading`:{let t=`h${e.level}`;return(0,x.jsxs)(t,{children:[(0,x.jsx)(pg,{nodes:e.children}),r]})}case`list`:{let t=e.ordered?`ol`:`ul`;return(0,x.jsx)(t,{children:e.items.map((t,n)=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(pg,{nodes:t}),n===e.items.length-1?r:null]},n))})}case`code`:return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(ag,{code:e.code,language:e.language||void 0}),r]});case`quote`:return(0,x.jsxs)(`blockquote`,{children:[(0,x.jsx)(pg,{nodes:e.children}),r]});case`table`:return(0,x.jsxs)(Y,{density:`sm`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsx)(Y.Row,{children:e.header.map((e,t)=>(0,x.jsx)(Y.HeadCell,{children:(0,x.jsx)(pg,{nodes:e})},t))})}),(0,x.jsx)(Y.Body,{children:e.rows.map((e,t)=>(0,x.jsx)(Y.Row,{children:e.map((e,t)=>(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(pg,{nodes:e})},t))},t))})]});case`rule`:return(0,x.jsx)(`hr`,{})}}function pg({nodes:e}){return e.map((e,t)=>{switch(e.kind){case`text`:return e.text;case`code`:return(0,x.jsx)(`code`,{children:e.text},t);case`strong`:return(0,x.jsx)(`strong`,{children:(0,x.jsx)(pg,{nodes:e.children})},t);case`em`:return(0,x.jsx)(`em`,{children:(0,x.jsx)(pg,{nodes:e.children})},t);case`link`:return(0,x.jsx)(`a`,{href:e.href,target:e.href.startsWith(`http`)?`_blank`:void 0,rel:e.href.startsWith(`http`)?`noreferrer`:void 0,children:(0,x.jsx)(pg,{nodes:e.children})},t)}})}var mg=Object.defineProperty,hg=(e,t)=>mg(e,`name`,{value:t,configurable:!0}),gg=`Tabs`,[_g,vg]=T(gg,[rc]),yg=rc(),[bg,xg]=_g(gg),Sg=b.forwardRef(hg(function(e,t){let{__scopeTabs:n,value:r,onValueChange:i,defaultValue:a,orientation:o=`horizontal`,dir:s,activationMode:c=`automatic`,...l}=e,u=G(s),[d,f]=kt({prop:r,onChange:i,defaultProp:a??``,caller:gg});return(0,x.jsx)(bg,{scope:n,baseId:bt(),value:d,onValueChange:f,orientation:o,dir:u,activationMode:c,children:(0,x.jsx)(L.div,{dir:u,"data-orientation":o,...l,ref:t})})},`Tabs`)),Cg=`TabsList`,wg=b.forwardRef(hg(function(e,t){let{__scopeTabs:n,loop:r=!0,...i}=e,a=xg(Cg,n),o=yg(n);return(0,x.jsx)(hc,{asChild:!0,...o,orientation:a.orientation,dir:a.dir,loop:r,children:(0,x.jsx)(L.div,{role:`tablist`,"aria-orientation":a.orientation,...i,ref:t})})},`TabsList`)),Tg=`TabsTrigger`,Eg=b.forwardRef(hg(function(e,t){let{__scopeTabs:n,value:r,disabled:i=!1,...a}=e,o=xg(Tg,n),s=yg(n),c=kg(o.baseId,r),l=Ag(o.baseId,r),u=r===o.value;return(0,x.jsx)(gc,{asChild:!0,...s,focusable:!i,active:u,children:(0,x.jsx)(L.button,{type:`button`,role:`tab`,"aria-selected":u,"aria-controls":l,"data-state":u?`active`:`inactive`,"data-disabled":i?``:void 0,disabled:i,id:c,...a,ref:t,onMouseDown:U(e.onMouseDown,e=>{!i&&e.button===0&&e.ctrlKey===!1?o.onValueChange(r):e.preventDefault()}),onKeyDown:U(e.onKeyDown,e=>{i||e.target!==e.currentTarget||[` `,`Enter`].includes(e.key)&&o.onValueChange(r)}),onFocus:U(e.onFocus,()=>{let e=o.activationMode!==`manual`;!u&&!i&&e&&o.onValueChange(r)})})})},`TabsTrigger`)),Dg=`TabsContent`,Og=b.forwardRef(hg(function(e,t){let{__scopeTabs:n,value:r,forceMount:i,children:a,...o}=e,s=xg(Dg,n),c=kg(s.baseId,r),l=Ag(s.baseId,r),u=r===s.value,d=b.useRef(u);return b.useEffect(()=>{let e=requestAnimationFrame(()=>d.current=!1);return()=>cancelAnimationFrame(e)},[]),(0,x.jsx)(bn,{present:i||u,children:({present:n})=>(0,x.jsx)(L.div,{"data-state":u?`active`:`inactive`,"data-orientation":s.orientation,role:`tabpanel`,"aria-labelledby":c,hidden:!n,id:l,tabIndex:0,...o,ref:t,style:{...e.style,animationDuration:d.current?`0s`:void 0},children:n&&a})})},`TabsContent`));function kg(e,t){return`${e}-trigger-${t}`}hg(kg,`makeTriggerId`);function Ag(e,t){return`${e}-content-${t}`}hg(Ag,`makeContentId`);var jg=Sg,Mg=wg,Ng=Eg,Pg=Og,Fg=(0,b.forwardRef)(function({variant:e=`line`,size:t=`md`,className:n,...r},i){return(0,x.jsx)(jg,{ref:i,className:R(`z-tabs`,n),"data-variant":e,"data-size":t,...r})}),Ig=(0,b.forwardRef)(function({className:e,...t},n){return(0,x.jsx)(Mg,{ref:n,className:R(`z-tabs__list`,e),...t})}),Lg=(0,b.forwardRef)(function({className:e,...t},n){return(0,x.jsx)(Ng,{ref:n,className:R(`z-tabs__trigger z-focusable`,e),...t})}),Rg=(0,b.forwardRef)(function({className:e,...t},n){return(0,x.jsx)(Pg,{ref:n,className:R(`z-tabs__content z-focusable`,e),...t})}),Z=Object.assign(Fg,{List:Ig,Trigger:Lg,Content:Rg}),zg=(0,b.forwardRef)(function({variant:e=`text`,width:t,height:n,lines:r=1,className:i,style:a,...o},s){return e===`text`&&r>1?(0,x.jsx)(`span`,{ref:s,className:R(`z-skeleton-lines`,i),"aria-hidden":`true`,style:a,...o,children:Array.from({length:r},(e,n)=>(0,x.jsx)(`span`,{className:`z-skeleton`,"data-variant":`text`,style:{width:n===r-1?`60%`:t}},n))}):(0,x.jsx)(`span`,{ref:s,className:R(`z-skeleton`,i),"data-variant":e,"aria-hidden":`true`,style:{width:t,height:n,...a},...o})}),Bg=(0,b.forwardRef)(function({label:e=`Thinking`,showLabel:t=!1,size:n=`md`,className:r,...i},a){return(0,x.jsxs)(`span`,{ref:a,className:R(`z-loader`,r),"data-size":n,role:`status`,"aria-label":e,...i,children:[(0,x.jsxs)(`span`,{className:`z-loader__dots`,"aria-hidden":`true`,children:[(0,x.jsx)(`span`,{}),(0,x.jsx)(`span`,{}),(0,x.jsx)(`span`,{})]}),t&&(0,x.jsx)(`span`,{className:`z-loader__label`,children:e})]})}),Vg=(0,b.forwardRef)(function({title:e,description:t,icon:n,action:r,size:i=`md`,tone:a=`neutral`,className:o,...s},c){return(0,x.jsxs)(`div`,{ref:c,className:R(`z-empty`,o),"data-size":i,"data-tone":a,...s,children:[n&&(0,x.jsx)(`span`,{className:`z-empty__icon`,"aria-hidden":`true`,children:n}),(0,x.jsx)(`p`,{className:`z-empty__title`,children:e}),t&&(0,x.jsx)(`p`,{className:`z-empty__description`,children:t}),r&&(0,x.jsx)(`div`,{className:`z-empty__action`,children:r})]})});function Hg({columns:e,cards:t,cardId:n,cardColumn:r,renderCard:i,cardLabel:a,onMove:o,density:s=`md`,label:c,className:l}){let[u,d]=(0,b.useState)(null),[f,p]=(0,b.useState)(null),[m,h]=(0,b.useState)(``),g=(0,b.useId)(),_=(0,b.useRef)(new Map),v=(0,b.useCallback)(e=>t.filter(t=>r(t)===e),[t,r]),y=(0,b.useCallback)((e,t,r,i)=>{(t!==r||v(t).findIndex(t=>n(t)===e)!==i)&&o?.({cardId:e,from:t,to:r,index:i})},[v,n,o]);(0,b.useEffect)(()=>{u&&_.current.get(u.id)?.focus()},[u,t]);let S=(e,t)=>{u&&(y(u.id,u.column,e,t),d(null),p(null))},C=(t,i,o,s)=>{if(t.target!==t.currentTarget)return;let c=n(i),l=t.key;if(l===` `||l===`Enter`){if(t.preventDefault(),!u)d({id:c,column:r(i),index:s}),h(`${a(i)} lifted. Use the arrow keys to move it, Enter to drop, Escape to cancel.`);else{let t=f??{column:u.column,index:u.index},n=e.find(e=>e.id===t.column);y(u.id,u.column,t.column,t.index),h(`${a(i)} moved to ${typeof n?.title==`string`?n.title:t.column}, position ${t.index+1}.`),d(null),p(null)}return}if(l===`Escape`&&u){t.preventDefault(),h(`${a(i)} put back.`),d(null),p(null);return}if(!u)return;let m=f??{column:u.column,index:u.index},g=e.findIndex(e=>e.id===m.column);if(l===`ArrowLeft`||l===`ArrowRight`){t.preventDefault();let r=e[g+(l===`ArrowRight`?1:-1)];if(!r)return;let i=v(r.id).filter(e=>n(e)!==u.id).length,a=Math.min(m.index,i);p({column:r.id,index:a}),h(`Over ${typeof r.title==`string`?r.title:r.id}, position ${a+1}.`);return}if(l===`ArrowUp`||l===`ArrowDown`){t.preventDefault();let e=v(m.column).filter(e=>n(e)!==u.id).length,r=Math.max(0,Math.min(e,m.index+(l===`ArrowDown`?1:-1)));p({column:m.column,index:r}),h(`Position ${r+1}.`)}};return(0,x.jsxs)(`div`,{className:R(`z-kanban`,l),"data-density":s,role:`group`,"aria-label":c,children:[(0,x.jsx)(`p`,{className:`z-sr-only`,role:`status`,"aria-live":`polite`,children:m}),e.map((e,t)=>{let r=v(e.id),o=f?.column===e.id,s=e.limit!==void 0&&r.length>e.limit;return(0,x.jsxs)(`section`,{className:`z-kanban__column`,"data-over":o||void 0,"aria-labelledby":`${g}-${e.id}`,onDragOver:t=>{u&&(t.preventDefault(),p({column:e.id,index:r.filter(e=>n(e)!==u.id).length}))},onDrop:t=>{t.preventDefault(),S(e.id,f?.column===e.id?f.index:r.length)},children:[(0,x.jsxs)(`header`,{className:`z-kanban__head`,children:[(0,x.jsx)(`h3`,{className:`z-kanban__title`,id:`${g}-${e.id}`,children:e.title}),(0,x.jsx)(z,{size:`sm`,tone:s?`warning`:`neutral`,variant:`outline`,children:e.limit===void 0?r.length:`${r.length}/${e.limit}`})]}),(0,x.jsxs)(`ul`,{className:`z-kanban__list`,children:[r.map((r,s)=>{let c=n(r),l=u?.id===c;return(0,x.jsx)(`li`,{className:`z-kanban__slot`,"data-drop":o&&f?.index===s?``:void 0,children:(0,x.jsx)(`article`,{ref:e=>{e?_.current.set(c,e):_.current.delete(c)},className:`z-kanban__card z-focusable`,tabIndex:0,draggable:!0,"data-lifted":l||void 0,"aria-roledescription":`Draggable card`,"aria-label":a(r),"aria-grabbed":l||void 0,onKeyDown:e=>C(e,r,t,s),onDragStart:()=>d({id:c,column:e.id,index:s}),onDragEnd:()=>{d(null),p(null)},children:i(r)})},c)}),r.length===0&&(0,x.jsx)(`li`,{className:`z-kanban__slot`,"data-drop":o?``:void 0,children:e.empty??(0,x.jsx)(Vg,{size:`sm`,title:`Nothing here`})})]})]},e.id)})]})}function Ug(e,t){return`${e}-option-${t}`}function Wg(e){let{options:t,label:n,description:r,error:i,placeholder:a,size:o=`md`,disabled:s,emptyMessage:c=`No matches`,className:l,id:u}=e,d=e.multiple===!0,f=(0,b.useId)(),p=u??f,m=`${p}-list`,[h,g]=(0,b.useState)(!1),[_,v]=(0,b.useState)(``),[y,S]=(0,b.useState)(0),C=(0,b.useRef)(null),w=(0,b.useRef)(null),T=(0,b.useRef)(null),E=(0,b.useMemo)(()=>{if(d)return e.value??[];let t=e.value;return t?[t]:[]},[d,e]),D=(0,b.useMemo)(()=>new Map(t.map(e=>[e.value,e])),[t]),O=(0,b.useMemo)(()=>{let e=_.trim().toLowerCase();return e?t.filter(t=>t.label.toLowerCase().includes(e)||(t.hint??``).toLowerCase().includes(e)):t},[t,_,d]);(0,b.useEffect)(()=>S(0),[_,h]),(0,b.useEffect)(()=>{if(!h)return;let e=e=>{T.current?.contains(e.target)||g(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[h]),(0,b.useEffect)(()=>{h&&w.current?.querySelector(`[data-active="true"]`)?.scrollIntoView({block:`nearest`})},[y,h]);let k=t=>{if(!t.disabled){if(d){let n=E.includes(t.value)?E.filter(e=>e!==t.value):[...E,t.value];e.onValueChange?.(n),v(``),C.current?.focus();return}e.onValueChange?.(t.value),v(``),g(!1)}},A=t=>{d&&(e.onValueChange?.(E.filter(e=>e!==t)),C.current?.focus())},j=e=>{let t=e.key;if(t===`ArrowDown`||t===`ArrowUp`){if(e.preventDefault(),!h){g(!0);return}let n=t===`ArrowDown`?1:-1;for(let e=1;e<=O.length;e++){let t=(y+n*e+O.length*e)%O.length;if(!O[t]?.disabled){S(t);return}}return}if(t===`Enter`&&h){let t=O[y];t&&(e.preventDefault(),k(t));return}if(t===`Escape`){h&&(e.preventDefault(),g(!1));return}t===`Backspace`&&d&&_===``&&E.length&&A(E[E.length-1])},ee=(0,b.useMemo)(()=>{let e=[];for(let t of O){let n=e[e.length-1];n&&n.name===t.group?n.options.push(t):e.push({name:t.group,options:[t]})}return e},[O]),M=-1,N=[r?`${p}-description`:null,i?`${p}-error`:null].filter(Boolean).join(` `)||void 0;return(0,x.jsxs)(`div`,{ref:T,className:R(`z-combobox`,l),"data-size":o,"data-invalid":i?``:void 0,"data-disabled":s||void 0,children:[(0,x.jsx)(`label`,{className:`z-combobox__label`,htmlFor:p,children:n}),(0,x.jsxs)(`div`,{className:`z-combobox__control`,children:[d&&E.map(e=>(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`soft`,className:`z-combobox__chip`,children:[D.get(e)?.label??e,(0,x.jsx)(`button`,{type:`button`,className:`z-combobox__remove z-focusable`,"aria-label":`Remove ${D.get(e)?.label??e}`,onClick:()=>A(e),disabled:s,children:(0,x.jsx)(H.Close,{size:12})})]},e)),(0,x.jsx)(`input`,{ref:C,id:p,className:`z-combobox__input z-focusable`,role:`combobox`,type:`text`,autoComplete:`off`,"aria-expanded":h,"aria-controls":m,"aria-autocomplete":`list`,"aria-activedescendant":h&&O[y]?Ug(p,y):void 0,"aria-describedby":N,"aria-invalid":i?!0:void 0,disabled:s,placeholder:d||!E.length?a:D.get(E[0])?.label,value:_,onChange:e=>{v(e.target.value),g(!0)},onFocus:()=>g(!0),onKeyDown:j}),(0,x.jsx)(`span`,{className:`z-combobox__chevron`,"aria-hidden":`true`,children:(0,x.jsx)(H.ChevronDown,{size:16})})]}),h&&(0,x.jsxs)(`ul`,{ref:w,className:`z-combobox__list`,id:m,role:`listbox`,"aria-label":typeof n==`string`?n:void 0,"aria-multiselectable":d||void 0,children:[ee.map((e,t)=>(0,x.jsxs)(`li`,{className:`z-combobox__group`,role:`presentation`,children:[e.name&&(0,x.jsx)(`p`,{className:`z-combobox__group-name`,children:e.name}),(0,x.jsx)(`ul`,{role:`presentation`,children:e.options.map(e=>{M+=1;let t=M,n=E.includes(e.value);return(0,x.jsxs)(`li`,{id:Ug(p,t),"data-value":e.value,className:`z-combobox__option`,role:`option`,"aria-selected":n,"aria-disabled":e.disabled||void 0,"data-active":t===y,"data-selected":n||void 0,onPointerDown:t=>{t.preventDefault(),k(e)},onPointerEnter:()=>S(t),children:[(0,x.jsx)(`span`,{className:`z-combobox__option-label`,children:e.label}),e.hint&&(0,x.jsx)(`span`,{className:`z-combobox__option-hint`,children:e.hint}),n&&(0,x.jsx)(`span`,{className:`z-combobox__tick`,"aria-hidden":`true`,children:(0,x.jsx)(H.Check,{size:14})})]},e.value)})})]},e.name??`g${t}`)),O.length===0&&(0,x.jsx)(`li`,{className:`z-combobox__empty`,role:`presentation`,children:c})]}),r&&!i&&(0,x.jsx)(`p`,{className:`z-combobox__description`,id:`${p}-description`,children:r}),i&&(0,x.jsx)(`p`,{className:`z-combobox__error`,id:`${p}-error`,children:i})]})}var Gg=[`new`,`reviewing`,`applying`,`ready`,`applied`,`interviewing`,`offer`,`rejected`,`passed`],Kg=[`wrong role shape`,`weak evidence match`,`compensation`,`location or authorisation`,`too managerial`,`too visual`,`too engineering`,`stale or duplicate`,`company`],qg=[`recruiter`,`hiring-manager`,`interviewer`,`referral`,`other`];async function Q(e,t){let n=await fetch(e,{headers:{"content-type":`application/json`},...t}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(r.error||`${n.status} ${n.statusText}`);return r}var $={summary:()=>Q(`/api/summary`),jobs:e=>{let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&r!==``&&r!==null&&t.set(n,String(r));return Q(`/api/jobs?${t}`)},facets:e=>{let t=new URLSearchParams;for(let[n,r]of Object.entries(e))r!==void 0&&r!==``&&r!==null&&t.set(n,String(r));return Q(`/api/jobs/facets?${t}`)},job:e=>Q(`/api/jobs/${encodeURIComponent(e)}`),attachPosting:(e,t,n=!1)=>Q(`/api/jobs/${encodeURIComponent(e)}/attach`,{method:`POST`,body:JSON.stringify({url:t,linkOnly:n})}),settings:()=>Q(`/api/settings`),saveSettings:e=>Q(`/api/settings`,{method:`PUT`,body:JSON.stringify(e)}),resumes:()=>Q(`/api/resumes`),useResume:e=>Q(`/api/resumes/use`,{method:`POST`,body:JSON.stringify({name:e})}),openResume:e=>Q(`/api/resumes/open`,{method:`POST`,body:JSON.stringify({name:e})}),revealJob:e=>Q(`/api/jobs/${encodeURIComponent(e)}/reveal`,{method:`POST`}),importLinks:e=>Q(`/api/jobs/import`,{method:`POST`,body:JSON.stringify({urls:e})}),today:(e=7)=>Q(`/api/today?cap=${e}`),setStatus:(e,t,n)=>Q(`/api/jobs/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify({status:t,reason:n})}),addNote:(e,t)=>Q(`/api/jobs/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify({note:t})}),packet:e=>Q(`/api/jobs/${encodeURIComponent(e)}/packet`),coverLetter:e=>Q(`/api/jobs/${encodeURIComponent(e)}/cover-letter`),writeCoverLetter:(e,t)=>Q(`/api/jobs/${encodeURIComponent(e)}/cover-letter`,{method:`POST`,body:JSON.stringify(t)}),tailoredResume:e=>Q(`/api/jobs/${encodeURIComponent(e)}/resume`),writeTailoredResume:(e,t)=>Q(`/api/jobs/${encodeURIComponent(e)}/resume`,{method:`POST`,body:JSON.stringify(t)}),saveTailoredResume:(e,t)=>Q(`/api/jobs/${encodeURIComponent(e)}/resume`,{method:`PUT`,body:JSON.stringify({text:t})}),resumePrintUrl:e=>`/api/jobs/${encodeURIComponent(e)}/resume.html`,saveCoverLetter:(e,t)=>Q(`/api/jobs/${encodeURIComponent(e)}/cover-letter`,{method:`PUT`,body:JSON.stringify({text:t})}),saveApplication:(e,t,n)=>Q(`/api/jobs/${encodeURIComponent(e)}`,{method:`PATCH`,body:JSON.stringify({application:{field:t,value:n}})}),runs:()=>Q(`/api/runs`),scan:()=>Q(`/api/scan`),startScan:(e=!1,t,n=!1)=>Q(`/api/scan`,{method:`POST`,body:JSON.stringify({dry:e,criteria:t||``,retryFailed:n})}),criteria:()=>Q(`/api/criteria`),saveCriteria:e=>Q(`/api/criteria`,{method:`PUT`,body:JSON.stringify({raw:e})}),outcomes:()=>Q(`/api/outcomes`),views:()=>Q(`/api/views`),defaultViews:()=>Q(`/api/views/defaults`),saveViews:e=>Q(`/api/views`,{method:`PUT`,body:JSON.stringify({views:e})}),mail:()=>Q(`/api/mail`),mailCheck:e=>Q(`/api/mail/check`,{method:`POST`,body:JSON.stringify({sinceDays:e})}),mailConfirm:(e,t)=>Q(`/api/mail/${encodeURIComponent(e)}/confirm`,{method:`POST`,body:JSON.stringify({noteId:t})}),mailConfirmSafe:()=>Q(`/api/mail/confirm-safe`,{method:`POST`}),mailDismiss:e=>Q(`/api/mail/${encodeURIComponent(e)}/dismiss`,{method:`POST`}),previewCriteria:e=>Q(`/api/criteria/preview`,{method:`POST`,body:JSON.stringify({raw:e})}),rescoreNotes:(e=!1)=>Q(`/api/rescore`,{method:`POST`,body:JSON.stringify({dry:e})}),criteriaPresets:()=>Q(`/api/criteria/presets`),criteriaPreset:e=>Q(`/api/criteria/presets/${encodeURIComponent(e)}`),saveCriteriaPreset:(e,t)=>Q(`/api/criteria/presets/${encodeURIComponent(e)}`,{method:`PUT`,body:JSON.stringify({raw:t})}),deleteCriteriaPreset:e=>Q(`/api/criteria/presets/${encodeURIComponent(e)}`,{method:`DELETE`}),activateCriteriaPreset:e=>Q(`/api/criteria/presets/${encodeURIComponent(e)}/activate`,{method:`POST`}),profileNotes:()=>Q(`/api/profile`),profileSummary:()=>Q(`/api/profile/summary`),saveProfileNote:(e,t)=>Q(`/api/profile`,{method:`PUT`,body:JSON.stringify({note:e,markdown:t})}),snippets:()=>Q(`/api/snippets`),saveSnippets:e=>Q(`/api/snippets`,{method:`PUT`,body:JSON.stringify({items:e})}),people:()=>Q(`/api/people`),person:e=>Q(`/api/people/${encodeURIComponent(e)}`),addPerson:e=>Q(`/api/people`,{method:`POST`,body:JSON.stringify(e)}),attachPerson:(e,t,n,r)=>Q(`/api/people/${encodeURIComponent(e)}/attach`,{method:`POST`,body:JSON.stringify({jobId:t,role:n,context:r})}),logContact:(e,t,n)=>Q(`/api/people/${encodeURIComponent(e)}/log`,{method:`POST`,body:JSON.stringify({text:t,date:n})}),jobPeople:e=>Q(`/api/jobs/${encodeURIComponent(e)}/people`),jobConnections:e=>Q(`/api/jobs/${encodeURIComponent(e)}/connections`),linkedinStatus:()=>Q(`/api/linkedin`),linkedinPreview:(e,t,n)=>Q(`/api/linkedin/preview`,{method:`POST`,body:JSON.stringify({source:e,since:t,everyone:n})}),linkedinImport:(e,t={})=>Q(`/api/linkedin/import`,{method:`POST`,body:JSON.stringify({source:e,...t})}),tools:()=>Q(`/api/tools`),companies:()=>Q(`/api/companies`),addCompany:e=>Q(`/api/companies`,{method:`POST`,body:JSON.stringify(e)}),findBoard:(e,t,n)=>Q(`/api/companies/find?slug=${encodeURIComponent(e)}&ats=${encodeURIComponent(t)}&name=${encodeURIComponent(n)}`),moveBoard:e=>Q(`/api/companies/move`,{method:`POST`,body:JSON.stringify(e)}),feeds:()=>Q(`/api/feeds`),onboarding:()=>Q(`/api/onboarding`),initProfile:()=>Q(`/api/onboarding/init`,{method:`POST`,body:`{}`}),importResume:e=>Q(`/api/onboarding/resume`,{method:`POST`,body:JSON.stringify({path:e})})},Jg=e=>`$${Math.round(e/1e3)}k`,Yg=e=>{let t=(e.replace(/\s*[•·].*$/,``).split(/(?<=[a-z])(?=[A-Z])/)[0]??``).replace(/\s+/g,` `).trim();return t.length>30?t.slice(0,29).trimEnd()+`…`:t},Xg=e=>{if(!e)return``;let t=Math.floor((Date.now()-new Date(e).getTime())/864e5);return Number.isFinite(t)?t<=0?`today`:`${t}d ago`:``},Zg={floor:`Floor`,stretch:`Stretch`,below:`Below`,unknown:`Not stated`},Qg={floor:`success`,stretch:`warning`,below:`neutral`,unknown:`neutral`},$g={new:`neutral`,reviewing:`primary`,applying:`primary`,ready:`warning`,applied:`primary`,interviewing:`warning`,offer:`success`,rejected:`danger`,passed:`neutral`};function e_(e){let[t,n]=(0,b.useState)(()=>typeof window<`u`&&window.matchMedia(e).matches);return(0,b.useEffect)(()=>{let t=window.matchMedia(e),r=()=>n(t.matches);return r(),t.addEventListener(`change`,r),()=>t.removeEventListener(`change`,r)},[e]),t}var t_={name:`TekJobs`,logo:`/brand/tekjobs-avatar-192.png`};function n_({href:e=`/`}){return(0,x.jsxs)(`a`,{className:`brand-mark`,href:e,"aria-label":t_.name,children:[t_.logo&&(0,x.jsx)(`img`,{className:`brand-mark__logo`,src:t_.logo,alt:``}),(0,x.jsxs)(`span`,{"aria-hidden":`true`,children:[`Tek`,(0,x.jsx)(`span`,{className:`brand-mark__accent`,children:`Jobs`})]})]})}function r_(){let[e,t]=(0,b.useState)(!1),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)(``),[o,s]=(0,b.useState)(null),[c,l]=(0,b.useState)(!1),u=(0,b.useRef)(null),d=()=>$.snippets().then(r).catch(e=>X({title:`Could not load the copy panel`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{e&&!n&&d()},[e]),(0,b.useEffect)(()=>{e?setTimeout(()=>u.current?.focus(),30):a(``)},[e]);let f=(0,b.useMemo)(()=>{let e=i.trim().toLowerCase(),t=(n?.items??[]).filter(t=>t.value&&(!e||`${t.group} ${t.label} ${t.value}`.toLowerCase().includes(e))),r=new Map;for(let e of t){let t=e.group||`Other`;r.has(t)||r.set(t,[]),r.get(t).push(e)}return[...r.entries()]},[n,i]),p=async e=>{try{await navigator.clipboard.writeText(e.value),s(e.label),setTimeout(()=>s(t=>t===e.label?null:t),1600)}catch(e){X({title:`Could not copy`,description:e.message,tone:`danger`})}},m=f[0]?.[1][0];return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(fd,{open:e,onOpenChange:t,size:`lg`,children:[(0,x.jsx)(Bh,{content:`Copy panel`,children:(0,x.jsx)(fd.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,"aria-label":`Copy panel`,leadingIcon:(0,x.jsx)(H.Copy,{})})})}),(0,x.jsx)(fd.Content,{align:`end`,showArrow:!1,children:(0,x.jsxs)(`div`,{className:`copy`,children:[(0,x.jsx)(`form`,{className:`copy__search`,onSubmit:e=>{e.preventDefault(),m&&p(m)},children:(0,x.jsx)(Zp,{ref:u,size:`sm`,"aria-label":`Find a snippet`,placeholder:`Find, then Enter copies the first`,leadingIcon:(0,x.jsx)(H.Search,{}),value:i,onChange:e=>a(e.target.value)})}),n?f.length===0?(0,x.jsx)(`p`,{className:`muted copy__empty`,children:n.items.length===0?`Nothing here yet. Customize adds lines.`:i?`Nothing matches.`:`Every snippet is empty. Customize fills them in.`}):(0,x.jsx)(`div`,{className:`copy__groups`,children:f.map(([e,t])=>(0,x.jsxs)(`div`,{className:`copy__group`,children:[(0,x.jsx)(`div`,{className:`microlabel`,children:e}),t.map(t=>(0,x.jsx)(B,{asChild:!0,variant:`ghost`,tone:`neutral`,size:`sm`,align:`start`,className:`copy__row`,children:(0,x.jsxs)(`button`,{type:`button`,onClick:()=>p(t),title:t.value,children:[(0,x.jsx)(`span`,{className:`copy__label`,children:t.label}),(0,x.jsxs)(`span`,{className:`copy__value num`,children:[o===t.label?`Copied`:t.value.split(`
58
58
  `)[0],t.value.includes(`
59
59
  `)&&o!==t.label?` …`:``]})]})},`${e}:${t.label}`))]},e))}):(0,x.jsx)(zg,{lines:4}),(0,x.jsxs)(`div`,{className:`copy__foot`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,leadingIcon:(0,x.jsx)(H.Edit,{}),onClick:()=>{t(!1),l(!0)},children:`Customize`}),n&&!n.exists&&(0,x.jsx)(`span`,{className:`muted`,children:`Read from your profile until you save once.`})]})]})})]}),c&&n&&(0,x.jsx)(i_,{initial:n.items,path:n.path,onClose:()=>l(!1),onSaved:e=>{r(e),l(!1)}})]})}function i_({initial:e,path:t,onClose:n,onSaved:r}){let[i,a]=(0,b.useState)(e.length?e:[{group:``,label:``,value:``}]),[o,s]=(0,b.useState)(!1),c=(e,t)=>a(n=>n.map((n,r)=>r===e?{...n,...t}:n)),l=(e,t)=>a(n=>{let r=e+t;if(r<0||r>=n.length)return n;let i=[...n];return[i[e],i[r]]=[i[r],i[e]],i}),u=e=>a(t=>t.filter((t,n)=>n!==e));return(0,x.jsx)(Sp,{open:!0,onOpenChange:e=>!e&&n(),side:`right`,size:`md`,children:(0,x.jsx)(Sp.Content,{children:(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(Sp.Title,{children:`Customize the copy panel`}),(0,x.jsxs)(Sp.Description,{children:[`Label is the button, group is its heading, value is what lands on the clipboard. Lines with no label are dropped. Saved to `,(0,x.jsx)(`code`,{className:`mono`,children:t.split(/[\\/]/).slice(-2).join(`/`)}),`, so Obsidian works too.`]}),(0,x.jsx)(`div`,{className:`copy__rows`,children:i.map((e,t)=>(0,x.jsxs)(`div`,{className:`copy__edit`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(Zp,{size:`sm`,label:`Label`,value:e.label,onChange:e=>c(t,{label:e.target.value})}),(0,x.jsx)(Zp,{size:`sm`,label:`Group`,value:e.group,onChange:e=>c(t,{group:e.target.value})})]}),(0,x.jsx)(Xp,{label:`Value`,rows:e.value.includes(`
60
- `)?4:1,value:e.value,onChange:e=>c(t,{value:e.target.value})}),(0,x.jsxs)(`div`,{className:`copy__edit-actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Move up`,leadingIcon:(0,x.jsx)(H.ArrowUp,{}),disabled:t===0,onClick:()=>l(t,-1)}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Move down`,leadingIcon:(0,x.jsx)(H.ArrowDown,{}),disabled:t===i.length-1,onClick:()=>l(t,1)}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`danger`,"aria-label":`Remove`,leadingIcon:(0,x.jsx)(H.Trash,{}),onClick:()=>u(t)})]})]},t))}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`neutral`,leadingIcon:(0,x.jsx)(H.Plus,{}),onClick:()=>a(e=>[...e,{group:e[e.length-1]?.group??``,label:``,value:``}]),children:`Add a line`}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:n,children:`Cancel`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,loading:o,onClick:async()=>{s(!0);try{let e=await $.saveSnippets(i);X({title:`Copy panel saved`,description:`Profile/Snippets.md`,tone:`success`}),r(e)}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}s(!1)},children:`Save`})]})]})})})}var a_=[{page:`onboarding`,label:`Get started`,icon:H.Sparkles},{page:`today`,label:`Today`,icon:H.Star},{page:`overview`,label:`Overview`,icon:H.Home},{page:`jobs`,label:`Jobs`,icon:H.Inbox},{page:`pipeline`,label:`Pipeline`,icon:H.Layers},{page:`mail`,label:`Mail`,icon:H.Mail},{page:`people`,label:`People`,icon:H.Users},{page:`companies`,label:`Sources`,icon:H.Globe},{page:`criteria`,label:`Criteria`,icon:H.Filter},{page:`profile`,label:`Profile`,icon:H.User},{page:`runs`,label:`Runs`,icon:H.Refresh},{page:`agent`,label:`Agent access`,icon:H.Terminal},{page:`settings`,label:`Settings`,icon:H.Settings}],o_={onboarding:`Get started`,today:`Today`,overview:`Overview`,jobs:`Jobs`,pipeline:`Pipeline`,mail:`Mail`,people:`People`,companies:`Sources`,criteria:`Criteria`,profile:`Profile`,runs:`Runs`,agent:`Agent access`,settings:`Settings`},s_=[{title:`Work`,pages:[`today`,`jobs`,`pipeline`,`mail`,`people`]},{title:`Insights`,pages:[`overview`]},{title:`Setup`,pages:[`profile`,`criteria`,`companies`]},{title:`System`,pages:[`runs`,`agent`,`settings`,`onboarding`]}];function c_({page:e,onNavigate:t,onSearch:n,theme:r,onToggleTheme:i,onboarded:a=!0,counts:o={},lastScan:s=``,children:c}){let[l,u]=(0,b.useState)(!1),d=e_(`(max-width: 40rem)`),[f,p]=(0,b.useState)(``),[m,h]=(0,b.useState)(()=>{try{return localStorage.getItem(`tekjobs.sidebar`)===`collapsed`}catch{return!1}}),g=()=>h(e=>{try{localStorage.setItem(`tekjobs.sidebar`,e?`open`:`collapsed`)}catch{}return!e}),_=e=>{t(e),u(!1)};return(0,x.jsxs)(`div`,{className:`shell${m?` shell--collapsed`:``}${d?` shell--strip`:``}`,children:[(0,x.jsx)(`aside`,{className:`sidebar`,"aria-label":`Primary`,children:(0,x.jsx)(l_,{page:e,onNavigate:_,onboarded:a,counts:o,lastScan:s,collapsed:m||d,onToggleCollapsed:d?void 0:g,tipSide:d?`bottom`:`right`})}),(0,x.jsxs)(`div`,{className:`main`,children:[(0,x.jsxs)(`header`,{className:`topbar`,children:[(0,x.jsxs)(Sp,{open:l,onOpenChange:u,side:`left`,size:`sm`,children:[(0,x.jsx)(Sp.Trigger,{asChild:!0,children:(0,x.jsx)(B,{className:`topbar__menu`,variant:`ghost`,size:`sm`,"aria-label":`Open navigation`,leadingIcon:(0,x.jsx)(H.Menu,{})})}),(0,x.jsxs)(Sp.Content,{children:[(0,x.jsx)(Sp.Title,{children:`Navigation`}),(0,x.jsx)(`div`,{className:`sidebar sidebar--sheet`,children:(0,x.jsx)(l_,{page:e,onNavigate:_,onboarded:a,counts:o,lastScan:s,collapsed:!1})})]})]}),(0,x.jsx)(`h1`,{className:`topbar__title`,children:o_[e]}),(0,x.jsx)(`form`,{className:`topbar__search`,onSubmit:e=>{e.preventDefault(),n(f.trim())},children:(0,x.jsx)(Zp,{size:`sm`,placeholder:`Search company or role`,"aria-label":`Search jobs`,leadingIcon:(0,x.jsx)(H.Search,{}),trailingIcon:(0,x.jsx)(`span`,{className:`num`,children:`⌘K`}),value:f,onChange:e=>p(e.target.value)})}),(0,x.jsxs)(`div`,{className:`topbar__actions`,children:[(0,x.jsx)(r_,{}),(0,x.jsx)(Bh,{content:r===`light`?`Switch to dark`:`Switch to light`,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,onClick:i,"aria-label":`Toggle theme`,leadingIcon:r===`light`?(0,x.jsx)(H.Moon,{}):(0,x.jsx)(H.Sun,{})})})]})]}),c]})]})}function l_({page:e,onNavigate:t,onboarded:n,counts:r,lastScan:i,collapsed:a,onToggleCollapsed:o,tipSide:s=`right`}){let c=new Map(a_.map(e=>[e.page,e])),l=n?s_:[{title:`Start`,pages:[`onboarding`]},...s_.map(e=>({...e,pages:e.pages.filter(e=>e!==`onboarding`)}))];return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`brand`,children:[(0,x.jsx)(n_,{}),o&&(0,x.jsx)(Bh,{content:a?`Expand the sidebar`:`Collapse the sidebar`,children:(0,x.jsx)(B,{className:`sidebar__collapse`,variant:`ghost`,size:`sm`,tone:`neutral`,"aria-label":a?`Expand the sidebar`:`Collapse the sidebar`,leadingIcon:a?(0,x.jsx)(H.ChevronRight,{}):(0,x.jsx)(H.ChevronLeft,{}),onClick:o})})]}),(0,x.jsx)(`nav`,{className:`nav`,"aria-label":`Pages`,children:l.map(n=>(0,x.jsxs)(`div`,{className:`nav__group`,children:[!a&&(0,x.jsx)(`div`,{className:`nav__group-title`,children:n.title}),n.pages.map(e=>c.get(e)).filter(e=>!!e).map(n=>{let i=(0,x.jsx)(B,{className:`nav__item`,align:`start`,variant:e===n.page?`soft`:`ghost`,tone:e===n.page?`primary`:`neutral`,size:`sm`,leadingIcon:(0,x.jsx)(n.icon,{}),trailingIcon:!a&&r[n.page]!=null?(0,x.jsx)(`span`,{className:`nav__count`,children:r[n.page]}):void 0,"aria-current":e===n.page?`page`:void 0,"aria-label":a?n.label:void 0,onClick:()=>t(n.page),children:a?null:n.label},n.page);return a?(0,x.jsx)(Bh,{content:r[n.page]==null?n.label:`${n.label} · ${r[n.page]}`,side:s,children:i},n.page):i})]},n.title))}),!a&&(0,x.jsx)(`div`,{className:`sidebar__foot`,children:(0,x.jsxs)(`div`,{children:[`Notes are the record.`,i&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`br`,{}),(0,x.jsx)(`span`,{className:`num`,children:i})]}),(0,x.jsx)(`br`,{}),(0,x.jsxs)(`span`,{className:`num`,children:[`v`,`0.35.1`]}),(0,x.jsx)(`br`,{}),(0,x.jsx)(`a`,{className:`sidebar__legal`,href:`https://tekjobs.timurtek.com/legal/terms`,target:`_blank`,rel:`noreferrer`,children:`Terms`}),` · `,(0,x.jsx)(`a`,{className:`sidebar__legal`,href:`https://tekjobs.timurtek.com/legal/privacy`,target:`_blank`,rel:`noreferrer`,children:`Privacy`})]})})]})}var u_=`{
60
+ `)?4:1,value:e.value,onChange:e=>c(t,{value:e.target.value})}),(0,x.jsxs)(`div`,{className:`copy__edit-actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Move up`,leadingIcon:(0,x.jsx)(H.ArrowUp,{}),disabled:t===0,onClick:()=>l(t,-1)}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Move down`,leadingIcon:(0,x.jsx)(H.ArrowDown,{}),disabled:t===i.length-1,onClick:()=>l(t,1)}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`danger`,"aria-label":`Remove`,leadingIcon:(0,x.jsx)(H.Trash,{}),onClick:()=>u(t)})]})]},t))}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`neutral`,leadingIcon:(0,x.jsx)(H.Plus,{}),onClick:()=>a(e=>[...e,{group:e[e.length-1]?.group??``,label:``,value:``}]),children:`Add a line`}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:n,children:`Cancel`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,loading:o,onClick:async()=>{s(!0);try{let e=await $.saveSnippets(i);X({title:`Copy panel saved`,description:`Profile/Snippets.md`,tone:`success`}),r(e)}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}s(!1)},children:`Save`})]})]})})})}var a_=[{page:`onboarding`,label:`Get started`,icon:H.Sparkles},{page:`today`,label:`Today`,icon:H.Star},{page:`overview`,label:`Overview`,icon:H.Home},{page:`jobs`,label:`Jobs`,icon:H.Inbox},{page:`pipeline`,label:`Pipeline`,icon:H.Layers},{page:`mail`,label:`Mail`,icon:H.Mail},{page:`people`,label:`People`,icon:H.Users},{page:`companies`,label:`Sources`,icon:H.Globe},{page:`criteria`,label:`Criteria`,icon:H.Filter},{page:`profile`,label:`Profile`,icon:H.User},{page:`runs`,label:`Runs`,icon:H.Refresh},{page:`agent`,label:`Agent access`,icon:H.Terminal},{page:`settings`,label:`Settings`,icon:H.Settings}],o_={onboarding:`Get started`,today:`Today`,overview:`Overview`,jobs:`Jobs`,pipeline:`Pipeline`,mail:`Mail`,people:`People`,companies:`Sources`,criteria:`Criteria`,profile:`Profile`,runs:`Runs`,agent:`Agent access`,settings:`Settings`},s_=[{title:`Work`,pages:[`today`,`jobs`,`pipeline`,`mail`,`people`]},{title:`Insights`,pages:[`overview`]},{title:`Setup`,pages:[`profile`,`criteria`,`companies`]},{title:`System`,pages:[`runs`,`agent`,`settings`,`onboarding`]}];function c_({page:e,onNavigate:t,onSearch:n,theme:r,onToggleTheme:i,onboarded:a=!0,counts:o={},lastScan:s=``,children:c}){let[l,u]=(0,b.useState)(!1),d=e_(`(max-width: 40rem)`),[f,p]=(0,b.useState)(``),[m,h]=(0,b.useState)(()=>{try{return localStorage.getItem(`tekjobs.sidebar`)===`collapsed`}catch{return!1}}),g=()=>h(e=>{try{localStorage.setItem(`tekjobs.sidebar`,e?`open`:`collapsed`)}catch{}return!e}),_=e=>{t(e),u(!1)};return(0,x.jsxs)(`div`,{className:`shell${m?` shell--collapsed`:``}${d?` shell--strip`:``}`,children:[(0,x.jsx)(`aside`,{className:`sidebar`,"aria-label":`Primary`,children:(0,x.jsx)(l_,{page:e,onNavigate:_,onboarded:a,counts:o,lastScan:s,collapsed:m||d,onToggleCollapsed:d?void 0:g,tipSide:d?`bottom`:`right`})}),(0,x.jsxs)(`div`,{className:`main`,children:[(0,x.jsxs)(`header`,{className:`topbar`,children:[(0,x.jsxs)(Sp,{open:l,onOpenChange:u,side:`left`,size:`sm`,children:[(0,x.jsx)(Sp.Trigger,{asChild:!0,children:(0,x.jsx)(B,{className:`topbar__menu`,variant:`ghost`,size:`sm`,"aria-label":`Open navigation`,leadingIcon:(0,x.jsx)(H.Menu,{})})}),(0,x.jsxs)(Sp.Content,{children:[(0,x.jsx)(Sp.Title,{children:`Navigation`}),(0,x.jsx)(`div`,{className:`sidebar sidebar--sheet`,children:(0,x.jsx)(l_,{page:e,onNavigate:_,onboarded:a,counts:o,lastScan:s,collapsed:!1})})]})]}),(0,x.jsx)(`h1`,{className:`topbar__title`,children:o_[e]}),(0,x.jsx)(`form`,{className:`topbar__search`,onSubmit:e=>{e.preventDefault(),n(f.trim())},children:(0,x.jsx)(Zp,{size:`sm`,placeholder:`Search company or role`,"aria-label":`Search jobs`,leadingIcon:(0,x.jsx)(H.Search,{}),trailingIcon:(0,x.jsx)(`span`,{className:`num`,children:`⌘K`}),value:f,onChange:e=>p(e.target.value)})}),(0,x.jsxs)(`div`,{className:`topbar__actions`,children:[(0,x.jsx)(r_,{}),(0,x.jsx)(Bh,{content:r===`light`?`Switch to dark`:`Switch to light`,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,onClick:i,"aria-label":`Toggle theme`,leadingIcon:r===`light`?(0,x.jsx)(H.Moon,{}):(0,x.jsx)(H.Sun,{})})})]})]}),c]})]})}function l_({page:e,onNavigate:t,onboarded:n,counts:r,lastScan:i,collapsed:a,onToggleCollapsed:o,tipSide:s=`right`}){let c=new Map(a_.map(e=>[e.page,e])),l=n?s_:[{title:`Start`,pages:[`onboarding`]},...s_.map(e=>({...e,pages:e.pages.filter(e=>e!==`onboarding`)}))];return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`brand`,children:[(0,x.jsx)(n_,{}),o&&(0,x.jsx)(Bh,{content:a?`Expand the sidebar`:`Collapse the sidebar`,children:(0,x.jsx)(B,{className:`sidebar__collapse`,variant:`ghost`,size:`sm`,tone:`neutral`,"aria-label":a?`Expand the sidebar`:`Collapse the sidebar`,leadingIcon:a?(0,x.jsx)(H.ChevronRight,{}):(0,x.jsx)(H.ChevronLeft,{}),onClick:o})})]}),(0,x.jsx)(`nav`,{className:`nav`,"aria-label":`Pages`,children:l.map(n=>(0,x.jsxs)(`div`,{className:`nav__group`,children:[!a&&(0,x.jsx)(`div`,{className:`nav__group-title`,children:n.title}),n.pages.map(e=>c.get(e)).filter(e=>!!e).map(n=>{let i=(0,x.jsx)(B,{className:`nav__item`,align:`start`,variant:e===n.page?`soft`:`ghost`,tone:e===n.page?`primary`:`neutral`,size:`sm`,leadingIcon:(0,x.jsx)(n.icon,{}),trailingIcon:!a&&r[n.page]!=null?(0,x.jsx)(`span`,{className:`nav__count`,children:r[n.page]}):void 0,"aria-current":e===n.page?`page`:void 0,"aria-label":a?n.label:void 0,onClick:()=>t(n.page),children:a?null:n.label},n.page);return a?(0,x.jsx)(Bh,{content:r[n.page]==null?n.label:`${n.label} · ${r[n.page]}`,side:s,children:i},n.page):i})]},n.title))}),!a&&(0,x.jsx)(`div`,{className:`sidebar__foot`,children:(0,x.jsxs)(`div`,{children:[`Notes are the record.`,i&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`br`,{}),(0,x.jsx)(`span`,{className:`num`,children:i})]}),(0,x.jsx)(`br`,{}),(0,x.jsxs)(`span`,{className:`num`,children:[`v`,`0.36.0`]}),(0,x.jsx)(`br`,{}),(0,x.jsx)(`a`,{className:`sidebar__legal`,href:`https://tekjobs.timurtek.com/legal/terms`,target:`_blank`,rel:`noreferrer`,children:`Terms`}),` · `,(0,x.jsx)(`a`,{className:`sidebar__legal`,href:`https://tekjobs.timurtek.com/legal/privacy`,target:`_blank`,rel:`noreferrer`,children:`Privacy`})]})})]})}var u_=`{
61
61
  "mcpServers": {
62
62
  "tekjobs": {
63
63
  "command": "tekjobs",
@@ -71,7 +71,7 @@ Defaulting to \`null\`.`}md(Ad,`getInvalidValueError`);var jd=xd,Md=Cd;(0,b.forw
71
71
  5. set_status id=<note> status=applying`})]})})]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:6})}):(0,x.jsxs)(Y,{"aria-label":`MCP tools`,density:`md`,stickyHeader:!0,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Tool`}),(0,x.jsx)(Y.HeadCell,{children:`What it does`})]})}),(0,x.jsxs)(Y.Body,{children:[e.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`code`,{className:`mono`,children:e.name})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.description})})]},e.name)),e.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:2,children:(0,x.jsxs)(`span`,{className:`muted`,children:[`The server did not answer; start it with `,(0,x.jsx)(`code`,{className:`mono`,children:`tekjobs up`}),`.`]})})})]})]})}),(0,x.jsxs)(`p`,{className:`muted`,children:[e?`${e.length} tools, read from the running server.`:``,` Confirming mail items and setting applied, interviewing or offer stay yours: an agent can read and draft, and moves a job only as far as ready.`]})]})}var f_=[`greenhouse`,`lever`,`ashby`,`workday`,`rippling`,`smartrecruiters`,`workable`,`bamboohr`,`breezy`,`personio`,`teamtailor`,`eightfold`],p_=[{key:`failed`,label:`Failed`,tone:`danger`},{key:`zero`,label:`Zero jobs`,tone:`warning`},{key:`stale`,label:`Stale`,tone:`warning`},{key:`never`,label:`Never fetched`,tone:`neutral`},{key:`ok`,label:`Healthy`,tone:`success`}],m_=Object.fromEntries(p_.map(e=>[e.key,e.tone])),h_=Object.fromEntries(p_.map(e=>[e.key,e.label]));function g_(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)(``),[o,s]=(0,b.useState)(`all`),[c,l]=(0,b.useState)(`all`),[u,d]=(0,b.useState)(!1),[f,p]=(0,b.useState)({name:``,ats:`greenhouse`,slug:``,tier:`B`,notes:``}),[m,h]=(0,b.useState)(!1),[g,_]=(0,b.useState)(!1);(0,b.useEffect)(()=>{$.companies().then(t).catch(e=>X({title:`Could not load the watchlist`,description:e.message,tone:`danger`})),$.feeds().then(r).catch(()=>r([]))},[]);let v=(0,b.useMemo)(()=>{let t={};for(let n of e??[])t[n.health.state]=(t[n.health.state]||0)+1;return t},[e]),y=(0,b.useMemo)(()=>{let t=i.trim().toLowerCase(),n=e=>p_.findIndex(t=>t.key===e);return(e??[]).filter(e=>(o===`all`||e.tier===o)&&(c===`all`||e.health.state===c)&&(!t||`${e.name} ${e.ats} ${e.slug}`.toLowerCase().includes(t))).sort((e,t)=>n(e.health.state)-n(t.health.state)||e.name.localeCompare(t.name))},[e,i,o,c]),S=v.failed||0,[C,w]=(0,b.useState)({}),T=e=>`${e.ats}:${e.slug}`,E=async e=>{w(t=>({...t,[T(e)]:`looking`}));try{w(t=>({...t,[T(e)]:void 0}));let t=await $.findBoard(e.slug,e.ats,e.name);w(n=>({...n,[T(e)]:t}))}catch(t){w(t=>{let n={...t};return delete n[T(e)],n}),X({title:`Could not probe`,description:t.message,tone:`danger`})}},D=async(e,n)=>{try{let r=await $.moveBoard({name:e.name,slug:e.slug,from:e.ats,to:n});t(r.companies),w(t=>{let n={...t};return delete n[T(e)],n}),X({title:`${e.name} now reads from ${n}`,description:`The row is updated in Targets/Companies.md; the next scan reads it there.`,tone:`success`})}catch(e){X({title:`Not moved`,description:e.message,tone:`danger`})}};return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`toolbar`,children:[(0,x.jsx)(Zp,{className:`toolbar__search`,size:`sm`,label:`Search`,placeholder:`Company, platform or slug`,value:i,onChange:e=>a(e.target.value)}),(0,x.jsxs)(J,{className:`toolbar__filter`,size:`sm`,label:`Tier`,value:o,onValueChange:s,children:[(0,x.jsx)(J.Item,{value:`all`,children:`All tiers`}),(0,x.jsx)(J.Item,{value:`A`,children:`A, dream`}),(0,x.jsx)(J.Item,{value:`B`,children:`B, strong`}),(0,x.jsx)(J.Item,{value:`C`,children:`C, fine`})]}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),S>0&&(0,x.jsxs)(B,{size:`sm`,variant:`soft`,tone:`danger`,leadingIcon:(0,x.jsx)(H.Refresh,{}),loading:g,onClick:async()=>{_(!0);try{let e=await $.startScan(!1,void 0,!0);X({title:e.running?`Retrying ${S} failed board${S===1?``:`s`}`:`A scan is already running`,description:e.running?`Only the boards that failed last time, no feeds. Progress is on Runs; this page updates when it finishes.`:`Wait for it to finish, then retry.`,tone:e.running?`success`:`neutral`})}catch(e){X({title:`Could not start the retry`,description:e.message,tone:`danger`})}_(!1)},children:[`Retry `,S,` failed`]}),(0,x.jsxs)(W,{open:u,onOpenChange:d,size:`sm`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,leadingIcon:(0,x.jsx)(H.Plus,{}),children:`Add a board`})}),(0,x.jsx)(W.Content,{children:(0,x.jsxs)(`form`,{className:`form`,onSubmit:async e=>{e.preventDefault(),h(!0);try{let e=await $.addCompany(f);t(e),d(!1),p({name:``,ats:`greenhouse`,slug:``,tier:`B`,notes:``}),X({title:`${f.name} added`,description:`It is fetched on the next scan.`,tone:`success`})}catch(e){X({title:`Not added`,description:e.message,tone:`danger`})}h(!1)},children:[(0,x.jsx)(W.Title,{children:`Watch a company board`}),(0,x.jsx)(W.Description,{children:`The slug is the board token in the careers URL. Rows are appended to Targets/Companies.md.`}),(0,x.jsx)(Zp,{label:`Company`,required:!0,value:f.name,onChange:e=>p({...f,name:e.target.value})}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(J,{label:`Platform`,value:f.ats,onValueChange:e=>p({...f,ats:e}),children:f_.map(e=>(0,x.jsx)(J.Item,{value:e,children:e},e))}),(0,x.jsxs)(J,{label:`Tier`,value:f.tier,onValueChange:e=>p({...f,tier:e}),children:[(0,x.jsx)(J.Item,{value:`A`,children:`A`}),(0,x.jsx)(J.Item,{value:`B`,children:`B`}),(0,x.jsx)(J.Item,{value:`C`,children:`C`})]})]}),(0,x.jsx)(Zp,{label:`Slug`,required:!0,description:f.ats===`workday`?`host/tenant/site`:f.ats===`eightfold`?`host/domain`:`as it appears in the board URL`,value:f.slug,onChange:e=>p({...f,slug:e.target.value})}),(0,x.jsx)(Zp,{label:`Notes`,value:f.notes,onChange:e=>p({...f,notes:e.target.value})}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,children:`Cancel`})}),(0,x.jsx)(B,{type:`submit`,tone:`primary`,loading:m,children:`Add`})]})]})})]})]}),(0,x.jsxs)(`div`,{className:`health`,role:`group`,"aria-label":`Filter boards by health`,children:[(0,x.jsxs)(B,{size:`sm`,variant:c===`all`?`soft`:`ghost`,tone:`neutral`,onClick:()=>l(`all`),children:[`All `,(0,x.jsx)(`span`,{className:`num`,children:e?.length??0})]}),p_.map(e=>(0,x.jsxs)(B,{size:`sm`,variant:c===e.key?`soft`:`ghost`,tone:e.tone===`danger`?`danger`:`neutral`,onClick:()=>l(c===e.key?`all`:e.key),children:[e.label,` `,(0,x.jsx)(`span`,{className:`num`,children:v[e.key]||0})]},e.key))]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:8})}):(0,x.jsxs)(Y,{"aria-label":`Company boards`,density:`md`,stickyHeader:!0,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Platform`}),(0,x.jsx)(Y.HeadCell,{children:`Slug`}),(0,x.jsx)(Y.HeadCell,{children:`Tier`}),(0,x.jsx)(Y.HeadCell,{children:`Health`}),(0,x.jsx)(Y.HeadCell,{children:`Last success`}),(0,x.jsx)(Y.HeadCell,{children:`Last attempt`}),(0,x.jsx)(Y.HeadCell,{children:`Notes`})]})}),(0,x.jsxs)(Y.Body,{children:[y.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.name}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.ats})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`code`,{className:`mono`,children:e.slug})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{tone:e.tier===`A`?`primary`:`neutral`,size:`sm`,children:e.tier||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(Bh,{content:e.health.lastError||e.status||`No fetch on record yet.`,children:(0,x.jsxs)(z,{tone:m_[e.health.state],variant:e.health.state===`ok`?`soft`:`solid`,size:`sm`,children:[h_[e.health.state],e.health.failStreak>1?` ×${e.health.failStreak}`:``]})})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted num`,children:e.health.lastOk?`${Xg(e.health.lastOk)} · ${e.health.lastOkJobs} job${e.health.lastOkJobs===1?``:`s`}`:e.status&&!e.status.startsWith(`bad-slug`)?e.status:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted num`,children:e.health.lastAttempt?Xg(e.health.lastAttempt):`—`})}),(0,x.jsxs)(Y.Cell,{children:[(0,x.jsx)(`span`,{className:`muted`,children:e.notes}),e.health.state===`failed`&&(()=>{let t=C[T(e)];return t===`looking`?(0,x.jsx)(`span`,{className:`muted`,children:` · looking…`}):t&&t.found.length?(0,x.jsxs)(`span`,{className:`sources__move`,children:[` · `,(0,x.jsxs)(B,{size:`sm`,variant:`link`,tone:`primary`,onClick:()=>D(e,t.found[0].ats),children:[`Move to `,t.found[0].ats,` (`,t.found[0].jobs,` job`,t.found[0].jobs===1?``:`s`,`)`]})]}):t?(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,t.note]}):(0,x.jsxs)(`span`,{className:`sources__move`,children:[` · `,(0,x.jsx)(B,{size:`sm`,variant:`link`,tone:`neutral`,onClick:()=>E(e),children:`Find board`})]})})()]})]},`${e.ats}:${e.slug}`)),y.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:8,children:(0,x.jsx)(`span`,{className:`muted`,children:e.length===0?`No boards on the watchlist yet. Add one, or run the onboarding to start from the registry.`:`No boards match. Loosen a filter.`})})})]})]})}),(0,x.jsxs)(`p`,{className:`muted`,children:[y.length,` of `,e?.length??0,` boards. Failed means the latest attempt failed; zero means it answered with nothing, which for a board that once had jobs usually means the slug moved; stale means no success in three days. The Retry button fetches only the failed boards and writes matches like any scan.`]}),(0,x.jsx)(`h2`,{className:`settings__h`,children:`Aggregator feeds`}),(0,x.jsx)(V,{padding:`none`,children:n===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:4})}):(0,x.jsxs)(Y,{"aria-label":`Aggregator feeds`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Feed`}),(0,x.jsx)(Y.HeadCell,{children:`On`}),(0,x.jsx)(Y.HeadCell,{children:`Health`}),(0,x.jsx)(Y.HeadCell,{children:`Last success`}),(0,x.jsx)(Y.HeadCell,{children:`Last attempt`})]})}),(0,x.jsx)(Y.Body,{children:n.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[e.label,(0,x.jsxs)(`small`,{children:[(0,x.jsxs)(`code`,{className:`mono`,children:[`openSources.`,e.key]}),e.needsKey?` · needs a key`:``]})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{tone:e.enabled?`success`:`neutral`,variant:`soft`,size:`sm`,children:e.enabled?`on`:`off`})}),(0,x.jsx)(Y.Cell,{children:e.enabled?(0,x.jsx)(Bh,{content:e.health.lastError||`No fetch on record yet.`,children:(0,x.jsx)(z,{tone:m_[e.health.state],variant:e.health.state===`ok`?`soft`:`solid`,size:`sm`,children:h_[e.health.state]})}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted num`,children:e.health.lastOk?`${Xg(e.health.lastOk)} · ${e.health.lastOkJobs} postings`:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted num`,children:e.health.lastAttempt?Xg(e.health.lastAttempt):`—`})})]},e.key))})]})}),(0,x.jsxs)(`p`,{className:`muted`,children:[`Feeds are switched on and off in Criteria under `,(0,x.jsx)(`code`,{className:`mono`,children:`openSources`}),`. TekJobs postings and RemoteOK and HN are on unless you turn them off; the rest are opt-in.`]})]})}var __={"design-eng":`design engineering`,adjacent:`adjacent titles`};function v_({title:e,rows:t,barBefore:n,barAfter:r}){return(0,x.jsxs)(`div`,{className:`preview__block`,children:[(0,x.jsxs)(`h3`,{children:[e,` `,(0,x.jsxs)(`span`,{className:`muted`,children:[`above the bar, `,n===r?`bar ${r}`:`bar ${n} → ${r}`]})]}),(0,x.jsxs)(`ul`,{className:`preview__list`,children:[t.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsxs)(`span`,{className:`preview__score`,children:[e.aboveBefore,` → `,e.aboveAfter]}),` `,__[e.key]??e.key,` `,(0,x.jsxs)(`span`,{className:`muted`,children:[`· `,e.notes,` notes, `,e.changed,` change`]})]},e.key)),t.length===0&&(0,x.jsx)(`li`,{className:`muted`,children:`Nothing to group.`})]})]})}function y_({title:e,rows:t,empty:n}){return(0,x.jsxs)(`div`,{className:`preview__block`,children:[(0,x.jsxs)(`h3`,{children:[e,` `,(0,x.jsxs)(`span`,{className:`muted`,children:[`(`,t.length,`)`]})]}),t.length===0?(0,x.jsx)(`p`,{className:`muted`,children:n}):(0,x.jsxs)(`ul`,{className:`preview__list`,children:[t.slice(0,8).map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsxs)(`span`,{className:`preview__score`,children:[e.before,` → `,e.after]}),` `,e.company,` — `,e.title]},e.id)),t.length>8&&(0,x.jsxs)(`li`,{className:`muted`,children:[`and `,t.length-8,` more`]})]})]})}var b_=`__active__`,x_=[`remoteok`,`hn`,`email`,`adzuna`,`usajobs`,`themuse`,`remotive`,`himalayas`,`jobicy`,`workingnomads`,`arbeitnow`,`wwr`,`wellfound`,`builtin`],S_={remoteok:`RemoteOK`,hn:`HN Who is hiring`,email:`Alert emails (Inbox/)`,adzuna:`Adzuna (needs a key)`,usajobs:`USAJOBS (needs a key)`,themuse:`The Muse`,remotive:`Remotive`,himalayas:`Himalayas`,jobicy:`Jobicy`,workingnomads:`Working Nomads`,arbeitnow:`Arbeitnow`,wwr:`We Work Remotely`,wellfound:`Wellfound`,builtin:`Built In`},C_=(e,t)=>t.reduce((e,t)=>e&&typeof e==`object`?e[t]:void 0,e);function w_(e,t,n){let[r,...i]=t;if(!r)return e;let a={...e};return i.length?(a[r]=w_(e[r]&&typeof e[r]==`object`&&!Array.isArray(e[r])?e[r]:{},i,n),a):(n===void 0?delete a[r]:a[r]=n,a)}function T_({doc:e,path:t,label:n,hint:r,onChange:i,step:a=1}){let o=C_(e,t);return(0,x.jsx)(Zp,{size:`sm`,type:`number`,step:a,label:n,description:r,value:typeof o==`number`?String(o):``,onChange:n=>i(w_(e,t,n.target.value===``?void 0:Number(n.target.value)))})}function E_({label:e,hint:t,value:n,weighted:r,rows:i=8,onCommit:a}){let o=e=>r?Object.entries(e||{}).map(([e,t])=>`${e}: ${t}`).join(`
72
72
  `):(e||[]).join(`
73
73
  `),[s,c]=(0,b.useState)(()=>o(n)),[l,u]=(0,b.useState)(``);return(0,b.useEffect)(()=>{c(o(n)),u(``)},[n]),(0,x.jsx)(Xp,{label:e,description:t,font:`mono`,rows:i,resize:`vertical`,value:s,onChange:e=>c(e.target.value),onBlur:()=>{let e=s.split(`
74
- `).map(e=>e.trim()).filter(Boolean);if(!r){u(``),a(e);return}let t={};for(let n of e){let e=n.match(/^(.*?)\s*:\s*(-?\d+(?:\.\d+)?)\s*$/);if(!e||!e[1]){u(`"${n}" is not "term: weight".`);return}t[e[1].trim().toLowerCase()]=Number(e[2])}u(``),a(t)},error:l||void 0})}function D_(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(``),[i,a]=(0,b.useState)(b_),[o,s]=(0,b.useState)([]),[c,l]=(0,b.useState)(!1),[u,d]=(0,b.useState)(``),[f,p]=(0,b.useState)(``),[m,h]=(0,b.useState)(null),[g,_]=(0,b.useState)(!1),[v,y]=(0,b.useState)(null),[S,C]=(0,b.useState)(!1),[w,T]=(0,b.useState)(null),E=(0,b.useRef)(null),[D,O]=(0,b.useState)(null),[k,A]=(0,b.useState)(!1),j=(0,b.useMemo)(()=>e?JSON.stringify(e,null,2):``,[e]),ee=e!==null&&j!==n,M=i!==b_;(0,b.useEffect)(()=>{if(E.current&&window.clearTimeout(E.current),!ee||M){T(null);return}return E.current=window.setTimeout(()=>{$.previewCriteria(j).then(T).catch(()=>T(null))},700),()=>{E.current&&window.clearTimeout(E.current)}},[j,ee,M]),(0,b.useEffect)(()=>{if(!ee)return;let e=e=>{e.preventDefault()};return window.addEventListener(`beforeunload`,e),()=>window.removeEventListener(`beforeunload`,e)},[ee]);let N=()=>$.criteriaPresets().then(s).catch(()=>s([])),te=async e=>{try{let n=e===b_?await $.criteria():await $.criteriaPreset(e);if(!n.parsed)throw Error(`That note's JSON does not parse. Fix it in Obsidian first.`);t(n.parsed),r(JSON.stringify(n.parsed,null,2)),d(JSON.stringify(n.parsed,null,2)),p(``),a(e)}catch(e){X({title:`Could not load criteria`,description:e.message,tone:`danger`})}};(0,b.useEffect)(()=>{te(b_),N()},[]),(0,b.useEffect)(()=>{d(j),p(``)},[j]);let P=e=>t(e),F=async()=>{if(e){l(!0);try{if(M){let e=await $.saveCriteriaPreset(i,j);r(JSON.stringify(e.parsed,null,2)),X({title:`Preset "${i}" saved`,description:`Run a scan with it from here or from Runs; make it active to have the daily scan use it.`,tone:`success`})}else{let e=!!w?.weightsChange,t=w?w.notesAtCurrent:0,n=await $.saveCriteria(j);r(JSON.stringify(n.parsed,null,2)),X({title:`Criteria saved`,description:`Targets/Search Criteria.md updated. The next scan uses it.`,tone:`success`}),O(e&&t>0?{notes:t}:null)}N()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}l(!1)}},ne=async()=>{if(e&&m?.trim()){l(!0);try{let e=await $.saveCriteriaPreset(m.trim(),j);h(null),await N(),a(e.name),r(JSON.stringify(e.parsed,null,2)),X({title:`Preset "${e.name}" created`,description:e.file,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}l(!1)}},re=async()=>{l(!0);try{await $.activateCriteriaPreset(i),await N(),X({title:`"${i}" is now the active criteria`,description:`Search Criteria.md holds a copy. The daily scan uses it from the next run.`,tone:`success`})}catch(e){X({title:`Could not activate`,description:e.message,tone:`danger`})}l(!1)},ie=async()=>{l(!0);try{await $.deleteCriteriaPreset(i),_(!1),await N(),await te(b_),X({title:`Preset deleted`,tone:`success`})}catch(e){X({title:`Could not delete`,description:e.message,tone:`danger`})}l(!1)},ae=async e=>{try{await $.startScan(e,M?i:void 0),X({title:e?`Dry run started`:`Scan started`,description:`Scoring with ${M?`"${i}"`:`the active criteria`}. Watch it on Runs.`,tone:`success`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},oe=async()=>{A(!0);try{let e=await $.rescoreNotes(!1);O(null),X({title:`${e.changed} note${e.changed===1?``:`s`} rescored`,description:`${e.alreadyCurrent} were already at these weights. Each moved note carries the new score, band and reasons, and a status-log line saying so.`,tone:`success`})}catch(e){X({title:`Rescore failed`,description:e.message,tone:`danger`})}A(!1)},se=async()=>{if(w){y(w);return}C(!0);try{y(await $.previewCriteria(j))}catch(e){X({title:`Could not preview`,description:e.message,tone:`danger`})}C(!1)},ce=()=>{try{let e=JSON.parse(u);t(e),p(``)}catch(e){p(e.message)}};if(!e)return(0,x.jsx)(zg,{variant:`rect`,height:`24rem`});let le=e.salary??{},ue={...Object.fromEntries(x_.map(e=>[e,!1])),...e.openSources??{}},de=o.find(e=>e.name===i);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`What the scan looks for and how it scores. Fields write into the JSON in `,M?(0,x.jsxs)(`code`,{children:[`Targets/Criteria/`,i,`.md`]}):(0,x.jsx)(`code`,{children:`Targets/Search Criteria.md`}),`; keys this form does not show are kept as they are.`]})}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[`bar `,String(e.minScore??`?`)]}),le.minAnnual&&(0,x.jsxs)(z,{tone:`success`,size:`sm`,children:[`floor `,Jg(le.minAnnual)]}),le.stretchAnnual&&(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[`stretch `,Jg(le.stretchAnnual)]}),ee&&(0,x.jsx)(z,{tone:`warning`,size:`sm`,children:`unsaved`})]})]}),(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsxs)(`div`,{className:`toolbar`,children:[(0,x.jsxs)(J,{className:`toolbar__filter toolbar__filter--wide`,size:`sm`,label:`Editing`,value:i,onValueChange:e=>{(!ee||window.confirm(`Discard unsaved changes?`))&&te(e)},children:[(0,x.jsx)(J.Item,{value:b_,children:`Active criteria (daily scan)`}),o.map(e=>(0,x.jsxs)(J.Item,{value:e.name,children:[e.name,e.active?` · same as active`:``]},e.name))]}),(0,x.jsx)(`div`,{className:`toolbar__spacer`}),(0,x.jsxs)(`div`,{className:`toolbar__switch pager__buttons`,children:[M&&(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`danger`,disabled:c,onClick:()=>_(!0),children:`Delete preset`}),M&&(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee||de?.active,onClick:re,children:de?.active?`Is the active set`:`Make active`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||S,loading:S,onClick:se,children:`Preview impact`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c,onClick:()=>h(M?`${i} copy`:``),children:`Save as preset…`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee,onClick:()=>ae(!0),children:`Dry run with this`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee,onClick:()=>ae(!1),children:`Scan with this`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:!ee||c,loading:c,onClick:F,children:M?`Save preset`:`Save to the vault`})]})]}),M&&de&&(0,x.jsxs)(`p`,{className:`muted`,children:[`Preset · `,de.titles,` title terms · updated `,de.updated,` · `,de.file]}),w&&(0,x.jsxs)(`div`,{className:`impact`,role:`status`,"aria-live":`polite`,children:[(0,x.jsx)(`span`,{className:`microlabel`,children:`If saved`}),(0,x.jsxs)(z,{size:`sm`,tone:w.aboveAfter>=w.aboveBefore?`success`:`warning`,children:[`above the bar `,w.aboveBefore,` → `,w.aboveAfter]}),(0,x.jsxs)(z,{size:`sm`,tone:w.changed?`primary`:`neutral`,children:[w.changed,` of `,w.openNotes,` change score`]}),(0,x.jsxs)(z,{size:`sm`,tone:w.rise.length?`success`:`neutral`,children:[w.rise.length,` rise`]}),(0,x.jsxs)(z,{size:`sm`,tone:w.fall.length?`warning`:`neutral`,children:[w.fall.length,` fall`]}),(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[`top 20: `,w.enterTop20.length,` in, `,w.leaveTop20.length,` out`]}),w.weightsChange&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsxs)(`span`,{className:`num`,children:[w.fingerprintBefore,` → `,w.fingerprintAfter]})}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,onClick:()=>y(w),children:`Details`})]}),D&&!ee&&(0,x.jsxs)(`div`,{className:`impact impact--after`,children:[(0,x.jsx)(`span`,{className:`microlabel`,children:`Saved`}),(0,x.jsxs)(`span`,{children:[D.notes,` open note`,D.notes===1?` was`:`s were`,` scored under the previous weights. The next scan scores new postings with the new ones; the existing notes keep their scores until you rescore them.`]}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsxs)(B,{size:`sm`,variant:`soft`,tone:`primary`,loading:k,disabled:k,onClick:oe,children:[`Rescore `,D.notes,` notes`]}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,disabled:k,onClick:()=>O(null),children:`Later`})]})]}),(0,x.jsxs)(Z,{defaultValue:`fields`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Criteria editors`,children:[(0,x.jsx)(Z.Trigger,{value:`fields`,children:`Fields`}),(0,x.jsx)(Z.Trigger,{value:`titles`,children:`Titles and terms`}),(0,x.jsx)(Z.Trigger,{value:`location`,children:`Location and pay`}),(0,x.jsx)(Z.Trigger,{value:`sources`,children:`Sources`}),(0,x.jsx)(Z.Trigger,{value:`json`,children:`JSON (advanced)`})]}),(0,x.jsx)(Z.Content,{value:`fields`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`minScore`],label:`Bar (minScore)`,hint:`A posting needs this many points to become a note.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`noTitleMatchPenalty`],label:`No title match penalty`,hint:`Taken when the title matches nothing in the title terms.`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`descCap`],label:`Description points cap`,hint:`Description terms add up to this many points, no more.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`maxDescriptionChars`],label:`Description characters kept in a note`,onChange:P,step:500})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`titleExtraPer`],label:`Points per extra title match`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`titleExtraCap`],label:`Extra title matches cap`,onChange:P})]}),(0,x.jsx)(`h3`,{children:`Seniority`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Boost (word: points)`,hint:`Words in the title that add. Example: staff: 10`,value:C_(e,[`seniority`,`boost`]),weighted:!0,rows:6,onCommit:t=>P(w_(e,[`seniority`,`boost`],t))}),(0,x.jsx)(E_,{label:`Penalty (word: points)`,hint:`Words in the title that subtract. Example: junior: -40`,value:C_(e,[`seniority`,`penalty`]),weighted:!0,rows:6,onCommit:t=>P(w_(e,[`seniority`,`penalty`],t))})]}),(0,x.jsx)(`h3`,{children:`Recency`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`recency`,`days2`],label:`Posted within 2 days`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`recency`,`days7`],label:`Within 7 days`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`recency`,`days30`],label:`Within 30 days`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`recency`,`days90`],label:`Within 90 days`,onChange:P})]}),(0,x.jsx)(`div`,{className:`form__row`,children:(0,x.jsx)(T_,{doc:e,path:[`recency`,`older`],label:`Older than 90 days`,onChange:P})})]})})}),(0,x.jsx)(Z.Content,{value:`titles`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Title terms (term: weight)`,hint:`The best single match in the title counts fully; each extra match adds the per-extra points. One per line.`,value:e.titleTerms,weighted:!0,rows:18,onCommit:t=>P(w_(e,[`titleTerms`],t))}),(0,x.jsx)(E_,{label:`Title exclusions (one per line)`,hint:`Any hit in the title drops the posting entirely.`,value:e.titleExclude,weighted:!1,rows:18,onCommit:t=>P(w_(e,[`titleExclude`],t))})]}),(0,x.jsx)(E_,{label:`Description terms (term: weight)`,hint:`Each term found in the description adds its weight, up to the description cap.`,value:e.descTerms,weighted:!0,rows:14,onCommit:t=>P(w_(e,[`descTerms`],t))})]})})}),(0,x.jsx)(Z.Content,{value:`location`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(`h3`,{children:`Location`}),(0,x.jsx)(Hp,{label:`Remote only`,description:`Anything not remote takes the penalty below, which drops it under the bar.`,checked:!!C_(e,[`location`,`requireRemote`]),onCheckedChange:t=>P(w_(e,[`location`,`requireRemote`],t===!0))}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`location`,`notRemotePenalty`],label:`Not remote penalty`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`location`,`remoteBoost`],label:`Remote boost`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`location`,`nonUsPenalty`],label:`Non-US penalty`,hint:`Applied when the location names a place in the list below and nothing US.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`location`,`bayAreaBoost`],label:`Metro boost`,hint:`For the metro terms below. Set to 0 to switch it off.`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Metro terms (one per line)`,hint:`Places that earn the metro boost. The interview seeds these from your location; empty the list for no boost.`,value:C_(e,[`location`,`bayAreaTerms`]),weighted:!1,rows:8,onCommit:t=>P(w_(e,[`location`,`bayAreaTerms`],t))}),(0,x.jsx)(E_,{label:`US terms (one per line)`,hint:`Words that mark a posting as US.`,value:C_(e,[`location`,`usTerms`]),weighted:!1,rows:8,onCommit:t=>P(w_(e,[`location`,`usTerms`],t))})]}),(0,x.jsx)(E_,{label:`Non-US terms (one per line)`,hint:`Places that trigger the non-US penalty. Whole words.`,value:C_(e,[`location`,`nonUsTerms`]),weighted:!1,rows:10,onCommit:t=>P(w_(e,[`location`,`nonUsTerms`],t))}),(0,x.jsx)(`h3`,{children:`Pay`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`minAnnual`],label:`Floor (annual)`,hint:`A stated range that tops out at or above this earns the bonus.`,onChange:P,step:5e3}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`stretchAnnual`],label:`Stretch (annual)`,hint:`Between stretch and floor is the stretch band: kept visible, small penalty.`,onChange:P,step:5e3})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`meetsBonus`],label:`Meets floor bonus`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`stretchPenalty`],label:`Stretch band penalty`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`belowPenalty`],label:`Below stretch penalty`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`abovePer10k`],label:`Points per $10k above floor`,hint:`Capped at ${String(C_(e,[`salary`,`aboveCap`])??`?`)} (aboveCap).`,onChange:P})]})]})})}),(0,x.jsx)(Z.Content,{value:`sources`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(`p`,{className:`muted`,children:`Aggregator feeds with no company slug. Company boards live on the Companies page. Adzuna and USAJOBS also need a free key in the environment.`}),(0,x.jsx)(`div`,{className:`form__row`,children:Object.keys(ue).map(t=>(0,x.jsx)(Hp,{label:S_[t]??t,checked:!!ue[t],onCheckedChange:n=>P(w_(e,[`openSources`,t],n===!0))},t))})]})})}),(0,x.jsx)(Z.Content,{value:`json`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(Xp,{label:`Criteria JSON`,description:`The whole document. Apply to push it into the fields; Save to write it to the vault.`,font:`mono`,rows:28,resize:`vertical`,value:u,onChange:e=>d(e.target.value),error:f||void 0}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:u===j,onClick:()=>{d(j),p(``)},children:`Revert`}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:u===j,onClick:ce,children:`Apply to fields`})]})]})})})]}),(0,x.jsx)(W,{open:v!==null,onOpenChange:e=>!e&&y(null),size:`lg`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`What this set would do to the notes you have`}),(0,x.jsxs)(W.Description,{children:[`Against the active criteria. Covers `,v?.covers,`. Nothing is written by a preview.`,v?.weightsChange?` The weights change (${v.fingerprintBefore} → ${v.fingerprintAfter}); ${v.notesAtCurrent} open notes were scored under the current ones and can be rescored after saving.`:` The weights do not change; only the bar or the sources do.`]}),v&&(0,x.jsxs)(`div`,{className:`preview`,children:[(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[v.openNotes,` open notes`]}),(0,x.jsxs)(z,{size:`sm`,tone:v.changed?`primary`:`neutral`,children:[v.changed,` change score`]}),(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[`bar `,v.barBefore,` → `,v.barAfter]}),(0,x.jsxs)(z,{size:`sm`,tone:v.aboveAfter>=v.aboveBefore?`success`:`warning`,children:[`above the bar `,v.aboveBefore,` → `,v.aboveAfter]})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Rise above the bar`,rows:v.rise,empty:`Nothing crosses upward.`}),(0,x.jsx)(y_,{title:`Fall below the bar`,rows:v.fall,empty:`Nothing drops out.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Enter the top 20`,rows:v.enterTop20,empty:`The top 20 keeps its members.`}),(0,x.jsx)(y_,{title:`Leave the top 20`,rows:v.leaveTop20,empty:`The top 20 keeps its members.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Biggest gains`,rows:v.up,empty:`No note gains points.`}),(0,x.jsx)(y_,{title:`Biggest losses`,rows:v.down,empty:`No note loses points.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(v_,{title:`By role family`,rows:v.byKind,barBefore:v.barBefore,barAfter:v.barAfter}),(0,x.jsx)(v_,{title:`By source`,rows:v.bySource,barBefore:v.barBefore,barAfter:v.barAfter})]})]}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Close`})}),ee&&(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:c,onClick:()=>{y(null),F()},children:M?`Save preset`:`Save to the vault`})]})]})}),(0,x.jsx)(W,{open:m!==null,onOpenChange:e=>!e&&h(null),size:`sm`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`Save as a preset`}),(0,x.jsx)(W.Description,{children:`A named copy under Targets/Criteria/. The daily scan keeps using the active set until you make this one active.`}),(0,x.jsx)(Zp,{label:`Name`,placeholder:`Wider net, 180k floor`,value:m??``,onChange:e=>h(e.target.value)}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Cancel`})}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:!m?.trim()||c,loading:c,onClick:ne,children:`Save preset`})]})]})}),(0,x.jsx)(W,{open:g,onOpenChange:_,size:`sm`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsxs)(W.Title,{children:[`Delete "`,i,`"?`]}),(0,x.jsx)(W.Description,{children:`Removes the note under Targets/Criteria/. The active criteria and every job note stay as they are.`}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Keep it`})}),(0,x.jsx)(B,{size:`sm`,tone:`danger`,disabled:c,loading:c,onClick:ie,children:`Delete`})]})]})})]})}function O_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)({emphasis:`auto`,length:`standard`,extra:``}),[s,c]=(0,b.useState)(!1),l=(0,b.useRef)(!1),u=(e,t)=>{n(e),t&&i(e.saved?.text??``)};(0,b.useEffect)(()=>{n(null),$.coverLetter(e.id).then(e=>u(e,!0)).catch(e=>X({title:`Could not read the letter`,description:e.message,tone:`danger`}))},[e.id]),(0,b.useEffect)(()=>{if(!t?.running){l.current&&t&&(l.current=!1,u(t,!t.error),t.error||X({title:`Cover letter drafted`,description:`Saved into the note. Read it before you use it.`,tone:`success`}));return}l.current=!0;let r=setInterval(()=>$.coverLetter(e.id).then(e=>n(e)).catch(()=>{}),2500);return()=>clearInterval(r)},[t?.running,e.id]);let d=async()=>{if(!t?.saved||window.confirm(`Write a new letter? It replaces the one saved in this note.`))try{u(await $.writeCoverLetter(e.id,a),!1)}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=async()=>{c(!0);try{u(await $.saveCoverLetter(e.id,r),!0),X({title:`Letter saved`,description:`Written into the note and checked against your resume.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}c(!1)},p=async()=>{try{await navigator.clipboard.writeText(r),X({title:`Copied`,tone:`success`})}catch{X({title:`Could not copy`,description:`Select the text and copy it by hand.`,tone:`danger`})}};if(!t)return(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})});let m=t.saved,h=!!m&&r!==m.text;return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`letter__options`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Emphasis`,value:a.emphasis,onValueChange:e=>o({...a,emphasis:e}),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`auto`,children:`Let the posting decide`}),(0,x.jsx)(J.Item,{value:`design-systems`,children:`Design systems first`}),(0,x.jsx)(J.Item,{value:`ai-product`,children:`AI product surfaces first`})]}),(0,x.jsxs)(J,{size:`sm`,label:`Length`,value:a.length,onValueChange:e=>o({...a,length:e}),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`short`,children:`Short, about 150 words`}),(0,x.jsx)(J.Item,{value:`standard`,children:`Standard, about 220 words`})]})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Anything it should include`,description:`Optional. A person you spoke to, a product of theirs you use, a point to make.`,value:a.extra,onChange:e=>o({...a,extra:e.target.value}),disabled:t.running}),(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:d,disabled:t.running,leadingIcon:t.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Sparkles,{}),children:t.running?`Writing`:m?`Write a new one`:`Write cover letter`}),m&&(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:p,leadingIcon:(0,x.jsx)(H.Copy,{}),children:`Copy`}),h&&(0,x.jsx)(B,{variant:`soft`,tone:`primary`,size:`sm`,onClick:f,loading:s,children:`Save edits`})]}),t.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`${t.runner} is writing from your resume and this posting`,size:`sm`}),t.error&&!t.running&&(0,x.jsx)(Vg,{tone:`danger`,size:`sm`,icon:(0,x.jsx)(H.Warning,{}),title:t.errorKind===`auth`?`${t.runner} is signed out`:t.errorKind===`missing`?`${t.runner} is not installed`:t.errorKind===`outdated`?`${t.runner} is out of date`:`The letter was not written`,description:`${t.error} You can also ask any agent connected to the TekJobs MCP server to write it: "write the cover letter for ${e.company}".`}),!m&&!t.running&&!t.error&&(0,x.jsx)(Vg,{size:`sm`,icon:(0,x.jsx)(H.File,{}),title:`No letter yet`,description:`It is written from your resume and ${e.company}'s posting, and only your resume supplies the facts.`}),m&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Xp,{label:`Cover letter`,rows:16,resize:`vertical`,value:r,onChange:e=>i(e.target.value),description:`Edit freely. Saving checks it against your resume again.`}),(0,x.jsxs)(`div`,{className:`letter__meta`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[m.words,` words`]}),m.warnings.length===0?(0,x.jsx)(z,{tone:`success`,size:`sm`,children:`Nothing flagged`}):(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[m.warnings.length,` to check`]}),h&&(0,x.jsx)(z,{tone:`primary`,variant:`outline`,size:`sm`,children:`Unsaved edits`})]}),m.warnings.length>0&&(0,x.jsx)(`ul`,{className:`letter__warnings`,children:m.warnings.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{tone:e.kind===`claim`||e.kind===`placeholder`?`danger`:`warning`,size:`sm`,children:e.kind}),(0,x.jsx)(`span`,{children:e.text})]},e.text))})]}),(0,x.jsx)(`p`,{className:`muted`,children:`The letter is saved under "Cover letter" in the job note. Nothing is sent from here; you paste it where the application asks for it.`})]})}var k_={recruiter:`recruiter`,"hiring-manager":`hiring manager`,interviewer:`interviewer`,referral:`referral`,other:`contact`},A_={recruiter:`primary`,"hiring-manager":`warning`,interviewer:`neutral`,referral:`success`,other:`neutral`},j_=e=>qg.includes(e)?e:`other`;function M_(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(``),[i,a]=(0,b.useState)(`all`),[o,s]=(0,b.useState)(null),c=()=>$.people().then(t).catch(e=>X({title:`Could not load people`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{c()},[]);let l=(0,b.useMemo)(()=>{let t=n.trim().toLowerCase();return(e??[]).filter(e=>(i===`all`||e.role===i)&&(!t||`${e.name} ${e.company} ${e.email}`.toLowerCase().includes(t)))},[e,n,i]);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`toolbar`,children:[(0,x.jsx)(Zp,{className:`toolbar__search`,size:`sm`,label:`Search`,placeholder:`Name, company or email`,value:n,onChange:e=>r(e.target.value)}),(0,x.jsxs)(J,{className:`toolbar__filter`,size:`sm`,label:`Role`,value:i,onValueChange:a,children:[(0,x.jsx)(J.Item,{value:`all`,children:`Everyone`}),qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))]}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(N_,{onAdded:e=>{c(),s(e.id)}})]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:6})}):e.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`No people yet`,description:`Confirming an email that a person wrote adds them here, with the thread. Or add someone: a recruiter who reached out, a referral, the hiring manager you met.`}):(0,x.jsxs)(Y,{"aria-label":`People`,density:`md`,stickyHeader:!0,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Name`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Email`}),(0,x.jsx)(Y.HeadCell,{children:`Last contact`}),(0,x.jsx)(Y.HeadCell,{children:`Threads`})]})}),(0,x.jsx)(Y.Body,{children:l.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,selected:o===e.id,onClick:()=>s(e.id),children:[(0,x.jsx)(Y.Cell,{children:e.name}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]})}),(0,x.jsx)(Y.Cell,{children:e.company||(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.email||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num`,children:e.lastContact?`${e.lastContact} · ${Xg(e.lastContact)}`:`—`})}),(0,x.jsxs)(Y.Cell,{children:[(0,x.jsx)(`span`,{className:`num`,children:e.threads.length}),e.live>0&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,e.live,` live`]})]})]},e.id))})]})}),(0,x.jsxs)(`p`,{className:`muted`,children:[l.length,` of `,e?.length??0,` people. Notes live in `,(0,x.jsx)(`code`,{className:`mono`,children:`People/`}),`; a job note lists its people under `,(0,x.jsx)(`code`,{className:`mono`,children:`## People`}),`.`]}),(0,x.jsx)(L_,{onDone:c}),(0,x.jsx)(P_,{id:o,onClose:()=>s(null),onChanged:c})]})}function N_({onAdded:e,job:t}){let[n,r]=(0,b.useState)(!1),i={name:``,role:`recruiter`,company:t?.company??``,email:``,links:``,about:``},[a,o]=(0,b.useState)(i),[s,c]=(0,b.useState)(!1);return(0,x.jsxs)(W,{open:n,onOpenChange:r,size:`sm`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,leadingIcon:(0,x.jsx)(H.Plus,{}),children:`Add a person`})}),(0,x.jsx)(W.Content,{children:(0,x.jsxs)(`form`,{className:`form`,onSubmit:async n=>{n.preventDefault(),c(!0);try{let n=await $.addPerson({...a,jobId:t?.id});r(!1),o(i),X({title:`${n.name} ${n.created===new Date().toISOString().slice(0,10)?`added`:`recognised`}`,description:t?`On ${t.company} - ${t.title}.`:`People/${n.id}.md`,tone:`success`}),e(n)}catch(e){X({title:`Not added`,description:e.message,tone:`danger`})}c(!1)},children:[(0,x.jsx)(W.Title,{children:t?`Someone on ${t.company}`:`Add a person`}),(0,x.jsx)(W.Description,{children:`A note under People/. Someone already there, by email or by name at the same company, is recognised rather than duplicated.`}),(0,x.jsx)(Zp,{label:`Name`,required:!0,value:a.name,onChange:e=>o({...a,name:e.target.value})}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(J,{label:`Role`,value:a.role,onValueChange:e=>o({...a,role:e}),children:qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))}),(0,x.jsx)(Zp,{label:`Company`,value:a.company,onChange:e=>o({...a,company:e.target.value})})]}),(0,x.jsx)(Zp,{label:`Email`,type:`email`,value:a.email,onChange:e=>o({...a,email:e.target.value})}),(0,x.jsx)(Zp,{label:`Links`,description:`LinkedIn or anything else, as text.`,value:a.links,onChange:e=>o({...a,links:e.target.value})}),(0,x.jsx)(Zp,{label:`About`,description:`How you know them, in a line.`,value:a.about,onChange:e=>o({...a,about:e.target.value})}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,children:`Cancel`})}),(0,x.jsx)(B,{type:`submit`,tone:`primary`,loading:s,children:`Add`})]})]})})]})}function P_({id:e,onClose:t,onChanged:n}){let[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(!1);return(0,b.useEffect)(()=>{i(null),e&&$.person(e).then(i).catch(e=>X({title:`Could not open the note`,description:e.message,tone:`danger`}))},[e]),(0,x.jsx)(Sp,{open:e!==null,onOpenChange:e=>!e&&t(),side:`right`,size:`md`,children:(0,x.jsx)(Sp.Content,{children:r?(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`sheet-head`,children:[(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[r.company||`no company`,r.created?` · since ${r.created}`:``]}),(0,x.jsx)(Sp.Title,{children:r.name}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsx)(z,{size:`sm`,tone:A_[j_(r.role)],variant:`soft`,children:k_[j_(r.role)]}),r.email&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:r.email})}),r.lastContact&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[`last contact `,(0,x.jsx)(`span`,{className:`num`,children:r.lastContact})]})]})]}),(0,x.jsx)(`div`,{className:`sheet-head__side`,children:(0,x.jsxs)(`div`,{className:`sheet-head__links`,children:[r.email&&(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:`mailto:${r.email}`,children:`Write to them ↗`})}),(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:r.obsidianUrl,title:r.path,children:`Open in Obsidian ↗`})})]})})]}),(r.about||r.links)&&(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`About`}),(0,x.jsxs)(`p`,{className:`muted`,children:[r.about,r.links?` ${r.links}`:``]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Threads`}),r.threads.length===0?(0,x.jsx)(`p`,{className:`muted`,children:`On no job note yet.`}):(0,x.jsx)(`ul`,{className:`people__threads`,children:r.threads.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`a`,{className:`people__thread`,href:`#/jobs?q=${encodeURIComponent(e.title.split(` - `)[0]??e.title)}`,children:e.title}),e.status&&(0,x.jsx)(z,{size:`sm`,tone:$g[e.status]??`neutral`,children:e.status}),e.role&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,e.role]})]},e.id))})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Log`}),(0,x.jsx)(dg,{text:r.log||`_Nothing logged yet._`})]}),(0,x.jsx)(Xp,{label:`Log a contact`,rows:3,value:a,onChange:e=>o(e.target.value),placeholder:`A call, a reply, a note to self. Dated today, moves last contact forward. Nothing is sent.`}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:async()=>{if(r&&a.trim()){c(!0);try{i(await $.logContact(r.id,a.trim())),o(``),n(),X({title:`Logged`,description:`On People/${r.id}.md; last contact is today.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}c(!1)}},disabled:s||!a.trim(),children:`Log it`})})]}):(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:5})})})})}function F_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)([]),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(`recruiter`),[l,u]=(0,b.useState)(``),[d,f]=(0,b.useState)(!1),p=()=>$.jobPeople(e.id).then(n).catch(()=>n([]));(0,b.useEffect)(()=>{p(),$.people().then(i).catch(()=>{})},[e.id]);let m=new Set((t??[]).map(e=>e.id)),h=r.filter(e=>!m.has(e.id));return(0,x.jsxs)(`div`,{className:`detail`,children:[t===null?(0,x.jsx)(zg,{lines:3}):t.length===0?(0,x.jsx)(`p`,{className:`muted`,children:`No one on this thread yet. Confirming an email a person wrote adds them; or add someone below.`}):(0,x.jsx)(`ul`,{className:`people__list`,children:t.map((e,t)=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),e.role&&(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),e.context&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.context})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[e.email&&(0,x.jsx)(`a`,{className:`num muted`,href:`mailto:${e.email}`,children:e.email}),e.id&&(0,x.jsx)(`a`,{className:`muted`,href:`#/people`,title:`People/${e.id}.md`,children:`People ↗`})]})]},`${e.id||e.name}-${t}`))}),(0,x.jsx)(I_,{job:e}),(0,x.jsxs)(`div`,{className:`people__add`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Someone already in People`,value:a||`__none__`,onValueChange:e=>o(e===`__none__`?``:e),children:[(0,x.jsx)(J.Item,{value:`__none__`,children:`Pick a person`}),h.map(e=>(0,x.jsxs)(J.Item,{value:e.id,children:[e.name,e.company?` · ${e.company}`:``]},e.id))]}),(0,x.jsx)(J,{size:`sm`,label:`On this thread as`,value:s,onValueChange:e=>c(e),children:qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Context`,placeholder:`A few words: reached out on LinkedIn, ran the screen, knows the team.`,value:l,onChange:e=>u(e.target.value)}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{size:`sm`,tone:`primary`,variant:`soft`,disabled:!a||d,onClick:async()=>{if(a){f(!0);try{await $.attachPerson(a,e.id,s,l.trim()),o(``),u(``),p(),X({title:`Added to the note`,description:`Under ## People on ${e.company} - ${e.title}.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}f(!1)}},children:`Add to this thread`}),(0,x.jsx)(N_,{job:e,onAdded:()=>{p(),$.people().then(i).catch(()=>{})}})]})]})]})}function I_({job:e}){let[t,n]=(0,b.useState)(null);if((0,b.useEffect)(()=>{$.jobConnections(e.id).then(n).catch(()=>n(null))},[e.id]),!t||!t.imported)return null;let r=t.people.slice(0,8);return(0,x.jsxs)(`div`,{className:`connections`,children:[(0,x.jsx)(`h4`,{className:`connections__title`,children:t.count===0?`No connections at ${e.company}`:`${t.count} connection${t.count===1?``:`s`} at ${e.company}`}),r.length>0&&(0,x.jsx)(`ul`,{className:`people__list`,children:r.map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),e.role!==`other`&&(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),e.title&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.title})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[e.connectedOn&&(0,x.jsxs)(`span`,{className:`num muted`,children:[`since `,e.connectedOn.slice(0,4)]}),e.url&&(0,x.jsx)(`a`,{className:`muted`,href:e.url,target:`_blank`,rel:`noreferrer`,children:`LinkedIn ↗`})]})]},e.url||e.name))}),t.count>r.length&&(0,x.jsxs)(`p`,{className:`muted`,children:[`and `,t.count-r.length,` more.`]}),(0,x.jsxs)(`p`,{className:`muted`,children:[`From your LinkedIn export, imported `,t.imported.slice(0,10),`. A warm introduction beats a cold apply.`]})]})}function L_({onDone:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(`roles`),[l,u]=(0,b.useState)(null),[d,f]=(0,b.useState)(``),p=()=>$.linkedinStatus().then(n).catch(()=>n({imported:null}));(0,b.useEffect)(()=>{p()},[]);let m=s===`everyone`,h=async()=>{f(`preview`);try{u(await $.linkedinPreview(r.trim(),a||void 0,m))}catch(e){X({title:`Could not read the export`,description:e.message,tone:`danger`})}f(``)},g=async()=>{f(`import`);try{let t=await $.linkedinImport(r.trim(),{since:a||void 0,everyone:m});X({title:`LinkedIn export imported`,description:`${t.people.created} people created, ${t.people.recognised} already there, ${t.people.attached} put on job notes; ${t.counts.connections} connections indexed.`,tone:`success`}),u(null),e(),p()}catch(e){X({title:`Import failed`,description:e.message,tone:`danger`})}f(``)},_=t?.source?t.source.split(/[\\/]/).pop():``;return(0,x.jsx)(V,{children:(0,x.jsxs)(`div`,{className:`linkedin`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h3`,{className:`connections__title`,children:`Bring your LinkedIn history`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`Request the larger archive at `,(0,x.jsx)(`a`,{href:`https://www.linkedin.com/mypreferences/d/download-my-data`,target:`_blank`,rel:`noreferrer`,children:`linkedin.com/mypreferences/d/download-my-data`}),`, download the zip when LinkedIn emails it (a partial in about ten minutes, the complete one within a day), and paste its path here. It is read in place and never copied. It writes, into this profile folder only: who you know at each company (shown on every job) and People notes for the recruiters and hiring managers who wrote.`]}),t?.imported&&t.counts&&(0,x.jsxs)(`p`,{className:`muted`,children:[`Last imported `,t.imported.slice(0,10),_?` from ${_}`:``,`: `,t.counts.connections,` connections, `,t.counts.threads,` conversations and `,t.counts.invitations,` invitations since `,t.since,`.`]})]}),(0,x.jsxs)(`div`,{className:`linkedin__form`,children:[(0,x.jsx)(Zp,{className:`linkedin__path`,size:`sm`,label:`Path to the export`,placeholder:`C:\\Users\\you\\Downloads\\Complete_LinkedInDataExport_2026-09-24.zip`,value:r,onChange:e=>i(e.target.value)}),(0,x.jsx)(Zp,{size:`sm`,type:`date`,label:`Since`,value:a,onChange:e=>o(e.target.value),description:`Default: 90 days ago`}),(0,x.jsxs)(J,{size:`sm`,label:`Write as People`,value:s,onValueChange:e=>c(e),children:[(0,x.jsx)(J.Item,{value:`roles`,children:`Recruiters and hiring managers`}),(0,x.jsx)(J.Item,{value:`everyone`,children:`Everyone who wrote`})]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,onClick:h,loading:d===`preview`,disabled:!r.trim()||d!==``,children:`Preview`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,onClick:g,loading:d===`import`,disabled:!r.trim()||d!==``,children:`Import`})]}),l&&(0,x.jsxs)(`div`,{className:`linkedin__preview`,children:[(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`strong`,{children:l.self||`You`}),`, `,l.kind===`zip`?`zip`:`folder`,` with `,l.files.length,` files read. `,l.counts.connections,` connections; `,l.counts.threads,` conversations and `,l.counts.invitations,` invitations since `,l.since,`; `,l.counts.applications,` applications (`,l.applicationsSince,` since then); `,l.counts.savedJobs,` saved jobs (`,l.savedJobsSince,` since then).`]}),(0,x.jsxs)(`p`,{children:[`Would write `,(0,x.jsx)(`strong`,{children:l.people.chosen}),` `,m?`people who wrote`:`recruiters and hiring managers`,` of `,l.people.candidates,` senders (`,l.people.onJobNotes,` at companies on your job notes). `,l.warmPaths.jobsWithConnections,` companies on your job notes have connections`,l.warmPaths.top.length?`: ${l.warmPaths.top.slice(0,6).map(e=>`${e.company} (${e.count})`).join(`, `)}`:``,`.`]}),l.people.sample.length>0&&(0,x.jsx)(`ul`,{className:`people__list`,children:l.people.sample.slice(0,6).map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),` `,(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),(e.title||e.company)&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:[e.title,e.company].filter(Boolean).join(` · `)})]}),(0,x.jsx)(`div`,{className:`pager__buttons`,children:(0,x.jsxs)(`span`,{className:`num muted`,children:[e.last,` · `,e.messages,` message`,e.messages===1?``:`s`]})})]},`${e.name}-${e.last}`))})]})]})})}function R_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(`auto`),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)(!1),d=(0,b.useRef)(!1),f=(e,t)=>{n(e),t&&i(e.saved?.text??``)};(0,b.useEffect)(()=>{n(null),$.tailoredResume(e.id).then(e=>f(e,!0)).catch(e=>X({title:`Could not read the resume`,description:e.message,tone:`danger`}))},[e.id]),(0,b.useEffect)(()=>{if(!t?.running){d.current&&t&&(d.current=!1,f(t,!t.error),t.error||X({title:`Resume tailored`,description:`Saved into the note. Read the warnings, then print.`,tone:`success`}));return}d.current=!0;let r=setInterval(()=>$.tailoredResume(e.id).then(e=>n(e)).catch(()=>{}),2500);return()=>clearInterval(r)},[t?.running,e.id]);let p=async()=>{if(!t?.saved||window.confirm(`Tailor again? It replaces the version saved in this note.`))try{f(await $.writeTailoredResume(e.id,{emphasis:a,extra:s}),!1)}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},m=async()=>{u(!0);try{f(await $.saveTailoredResume(e.id,r),!0),X({title:`Saved`,description:`Checked against your resume of record again.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}u(!1)};if(!t)return(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})});let h=t.saved,g=!!h&&r!==h.text,_=h?h.warnings.filter(e=>e.kind===`trace`||e.kind===`claim`||e.kind===`header`||e.kind===`date`).length:0;return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`letter__options`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Emphasis`,value:a,onValueChange:e=>o(e),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`auto`,children:`Let the posting decide`}),(0,x.jsx)(J.Item,{value:`design-systems`,children:`Design systems first`}),(0,x.jsx)(J.Item,{value:`ai-product`,children:`AI product surfaces first`})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Anything to bring forward`,description:`Optional. A project, a tool, a role to lead with.`,value:s,onChange:e=>c(e.target.value),disabled:t.running})]}),(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:p,disabled:t.running,leadingIcon:t.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Sparkles,{}),children:t.running?`Tailoring`:h?`Tailor again`:`Tailor my resume to this posting`}),h&&(0,x.jsx)(B,{asChild:!0,variant:`soft`,size:`sm`,trailingIcon:(0,x.jsx)(H.ExternalLink,{}),children:(0,x.jsx)(`a`,{href:$.resumePrintUrl(e.id),target:`_blank`,rel:`noopener noreferrer`,children:`Print / save as PDF`})}),g&&(0,x.jsx)(B,{variant:`soft`,tone:`primary`,size:`sm`,onClick:m,loading:l,children:`Save edits`})]}),t.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`${t.runner} is reordering your resume for ${e.company}`,size:`sm`}),t.error&&!t.running&&(0,x.jsx)(Vg,{tone:`danger`,size:`sm`,icon:(0,x.jsx)(H.Warning,{}),title:t.errorKind===`auth`?`${t.runner} is signed out`:t.errorKind===`outdated`?`${t.runner} is out of date`:`The resume was not written`,description:t.error}),!h&&!t.running&&!t.error&&(0,x.jsx)(Vg,{size:`sm`,icon:(0,x.jsx)(H.File,{}),title:`Not tailored yet`,description:`Same jobs, dates and numbers as your resume of record. The summary, order and emphasis change for ${e.company}. Nothing is added.`}),h&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`letter__meta`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[h.words,` words · `,h.bullets,` bullets`]}),_===0?(0,x.jsx)(z,{tone:`success`,size:`sm`,children:`Every line traces to your resume`}):(0,x.jsxs)(z,{tone:`danger`,size:`sm`,children:[_,` line`,_===1?``:`s`,` not on your resume`]}),h.warnings.length>_&&(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[h.warnings.length-_,` style`]}),g&&(0,x.jsx)(z,{tone:`primary`,variant:`outline`,size:`sm`,children:`Unsaved edits`})]}),h.warnings.length>0&&(0,x.jsx)(`ul`,{className:`letter__warnings`,children:h.warnings.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{tone:e.kind===`style`||e.kind===`length`?`warning`:`danger`,size:`sm`,children:e.kind}),(0,x.jsx)(`span`,{children:e.text})]},e.text))}),(0,x.jsxs)(Z,{defaultValue:`preview`,variant:`pill`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Resume view`,children:[(0,x.jsx)(Z.Trigger,{value:`preview`,children:`Preview`}),(0,x.jsx)(Z.Trigger,{value:`edit`,children:`Edit`})]}),(0,x.jsx)(Z.Content,{value:`preview`,children:(0,x.jsx)(`div`,{className:`resume-preview`,children:(0,x.jsx)(dg,{text:r})})}),(0,x.jsx)(Z.Content,{value:`edit`,children:(0,x.jsx)(Xp,{label:`Tailored resume (Markdown)`,rows:24,resize:`vertical`,font:`mono`,value:r,onChange:e=>i(e.target.value),description:`Keep the headings. Saving re-runs the trace check.`})})]})]}),(0,x.jsx)(`p`,{className:`muted`,children:`Saved under "Tailored resume" in the job note; the packet's Resume variant field points at it. The PDF you upload comes from the print view.`})]})}var z_=e=>e===`tekjobs`;function B_({label:e=`TekJobs`}){return(0,x.jsxs)(z,{tone:`primary`,variant:`solid`,size:`sm`,title:`Posted on TekJobs by the employer`,children:[(0,x.jsx)(`img`,{className:`posted__glyph`,src:t_.logo,alt:``,width:12,height:12}),e]})}function V_({onAdded:e,onOpen:t}){let[n,r]=(0,b.useState)(!1),[i,a]=(0,b.useState)(``),[o,s]=(0,b.useState)(!1),[c,l]=(0,b.useState)(null),u=i.split(/\s+/).map(e=>e.trim()).filter(e=>/^https?:\/\//i.test(e));return(0,x.jsxs)(W,{open:n,onOpenChange:e=>{r(e),e||(a(``),l(null))},size:`md`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{size:`sm`,variant:`soft`,leadingIcon:(0,x.jsx)(H.Plus,{}),children:`Add by link`})}),(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`Add postings by link`}),(0,x.jsx)(W.Description,{children:`One link per line. LinkedIn job pages, company careers pages, and Greenhouse, Lever or Ashby postings. Each is read once, scored like the scan does, and written as a note unless it is already here.`}),(0,x.jsx)(Xp,{label:`Links`,rows:5,value:i,onChange:e=>a(e.target.value),placeholder:`https://www.linkedin.com/jobs/view/…
74
+ `).map(e=>e.trim()).filter(Boolean);if(!r){u(``),a(e);return}let t={};for(let n of e){let e=n.match(/^(.*?)\s*:\s*(-?\d+(?:\.\d+)?)\s*$/);if(!e||!e[1]){u(`"${n}" is not "term: weight".`);return}t[e[1].trim().toLowerCase()]=Number(e[2])}u(``),a(t)},error:l||void 0})}function D_(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(``),[i,a]=(0,b.useState)(b_),[o,s]=(0,b.useState)([]),[c,l]=(0,b.useState)(!1),[u,d]=(0,b.useState)(``),[f,p]=(0,b.useState)(``),[m,h]=(0,b.useState)(null),[g,_]=(0,b.useState)(!1),[v,y]=(0,b.useState)(null),[S,C]=(0,b.useState)(!1),[w,T]=(0,b.useState)(null),E=(0,b.useRef)(null),[D,O]=(0,b.useState)(null),[k,A]=(0,b.useState)(!1),j=(0,b.useMemo)(()=>e?JSON.stringify(e,null,2):``,[e]),ee=e!==null&&j!==n,M=i!==b_;(0,b.useEffect)(()=>{if(E.current&&window.clearTimeout(E.current),!ee||M){T(null);return}return E.current=window.setTimeout(()=>{$.previewCriteria(j).then(T).catch(()=>T(null))},700),()=>{E.current&&window.clearTimeout(E.current)}},[j,ee,M]),(0,b.useEffect)(()=>{if(!ee)return;let e=e=>{e.preventDefault()};return window.addEventListener(`beforeunload`,e),()=>window.removeEventListener(`beforeunload`,e)},[ee]);let N=()=>$.criteriaPresets().then(s).catch(()=>s([])),te=async e=>{try{let n=e===b_?await $.criteria():await $.criteriaPreset(e);if(!n.parsed)throw Error(`That note's JSON does not parse. Fix it in Obsidian first.`);t(n.parsed),r(JSON.stringify(n.parsed,null,2)),d(JSON.stringify(n.parsed,null,2)),p(``),a(e)}catch(e){X({title:`Could not load criteria`,description:e.message,tone:`danger`})}};(0,b.useEffect)(()=>{te(b_),N()},[]),(0,b.useEffect)(()=>{d(j),p(``)},[j]);let P=e=>t(e),F=async()=>{if(e){l(!0);try{if(M){let e=await $.saveCriteriaPreset(i,j);r(JSON.stringify(e.parsed,null,2)),X({title:`Preset "${i}" saved`,description:`Run a scan with it from here or from Runs; make it active to have the daily scan use it.`,tone:`success`})}else{let e=!!w?.weightsChange,t=w?w.notesAtCurrent:0,n=await $.saveCriteria(j);r(JSON.stringify(n.parsed,null,2)),X({title:`Criteria saved`,description:`Targets/Search Criteria.md updated. The next scan uses it.`,tone:`success`}),O(e&&t>0?{notes:t}:null)}N()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}l(!1)}},ne=async()=>{if(e&&m?.trim()){l(!0);try{let e=await $.saveCriteriaPreset(m.trim(),j);h(null),await N(),a(e.name),r(JSON.stringify(e.parsed,null,2)),X({title:`Preset "${e.name}" created`,description:e.file,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}l(!1)}},re=async()=>{l(!0);try{await $.activateCriteriaPreset(i),await N(),X({title:`"${i}" is now the active criteria`,description:`Search Criteria.md holds a copy. The daily scan uses it from the next run.`,tone:`success`})}catch(e){X({title:`Could not activate`,description:e.message,tone:`danger`})}l(!1)},ie=async()=>{l(!0);try{await $.deleteCriteriaPreset(i),_(!1),await N(),await te(b_),X({title:`Preset deleted`,tone:`success`})}catch(e){X({title:`Could not delete`,description:e.message,tone:`danger`})}l(!1)},ae=async e=>{try{await $.startScan(e,M?i:void 0),X({title:e?`Dry run started`:`Scan started`,description:`Scoring with ${M?`"${i}"`:`the active criteria`}. Watch it on Runs.`,tone:`success`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},oe=async()=>{A(!0);try{let e=await $.rescoreNotes(!1);O(null),X({title:`${e.changed} note${e.changed===1?``:`s`} rescored`,description:`${e.alreadyCurrent} were already at these weights. Each moved note carries the new score, band and reasons, and a status-log line saying so.`,tone:`success`})}catch(e){X({title:`Rescore failed`,description:e.message,tone:`danger`})}A(!1)},se=async()=>{if(w){y(w);return}C(!0);try{y(await $.previewCriteria(j))}catch(e){X({title:`Could not preview`,description:e.message,tone:`danger`})}C(!1)},ce=()=>{try{let e=JSON.parse(u);t(e),p(``)}catch(e){p(e.message)}};if(!e)return(0,x.jsx)(zg,{variant:`rect`,height:`24rem`});let le=e.salary??{},ue={...Object.fromEntries(x_.map(e=>[e,!1])),...e.openSources??{}},de=o.find(e=>e.name===i);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`What the scan looks for and how it scores. Fields write into the JSON in `,M?(0,x.jsxs)(`code`,{children:[`Targets/Criteria/`,i,`.md`]}):(0,x.jsx)(`code`,{children:`Targets/Search Criteria.md`}),`; keys this form does not show are kept as they are.`]})}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[`bar `,String(e.minScore??`?`)]}),le.minAnnual&&(0,x.jsxs)(z,{tone:`success`,size:`sm`,children:[`floor `,Jg(le.minAnnual)]}),le.stretchAnnual&&(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[`stretch `,Jg(le.stretchAnnual)]}),ee&&(0,x.jsx)(z,{tone:`warning`,size:`sm`,children:`unsaved`})]})]}),(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsxs)(`div`,{className:`toolbar`,children:[(0,x.jsxs)(J,{className:`toolbar__filter toolbar__filter--wide`,size:`sm`,label:`Editing`,value:i,onValueChange:e=>{(!ee||window.confirm(`Discard unsaved changes?`))&&te(e)},children:[(0,x.jsx)(J.Item,{value:b_,children:`Active criteria (daily scan)`}),o.map(e=>(0,x.jsxs)(J.Item,{value:e.name,children:[e.name,e.active?` · same as active`:``]},e.name))]}),(0,x.jsx)(`div`,{className:`toolbar__spacer`}),(0,x.jsxs)(`div`,{className:`toolbar__switch pager__buttons`,children:[M&&(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`danger`,disabled:c,onClick:()=>_(!0),children:`Delete preset`}),M&&(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee||de?.active,onClick:re,children:de?.active?`Is the active set`:`Make active`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||S,loading:S,onClick:se,children:`Preview impact`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c,onClick:()=>h(M?`${i} copy`:``),children:`Save as preset…`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee,onClick:()=>ae(!0),children:`Dry run with this`}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:c||ee,onClick:()=>ae(!1),children:`Scan with this`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:!ee||c,loading:c,onClick:F,children:M?`Save preset`:`Save to the vault`})]})]}),M&&de&&(0,x.jsxs)(`p`,{className:`muted`,children:[`Preset · `,de.titles,` title terms · updated `,de.updated,` · `,de.file]}),w&&(0,x.jsxs)(`div`,{className:`impact`,role:`status`,"aria-live":`polite`,children:[(0,x.jsx)(`span`,{className:`microlabel`,children:`If saved`}),(0,x.jsxs)(z,{size:`sm`,tone:w.aboveAfter>=w.aboveBefore?`success`:`warning`,children:[`above the bar `,w.aboveBefore,` → `,w.aboveAfter]}),(0,x.jsxs)(z,{size:`sm`,tone:w.changed?`primary`:`neutral`,children:[w.changed,` of `,w.openNotes,` change score`]}),(0,x.jsxs)(z,{size:`sm`,tone:w.rise.length?`success`:`neutral`,children:[w.rise.length,` rise`]}),(0,x.jsxs)(z,{size:`sm`,tone:w.fall.length?`warning`:`neutral`,children:[w.fall.length,` fall`]}),(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[`top 20: `,w.enterTop20.length,` in, `,w.leaveTop20.length,` out`]}),w.weightsChange&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsxs)(`span`,{className:`num`,children:[w.fingerprintBefore,` → `,w.fingerprintAfter]})}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,onClick:()=>y(w),children:`Details`})]}),D&&!ee&&(0,x.jsxs)(`div`,{className:`impact impact--after`,children:[(0,x.jsx)(`span`,{className:`microlabel`,children:`Saved`}),(0,x.jsxs)(`span`,{children:[D.notes,` open note`,D.notes===1?` was`:`s were`,` scored under the previous weights. The next scan scores new postings with the new ones; the existing notes keep their scores until you rescore them.`]}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsxs)(B,{size:`sm`,variant:`soft`,tone:`primary`,loading:k,disabled:k,onClick:oe,children:[`Rescore `,D.notes,` notes`]}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,disabled:k,onClick:()=>O(null),children:`Later`})]})]}),(0,x.jsxs)(Z,{defaultValue:`fields`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Criteria editors`,children:[(0,x.jsx)(Z.Trigger,{value:`fields`,children:`Fields`}),(0,x.jsx)(Z.Trigger,{value:`titles`,children:`Titles and terms`}),(0,x.jsx)(Z.Trigger,{value:`location`,children:`Location and pay`}),(0,x.jsx)(Z.Trigger,{value:`sources`,children:`Sources`}),(0,x.jsx)(Z.Trigger,{value:`json`,children:`JSON (advanced)`})]}),(0,x.jsx)(Z.Content,{value:`fields`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`minScore`],label:`Bar (minScore)`,hint:`A posting needs this many points to become a note.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`noTitleMatchPenalty`],label:`No title match penalty`,hint:`Taken when the title matches nothing in the title terms.`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`descCap`],label:`Description points cap`,hint:`Description terms add up to this many points, no more.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`maxDescriptionChars`],label:`Description characters kept in a note`,onChange:P,step:500})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`titleExtraPer`],label:`Points per extra title match`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`titleExtraCap`],label:`Extra title matches cap`,onChange:P})]}),(0,x.jsx)(`h3`,{children:`Seniority`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Boost (word: points)`,hint:`Words in the title that add. Example: staff: 10`,value:C_(e,[`seniority`,`boost`]),weighted:!0,rows:6,onCommit:t=>P(w_(e,[`seniority`,`boost`],t))}),(0,x.jsx)(E_,{label:`Penalty (word: points)`,hint:`Words in the title that subtract. Example: junior: -40`,value:C_(e,[`seniority`,`penalty`]),weighted:!0,rows:6,onCommit:t=>P(w_(e,[`seniority`,`penalty`],t))})]}),(0,x.jsx)(`h3`,{children:`Recency`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`recency`,`days2`],label:`Posted within 2 days`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`recency`,`days7`],label:`Within 7 days`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`recency`,`days30`],label:`Within 30 days`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`recency`,`days90`],label:`Within 90 days`,onChange:P})]}),(0,x.jsx)(`div`,{className:`form__row`,children:(0,x.jsx)(T_,{doc:e,path:[`recency`,`older`],label:`Older than 90 days`,onChange:P})})]})})}),(0,x.jsx)(Z.Content,{value:`titles`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Title terms (term: weight)`,hint:`The best single match in the title counts fully; each extra match adds the per-extra points. One per line.`,value:e.titleTerms,weighted:!0,rows:18,onCommit:t=>P(w_(e,[`titleTerms`],t))}),(0,x.jsx)(E_,{label:`Title exclusions (one per line)`,hint:`Any hit in the title drops the posting entirely. Abbreviations are spelled out first, so director catches Sr. Dir.`,value:e.titleExclude,weighted:!1,rows:18,onCommit:t=>P(w_(e,[`titleExclude`],t))})]}),(0,x.jsx)(E_,{label:`Company exclusions (one per line)`,hint:`Any hit in the company name drops the posting entirely: industries, staffing agencies, names. Title words do not catch these.`,value:e.companyExclude??[],weighted:!1,rows:6,onCommit:t=>P(w_(e,[`companyExclude`],t))}),(0,x.jsx)(E_,{label:`Description terms (term: weight)`,hint:`Each term found in the description adds its weight, up to the description cap.`,value:e.descTerms,weighted:!0,rows:14,onCommit:t=>P(w_(e,[`descTerms`],t))})]})})}),(0,x.jsx)(Z.Content,{value:`location`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(`h3`,{children:`Location`}),(0,x.jsx)(Hp,{label:`Remote only`,description:`Anything not remote takes the penalty below, which drops it under the bar.`,checked:!!C_(e,[`location`,`requireRemote`]),onCheckedChange:t=>P(w_(e,[`location`,`requireRemote`],t===!0))}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`location`,`notRemotePenalty`],label:`Not remote penalty`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`location`,`remoteBoost`],label:`Remote boost`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`location`,`nonUsPenalty`],label:`Non-US penalty`,hint:`Applied when the location names a place in the list below and nothing US.`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`location`,`bayAreaBoost`],label:`Metro boost`,hint:`For the metro terms below. Set to 0 to switch it off.`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(E_,{label:`Metro terms (one per line)`,hint:`Places that earn the metro boost. The interview seeds these from your location; empty the list for no boost.`,value:C_(e,[`location`,`bayAreaTerms`]),weighted:!1,rows:8,onCommit:t=>P(w_(e,[`location`,`bayAreaTerms`],t))}),(0,x.jsx)(E_,{label:`US terms (one per line)`,hint:`Words that mark a posting as US.`,value:C_(e,[`location`,`usTerms`]),weighted:!1,rows:8,onCommit:t=>P(w_(e,[`location`,`usTerms`],t))})]}),(0,x.jsx)(E_,{label:`Non-US terms (one per line)`,hint:`Places that trigger the non-US penalty. Whole words.`,value:C_(e,[`location`,`nonUsTerms`]),weighted:!1,rows:10,onCommit:t=>P(w_(e,[`location`,`nonUsTerms`],t))}),(0,x.jsx)(`h3`,{children:`Pay`}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`minAnnual`],label:`Floor (annual)`,hint:`A stated range that tops out at or above this earns the bonus.`,onChange:P,step:5e3}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`stretchAnnual`],label:`Stretch (annual)`,hint:`Between stretch and floor is the stretch band: kept visible, small penalty.`,onChange:P,step:5e3})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`meetsBonus`],label:`Meets floor bonus`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`stretchPenalty`],label:`Stretch band penalty`,onChange:P})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(T_,{doc:e,path:[`salary`,`belowPenalty`],label:`Below stretch penalty`,onChange:P}),(0,x.jsx)(T_,{doc:e,path:[`salary`,`abovePer10k`],label:`Points per $10k above floor`,hint:`Capped at ${String(C_(e,[`salary`,`aboveCap`])??`?`)} (aboveCap).`,onChange:P})]})]})})}),(0,x.jsx)(Z.Content,{value:`sources`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(`p`,{className:`muted`,children:`Aggregator feeds with no company slug. Company boards live on the Companies page. Adzuna and USAJOBS also need a free key in the environment.`}),(0,x.jsx)(`div`,{className:`form__row`,children:Object.keys(ue).map(t=>(0,x.jsx)(Hp,{label:S_[t]??t,checked:!!ue[t],onCheckedChange:n=>P(w_(e,[`openSources`,t],n===!0))},t))})]})})}),(0,x.jsx)(Z.Content,{value:`json`,children:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsx)(Xp,{label:`Criteria JSON`,description:`The whole document. Apply to push it into the fields; Save to write it to the vault.`,font:`mono`,rows:28,resize:`vertical`,value:u,onChange:e=>d(e.target.value),error:f||void 0}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:u===j,onClick:()=>{d(j),p(``)},children:`Revert`}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:u===j,onClick:ce,children:`Apply to fields`})]})]})})})]}),(0,x.jsx)(W,{open:v!==null,onOpenChange:e=>!e&&y(null),size:`lg`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`What this set would do to the notes you have`}),(0,x.jsxs)(W.Description,{children:[`Against the active criteria. Covers `,v?.covers,`. Nothing is written by a preview.`,v?.weightsChange?` The weights change (${v.fingerprintBefore} → ${v.fingerprintAfter}); ${v.notesAtCurrent} open notes were scored under the current ones and can be rescored after saving.`:` The weights do not change; only the bar or the sources do.`]}),v&&(0,x.jsxs)(`div`,{className:`preview`,children:[(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[v.openNotes,` open notes`]}),(0,x.jsxs)(z,{size:`sm`,tone:v.changed?`primary`:`neutral`,children:[v.changed,` change score`]}),(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,children:[`bar `,v.barBefore,` → `,v.barAfter]}),(0,x.jsxs)(z,{size:`sm`,tone:v.aboveAfter>=v.aboveBefore?`success`:`warning`,children:[`above the bar `,v.aboveBefore,` → `,v.aboveAfter]})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Rise above the bar`,rows:v.rise,empty:`Nothing crosses upward.`}),(0,x.jsx)(y_,{title:`Fall below the bar`,rows:v.fall,empty:`Nothing drops out.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Enter the top 20`,rows:v.enterTop20,empty:`The top 20 keeps its members.`}),(0,x.jsx)(y_,{title:`Leave the top 20`,rows:v.leaveTop20,empty:`The top 20 keeps its members.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(y_,{title:`Biggest gains`,rows:v.up,empty:`No note gains points.`}),(0,x.jsx)(y_,{title:`Biggest losses`,rows:v.down,empty:`No note loses points.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(v_,{title:`By role family`,rows:v.byKind,barBefore:v.barBefore,barAfter:v.barAfter}),(0,x.jsx)(v_,{title:`By source`,rows:v.bySource,barBefore:v.barBefore,barAfter:v.barAfter})]})]}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Close`})}),ee&&(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:c,onClick:()=>{y(null),F()},children:M?`Save preset`:`Save to the vault`})]})]})}),(0,x.jsx)(W,{open:m!==null,onOpenChange:e=>!e&&h(null),size:`sm`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`Save as a preset`}),(0,x.jsx)(W.Description,{children:`A named copy under Targets/Criteria/. The daily scan keeps using the active set until you make this one active.`}),(0,x.jsx)(Zp,{label:`Name`,placeholder:`Wider net, 180k floor`,value:m??``,onChange:e=>h(e.target.value)}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Cancel`})}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:!m?.trim()||c,loading:c,onClick:ne,children:`Save preset`})]})]})}),(0,x.jsx)(W,{open:g,onOpenChange:_,size:`sm`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsxs)(W.Title,{children:[`Delete "`,i,`"?`]}),(0,x.jsx)(W.Description,{children:`Removes the note under Targets/Criteria/. The active criteria and every job note stay as they are.`}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Keep it`})}),(0,x.jsx)(B,{size:`sm`,tone:`danger`,disabled:c,loading:c,onClick:ie,children:`Delete`})]})]})})]})}function O_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)({emphasis:`auto`,length:`standard`,extra:``}),[s,c]=(0,b.useState)(!1),l=(0,b.useRef)(!1),u=(e,t)=>{n(e),t&&i(e.saved?.text??``)};(0,b.useEffect)(()=>{n(null),$.coverLetter(e.id).then(e=>u(e,!0)).catch(e=>X({title:`Could not read the letter`,description:e.message,tone:`danger`}))},[e.id]),(0,b.useEffect)(()=>{if(!t?.running){l.current&&t&&(l.current=!1,u(t,!t.error),t.error||X({title:`Cover letter drafted`,description:`Saved into the note. Read it before you use it.`,tone:`success`}));return}l.current=!0;let r=setInterval(()=>$.coverLetter(e.id).then(e=>n(e)).catch(()=>{}),2500);return()=>clearInterval(r)},[t?.running,e.id]);let d=async()=>{if(!t?.saved||window.confirm(`Write a new letter? It replaces the one saved in this note.`))try{u(await $.writeCoverLetter(e.id,a),!1)}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=async()=>{c(!0);try{u(await $.saveCoverLetter(e.id,r),!0),X({title:`Letter saved`,description:`Written into the note and checked against your resume.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}c(!1)},p=async()=>{try{await navigator.clipboard.writeText(r),X({title:`Copied`,tone:`success`})}catch{X({title:`Could not copy`,description:`Select the text and copy it by hand.`,tone:`danger`})}};if(!t)return(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})});let m=t.saved,h=!!m&&r!==m.text;return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`letter__options`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Emphasis`,value:a.emphasis,onValueChange:e=>o({...a,emphasis:e}),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`auto`,children:`Let the posting decide`}),(0,x.jsx)(J.Item,{value:`design-systems`,children:`Design systems first`}),(0,x.jsx)(J.Item,{value:`ai-product`,children:`AI product surfaces first`})]}),(0,x.jsxs)(J,{size:`sm`,label:`Length`,value:a.length,onValueChange:e=>o({...a,length:e}),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`short`,children:`Short, about 150 words`}),(0,x.jsx)(J.Item,{value:`standard`,children:`Standard, about 220 words`})]})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Anything it should include`,description:`Optional. A person you spoke to, a product of theirs you use, a point to make.`,value:a.extra,onChange:e=>o({...a,extra:e.target.value}),disabled:t.running}),(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:d,disabled:t.running,leadingIcon:t.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Sparkles,{}),children:t.running?`Writing`:m?`Write a new one`:`Write cover letter`}),m&&(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:p,leadingIcon:(0,x.jsx)(H.Copy,{}),children:`Copy`}),h&&(0,x.jsx)(B,{variant:`soft`,tone:`primary`,size:`sm`,onClick:f,loading:s,children:`Save edits`})]}),t.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`${t.runner} is writing from your resume and this posting`,size:`sm`}),t.error&&!t.running&&(0,x.jsx)(Vg,{tone:`danger`,size:`sm`,icon:(0,x.jsx)(H.Warning,{}),title:t.errorKind===`auth`?`${t.runner} is signed out`:t.errorKind===`missing`?`${t.runner} is not installed`:t.errorKind===`outdated`?`${t.runner} is out of date`:`The letter was not written`,description:`${t.error} You can also ask any agent connected to the TekJobs MCP server to write it: "write the cover letter for ${e.company}".`}),!m&&!t.running&&!t.error&&(0,x.jsx)(Vg,{size:`sm`,icon:(0,x.jsx)(H.File,{}),title:`No letter yet`,description:`It is written from your resume and ${e.company}'s posting, and only your resume supplies the facts.`}),m&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Xp,{label:`Cover letter`,rows:16,resize:`vertical`,value:r,onChange:e=>i(e.target.value),description:`Edit freely. Saving checks it against your resume again.`}),(0,x.jsxs)(`div`,{className:`letter__meta`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[m.words,` words`]}),m.warnings.length===0?(0,x.jsx)(z,{tone:`success`,size:`sm`,children:`Nothing flagged`}):(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[m.warnings.length,` to check`]}),h&&(0,x.jsx)(z,{tone:`primary`,variant:`outline`,size:`sm`,children:`Unsaved edits`})]}),m.warnings.length>0&&(0,x.jsx)(`ul`,{className:`letter__warnings`,children:m.warnings.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{tone:e.kind===`claim`||e.kind===`placeholder`?`danger`:`warning`,size:`sm`,children:e.kind}),(0,x.jsx)(`span`,{children:e.text})]},e.text))})]}),(0,x.jsx)(`p`,{className:`muted`,children:`The letter is saved under "Cover letter" in the job note. Nothing is sent from here; you paste it where the application asks for it.`})]})}var k_={recruiter:`recruiter`,"hiring-manager":`hiring manager`,interviewer:`interviewer`,referral:`referral`,other:`contact`},A_={recruiter:`primary`,"hiring-manager":`warning`,interviewer:`neutral`,referral:`success`,other:`neutral`},j_=e=>qg.includes(e)?e:`other`;function M_(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(``),[i,a]=(0,b.useState)(`all`),[o,s]=(0,b.useState)(null),c=()=>$.people().then(t).catch(e=>X({title:`Could not load people`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{c()},[]);let l=(0,b.useMemo)(()=>{let t=n.trim().toLowerCase();return(e??[]).filter(e=>(i===`all`||e.role===i)&&(!t||`${e.name} ${e.company} ${e.email}`.toLowerCase().includes(t)))},[e,n,i]);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`toolbar`,children:[(0,x.jsx)(Zp,{className:`toolbar__search`,size:`sm`,label:`Search`,placeholder:`Name, company or email`,value:n,onChange:e=>r(e.target.value)}),(0,x.jsxs)(J,{className:`toolbar__filter`,size:`sm`,label:`Role`,value:i,onValueChange:a,children:[(0,x.jsx)(J.Item,{value:`all`,children:`Everyone`}),qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))]}),(0,x.jsx)(`span`,{className:`toolbar__spacer`}),(0,x.jsx)(N_,{onAdded:e=>{c(),s(e.id)}})]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:6})}):e.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`No people yet`,description:`Confirming an email that a person wrote adds them here, with the thread. Or add someone: a recruiter who reached out, a referral, the hiring manager you met.`}):(0,x.jsxs)(Y,{"aria-label":`People`,density:`md`,stickyHeader:!0,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Name`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Email`}),(0,x.jsx)(Y.HeadCell,{children:`Last contact`}),(0,x.jsx)(Y.HeadCell,{children:`Threads`})]})}),(0,x.jsx)(Y.Body,{children:l.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,selected:o===e.id,onClick:()=>s(e.id),children:[(0,x.jsx)(Y.Cell,{children:e.name}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]})}),(0,x.jsx)(Y.Cell,{children:e.company||(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.email||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num`,children:e.lastContact?`${e.lastContact} · ${Xg(e.lastContact)}`:`—`})}),(0,x.jsxs)(Y.Cell,{children:[(0,x.jsx)(`span`,{className:`num`,children:e.threads.length}),e.live>0&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,e.live,` live`]})]})]},e.id))})]})}),(0,x.jsxs)(`p`,{className:`muted`,children:[l.length,` of `,e?.length??0,` people. Notes live in `,(0,x.jsx)(`code`,{className:`mono`,children:`People/`}),`; a job note lists its people under `,(0,x.jsx)(`code`,{className:`mono`,children:`## People`}),`.`]}),(0,x.jsx)(L_,{onDone:c}),(0,x.jsx)(P_,{id:o,onClose:()=>s(null),onChanged:c})]})}function N_({onAdded:e,job:t}){let[n,r]=(0,b.useState)(!1),i={name:``,role:`recruiter`,company:t?.company??``,email:``,links:``,about:``},[a,o]=(0,b.useState)(i),[s,c]=(0,b.useState)(!1);return(0,x.jsxs)(W,{open:n,onOpenChange:r,size:`sm`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,leadingIcon:(0,x.jsx)(H.Plus,{}),children:`Add a person`})}),(0,x.jsx)(W.Content,{children:(0,x.jsxs)(`form`,{className:`form`,onSubmit:async n=>{n.preventDefault(),c(!0);try{let n=await $.addPerson({...a,jobId:t?.id});r(!1),o(i),X({title:`${n.name} ${n.created===new Date().toISOString().slice(0,10)?`added`:`recognised`}`,description:t?`On ${t.company} - ${t.title}.`:`People/${n.id}.md`,tone:`success`}),e(n)}catch(e){X({title:`Not added`,description:e.message,tone:`danger`})}c(!1)},children:[(0,x.jsx)(W.Title,{children:t?`Someone on ${t.company}`:`Add a person`}),(0,x.jsx)(W.Description,{children:`A note under People/. Someone already there, by email or by name at the same company, is recognised rather than duplicated.`}),(0,x.jsx)(Zp,{label:`Name`,required:!0,value:a.name,onChange:e=>o({...a,name:e.target.value})}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(J,{label:`Role`,value:a.role,onValueChange:e=>o({...a,role:e}),children:qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))}),(0,x.jsx)(Zp,{label:`Company`,value:a.company,onChange:e=>o({...a,company:e.target.value})})]}),(0,x.jsx)(Zp,{label:`Email`,type:`email`,value:a.email,onChange:e=>o({...a,email:e.target.value})}),(0,x.jsx)(Zp,{label:`Links`,description:`LinkedIn or anything else, as text.`,value:a.links,onChange:e=>o({...a,links:e.target.value})}),(0,x.jsx)(Zp,{label:`About`,description:`How you know them, in a line.`,value:a.about,onChange:e=>o({...a,about:e.target.value})}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,children:`Cancel`})}),(0,x.jsx)(B,{type:`submit`,tone:`primary`,loading:s,children:`Add`})]})]})})]})}function P_({id:e,onClose:t,onChanged:n}){let[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(!1);return(0,b.useEffect)(()=>{i(null),e&&$.person(e).then(i).catch(e=>X({title:`Could not open the note`,description:e.message,tone:`danger`}))},[e]),(0,x.jsx)(Sp,{open:e!==null,onOpenChange:e=>!e&&t(),side:`right`,size:`md`,children:(0,x.jsx)(Sp.Content,{children:r?(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`sheet-head`,children:[(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[r.company||`no company`,r.created?` · since ${r.created}`:``]}),(0,x.jsx)(Sp.Title,{children:r.name}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsx)(z,{size:`sm`,tone:A_[j_(r.role)],variant:`soft`,children:k_[j_(r.role)]}),r.email&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:r.email})}),r.lastContact&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[`last contact `,(0,x.jsx)(`span`,{className:`num`,children:r.lastContact})]})]})]}),(0,x.jsx)(`div`,{className:`sheet-head__side`,children:(0,x.jsxs)(`div`,{className:`sheet-head__links`,children:[r.email&&(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:`mailto:${r.email}`,children:`Write to them ↗`})}),(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:r.obsidianUrl,title:r.path,children:`Open in Obsidian ↗`})})]})})]}),(r.about||r.links)&&(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`About`}),(0,x.jsxs)(`p`,{className:`muted`,children:[r.about,r.links?` ${r.links}`:``]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Threads`}),r.threads.length===0?(0,x.jsx)(`p`,{className:`muted`,children:`On no job note yet.`}):(0,x.jsx)(`ul`,{className:`people__threads`,children:r.threads.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(`a`,{className:`people__thread`,href:`#/jobs?q=${encodeURIComponent(e.title.split(` - `)[0]??e.title)}`,children:e.title}),e.status&&(0,x.jsx)(z,{size:`sm`,tone:$g[e.status]??`neutral`,children:e.status}),e.role&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,e.role]})]},e.id))})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Log`}),(0,x.jsx)(dg,{text:r.log||`_Nothing logged yet._`})]}),(0,x.jsx)(Xp,{label:`Log a contact`,rows:3,value:a,onChange:e=>o(e.target.value),placeholder:`A call, a reply, a note to self. Dated today, moves last contact forward. Nothing is sent.`}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:async()=>{if(r&&a.trim()){c(!0);try{i(await $.logContact(r.id,a.trim())),o(``),n(),X({title:`Logged`,description:`On People/${r.id}.md; last contact is today.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}c(!1)}},disabled:s||!a.trim(),children:`Log it`})})]}):(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:5})})})})}function F_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)([]),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(`recruiter`),[l,u]=(0,b.useState)(``),[d,f]=(0,b.useState)(!1),p=()=>$.jobPeople(e.id).then(n).catch(()=>n([]));(0,b.useEffect)(()=>{p(),$.people().then(i).catch(()=>{})},[e.id]);let m=new Set((t??[]).map(e=>e.id)),h=r.filter(e=>!m.has(e.id));return(0,x.jsxs)(`div`,{className:`detail`,children:[t===null?(0,x.jsx)(zg,{lines:3}):t.length===0?(0,x.jsx)(`p`,{className:`muted`,children:`No one on this thread yet. Confirming an email a person wrote adds them; or add someone below.`}):(0,x.jsx)(`ul`,{className:`people__list`,children:t.map((e,t)=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),e.role&&(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),e.context&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.context})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[e.email&&(0,x.jsx)(`a`,{className:`num muted`,href:`mailto:${e.email}`,children:e.email}),e.id&&(0,x.jsx)(`a`,{className:`muted`,href:`#/people`,title:`People/${e.id}.md`,children:`People ↗`})]})]},`${e.id||e.name}-${t}`))}),(0,x.jsx)(I_,{job:e}),(0,x.jsxs)(`div`,{className:`people__add`,children:[(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Someone already in People`,value:a||`__none__`,onValueChange:e=>o(e===`__none__`?``:e),children:[(0,x.jsx)(J.Item,{value:`__none__`,children:`Pick a person`}),h.map(e=>(0,x.jsxs)(J.Item,{value:e.id,children:[e.name,e.company?` · ${e.company}`:``]},e.id))]}),(0,x.jsx)(J,{size:`sm`,label:`On this thread as`,value:s,onValueChange:e=>c(e),children:qg.map(e=>(0,x.jsx)(J.Item,{value:e,children:k_[e]},e))})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Context`,placeholder:`A few words: reached out on LinkedIn, ran the screen, knows the team.`,value:l,onChange:e=>u(e.target.value)}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{size:`sm`,tone:`primary`,variant:`soft`,disabled:!a||d,onClick:async()=>{if(a){f(!0);try{await $.attachPerson(a,e.id,s,l.trim()),o(``),u(``),p(),X({title:`Added to the note`,description:`Under ## People on ${e.company} - ${e.title}.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}f(!1)}},children:`Add to this thread`}),(0,x.jsx)(N_,{job:e,onAdded:()=>{p(),$.people().then(i).catch(()=>{})}})]})]})]})}function I_({job:e}){let[t,n]=(0,b.useState)(null);if((0,b.useEffect)(()=>{$.jobConnections(e.id).then(n).catch(()=>n(null))},[e.id]),!t||!t.imported)return null;let r=t.people.slice(0,8);return(0,x.jsxs)(`div`,{className:`connections`,children:[(0,x.jsx)(`h4`,{className:`connections__title`,children:t.count===0?`No connections at ${e.company}`:`${t.count} connection${t.count===1?``:`s`} at ${e.company}`}),r.length>0&&(0,x.jsx)(`ul`,{className:`people__list`,children:r.map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),e.role!==`other`&&(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),e.title&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.title})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[e.connectedOn&&(0,x.jsxs)(`span`,{className:`num muted`,children:[`since `,e.connectedOn.slice(0,4)]}),e.url&&(0,x.jsx)(`a`,{className:`muted`,href:e.url,target:`_blank`,rel:`noreferrer`,children:`LinkedIn ↗`})]})]},e.url||e.name))}),t.count>r.length&&(0,x.jsxs)(`p`,{className:`muted`,children:[`and `,t.count-r.length,` more.`]}),(0,x.jsxs)(`p`,{className:`muted`,children:[`From your LinkedIn export, imported `,t.imported.slice(0,10),`. A warm introduction beats a cold apply.`]})]})}function L_({onDone:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(``),[s,c]=(0,b.useState)(`roles`),[l,u]=(0,b.useState)(null),[d,f]=(0,b.useState)(``),p=()=>$.linkedinStatus().then(n).catch(()=>n({imported:null}));(0,b.useEffect)(()=>{p()},[]);let m=s===`everyone`,h=async()=>{f(`preview`);try{u(await $.linkedinPreview(r.trim(),a||void 0,m))}catch(e){X({title:`Could not read the export`,description:e.message,tone:`danger`})}f(``)},g=async()=>{f(`import`);try{let t=await $.linkedinImport(r.trim(),{since:a||void 0,everyone:m});X({title:`LinkedIn export imported`,description:`${t.people.created} people created, ${t.people.recognised} already there, ${t.people.attached} put on job notes; ${t.counts.connections} connections indexed.`,tone:`success`}),u(null),e(),p()}catch(e){X({title:`Import failed`,description:e.message,tone:`danger`})}f(``)},_=t?.source?t.source.split(/[\\/]/).pop():``;return(0,x.jsx)(V,{children:(0,x.jsxs)(`div`,{className:`linkedin`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h3`,{className:`connections__title`,children:`Bring your LinkedIn history`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`Request the larger archive at `,(0,x.jsx)(`a`,{href:`https://www.linkedin.com/mypreferences/d/download-my-data`,target:`_blank`,rel:`noreferrer`,children:`linkedin.com/mypreferences/d/download-my-data`}),`, download the zip when LinkedIn emails it (a partial in about ten minutes, the complete one within a day), and paste its path here. It is read in place and never copied. It writes, into this profile folder only: who you know at each company (shown on every job) and People notes for the recruiters and hiring managers who wrote.`]}),t?.imported&&t.counts&&(0,x.jsxs)(`p`,{className:`muted`,children:[`Last imported `,t.imported.slice(0,10),_?` from ${_}`:``,`: `,t.counts.connections,` connections, `,t.counts.threads,` conversations and `,t.counts.invitations,` invitations since `,t.since,`.`]})]}),(0,x.jsxs)(`div`,{className:`linkedin__form`,children:[(0,x.jsx)(Zp,{className:`linkedin__path`,size:`sm`,label:`Path to the export`,placeholder:`C:\\Users\\you\\Downloads\\Complete_LinkedInDataExport_2026-09-24.zip`,value:r,onChange:e=>i(e.target.value)}),(0,x.jsx)(Zp,{size:`sm`,type:`date`,label:`Since`,value:a,onChange:e=>o(e.target.value),description:`Default: 90 days ago`}),(0,x.jsxs)(J,{size:`sm`,label:`Write as People`,value:s,onValueChange:e=>c(e),children:[(0,x.jsx)(J.Item,{value:`roles`,children:`Recruiters and hiring managers`}),(0,x.jsx)(J.Item,{value:`everyone`,children:`Everyone who wrote`})]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,onClick:h,loading:d===`preview`,disabled:!r.trim()||d!==``,children:`Preview`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,onClick:g,loading:d===`import`,disabled:!r.trim()||d!==``,children:`Import`})]}),l&&(0,x.jsxs)(`div`,{className:`linkedin__preview`,children:[(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`strong`,{children:l.self||`You`}),`, `,l.kind===`zip`?`zip`:`folder`,` with `,l.files.length,` files read. `,l.counts.connections,` connections; `,l.counts.threads,` conversations and `,l.counts.invitations,` invitations since `,l.since,`; `,l.counts.applications,` applications (`,l.applicationsSince,` since then); `,l.counts.savedJobs,` saved jobs (`,l.savedJobsSince,` since then).`]}),(0,x.jsxs)(`p`,{children:[`Would write `,(0,x.jsx)(`strong`,{children:l.people.chosen}),` `,m?`people who wrote`:`recruiters and hiring managers`,` of `,l.people.candidates,` senders (`,l.people.onJobNotes,` at companies on your job notes). `,l.warmPaths.jobsWithConnections,` companies on your job notes have connections`,l.warmPaths.top.length?`: ${l.warmPaths.top.slice(0,6).map(e=>`${e.company} (${e.count})`).join(`, `)}`:``,`.`]}),l.people.sample.length>0&&(0,x.jsx)(`ul`,{className:`people__list`,children:l.people.sample.slice(0,6).map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.name}),` `,(0,x.jsx)(z,{size:`sm`,tone:A_[j_(e.role)],variant:`soft`,children:k_[j_(e.role)]}),(e.title||e.company)&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:[e.title,e.company].filter(Boolean).join(` · `)})]}),(0,x.jsx)(`div`,{className:`pager__buttons`,children:(0,x.jsxs)(`span`,{className:`num muted`,children:[e.last,` · `,e.messages,` message`,e.messages===1?``:`s`]})})]},`${e.name}-${e.last}`))})]})]})})}function R_({job:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(`auto`),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)(!1),d=(0,b.useRef)(!1),f=(e,t)=>{n(e),t&&i(e.saved?.text??``)};(0,b.useEffect)(()=>{n(null),$.tailoredResume(e.id).then(e=>f(e,!0)).catch(e=>X({title:`Could not read the resume`,description:e.message,tone:`danger`}))},[e.id]),(0,b.useEffect)(()=>{if(!t?.running){d.current&&t&&(d.current=!1,f(t,!t.error),t.error||X({title:`Resume tailored`,description:`Saved into the note. Read the warnings, then print.`,tone:`success`}));return}d.current=!0;let r=setInterval(()=>$.tailoredResume(e.id).then(e=>n(e)).catch(()=>{}),2500);return()=>clearInterval(r)},[t?.running,e.id]);let p=async()=>{if(!t?.saved||window.confirm(`Tailor again? It replaces the version saved in this note.`))try{f(await $.writeTailoredResume(e.id,{emphasis:a,extra:s}),!1)}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},m=async()=>{u(!0);try{f(await $.saveTailoredResume(e.id,r),!0),X({title:`Saved`,description:`Checked against your resume of record again.`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}u(!1)};if(!t)return(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})});let h=t.saved,g=!!h&&r!==h.text,_=h?h.warnings.filter(e=>e.kind===`trace`||e.kind===`claim`||e.kind===`header`||e.kind===`date`).length:0;return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`letter__options`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Emphasis`,value:a,onValueChange:e=>o(e),disabled:t.running,children:[(0,x.jsx)(J.Item,{value:`auto`,children:`Let the posting decide`}),(0,x.jsx)(J.Item,{value:`design-systems`,children:`Design systems first`}),(0,x.jsx)(J.Item,{value:`ai-product`,children:`AI product surfaces first`})]}),(0,x.jsx)(Zp,{size:`sm`,label:`Anything to bring forward`,description:`Optional. A project, a tool, a role to lead with.`,value:s,onChange:e=>c(e.target.value),disabled:t.running})]}),(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:p,disabled:t.running,leadingIcon:t.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Sparkles,{}),children:t.running?`Tailoring`:h?`Tailor again`:`Tailor my resume to this posting`}),h&&(0,x.jsx)(B,{asChild:!0,variant:`soft`,size:`sm`,trailingIcon:(0,x.jsx)(H.ExternalLink,{}),children:(0,x.jsx)(`a`,{href:$.resumePrintUrl(e.id),target:`_blank`,rel:`noopener noreferrer`,children:`Print / save as PDF`})}),g&&(0,x.jsx)(B,{variant:`soft`,tone:`primary`,size:`sm`,onClick:m,loading:l,children:`Save edits`})]}),t.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`${t.runner} is reordering your resume for ${e.company}`,size:`sm`}),t.error&&!t.running&&(0,x.jsx)(Vg,{tone:`danger`,size:`sm`,icon:(0,x.jsx)(H.Warning,{}),title:t.errorKind===`auth`?`${t.runner} is signed out`:t.errorKind===`outdated`?`${t.runner} is out of date`:`The resume was not written`,description:t.error}),!h&&!t.running&&!t.error&&(0,x.jsx)(Vg,{size:`sm`,icon:(0,x.jsx)(H.File,{}),title:`Not tailored yet`,description:`Same jobs, dates and numbers as your resume of record. The summary, order and emphasis change for ${e.company}. Nothing is added.`}),h&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`letter__meta`,children:[(0,x.jsxs)(z,{tone:`neutral`,size:`sm`,children:[h.words,` words · `,h.bullets,` bullets`]}),_===0?(0,x.jsx)(z,{tone:`success`,size:`sm`,children:`Every line traces to your resume`}):(0,x.jsxs)(z,{tone:`danger`,size:`sm`,children:[_,` line`,_===1?``:`s`,` not on your resume`]}),h.warnings.length>_&&(0,x.jsxs)(z,{tone:`warning`,size:`sm`,children:[h.warnings.length-_,` style`]}),g&&(0,x.jsx)(z,{tone:`primary`,variant:`outline`,size:`sm`,children:`Unsaved edits`})]}),h.warnings.length>0&&(0,x.jsx)(`ul`,{className:`letter__warnings`,children:h.warnings.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{tone:e.kind===`style`||e.kind===`length`?`warning`:`danger`,size:`sm`,children:e.kind}),(0,x.jsx)(`span`,{children:e.text})]},e.text))}),(0,x.jsxs)(Z,{defaultValue:`preview`,variant:`pill`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Resume view`,children:[(0,x.jsx)(Z.Trigger,{value:`preview`,children:`Preview`}),(0,x.jsx)(Z.Trigger,{value:`edit`,children:`Edit`})]}),(0,x.jsx)(Z.Content,{value:`preview`,children:(0,x.jsx)(`div`,{className:`resume-preview`,children:(0,x.jsx)(dg,{text:r})})}),(0,x.jsx)(Z.Content,{value:`edit`,children:(0,x.jsx)(Xp,{label:`Tailored resume (Markdown)`,rows:24,resize:`vertical`,font:`mono`,value:r,onChange:e=>i(e.target.value),description:`Keep the headings. Saving re-runs the trace check.`})})]})]}),(0,x.jsx)(`p`,{className:`muted`,children:`Saved under "Tailored resume" in the job note; the packet's Resume variant field points at it. The PDF you upload comes from the print view.`})]})}var z_=e=>e===`tekjobs`;function B_({label:e=`TekJobs`}){return(0,x.jsxs)(z,{tone:`primary`,variant:`solid`,size:`sm`,title:`Posted on TekJobs by the employer`,children:[(0,x.jsx)(`img`,{className:`posted__glyph`,src:t_.logo,alt:``,width:12,height:12}),e]})}function V_({onAdded:e,onOpen:t}){let[n,r]=(0,b.useState)(!1),[i,a]=(0,b.useState)(``),[o,s]=(0,b.useState)(!1),[c,l]=(0,b.useState)(null),u=i.split(/\s+/).map(e=>e.trim()).filter(e=>/^https?:\/\//i.test(e));return(0,x.jsxs)(W,{open:n,onOpenChange:e=>{r(e),e||(a(``),l(null))},size:`md`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{size:`sm`,variant:`soft`,leadingIcon:(0,x.jsx)(H.Plus,{}),children:`Add by link`})}),(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`Add postings by link`}),(0,x.jsx)(W.Description,{children:`One link per line. LinkedIn job pages, company careers pages, and Greenhouse, Lever or Ashby postings. Each is read once, scored like the scan does, and written as a note unless it is already here.`}),(0,x.jsx)(Xp,{label:`Links`,rows:5,value:i,onChange:e=>a(e.target.value),placeholder:`https://www.linkedin.com/jobs/view/…
75
75
  https://jobs.lever.co/…`,disabled:o}),c&&(0,x.jsx)(`ul`,{className:`import-results`,children:c.map((e,n)=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{size:`sm`,tone:e.ok?e.added?`success`:`neutral`:`danger`,children:e.ok?e.added?`added`:`already here`:`failed`}),e.ok?(0,x.jsxs)(`span`,{className:`import-results__row`,children:[(0,x.jsxs)(`span`,{children:[e.score,` ·`]}),e.id?(0,x.jsxs)(B,{variant:`link`,size:`sm`,tone:`primary`,onClick:()=>{r(!1),t(e.id)},children:[e.company,` — `,e.title]}):(0,x.jsxs)(`span`,{children:[e.company,` — `,e.title]}),e.link&&(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,trailingIcon:(0,x.jsx)(H.ExternalLink,{}),children:(0,x.jsx)(`a`,{href:e.link,target:`_blank`,rel:`noopener noreferrer`,children:`Open posting`})}),e.reason&&(0,x.jsxs)(`span`,{className:`muted`,children:[`(`,e.reason,`)`]}),e.belowMin&&(0,x.jsx)(`span`,{className:`muted`,children:`· below the scan's minimum, written anyway`})]}):(0,x.jsxs)(`span`,{children:[e.error,` (`,e.url,`)`]})]},n))}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:o,children:`Close`})}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:o||u.length===0,loading:o,onClick:async()=>{s(!0);try{let t=await $.importLinks(u);l(t);let n=t.filter(e=>e.added);n.length?(X({title:`${n.length} job${n.length===1?``:`s`} added`,description:n.map(e=>`${e.company}: ${e.title}`).join(` · `),tone:`success`}),e(n[0]?.id??null)):X({title:`Nothing new`,description:`Every link was already here, or could not be read.`,tone:`warning`})}catch(e){X({title:`Import failed`,description:e.message,tone:`danger`})}finally{s(!1)}},children:o?`Reading…`:`Add ${u.length||``}`.trim()})]})]})]})}function H_({job:e,onAttached:t}){let[n,r]=(0,b.useState)(!1),[i,a]=(0,b.useState)(``),[o,s]=(0,b.useState)(!1),c=e.source===`mail`||e.source===`page`||!e.url||/mail\.google\.com/.test(e.url),l=async(n=!1)=>{s(!0);try{let o=await $.attachPosting(e.id,i.trim(),n);t(o),r(!1),a(``),o.linkOnly?X({title:`${o.company}: link saved`,description:o.warning?`The posting itself could not be read (${o.warning}), so only the link is on the note. Open posting now goes there.`:`Only the link is on the note; nothing else changed.`,tone:`neutral`}):X({title:`${o.company}: posting attached`,description:`Scored ${o.score} from the posting. Status, notes and drafts kept.`,tone:`success`})}catch(e){X({title:`Could not attach`,description:e.message,tone:`danger`})}finally{s(!1)}};return(0,x.jsxs)(W,{open:n,onOpenChange:r,size:`sm`,children:[(0,x.jsx)(W.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:c?`soft`:`ghost`,size:`sm`,leadingIcon:(0,x.jsx)(H.Link,{}),children:c?`Attach posting`:`Replace posting`})}),(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:c?`Attach the posting`:`Replace the posting`}),(0,x.jsxs)(W.Description,{children:[c?`This note was created without the posting itself. `:``,`Paste the job's link. Attach reads the posting and replaces the note's facts, score and description; status, notes, packet and drafts stay. Link only just records the link, for a page that cannot be read (LinkedIn, a login wall) or when the note's facts are already right.`]}),(0,x.jsx)(Zp,{label:`Posting link`,placeholder:`https://jobs.ashbyhq.com/… or the company careers page`,value:i,onChange:e=>a(e.target.value),disabled:o}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:o,children:`Cancel`})}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`neutral`,disabled:o||!/^https?:\/\//i.test(i.trim()),onClick:()=>l(!0),children:`Link only`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:o||!/^https?:\/\//i.test(i.trim()),loading:o,onClick:()=>l(!1),children:`Attach`})]})]})]})}var U_=25,W_=[[``,`any time`],[`2`,`2 days`],[`7`,`7 days`],[`14`,`14 days`],[`30`,`30 days`],[`90`,`90 days`]],G_={q:``,location:``,remote:!1,kind:`all`,band:[],status:[],source:[],company:[],minScore:`45`,maxScore:``,payMin:``,payMax:``,payKnown:!1,postedDays:``,foundDays:``},K_=()=>new URLSearchParams(window.location.hash.split(`?`)[1]??``),q_=[{key:`minScore`,label:`Score at least`},{key:`remote`,label:`Remote only`},{key:`location`,label:`Location`},{key:`kind`,label:`Title`},{key:`band`,label:`Pay band`},{key:`status`,label:`Status`},{key:`source`,label:`Source`},{key:`company`,label:`Company`},{key:`payMin`,label:`Pay at least`},{key:`payMax`,label:`Pay at most`},{key:`payKnown`,label:`Stated pay only`},{key:`postedDays`,label:`Posted within`},{key:`foundDays`,label:`Found within`},{key:`maxScore`,label:`Score at most`}],J_=(e,t)=>{let n=e[t];return Array.isArray(n)?n.length>0:typeof n==`boolean`?n:t===`minScore`?n!==``&&n!==`0`:n!==G_[t]};function Y_(e){let t=e===void 0?K_():new URLSearchParams(e),n={...G_,band:[],status:[],source:[],company:[]},r=n;for(let e of Object.keys(G_)){let n=t.get(e);if(n===null)continue;let i=G_[e];r[e]=Array.isArray(i)?n.split(`,`).filter(Boolean):typeof i==`boolean`?n===`1`:n}return n}function X_(e,t,n){let r=new URLSearchParams;for(let t of Object.keys(G_)){let n=e[t];Array.isArray(n)?n.length&&r.set(t,n.join(`,`)):typeof n==`boolean`?n&&r.set(t,`1`):n!==G_[t]&&r.set(t,n)}return t!==`score`&&r.set(`sort`,t),n!==`desc`&&r.set(`dir`,n),r.toString()}function Z_(e,t,n){let r=X_(e,t,n);window.history.replaceState(null,``,`#/jobs${r?`?${r}`:``}`)}var Q_=e=>({q:e.q,location:e.location,remote:e.remote?1:void 0,kind:e.kind===`all`?void 0:e.kind,band:e.band.join(`,`),status:e.status.join(`,`),source:e.source.join(`,`),company:e.company.join(`,`),minScore:e.minScore===`0`||e.minScore===``?void 0:Number(e.minScore),maxScore:e.maxScore?Number(e.maxScore):void 0,payMin:e.payMin?Number(e.payMin):void 0,payMax:e.payMax?Number(e.payMax):void 0,payKnown:e.payKnown?1:void 0,postedDays:e.postedDays?Number(e.postedDays):void 0,foundDays:e.foundDays?Number(e.foundDays):void 0}),$_=(e,t,n)=>e.map(e=>({value:e,label:n(e),hint:t?String(t[e]??0):void 0})),ev=`tekjobs.jobs.last`,tv=e=>{try{localStorage.setItem(ev,e)}catch{}},nv=()=>{let[e,t]=window.location.hash.replace(/^#\/?/,``).split(`?`);if(e!==`jobs`||t)return;let n=``;try{n=localStorage.getItem(ev)??``}catch{}n&&window.history.replaceState(null,``,`#/jobs?${n}`)};function rv({initialQuery:e=``}){e||nv();let[t,n]=(0,b.useState)(()=>{let t=Y_();return e?{...t,q:e}:t}),[r,i]=(0,b.useState)(()=>K_().get(`sort`)||`score`),[a,o]=(0,b.useState)(()=>K_().get(`dir`)===`asc`?`asc`:`desc`),[s,c]=(0,b.useState)(0),[l,u]=(0,b.useState)(null),[d,f]=(0,b.useState)(0),[p,m]=(0,b.useState)(null),[h,g]=(0,b.useState)(null),[_,v]=(0,b.useState)(null),y=(0,b.useRef)(null),[S,C]=(0,b.useState)([]),[w,T]=(0,b.useState)([]),[E,D]=(0,b.useState)([]),[O,k]=(0,b.useState)(null),[A,j]=(0,b.useState)(()=>{try{return localStorage.getItem(`tekjobs.jobs.condensed`)===`1`}catch{return!1}}),ee=()=>j(e=>{try{localStorage.setItem(`tekjobs.jobs.condensed`,e?`0`:`1`)}catch{}return!e}),[M,N]=(0,b.useState)(()=>K_().get(`open`)),[te,P]=(0,b.useState)(0);(0,b.useEffect)(()=>{$.views().then(T).catch(()=>{}),$.defaultViews().then(D).catch(()=>{}),$.facets({}).then(e=>g(e.total)).catch(()=>{}),$.summary().then(e=>{if(!e.minScore)return;let t=String(e.minScore),r=K_().has(`minScore`);G_.minScore=t,r||n(e=>e.minScore===`45`||e.minScore===``?{...e,minScore:t}:e)}).catch(()=>{})},[]);let F=(e,t)=>{n(n=>({...n,[e]:t})),c(0)},ne=(0,b.useMemo)(()=>Q_(t),[t]),re=JSON.stringify(ne),ie=t.remote;(0,b.useEffect)(()=>{e&&F(`q`,e)},[e]),(0,b.useEffect)(()=>{Z_(t,r,a),tv(X_(t,r,a))},[t,r,a]),(0,b.useEffect)(()=>{let e=()=>{if(window.location.hash.replace(/^#\/?/,``).split(`?`)[0]!==`jobs`)return;nv();let e=Y_(),s=K_().get(`sort`)||`score`,l=K_().get(`dir`)===`asc`?`asc`:`desc`;X_(e,s,l)!==X_(t,r,a)&&(n(e),i(s),o(l),c(0))};return window.addEventListener(`hashchange`,e),()=>window.removeEventListener(`hashchange`,e)},[t,r,a]),(0,b.useEffect)(()=>{let e=!0;return $.jobs({...ne,sort:r,dir:a,limit:U_,offset:s*U_}).then(t=>{e&&(u(t.rows),f(t.total))}).catch(e=>X({title:`Could not load jobs`,description:e.message,tone:`danger`})),$.facets(ne).then(t=>{e&&m(t)}).catch(()=>{}),()=>{e=!1}},[re,r,a,s,te]);let ae=$_(Gg,p?.status,e=>e),oe=$_([`floor`,`stretch`,`below`,`unknown`],p?.band,e=>Zg[e]),se=$_(Array.from(new Set([...p?.source.link?[`link`]:[],...Object.entries(p?.source??{}).filter(([e])=>e!==`link`).sort((e,t)=>t[1]-e[1]).map(([e])=>e),...t.source])),p?.source,e=>e===`link`?`added by link`:e),ce=$_(Array.from(new Set([...t.company,...Object.entries(p?.company??{}).sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).map(([e])=>e)])),p?.company,e=>e),le=p?.pay,ue=Math.max(1,Math.ceil(d/U_)),de=Math.min(s,ue-1),fe=e=>{r===e?o(a===`desc`?`asc`:`desc`):(i(e),o(e===`company`||e===`title`?`asc`:`desc`)),c(0)},pe=(e,t,n)=>(0,x.jsx)(Y.HeadCell,{...n,"aria-sort":r===e?a===`desc`?`descending`:`ascending`:void 0,children:(0,x.jsx)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>fe(e),trailingIcon:r===e?a===`desc`?(0,x.jsx)(H.ArrowDown,{}):(0,x.jsx)(H.ArrowUp,{}):void 0,children:(0,x.jsx)(`span`,{className:`col`,children:t})})}),me=e=>u(t=>t&&t.map(t=>t.id===e.id?{...t,status:e.status}:t)),I=e_(`(min-width: 68.75rem)`),he=I&&M!==null,ge=l?l.findIndex(e=>e.id===M):-1,_e=(0,b.useRef)(null);(0,b.useEffect)(()=>{if(!l||!_e.current)return;let e=_e.current;_e.current=null;let t=e===`first`?l[0]:l[l.length-1];t&&N(t.id)},[l]);let ve=e=>{if(!l||l.length===0)return;let t=l[0];if(ge<0){t&&N(t.id);return}let n=ge+e,r=l[n];r?N(r.id):n>=l.length&&de<ue-1?(_e.current=`first`,c(de+1)):n<0&&de>0&&(_e.current=`last`,c(de-1))};(0,b.useEffect)(()=>{if(M===null)return;let e=e=>{let t=e.target;e.defaultPrevented||e.metaKey||e.ctrlKey||e.altKey||t&&(/^(input|textarea|select)$/i.test(t.tagName)||t.isContentEditable)||(e.key===`Escape`?N(null):e.key===`j`||e.key===`ArrowDown`?(e.preventDefault(),ve(1)):(e.key===`k`||e.key===`ArrowUp`)&&(e.preventDefault(),ve(-1)))};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)});let L={pos:ge>=0?de*U_+ge:-1,total:d,prev:()=>ve(-1),next:()=>ve(1)},ye=q_.filter(e=>J_(t,e.key)).length+ +!!t.q,be=e=>{switch(e){case`location`:return(0,x.jsx)(Zp,{size:`sm`,label:`Location`,description:`Comma-separated, any of; whole words.`,placeholder:`seattle, wa, united states`,value:t.location,onChange:e=>F(`location`,e.target.value),autoFocus:!0});case`remote`:return(0,x.jsx)(Hp,{size:`sm`,label:`Remote only${p?` (${p.remote.remote})`:``}`,checked:t.remote,onCheckedChange:e=>F(`remote`,e===!0)});case`payKnown`:return(0,x.jsx)(Hp,{size:`sm`,label:`Stated pay only`,checked:t.payKnown,onCheckedChange:e=>F(`payKnown`,e===!0)});case`kind`:return(0,x.jsxs)(J,{size:`sm`,label:`Title`,value:t.kind,onValueChange:e=>F(`kind`,e),children:[(0,x.jsx)(J.Item,{value:`all`,children:`All titles`}),(0,x.jsxs)(J.Item,{value:`design-eng`,children:[`Design engineering`,p?` (${p.kind[`design-eng`]??0})`:``]}),(0,x.jsxs)(J.Item,{value:`adjacent`,children:[`Adjacent`,p?` (${p.kind.adjacent??0})`:``]})]});case`band`:return(0,x.jsx)(Wg,{size:`sm`,multiple:!0,label:`Pay band`,placeholder:`All bands`,emptyMessage:`No band by that name.`,options:oe,value:t.band,onValueChange:e=>F(`band`,e)});case`status`:return(0,x.jsx)(Wg,{size:`sm`,multiple:!0,label:`Status`,placeholder:`All statuses`,emptyMessage:`No status by that name.`,options:ae,value:t.status,onValueChange:e=>F(`status`,e)});case`source`:return(0,x.jsx)(Wg,{size:`sm`,multiple:!0,label:`Source`,placeholder:`All sources`,emptyMessage:`No source by that name.`,options:se,value:t.source,onValueChange:e=>F(`source`,e)});case`company`:return(0,x.jsx)(Wg,{size:`sm`,multiple:!0,label:`Company`,placeholder:`Any company`,emptyMessage:`No company in the current results by that name.`,options:ce,value:t.company,onValueChange:e=>F(`company`,e)});case`payMin`:return(0,x.jsx)(Zp,{size:`sm`,type:`number`,step:1e4,label:`Pay at least`,description:le?`Top of the stated range. Stated on ${le.stated} of ${le.stated+le.unstated}.`:void 0,placeholder:`200000`,value:t.payMin,onChange:e=>F(`payMin`,e.target.value),autoFocus:!0});case`payMax`:return(0,x.jsx)(Zp,{size:`sm`,type:`number`,step:1e4,label:`Pay at most`,description:le&&le.stated?`${Jg(le.min)} to ${Jg(le.max)}, median ${Jg(le.median)}.`:void 0,placeholder:`300000`,value:t.payMax,onChange:e=>F(`payMax`,e.target.value),autoFocus:!0});case`minScore`:return(0,x.jsx)(J,{size:`sm`,label:`Score at least`,value:t.minScore||`0`,onValueChange:e=>F(`minScore`,e),children:[`0`,`45`,`60`,`75`,`90`,`100`].map(e=>(0,x.jsx)(J.Item,{value:e,children:e===`0`?`any`:`${e} pts`},e))});case`maxScore`:return(0,x.jsx)(Zp,{size:`sm`,type:`number`,label:`Score at most`,placeholder:`any`,value:t.maxScore,onChange:e=>F(`maxScore`,e.target.value),autoFocus:!0});case`postedDays`:case`foundDays`:return(0,x.jsx)(J,{size:`sm`,label:e===`postedDays`?`Posted within`:`Found within`,value:t[e],onValueChange:t=>F(e,t),children:W_.map(([e,t])=>(0,x.jsx)(J.Item,{value:e,children:t},e||`any`))})}},xe=e=>{let n=t[e];return Array.isArray(n)?e===`band`?n.map(e=>Zg[e]).join(`, `):n.length>2?`${n.slice(0,2).join(`, `)} +${n.length-2}`:n.join(`, `):typeof n==`boolean`?``:e===`kind`?n===`design-eng`?`design engineering`:n===`adjacent`?`adjacent`:``:e===`payMin`||e===`payMax`?n?Jg(Number(n)):``:e===`minScore`||e===`maxScore`?n&&n!==`0`?`${n} pts`:``:e===`postedDays`||e===`foundDays`?n?`${n} days`:``:n},Se=e=>{let t=G_[e];F(e,e===`minScore`?`0`:Array.isArray(t)?[]:t),v(null),C(t=>t.filter(t=>t!==e))},Ce=e=>{e===`remote`||e===`payKnown`?F(e,!0):e===`kind`?F(e,`design-eng`):e===`postedDays`?F(e,`7`):e===`minScore`&&(!t.minScore||t.minScore===`0`)&&F(e,`45`),C(t=>t.includes(e)?t:[...t,e]),v(e)},we=q_.filter(e=>J_(t,e.key)||_===e.key||S.includes(e.key)),Te=q_.filter(e=>!J_(t,e.key)&&!S.includes(e.key)),Ee=X_(t,r,a),De=e=>{n(Y_(e.query)),c(0)},Oe=async()=>{let e=(O??``).trim();if(e)try{T(await $.saveViews([...w.filter(t=>t.name!==e),{name:e,query:Ee}])),k(null),X({title:`View "${e}" saved`,description:`Targets/Job Views.md`,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}},ke=async e=>{try{T(await $.saveViews(w.filter(t=>t.name!==e)))}catch(e){X({title:`Not removed`,description:e.message,tone:`danger`})}};return(0,x.jsxs)(`div`,{className:he?`jobs jobs--split`:`jobs`,children:[he?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`aside`,{className:`jobs__list`,"aria-label":`Matches`,children:[(0,x.jsxs)(`div`,{className:`ctools`,children:[(0,x.jsxs)(`div`,{className:`ctools__row`,children:[(0,x.jsx)(Zp,{size:`sm`,"aria-label":`Search`,placeholder:`Search company or role`,value:t.q,onChange:e=>F(`q`,e.target.value)}),(0,x.jsx)(Bh,{content:`Back to the full table (Esc)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Back to the full table`,leadingIcon:(0,x.jsx)(H.Grid,{}),onClick:()=>N(null)})})]}),(0,x.jsxs)(`div`,{className:`ctools__row ctools__meta`,children:[(0,x.jsxs)(`span`,{children:[(0,x.jsx)(`b`,{className:`num`,children:d}),h===null?null:(0,x.jsxs)(x.Fragment,{children:[` of `,h]}),` · `,ye,` filter`,ye===1?``:`s`]}),(0,x.jsx)(`span`,{className:`num`,children:`J K move · Esc close`})]})]}),(0,x.jsxs)(`div`,{className:`clist`,children:[(l??[]).map(e=>(0,x.jsx)(B,{asChild:!0,variant:`ghost`,size:`sm`,align:`start`,className:`clist__item`,children:(0,x.jsxs)(`button`,{type:`button`,"aria-current":e.id===M?`true`:void 0,"data-posted":z_(e.source)||void 0,onClick:()=>N(e.id),children:[(0,x.jsx)(`span`,{className:`clist__score num`,children:e.score}),(0,x.jsxs)(`span`,{className:`clist__text`,children:[(0,x.jsx)(`span`,{className:`clist__role`,children:e.title}),(0,x.jsxs)(`span`,{className:`clist__meta`,children:[e.company,` · `,(0,x.jsx)(`span`,{className:`num${e.payBand===`floor`?` clist__pay--floor`:``}`,children:e.salaryMax?Yg(e.salary):`not stated`}),` · `,Xg(e.posted)||`—`]})]})]})},e.id)),l&&l.length===0&&(0,x.jsx)(`p`,{className:`muted`,children:`Nothing matches these filters.`}),l&&ue>1&&(0,x.jsxs)(`div`,{className:`clist__pager`,children:[(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:de===0,onClick:()=>c(de-1),children:`Previous`}),(0,x.jsxs)(`span`,{className:`muted num`,children:[de+1,` / `,ue]}),(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:de>=ue-1,onClick:()=>c(de+1),children:`Next`})]})]})]}),(0,x.jsx)(`section`,{className:`jobs__detail`,"aria-label":`Job`,children:(0,x.jsx)(ov,{id:M,inline:!0,nav:L,onClose:()=>N(null),onChanged:me})})]}):(0,x.jsxs)(x.Fragment,{children:[!A&&(0,x.jsxs)(`div`,{className:`views`,children:[(0,x.jsx)(Bh,{content:`Hide the views and filters`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Hide the views and filters`,leadingIcon:(0,x.jsx)(H.ChevronUp,{}),onClick:ee})}),(0,x.jsx)(`span`,{className:`views__label`,children:`Views`}),E.map(e=>(0,x.jsx)(`div`,{className:`chip chip--default${e.query===Ee?` chip--current`:``}`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:e.query===Ee?`primary`:`neutral`,title:`From your criteria: ${e.hint}`,onClick:()=>De(e),children:e.name})},`d:${e.name}`)),w.map(e=>(0,x.jsxs)(`div`,{className:`chip${e.query===Ee?` chip--current`:``}`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:e.query===Ee?`primary`:`neutral`,onClick:()=>De(e),children:e.name}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Remove the view ${e.name}`,onClick:()=>ke(e.name),children:`×`})]},e.name)),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,leadingIcon:(0,x.jsx)(H.Plus,{}),disabled:!Ee,onClick:()=>k(``),children:`Save current filters as a view`}),(0,x.jsx)(`div`,{className:`toolbar__spacer`})]}),!A&&(0,x.jsxs)(`div`,{className:`filters`,children:[(0,x.jsx)(Zp,{className:`filters__search`,size:`sm`,label:`Search`,placeholder:`company or role`,value:t.q,onChange:e=>F(`q`,e.target.value)}),we.map(e=>{let n=J_(t,e.key),r=xe(e.key);return(0,x.jsxs)(`div`,{className:`chip${n?` chip--on`:``}`,children:[(0,x.jsxs)(fd,{open:_===e.key,onOpenChange:t=>v(t?e.key:null),size:`sm`,children:[(0,x.jsx)(fd.Trigger,{asChild:!0,children:(0,x.jsxs)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,leadingIcon:(0,x.jsx)(`span`,{className:`chip__dot`,"aria-hidden":`true`}),children:[e.label,r&&(0,x.jsx)(`span`,{className:`chip__value num`,children:r})]})}),(0,x.jsx)(fd.Content,{align:`start`,showArrow:!1,children:(0,x.jsx)(`div`,{className:`chip__editor`,children:be(e.key)})})]}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Remove ${e.label}`,onClick:()=>Se(e.key),children:`×`})]},e.key)}),Te.length>0&&(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,leadingIcon:(0,x.jsx)(H.Plus,{}),trailingIcon:(0,x.jsx)(H.ChevronDown,{}),children:`Filter`})}),(0,x.jsx)(Tu.Content,{align:`start`,onCloseAutoFocus:e=>{y.current&&(y.current=null,e.preventDefault())},children:Te.map(e=>(0,x.jsx)(Tu.Item,{onSelect:()=>{y.current=e.key,Ce(e.key)},children:e.label},e.key))})]}),we.some(e=>J_(t,e.key)&&e.key!==`minScore`)||t.q?(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,onClick:()=>{n({...G_,band:[],status:[],source:[],company:[]}),c(0)},children:`Clear`}):null,(0,x.jsx)(`div`,{className:`toolbar__spacer`}),(0,x.jsx)(V_,{onAdded:e=>{P(e=>e+1),e&&N(e)},onOpen:e=>N(e)})]}),(0,x.jsxs)(`div`,{className:`filters__summary`,children:[(0,x.jsxs)(`span`,{children:[A&&(0,x.jsx)(Bh,{content:`Show the views and filters (${we.filter(e=>J_(t,e.key)).length+ +!!t.q} active)`,children:(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`neutral`,"aria-label":`Show the views and filters`,leadingIcon:(0,x.jsx)(H.ChevronDown,{}),onClick:ee})}),(0,x.jsx)(`b`,{className:`num`,children:d}),` of `,(0,x.jsx)(`span`,{className:`num`,children:h??`…`}),` matches`,le&&le.stated>0&&(0,x.jsxs)(x.Fragment,{children:[` · pay stated on `,(0,x.jsx)(`span`,{className:`num`,children:le.stated}),`, median top of range `,(0,x.jsx)(`span`,{className:`num`,children:Jg(le.median)})]})]}),(0,x.jsxs)(`span`,{className:`num filters__query`,children:[`/jobs`,Ee?`?${Ee}`:``]})]}),(0,x.jsx)(W,{open:O!==null,onOpenChange:e=>!e&&k(null),size:`sm`,children:(0,x.jsxs)(W.Content,{children:[(0,x.jsx)(W.Title,{children:`Save these filters as a view`}),(0,x.jsx)(W.Description,{children:`A named link to exactly this filter set, kept in Targets/Job Views.md. Same name replaces the old one.`}),(0,x.jsx)(Zp,{label:`Name`,placeholder:`Design eng at floor`,value:O??``,onChange:e=>k(e.target.value),autoFocus:!0}),(0,x.jsxs)(`p`,{className:`muted num filters__query`,children:[`/jobs?`,Ee]}),(0,x.jsxs)(W.Footer,{children:[(0,x.jsx)(W.Close,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,children:`Cancel`})}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:!O?.trim(),onClick:Oe,children:`Save view`})]})]})}),(0,x.jsx)(V,{padding:`none`,children:(0,x.jsx)(`div`,{className:`jobs-narrow`,children:l===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:8})}):(0,x.jsxs)(Y,{"aria-label":`Job matches`,density:`md`,stickyHeader:!0,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[pe(`score`,`Score`,{align:`end`,numeric:!0}),pe(`company`,`Company`),pe(`title`,`Role`),pe(`salaryMax`,`Pay`),(0,x.jsx)(Y.HeadCell,{children:`Location`}),pe(`posted`,`Posted`),(0,x.jsx)(Y.HeadCell,{children:`Status`})]})}),(0,x.jsxs)(Y.Body,{children:[l.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,selected:M===e.id,"data-posted":z_(e.source)||void 0,onClick:()=>N(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(`span`,{className:`num`,children:e.score})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[e.title,e.kind===`design-eng`&&(0,x.jsx)(`small`,{children:`design engineering`}),e.addedBy===`link`&&(0,x.jsx)(`small`,{children:`added by link`})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{tone:Qg[e.payBand],variant:e.payBand===`floor`?`solid`:`soft`,size:`sm`,children:e.salaryMax?Yg(e.salary):Zg[e.payBand]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`where`,children:[(0,x.jsx)(z,{tone:e.remote?`success`:`neutral`,variant:`soft`,size:`sm`,children:e.remote?`remote`:`on-site`}),(0,x.jsx)(`span`,{className:`clamp`,children:e.location})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted num`,children:Xg(e.posted)||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{tone:$g[e.status],size:`sm`,children:e.status})})]},e.id)),l.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:7,children:(0,x.jsx)(`span`,{className:`muted`,children:`Nothing matches these filters. Loosen one.`})})})]})]})})}),(0,x.jsxs)(`div`,{className:`pager`,children:[(0,x.jsxs)(`span`,{children:[d,` match`,d===1?``:`es`,`, page `,de+1,` of `,ue,ie&&(0,x.jsx)(`span`,{className:`muted`,children:` · on-site and hybrid hidden`})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:de===0,onClick:()=>c(de-1),children:`Previous`}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:de>=ue-1,onClick:()=>c(de+1),children:`Next`})]})]})]}),!I&&(0,x.jsx)(av,{id:M,nav:L,onClose:()=>N(null),onChanged:me})]})}function iv(e){return e.split(`
76
- `).map(e=>e.replace(/^-\s*/,``).trim()).filter(Boolean).map(e=>{let t=[...e.matchAll(/(?<![\w$])([+-]\d+)\b/g)].reduce((e,t)=>e+Number(t[1]),0),n=e.replace(/(?<![\w$])[+-]\d+\b/g,``).replace(/\(\s*[,\s]*/g,`(`).replace(/[,\s]*\)/g,`)`).replace(/\(\)/g,``).replace(/\s+,/g,`,`).replace(/\s{2,}/g,` `).replace(/\s+:/g,`:`).trim(),r=n.indexOf(`:`),i=(r>=0?n.slice(0,r):n).trim().replace(/[,:]$/,``),a=(r>=0?n.slice(r+1):``).trim();return{label:i.charAt(0).toUpperCase()+i.slice(1),detail:a,points:t}})}function av(e){return(0,x.jsx)(Sp,{open:e.id!==null,onOpenChange:t=>!t&&e.onClose(),side:`right`,size:`lg`,children:(0,x.jsx)(Sp.Content,{children:(0,x.jsx)(ov,{...e})})})}function ov({id:e,onClose:t,onChanged:n,nav:r,inline:i=!1}){let[a,o]=(0,b.useState)(null),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)(!1);(0,b.useEffect)(()=>{o(null),e&&$.job(e).then(o).catch(e=>X({title:`Could not open the note`,description:e.message,tone:`danger`}))},[e]);let d=async e=>{if(a){u(!0);try{let t=await $.setStatus(a.id,e);o(t),n(t),X({title:`${a.company}: ${e}`,description:`Written to the note's frontmatter and status log.`,tone:`success`})}catch(e){X({title:`Status not saved`,description:e.message,tone:`danger`})}u(!1)}},f=async()=>{if(a&&s.trim()){u(!0);try{let e=await $.addNote(a.id,s);o(e),c(``),X({title:`Note added`,tone:`success`})}catch(e){X({title:`Note not saved`,description:e.message,tone:`danger`})}u(!1)}},[p,m]=(0,b.useState)(null);(0,b.useEffect)(()=>{Promise.all([$.summary(),$.companies()]).then(([e,t])=>m({ceiling:e.ceiling,bar:e.minScore,boards:t.map(e=>({name:e.name,tier:e.tier,status:e.status}))})).catch(()=>{})},[]);let h=(0,b.useMemo)(()=>a?iv(a.sections.why):[],[a]),g=a&&p?.ceiling?Math.max(0,Math.min(100,Math.round(a.score/p.ceiling*100))):null,_=a&&p?p.boards.find(e=>e.name.toLowerCase()===a.company.toLowerCase()):null,v=a?a.sections.description.replace(/^>.*$/m,``).replace(/[#*_`>]/g,``).replace(/\s+/g,` `).trim().slice(0,320):``,y=async e=>{if(a){u(!0);try{let t=await $.setStatus(a.id,`passed`,e);o(t),n(t),X({title:`${a.company}: passed`,description:e,tone:`neutral`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}u(!1)}},S=r&&(0,x.jsxs)(`div`,{className:`sheet-nav`,children:[(0,x.jsx)(Bh,{content:`Previous (K)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Previous job`,leadingIcon:(0,x.jsx)(H.ChevronUp,{}),disabled:r.pos<=0,onClick:r.prev})}),(0,x.jsx)(Bh,{content:`Next (J)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Next job`,leadingIcon:(0,x.jsx)(H.ChevronDown,{}),disabled:r.pos<0?r.total===0:r.pos>=r.total-1,onClick:r.next})}),(0,x.jsx)(`span`,{className:`sheet-nav__count num`,children:r.pos>=0?`${r.pos+1} of ${r.total}`:`not in this view`}),i&&(0,x.jsx)(Bh,{content:`Close (Esc)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Close`,leadingIcon:(0,x.jsx)(H.Close,{}),onClick:t,className:`sheet-nav__close`})})]});return(0,x.jsx)(x.Fragment,{children:a?(0,x.jsxs)(`div`,{className:`detail`,children:[S,(0,x.jsxs)(`div`,{className:`sheet-head`,children:[(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[a.company,` · `,a.location||`location n/a`,` · `,z_(a.source)?`posted on TekJobs`:a.source,` · found `,Xg(a.found)||a.found]}),i?(0,x.jsx)(`h2`,{className:`sheet-head__title`,children:a.title}):(0,x.jsx)(Sp.Title,{children:a.title}),(0,x.jsxs)(`div`,{className:`chips`,children:[z_(a.source)&&(0,x.jsx)(B_,{label:`Posted on TekJobs`}),(0,x.jsx)(z,{tone:a.payBand===`floor`?`primary`:`neutral`,variant:`soft`,size:`sm`,children:(0,x.jsx)(`span`,{className:`num`,children:a.salaryMax?Yg(a.salary):`pay not stated`})}),a.salaryMax>0&&(0,x.jsx)(z,{tone:`neutral`,variant:`outline`,size:`sm`,children:Zg[a.payBand].toLowerCase()}),(0,x.jsx)(z,{tone:a.remote?`success`:`neutral`,variant:a.remote?`soft`:`outline`,size:`sm`,children:a.remote?`remote`:`on-site`}),(0,x.jsx)(z,{tone:$g[a.status],size:`sm`,children:a.status})]})]}),(0,x.jsxs)(`div`,{className:`sheet-head__side`,children:[(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[a.status===`new`&&(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:l,onClick:()=>d(`reviewing`),children:`Shortlist`}),(a.status===`new`||a.status===`reviewing`)&&(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:l,trailingIcon:(0,x.jsx)(H.ChevronDown,{}),children:`Pass`})}),(0,x.jsx)(Tu.Content,{align:`end`,children:Kg.map(e=>(0,x.jsx)(Tu.Item,{onSelect:()=>y(e),children:e},e))})]}),(0,x.jsx)(J,{size:`sm`,label:`Status`,value:a.status,onValueChange:e=>d(e),disabled:l,children:Gg.map(e=>(0,x.jsx)(J.Item,{value:e,children:e},e))})]}),(0,x.jsxs)(`div`,{className:`sheet-head__links`,children:[(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:a.url,target:`_blank`,rel:`noopener noreferrer`,children:`Open posting ↗`})}),(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:a.obsidianUrl,title:a.path,children:`Open in Obsidian ↗`})}),(0,x.jsx)(B,{variant:`link`,size:`sm`,tone:`neutral`,title:a.path,onClick:()=>$.revealJob(a.id).catch(e=>X({title:`Could not show the file`,description:e.message,tone:`danger`})),children:`Show file`}),(0,x.jsx)(H_,{job:a,onAttached:e=>{o(e),n(e)}})]})]})]}),(0,x.jsxs)(Z,{defaultValue:`why`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Job note sections`,children:[(0,x.jsx)(Z.Trigger,{value:`why`,children:`Match reasons`}),(0,x.jsx)(Z.Trigger,{value:`description`,children:`Description`}),(0,x.jsx)(Z.Trigger,{value:`application`,children:`Application packet`}),(0,x.jsx)(Z.Trigger,{value:`resume`,children:`Tailored resume`}),(0,x.jsx)(Z.Trigger,{value:`letter`,children:`Cover letter`}),(0,x.jsx)(Z.Trigger,{value:`people`,children:`People`}),(0,x.jsx)(Z.Trigger,{value:`notes`,children:`Notes`})]}),(0,x.jsx)(Z.Content,{value:`why`,children:(0,x.jsxs)(`div`,{className:`split`,children:[(0,x.jsxs)(`div`,{className:`reasons`,children:[(0,x.jsxs)(`div`,{className:`reasons__head`,children:[(0,x.jsxs)(`span`,{className:`muted`,children:[`Scored `,(0,x.jsx)(`span`,{className:`num`,children:a.score}),p?.ceiling?(0,x.jsxs)(x.Fragment,{children:[` of `,(0,x.jsx)(`span`,{className:`num`,children:p.ceiling}),` possible`]}):null,` with the active criteria`,p?.bar?(0,x.jsxs)(x.Fragment,{children:[` (bar `,(0,x.jsx)(`span`,{className:`num`,children:p.bar}),`)`]}):null,`.`]}),g!==null&&(0,x.jsxs)(`span`,{className:`reasons__fit num`,children:[g,(0,x.jsx)(`small`,{children:` fit`})]})]}),h.map((e,t)=>(0,x.jsxs)(`div`,{className:`reasons__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{children:e.label}),e.detail&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.detail})]}),(0,x.jsxs)(`span`,{className:`num reasons__pts${e.points<0?` reasons__pts--neg`:``}`,children:[e.points<0?`−`:`+`,Math.abs(e.points)]})]},t)),h.length===0&&(0,x.jsx)(`p`,{className:`muted`,children:`No match reasons recorded.`}),(0,x.jsxs)(`details`,{className:`reasons__log`,children:[(0,x.jsx)(`summary`,{children:`Status log`}),(0,x.jsx)(dg,{text:a.sections.log||`_Nothing yet._`})]})]}),(0,x.jsxs)(`aside`,{className:`split__aside`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`From the posting`}),(0,x.jsx)(`p`,{children:v?`${v}${a.sections.description.length>320?`…`:``}`:`The posting had no description text. Open the posting, or attach one.`})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Note`}),(0,x.jsxs)(`p`,{className:`num small`,children:[a.path.split(/[\\/]/).slice(-2).join(`/`),(0,x.jsx)(`br`,{}),`status: `,a.status,` · found `,a.found,a.addedBy===`scan`?``:` · added by ${a.addedBy}`]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Board`}),(0,x.jsx)(`p`,{children:_?`Tier ${_.tier} board, last fetch ${_.status||`not yet run`}.`:`${a.source}; not on the watchlist.`})]})]})]})}),(0,x.jsx)(Z.Content,{value:`description`,children:(0,x.jsx)(dg,{text:a.sections.description||`_The posting had no description text. Open the posting._`})}),(0,x.jsx)(Z.Content,{value:`application`,children:(0,x.jsx)(sv,{job:a,onStatus:d,busy:l})}),(0,x.jsx)(Z.Content,{value:`resume`,children:(0,x.jsx)(R_,{job:a})}),(0,x.jsx)(Z.Content,{value:`letter`,children:(0,x.jsx)(O_,{job:a})}),(0,x.jsx)(Z.Content,{value:`people`,children:(0,x.jsx)(F_,{job:a})}),(0,x.jsx)(Z.Content,{value:`notes`,children:(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(dg,{text:a.sections.notes||`_No notes yet._`}),(0,x.jsx)(Xp,{label:`Add a note`,rows:3,value:s,onChange:e=>c(e.target.value),placeholder:`Appended to the note with today's date.`}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:f,disabled:l||!s.trim(),children:`Save note`})})]})})]})]}):(0,x.jsxs)(`div`,{className:`detail`,children:[S,(0,x.jsx)(zg,{lines:6})]})})}function sv({job:e,onStatus:t,busy:n}){let[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)({}),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)([]),d=()=>$.packet(e.id).then(e=>{i(e),o(e.values)}).catch(e=>X({title:`Could not read the packet`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{d(),$.resumes().then(e=>u(e.files.map(e=>e.name))).catch(()=>{})},[e.id]);let f=async(t,n)=>{o(e=>({...e,[t]:n})),c(t);try{await $.saveApplication(e.id,t,n),await d(),X({title:`${t} saved`,description:n,tone:`success`})}catch(e){X({title:`${t} not saved`,description:e.message,tone:`danger`})}finally{c(``)}},p=async t=>{if(r&&a[t]!==r.values[t]){c(t);try{await $.saveApplication(e.id,t,a[t]??``),await d(),X({title:`${t} saved`,description:`Written into the note.`,tone:`success`})}catch(e){X({title:`${t} not saved`,description:e.message,tone:`danger`})}finally{c(``)}}};return r?(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`packet__state`,children:[(0,x.jsxs)(z,{tone:r.ready?`success`:`neutral`,variant:r.ready?`soft`:`outline`,children:[r.filled,` of `,r.total,` filled`]}),r.ready?(0,x.jsx)(`p`,{className:`muted`,children:`Every required field has something in it. Read it before you send it — this says the boxes are full, not that the application is good.`}):(0,x.jsxs)(`p`,{className:`muted`,children:[`Still required: `,r.missing.join(`, `),`.`]})]}),r.ready&&e.status!==`applied`&&(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[e.status!==`ready`&&(0,x.jsx)(B,{size:`sm`,tone:`primary`,variant:`soft`,disabled:n,onClick:()=>t(`ready`),children:`Mark ready for approval`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:n,onClick:()=>{window.confirm(`Only mark this applied if you have actually sent it to ${e.company}. Nothing here can send an application.`)&&t(`applied`)},children:`I have applied`})]}),r.fields.map(({field:e,hint:t,required:n})=>(0,x.jsxs)(`div`,{className:`packet__field`,children:[(0,x.jsx)(Xp,{label:n?`${e} *`:e,description:t,rows:e===`Tailored summary`||e===`Tailored bullets`||e===`Cover letter`||e===`Outreach message`||e===`Questions`||e===`Risks`?3:1,value:a[e]??``,onChange:t=>o({...a,[e]:t.target.value}),onBlur:()=>p(e),placeholder:n?`Required before this is ready.`:``}),e===`Resume variant`&&l.length>0&&(0,x.jsx)(`div`,{className:`chips`,children:l.map(t=>(0,x.jsx)(B,{size:`sm`,variant:a[e]===t?`soft`:`ghost`,tone:a[e]===t?`primary`:`neutral`,onClick:()=>f(e,t),children:t},t))}),s===e&&(0,x.jsx)(`span`,{className:`muted`,children:`Saving…`})]},e)),(0,x.jsx)(`p`,{className:`muted`,children:`Fields are written into the note's Application section as you leave each one. An agent fills the same fields through the TekJobs MCP server — see Agent access.`})]}):(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})})}var cv={confirmation:`success`,rejection:`danger`,advance:`primary`,scheduling:`primary`,"info-request":`warning`,outreach:`warning`,other:`neutral`},lv={confirmation:`confirmed`,rejection:`rejected`,advance:`advanced`,scheduling:`scheduling`,"info-request":`asks for more`,outreach:`reached out`,other:`other`};function uv(e,t){let n=e.suggestion;return t?n.action===`status`?`mark it ${n.status}${n.appliedOn?` as of ${n.appliedOn}`:``}`:`add the mail to the note${n.appliedOn?`, set Applied on if empty`:``}`:`create a note for ${e.company} and mark it ${n.status}`}function dv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(0);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(pv,{onOpen:t,onChanged:()=>r(e=>e+1)},n),(0,x.jsx)(av,{id:e,onClose:()=>t(null),onChanged:e=>{}})]})}function fv({onOpen:e}){let[t,n]=(0,b.useState)(null);(0,b.useEffect)(()=>{$.mail().then(n).catch(()=>{})},[]);let r=t?.groups.length??0;return!t||r===0&&!t.running?null:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`mailstrip`,children:[(0,x.jsxs)(`span`,{children:[t.running?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Bg,{size:`sm`}),` Reading the mailbox.`]}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`b`,{className:`num`,children:r}),` `,r===1?`email group waits`:`email groups wait`,` for a decision.`]}),t.lastRun&&(0,x.jsxs)(`span`,{className:`muted`,children:[` Last read `,(0,x.jsx)(`span`,{className:`num`,children:t.lastRun.slice(0,16).replace(`T`,` `)}),` UTC.`]})]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,leadingIcon:(0,x.jsx)(H.Mail,{}),onClick:e,children:`Open Mail`})]})})}function pv({onOpen:e,onChanged:t}){let[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)({}),[o,s]=(0,b.useState)(null),[c,l]=(0,b.useState)(null),u=()=>$.mail().then(r).catch(()=>{});(0,b.useEffect)(()=>{u()},[]),(0,b.useEffect)(()=>{if(!n?.running)return;let e=setInterval(()=>$.mail().then(e=>{r(e),!e.running&&e.error&&X({title:`Mail check failed`,description:e.error,tone:`danger`})}).catch(()=>{}),4e3);return()=>clearInterval(e)},[n?.running]);let d=async()=>{try{r(await $.mailCheck()),X({title:`Reading the mailbox`,description:`Through the local CLI, Gmail read tools only. A few minutes.`,tone:`neutral`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=async(e,n)=>{s(e.id);try{let a=e.id in i?i[e.id]:e.noteId;r(n===`confirm`?await $.mailConfirm(e.id,a||void 0):await $.mailDismiss(e.id)),n===`confirm`&&(X({title:`${e.company}: ${uv(e,i[e.id]||e.noteId)}`,description:`Written to the note.`,tone:`success`}),t())}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{s(null)}},p=n?.groups??[],m=(n?.items??[]).filter(e=>e.state!==`pending`).sort((e,t)=>(t.resolved?.at??``).localeCompare(e.resolved?.at??``)),h=m.length,[g,_]=(0,b.useState)(!1),v=e=>e.state===`dismissed`?`dismissed`:e.resolved?.action===`create`?`note created, marked ${e.resolved.status}`:e.resolved?.action===`status`?`marked ${e.resolved.status}`:`recorded on the note`,y=p.filter(e=>e.kind===`confirmation`&&e.match===`exact`&&e.noteId).length;return(0,x.jsxs)(`section`,{className:`today__section`,id:`mail-says`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Mail says`}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[n?.lastRun&&(0,x.jsxs)(`span`,{className:`muted`,children:[`last read `,n.lastRun.slice(0,16).replace(`T`,` `),` UTC, `,n.lastSinceDays,` days back`]}),h>0&&(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:()=>_(e=>!e),children:g?`Hide handled`:`${h} handled`}),y>0&&(0,x.jsxs)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:o===`safe`||!!n?.running,loading:o===`safe`,title:`Confirmations whose note matched by exact title: records the mail, marks still-open notes applied as of the mail's date. Rejections, interviews, company-only matches and creates stay one at a time.`,onClick:async()=>{s(`safe`);try{let e=await $.mailConfirmSafe();r(e),X({title:`${e.confirmed} confirmations recorded`,description:`Exact-title matches only. The rest are still listed.`,tone:`success`}),t()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{s(null)}},children:[`Confirm the exact matches (`,y,`)`]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:!!n?.running,leadingIcon:n?.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Mail,{}),onClick:d,children:n?.running?`Reading the mailbox`:`Check mail`})]})]}),!n||p.length===0&&!n.running?(0,x.jsx)(V,{padding:`md`,children:(0,x.jsx)(Vg,{size:`sm`,title:n?.lastRun?`Nothing waiting from the mailbox`:`The mailbox has not been read yet`,description:n?.error?n.error:`The morning task reads application emails through your signed-in CLI (Gmail read tools only) and lists what they say about your applications here. You confirm each one. Check mail reads again now.`})}):(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Application emails waiting for a decision`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Date`}),(0,x.jsx)(Y.HeadCell,{children:`Mail says`}),(0,x.jsx)(Y.HeadCell,{children:`Company and role`}),(0,x.jsx)(Y.HeadCell,{children:`Note`}),(0,x.jsx)(Y.HeadCell,{children:`Confirm`})]})}),(0,x.jsxs)(Y.Body,{children:[p.map(t=>{let r=i[t.id]||t.noteId;return(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>l(t),children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:t.date||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[(0,x.jsxs)(`span`,{className:`chips`,children:[t.kinds.map(e=>(0,x.jsx)(z,{size:`sm`,tone:cv[e],children:lv[e]},e)),t.count>1&&(0,x.jsxs)(`small`,{children:[t.count,` emails`,t.first&&t.first!==t.date?`, ${t.first} to ${t.date}`:``]})]}),(0,x.jsx)(`small`,{title:t.subject,children:t.gist})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[t.company,(0,x.jsx)(`small`,{children:t.role||`role not stated`}),t.person&&(0,x.jsxs)(`small`,{title:`${t.person.email}. Confirming adds them to People and to the note.`,children:[`from `,t.person.name]})]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:t.match===`none`?(0,x.jsx)(`span`,{className:`muted`,children:`no note; confirm creates one`}):t.match===`exact`||t.match===`company`&&t.candidates.length<=1?(0,x.jsxs)(`span`,{className:`who__text`,children:[(0,x.jsxs)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>e(t.noteId),children:[t.noteTitle,` · `,t.noteStatus]}),n.items.find(e=>e.id===t.id)?.via===`link`&&(0,x.jsx)(`small`,{children:`matched by the posting link`})]}):(0,x.jsxs)(J,{size:`sm`,label:t.match===`company-other-role`?`Not a role in the vault`:`Which role`,value:r||`__new__`,onValueChange:e=>a(n=>({...n,[t.id]:e===`__new__`?``:e})),children:[(0,x.jsx)(J.Item,{value:`__new__`,children:`New note for this role`}),t.candidates.map(e=>(0,x.jsxs)(J.Item,{value:e.id,children:[e.title,` · `,e.status]},e.id))]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:(0,x.jsxs)(`div`,{className:`today__actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:o===t.id,title:uv(t,r),onClick:()=>f(t,`confirm`),children:r?t.suggestion.action===`record`?`Record`:`Mark ${t.suggestion.status}`:`Create and mark`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,disabled:o===t.id,onClick:()=>f(t,`dismiss`),children:`Dismiss`})]})})]},t.id)}),n.running&&p.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:5,children:(0,x.jsx)(`span`,{className:`muted`,children:`Reading…`})})})]})]})}),g&&(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Application emails already handled`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Mail date`}),(0,x.jsx)(Y.HeadCell,{children:`Mail said`}),(0,x.jsx)(Y.HeadCell,{children:`Company and role`}),(0,x.jsx)(Y.HeadCell,{children:`Note`}),(0,x.jsx)(Y.HeadCell,{children:`What was done`})]})}),(0,x.jsx)(Y.Body,{children:m.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>l(mv(t)),children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:t.date||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:cv[t.kind],children:lv[t.kind]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[t.company,(0,x.jsx)(`small`,{children:t.role||`role not stated`})]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:t.noteId?(0,x.jsx)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>e(t.noteId),children:t.noteId.replace(/ \([0-9a-f]+\)$/,``)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`muted`,children:[v(t),t.resolved?.at?`, ${t.resolved.at.slice(0,16).replace(`T`,` `)} UTC`:``]})})]},t.id))})]})}),(0,x.jsx)(hv,{group:c,items:n?.items??[],busy:o,onClose:()=>l(null),onOpenNote:e,onAct:async(e,t)=>{await f(e,t),l(null)}})]})}function mv(e){return{id:e.id,ids:[e.id],count:1,company:e.company,role:e.role,kind:e.kind,kinds:[e.kind],date:e.date,first:e.date,gist:e.gist,subject:e.subject,from:e.from,link:e.link,person:e.person??null,match:e.match,noteId:e.noteId,noteTitle:e.noteTitle,noteStatus:e.noteStatus,candidates:e.candidates,suggestion:e.suggestion}}function hv({group:e,items:t,busy:n,onClose:r,onOpenNote:i,onAct:a}){let o=e?t.filter(t=>e.ids.includes(t.id)).sort((e,t)=>(t.date||``).localeCompare(e.date||``)):[],s=o.some(e=>e.state===`pending`);return(0,x.jsx)(Sp,{open:e!==null,onOpenChange:e=>!e&&r(),side:`right`,size:`md`,children:(0,x.jsx)(Sp.Content,{children:e&&(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(`div`,{className:`sheet-head`,children:(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[e.company,e.role?` · ${e.role}`:``]}),(0,x.jsx)(Sp.Title,{children:e.subject||e.gist}),(0,x.jsxs)(`div`,{className:`chips`,children:[e.kinds.map(e=>(0,x.jsx)(z,{size:`sm`,tone:cv[e],children:lv[e]},e)),e.date&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:e.date})}),e.count>1&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[e.count,` emails`]})]})]})}),(0,x.jsx)(`p`,{children:e.gist}),(0,x.jsxs)(`dl`,{className:`mailsheet__facts`,children:[(0,x.jsx)(`dt`,{children:`From`}),(0,x.jsx)(`dd`,{children:e.person?`${e.person.name}${e.person.email?` <${e.person.email}>`:``}`:e.from}),(0,x.jsx)(`dt`,{children:`Note`}),(0,x.jsx)(`dd`,{children:e.noteId?(0,x.jsxs)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>i(e.noteId),children:[e.noteTitle||e.noteId,` · `,e.noteStatus]}):(0,x.jsx)(`span`,{className:`muted`,children:`none yet; confirming creates one`})}),s&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`dt`,{children:`Confirming`}),(0,x.jsx)(`dd`,{children:uv(e,e.noteId)})]})]}),(0,x.jsx)(`h4`,{className:`connections__title`,children:o.length===1?`The email`:`The ${o.length} emails`}),(0,x.jsx)(`ul`,{className:`people__list`,children:o.map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.subject||e.gist}),(0,x.jsxs)(`div`,{className:`reasons__detail`,children:[[e.date,lv[e.kind],e.fromName||e.from].filter(Boolean).join(` · `),e.gist&&e.subject?` · ${e.gist}`:``]})]}),(0,x.jsx)(`div`,{className:`pager__buttons`,children:(0,x.jsx)(B,{asChild:!0,size:`sm`,variant:`ghost`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:e.link,target:`_blank`,rel:`noreferrer`,children:`Open in Gmail ↗`})})})]},e.id))}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{asChild:!0,variant:`soft`,children:(0,x.jsx)(`a`,{href:e.link,target:`_blank`,rel:`noreferrer`,children:`Open in Gmail ↗`})}),s&&(0,x.jsx)(B,{tone:`primary`,disabled:n===e.id,onClick:()=>a(e,`confirm`),children:e.noteId?e.suggestion.action===`record`?`Record`:`Mark ${e.suggestion.status}`:`Create and mark`}),s&&(0,x.jsx)(B,{variant:`ghost`,disabled:n===e.id,onClick:()=>a(e,`dismiss`),children:`Dismiss`})]})]})})})}var gv=`Use the tekjobs MCP server. Call onboarding_status, then onboarding_materials, and follow its script: interview me, write my profile with save_profile, set the criteria with set_criteria, run a dry scan, and show me the top matches.`;function _v({onDone:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(!1),s=()=>$.onboarding().then(n).catch(e=>X({title:`Server not answering`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{s()},[]);let c=async()=>{o(!0);try{let e=await $.initProfile();X({title:`Profile folder ready`,description:e.made.length?`Created ${e.made.join(`, `)}`:`It already existed; nothing was overwritten.`,tone:`success`}),await s()}catch(e){X({title:`Could not create the folder`,description:e.message,tone:`danger`})}o(!1)},l=async()=>{if(r.trim()){o(!0);try{X({title:`Resume imported`,description:`${(await $.importResume(r.trim())).chars.toLocaleString()} characters of text extracted.`,tone:`success`}),i(``),await s()}catch(e){X({title:`Import failed`,description:e.message,tone:`danger`})}o(!1)}};if(!t)return(0,x.jsx)(zg,{variant:`rect`,height:`20rem`});let u=t.steps.filter(e=>e.done).length;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Five steps from an empty folder to a daily scan that knows who you are. Your profile lives at `,(0,x.jsx)(`code`,{children:t.dir}),`. The scan and the notes stay on this machine; the interview and the drafting send what you choose to the AI client you connect.`]})}),(0,x.jsxs)(z,{tone:t.complete?`success`:`primary`,size:`sm`,children:[u,` of `,t.steps.length,` done`]})]}),(0,x.jsx)(`div`,{className:`steps`,children:t.steps.map((e,t)=>(0,x.jsx)(V,{padding:`md`,variant:e.done?`sunken`:`outlined`,children:(0,x.jsxs)(`div`,{className:`step`,children:[(0,x.jsx)(`div`,{className:`step__mark`,children:e.done?(0,x.jsx)(H.Success,{}):(0,x.jsx)(`span`,{className:`step__n`,children:t+1})}),(0,x.jsxs)(`div`,{className:`step__body`,children:[(0,x.jsx)(`span`,{className:`step__label`,children:e.label}),!e.done&&(0,x.jsx)(`p`,{className:`muted`,children:e.how}),!e.done&&e.id===`folder`&&(0,x.jsx)(`div`,{className:`form__actions form__actions--start`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:a,onClick:c,children:`Create the profile folder`})}),!e.done&&e.id===`resume`&&(0,x.jsxs)(`div`,{className:`step__row`,children:[(0,x.jsx)(Zp,{size:`sm`,label:`Path to your resume`,placeholder:`C:\\Users\\you\\Downloads\\resume.pdf`,description:`PDF, DOCX, Markdown or text. The file is copied into Profile/ and its text extracted.`,value:r,onChange:e=>i(e.target.value)}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:a,disabled:!r.trim(),onClick:l,children:`Import`})]}),!e.done&&e.id===`profile`&&(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(`p`,{className:`muted`,children:`The interview runs in your own LLM, not here. Open Claude Code in the app folder (its .mcp.json connects it) and paste:`}),(0,x.jsx)(ag,{code:gv,language:`text`,wrap:!0}),(0,x.jsx)(`p`,{className:`muted`,children:`Codex, Cursor or Claude Desktop work the same way once the tekjobs MCP server is added; see Agent access.`})]}),!e.done&&e.id===`scan`&&(0,x.jsx)(`div`,{className:`form__actions form__actions--start`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:()=>{$.startScan(!1).then(()=>X({title:`Scan started`,description:`Watch it on the Runs screen.`,tone:`success`})).catch(e=>X({title:`Could not start`,description:e.message,tone:`danger`}))},children:`Run the first scan`})})]})]})},e.id))}),t.complete&&(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,onClick:e,trailingIcon:(0,x.jsx)(H.ArrowRight,{}),children:`Go to the overview`})})]})}function vv({label:e,value:t,hint:n,tone:r=`neutral`,series:i,onClick:a}){return(0,x.jsx)(V,{padding:`md`,interactive:!!a,onClick:a,children:(0,x.jsxs)(`div`,{className:`stat`,children:[(0,x.jsx)(`span`,{className:`stat__label`,children:e}),(0,x.jsxs)(`div`,{className:`stat__row`,children:[(0,x.jsx)(`span`,{className:`stat__value`,children:t}),i&&i.length>1&&(0,x.jsx)(`div`,{className:`stat__spark`,children:(0,x.jsx)(Cp,{values:i,tone:r===`neutral`?`primary`:r,"aria-label":`${e}, per scan`})})]}),n&&(0,x.jsx)(`div`,{className:`stat__delta`,children:(0,x.jsx)(z,{tone:r,size:`sm`,children:n})})]})})}var yv=e=>e===null?`—`:`${Math.round(e*100)}%`,bv={found:`Found`,reviewed:`Reviewed`,shortlisted:`Shortlisted`,applied:`Applied`,interviewing:`Interviewing`,offer:`Offer`},xv={"design-eng":`Design engineering`,adjacent:`Adjacent titles`};function Sv({onNavigate:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(``);if((0,b.useEffect)(()=>{$.summary().then(n).catch(e=>o(e.message)),$.outcomes().then(i).catch(()=>{})},[]),a)return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`p`,{className:`muted`,children:[`The server is not answering: `,a,`. Start it with `,(0,x.jsx)(`code`,{children:`npm run server`}),`.`]})});if(!t||!r)return(0,x.jsx)(zg,{variant:`rect`,height:`12rem`});let s=[`floor`,`stretch`,`below`,`unknown`],c=[`new`,`reviewing`,`applying`,`applied`,`interviewing`,`offer`,`rejected`,`passed`],l=r.waiting.buckets[14]??0,u=r.thisWeek.followUps.filter(e=>e.inDays<=0).length,d=r.appliedPerWeek;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`b`,{children:r.funnel.applied}),` applied, `,(0,x.jsx)(`b`,{children:yv(r.responseRate)}),` answered, `,(0,x.jsx)(`b`,{children:r.funnel.interviewing}),` interviewing`,l?(0,x.jsxs)(x.Fragment,{children:[`, `,(0,x.jsx)(`b`,{children:l}),` waiting two weeks or more`]}):null,`.`,` `,`The inventory: `,t.open,` open matches across `,t.companies,` boards, floor `,t.floor?Jg(t.floor):`unset`,`, bar `,t.minScore??`unset`,`.`]})}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:()=>e(`runs`),children:`Runs`})]}),(0,x.jsxs)(`div`,{className:`stats z-stagger`,children:[(0,x.jsx)(vv,{label:`Applied`,value:String(r.funnel.applied),hint:`${r.funnel.shortlisted} shortlisted, ${r.funnel.reviewed} reviewed`,tone:`primary`,onClick:()=>e(`pipeline`)}),(0,x.jsx)(vv,{label:`Response rate`,value:yv(r.responseRate),hint:r.funnel.applied?`${r.responded} of ${r.funnel.applied} answered, interview or no`:`nothing applied to yet`,tone:r.responseRate&&r.responseRate>0?`success`:`neutral`}),(0,x.jsx)(vv,{label:`Waiting 14 days or more`,value:String(l),hint:`${r.waiting.buckets[7]??0} past 7 days, ${r.waiting.buckets[21]??0} past 21`,tone:(r.waiting.buckets[21]??0)>0?`warning`:`neutral`}),(0,x.jsx)(vv,{label:`Discovery to application`,value:r.medianDaysToApply===null?`—`:`${r.medianDaysToApply}d`,hint:`median, found to applied`})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Funnel`}),(0,x.jsx)(`p`,{children:`Each stage counts everything that reached it, whatever happened after. The rate is the share of the stage before.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Application funnel`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Stage`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Jobs`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Of the stage before`}),(0,x.jsx)(Y.HeadCell,{children:`Share`})]})}),(0,x.jsx)(Y.Body,{children:r.stages.map((e,t)=>{let n=r.stages[0]?.count||1;return(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:bv[e.stage]??e.stage}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.count}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(`span`,{className:e.rate===null?`muted`:``,children:t===0?`—`:yv(e.rate)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`div`,{className:`funnel__bar`,role:`presentation`,children:(0,x.jsx)(`span`,{style:{width:`${Math.max(e.count?2:0,Math.round(e.count/n*100))}%`}})})})]},e.stage)})})]}),(0,x.jsxs)(`p`,{className:`muted panel--pad`,children:[r.passed,` passed on, `,r.rejected,` rejected.`]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`This week`}),(0,x.jsxs)(`p`,{children:[`Follow-ups due in the next seven days`,u?`, ${u} already past`:``,`, and the interviews in progress. Dates come from each note's packet.`]})]})})}),(0,x.jsxs)(Y,{"aria-label":`This week`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{align:`end`,children:`When`})]})}),(0,x.jsxs)(Y.Body,{children:[r.thisWeek.followUps.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>e(`jobs`,t.company),children:[(0,x.jsx)(Y.Cell,{children:t.company}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`clamp`,children:t.title})}),(0,x.jsx)(Y.Cell,{align:`end`,children:(0,x.jsx)(z,{size:`sm`,tone:t.inDays<0?`danger`:t.inDays===0?`warning`:`neutral`,children:t.inDays<0?`follow up, ${-t.inDays}d late`:t.inDays===0?`follow up today`:`follow up in ${t.inDays}d`})})]},t.id)),r.thisWeek.interviewing.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>e(`jobs`,t.company),children:[(0,x.jsx)(Y.Cell,{children:t.company}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`clamp`,children:t.title})}),(0,x.jsx)(Y.Cell,{align:`end`,children:(0,x.jsx)(z,{size:`sm`,tone:`primary`,children:`interviewing`})})]},t.id)),r.thisWeek.followUps.length===0&&r.thisWeek.interviewing.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:3,children:(0,x.jsx)(`span`,{className:`muted`,children:`Nothing due this week. Applied roles get a follow-up date in their packet when you mark them applied.`})})})]})]})]})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Applications per week`}),(0,x.jsx)(`p`,{children:`Sent, by the week of the packet's Applied on date.`})]})}),d.length>0?(0,x.jsx)(Ye,{series:[{name:`Applied`,values:d.map(e=>e.n)}],labels:d.map(e=>e.week.slice(5)),height:180,"aria-label":`Applications per week`}):(0,x.jsx)(`p`,{className:`muted`,children:`Nothing applied to yet.`})]})}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`What answers`}),(0,x.jsx)(`p`,{children:`By role family, then by the board that surfaced the job.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Outcomes by role family`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Role family`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Found`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Applied`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Answered`})]})}),(0,x.jsx)(Y.Body,{children:r.byKind.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:xv[e.kind]??e.kind}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.found}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.applied}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.applied?`${e.responded} (${yv(e.responded/e.applied)})`:`—`})]},e.kind))})]}),r.bySource.length>0&&(0,x.jsx)(`div`,{className:`chips panel--pad`,children:r.bySource.map(e=>(0,x.jsxs)(z,{size:`sm`,tone:e.responded?`success`:`neutral`,variant:`soft`,children:[e.source,`: `,e.applied,` applied`,e.responded?`, ${e.responded} answered`:``]},e.source))})]})]}),(0,x.jsxs)(`div`,{className:`stats z-stagger`,children:[(0,x.jsx)(vv,{label:`Open matches`,value:String(t.open),hint:`${t.byStatus.new??0} unreviewed`,onClick:()=>e(`jobs`)}),(0,x.jsx)(vv,{label:`Design-engineer roles at the floor`,value:String(t.designEng.floor),hint:`of ${t.designEng.total} with the title`,tone:`success`,onClick:()=>e(`jobs`)}),(0,x.jsx)(vv,{label:`Pay under the floor, above the stretch line`,value:String(t.byBand.stretch??0),hint:`${t.designEng.stretch} design-engineer`,tone:`warning`}),(0,x.jsx)(vv,{label:`Active applications`,value:String(t.active),hint:t.active?`in flight`:`none yet`,tone:t.active?`primary`:`neutral`,onClick:()=>e(`pipeline`)})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Pipeline`}),(0,x.jsx)(`p`,{children:`Every open note by status. Change a status in Jobs or Pipeline; the note is the record.`})]})}),(0,x.jsx)(Ye,{series:[{name:`Jobs`,values:c.map(e=>t.byStatus[e]??0)}],labels:[...c],height:200,"aria-label":`Jobs by status`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Stated pay against the floor`}),(0,x.jsx)(`p`,{children:`Open matches by band.`})]})}),(0,x.jsx)(Ye,{series:[{name:`Matches`,values:s.map(e=>t.byBand[e]??0)}],labels:[`Floor`,`Stretch`,`Below`,`Not stated`],height:200,"aria-label":`Matches by pay band`})]})})]})]})}function Cv({onNavigate:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(null),[s,c]=(0,b.useState)(null),l=()=>$.today().then(n).catch(e=>i(e.message));(0,b.useEffect)(()=>{l()},[]);let u=async(e,t,n)=>{c(e.id);try{await $.setStatus(e.id,t,n),X({title:`${e.company}: ${t===`reviewing`?`shortlisted`:`passed`}`,description:n,tone:t===`reviewing`?`success`:`neutral`}),await l()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{c(null)}};if(r)return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`p`,{className:`muted`,children:[`The server is not answering: `,r,`. Start it with `,(0,x.jsx)(`code`,{children:`npm run server`}),`.`]})});if(!t)return(0,x.jsx)(zg,{variant:`rect`,height:`18rem`});let{counts:d,sections:f}=t,p=[...f.preparing,...f.followUps,...f.interviewing];return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h1`,{className:`today__date`,children:new Date().toLocaleDateString(`en-US`,{weekday:`long`,day:`numeric`,month:`long`})}),(0,x.jsx)(`p`,{children:f.triage.length===0?`Today's queue is clear. The next scan refills it.`:`${f.triage.length===1?`One`:f.triage.length} to decide on, best fit first. The other ${d.unreviewed-f.triage.length} unreviewed wait in Jobs and do not count against you. Fit is the share of the ${t.ceiling} points this criteria set can award.`})]}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:()=>e(`jobs`),children:`See all matches`})]}),(0,x.jsxs)(`div`,{className:`today__figures`,children:[(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{children:d.open}),(0,x.jsx)(`small`,{children:`open`})]}),(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{children:d.aging}),(0,x.jsx)(`small`,{children:`waiting 2d+`})]}),(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{"data-tone":d.closedUnreviewed>0?`danger`:void 0,children:d.closedUnreviewed}),(0,x.jsx)(`small`,{children:`closed unseen`})]})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsxs)(`div`,{className:`today__section-head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Decide on these`}),(0,x.jsx)(`span`,{className:`today__hint`,children:`shortlist · pass · open sheet`})]}),f.triage.length===0?(0,x.jsx)(V,{padding:`md`,children:(0,x.jsx)(Vg,{size:`sm`,title:`Inbox clear`,description:`Nothing unreviewed is open right now. The next scan will refill this.`})}):(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Matches to decide on`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Pay`}),(0,x.jsx)(Y.HeadCell,{children:`Found`}),(0,x.jsx)(Y.HeadCell,{children:`Decide`})]})}),(0,x.jsx)(Y.Body,{children:f.triage.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,selected:a===e.id,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[e.title,e.kind===`design-eng`&&(0,x.jsx)(`small`,{children:`design engineering`})]})}),(0,x.jsx)(Y.Cell,{children:e.salaryMax>0?(0,x.jsx)(z,{tone:Qg[e.payBand],size:`sm`,children:Yg(e.salary)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:Xg(e.found)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`today__actions`,onClick:e=>e.stopPropagation(),children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:s===e.id,onClick:()=>u(e,`reviewing`),children:`Shortlist`}),(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,disabled:s===e.id,trailingIcon:(0,x.jsx)(H.ChevronDown,{}),children:`Pass`})}),(0,x.jsx)(Tu.Content,{align:`end`,children:Kg.map(t=>(0,x.jsx)(Tu.Item,{onSelect:()=>u(e,`passed`,t),children:t},t))})]})]})})]},e.id))})]})})]}),(0,x.jsx)(fv,{onOpen:()=>e(`mail`)}),f.started.length>0&&(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Already started`}),(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Applications with a packet started`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Packet`}),(0,x.jsx)(Y.HeadCell,{children:`Pay`}),(0,x.jsx)(Y.HeadCell,{children:`Status`})]})}),(0,x.jsx)(Y.Body,{children:f.started.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,selected:a===e.id,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(z,{size:`sm`,tone:`primary`,variant:`soft`,children:[e.packet,` filled`]})}),(0,x.jsx)(Y.Cell,{children:e.salaryMax>0?(0,x.jsx)(z,{tone:Qg[e.payBand],size:`sm`,children:Yg(e.salary)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:e.closed?(0,x.jsxs)(z,{size:`sm`,tone:`danger`,children:[`closed `,e.closed]}):(0,x.jsx)(z,{size:`sm`,tone:e.status===`ready`?`warning`:`neutral`,children:e.status})})]},e.id))})]})}),(0,x.jsx)(`p`,{className:`muted`,children:`Work you have already put in, wherever it ranks. The fit score knows nothing about a drafted packet, so these would otherwise fall off the bottom of the queue.`})]}),(f.aging.length>0||f.missed.length>0)&&(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Going, and gone`}),(0,x.jsxs)(`div`,{className:`today__cols`,children:[f.aging.length>0&&(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsx)(`h3`,{className:`today__subheading`,children:`Still open, still unread`}),(0,x.jsx)(`p`,{className:`muted`,children:`Listings here close after two days, at the median.`}),(0,x.jsx)(`ul`,{className:`today__list`,children:f.aging.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsxs)(B,{className:`today__row`,variant:`ghost`,align:`start`,size:`sm`,onClick:()=>o(e.id),children:[(0,x.jsx)(Ev,{value:e.fit}),(0,x.jsx)(`span`,{className:`today__row-text`,children:wv(e.company,e.title,52)}),(0,x.jsxs)(z,{size:`sm`,tone:(e.days??0)>=5?`danger`:`warning`,variant:`outline`,children:[e.days,`d`]})]})},e.id))})]}),f.missed.length>0&&(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsx)(`h3`,{className:`today__subheading`,children:`Closed before you saw them`}),(0,x.jsxs)(`p`,{className:`muted`,children:[d.closedUnreviewed,` this week. This is what the queue costs when it is skipped.`]}),(0,x.jsx)(`ul`,{className:`today__list`,children:f.missed.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsxs)(B,{className:`today__row`,variant:`ghost`,align:`start`,size:`sm`,onClick:()=>o(e.id),children:[(0,x.jsx)(Ev,{value:e.fit}),(0,x.jsx)(`span`,{className:`today__row-text`,children:wv(e.company,e.title,36)}),(0,x.jsx)(`span`,{className:`muted`,children:e.closed})]})},e.id))})]})]})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`In flight`}),(0,x.jsx)(V,{padding:p.length?`none`:`md`,children:p.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`Nothing in flight`,description:`Applications being prepared, follow-ups that are due, and interviews appear here once jobs move past Shortlisted.`,action:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:()=>e(`pipeline`),children:`Open the pipeline`})}):(0,x.jsxs)(Y,{"aria-label":`In flight`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Status`}),(0,x.jsx)(Y.HeadCell,{children:`Due`}),(0,x.jsx)(Y.HeadCell,{children:`Write to`})]})}),(0,x.jsx)(Y.Body,{children:p.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:`primary`,children:e.status})}),(0,x.jsx)(Y.Cell,{children:e.due||(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(Tv,{contact:e.contact})})]},e.id))})]})})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsxs)(`div`,{className:`today__section-head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Waiting on a reply`}),(0,x.jsxs)(`span`,{className:`today__hint`,children:[`applied `,d.waitingDays,`d+ ago, nothing back · `,d.waiting,` in all`]})]}),(0,x.jsx)(V,{padding:f.waiting.length===0?`md`:`none`,children:f.waiting.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`Nothing has gone quiet`,description:`Applications with no answer after ${d.waitingDays} days land here, with the person to ask.`}):(0,x.jsxs)(Y,{"aria-label":`Applications waiting on a reply`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Days`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Applied`}),(0,x.jsx)(Y.HeadCell,{children:`Write to`})]})}),(0,x.jsx)(Y.Body,{children:f.waiting.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(`span`,{className:`num`,"data-tone":(e.days??0)>=21?`danger`:void 0,children:e.days})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.appliedOn})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(Tv,{contact:e.contact})})]},e.id))})]})})]}),(0,x.jsx)(av,{id:a,onClose:()=>o(null),onChanged:e=>{l()}})]})}var wv=(e,t,n=64)=>{let r=`${e} — ${t}`.replace(/\s+/g,` `).trim();return r.length>n?`${r.slice(0,n-1).trimEnd()}…`:r};function Tv({contact:e}){return e?(0,x.jsxs)(`span`,{className:`who__text`,children:[e.email?(0,x.jsxs)(`a`,{className:`people__thread`,href:`mailto:${e.email}`,onClick:e=>e.stopPropagation(),children:[e.name,` ↗`]}):e.name,(0,x.jsxs)(`small`,{children:[e.role||`contact`,e.others>0?` · +${e.others}`:``]})]}):(0,x.jsx)(`span`,{className:`muted`,title:`Open the sheet's People tab to add someone.`,children:`no one on the thread`})}function Ev({value:e}){return(0,x.jsx)(z,{size:`sm`,tone:e>=80?`success`:e>=60?`primary`:`neutral`,variant:e>=60?`soft`:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:e})})}var Dv=[{id:`reviewing`,title:`Reviewing`},{id:`applying`,title:`Applying`,limit:5},{id:`ready`,title:`Ready`,limit:5},{id:`applied`,title:`Applied`},{id:`interviewing`,title:`Interviewing`},{id:`offer`,title:`Offer`}],Ov=new Set(Dv.map(e=>e.id));function kv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)([]),o=()=>$.jobs({status:`all`,limit:2e3}).then(e=>t(e.rows)).catch(e=>X({title:`Could not load the board`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{o()},[]);let s=async(n,r)=>{let i=e?.find(e=>e.id===n);if(i&&i.status!==r){t(e=>e&&e.map(e=>e.id===n?{...e,status:r}:e));try{await $.setStatus(n,r),X({title:`${i.company}: ${r}`,tone:`success`})}catch(e){X({title:`Move not saved`,description:e.message,tone:`danger`}),o()}}},c=e=>t(t=>t&&t.map(t=>t.id===e.id?{...t,status:e.status}:t)),l=(0,b.useMemo)(()=>{let t=new Map;for(let n of e??[])Ov.has(n.status)&&t.set(n.company,(t.get(n.company)??0)+1);return[...t.entries()].sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).map(([e,t])=>({value:e,label:e,hint:`${t} on the board`}))},[e]);if(!e)return(0,x.jsx)(zg,{variant:`rect`,height:`20rem`});let u=new Set(i),d=e.filter(e=>Ov.has(e.status)&&(u.size===0||u.has(e.company))).sort((e,t)=>t.score-e.score),f=e.filter(e=>e.status===`new`).length,p=e.filter(e=>e.status===`rejected`||e.status===`passed`).length;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Committed work only. Drag a card, or focus one and press Space to lift it, arrows to move it, Enter to drop. Every move is written to the job note.`,f?` ${f} new matches wait on Today, not here.`:``,p?` ${p} closed are not shown.`:``]})})}),(0,x.jsx)(`div`,{className:`toolbar`,children:(0,x.jsx)(Wg,{className:`toolbar__filter toolbar__filter--wide`,size:`sm`,multiple:!0,label:`Companies`,placeholder:i.length?``:`All companies`,description:`Narrow the board to the companies you are actually working.`,emptyMessage:`No company on the board matches that.`,options:l,value:i,onValueChange:a})}),(0,x.jsx)(Hg,{label:`Job pipeline`,columns:Dv,cards:d,cardId:e=>e.id,cardColumn:e=>e.status,cardLabel:e=>`${e.title} at ${e.company}`,onMove:e=>s(e.cardId,e.to),renderCard:e=>(0,x.jsxs)(`div`,{className:`kcard`,"data-posted":z_(e.source)||void 0,onClick:()=>r(e.id),children:[(0,x.jsxs)(`div`,{className:`kcard__head`,children:[(0,x.jsxs)(`span`,{className:`kcard__company posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]}),(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,"aria-label":`Move ${e.title}`,leadingIcon:(0,x.jsx)(H.More,{}),onClick:e=>e.stopPropagation()})}),(0,x.jsx)(Tu.Content,{align:`end`,onClick:e=>e.stopPropagation(),children:Gg.filter(t=>t!==e.status).map(t=>(0,x.jsxs)(Tu.Item,{onSelect:()=>s(e.id,t),children:[`Move to `,t]},t))})]})]}),(0,x.jsx)(`span`,{className:`kcard__title`,children:e.title}),(0,x.jsxs)(`div`,{className:`kcard__meta num`,children:[(0,x.jsx)(`span`,{className:`kcard__score`,children:e.score}),e.salaryMax>0&&(0,x.jsx)(`span`,{className:e.payBand===`floor`?`kcard__pay kcard__pay--floor`:`kcard__pay`,children:Yg(e.salary)})]})]})}),(0,x.jsx)(av,{id:n,onClose:()=>r(null),onChanged:c})]})}var Av={ok:`success`,warn:`warning`,missing:`danger`,info:`neutral`};function jv({s:e}){return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:e.basics.name||`No name yet`}),(0,x.jsx)(`p`,{children:[e.basics.currentRole,e.basics.location].filter(Boolean).join(` · `)||`The Basics section is empty.`})]}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsx)(z,{size:`sm`,tone:e.status===`draft`?`warning`:`success`,children:e.status===`draft`?`draft`:`reviewed`}),e.updated&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[`updated `,e.updated]})]})]}),e.summary?(0,x.jsx)(`p`,{children:e.summary}):(0,x.jsx)(`p`,{className:`muted`,children:`The three-sentence summary is still the template. It leads every cover letter.`}),(e.basics.email||e.basics.links.length>0)&&(0,x.jsx)(`p`,{className:`muted mono`,children:[e.basics.email,...e.basics.links].filter(Boolean).join(` · `)})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Needs attention`}),(0,x.jsx)(`p`,{children:`What a reader of these notes would trip on. Each line names the note to fix.`})]}),(0,x.jsx)(z,{size:`sm`,tone:e.attention.length?`warning`:`success`,children:e.attention.length?`${e.attention.length} item${e.attention.length===1?``:`s`}`:`nothing stale`})]}),e.attention.length>0?(0,x.jsx)(`ul`,{className:`summary__list`,children:e.attention.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.note}),` `,e.text]},e.text))}):(0,x.jsx)(`p`,{className:`muted`,children:`Every field is filled, the resume of record is fresh, and the criteria agree with the profile.`})]})}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Target roles`}),(0,x.jsx)(`p`,{children:`From the profile's table. "In criteria" means a title term the scan scores on matches the title; a title without one is never found by the scan.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Target roles`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Tier`}),(0,x.jsx)(Y.HeadCell,{children:`Title`}),(0,x.jsx)(Y.HeadCell,{children:`In criteria`})]})}),(0,x.jsxs)(Y.Body,{children:[e.targets.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:e.tier===`A`?`primary`:`neutral`,children:e.tier})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:e.term?(0,x.jsxs)(`span`,{className:`muted`,children:[`yes · `,(0,x.jsx)(`span`,{className:`mono`,children:e.term})]}):(0,x.jsx)(z,{size:`sm`,tone:`warning`,variant:`soft`,children:`no title term`})})]},`${e.tier}-${e.title}`)),e.targets.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:3,children:(0,x.jsx)(`span`,{className:`muted`,children:`The Target roles table is empty.`})})})]})]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Constraints against the criteria`}),(0,x.jsx)(`p`,{children:`What the profile says beside what the scan enforces.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Constraints against the criteria`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Constraint`}),(0,x.jsx)(Y.HeadCell,{children:`Profile`}),(0,x.jsx)(Y.HeadCell,{children:`Criteria`}),(0,x.jsx)(Y.HeadCell,{})]})}),(0,x.jsx)(Y.Body,{children:e.constraints.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.label}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:e.profile?``:`muted`,children:e.profile||`not set`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:e.criteria?`num`:`muted`,children:e.criteria||`—`})}),(0,x.jsx)(Y.Cell,{children:e.level!==`info`&&(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.level===`ok`?`agree`:e.level===`warn`?`differ`:`missing`})})]},e.label))})]})]})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Documents`}),(0,x.jsx)(`p`,{children:`The notes and files the drafts are built from, and how fresh each one is.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Documents`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Document`}),(0,x.jsx)(Y.HeadCell,{children:`State`}),(0,x.jsx)(Y.HeadCell,{children:`Where`})]})}),(0,x.jsx)(Y.Body,{children:e.documents.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.label}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.state})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted mono`,children:e.where})})]},e.label))})]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`What feeds what`}),(0,x.jsx)(`p`,{children:`Which note each thing the app writes is built from. Change the note, and everything after it changes.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`What feeds what`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Produces`}),(0,x.jsx)(Y.HeadCell,{children:`Reads`})]})}),(0,x.jsx)(Y.Body,{children:e.feeds.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.produces}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.reads})})]},e.produces))})]})]})]}),e.proofPoints.length>0&&(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Proof points`}),(0,x.jsxs)(`p`,{children:[e.proofPoints.length,` on file; the ones without a number are flagged above. Cover letters quote from these and nothing else.`]})]})}),(0,x.jsx)(`ul`,{className:`summary__list`,children:e.proofPoints.map(e=>(0,x.jsxs)(`li`,{children:[e.hasNumber?null:(0,x.jsx)(z,{size:`sm`,tone:`warning`,variant:`soft`,children:`no number`}),` `,e.text]},e.text))})]})})]})}var Mv=e=>e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,``);function Nv({note:e,onSaved:t}){let[n,r]=(0,b.useState)(e.markdown),[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(e.editable?`edit`:`preview`);(0,b.useEffect)(()=>r(e.markdown),[e.markdown]);let c=n!==e.markdown;return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{children:e.hint}),(0,x.jsx)(`p`,{className:`muted`,children:(0,x.jsx)(`code`,{children:e.path})})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsx)(Z,{value:o,onValueChange:e=>s(e),variant:`pill`,size:`sm`,children:(0,x.jsxs)(Z.List,{"aria-label":`Edit or preview`,children:[(0,x.jsx)(Z.Trigger,{value:`edit`,children:e.editable?`Edit`:`Source`}),(0,x.jsx)(Z.Trigger,{value:`preview`,children:`Preview`})]})}),(0,x.jsx)(B,{asChild:!0,variant:`soft`,size:`sm`,trailingIcon:(0,x.jsx)(H.ExternalLink,{}),children:(0,x.jsx)(`a`,{href:`obsidian://open?path=${encodeURIComponent(e.path)}`,children:`Open in Obsidian`})})]})]}),!e.exists&&(0,x.jsx)(z,{tone:`warning`,size:`sm`,children:`This note does not exist yet; saving creates it.`}),o===`preview`?(0,x.jsx)(`div`,{className:`preview-doc`,children:(0,x.jsx)(dg,{text:Mv(n)||`_Nothing here yet._`})}):(0,x.jsx)(Xp,{label:`${e.title} (Markdown)`,font:`mono`,rows:28,resize:`vertical`,value:n,onChange:e=>r(e.target.value),disabled:!e.editable,description:e.editable?void 0:`Read-only here. Pick a variant below, or edit the resume file and run tekjobs resume sync.`}),e.editable&&(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:!c||i,onClick:()=>r(e.markdown),children:`Discard`}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:!c||i,loading:i,onClick:async()=>{a(!0);try{let r=await $.saveProfileNote(e.key,n);X({title:`${e.title} saved`,description:r.saved,tone:`success`}),t()}catch(t){X({title:`${e.title} not saved`,description:t.message,tone:`danger`})}a(!1)},children:`Save to the vault`})]})]})})}function Pv({onChanged:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),a=()=>$.resumes().then(n).catch(e=>X({title:`Could not read the resume folder`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{a()},[]);let o=async t=>{i(t);try{let n=await $.useResume(t);X({title:`${t} is the resume of record`,description:`${n.chars} characters into Profile/Resume.md; ${n.added.length} lines new, ${n.removed.length} gone${n.stale.length?`, ${n.stale.length} drafts quote a removed claim`:``}.`,tone:`success`}),a(),e()}catch(e){X({title:`Not switched`,description:e.message,tone:`danger`})}i(``)},s=e=>`${Math.max(1,Math.round(e/1024))} KB`;return(0,x.jsx)(V,{padding:t&&t.files.length?`none`:`md`,children:t?t.files.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`No resume variants yet`,description:`Drop PDF, DOCX, Markdown or text files into ${t.dir}${t.exists?``:` (the folder does not exist yet)`} and they appear here. The folder is set in Settings.`}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(Y,{"aria-label":`Resume variants`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`File`}),(0,x.jsx)(Y.HeadCell,{children:`Changed`}),(0,x.jsx)(Y.HeadCell,{children:`Size`}),(0,x.jsx)(Y.HeadCell,{children:`Use`})]})}),(0,x.jsx)(Y.Body,{children:t.files.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`chips`,children:[e.name,e.current&&(0,x.jsx)(z,{size:`sm`,tone:`primary`,variant:`soft`,children:`resume of record`})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.modified})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:s(e.size)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,onClick:()=>$.openResume(e.name).catch(e=>X({title:`Could not open`,description:e.message,tone:`danger`})),children:`Open`}),!e.current&&(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:!!r,loading:r===e.name,onClick:()=>o(e.name),children:`Make it the resume of record`})]})})]},e.name))})]}),(0,x.jsxs)(`p`,{className:`muted variants__foot`,children:[`From `,(0,x.jsx)(`code`,{className:`mono`,children:t.dir}),`. Making one the record reads it into Profile/Resume.md, which every tailored resume and letter starts from; the packet's Resume variant field offers these names.`]})]}):(0,x.jsx)(zg,{lines:3})})}function Fv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),i=()=>($.profileSummary().then(r).catch(()=>{}),$.profileNotes().then(e=>t(e.notes)).catch(e=>X({title:`Could not load the profile`,description:e.message,tone:`danger`})));return(0,b.useEffect)(()=>{i()},[]),e?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsx)(`p`,{children:`Who you are, how the story is told, and how you write. Cover letters, tailored resumes and application packets read these notes; the scan reads the Criteria page. Saving keeps yesterday's copy beside the note.`})})}),(0,x.jsxs)(Z,{defaultValue:`summary`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Profile notes`,children:[(0,x.jsx)(Z.Trigger,{value:`summary`,children:`Summary`}),e.map(e=>(0,x.jsx)(Z.Trigger,{value:e.key,children:e.title},e.key))]}),(0,x.jsx)(Z.Content,{value:`summary`,children:n?(0,x.jsx)(jv,{s:n}):(0,x.jsx)(zg,{variant:`rect`,height:`12rem`})}),e.map(e=>(0,x.jsx)(Z.Content,{value:e.key,children:(0,x.jsxs)(`div`,{className:`detail`,children:[e.key===`resume`&&(0,x.jsx)(Pv,{onChanged:i}),(0,x.jsx)(Nv,{note:e,onSaved:i})]})},e.key))]})]}):(0,x.jsx)(zg,{variant:`rect`,height:`24rem`})}var Iv=`__active__`,Lv={success:{label:`Success`,tone:`success`},partial:{label:`Partial`,tone:`warning`},failed:{label:`Failed`,tone:`danger`}},Rv=e=>e.dry?`dry run`:e.via===`schedule`?`scheduled`:e.via===`mcp`?`agent`:e.via===`cli`?`manual, CLI`:e.via===`app`?`manual`:``,zv=e=>{let t=e.match(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}) UTC$/);if(!t)return``;let n=new Date(`${t[1]}T${t[2]}:00Z`);return Number.isNaN(n.getTime())?``:`${n.toLocaleString()} local`};function Bv(e){if(e.running||e.exitCode===null)return null;if(e.exitCode!==0)return`failed`;let t=(e.output.find(e=>/Boards: \d+\/\d+/.test(e))||``).match(/Boards: (\d+)\/(\d+)/),n=e.output.some(e=>/^- .+?: failed: /.test(e)||/^\s+x /.test(e));return t?Number(t[1])===0&&Number(t[2])>0?`failed`:Number(t[1])===Number(t[2])&&!n?`success`:`partial`:`success`}function Vv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)([]),[o,s]=(0,b.useState)(Iv),[c,l]=(0,b.useState)(null),u=()=>$.runs().then(t).catch(()=>t([]));(0,b.useEffect)(()=>{u(),$.scan().then(r).catch(()=>{}),$.criteriaPresets().then(a).catch(()=>a([]))},[]),(0,b.useEffect)(()=>{if(!n?.running)return;let e=setInterval(()=>$.scan().then(e=>{r(e),e.running||u()}).catch(()=>{}),2e3);return()=>clearInterval(e)},[n?.running]);let d=async(e,t=!1)=>{let n=o===Iv?void 0:o;try{r(await $.startScan(e,n,t)),X({title:t?`Retrying the failed boards`:e?`Dry run started`:`Scan started`,description:t?`Only the boards whose last attempt failed, no feeds.`:`Every board, scored with ${n?`the "${n}" preset`:`the active criteria`}.`,tone:`success`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=(e??[]).flatMap(e=>e.runs.map((t,n)=>({...t,key:`${e.date}-${n}`})).reverse()),p=f[0],m=!!p&&!p.dry&&p.boardsOk<p.boardsTotal,h=n?Bv(n):null;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsx)(`p`,{children:`Each scan fetches every board, scores, and writes new matches to the vault. The morning task runs it with the active criteria; here you can run one now, with the active set or a preset from the Criteria page. Times are UTC; hover one for your clock.`})}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Score with`,value:o,onValueChange:s,disabled:!!n?.running,children:[(0,x.jsx)(J.Item,{value:Iv,children:`Active criteria`}),i.map(e=>(0,x.jsx)(J.Item,{value:e.name,children:e.name},e.name))]}),m&&(0,x.jsx)(Bh,{content:`${p.boardsTotal-p.boardsOk} board${p.boardsTotal-p.boardsOk===1?``:`s`} did not answer last time. Fetch only those; Sources shows each one's health.`,children:(0,x.jsx)(B,{variant:`soft`,tone:`danger`,size:`sm`,disabled:!!n?.running,leadingIcon:(0,x.jsx)(H.Refresh,{}),onClick:()=>d(!1,!0),children:`Retry failed`})}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:!!n?.running,onClick:()=>d(!0),children:`Dry run`}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:!!n?.running,leadingIcon:n?.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Refresh,{}),onClick:()=>d(!1),children:n?.running?`Scanning`:`Scan now`})]})]}),n&&(n.running||n.output.length>0)&&(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`runs__live`,children:n.running?`Running`:h?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(z,{tone:Lv[h].tone,size:`sm`,children:Lv[h].label}),` `,(0,x.jsx)(`span`,{children:h===`failed`?`exit code ${n.exitCode}`:`finished`})]}):`Finished`}),(0,x.jsxs)(`p`,{children:[n.startedAt?`Started ${n.startedAt.replace(`T`,` `).slice(0,19)} UTC`:``,n.criteria?` · preset "${n.criteria}"`:``]})]}),n.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`Fetching boards`,size:`sm`})]}),(0,x.jsx)(ag,{code:n.output.slice(-40).join(`
77
- `)||`…`,language:`text`,showCopy:!1,wrap:!0})]})}),f.length>1&&(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`New matches per scan`}),(0,x.jsx)(`p`,{children:`What each of the last twelve runs added, most recent on the right.`})]})}),(0,x.jsx)(Fi,{series:[{name:`New matches`,values:[...f].slice(0,12).reverse().map(e=>e.newMatches)}],labels:[...f].slice(0,12).reverse().map(e=>e.when.slice(5,16)),area:!0,height:200,"aria-label":`New matches per scan`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Last scan`}),(0,x.jsx)(`p`,{children:p?p.when:``})]}),p&&(0,x.jsx)(z,{tone:Lv[p.outcome].tone,size:`sm`,children:Lv[p.outcome].label})]}),p&&(0,x.jsxs)(`dl`,{className:`detail__grid`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Postings scanned`}),(0,x.jsx)(`dd`,{children:p.scanned.toLocaleString()})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Above the bar`}),(0,x.jsx)(`dd`,{children:p.matched})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`New notes`}),(0,x.jsx)(`dd`,{children:p.dry?`dry run`:p.newMatches})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Closed listings`}),(0,x.jsx)(`dd`,{children:p.dry?`—`:p.closed})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Duration`}),(0,x.jsxs)(`dd`,{children:[p.seconds,`s`]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Boards`}),(0,x.jsxs)(`dd`,{children:[p.boardsOk,`/`,p.boardsTotal]})]})]})]})})]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:6})}):(0,x.jsxs)(Y,{"aria-label":`Scan history`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Outcome`}),(0,x.jsx)(Y.HeadCell,{children:`When`}),(0,x.jsx)(Y.HeadCell,{children:`Boards`}),(0,x.jsx)(Y.HeadCell,{children:`Criteria`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Scanned`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Above bar`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`New`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Closed`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Seconds`})]})}),(0,x.jsxs)(Y.Body,{children:[f.map(e=>{let t=[...e.failed?e.failed.split(/;\s*/).filter(Boolean).map(e=>`board: ${e}`):[],...(e.feedsFailed||[]).map(e=>`feed: ${e}`)],n=t.length>0,r=c===e.key;return[(0,x.jsxs)(Y.Row,{interactive:n,onClick:n?()=>l(r?null:e.key):void 0,"aria-expanded":n?r:void 0,children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`runs__outcome`,children:[(0,x.jsx)(z,{tone:Lv[e.outcome].tone,variant:e.outcome===`success`?`soft`:`solid`,size:`sm`,children:Lv[e.outcome].label}),Rv(e)&&(0,x.jsx)(`small`,{className:`muted`,children:Rv(e)})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num`,title:zv(e.when),children:e.when})}),(0,x.jsxs)(Y.Cell,{children:[(0,x.jsxs)(`span`,{className:`num`,children:[e.boardsOk,`/`,e.boardsTotal]}),n&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,t.length,` problem`,t.length===1?``:`s`,` `,r?`▾`:`▸`]})]}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.criteria||`—`})}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.scanned.toLocaleString()}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.matched}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.dry?(0,x.jsx)(`span`,{className:`muted`,children:`—`}):e.newMatches}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.dry?(0,x.jsx)(`span`,{className:`muted`,children:`—`}):e.closed}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.seconds})]},e.key),n&&r?(0,x.jsx)(Y.Row,{children:(0,x.jsxs)(Y.Cell,{colSpan:9,children:[(0,x.jsx)(`ul`,{className:`runs__problems`,children:t.map(e=>(0,x.jsx)(`li`,{className:`mono`,children:e},e))}),(0,x.jsx)(`p`,{className:`muted`,children:`A board that fails once is usually a hiccup; one that fails every run has moved. Sources shows each board's health and last success.`})]})},`${e.key}-problems`):null]}),f.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:9,children:(0,x.jsx)(`span`,{className:`muted`,children:`No scans logged yet.`})})})]})]})})]})}function Hv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)({profile:``,resumeDir:``,llmCommand:``,llmArgs:``,contact:``}),[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(!1),c=()=>$.settings().then(e=>{t(e),r({profile:e.profile.configured||e.profile.active,resumeDir:e.resumeDir.configured||e.resumeDir.path,llmCommand:e.llm.command,llmArgs:e.llm.args,contact:e.contact})}).catch(e=>X({title:`Could not read the settings`,description:e.message,tone:`danger`}));return(0,b.useEffect)(()=>{c()},[]),e?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Where things live. These are the only settings kept outside the profile folder, in `,(0,x.jsx)(`code`,{className:`mono`,children:e.configFile}),`; everything about the search itself is a note in the folder.`]})})}),(0,x.jsxs)(`div`,{className:`detail`,children:[o&&(0,x.jsxs)(z,{tone:`warning`,size:`md`,children:[`The profile folder changed. Restart the server (`,(0,x.jsx)(`code`,{className:`mono`,children:`npm run server`}),`, or the scheduled task's next run) to switch; until then the app keeps reading `,e.profile.active,`.`]}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Profile folder`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`Your job search: profile, resume, criteria, watchlist, one note per job, logs. Plain markdown; point Obsidian at it. Reading now: `,(0,x.jsx)(`code`,{className:`mono`,children:e.profile.active}),e.profile.fromEnv?` (set by TEKJOBS_PROFILE in the environment, which wins over this file)`:``,`.`]})]}),(0,x.jsx)(Zp,{label:`Folder`,value:n.profile,onChange:e=>r({...n,profile:e.target.value}),description:`Must exist. To start a new profile somewhere, run tekjobs init <dir> instead; it writes the starter notes. Takes effect on the next server start.`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Resume variants folder`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`PDF, DOCX, Markdown or text files, one per variant. The Profile page lists them and makes any one the resume of record; the packet's Resume variant field offers their names. `,e.resumeDir.exists?``:`This folder does not exist yet.`]})]}),(0,x.jsx)(Zp,{label:`Folder`,value:n.resumeDir,onChange:e=>r({...n,resumeDir:e.target.value}),description:`Default: Templates/Resume inside the profile folder. Resume of record now: ${e.resumeSource||`not set`}.`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Writing CLI`}),(0,x.jsx)(`p`,{className:`muted`,children:`The local coding CLI that writes letters and tailored resumes and reads the mailbox. It must be signed in on this machine. Claude Code by default; another CLI works if it takes the prompt on stdin and prints the answer.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(Zp,{label:`Command`,value:n.llmCommand,onChange:e=>r({...n,llmCommand:e.target.value})}),(0,x.jsx)(Zp,{label:`Arguments`,value:n.llmArgs,onChange:e=>r({...n,llmArgs:e.target.value}),font:`mono`})]})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Contact for scans`}),(0,x.jsx)(`p`,{className:`muted`,children:`Optional. Added to the user agent on every request the scan makes, so a site can reach the person running it.`})]}),(0,x.jsx)(Zp,{label:`Email`,type:`email`,value:n.contact,onChange:e=>r({...n,contact:e.target.value})})]})}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:i,onClick:async()=>{a(!0);try{let e=await $.saveSettings(n);t(e),s(e.restart||o),X({title:`Settings saved`,description:e.configFile,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}a(!1)},children:`Save settings`})})]})]}):(0,x.jsx)(zg,{variant:`rect`,height:`20rem`})}function Uv(){let[e,t]=(0,b.useState)(()=>{let e=new URLSearchParams(window.location.search).get(`theme`);if(e===`light`||e===`dark`)return e;let t=document.documentElement.dataset.theme;return t===`light`||t===`dark`?t:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`});return(0,b.useEffect)(()=>{document.documentElement.dataset.theme=e},[e]),[e,()=>t(e=>e===`light`?`dark`:`light`)]}function Wv(){let e=()=>{let[e,t]=window.location.hash.replace(/^#\/?/,``).split(`?`);return{page:[`onboarding`,`today`,`overview`,`jobs`,`pipeline`,`mail`,`people`,`companies`,`criteria`,`profile`,`runs`,`agent`,`settings`].includes(e??``)?e:`today`,q:new URLSearchParams(t).get(`q`)??``}},[t,n]=(0,b.useState)(e);return(0,b.useEffect)(()=>{let t=()=>n(e());return window.addEventListener(`hashchange`,t),()=>window.removeEventListener(`hashchange`,t)},[]),[t.page,t.q,(e,t)=>{window.location.hash=t?`/${e}?q=${encodeURIComponent(t)}`:`/${e}`}]}function Gv(){let[e,t,n]=Wv(),[r,i]=Uv(),[a,o]=(0,b.useState)(!0),[s,c]=(0,b.useState)({}),[l,u]=(0,b.useState)(``);return(0,b.useEffect)(()=>{$.onboarding().then(e=>{o(e.complete),!e.complete&&!window.location.hash&&n(`onboarding`)}).catch(()=>{})},[]),(0,b.useEffect)(()=>{$.summary().then(e=>{c(t=>({...t,jobs:e.open,companies:e.companies})),e.lastRun&&u(`Last scan ${e.lastRun.when.slice(11,16)} · ${e.lastRun.boardsOk}/${e.lastRun.boardsTotal} boards`)}).catch(()=>{}),$.today().then(e=>c(t=>({...t,today:e.sections.triage.length}))).catch(()=>{}),$.mail().then(e=>c(t=>({...t,mail:e.groups.length}))).catch(()=>{})},[e]),(0,x.jsx)(Bh.Provider,{children:(0,x.jsx)($m.Provider,{position:`bottom-right`,children:(0,x.jsx)(c_,{page:e,onNavigate:e=>n(e),onSearch:e=>n(`jobs`,e),theme:r,onToggleTheme:i,onboarded:a,counts:s,lastScan:l,children:(0,x.jsxs)(`div`,{className:`page z-enter-fade`,children:[e===`onboarding`&&(0,x.jsx)(_v,{onDone:()=>n(`overview`)}),e===`today`&&(0,x.jsx)(Cv,{onNavigate:n}),e===`overview`&&(0,x.jsx)(Sv,{onNavigate:n}),e===`jobs`&&(0,x.jsx)(rv,{initialQuery:t}),e===`pipeline`&&(0,x.jsx)(kv,{}),e===`mail`&&(0,x.jsx)(dv,{}),e===`people`&&(0,x.jsx)(M_,{}),e===`companies`&&(0,x.jsx)(g_,{}),e===`criteria`&&(0,x.jsx)(D_,{}),e===`profile`&&(0,x.jsx)(Fv,{}),e===`runs`&&(0,x.jsx)(Vv,{}),e===`agent`&&(0,x.jsx)(d_,{}),e===`settings`&&(0,x.jsx)(Hv,{})]},e)})})})}(0,y.createRoot)(document.getElementById(`root`)).render((0,x.jsx)(b.StrictMode,{children:(0,x.jsx)(Gv,{})}));
76
+ `).map(e=>e.replace(/^-\s*/,``).trim()).filter(Boolean).map(e=>{let t=[...e.matchAll(/(?<![\w$])([+-]\d+)\b/g)].reduce((e,t)=>e+Number(t[1]),0),n=e.replace(/(?<![\w$])[+-]\d+\b/g,``).replace(/\(\s*[,\s]*/g,`(`).replace(/[,\s]*\)/g,`)`).replace(/\(\)/g,``).replace(/\s+,/g,`,`).replace(/\s{2,}/g,` `).replace(/\s+:/g,`:`).trim(),r=n.indexOf(`:`),i=(r>=0?n.slice(0,r):n).trim().replace(/[,:]$/,``),a=(r>=0?n.slice(r+1):``).trim();return{label:i.charAt(0).toUpperCase()+i.slice(1),detail:a,points:t}})}function av(e){return(0,x.jsx)(Sp,{open:e.id!==null,onOpenChange:t=>!t&&e.onClose(),side:`right`,size:`lg`,children:(0,x.jsx)(Sp.Content,{children:(0,x.jsx)(ov,{...e})})})}function ov({id:e,onClose:t,onChanged:n,nav:r,inline:i=!1}){let[a,o]=(0,b.useState)(null),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)(!1);(0,b.useEffect)(()=>{o(null),e&&$.job(e).then(o).catch(e=>X({title:`Could not open the note`,description:e.message,tone:`danger`}))},[e]);let d=async e=>{if(a){u(!0);try{let t=await $.setStatus(a.id,e);o(t),n(t),X({title:`${a.company}: ${e}`,description:`Written to the note's frontmatter and status log.`,tone:`success`})}catch(e){X({title:`Status not saved`,description:e.message,tone:`danger`})}u(!1)}},f=async()=>{if(a&&s.trim()){u(!0);try{let e=await $.addNote(a.id,s);o(e),c(``),X({title:`Note added`,tone:`success`})}catch(e){X({title:`Note not saved`,description:e.message,tone:`danger`})}u(!1)}},[p,m]=(0,b.useState)(null);(0,b.useEffect)(()=>{Promise.all([$.summary(),$.companies()]).then(([e,t])=>m({ceiling:e.ceiling,bar:e.minScore,boards:t.map(e=>({name:e.name,tier:e.tier,status:e.status}))})).catch(()=>{})},[]);let h=(0,b.useMemo)(()=>a?iv(a.sections.why):[],[a]),g=a&&p?.ceiling?Math.max(0,Math.min(100,Math.round(a.score/p.ceiling*100))):null,_=a&&p?p.boards.find(e=>e.name.toLowerCase()===a.company.toLowerCase()):null,v=a?a.sections.description.replace(/^>.*$/m,``).replace(/[#*_`>]/g,``).replace(/\s+/g,` `).trim().slice(0,320):``,y=async e=>{if(a){u(!0);try{let t=await $.setStatus(a.id,`passed`,e);o(t),n(t),X({title:`${a.company}: passed`,description:e,tone:`neutral`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}u(!1)}},S=r&&(0,x.jsxs)(`div`,{className:`sheet-nav`,children:[(0,x.jsx)(Bh,{content:`Previous (K)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Previous job`,leadingIcon:(0,x.jsx)(H.ChevronUp,{}),disabled:r.pos<=0,onClick:r.prev})}),(0,x.jsx)(Bh,{content:`Next (J)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Next job`,leadingIcon:(0,x.jsx)(H.ChevronDown,{}),disabled:r.pos<0?r.total===0:r.pos>=r.total-1,onClick:r.next})}),(0,x.jsx)(`span`,{className:`sheet-nav__count num`,children:r.pos>=0?`${r.pos+1} of ${r.total}`:`not in this view`}),i&&(0,x.jsx)(Bh,{content:`Close (Esc)`,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,"aria-label":`Close`,leadingIcon:(0,x.jsx)(H.Close,{}),onClick:t,className:`sheet-nav__close`})})]});return(0,x.jsx)(x.Fragment,{children:a?(0,x.jsxs)(`div`,{className:`detail`,children:[S,(0,x.jsxs)(`div`,{className:`sheet-head`,children:[(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[a.company,` · `,a.location||`location n/a`,` · `,z_(a.source)?`posted on TekJobs`:a.source,` · found `,Xg(a.found)||a.found]}),i?(0,x.jsx)(`h2`,{className:`sheet-head__title`,children:a.title}):(0,x.jsx)(Sp.Title,{children:a.title}),(0,x.jsxs)(`div`,{className:`chips`,children:[z_(a.source)&&(0,x.jsx)(B_,{label:`Posted on TekJobs`}),(0,x.jsx)(z,{tone:a.payBand===`floor`?`primary`:`neutral`,variant:`soft`,size:`sm`,children:(0,x.jsx)(`span`,{className:`num`,children:a.salaryMax?Yg(a.salary):`pay not stated`})}),a.salaryMax>0&&(0,x.jsx)(z,{tone:`neutral`,variant:`outline`,size:`sm`,children:Zg[a.payBand].toLowerCase()}),(0,x.jsx)(z,{tone:a.remote?`success`:`neutral`,variant:a.remote?`soft`:`outline`,size:`sm`,children:a.remote?`remote`:`on-site`}),(0,x.jsx)(z,{tone:$g[a.status],size:`sm`,children:a.status})]})]}),(0,x.jsxs)(`div`,{className:`sheet-head__side`,children:[(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[a.status===`new`&&(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:l,onClick:()=>d(`reviewing`),children:`Shortlist`}),(a.status===`new`||a.status===`reviewing`)&&(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:l,trailingIcon:(0,x.jsx)(H.ChevronDown,{}),children:`Pass`})}),(0,x.jsx)(Tu.Content,{align:`end`,children:Kg.map(e=>(0,x.jsx)(Tu.Item,{onSelect:()=>y(e),children:e},e))})]}),(0,x.jsx)(J,{size:`sm`,label:`Status`,value:a.status,onValueChange:e=>d(e),disabled:l,children:Gg.map(e=>(0,x.jsx)(J.Item,{value:e,children:e},e))})]}),(0,x.jsxs)(`div`,{className:`sheet-head__links`,children:[(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:a.url,target:`_blank`,rel:`noopener noreferrer`,children:`Open posting ↗`})}),(0,x.jsx)(B,{asChild:!0,variant:`link`,size:`sm`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:a.obsidianUrl,title:a.path,children:`Open in Obsidian ↗`})}),(0,x.jsx)(B,{variant:`link`,size:`sm`,tone:`neutral`,title:a.path,onClick:()=>$.revealJob(a.id).catch(e=>X({title:`Could not show the file`,description:e.message,tone:`danger`})),children:`Show file`}),(0,x.jsx)(H_,{job:a,onAttached:e=>{o(e),n(e)}})]})]})]}),(0,x.jsxs)(Z,{defaultValue:`why`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Job note sections`,children:[(0,x.jsx)(Z.Trigger,{value:`why`,children:`Match reasons`}),(0,x.jsx)(Z.Trigger,{value:`description`,children:`Description`}),(0,x.jsx)(Z.Trigger,{value:`application`,children:`Application packet`}),(0,x.jsx)(Z.Trigger,{value:`resume`,children:`Tailored resume`}),(0,x.jsx)(Z.Trigger,{value:`letter`,children:`Cover letter`}),(0,x.jsx)(Z.Trigger,{value:`people`,children:`People`}),(0,x.jsx)(Z.Trigger,{value:`notes`,children:`Notes`})]}),(0,x.jsx)(Z.Content,{value:`why`,children:(0,x.jsxs)(`div`,{className:`split`,children:[(0,x.jsxs)(`div`,{className:`reasons`,children:[(0,x.jsxs)(`div`,{className:`reasons__head`,children:[(0,x.jsxs)(`span`,{className:`muted`,children:[`Scored `,(0,x.jsx)(`span`,{className:`num`,children:a.score}),p?.ceiling?(0,x.jsxs)(x.Fragment,{children:[` of `,(0,x.jsx)(`span`,{className:`num`,children:p.ceiling}),` possible`]}):null,` with the active criteria`,p?.bar?(0,x.jsxs)(x.Fragment,{children:[` (bar `,(0,x.jsx)(`span`,{className:`num`,children:p.bar}),`)`]}):null,`.`]}),g!==null&&(0,x.jsxs)(`span`,{className:`reasons__fit num`,children:[g,(0,x.jsx)(`small`,{children:` fit`})]})]}),h.map((e,t)=>(0,x.jsxs)(`div`,{className:`reasons__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{children:e.label}),e.detail&&(0,x.jsx)(`div`,{className:`reasons__detail`,children:e.detail})]}),(0,x.jsxs)(`span`,{className:`num reasons__pts${e.points<0?` reasons__pts--neg`:``}`,children:[e.points<0?`−`:`+`,Math.abs(e.points)]})]},t)),h.length===0&&(0,x.jsx)(`p`,{className:`muted`,children:`No match reasons recorded.`}),(0,x.jsxs)(`details`,{className:`reasons__log`,children:[(0,x.jsx)(`summary`,{children:`Status log`}),(0,x.jsx)(dg,{text:a.sections.log||`_Nothing yet._`})]})]}),(0,x.jsxs)(`aside`,{className:`split__aside`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`From the posting`}),(0,x.jsx)(`p`,{children:v?`${v}${a.sections.description.length>320?`…`:``}`:`The posting had no description text. Open the posting, or attach one.`})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Note`}),(0,x.jsxs)(`p`,{className:`num small`,children:[a.path.split(/[\\/]/).slice(-2).join(`/`),(0,x.jsx)(`br`,{}),`status: `,a.status,` · found `,a.found,a.addedBy===`scan`?``:` · added by ${a.addedBy}`]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`div`,{className:`microlabel`,children:`Board`}),(0,x.jsx)(`p`,{children:_?`Tier ${_.tier} board, last fetch ${_.status||`not yet run`}.`:`${a.source}; not on the watchlist.`})]})]})]})}),(0,x.jsx)(Z.Content,{value:`description`,children:(0,x.jsx)(dg,{text:a.sections.description||`_The posting had no description text. Open the posting._`})}),(0,x.jsx)(Z.Content,{value:`application`,children:(0,x.jsx)(sv,{job:a,onStatus:d,busy:l})}),(0,x.jsx)(Z.Content,{value:`resume`,children:(0,x.jsx)(R_,{job:a})}),(0,x.jsx)(Z.Content,{value:`letter`,children:(0,x.jsx)(O_,{job:a})}),(0,x.jsx)(Z.Content,{value:`people`,children:(0,x.jsx)(F_,{job:a})}),(0,x.jsx)(Z.Content,{value:`notes`,children:(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(dg,{text:a.sections.notes||`_No notes yet._`}),(0,x.jsx)(Xp,{label:`Add a note`,rows:3,value:s,onChange:e=>c(e.target.value),placeholder:`Appended to the note with today's date.`}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:f,disabled:l||!s.trim(),children:`Save note`})})]})})]})]}):(0,x.jsxs)(`div`,{className:`detail`,children:[S,(0,x.jsx)(zg,{lines:6})]})})}function sv({job:e,onStatus:t,busy:n}){let[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)({}),[s,c]=(0,b.useState)(``),[l,u]=(0,b.useState)([]),d=()=>$.packet(e.id).then(e=>{i(e),o(e.values)}).catch(e=>X({title:`Could not read the packet`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{d(),$.resumes().then(e=>u(e.files.map(e=>e.name))).catch(()=>{})},[e.id]);let f=async(t,n)=>{o(e=>({...e,[t]:n})),c(t);try{await $.saveApplication(e.id,t,n),await d(),X({title:`${t} saved`,description:n,tone:`success`})}catch(e){X({title:`${t} not saved`,description:e.message,tone:`danger`})}finally{c(``)}},p=async t=>{if(r&&a[t]!==r.values[t]){c(t);try{await $.saveApplication(e.id,t,a[t]??``),await d(),X({title:`${t} saved`,description:`Written into the note.`,tone:`success`})}catch(e){X({title:`${t} not saved`,description:e.message,tone:`danger`})}finally{c(``)}}};return r?(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`div`,{className:`packet__state`,children:[(0,x.jsxs)(z,{tone:r.ready?`success`:`neutral`,variant:r.ready?`soft`:`outline`,children:[r.filled,` of `,r.total,` filled`]}),r.ready?(0,x.jsx)(`p`,{className:`muted`,children:`Every required field has something in it. Read it before you send it — this says the boxes are full, not that the application is good.`}):(0,x.jsxs)(`p`,{className:`muted`,children:[`Still required: `,r.missing.join(`, `),`.`]})]}),r.ready&&e.status!==`applied`&&(0,x.jsxs)(`div`,{className:`form__actions form__actions--start`,children:[e.status!==`ready`&&(0,x.jsx)(B,{size:`sm`,tone:`primary`,variant:`soft`,disabled:n,onClick:()=>t(`ready`),children:`Mark ready for approval`}),(0,x.jsx)(B,{size:`sm`,tone:`primary`,disabled:n,onClick:()=>{window.confirm(`Only mark this applied if you have actually sent it to ${e.company}. Nothing here can send an application.`)&&t(`applied`)},children:`I have applied`})]}),r.fields.map(({field:e,hint:t,required:n})=>(0,x.jsxs)(`div`,{className:`packet__field`,children:[(0,x.jsx)(Xp,{label:n?`${e} *`:e,description:t,rows:e===`Tailored summary`||e===`Tailored bullets`||e===`Cover letter`||e===`Outreach message`||e===`Questions`||e===`Risks`?3:1,value:a[e]??``,onChange:t=>o({...a,[e]:t.target.value}),onBlur:()=>p(e),placeholder:n?`Required before this is ready.`:``}),e===`Resume variant`&&l.length>0&&(0,x.jsx)(`div`,{className:`chips`,children:l.map(t=>(0,x.jsx)(B,{size:`sm`,variant:a[e]===t?`soft`:`ghost`,tone:a[e]===t?`primary`:`neutral`,onClick:()=>f(e,t),children:t},t))}),s===e&&(0,x.jsx)(`span`,{className:`muted`,children:`Saving…`})]},e)),(0,x.jsx)(`p`,{className:`muted`,children:`Fields are written into the note's Application section as you leave each one. An agent fills the same fields through the TekJobs MCP server — see Agent access.`})]}):(0,x.jsx)(`div`,{className:`detail`,children:(0,x.jsx)(zg,{lines:6})})}var cv={confirmation:`success`,rejection:`danger`,advance:`primary`,scheduling:`primary`,"info-request":`warning`,outreach:`warning`,other:`neutral`},lv={confirmation:`confirmed`,rejection:`rejected`,advance:`advanced`,scheduling:`scheduling`,"info-request":`asks for more`,outreach:`reached out`,other:`other`};function uv(e,t){let n=e.suggestion;return t?n.action===`status`?`mark it ${n.status}${n.appliedOn?` as of ${n.appliedOn}`:``}`:`add the mail to the note${n.appliedOn?`, set Applied on if empty`:``}`:`create a note for ${e.company} and mark it ${n.status}`}function dv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(0);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(pv,{onOpen:t,onChanged:()=>r(e=>e+1)},n),(0,x.jsx)(av,{id:e,onClose:()=>t(null),onChanged:e=>{}})]})}function fv({onOpen:e}){let[t,n]=(0,b.useState)(null);(0,b.useEffect)(()=>{$.mail().then(n).catch(()=>{})},[]);let r=t?.groups.length??0;return!t||r===0&&!t.running?null:(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`mailstrip`,children:[(0,x.jsxs)(`span`,{children:[t.running?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(Bg,{size:`sm`}),` Reading the mailbox.`]}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`b`,{className:`num`,children:r}),` `,r===1?`email group waits`:`email groups wait`,` for a decision.`]}),t.lastRun&&(0,x.jsxs)(`span`,{className:`muted`,children:[` Last read `,(0,x.jsx)(`span`,{className:`num`,children:t.lastRun.slice(0,16).replace(`T`,` `)}),` UTC.`]})]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,leadingIcon:(0,x.jsx)(H.Mail,{}),onClick:e,children:`Open Mail`})]})})}function pv({onOpen:e,onChanged:t}){let[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)({}),[o,s]=(0,b.useState)(null),[c,l]=(0,b.useState)(null),u=()=>$.mail().then(r).catch(()=>{});(0,b.useEffect)(()=>{u()},[]),(0,b.useEffect)(()=>{if(!n?.running)return;let e=setInterval(()=>$.mail().then(e=>{r(e),!e.running&&e.error&&X({title:`Mail check failed`,description:e.error,tone:`danger`})}).catch(()=>{}),4e3);return()=>clearInterval(e)},[n?.running]);let d=async()=>{try{r(await $.mailCheck()),X({title:`Reading the mailbox`,description:`Through the local CLI, Gmail read tools only. A few minutes.`,tone:`neutral`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=async(e,n)=>{s(e.id);try{let a=e.id in i?i[e.id]:e.noteId;r(n===`confirm`?await $.mailConfirm(e.id,a||void 0):await $.mailDismiss(e.id)),n===`confirm`&&(X({title:`${e.company}: ${uv(e,i[e.id]||e.noteId)}`,description:`Written to the note.`,tone:`success`}),t())}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{s(null)}},p=n?.groups??[],m=(n?.items??[]).filter(e=>e.state!==`pending`).sort((e,t)=>(t.resolved?.at??``).localeCompare(e.resolved?.at??``)),h=m.length,[g,_]=(0,b.useState)(!1),v=e=>e.state===`dismissed`?`dismissed`:e.resolved?.action===`create`?`note created, marked ${e.resolved.status}`:e.resolved?.action===`status`?`marked ${e.resolved.status}`:`recorded on the note`,y=p.filter(e=>e.kind===`confirmation`&&e.match===`exact`&&e.noteId).length;return(0,x.jsxs)(`section`,{className:`today__section`,id:`mail-says`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Mail says`}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[n?.lastRun&&(0,x.jsxs)(`span`,{className:`muted`,children:[`last read `,n.lastRun.slice(0,16).replace(`T`,` `),` UTC, `,n.lastSinceDays,` days back`]}),h>0&&(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:()=>_(e=>!e),children:g?`Hide handled`:`${h} handled`}),y>0&&(0,x.jsxs)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:o===`safe`||!!n?.running,loading:o===`safe`,title:`Confirmations whose note matched by exact title: records the mail, marks still-open notes applied as of the mail's date. Rejections, interviews, company-only matches and creates stay one at a time.`,onClick:async()=>{s(`safe`);try{let e=await $.mailConfirmSafe();r(e),X({title:`${e.confirmed} confirmations recorded`,description:`Exact-title matches only. The rest are still listed.`,tone:`success`}),t()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{s(null)}},children:[`Confirm the exact matches (`,y,`)`]}),(0,x.jsx)(B,{size:`sm`,variant:`soft`,disabled:!!n?.running,leadingIcon:n?.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Mail,{}),onClick:d,children:n?.running?`Reading the mailbox`:`Check mail`})]})]}),!n||p.length===0&&!n.running?(0,x.jsx)(V,{padding:`md`,children:(0,x.jsx)(Vg,{size:`sm`,title:n?.lastRun?`Nothing waiting from the mailbox`:`The mailbox has not been read yet`,description:n?.error?n.error:`The morning task reads application emails through your signed-in CLI (Gmail read tools only) and lists what they say about your applications here. You confirm each one. Check mail reads again now.`})}):(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Application emails waiting for a decision`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Date`}),(0,x.jsx)(Y.HeadCell,{children:`Mail says`}),(0,x.jsx)(Y.HeadCell,{children:`Company and role`}),(0,x.jsx)(Y.HeadCell,{children:`Note`}),(0,x.jsx)(Y.HeadCell,{children:`Confirm`})]})}),(0,x.jsxs)(Y.Body,{children:[p.map(t=>{let r=i[t.id]||t.noteId;return(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>l(t),children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:t.date||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[(0,x.jsxs)(`span`,{className:`chips`,children:[t.kinds.map(e=>(0,x.jsx)(z,{size:`sm`,tone:cv[e],children:lv[e]},e)),t.count>1&&(0,x.jsxs)(`small`,{children:[t.count,` emails`,t.first&&t.first!==t.date?`, ${t.first} to ${t.date}`:``]})]}),(0,x.jsx)(`small`,{title:t.subject,children:t.gist})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[t.company,(0,x.jsx)(`small`,{children:t.role||`role not stated`}),t.person&&(0,x.jsxs)(`small`,{title:`${t.person.email}. Confirming adds them to People and to the note.`,children:[`from `,t.person.name]})]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:t.match===`none`?(0,x.jsx)(`span`,{className:`muted`,children:`no note; confirm creates one`}):t.match===`exact`||t.match===`company`&&t.candidates.length<=1?(0,x.jsxs)(`span`,{className:`who__text`,children:[(0,x.jsxs)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>e(t.noteId),children:[t.noteTitle,` · `,t.noteStatus]}),n.items.find(e=>e.id===t.id)?.via===`link`&&(0,x.jsx)(`small`,{children:`matched by the posting link`})]}):(0,x.jsxs)(J,{size:`sm`,label:t.match===`company-other-role`?`Not a role in the vault`:`Which role`,value:r||`__new__`,onValueChange:e=>a(n=>({...n,[t.id]:e===`__new__`?``:e})),children:[(0,x.jsx)(J.Item,{value:`__new__`,children:`New note for this role`}),t.candidates.map(e=>(0,x.jsxs)(J.Item,{value:e.id,children:[e.title,` · `,e.status]},e.id))]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:(0,x.jsxs)(`div`,{className:`today__actions`,children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:o===t.id,title:uv(t,r),onClick:()=>f(t,`confirm`),children:r?t.suggestion.action===`record`?`Record`:`Mark ${t.suggestion.status}`:`Create and mark`}),(0,x.jsx)(B,{size:`sm`,variant:`ghost`,disabled:o===t.id,onClick:()=>f(t,`dismiss`),children:`Dismiss`})]})})]},t.id)}),n.running&&p.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:5,children:(0,x.jsx)(`span`,{className:`muted`,children:`Reading…`})})})]})]})}),g&&(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Application emails already handled`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Mail date`}),(0,x.jsx)(Y.HeadCell,{children:`Mail said`}),(0,x.jsx)(Y.HeadCell,{children:`Company and role`}),(0,x.jsx)(Y.HeadCell,{children:`Note`}),(0,x.jsx)(Y.HeadCell,{children:`What was done`})]})}),(0,x.jsx)(Y.Body,{children:m.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>l(mv(t)),children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:t.date||`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:cv[t.kind],children:lv[t.kind]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[t.company,(0,x.jsx)(`small`,{children:t.role||`role not stated`})]})}),(0,x.jsx)(Y.Cell,{onClick:e=>e.stopPropagation(),children:t.noteId?(0,x.jsx)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>e(t.noteId),children:t.noteId.replace(/ \([0-9a-f]+\)$/,``)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`muted`,children:[v(t),t.resolved?.at?`, ${t.resolved.at.slice(0,16).replace(`T`,` `)} UTC`:``]})})]},t.id))})]})}),(0,x.jsx)(hv,{group:c,items:n?.items??[],busy:o,onClose:()=>l(null),onOpenNote:e,onAct:async(e,t)=>{await f(e,t),l(null)}})]})}function mv(e){return{id:e.id,ids:[e.id],count:1,company:e.company,role:e.role,kind:e.kind,kinds:[e.kind],date:e.date,first:e.date,gist:e.gist,subject:e.subject,from:e.from,link:e.link,person:e.person??null,match:e.match,noteId:e.noteId,noteTitle:e.noteTitle,noteStatus:e.noteStatus,candidates:e.candidates,suggestion:e.suggestion}}function hv({group:e,items:t,busy:n,onClose:r,onOpenNote:i,onAct:a}){let o=e?t.filter(t=>e.ids.includes(t.id)).sort((e,t)=>(t.date||``).localeCompare(e.date||``)):[],s=o.some(e=>e.state===`pending`);return(0,x.jsx)(Sp,{open:e!==null,onOpenChange:e=>!e&&r(),side:`right`,size:`md`,children:(0,x.jsx)(Sp.Content,{children:e&&(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(`div`,{className:`sheet-head`,children:(0,x.jsxs)(`div`,{className:`sheet-head__main`,children:[(0,x.jsxs)(`p`,{className:`sheet-head__meta`,children:[e.company,e.role?` · ${e.role}`:``]}),(0,x.jsx)(Sp.Title,{children:e.subject||e.gist}),(0,x.jsxs)(`div`,{className:`chips`,children:[e.kinds.map(e=>(0,x.jsx)(z,{size:`sm`,tone:cv[e],children:lv[e]},e)),e.date&&(0,x.jsx)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:e.date})}),e.count>1&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[e.count,` emails`]})]})]})}),(0,x.jsx)(`p`,{children:e.gist}),(0,x.jsxs)(`dl`,{className:`mailsheet__facts`,children:[(0,x.jsx)(`dt`,{children:`From`}),(0,x.jsx)(`dd`,{children:e.person?`${e.person.name}${e.person.email?` <${e.person.email}>`:``}`:e.from}),(0,x.jsx)(`dt`,{children:`Note`}),(0,x.jsx)(`dd`,{children:e.noteId?(0,x.jsxs)(B,{variant:`link`,size:`sm`,tone:`neutral`,onClick:()=>i(e.noteId),children:[e.noteTitle||e.noteId,` · `,e.noteStatus]}):(0,x.jsx)(`span`,{className:`muted`,children:`none yet; confirming creates one`})}),s&&(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`dt`,{children:`Confirming`}),(0,x.jsx)(`dd`,{children:uv(e,e.noteId)})]})]}),(0,x.jsx)(`h4`,{className:`connections__title`,children:o.length===1?`The email`:`The ${o.length} emails`}),(0,x.jsx)(`ul`,{className:`people__list`,children:o.map(e=>(0,x.jsxs)(`li`,{className:`people__row`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`span`,{children:e.subject||e.gist}),(0,x.jsxs)(`div`,{className:`reasons__detail`,children:[[e.date,lv[e.kind],e.fromName||e.from].filter(Boolean).join(` · `),e.gist&&e.subject?` · ${e.gist}`:``]})]}),(0,x.jsx)(`div`,{className:`pager__buttons`,children:(0,x.jsx)(B,{asChild:!0,size:`sm`,variant:`ghost`,tone:`neutral`,children:(0,x.jsx)(`a`,{href:e.link,target:`_blank`,rel:`noreferrer`,children:`Open in Gmail ↗`})})})]},e.id))}),(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{asChild:!0,variant:`soft`,children:(0,x.jsx)(`a`,{href:e.link,target:`_blank`,rel:`noreferrer`,children:`Open in Gmail ↗`})}),s&&(0,x.jsx)(B,{tone:`primary`,disabled:n===e.id,onClick:()=>a(e,`confirm`),children:e.noteId?e.suggestion.action===`record`?`Record`:`Mark ${e.suggestion.status}`:`Create and mark`}),s&&(0,x.jsx)(B,{variant:`ghost`,disabled:n===e.id,onClick:()=>a(e,`dismiss`),children:`Dismiss`})]})]})})})}var gv=`Use the tekjobs MCP server. Call onboarding_status, then onboarding_materials, and follow its script: interview me, write my profile with save_profile, set the criteria with set_criteria, run a dry scan, and show me the top matches.`;function _v({onDone:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(!1),s=()=>$.onboarding().then(n).catch(e=>X({title:`Server not answering`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{s()},[]);let c=async()=>{o(!0);try{let e=await $.initProfile();X({title:`Profile folder ready`,description:e.made.length?`Created ${e.made.join(`, `)}`:`It already existed; nothing was overwritten.`,tone:`success`}),await s()}catch(e){X({title:`Could not create the folder`,description:e.message,tone:`danger`})}o(!1)},l=async()=>{if(r.trim()){o(!0);try{X({title:`Resume imported`,description:`${(await $.importResume(r.trim())).chars.toLocaleString()} characters of text extracted.`,tone:`success`}),i(``),await s()}catch(e){X({title:`Import failed`,description:e.message,tone:`danger`})}o(!1)}};if(!t)return(0,x.jsx)(zg,{variant:`rect`,height:`20rem`});let u=t.steps.filter(e=>e.done).length;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Five steps from an empty folder to a daily scan that knows who you are. Your profile lives at `,(0,x.jsx)(`code`,{children:t.dir}),`. The scan and the notes stay on this machine; the interview and the drafting send what you choose to the AI client you connect.`]})}),(0,x.jsxs)(z,{tone:t.complete?`success`:`primary`,size:`sm`,children:[u,` of `,t.steps.length,` done`]})]}),(0,x.jsx)(`div`,{className:`steps`,children:t.steps.map((e,t)=>(0,x.jsx)(V,{padding:`md`,variant:e.done?`sunken`:`outlined`,children:(0,x.jsxs)(`div`,{className:`step`,children:[(0,x.jsx)(`div`,{className:`step__mark`,children:e.done?(0,x.jsx)(H.Success,{}):(0,x.jsx)(`span`,{className:`step__n`,children:t+1})}),(0,x.jsxs)(`div`,{className:`step__body`,children:[(0,x.jsx)(`span`,{className:`step__label`,children:e.label}),!e.done&&(0,x.jsx)(`p`,{className:`muted`,children:e.how}),!e.done&&e.id===`folder`&&(0,x.jsx)(`div`,{className:`form__actions form__actions--start`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:a,onClick:c,children:`Create the profile folder`})}),!e.done&&e.id===`resume`&&(0,x.jsxs)(`div`,{className:`step__row`,children:[(0,x.jsx)(Zp,{size:`sm`,label:`Path to your resume`,placeholder:`C:\\Users\\you\\Downloads\\resume.pdf`,description:`PDF, DOCX, Markdown or text. The file is copied into Profile/ and its text extracted.`,value:r,onChange:e=>i(e.target.value)}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:a,disabled:!r.trim(),onClick:l,children:`Import`})]}),!e.done&&e.id===`profile`&&(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsxs)(`p`,{className:`muted`,children:[`The interview runs in your own AI client, not here. Connect the server once (`,(0,x.jsx)(`code`,{className:`mono`,children:`claude mcp add tekjobs -- tekjobs mcp`}),`; from a clone, opening Claude Code in `,(0,x.jsx)(`code`,{className:`mono`,children:`app/`}),` does it) and paste:`]}),(0,x.jsx)(ag,{code:gv,language:`text`,wrap:!0}),(0,x.jsx)(`p`,{className:`muted`,children:`Codex, Cursor or Claude Desktop work the same way once the tekjobs MCP server is added; see Agent access.`})]}),!e.done&&e.id===`scan`&&(0,x.jsx)(`div`,{className:`form__actions form__actions--start`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,onClick:()=>{$.startScan(!1).then(()=>X({title:`Scan started`,description:`Watch it on the Runs screen.`,tone:`success`})).catch(e=>X({title:`Could not start`,description:e.message,tone:`danger`}))},children:`Run the first scan`})})]})]})},e.id))}),t.complete&&(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,onClick:e,trailingIcon:(0,x.jsx)(H.ArrowRight,{}),children:`Go to the overview`})})]})}function vv({label:e,value:t,hint:n,tone:r=`neutral`,series:i,onClick:a}){return(0,x.jsx)(V,{padding:`md`,interactive:!!a,onClick:a,children:(0,x.jsxs)(`div`,{className:`stat`,children:[(0,x.jsx)(`span`,{className:`stat__label`,children:e}),(0,x.jsxs)(`div`,{className:`stat__row`,children:[(0,x.jsx)(`span`,{className:`stat__value`,children:t}),i&&i.length>1&&(0,x.jsx)(`div`,{className:`stat__spark`,children:(0,x.jsx)(Cp,{values:i,tone:r===`neutral`?`primary`:r,"aria-label":`${e}, per scan`})})]}),n&&(0,x.jsx)(`div`,{className:`stat__delta`,children:(0,x.jsx)(z,{tone:r,size:`sm`,children:n})})]})})}var yv=e=>e===null?`—`:`${Math.round(e*100)}%`,bv={found:`Found`,reviewed:`Reviewed`,shortlisted:`Shortlisted`,applied:`Applied`,interviewing:`Interviewing`,offer:`Offer`},xv={"design-eng":`Design engineering`,adjacent:`Adjacent titles`};function Sv({onNavigate:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(null),[a,o]=(0,b.useState)(``);if((0,b.useEffect)(()=>{$.summary().then(n).catch(e=>o(e.message)),$.outcomes().then(i).catch(()=>{})},[]),a)return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`p`,{className:`muted`,children:[`The server is not answering: `,a,`. Start it with `,(0,x.jsx)(`code`,{children:`npm run server`}),`.`]})});if(!t||!r)return(0,x.jsx)(zg,{variant:`rect`,height:`12rem`});let s=[`floor`,`stretch`,`below`,`unknown`],c=[`new`,`reviewing`,`applying`,`applied`,`interviewing`,`offer`,`rejected`,`passed`],l=r.waiting.buckets[14]??0,u=r.thisWeek.followUps.filter(e=>e.inDays<=0).length,d=r.appliedPerWeek;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[(0,x.jsx)(`b`,{children:r.funnel.applied}),` applied, `,(0,x.jsx)(`b`,{children:yv(r.responseRate)}),` answered, `,(0,x.jsx)(`b`,{children:r.funnel.interviewing}),` interviewing`,l?(0,x.jsxs)(x.Fragment,{children:[`, `,(0,x.jsx)(`b`,{children:l}),` waiting two weeks or more`]}):null,`.`,` `,`The inventory: `,t.open,` open matches across `,t.companies,` boards, floor `,t.floor?Jg(t.floor):`unset`,`, bar `,t.minScore??`unset`,`.`]})}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:()=>e(`runs`),children:`Runs`})]}),(0,x.jsxs)(`div`,{className:`stats z-stagger`,children:[(0,x.jsx)(vv,{label:`Applied`,value:String(r.funnel.applied),hint:`${r.funnel.shortlisted} shortlisted, ${r.funnel.reviewed} reviewed`,tone:`primary`,onClick:()=>e(`pipeline`)}),(0,x.jsx)(vv,{label:`Response rate`,value:yv(r.responseRate),hint:r.funnel.applied?`${r.responded} of ${r.funnel.applied} answered, interview or no`:`nothing applied to yet`,tone:r.responseRate&&r.responseRate>0?`success`:`neutral`}),(0,x.jsx)(vv,{label:`Waiting 14 days or more`,value:String(l),hint:`${r.waiting.buckets[7]??0} past 7 days, ${r.waiting.buckets[21]??0} past 21`,tone:(r.waiting.buckets[21]??0)>0?`warning`:`neutral`}),(0,x.jsx)(vv,{label:`Discovery to application`,value:r.medianDaysToApply===null?`—`:`${r.medianDaysToApply}d`,hint:`median, found to applied`})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Funnel`}),(0,x.jsx)(`p`,{children:`Each stage counts everything that reached it, whatever happened after. The rate is the share of the stage before.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Application funnel`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Stage`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Jobs`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Of the stage before`}),(0,x.jsx)(Y.HeadCell,{children:`Share`})]})}),(0,x.jsx)(Y.Body,{children:r.stages.map((e,t)=>{let n=r.stages[0]?.count||1;return(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:bv[e.stage]??e.stage}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.count}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(`span`,{className:e.rate===null?`muted`:``,children:t===0?`—`:yv(e.rate)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`div`,{className:`funnel__bar`,role:`presentation`,children:(0,x.jsx)(`span`,{style:{width:`${Math.max(e.count?2:0,Math.round(e.count/n*100))}%`}})})})]},e.stage)})})]}),(0,x.jsxs)(`p`,{className:`muted panel--pad`,children:[r.passed,` passed on, `,r.rejected,` rejected.`]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`This week`}),(0,x.jsxs)(`p`,{children:[`Follow-ups due in the next seven days`,u?`, ${u} already past`:``,`, and the interviews in progress. Dates come from each note's packet.`]})]})})}),(0,x.jsxs)(Y,{"aria-label":`This week`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{align:`end`,children:`When`})]})}),(0,x.jsxs)(Y.Body,{children:[r.thisWeek.followUps.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>e(`jobs`,t.company),children:[(0,x.jsx)(Y.Cell,{children:t.company}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`clamp`,children:t.title})}),(0,x.jsx)(Y.Cell,{align:`end`,children:(0,x.jsx)(z,{size:`sm`,tone:t.inDays<0?`danger`:t.inDays===0?`warning`:`neutral`,children:t.inDays<0?`follow up, ${-t.inDays}d late`:t.inDays===0?`follow up today`:`follow up in ${t.inDays}d`})})]},t.id)),r.thisWeek.interviewing.map(t=>(0,x.jsxs)(Y.Row,{interactive:!0,onClick:()=>e(`jobs`,t.company),children:[(0,x.jsx)(Y.Cell,{children:t.company}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`clamp`,children:t.title})}),(0,x.jsx)(Y.Cell,{align:`end`,children:(0,x.jsx)(z,{size:`sm`,tone:`primary`,children:`interviewing`})})]},t.id)),r.thisWeek.followUps.length===0&&r.thisWeek.interviewing.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:3,children:(0,x.jsx)(`span`,{className:`muted`,children:`Nothing due this week. Applied roles get a follow-up date in their packet when you mark them applied.`})})})]})]})]})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Applications per week`}),(0,x.jsx)(`p`,{children:`Sent, by the week of the packet's Applied on date.`})]})}),d.length>0?(0,x.jsx)(Ye,{series:[{name:`Applied`,values:d.map(e=>e.n)}],labels:d.map(e=>e.week.slice(5)),height:180,"aria-label":`Applications per week`}):(0,x.jsx)(`p`,{className:`muted`,children:`Nothing applied to yet.`})]})}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`What answers`}),(0,x.jsx)(`p`,{children:`By role family, then by the board that surfaced the job.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Outcomes by role family`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Role family`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Found`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Applied`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Answered`})]})}),(0,x.jsx)(Y.Body,{children:r.byKind.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:xv[e.kind]??e.kind}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.found}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.applied}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.applied?`${e.responded} (${yv(e.responded/e.applied)})`:`—`})]},e.kind))})]}),r.bySource.length>0&&(0,x.jsx)(`div`,{className:`chips panel--pad`,children:r.bySource.map(e=>(0,x.jsxs)(z,{size:`sm`,tone:e.responded?`success`:`neutral`,variant:`soft`,children:[e.source,`: `,e.applied,` applied`,e.responded?`, ${e.responded} answered`:``]},e.source))})]})]}),(0,x.jsxs)(`div`,{className:`stats z-stagger`,children:[(0,x.jsx)(vv,{label:`Open matches`,value:String(t.open),hint:`${t.byStatus.new??0} unreviewed`,onClick:()=>e(`jobs`)}),(0,x.jsx)(vv,{label:`Design-engineer roles at the floor`,value:String(t.designEng.floor),hint:`of ${t.designEng.total} with the title`,tone:`success`,onClick:()=>e(`jobs`)}),(0,x.jsx)(vv,{label:`Pay under the floor, above the stretch line`,value:String(t.byBand.stretch??0),hint:`${t.designEng.stretch} design-engineer`,tone:`warning`}),(0,x.jsx)(vv,{label:`Active applications`,value:String(t.active),hint:t.active?`in flight`:`none yet`,tone:t.active?`primary`:`neutral`,onClick:()=>e(`pipeline`)})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Pipeline`}),(0,x.jsx)(`p`,{children:`Every open note by status. Change a status in Jobs or Pipeline; the note is the record.`})]})}),(0,x.jsx)(Ye,{series:[{name:`Jobs`,values:c.map(e=>t.byStatus[e]??0)}],labels:[...c],height:200,"aria-label":`Jobs by status`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Stated pay against the floor`}),(0,x.jsx)(`p`,{children:`Open matches by band.`})]})}),(0,x.jsx)(Ye,{series:[{name:`Matches`,values:s.map(e=>t.byBand[e]??0)}],labels:[`Floor`,`Stretch`,`Below`,`Not stated`],height:200,"aria-label":`Matches by pay band`})]})})]})]})}function Cv({onNavigate:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),[a,o]=(0,b.useState)(null),[s,c]=(0,b.useState)(null),l=()=>$.today().then(n).catch(e=>i(e.message));(0,b.useEffect)(()=>{l()},[]);let u=async(e,t,n)=>{c(e.id);try{await $.setStatus(e.id,t,n),X({title:`${e.company}: ${t===`reviewing`?`shortlisted`:`passed`}`,description:n,tone:t===`reviewing`?`success`:`neutral`}),await l()}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}finally{c(null)}};if(r)return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`p`,{className:`muted`,children:[`The server is not answering: `,r,`. Start it with `,(0,x.jsx)(`code`,{children:`npm run server`}),`.`]})});if(!t)return(0,x.jsx)(zg,{variant:`rect`,height:`18rem`});let{counts:d,sections:f}=t,p=[...f.preparing,...f.followUps,...f.interviewing];return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h1`,{className:`today__date`,children:new Date().toLocaleDateString(`en-US`,{weekday:`long`,day:`numeric`,month:`long`})}),(0,x.jsx)(`p`,{children:f.triage.length===0?`Today's queue is clear. The next scan refills it.`:`${f.triage.length===1?`One`:f.triage.length} to decide on, best fit first. The other ${d.unreviewed-f.triage.length} unreviewed wait in Jobs and do not count against you. Fit is the share of the ${t.ceiling} points this criteria set can award.`})]}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,onClick:()=>e(`jobs`),children:`See all matches`})]}),(0,x.jsxs)(`div`,{className:`today__figures`,children:[(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{children:d.open}),(0,x.jsx)(`small`,{children:`open`})]}),(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{children:d.aging}),(0,x.jsx)(`small`,{children:`waiting 2d+`})]}),(0,x.jsxs)(`div`,{className:`today__figure`,children:[(0,x.jsx)(`b`,{"data-tone":d.closedUnreviewed>0?`danger`:void 0,children:d.closedUnreviewed}),(0,x.jsx)(`small`,{children:`closed unseen`})]})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsxs)(`div`,{className:`today__section-head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Decide on these`}),(0,x.jsx)(`span`,{className:`today__hint`,children:`shortlist · pass · open sheet`})]}),f.triage.length===0?(0,x.jsx)(V,{padding:`md`,children:(0,x.jsx)(Vg,{size:`sm`,title:`Inbox clear`,description:`Nothing unreviewed is open right now. The next scan will refill this.`})}):(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Matches to decide on`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Pay`}),(0,x.jsx)(Y.HeadCell,{children:`Found`}),(0,x.jsx)(Y.HeadCell,{children:`Decide`})]})}),(0,x.jsx)(Y.Body,{children:f.triage.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,selected:a===e.id,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`who__text`,children:[e.title,e.kind===`design-eng`&&(0,x.jsx)(`small`,{children:`design engineering`})]})}),(0,x.jsx)(Y.Cell,{children:e.salaryMax>0?(0,x.jsx)(z,{tone:Qg[e.payBand],size:`sm`,children:Yg(e.salary)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:Xg(e.found)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`today__actions`,onClick:e=>e.stopPropagation(),children:[(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:s===e.id,onClick:()=>u(e,`reviewing`),children:`Shortlist`}),(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,disabled:s===e.id,trailingIcon:(0,x.jsx)(H.ChevronDown,{}),children:`Pass`})}),(0,x.jsx)(Tu.Content,{align:`end`,children:Kg.map(t=>(0,x.jsx)(Tu.Item,{onSelect:()=>u(e,`passed`,t),children:t},t))})]})]})})]},e.id))})]})})]}),(0,x.jsx)(fv,{onOpen:()=>e(`mail`)}),f.started.length>0&&(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Already started`}),(0,x.jsx)(V,{padding:`none`,children:(0,x.jsxs)(Y,{"aria-label":`Applications with a packet started`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Packet`}),(0,x.jsx)(Y.HeadCell,{children:`Pay`}),(0,x.jsx)(Y.HeadCell,{children:`Status`})]})}),(0,x.jsx)(Y.Body,{children:f.started.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,selected:a===e.id,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(z,{size:`sm`,tone:`primary`,variant:`soft`,children:[e.packet,` filled`]})}),(0,x.jsx)(Y.Cell,{children:e.salaryMax>0?(0,x.jsx)(z,{tone:Qg[e.payBand],size:`sm`,children:Yg(e.salary)}):(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:e.closed?(0,x.jsxs)(z,{size:`sm`,tone:`danger`,children:[`closed `,e.closed]}):(0,x.jsx)(z,{size:`sm`,tone:e.status===`ready`?`warning`:`neutral`,children:e.status})})]},e.id))})]})}),(0,x.jsx)(`p`,{className:`muted`,children:`Work you have already put in, wherever it ranks. The fit score knows nothing about a drafted packet, so these would otherwise fall off the bottom of the queue.`})]}),(f.aging.length>0||f.missed.length>0)&&(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Going, and gone`}),(0,x.jsxs)(`div`,{className:`today__cols`,children:[f.aging.length>0&&(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsx)(`h3`,{className:`today__subheading`,children:`Still open, still unread`}),(0,x.jsx)(`p`,{className:`muted`,children:`Listings here close after two days, at the median.`}),(0,x.jsx)(`ul`,{className:`today__list`,children:f.aging.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsxs)(B,{className:`today__row`,variant:`ghost`,align:`start`,size:`sm`,onClick:()=>o(e.id),children:[(0,x.jsx)(Ev,{value:e.fit}),(0,x.jsx)(`span`,{className:`today__row-text`,children:wv(e.company,e.title,52)}),(0,x.jsxs)(z,{size:`sm`,tone:(e.days??0)>=5?`danger`:`warning`,variant:`outline`,children:[e.days,`d`]})]})},e.id))})]}),f.missed.length>0&&(0,x.jsxs)(V,{padding:`md`,children:[(0,x.jsx)(`h3`,{className:`today__subheading`,children:`Closed before you saw them`}),(0,x.jsxs)(`p`,{className:`muted`,children:[d.closedUnreviewed,` this week. This is what the queue costs when it is skipped.`]}),(0,x.jsx)(`ul`,{className:`today__list`,children:f.missed.map(e=>(0,x.jsx)(`li`,{children:(0,x.jsxs)(B,{className:`today__row`,variant:`ghost`,align:`start`,size:`sm`,onClick:()=>o(e.id),children:[(0,x.jsx)(Ev,{value:e.fit}),(0,x.jsx)(`span`,{className:`today__row-text`,children:wv(e.company,e.title,36)}),(0,x.jsx)(`span`,{className:`muted`,children:e.closed})]})},e.id))})]})]})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`In flight`}),(0,x.jsx)(V,{padding:p.length?`none`:`md`,children:p.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`Nothing in flight`,description:`Applications being prepared, follow-ups that are due, and interviews appear here once jobs move past Shortlisted.`,action:(0,x.jsx)(B,{size:`sm`,variant:`ghost`,onClick:()=>e(`pipeline`),children:`Open the pipeline`})}):(0,x.jsxs)(Y,{"aria-label":`In flight`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Fit`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Status`}),(0,x.jsx)(Y.HeadCell,{children:`Due`}),(0,x.jsx)(Y.HeadCell,{children:`Write to`})]})}),(0,x.jsx)(Y.Body,{children:p.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(Ev,{value:e.fit})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:`primary`,children:e.status})}),(0,x.jsx)(Y.Cell,{children:e.due||(0,x.jsx)(`span`,{className:`muted`,children:`—`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(Tv,{contact:e.contact})})]},e.id))})]})})]}),(0,x.jsxs)(`section`,{className:`today__section`,children:[(0,x.jsxs)(`div`,{className:`today__section-head`,children:[(0,x.jsx)(`h2`,{className:`today__heading`,children:`Waiting on a reply`}),(0,x.jsxs)(`span`,{className:`today__hint`,children:[`applied `,d.waitingDays,`d+ ago, nothing back · `,d.waiting,` in all`]})]}),(0,x.jsx)(V,{padding:f.waiting.length===0?`md`:`none`,children:f.waiting.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`Nothing has gone quiet`,description:`Applications with no answer after ${d.waitingDays} days land here, with the person to ask.`}):(0,x.jsxs)(Y,{"aria-label":`Applications waiting on a reply`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Days`}),(0,x.jsx)(Y.HeadCell,{children:`Company`}),(0,x.jsx)(Y.HeadCell,{children:`Role`}),(0,x.jsx)(Y.HeadCell,{children:`Applied`}),(0,x.jsx)(Y.HeadCell,{children:`Write to`})]})}),(0,x.jsx)(Y.Body,{children:f.waiting.map(e=>(0,x.jsxs)(Y.Row,{interactive:!0,"data-posted":z_(e.source)||void 0,onClick:()=>o(e.id),children:[(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:(0,x.jsx)(`span`,{className:`num`,"data-tone":(e.days??0)>=21?`danger`:void 0,children:e.days})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.appliedOn})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(Tv,{contact:e.contact})})]},e.id))})]})})]}),(0,x.jsx)(av,{id:a,onClose:()=>o(null),onChanged:e=>{l()}})]})}var wv=(e,t,n=64)=>{let r=`${e} — ${t}`.replace(/\s+/g,` `).trim();return r.length>n?`${r.slice(0,n-1).trimEnd()}…`:r};function Tv({contact:e}){return e?(0,x.jsxs)(`span`,{className:`who__text`,children:[e.email?(0,x.jsxs)(`a`,{className:`people__thread`,href:`mailto:${e.email}`,onClick:e=>e.stopPropagation(),children:[e.name,` ↗`]}):e.name,(0,x.jsxs)(`small`,{children:[e.role||`contact`,e.others>0?` · +${e.others}`:``]})]}):(0,x.jsx)(`span`,{className:`muted`,title:`Open the sheet's People tab to add someone.`,children:`no one on the thread`})}function Ev({value:e}){return(0,x.jsx)(z,{size:`sm`,tone:e>=80?`success`:e>=60?`primary`:`neutral`,variant:e>=60?`soft`:`outline`,children:(0,x.jsx)(`span`,{className:`num`,children:e})})}var Dv=[{id:`reviewing`,title:`Reviewing`},{id:`applying`,title:`Applying`,limit:5},{id:`ready`,title:`Ready`,limit:5},{id:`applied`,title:`Applied`},{id:`interviewing`,title:`Interviewing`},{id:`offer`,title:`Offer`}],Ov=new Set(Dv.map(e=>e.id));function kv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)([]),o=()=>$.jobs({status:`all`,limit:2e3}).then(e=>t(e.rows)).catch(e=>X({title:`Could not load the board`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{o()},[]);let s=async(n,r)=>{let i=e?.find(e=>e.id===n);if(i&&i.status!==r){t(e=>e&&e.map(e=>e.id===n?{...e,status:r}:e));try{await $.setStatus(n,r),X({title:`${i.company}: ${r}`,tone:`success`})}catch(e){X({title:`Move not saved`,description:e.message,tone:`danger`}),o()}}},c=e=>t(t=>t&&t.map(t=>t.id===e.id?{...t,status:e.status}:t)),l=(0,b.useMemo)(()=>{let t=new Map;for(let n of e??[])Ov.has(n.status)&&t.set(n.company,(t.get(n.company)??0)+1);return[...t.entries()].sort((e,t)=>t[1]-e[1]||e[0].localeCompare(t[0])).map(([e,t])=>({value:e,label:e,hint:`${t} on the board`}))},[e]);if(!e)return(0,x.jsx)(zg,{variant:`rect`,height:`20rem`});let u=new Set(i),d=e.filter(e=>Ov.has(e.status)&&(u.size===0||u.has(e.company))).sort((e,t)=>t.score-e.score),f=e.filter(e=>e.status===`new`).length,p=e.filter(e=>e.status===`rejected`||e.status===`passed`).length;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Committed work only. Drag a card, or focus one and press Space to lift it, arrows to move it, Enter to drop. Every move is written to the job note.`,f?` ${f} new matches wait on Today, not here.`:``,p?` ${p} closed are not shown.`:``]})})}),(0,x.jsx)(`div`,{className:`toolbar`,children:(0,x.jsx)(Wg,{className:`toolbar__filter toolbar__filter--wide`,size:`sm`,multiple:!0,label:`Companies`,placeholder:i.length?``:`All companies`,description:`Narrow the board to the companies you are actually working.`,emptyMessage:`No company on the board matches that.`,options:l,value:i,onValueChange:a})}),(0,x.jsx)(Hg,{label:`Job pipeline`,columns:Dv,cards:d,cardId:e=>e.id,cardColumn:e=>e.status,cardLabel:e=>`${e.title} at ${e.company}`,onMove:e=>s(e.cardId,e.to),renderCard:e=>(0,x.jsxs)(`div`,{className:`kcard`,"data-posted":z_(e.source)||void 0,onClick:()=>r(e.id),children:[(0,x.jsxs)(`div`,{className:`kcard__head`,children:[(0,x.jsxs)(`span`,{className:`kcard__company posted-co`,children:[e.company,z_(e.source)&&(0,x.jsx)(B_,{})]}),(0,x.jsxs)(Tu,{children:[(0,x.jsx)(Tu.Trigger,{asChild:!0,children:(0,x.jsx)(B,{variant:`ghost`,size:`sm`,"aria-label":`Move ${e.title}`,leadingIcon:(0,x.jsx)(H.More,{}),onClick:e=>e.stopPropagation()})}),(0,x.jsx)(Tu.Content,{align:`end`,onClick:e=>e.stopPropagation(),children:Gg.filter(t=>t!==e.status).map(t=>(0,x.jsxs)(Tu.Item,{onSelect:()=>s(e.id,t),children:[`Move to `,t]},t))})]})]}),(0,x.jsx)(`span`,{className:`kcard__title`,children:e.title}),(0,x.jsxs)(`div`,{className:`kcard__meta num`,children:[(0,x.jsx)(`span`,{className:`kcard__score`,children:e.score}),e.salaryMax>0&&(0,x.jsx)(`span`,{className:e.payBand===`floor`?`kcard__pay kcard__pay--floor`:`kcard__pay`,children:Yg(e.salary)})]})]})}),(0,x.jsx)(av,{id:n,onClose:()=>r(null),onChanged:c})]})}var Av={ok:`success`,warn:`warning`,missing:`danger`,info:`neutral`};function jv({s:e}){return(0,x.jsxs)(`div`,{className:`detail`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:e.basics.name||`No name yet`}),(0,x.jsx)(`p`,{children:[e.basics.currentRole,e.basics.location].filter(Boolean).join(` · `)||`The Basics section is empty.`})]}),(0,x.jsxs)(`div`,{className:`chips`,children:[(0,x.jsx)(z,{size:`sm`,tone:e.status===`draft`?`warning`:`success`,children:e.status===`draft`?`draft`:`reviewed`}),e.updated&&(0,x.jsxs)(z,{size:`sm`,tone:`neutral`,variant:`outline`,children:[`updated `,e.updated]})]})]}),e.summary?(0,x.jsx)(`p`,{children:e.summary}):(0,x.jsx)(`p`,{className:`muted`,children:`The three-sentence summary is still the template. It leads every cover letter.`}),(e.basics.email||e.basics.links.length>0)&&(0,x.jsx)(`p`,{className:`muted mono`,children:[e.basics.email,...e.basics.links].filter(Boolean).join(` · `)})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Needs attention`}),(0,x.jsx)(`p`,{children:`What a reader of these notes would trip on. Each line names the note to fix.`})]}),(0,x.jsx)(z,{size:`sm`,tone:e.attention.length?`warning`:`success`,children:e.attention.length?`${e.attention.length} item${e.attention.length===1?``:`s`}`:`nothing stale`})]}),e.attention.length>0?(0,x.jsx)(`ul`,{className:`summary__list`,children:e.attention.map(e=>(0,x.jsxs)(`li`,{children:[(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.note}),` `,e.text]},e.text))}):(0,x.jsx)(`p`,{className:`muted`,children:`Every field is filled, the resume of record is fresh, and the criteria agree with the profile.`})]})}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Target roles`}),(0,x.jsx)(`p`,{children:`From the profile's table. "In criteria" means a title term the scan scores on matches the title; a title without one is never found by the scan.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Target roles`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Tier`}),(0,x.jsx)(Y.HeadCell,{children:`Title`}),(0,x.jsx)(Y.HeadCell,{children:`In criteria`})]})}),(0,x.jsxs)(Y.Body,{children:[e.targets.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:e.tier===`A`?`primary`:`neutral`,children:e.tier})}),(0,x.jsx)(Y.Cell,{children:e.title}),(0,x.jsx)(Y.Cell,{children:e.term?(0,x.jsxs)(`span`,{className:`muted`,children:[`yes · `,(0,x.jsx)(`span`,{className:`mono`,children:e.term})]}):(0,x.jsx)(z,{size:`sm`,tone:`warning`,variant:`soft`,children:`no title term`})})]},`${e.tier}-${e.title}`)),e.targets.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:3,children:(0,x.jsx)(`span`,{className:`muted`,children:`The Target roles table is empty.`})})})]})]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Constraints against the criteria`}),(0,x.jsx)(`p`,{children:`What the profile says beside what the scan enforces.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Constraints against the criteria`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Constraint`}),(0,x.jsx)(Y.HeadCell,{children:`Profile`}),(0,x.jsx)(Y.HeadCell,{children:`Criteria`}),(0,x.jsx)(Y.HeadCell,{})]})}),(0,x.jsx)(Y.Body,{children:e.constraints.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.label}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:e.profile?``:`muted`,children:e.profile||`not set`})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:e.criteria?`num`:`muted`,children:e.criteria||`—`})}),(0,x.jsx)(Y.Cell,{children:e.level!==`info`&&(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.level===`ok`?`agree`:e.level===`warn`?`differ`:`missing`})})]},e.label))})]})]})]}),(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Documents`}),(0,x.jsx)(`p`,{children:`The notes and files the drafts are built from, and how fresh each one is.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`Documents`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Document`}),(0,x.jsx)(Y.HeadCell,{children:`State`}),(0,x.jsx)(Y.HeadCell,{children:`Where`})]})}),(0,x.jsx)(Y.Body,{children:e.documents.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.label}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(z,{size:`sm`,tone:Av[e.level],variant:`soft`,children:e.state})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted mono`,children:e.where})})]},e.label))})]})]}),(0,x.jsxs)(V,{padding:`none`,children:[(0,x.jsx)(`div`,{className:`panel panel--pad`,children:(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`What feeds what`}),(0,x.jsx)(`p`,{children:`Which note each thing the app writes is built from. Change the note, and everything after it changes.`})]})})}),(0,x.jsxs)(Y,{"aria-label":`What feeds what`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Produces`}),(0,x.jsx)(Y.HeadCell,{children:`Reads`})]})}),(0,x.jsx)(Y.Body,{children:e.feeds.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:e.produces}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.reads})})]},e.produces))})]})]})]}),e.proofPoints.length>0&&(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Proof points`}),(0,x.jsxs)(`p`,{children:[e.proofPoints.length,` on file; the ones without a number are flagged above. Cover letters quote from these and nothing else.`]})]})}),(0,x.jsx)(`ul`,{className:`summary__list`,children:e.proofPoints.map(e=>(0,x.jsxs)(`li`,{children:[e.hasNumber?null:(0,x.jsx)(z,{size:`sm`,tone:`warning`,variant:`soft`,children:`no number`}),` `,e.text]},e.text))})]})})]})}var Mv=e=>e.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/,``);function Nv({note:e,onSaved:t}){let[n,r]=(0,b.useState)(e.markdown),[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(e.editable?`edit`:`preview`);(0,b.useEffect)(()=>r(e.markdown),[e.markdown]);let c=n!==e.markdown;return(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`p`,{children:e.hint}),(0,x.jsx)(`p`,{className:`muted`,children:(0,x.jsx)(`code`,{children:e.path})})]}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsx)(Z,{value:o,onValueChange:e=>s(e),variant:`pill`,size:`sm`,children:(0,x.jsxs)(Z.List,{"aria-label":`Edit or preview`,children:[(0,x.jsx)(Z.Trigger,{value:`edit`,children:e.editable?`Edit`:`Source`}),(0,x.jsx)(Z.Trigger,{value:`preview`,children:`Preview`})]})}),(0,x.jsx)(B,{asChild:!0,variant:`soft`,size:`sm`,trailingIcon:(0,x.jsx)(H.ExternalLink,{}),children:(0,x.jsx)(`a`,{href:`obsidian://open?path=${encodeURIComponent(e.path)}`,children:`Open in Obsidian`})})]})]}),!e.exists&&(0,x.jsx)(z,{tone:`warning`,size:`sm`,children:`This note does not exist yet; saving creates it.`}),o===`preview`?(0,x.jsx)(`div`,{className:`preview-doc`,children:(0,x.jsx)(dg,{text:Mv(n)||`_Nothing here yet._`})}):(0,x.jsx)(Xp,{label:`${e.title} (Markdown)`,font:`mono`,rows:28,resize:`vertical`,value:n,onChange:e=>r(e.target.value),disabled:!e.editable,description:e.editable?void 0:`Read-only here. Pick a variant below, or edit the resume file and run tekjobs resume sync.`}),e.editable&&(0,x.jsxs)(`div`,{className:`form__actions`,children:[(0,x.jsx)(B,{variant:`ghost`,size:`sm`,disabled:!c||i,onClick:()=>r(e.markdown),children:`Discard`}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:!c||i,loading:i,onClick:async()=>{a(!0);try{let r=await $.saveProfileNote(e.key,n);X({title:`${e.title} saved`,description:r.saved,tone:`success`}),t()}catch(t){X({title:`${e.title} not saved`,description:t.message,tone:`danger`})}a(!1)},children:`Save to the vault`})]})]})})}function Pv({onChanged:e}){let[t,n]=(0,b.useState)(null),[r,i]=(0,b.useState)(``),a=()=>$.resumes().then(n).catch(e=>X({title:`Could not read the resume folder`,description:e.message,tone:`danger`}));(0,b.useEffect)(()=>{a()},[]);let o=async t=>{i(t);try{let n=await $.useResume(t);X({title:`${t} is the resume of record`,description:`${n.chars} characters into Profile/Resume.md; ${n.added.length} lines new, ${n.removed.length} gone${n.stale.length?`, ${n.stale.length} drafts quote a removed claim`:``}.`,tone:`success`}),a(),e()}catch(e){X({title:`Not switched`,description:e.message,tone:`danger`})}i(``)},s=e=>`${Math.max(1,Math.round(e/1024))} KB`;return(0,x.jsx)(V,{padding:t&&t.files.length?`none`:`md`,children:t?t.files.length===0?(0,x.jsx)(Vg,{size:`sm`,title:`No resume variants yet`,description:`Drop PDF, DOCX, Markdown or text files into ${t.dir}${t.exists?``:` (the folder does not exist yet)`} and they appear here. The folder is set in Settings.`}):(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(Y,{"aria-label":`Resume variants`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`File`}),(0,x.jsx)(Y.HeadCell,{children:`Changed`}),(0,x.jsx)(Y.HeadCell,{children:`Size`}),(0,x.jsx)(Y.HeadCell,{children:`Use`})]})}),(0,x.jsx)(Y.Body,{children:t.files.map(e=>(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`span`,{className:`chips`,children:[e.name,e.current&&(0,x.jsx)(z,{size:`sm`,tone:`primary`,variant:`soft`,children:`resume of record`})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:e.modified})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num muted`,children:s(e.size)})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsx)(B,{size:`sm`,variant:`ghost`,tone:`neutral`,onClick:()=>$.openResume(e.name).catch(e=>X({title:`Could not open`,description:e.message,tone:`danger`})),children:`Open`}),!e.current&&(0,x.jsx)(B,{size:`sm`,variant:`soft`,tone:`primary`,disabled:!!r,loading:r===e.name,onClick:()=>o(e.name),children:`Make it the resume of record`})]})})]},e.name))})]}),(0,x.jsxs)(`p`,{className:`muted variants__foot`,children:[`From `,(0,x.jsx)(`code`,{className:`mono`,children:t.dir}),`. Making one the record reads it into Profile/Resume.md, which every tailored resume and letter starts from; the packet's Resume variant field offers these names.`]})]}):(0,x.jsx)(zg,{lines:3})})}function Fv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),i=()=>($.profileSummary().then(r).catch(()=>{}),$.profileNotes().then(e=>t(e.notes)).catch(e=>X({title:`Could not load the profile`,description:e.message,tone:`danger`})));return(0,b.useEffect)(()=>{i()},[]),e?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsx)(`p`,{children:`Who you are, how the story is told, and how you write. Cover letters, tailored resumes and application packets read these notes; the scan reads the Criteria page. Saving keeps yesterday's copy beside the note.`})})}),(0,x.jsxs)(Z,{defaultValue:`summary`,variant:`line`,size:`sm`,children:[(0,x.jsxs)(Z.List,{"aria-label":`Profile notes`,children:[(0,x.jsx)(Z.Trigger,{value:`summary`,children:`Summary`}),e.map(e=>(0,x.jsx)(Z.Trigger,{value:e.key,children:e.title},e.key))]}),(0,x.jsx)(Z.Content,{value:`summary`,children:n?(0,x.jsx)(jv,{s:n}):(0,x.jsx)(zg,{variant:`rect`,height:`12rem`})}),e.map(e=>(0,x.jsx)(Z.Content,{value:e.key,children:(0,x.jsxs)(`div`,{className:`detail`,children:[e.key===`resume`&&(0,x.jsx)(Pv,{onChanged:i}),(0,x.jsx)(Nv,{note:e,onSaved:i})]})},e.key))]})]}):(0,x.jsx)(zg,{variant:`rect`,height:`24rem`})}var Iv=`__active__`,Lv={success:{label:`Success`,tone:`success`},partial:{label:`Partial`,tone:`warning`},failed:{label:`Failed`,tone:`danger`}},Rv=e=>e.dry?`dry run`:e.via===`schedule`?`scheduled`:e.via===`mcp`?`agent`:e.via===`cli`?`manual, CLI`:e.via===`app`?`manual`:``,zv=e=>{let t=e.match(/^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}) UTC$/);if(!t)return``;let n=new Date(`${t[1]}T${t[2]}:00Z`);return Number.isNaN(n.getTime())?``:`${n.toLocaleString()} local`};function Bv(e){if(e.running||e.exitCode===null)return null;if(e.exitCode!==0)return`failed`;let t=(e.output.find(e=>/Boards: \d+\/\d+/.test(e))||``).match(/Boards: (\d+)\/(\d+)/),n=e.output.some(e=>/^- .+?: failed: /.test(e)||/^\s+x /.test(e));return t?Number(t[1])===0&&Number(t[2])>0?`failed`:Number(t[1])===Number(t[2])&&!n?`success`:`partial`:`success`}function Vv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)(null),[i,a]=(0,b.useState)([]),[o,s]=(0,b.useState)(Iv),[c,l]=(0,b.useState)(null),u=()=>$.runs().then(t).catch(()=>t([]));(0,b.useEffect)(()=>{u(),$.scan().then(r).catch(()=>{}),$.criteriaPresets().then(a).catch(()=>a([]))},[]),(0,b.useEffect)(()=>{if(!n?.running)return;let e=setInterval(()=>$.scan().then(e=>{r(e),e.running||u()}).catch(()=>{}),2e3);return()=>clearInterval(e)},[n?.running]);let d=async(e,t=!1)=>{let n=o===Iv?void 0:o;try{r(await $.startScan(e,n,t)),X({title:t?`Retrying the failed boards`:e?`Dry run started`:`Scan started`,description:t?`Only the boards whose last attempt failed, no feeds.`:`Every board, scored with ${n?`the "${n}" preset`:`the active criteria`}.`,tone:`success`})}catch(e){X({title:`Could not start`,description:e.message,tone:`danger`})}},f=(e??[]).flatMap(e=>e.runs.map((t,n)=>({...t,key:`${e.date}-${n}`})).reverse()),p=f[0],m=!!p&&!p.dry&&p.boardsOk<p.boardsTotal,h=n?Bv(n):null;return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsxs)(`div`,{className:`page__head`,children:[(0,x.jsx)(`div`,{children:(0,x.jsx)(`p`,{children:`Each scan fetches every board, scores, and writes new matches to the vault. The morning task runs it with the active criteria; here you can run one now, with the active set or a preset from the Criteria page. Times are UTC; hover one for your clock.`})}),(0,x.jsxs)(`div`,{className:`pager__buttons`,children:[(0,x.jsxs)(J,{size:`sm`,label:`Score with`,value:o,onValueChange:s,disabled:!!n?.running,children:[(0,x.jsx)(J.Item,{value:Iv,children:`Active criteria`}),i.map(e=>(0,x.jsx)(J.Item,{value:e.name,children:e.name},e.name))]}),m&&(0,x.jsx)(Bh,{content:`${p.boardsTotal-p.boardsOk} board${p.boardsTotal-p.boardsOk===1?``:`s`} did not answer last time. Fetch only those; Sources shows each one's health.`,children:(0,x.jsx)(B,{variant:`soft`,tone:`danger`,size:`sm`,disabled:!!n?.running,leadingIcon:(0,x.jsx)(H.Refresh,{}),onClick:()=>d(!1,!0),children:`Retry failed`})}),(0,x.jsx)(B,{variant:`soft`,size:`sm`,disabled:!!n?.running,onClick:()=>d(!0),children:`Dry run`}),(0,x.jsx)(B,{tone:`primary`,size:`sm`,disabled:!!n?.running,leadingIcon:n?.running?(0,x.jsx)(Bg,{size:`sm`}):(0,x.jsx)(H.Refresh,{}),onClick:()=>d(!1),children:n?.running?`Scanning`:`Scan now`})]})]}),n&&(n.running||n.output.length>0)&&(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`runs__live`,children:n.running?`Running`:h?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(z,{tone:Lv[h].tone,size:`sm`,children:Lv[h].label}),` `,(0,x.jsx)(`span`,{children:h===`failed`?`exit code ${n.exitCode}`:`finished`})]}):`Finished`}),(0,x.jsxs)(`p`,{children:[n.startedAt?`Started ${n.startedAt.replace(`T`,` `).slice(0,19)} UTC`:``,n.criteria?` · preset "${n.criteria}"`:``]})]}),n.running&&(0,x.jsx)(Bg,{showLabel:!0,label:`Fetching boards`,size:`sm`})]}),(0,x.jsx)(ag,{code:n.output.slice(-40).join(`
77
+ `)||`…`,language:`text`,showCopy:!1,wrap:!0})]})}),f.length>1&&(0,x.jsxs)(`div`,{className:`charts`,children:[(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsx)(`div`,{className:`panel__head`,children:(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`New matches per scan`}),(0,x.jsx)(`p`,{children:`What each of the last twelve runs added, most recent on the right.`})]})}),(0,x.jsx)(Fi,{series:[{name:`New matches`,values:[...f].slice(0,12).reverse().map(e=>e.newMatches)}],labels:[...f].slice(0,12).reverse().map(e=>e.when.slice(5,16)),area:!0,height:200,"aria-label":`New matches per scan`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`panel`,children:[(0,x.jsxs)(`div`,{className:`panel__head`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{children:`Last scan`}),(0,x.jsx)(`p`,{children:p?p.when:``})]}),p&&(0,x.jsx)(z,{tone:Lv[p.outcome].tone,size:`sm`,children:Lv[p.outcome].label})]}),p&&(0,x.jsxs)(`dl`,{className:`detail__grid`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Postings scanned`}),(0,x.jsx)(`dd`,{children:p.scanned.toLocaleString()})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Above the bar`}),(0,x.jsx)(`dd`,{children:p.matched})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`New notes`}),(0,x.jsx)(`dd`,{children:p.dry?`dry run`:p.newMatches})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Closed listings`}),(0,x.jsx)(`dd`,{children:p.dry?`—`:p.closed})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Duration`}),(0,x.jsxs)(`dd`,{children:[p.seconds,`s`]})]}),(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`dt`,{children:`Boards`}),(0,x.jsxs)(`dd`,{children:[p.boardsOk,`/`,p.boardsTotal]})]})]})]})})]}),(0,x.jsx)(V,{padding:`none`,children:e===null?(0,x.jsx)(`div`,{className:`loading`,children:(0,x.jsx)(zg,{lines:6})}):(0,x.jsxs)(Y,{"aria-label":`Scan history`,density:`md`,children:[(0,x.jsx)(Y.Head,{children:(0,x.jsxs)(Y.Row,{children:[(0,x.jsx)(Y.HeadCell,{children:`Outcome`}),(0,x.jsx)(Y.HeadCell,{children:`When`}),(0,x.jsx)(Y.HeadCell,{children:`Boards`}),(0,x.jsx)(Y.HeadCell,{children:`Criteria`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Scanned`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Above bar`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`New`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Closed`}),(0,x.jsx)(Y.HeadCell,{align:`end`,numeric:!0,children:`Seconds`})]})}),(0,x.jsxs)(Y.Body,{children:[f.map(e=>{let t=[...e.failed?e.failed.split(/;\s*/).filter(Boolean).map(e=>`board: ${e}`):[],...(e.feedsFailed||[]).map(e=>`feed: ${e}`)],n=t.length>0,r=c===e.key;return[(0,x.jsxs)(Y.Row,{interactive:n,onClick:n?()=>l(r?null:e.key):void 0,"aria-expanded":n?r:void 0,children:[(0,x.jsx)(Y.Cell,{children:(0,x.jsxs)(`div`,{className:`runs__outcome`,children:[(0,x.jsx)(z,{tone:Lv[e.outcome].tone,variant:e.outcome===`success`?`soft`:`solid`,size:`sm`,children:Lv[e.outcome].label}),Rv(e)&&(0,x.jsx)(`small`,{className:`muted`,children:Rv(e)})]})}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`num`,title:zv(e.when),children:e.when})}),(0,x.jsxs)(Y.Cell,{children:[(0,x.jsxs)(`span`,{className:`num`,children:[e.boardsOk,`/`,e.boardsTotal]}),n&&(0,x.jsxs)(`span`,{className:`muted`,children:[` · `,t.length,` problem`,t.length===1?``:`s`,` `,r?`▾`:`▸`]})]}),(0,x.jsx)(Y.Cell,{children:(0,x.jsx)(`span`,{className:`muted`,children:e.criteria||`—`})}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.scanned.toLocaleString()}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.matched}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.dry?(0,x.jsx)(`span`,{className:`muted`,children:`—`}):e.newMatches}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.dry?(0,x.jsx)(`span`,{className:`muted`,children:`—`}):e.closed}),(0,x.jsx)(Y.Cell,{align:`end`,numeric:!0,children:e.seconds})]},e.key),n&&r?(0,x.jsx)(Y.Row,{children:(0,x.jsxs)(Y.Cell,{colSpan:9,children:[(0,x.jsx)(`ul`,{className:`runs__problems`,children:t.map(e=>(0,x.jsx)(`li`,{className:`mono`,children:e},e))}),(0,x.jsx)(`p`,{className:`muted`,children:`A board that fails once is usually a hiccup; one that fails every run has moved. Sources shows each board's health and last success.`})]})},`${e.key}-problems`):null]}),f.length===0&&(0,x.jsx)(Y.Row,{children:(0,x.jsx)(Y.Cell,{colSpan:9,children:(0,x.jsx)(`span`,{className:`muted`,children:`No scans logged yet.`})})})]})]})})]})}function Hv(){let[e,t]=(0,b.useState)(null),[n,r]=(0,b.useState)({profile:``,resumeDir:``,llmCommand:``,llmArgs:``,contact:``}),[i,a]=(0,b.useState)(!1),[o,s]=(0,b.useState)(!1),c=()=>$.settings().then(e=>{t(e),r({profile:e.profile.configured||e.profile.active,resumeDir:e.resumeDir.configured||e.resumeDir.path,llmCommand:e.llm.command,llmArgs:e.llm.args,contact:e.contact})}).catch(e=>X({title:`Could not read the settings`,description:e.message,tone:`danger`}));return(0,b.useEffect)(()=>{c()},[]),e?(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`div`,{className:`page__head`,children:(0,x.jsx)(`div`,{children:(0,x.jsxs)(`p`,{children:[`Where things live. These are the only settings kept outside the profile folder, in `,(0,x.jsx)(`code`,{className:`mono`,children:e.configFile}),`; everything about the search itself is a note in the folder.`]})})}),(0,x.jsxs)(`div`,{className:`detail`,children:[o&&(0,x.jsxs)(z,{tone:`warning`,size:`md`,children:[`The profile folder changed. Restart the server (`,(0,x.jsx)(`code`,{className:`mono`,children:`npm run server`}),`, or the scheduled task's next run) to switch; until then the app keeps reading `,e.profile.active,`.`]}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Profile folder`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`Your job search: profile, resume, criteria, watchlist, one note per job, logs. Plain markdown; point Obsidian at it. Reading now: `,(0,x.jsx)(`code`,{className:`mono`,children:e.profile.active}),e.profile.fromEnv?` (set by TEKJOBS_PROFILE in the environment, which wins over this file)`:``,`.`]})]}),(0,x.jsx)(Zp,{label:`Folder`,value:n.profile,onChange:e=>r({...n,profile:e.target.value}),description:`Must exist. To start a new profile somewhere, run tekjobs init <dir> instead; it writes the starter notes. Takes effect on the next server start.`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Resume variants folder`}),(0,x.jsxs)(`p`,{className:`muted`,children:[`PDF, DOCX, Markdown or text files, one per variant. The Profile page lists them and makes any one the resume of record; the packet's Resume variant field offers their names. `,e.resumeDir.exists?``:`This folder does not exist yet; it is optional until you keep more than one resume.`]})]}),(0,x.jsx)(Zp,{label:`Folder`,value:n.resumeDir,onChange:e=>r({...n,resumeDir:e.target.value}),description:`Default: Templates/Resume inside the profile folder. Resume of record now: ${e.resumeSource||`not set. Import one on the Onboarding page, or run tekjobs resume <file>`}.`})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Writing CLI`}),(0,x.jsx)(`p`,{className:`muted`,children:`The local coding CLI that writes letters and tailored resumes and reads the mailbox. It must be signed in on this machine. Claude Code by default; another CLI works if it takes the prompt on stdin and prints the answer.`})]}),(0,x.jsxs)(`div`,{className:`form__row`,children:[(0,x.jsx)(Zp,{label:`Command`,value:n.llmCommand,onChange:e=>r({...n,llmCommand:e.target.value})}),(0,x.jsx)(Zp,{label:`Arguments`,value:n.llmArgs,onChange:e=>r({...n,llmArgs:e.target.value}),font:`mono`})]})]})}),(0,x.jsx)(V,{padding:`md`,children:(0,x.jsxs)(`div`,{className:`form`,children:[(0,x.jsxs)(`div`,{children:[(0,x.jsx)(`h2`,{className:`settings__h`,children:`Contact for scans`}),(0,x.jsx)(`p`,{className:`muted`,children:`Optional. Added to the user agent on every request the scan makes, so a site can reach the person running it.`})]}),(0,x.jsx)(Zp,{label:`Email`,type:`email`,value:n.contact,onChange:e=>r({...n,contact:e.target.value})})]})}),(0,x.jsx)(`div`,{className:`form__actions`,children:(0,x.jsx)(B,{tone:`primary`,size:`sm`,loading:i,onClick:async()=>{a(!0);try{let e=await $.saveSettings(n);t(e),s(e.restart||o),X({title:`Settings saved`,description:e.configFile,tone:`success`})}catch(e){X({title:`Not saved`,description:e.message,tone:`danger`})}a(!1)},children:`Save settings`})})]})]}):(0,x.jsx)(zg,{variant:`rect`,height:`20rem`})}function Uv(){let[e,t]=(0,b.useState)(()=>{let e=new URLSearchParams(window.location.search).get(`theme`);if(e===`light`||e===`dark`)return e;let t=document.documentElement.dataset.theme;return t===`light`||t===`dark`?t:window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`});return(0,b.useEffect)(()=>{document.documentElement.dataset.theme=e},[e]),[e,()=>t(e=>e===`light`?`dark`:`light`)]}function Wv(){let e=()=>{let[e,t]=window.location.hash.replace(/^#\/?/,``).split(`?`);return{page:[`onboarding`,`today`,`overview`,`jobs`,`pipeline`,`mail`,`people`,`companies`,`criteria`,`profile`,`runs`,`agent`,`settings`].includes(e??``)?e:`today`,q:new URLSearchParams(t).get(`q`)??``}},[t,n]=(0,b.useState)(e);return(0,b.useEffect)(()=>{let t=()=>n(e());return window.addEventListener(`hashchange`,t),()=>window.removeEventListener(`hashchange`,t)},[]),[t.page,t.q,(e,t)=>{window.location.hash=t?`/${e}?q=${encodeURIComponent(t)}`:`/${e}`}]}function Gv(){let[e,t,n]=Wv(),[r,i]=Uv(),[a,o]=(0,b.useState)(!0),[s,c]=(0,b.useState)({}),[l,u]=(0,b.useState)(``);return(0,b.useEffect)(()=>{$.onboarding().then(e=>{o(e.complete),!e.complete&&!window.location.hash&&n(`onboarding`)}).catch(()=>{})},[]),(0,b.useEffect)(()=>{$.summary().then(e=>{c(t=>({...t,jobs:e.open,companies:e.companies})),e.lastRun&&u(`Last scan ${e.lastRun.when.slice(11,16)} · ${e.lastRun.boardsOk}/${e.lastRun.boardsTotal} boards`)}).catch(()=>{}),$.today().then(e=>c(t=>({...t,today:e.sections.triage.length}))).catch(()=>{}),$.mail().then(e=>c(t=>({...t,mail:e.groups.length}))).catch(()=>{})},[e]),(0,x.jsx)(Bh.Provider,{children:(0,x.jsx)($m.Provider,{position:`bottom-right`,children:(0,x.jsx)(c_,{page:e,onNavigate:e=>n(e),onSearch:e=>n(`jobs`,e),theme:r,onToggleTheme:i,onboarded:a,counts:s,lastScan:l,children:(0,x.jsxs)(`div`,{className:`page z-enter-fade`,children:[e===`onboarding`&&(0,x.jsx)(_v,{onDone:()=>n(`overview`)}),e===`today`&&(0,x.jsx)(Cv,{onNavigate:n}),e===`overview`&&(0,x.jsx)(Sv,{onNavigate:n}),e===`jobs`&&(0,x.jsx)(rv,{initialQuery:t}),e===`pipeline`&&(0,x.jsx)(kv,{}),e===`mail`&&(0,x.jsx)(dv,{}),e===`people`&&(0,x.jsx)(M_,{}),e===`companies`&&(0,x.jsx)(g_,{}),e===`criteria`&&(0,x.jsx)(D_,{}),e===`profile`&&(0,x.jsx)(Fv,{}),e===`runs`&&(0,x.jsx)(Vv,{}),e===`agent`&&(0,x.jsx)(d_,{}),e===`settings`&&(0,x.jsx)(Hv,{})]},e)})})})}(0,y.createRoot)(document.getElementById(`root`)).render((0,x.jsx)(b.StrictMode,{children:(0,x.jsx)(Gv,{})}));
@@ -8,7 +8,7 @@
8
8
  <link rel="icon" href="/brand/tekjobs-avatar-192.png" type="image/png" sizes="192x192" />
9
9
  <link rel="apple-touch-icon" href="/brand/tekjobs-avatar-192.png" />
10
10
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:wght@500;600&family=Hanken+Grotesk:wght@400;500;600&family=Azeret+Mono:wght@400;500&display=swap" data-zengin="fonts" />
11
- <script type="module" crossorigin src="/assets/index-BTDWWylf.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-BLIlxd3x.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CR3ppGJT.css">
13
13
  </head>
14
14
  <body>
@@ -33,7 +33,7 @@ export const TOOLS = [
33
33
  { name: 'application_packet', description: "The application packet for one job as structured data: every field, what is in it, which required ones are still missing, and whether it is ready for a person to approve. 'ready' means the required fields are filled, not that the application is good, and it is never permission to send anything.", inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] } },
34
34
  { name: 'application_materials', description: 'Everything needed to tailor an application for one job: the job note plus the candidate profile, positioning note, and current resume draft from the vault. Read this, then draft; then save with save_application_field.', inputSchema: { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] } },
35
35
  { name: 'summary', description: 'Pipeline counts by status, pay band and kind; last scan; current floor, stretch and score bar.', inputSchema: { type: 'object', properties: {} } },
36
- { name: 'run_scan', description: 'Start a scan of every board now. It returns at once; the scan runs on its own (it survives this session ending) and takes two to three minutes. Poll scan_status. Pass dry=true to score without writing notes. Pass criteria=<preset name> to score this one run with a named criteria preset instead of the active Search Criteria (see list_criteria_presets).', inputSchema: { type: 'object', properties: { dry: { type: 'boolean' }, criteria: { type: 'string' } } } },
36
+ { name: 'run_scan', description: 'Start a scan of every board now. It returns at once; the scan runs on its own (it survives this session ending) and takes two to three minutes. Poll scan_status. Pass dry=true to score without writing notes. Pass criteria=<preset name> to score this one run with a named criteria preset instead of the active Search Criteria (see list_criteria_presets). Pass wait=<seconds> (up to 300) to answer only when the scan has finished, for a client that cannot poll between turns; the scan keeps running if the wait ends first.', inputSchema: { type: 'object', properties: { dry: { type: 'boolean' }, criteria: { type: 'string' }, wait: { type: 'number', description: 'seconds to wait for the scan to finish, up to 300; omit to return at once' } } } },
37
37
  { name: 'mail_check', description: 'Start a read-only pass over the person\'s mailbox for application updates (confirmations, rejections, interview invitations) through the local CLI\'s Gmail connector, with only the Gmail read tools allowed. Runs in the background for a few minutes; poll mail_items. days: how far back (default: since the last check, or 21 days the first time).', inputSchema: { type: 'object', properties: { days: { type: 'number' } } } },
38
38
  { name: 'mail_items', description: 'The application emails found so far, each matched to a job note (exact role, same company, or none) with what confirming it would do. Confirming is done by the person in the app; an agent can read these and tell them what is waiting.', inputSchema: { type: 'object', properties: {} } },
39
39
  { name: 'preview_criteria', description: 'What a proposed criteria JSON would do to the notes that exist, without saving or scanning: how many rise above or fall below the bar, who enters or leaves the top 20, the biggest movers. Covers title terms, recency and pay exactly; description, seniority and location rules need a scan.', inputSchema: { type: 'object', properties: { raw: { type: 'string' } }, required: ['raw'] } },
@@ -43,7 +43,7 @@ export const TOOLS = [
43
43
  { name: 'activate_criteria_preset', description: 'Copy a named preset into Targets/Search Criteria.md so the daily scan and everything else use it.', inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] } },
44
44
  { name: 'scan_status', description: 'Whether a scan is running, when it started and finished, its exit code, and its last output lines. The scan runs on its own and its status lives in the profile folder, so this answers correctly from a new session or after this server restarts.', inputSchema: { type: 'object', properties: {} } },
45
45
  { name: 'rescore_notes', description: 'Score every existing note again under the saved criteria (the CLI\'s rescore --full): score, pay band, match reasons and a status-log line on each note that moved; notes already at the current weights are left alone. dry previews the count.', inputSchema: { type: 'object', properties: { dry: { type: 'boolean' } } } },
46
- { name: 'scan_preview', description: 'The top of the last scan\'s ranking, dry or real, with score, pay band and the first reasons: what the criteria find, before or without notes. Use after a dry run_scan.', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: '1 to 50, default 15' } } } },
46
+ { name: 'scan_preview', description: 'The top of the last scan\'s ranking, dry or real, with score, pay band and the first reasons: what the criteria find, before or without notes. Use after a dry run_scan. `dropped` says what the hard exclusions removed: a count for title rules and the list of postings company rules dropped, with the rule that hit. In each row, `salary` is the range as the posting states it (not a floor); the pay score reads the TOP of that range, and `payBand` says where that top sits against the criteria floor: floor (at or above), stretch, below, or unknown (no stated range).', inputSchema: { type: 'object', properties: { limit: { type: 'number', description: '1 to 50, default 15' } } } },
47
47
  { name: 'get_criteria', description: 'The scoring criteria JSON from Targets/Search Criteria.md.', inputSchema: { type: 'object', properties: {} } },
48
48
  { name: 'set_criteria', description: 'Replace the criteria JSON block. Pass the full JSON as a string; it is validated before writing.', inputSchema: { type: 'object', properties: { raw: { type: 'string' } }, required: ['raw'] } },
49
49
  { name: 'list_companies', description: 'The company watchlist rows (name, ats, slug, tier, status) with each board\'s health: state (failed, zero, stale, never, ok), last success, last attempt, last error.', inputSchema: { type: 'object', properties: {} } },
@@ -79,7 +79,14 @@ export async function call(name, a = {}) {
79
79
  case 'save_cover_letter': return letter.save(a.id, a.text, 'mcp');
80
80
  case 'application_materials': return { job: store.getJob(a.id), packet: store.applicationPacket(a.id), ...store.profile() };
81
81
  case 'summary': return store.summary();
82
- case 'run_scan': return store.runScan(a.dry ? ['--dry'] : [], { criteria: a.criteria || '', via: 'mcp' });
82
+ case 'run_scan': {
83
+ const started = store.runScan(a.dry ? ['--dry'] : [], { criteria: a.criteria || '', via: 'mcp' });
84
+ const wait = Math.min(300, Math.max(0, Number(a.wait) || 0));
85
+ if (!wait) return started;
86
+ const until = Date.now() + wait * 1000;
87
+ while (Date.now() < until && store.scanStatus().running) await new Promise((r) => setTimeout(r, 2000));
88
+ return store.scanStatus();
89
+ }
83
90
  case 'mail_check': return mail.start({ sinceDays: a.days });
84
91
  case 'mail_items': return mail.items();
85
92
  case 'preview_criteria': return store.previewCriteria(a.raw);
@@ -1135,7 +1135,12 @@ export function scanPreview({ limit = 15 } = {}) {
1135
1135
  score: j.score, company: j.company, title: j.title, location: j.location, remote: !!j.remote, salary: j.salary || '', payBand: j.payBand, posted: j.posted, url: j.url, source: j.source, isNew: !!j.isNew,
1136
1136
  reasons: (j.reasons || []).slice(0, 3),
1137
1137
  }));
1138
- return { when: snap.when, minScore: snap.minScore, total: (snap.jobs || []).length, aboveBar: (snap.jobs || []).filter((j) => j.score >= (snap.minScore || 0)).length, failed: (snap.failed || []).length, rows };
1138
+ return {
1139
+ when: snap.when, minScore: snap.minScore, total: (snap.jobs || []).length, aboveBar: (snap.jobs || []).filter((j) => j.score >= (snap.minScore || 0)).length, failed: (snap.failed || []).length, rows,
1140
+ // What the hard exclusions removed before ranking: a count for title rules, the list for company rules.
1141
+ dropped: snap.dropped || null,
1142
+ fields: { salary: 'the range as the posting states it, not a floor; the pay score reads its top', payBand: 'where that top sits against the criteria floor: floor (at or above), stretch, below, unknown (no stated range)' },
1143
+ };
1139
1144
  }
1140
1145
  export function runScan(args = [], { criteria = '', retryFailed = false, via = 'app' } = {}) {
1141
1146
  if (scanStatus().running) return scanStatus();
package/cli.mjs CHANGED
@@ -12,6 +12,8 @@ const opt = (f) => { const i = rest.indexOf(f); return i >= 0 ? rest[i + 1] : un
12
12
  const HELP = `tekjobs — a local job-search machine
13
13
 
14
14
  tekjobs init [dir] [--resume <file>] create the profile folder (default ~/.tekjobs/profile), remember it, import a resume
15
+ tekjobs init --sample [dir] a complete, fictional search to look at first (default ~/.tekjobs/sample);
16
+ nothing in it is real; \`tekjobs init\` afterwards starts your own
15
17
  tekjobs resume <file> import or replace the resume (PDF, DOCX, Markdown, text)
16
18
  tekjobs resume sync [<url|file>] refresh Profile/Resume.md from where you keep your resume (a link-shared
17
19
  Google Doc, a public page, or a file); remembers the source; flags drafts
@@ -52,6 +54,22 @@ async function main() {
52
54
  if (!cmd || cmd === 'help' || cmd === '--help') return console.log(HELP);
53
55
  if (cmd === '--version' || cmd === '-v' || cmd === 'version') return console.log(JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8')).version);
54
56
  if (cmd === 'schedule') return schedule();
57
+ if (cmd === 'init' && rest.includes('--sample')) {
58
+ // The fictional search, copied where the app and the MCP server will read it next. Its own folder by default,
59
+ // so a later plain `init` starts the person's real profile beside it and leaves this one in place.
60
+ const dirArg = rest.find((a) => !a.startsWith('--'));
61
+ const dir = path.resolve(dirArg || path.join(process.env.USERPROFILE || process.env.HOME || '.', '.tekjobs', 'sample'));
62
+ const { installSample } = await import('./scraper/profile.mjs');
63
+ const r = installSample(dir);
64
+ console.log(`Sample profile: ${r.dir} (${r.files} files)
65
+ Jordan Example, a design engineer three weeks into a fictional search: fourteen postings, one interview, a rejection,
66
+ people on the threads, two scan logs. Nothing in it is a real person, company or posting.
67
+
68
+ tekjobs up the app on http://127.0.0.1:8787 shows it (tekjobs down first if it is already running)
69
+ tekjobs mcp your AI client reads it too, until the next init
70
+ tekjobs init when you are ready for your own search; the sample folder stays where it is`);
71
+ return;
72
+ }
55
73
  if (cmd === 'init') {
56
74
  const dirArg = rest.find((a) => !a.startsWith('--') && a !== opt('--resume'));
57
75
  const dir = path.resolve(dirArg || process.env.TEKJOBS_PROFILE || path.join(process.env.USERPROFILE || process.env.HOME || '.', '.tekjobs', 'profile'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurtekb/tekjobs",
3
- "version": "0.35.2",
3
+ "version": "0.37.0",
4
4
  "description": "A local-first job-search machine: watches hundreds of company job boards, scores every posting against your profile, and files matches into a folder of markdown notes you own. Bring your own LLM through MCP.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/run.mjs CHANGED
@@ -143,6 +143,15 @@ for (const j of jobs) {
143
143
  j.scored = scoreJob(j, criteria);
144
144
  }
145
145
  const scored = jobs.filter((j) => !j.scored.excluded).sort((a, b) => b.scored.score - a.scored.score);
146
+ // What the hard exclusions dropped, so a person can see the rule working (and catch one that is too wide). Title
147
+ // exclusions drop thousands of unrelated postings a run and are counted; company exclusions are few and listed.
148
+ const excluded = jobs.filter((j) => j.scored.excluded);
149
+ const droppedByCompany = excluded.filter((j) => /^excluded by company/.test(j.scored.reasons?.[0] || ''));
150
+ const dropped = {
151
+ total: excluded.length,
152
+ byTitle: excluded.length - droppedByCompany.length,
153
+ byCompany: droppedByCompany.slice(0, 200).map((j) => ({ company: j.company, title: j.title, location: j.location || '', url: j.url, source: j.source, rule: (j.scored.reasons[0].match(/"([^"]+)"/) || [])[1] || '' })),
154
+ };
146
155
  const matches = scored.filter((j) => j.scored.score >= criteria.minScore);
147
156
 
148
157
  // 4. Write new matches to the vault
@@ -167,7 +176,7 @@ saveHealth(health);
167
176
 
168
177
  // 5. Debug snapshot: everything scored, so near-misses can be reviewed and criteria tuned
169
178
  fs.writeFileSync(P.lastRun, JSON.stringify({
170
- when: new Date().toISOString(), minScore: criteria.minScore, failed,
179
+ when: new Date().toISOString(), minScore: criteria.minScore, failed, dropped,
171
180
  jobs: scored.slice(0, 800).map((j) => ({ score: j.scored.score, company: j.company, title: j.title, location: j.location, remote: !!j.remote, salary: j.salary || '', salaryMin: j.salaryMin || null, salaryMax: j.salaryMax || null, payBand: j.scored.payBand, posted: j.posted, url: j.url, source: j.source, reasons: j.scored.reasons, isNew: !seen[j.id] || fresh.includes(j) })),
172
181
  }, null, 2));
173
182
 
@@ -182,7 +191,7 @@ const summary = {
182
191
  };
183
192
  const logLines = [
184
193
  `## Run ${summary.when}${DRY ? ' (dry)' : ''}`,
185
- `- Boards: ${summary.companiesOk}/${summary.companiesTotal} ok · postings scanned: ${summary.totalJobs} · scored ≥ ${criteria.minScore}: ${matches.length} · **new: ${written.length}** · closed: ${closed.length} · ${((Date.now() - t0) / 1000).toFixed(1)}s`,
194
+ `- Boards: ${summary.companiesOk}/${summary.companiesTotal} ok · postings scanned: ${summary.totalJobs} · dropped by exclusions: ${dropped.total}${dropped.byCompany.length ? ` (${dropped.byCompany.length} by company)` : ''} · scored ≥ ${criteria.minScore}: ${matches.length} · **new: ${written.length}** · closed: ${closed.length} · ${((Date.now() - t0) / 1000).toFixed(1)}s`,
186
195
  `- Criteria: ${criteriaLabel}`,
187
196
  // Who started it: the morning task (run.cmd / run.sh), the app, an agent over MCP, or someone at the CLI.
188
197
  `- Via: ${process.env.TEKJOBS_RUN_VIA || 'cli'}`,
@@ -2,7 +2,7 @@
2
2
 
3
3
  A complete, fictional TekJobs profile folder: Jordan Example, a design engineer in Portland, three weeks into a search. Fourteen postings at companies that do not exist, one application in interview, one rejected, two passed, one listing closed, three people on the threads, two scan logs and the dashboard. Every note was written by the product's own code (`npm run sample` rebuilds it), so it is always in the shape the app expects.
4
4
 
5
- Look at it in the app without touching your own folder:
5
+ Look at it in the app without touching your own folder. Installed from npm: `tekjobs init --sample`, then `tekjobs up`. From a clone:
6
6
 
7
7
  ```
8
8
  TEKJOBS_PROFILE=$PWD/samples/vault npm run serve
@@ -7,6 +7,7 @@ import { P, VAULT, rememberProfileDir, loadCriteria } from './config.mjs';
7
7
  import { extractText } from './resume.mjs';
8
8
 
9
9
  const STARTER = fileURLToPath(new URL('./starter/', import.meta.url));
10
+ const SAMPLE = fileURLToPath(new URL('../samples/vault/', import.meta.url));
10
11
  const today = () => new Date().toISOString().slice(0, 10);
11
12
 
12
13
  /** Create the folder layout and starter notes in `dir` (default: the resolved profile dir). Never overwrites. */
@@ -28,6 +29,20 @@ export function initProfile(dir = VAULT) {
28
29
  return { dir, made };
29
30
  }
30
31
 
32
+ /**
33
+ * Copy the fictional sample search (samples/vault, shipped in the package) into `dir` and make it the profile the
34
+ * app and the MCP server read next. Refuses a folder that already has files in it: it never merges into a real one.
35
+ */
36
+ export function installSample(dir) {
37
+ if (!fs.existsSync(SAMPLE)) throw new Error(`The sample folder is missing from this install (${SAMPLE}).`);
38
+ if (fs.existsSync(dir) && fs.readdirSync(dir).length) throw new Error(`${dir} already has files in it. Pick an empty folder: tekjobs init --sample <dir>`);
39
+ fs.cpSync(SAMPLE, dir, { recursive: true });
40
+ fs.mkdirSync(path.join(dir, '.tekjobs'), { recursive: true });
41
+ rememberProfileDir(dir);
42
+ const count = (d) => fs.readdirSync(d, { withFileTypes: true }).reduce((n, e) => n + (e.isDirectory() ? count(path.join(d, e.name)) : 1), 0);
43
+ return { dir, files: count(dir) };
44
+ }
45
+
31
46
  /** Copy a resume into Profile/ and write its extracted text beside it as `Resume - Source.md`. */
32
47
  export async function importResume(file, dir = VAULT) {
33
48
  if (!fs.existsSync(file)) throw Object.assign(new Error(`No such file: ${file}`), { status: 404 });
@@ -115,12 +130,13 @@ const INTERVIEW_SCRIPT = `You are onboarding a job seeker into TekJobs. Goal: wr
115
130
  3. Write Profile/Profile.md using the existing note's headings (Basics · What you are, in three sentences · Target roles table with tiers A/B · Constraints & preferences · Proof points · Documents). Proof points are one line each, with numbers. Call save_profile with the full markdown.
116
131
  4. Build the criteria from the current JSON (keep every key). Set:
117
132
  - titleTerms: exact lowercase substrings that appear in real job titles for the target roles, weighted 40 for exact-fit titles down to ~20 for adjacent ones. Include common variants ("front-end", "frontend", "front end").
118
- - titleExclude: add the user's hard exclusions as lowercase substrings.
133
+ - titleExclude: add the user's hard exclusions as lowercase substrings (titles and words in titles; abbreviations like "sr." and "dir." are spelled out before matching).
134
+ - companyExclude: industries, company types and names the user will not work for, as lowercase substrings of the company name ("casino", "gambling", "staffing", "defense"). Title words do not catch these.
119
135
  - descTerms: 15 to 30 stack/domain words with weights 2 to 6.
120
136
  - salary.minAnnual and salary.stretchAnnual as integers (or null if the user declines).
121
137
  - location.requireRemote true only if the user said remote only; add their metro to bayAreaTerms with bayAreaBoost 12 if hybrid there is acceptable.
122
138
  Call set_criteria with the full JSON string. It is validated before writing.
123
- 5. Call run_scan with dry=true and poll scan_status every few seconds until running is false (two to three minutes; the scan runs on its own, so if this session ends first, the next one can pick up with scan_status). A dry run writes no notes, so do not use search_jobs yet: call scan_preview limit=15 and show the user the top matches with score, pay band and one reason each. Ask whether the list looks right. Adjust the criteria once if it does not (set_criteria, then another dry run_scan and scan_preview). When it does, call run_scan with dry=false and poll scan_status until it finishes; that run writes the notes, and search_jobs and the app's Today page work from then on.
139
+ 5. Call run_scan with dry=true and poll scan_status every few seconds until running is false (two to three minutes; the scan runs on its own, so if this session ends first, the next one can pick up with scan_status). If you cannot poll between turns, pass wait=240 to run_scan and it answers when the scan is done. A dry run writes no notes, so do not use search_jobs yet: call scan_preview limit=15 and show the user the top matches with score, pay band and one reason each. Ask whether the list looks right. Adjust the criteria once if it does not (set_criteria, then another dry run_scan and scan_preview). When it does, call run_scan with dry=false and poll scan_status until it finishes; that run writes the notes, and search_jobs and the app's Today page work from then on.
124
140
  6. Finish by telling the user where things live: Profile/Profile.md, Targets/Search Criteria.md, Jobs/. Remind them the daily scan runs on its own from here.`;
125
141
 
126
142
  function criteriaNote(json) {
@@ -134,7 +150,8 @@ updated: ${today()}
134
150
 
135
151
  How scoring works:
136
152
  - **titleTerms** — best single match in the job title counts fully, each extra match adds 5. Empty until the interview runs.
137
- - **titleExclude** — any hit in the title drops the job entirely.
153
+ - **titleExclude** — any hit in the title drops the job entirely. Abbreviations are spelled out first, so "director" catches "Sr. Dir".
154
+ - **companyExclude** — any hit in the company name drops the job entirely: industries, staffing agencies, names.
138
155
  - **noTitleMatchPenalty** — a posting whose title matches nothing in \`titleTerms\` takes this hit, so location and recency alone can't carry it over the bar.
139
156
  - **descTerms** — each term found in the description adds its weight (capped at \`descCap\`).
140
157
  - **seniority** — senior/staff/lead/principal adds; junior/intern subtracts.
@@ -17,7 +17,7 @@ import fs from 'node:fs';
17
17
  import path from 'node:path';
18
18
  import crypto from 'node:crypto';
19
19
  import { P, loadCriteria } from './config.mjs';
20
- import { scoreJob } from './score.mjs';
20
+ import { scoreJob, normalizeTitle } from './score.mjs';
21
21
 
22
22
  /**
23
23
  * A short fingerprint of every criteria key the scorer reads.
@@ -48,7 +48,7 @@ const num = (v) => (Number.isFinite(Number(v)) ? Number(v) : 0);
48
48
  /** Title points under one set of weights. `extraCap` null means the old, uncapped behaviour. */
49
49
  export function titlePoints(title = '', c = {}, extraCap) {
50
50
  const hits = Object.entries(c.titleTerms || {})
51
- .filter(([t]) => title.toLowerCase().includes(t.toLowerCase()))
51
+ .filter(([t]) => normalizeTitle(title).includes(t.toLowerCase()))
52
52
  .sort((a, b) => b[1] - a[1]);
53
53
  if (!hits.length) return c.noTitleMatchPenalty ?? -40;
54
54
  const per = c.titleExtraPer ?? 5;
package/scraper/score.mjs CHANGED
@@ -16,13 +16,28 @@ export function parseSalary(text = '') {
16
16
  }
17
17
  const wordHit = (hay, term) => new RegExp(`(^|[^a-z0-9])${esc(term)}([^a-z0-9]|$)`, 'i').test(hay);
18
18
 
19
+ /**
20
+ * The abbreviations postings use in titles, spelled out before anything matches against them, so "Sr. Dir, Design"
21
+ * meets the "director" exclusion and the "senior" boost the way "Senior Director, Design" does. Whole words only.
22
+ */
23
+ const ABBREVIATIONS = [
24
+ [/\bsr\b\.?/g, 'senior'], [/\bjr\b\.?/g, 'junior'], [/\bdir\b\.?/g, 'director'], [/\bmgr\b\.?/g, 'manager'],
25
+ [/\beng\b\.?/g, 'engineer'], [/\bassoc\b\.?/g, 'associate'], [/\bprin\b\.?/g, 'principal'], [/\bswe\b/g, 'software engineer'],
26
+ ];
27
+ export function normalizeTitle(title) {
28
+ let t = String(title || '').toLowerCase();
29
+ for (const [re, word] of ABBREVIATIONS) t = t.replace(re, word);
30
+ return t;
31
+ }
32
+
19
33
  /**
20
34
  * Returns { score, reasons[], excluded } for one normalized job against the criteria JSON.
21
35
  * `now` is the moment recency is judged from: the scan passes nothing (today); a rescore of an existing note
22
36
  * passes the day the note was found, so the posting keeps the freshness it had when it was scored.
23
37
  */
24
38
  export function scoreJob(job, c, { now = Date.now() } = {}) {
25
- const title = (job.title || '').toLowerCase();
39
+ const title = normalizeTitle(job.title);
40
+ const company = (job.company || '').toLowerCase();
26
41
  const desc = (job.descriptionText || '').toLowerCase();
27
42
  const loc = (job.location || '').toLowerCase();
28
43
  const reasons = [];
@@ -31,6 +46,10 @@ export function scoreJob(job, c, { now = Date.now() } = {}) {
31
46
  for (const ex of c.titleExclude || []) {
32
47
  if (title.includes(ex.toLowerCase())) return { score: -999, reasons: [`excluded by title: "${ex}"`], excluded: true };
33
48
  }
49
+ // Company exclusions: industries, staffing agencies, names. A hit anywhere in the company name drops the posting.
50
+ for (const ex of c.companyExclude || []) {
51
+ if (ex && company.includes(String(ex).toLowerCase())) return { score: -999, reasons: [`excluded by company: "${ex}"`], excluded: true };
52
+ }
34
53
 
35
54
  const titleHits = Object.entries(c.titleTerms || {})
36
55
  .filter(([t]) => title.includes(t.toLowerCase()))
@@ -2,6 +2,7 @@
2
2
  // { id, source, company, title, url, location, remote, posted, descriptionHtml, salary, department, employmentType }
3
3
 
4
4
  import { UA } from './config.mjs';
5
+ import { normalizeTitle } from './score.mjs';
5
6
 
6
7
  async function getJSON(url, { timeoutMs = 25000 } = {}) {
7
8
  const ctrl = new AbortController();
@@ -271,7 +272,7 @@ export async function fetchWorkday(company, slug, titleFilter = () => true, { ma
271
272
  export function makeTitleFilter(criteria) {
272
273
  const terms = Object.keys(criteria?.titleTerms || {}).map((t) => t.toLowerCase());
273
274
  const excl = (criteria?.titleExclude || []).map((t) => t.toLowerCase());
274
- return (title) => { const t = (title || '').toLowerCase(); return terms.some((k) => t.includes(k)) && !excl.some((k) => t.includes(k)); };
275
+ return (title) => { const t = normalizeTitle(title); return terms.some((k) => t.includes(k)) && !excl.some((k) => t.includes(k)); };
275
276
  }
276
277
 
277
278
  export async function fetchCompany(c, criteria) {
@@ -9,6 +9,7 @@
9
9
  "intern", "internship", "apprentice", "new grad", "recruit", "account executive", "customer success",
10
10
  "manufacturing", "process engineer", "chemical", "biomedical", "automotive", "aerospace"
11
11
  ],
12
+ "companyExclude": [],
12
13
  "descTerms": {},
13
14
  "seniority": {
14
15
  "boost": { "senior": 8, "staff": 10, "lead": 10, "principal": 10, "head of": 8, "founding": 8 },