@timurtekb/tekjobs 0.36.0 → 0.37.1

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
+ ## <small>0.37.1 (2026-10-07)</small>
6
+
7
+ * fix(app): a second profile never sees the first person's resume settings or moves the pointer ([19ab826](https://github.com/Timurtek/tekjobs/commit/19ab826))
8
+
9
+ ## 0.37.0 (2026-10-07)
10
+
11
+ * feat(scan): the run reports what the hard exclusions dropped ([58cfb62](https://github.com/Timurtek/tekjobs/commit/58cfb62))
12
+
5
13
  ## 0.36.0 (2026-10-07)
6
14
 
7
15
  * feat(cli): tekjobs init --sample, company exclusions, and the rest of the first-run notes ([a0b88b0](https://github.com/Timurtek/tekjobs/commit/a0b88b0))
package/README.md CHANGED
@@ -157,7 +157,7 @@ The app's **Criteria** page edits the same JSON as fields (bar, penalties, title
157
157
 
158
158
  The **Profile** page edits the notes applications are written from: `Profile/Profile.md` (who you are), `Positioning.md` (how the story is told), `Voice.md` (how you write), each with an Edit and a Preview; the resume note is shown read-only because `tekjobs resume sync` replaces it. Above it, **resume variants**: every PDF, DOCX, Markdown or text file in the variants folder (`Templates/Resume` inside the profile folder unless Settings says otherwise), each one a click from being the resume of record, and offered by name in the packet's Resume variant field.
159
159
 
160
- **Settings** (System) holds the few things kept outside the profile folder, in `~/.tekjobs/config.json`: the profile folder itself (a change takes effect on the next server start; `tekjobs init <dir>` starts a new one), the resume variants folder, the writing CLI's command and arguments, and the optional contact for scan requests.
160
+ **Settings** (System) holds two kinds of thing. About this computer, in `~/.tekjobs/config.json`: the profile folder itself (a change takes effect on the next server start; `tekjobs init <dir>` starts a new one), the writing CLI's command and arguments, and the optional contact for scan requests. About this search, inside the profile in `.tekjobs/settings.json`: the resume of record and the resume variants folder, so a second profile on the same machine (the sample, a test persona) never sees another person's resumes.
161
161
 
162
162
  ## Commands
163
163
 
@@ -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.2`]}),(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.37.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",
@@ -74,4 +74,4 @@ Defaulting to \`null\`.`}md(Ad,`getInvalidValueError`);var jd=xd,Md=Cd;(0,b.forw
74
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
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,{})}));
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. The profile folder, the writing CLI and the contact are about this computer and sit in `,(0,x.jsx)(`code`,{className:`mono`,children:e.configFile}),`. The resume of record and the variants folder are about this search and sit inside the profile, in `,(0,x.jsx)(`code`,{className:`mono`,children:e.profileSettingsFile}),`, so a second profile never sees them. Everything else 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.jsxs)(`h2`,{className:`settings__h`,children:[`Profile folder `,(0,x.jsx)(`span`,{className:`muted`,children:`(this computer)`})]}),(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.jsxs)(`h2`,{className:`settings__h`,children:[`Resume variants folder `,(0,x.jsx)(`span`,{className:`muted`,children:`(this profile)`})]}),(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.jsxs)(`h2`,{className:`settings__h`,children:[`Writing CLI `,(0,x.jsx)(`span`,{className:`muted`,children:`(this computer)`})]}),(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.jsxs)(`h2`,{className:`settings__h`,children:[`Contact for scans `,(0,x.jsx)(`span`,{className:`muted`,children:`(this computer)`})]}),(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-DR4ECosu.js"></script>
11
+ <script type="module" crossorigin src="/assets/index-C77iGKNO.js"></script>
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-CR3ppGJT.css">
13
13
  </head>
14
14
  <body>
@@ -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. 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' } } } },
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: {} } },
@@ -6,7 +6,7 @@ import path from 'node:path';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { readStatus as readScanStatus, writeStatus as writeScanStatus, scanState, tail as tailLog, logFile } from '../../scraper/scan-status.mjs';
8
8
  import { fileURLToPath } from 'node:url';
9
- import { DATA_DIR, P, VAULT, HOME_DIR, CONFIG_FILE, loadCriteria, loadCompanies, criteriaPresetFile } from '../../scraper/config.mjs';
9
+ import { DATA_DIR, P, VAULT, HOME_DIR, CONFIG_FILE, PROFILE_SETTINGS_FILE, profileSettings, writeProfileSettings, loadCriteria, loadCompanies, criteriaPresetFile } from '../../scraper/config.mjs';
10
10
  import { loadHealth, healthState } from '../../scraper/health.mjs';
11
11
  import { readFrontmatter, LEGACY_NARRATIVE_DEFAULT } from '../../scraper/vault.mjs';
12
12
  import { parseHNHeader } from '../../scraper/sources.mjs';
@@ -650,9 +650,11 @@ export function outcomes({ agingDays = [7, 14, 21] } = {}) {
650
650
  }
651
651
 
652
652
  // ---------- settings ----------
653
- // The few things that live outside the profile folder because they say where it is: ~/.tekjobs/config.json.
654
- // The profile folder itself is read once at start (every module holds its paths), so changing it here takes a
655
- // server restart; the other settings are read when used.
653
+ // Two scopes. The machine config (~/.tekjobs/config.json) says where the profile folder is, which CLI writes, and
654
+ // whom to contact: things about this computer. The resume of record and the variants folder are about one person's
655
+ // search and live in the profile (<profile>/.tekjobs/settings.json), so a second profile never sees them. The
656
+ // profile folder itself is read once at start (every module holds its paths), so changing it takes a server
657
+ // restart; the other settings are read when used.
656
658
  function readConfigFile() { try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); } catch { return {}; } }
657
659
  function writeConfigFile(patch) {
658
660
  fs.mkdirSync(HOME_DIR, { recursive: true });
@@ -662,16 +664,18 @@ function writeConfigFile(patch) {
662
664
  return next;
663
665
  }
664
666
  export function resumeDir() {
665
- const cfg = readConfigFile();
666
- return cfg.resumeDir ? path.resolve(cfg.resumeDir) : path.join(VAULT, 'Templates', 'Resume');
667
+ const own = profileSettings();
668
+ return own.resumeDir ? path.resolve(VAULT, own.resumeDir) : path.join(VAULT, 'Templates', 'Resume');
667
669
  }
668
670
  export function settings() {
669
671
  const cfg = readConfigFile();
672
+ const own = profileSettings();
670
673
  return {
671
674
  configFile: CONFIG_FILE,
675
+ profileSettingsFile: PROFILE_SETTINGS_FILE,
672
676
  profile: { active: VAULT, configured: cfg.profile || '', fromEnv: !!(process.env.TEKJOBS_PROFILE || process.env.TEKJOBS_VAULT), exists: fs.existsSync(VAULT) },
673
- resumeDir: { path: resumeDir(), configured: cfg.resumeDir || '', exists: fs.existsSync(resumeDir()) },
674
- resumeSource: cfg.resumeSource || '',
677
+ resumeDir: { path: resumeDir(), configured: own.resumeDir || '', exists: fs.existsSync(resumeDir()) },
678
+ resumeSource: own.resumeSource || '',
675
679
  llm: { command: cfg.llm?.command || 'claude', args: (cfg.llm?.args || ['-p', '--output-format', 'text']).join(' '), configured: !!cfg.llm },
676
680
  contact: cfg.contact || '',
677
681
  };
@@ -690,9 +694,10 @@ export function saveSettings({ profile, resumeDir: rd, llmCommand, llmArgs, cont
690
694
  } else patch.profile = '';
691
695
  }
692
696
  if (rd !== undefined) {
697
+ // The variants folder is the profile's, not the machine's.
693
698
  const dir = String(rd).trim();
694
- if (dir && !fs.existsSync(path.resolve(dir))) throw Object.assign(new Error(`${path.resolve(dir)} does not exist.`), { status: 400 });
695
- patch.resumeDir = dir ? path.resolve(dir) : '';
699
+ if (dir && !fs.existsSync(path.resolve(VAULT, dir))) throw Object.assign(new Error(`${path.resolve(VAULT, dir)} does not exist.`), { status: 400 });
700
+ writeProfileSettings({ resumeDir: dir ? path.resolve(VAULT, dir) : '' });
696
701
  }
697
702
  if (llmCommand !== undefined || llmArgs !== undefined) {
698
703
  const command = String(llmCommand ?? 'claude').trim() || 'claude';
@@ -710,7 +715,7 @@ export function saveSettings({ profile, resumeDir: rd, llmCommand, llmArgs, cont
710
715
  const RESUME_EXT = new Set(['.pdf', '.docx', '.md', '.txt']);
711
716
  export function listResumes() {
712
717
  const dir = resumeDir();
713
- const current = readConfigFile().resumeSource || '';
718
+ const current = profileSettings().resumeSource || '';
714
719
  const files = fs.existsSync(dir) ? fs.readdirSync(dir).filter((f) => RESUME_EXT.has(path.extname(f).toLowerCase())) : [];
715
720
  const rows = files.map((f) => {
716
721
  const p = path.join(dir, f);
@@ -1137,6 +1142,8 @@ export function scanPreview({ limit = 15 } = {}) {
1137
1142
  }));
1138
1143
  return {
1139
1144
  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,
1145
+ // What the hard exclusions removed before ranking: a count for title rules, the list for company rules.
1146
+ dropped: snap.dropped || null,
1140
1147
  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)' },
1141
1148
  };
1142
1149
  }
package/cli.mjs CHANGED
@@ -60,7 +60,7 @@ async function main() {
60
60
  const dirArg = rest.find((a) => !a.startsWith('--'));
61
61
  const dir = path.resolve(dirArg || path.join(process.env.USERPROFILE || process.env.HOME || '.', '.tekjobs', 'sample'));
62
62
  const { installSample } = await import('./scraper/profile.mjs');
63
- const r = installSample(dir);
63
+ const r = installSample(dir, { remember: true });
64
64
  console.log(`Sample profile: ${r.dir} (${r.files} files)
65
65
  Jordan Example, a design engineer three weeks into a fictional search: fourteen postings, one interview, a rejection,
66
66
  people on the threads, two scan logs. Nothing in it is a real person, company or posting.
@@ -75,7 +75,7 @@ async function main() {
75
75
  const dir = path.resolve(dirArg || process.env.TEKJOBS_PROFILE || path.join(process.env.USERPROFILE || process.env.HOME || '.', '.tekjobs', 'profile'));
76
76
  process.env.TEKJOBS_PROFILE = dir;
77
77
  const { initProfile, importResume, onboardingStatus } = await import('./scraper/profile.mjs');
78
- const r = initProfile(dir);
78
+ const r = initProfile(dir, { remember: true });
79
79
  console.log(`Profile folder: ${r.dir}${r.made.length ? `\n created: ${r.made.join(', ')}` : '\n (already existed; nothing overwritten)'}`);
80
80
  if (opt('--resume')) { const i = await importResume(path.resolve(opt('--resume')), dir); console.log(`Resume imported: ${i.chars} characters → ${i.source}`); }
81
81
  return printStatus(onboardingStatus(dir));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurtekb/tekjobs",
3
- "version": "0.36.0",
3
+ "version": "0.37.1",
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'}`,
@@ -42,6 +42,38 @@ export const PROFILE_DIR = VAULT;
42
42
  /** Scan state lives inside the profile so a profile folder is self-contained and portable. */
43
43
  export const DATA_DIR = path.join(VAULT, '.tekjobs');
44
44
 
45
+ /**
46
+ * Settings that belong to one person's search, kept inside the profile folder: the resume of record and the folder
47
+ * of resume variants. They used to live in ~/.tekjobs/config.json, which every profile on the machine read, so a
48
+ * second profile (the sample, a test persona) saw the first person's resume files. Now the machine config says only
49
+ * where the profile is, which CLI writes, and whom to contact; an older install's resume settings are adopted into
50
+ * the profile they were saved for (the one the machine config points at) the first time they are read, and are
51
+ * never applied to any other profile.
52
+ */
53
+ export const PROFILE_SETTINGS_FILE = path.join(DATA_DIR, 'settings.json');
54
+ export function readProfileSettings() {
55
+ try { return JSON.parse(fs.readFileSync(PROFILE_SETTINGS_FILE, 'utf8')); } catch { return {}; }
56
+ }
57
+ export function writeProfileSettings(patch) {
58
+ fs.mkdirSync(DATA_DIR, { recursive: true });
59
+ const next = { ...readProfileSettings(), ...patch };
60
+ for (const k of Object.keys(next)) if (next[k] === '' || next[k] === null || next[k] === undefined) delete next[k];
61
+ fs.writeFileSync(PROFILE_SETTINGS_FILE, JSON.stringify(next, null, 2));
62
+ return next;
63
+ }
64
+ export function profileSettings() {
65
+ const own = readProfileSettings();
66
+ if (own.resumeSource || own.resumeDir || own.adopted) return own;
67
+ const cfg = readConfig();
68
+ if (!cfg.resumeSource && !cfg.resumeDir) return own;
69
+ const savedFor = cfg.profile ? path.resolve(cfg.profile) : '';
70
+ if (savedFor !== VAULT) return own; // another profile's settings: not ours to read
71
+ const adopted = writeProfileSettings({ resumeSource: cfg.resumeSource || '', resumeDir: cfg.resumeDir || '', adopted: new Date().toISOString().slice(0, 10) });
72
+ const { resumeSource, resumeDir, ...machine } = cfg;
73
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(machine, null, 2));
74
+ return adopted;
75
+ }
76
+
45
77
  export const P = {
46
78
  profile: path.join(VAULT, 'Profile', 'Profile.md'),
47
79
  profileDir: path.join(VAULT, 'Profile'),
@@ -10,8 +10,13 @@ const STARTER = fileURLToPath(new URL('./starter/', import.meta.url));
10
10
  const SAMPLE = fileURLToPath(new URL('../samples/vault/', import.meta.url));
11
11
  const today = () => new Date().toISOString().slice(0, 10);
12
12
 
13
- /** Create the folder layout and starter notes in `dir` (default: the resolved profile dir). Never overwrites. */
14
- export function initProfile(dir = VAULT) {
13
+ /**
14
+ * Create the folder layout and starter notes in `dir` (default: the resolved profile dir). Never overwrites.
15
+ * `remember` writes the machine pointer (~/.tekjobs/config.json): the CLI's `init` asks for it, because that is what
16
+ * init means; the app and the MCP server never do, since a server reading a profile through TEKJOBS_PROFILE must
17
+ * not redirect every other session on the machine to it.
18
+ */
19
+ export function initProfile(dir = VAULT, { remember = false } = {}) {
15
20
  const made = [];
16
21
  const mk = (rel, content) => {
17
22
  const file = path.join(dir, rel);
@@ -25,7 +30,7 @@ export function initProfile(dir = VAULT) {
25
30
  mk('Targets/Search Criteria.md', criteriaNote(fs.readFileSync(path.join(STARTER, 'criteria.json'), 'utf8').trim()));
26
31
  mk('Targets/Companies.md', companiesNote(fs.readFileSync(path.join(STARTER, 'companies-table.md'), 'utf8')));
27
32
  mk('README.md', readme(dir));
28
- rememberProfileDir(dir);
33
+ if (remember) rememberProfileDir(dir);
29
34
  return { dir, made };
30
35
  }
31
36
 
@@ -33,12 +38,12 @@ export function initProfile(dir = VAULT) {
33
38
  * Copy the fictional sample search (samples/vault, shipped in the package) into `dir` and make it the profile the
34
39
  * app and the MCP server read next. Refuses a folder that already has files in it: it never merges into a real one.
35
40
  */
36
- export function installSample(dir) {
41
+ export function installSample(dir, { remember = false } = {}) {
37
42
  if (!fs.existsSync(SAMPLE)) throw new Error(`The sample folder is missing from this install (${SAMPLE}).`);
38
43
  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
44
  fs.cpSync(SAMPLE, dir, { recursive: true });
40
45
  fs.mkdirSync(path.join(dir, '.tekjobs'), { recursive: true });
41
- rememberProfileDir(dir);
46
+ if (remember) rememberProfileDir(dir);
42
47
  const count = (d) => fs.readdirSync(d, { withFileTypes: true }).reduce((n, e) => n + (e.isDirectory() ? count(path.join(d, e.name)) : 1), 0);
43
48
  return { dir, files: count(dir) };
44
49
  }
@@ -14,7 +14,7 @@
14
14
  // - a local .md, .txt, .docx or .pdf — including a Doc downloaded with File > Download
15
15
  import fs from 'node:fs';
16
16
  import path from 'node:path';
17
- import { P, VAULT, CONFIG_FILE, HOME_DIR } from './config.mjs';
17
+ import { P, VAULT, profileSettings, writeProfileSettings } from './config.mjs';
18
18
  import { htmlToText } from './sources.mjs';
19
19
  import { extractText } from './resume.mjs';
20
20
 
@@ -27,15 +27,12 @@ const today = () => new Date().toISOString().slice(0, 10);
27
27
 
28
28
  // ---------------- the remembered source ----------------
29
29
 
30
- function readConfig() {
31
- try { return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8')); } catch { return {}; }
32
- }
30
+ // Kept in the profile (<profile>/.tekjobs/settings.json), never in the machine config: it is this person's resume.
33
31
  export function rememberedSource() {
34
- return readConfig().resumeSource || '';
32
+ return profileSettings().resumeSource || '';
35
33
  }
36
34
  function rememberSource(source) {
37
- fs.mkdirSync(HOME_DIR, { recursive: true });
38
- fs.writeFileSync(CONFIG_FILE, JSON.stringify({ ...readConfig(), resumeSource: source }, null, 2));
35
+ writeProfileSettings({ resumeSource: source });
39
36
  }
40
37
 
41
38
  // ---------------- fetching ----------------