om-memory-system 4.4.0-next.65 → 4.4.0-next.67

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.
@@ -120,6 +120,6 @@ ${e}</tr>
120
120
  `}strong({tokens:e}){return`<strong>${this.parser.parseInline(e)}</strong>`}em({tokens:e}){return`<em>${this.parser.parseInline(e)}</em>`}codespan({text:e}){return`<code>${Vf(e,!0)}</code>`}br(e){return`<br>`}del({tokens:e}){return`<del>${this.parser.parseInline(e)}</del>`}link({href:e,title:t,tokens:n}){let r=this.parser.parseInline(n),i=Hf(e);if(i===null)return r;e=i;let a=`<a href="`+e+`"`;return t&&(a+=` title="`+Vf(t)+`"`),a+=`>`+r+`</a>`,a}image({href:e,title:t,text:n,tokens:r}){r&&(n=this.parser.parseInline(r,this.parser.textRenderer));let i=Hf(e);if(i===null)return Vf(n);e=i;let a=`<img src="${e}" alt="${Vf(n)}"`;return t&&(a+=` title="${Vf(t)}"`),a+=`>`,a}text(e){return`tokens`in e&&e.tokens?this.parser.parseInline(e.tokens):`escaped`in e&&e.escaped?e.text:Vf(e.text)}},$f=class{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return``+e}image({text:e}){return``+e}br(){return``}checkbox({raw:e}){return e}},ep=class e{options;renderer;textRenderer;constructor(e){this.options=e||X,this.options.renderer=this.options.renderer||new Qf,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new $f}static parse(t,n){return new e(n).parse(t)}static parseInline(t,n){return new e(n).parseInline(t)}parse(e){this.renderer.parser=this;let t=``;for(let n=0;n<e.length;n++){let r=e[n];if(this.options.extensions?.renderers?.[r.type]){let e=r,n=this.options.extensions.renderers[e.type].call({parser:this},e);if(n!==!1||![`space`,`hr`,`heading`,`code`,`table`,`blockquote`,`list`,`checkbox`,`html`,`def`,`paragraph`,`text`].includes(e.type)){t+=n||``;continue}}let i=r;switch(i.type){case`space`:t+=this.renderer.space(i);break;case`hr`:t+=this.renderer.hr(i);break;case`heading`:t+=this.renderer.heading(i);break;case`code`:t+=this.renderer.code(i);break;case`table`:t+=this.renderer.table(i);break;case`blockquote`:t+=this.renderer.blockquote(i);break;case`list`:t+=this.renderer.list(i);break;case`checkbox`:t+=this.renderer.checkbox(i);break;case`html`:t+=this.renderer.html(i);break;case`def`:t+=this.renderer.def(i);break;case`paragraph`:t+=this.renderer.paragraph(i);break;case`text`:t+=this.renderer.text(i);break;default:{let e=`Token with "`+i.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return t}parseInline(e,t=this.renderer){this.renderer.parser=this;let n=``;for(let r=0;r<e.length;r++){let i=e[r];if(this.options.extensions?.renderers?.[i.type]){let e=this.options.extensions.renderers[i.type].call({parser:this},i);if(e!==!1||![`escape`,`html`,`link`,`image`,`checkbox`,`strong`,`em`,`codespan`,`br`,`del`,`text`].includes(i.type)){n+=e||``;continue}}let a=i;switch(a.type){case`escape`:n+=t.text(a);break;case`html`:n+=t.html(a);break;case`link`:n+=t.link(a);break;case`image`:n+=t.image(a);break;case`checkbox`:n+=t.checkbox(a);break;case`strong`:n+=t.strong(a);break;case`em`:n+=t.em(a);break;case`codespan`:n+=t.codespan(a);break;case`br`:n+=t.br(a);break;case`del`:n+=t.del(a);break;case`text`:n+=t.text(a);break;default:{let e=`Token with "`+a.type+`" type was not found.`;if(this.options.silent)return console.error(e),``;throw Error(e)}}}return n}},tp=class{options;block;constructor(e){this.options=e||X}static passThroughHooks=new Set([`preprocess`,`postprocess`,`processAllTokens`,`emStrongMask`]);static passThroughHooksRespectAsync=new Set([`preprocess`,`postprocess`,`processAllTokens`]);preprocess(e){return e}postprocess(e){return e}processAllTokens(e){return e}emStrongMask(e){return e}provideLexer(e=this.block){return e?Zf.lex:Zf.lexInline}provideParser(e=this.block){return e?ep.parse:ep.parseInline}},np=new class{defaults=xd();options=this.setOptions;parse=this.parseMarkdown(!0);parseInline=this.parseMarkdown(!1);Parser=ep;Renderer=Qf;TextRenderer=$f;Lexer=Zf;Tokenizer=Xf;Hooks=tp;constructor(...e){this.use(...e)}walkTokens(e,t){let n=[];for(let r of e)switch(n=n.concat(t.call(this,r)),r.type){case`table`:{let e=r;for(let r of e.header)n=n.concat(this.walkTokens(r.tokens,t));for(let r of e.rows)for(let e of r)n=n.concat(this.walkTokens(e.tokens,t));break}case`list`:{let e=r;n=n.concat(this.walkTokens(e.items,t));break}default:{let e=r;this.defaults.extensions?.childTokens?.[e.type]?this.defaults.extensions.childTokens[e.type].forEach(r=>{let i=e[r].flat(1/0);n=n.concat(this.walkTokens(i,t))}):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){let t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach(e=>{let n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach(e=>{if(!e.name)throw Error(`extension name required`);if(`renderer`in e){let n=t.renderers[e.name];n?t.renderers[e.name]=function(...t){let r=e.renderer.apply(this,t);return r===!1&&(r=n.apply(this,t)),r}:t.renderers[e.name]=e.renderer}if(`tokenizer`in e){if(!e.level||e.level!==`block`&&e.level!==`inline`)throw Error(`extension level must be 'block' or 'inline'`);let n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&(e.level===`block`?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:e.level===`inline`&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}`childTokens`in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)}),n.extensions=t),e.renderer){let t=this.defaults.renderer||new Qf(this.defaults);for(let n in e.renderer){if(!(n in t))throw Error(`renderer '${n}' does not exist`);if([`options`,`parser`].includes(n))continue;let r=n,i=e.renderer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n||``}}n.renderer=t}if(e.tokenizer){let t=this.defaults.tokenizer||new Xf(this.defaults);for(let n in e.tokenizer){if(!(n in t))throw Error(`tokenizer '${n}' does not exist`);if([`options`,`rules`,`lexer`].includes(n))continue;let r=n,i=e.tokenizer[r],a=t[r];t[r]=(...e)=>{let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){let t=this.defaults.hooks||new tp;for(let n in e.hooks){if(!(n in t))throw Error(`hook '${n}' does not exist`);if([`options`,`block`].includes(n))continue;let r=n,i=e.hooks[r],a=t[r];t[r]=tp.passThroughHooks.has(n)?e=>{if(this.defaults.async&&tp.passThroughHooksRespectAsync.has(n))return(async()=>{let n=await i.call(t,e);return a.call(t,n)})();let r=i.call(t,e);return a.call(t,r)}:(...e)=>{if(this.defaults.async)return(async()=>{let n=await i.apply(t,e);return n===!1&&(n=await a.apply(t,e)),n})();let n=i.apply(t,e);return n===!1&&(n=a.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){let t=this.defaults.walkTokens,r=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(r.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}}),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return Zf.lex(e,t??this.defaults)}parser(e,t){return ep.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{let r={...n},i={...this.defaults,...r},a=this.onError(!!i.silent,!!i.async);if(this.defaults.async===!0&&r.async===!1)return a(Error(`marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.`));if(typeof t>`u`||t===null)return a(Error(`marked(): input parameter is undefined or null`));if(typeof t!=`string`)return a(Error(`marked(): input parameter is of type `+Object.prototype.toString.call(t)+`, string expected`));if(i.hooks&&(i.hooks.options=i,i.hooks.block=e),i.async)return(async()=>{let n=i.hooks?await i.hooks.preprocess(t):t,r=await(i.hooks?await i.hooks.provideLexer(e):e?Zf.lex:Zf.lexInline)(n,i),a=i.hooks?await i.hooks.processAllTokens(r):r;i.walkTokens&&await Promise.all(this.walkTokens(a,i.walkTokens));let o=await(i.hooks?await i.hooks.provideParser(e):e?ep.parse:ep.parseInline)(a,i);return i.hooks?await i.hooks.postprocess(o):o})().catch(a);try{i.hooks&&(t=i.hooks.preprocess(t));let n=(i.hooks?i.hooks.provideLexer(e):e?Zf.lex:Zf.lexInline)(t,i);i.hooks&&(n=i.hooks.processAllTokens(n)),i.walkTokens&&this.walkTokens(n,i.walkTokens);let r=(i.hooks?i.hooks.provideParser(e):e?ep.parse:ep.parseInline)(n,i);return i.hooks&&(r=i.hooks.postprocess(r)),r}catch(e){return a(e)}}}onError(e,t){return n=>{if(n.message+=`
121
121
  Please report this to https://github.com/markedjs/marked.`,e){let e=`<p>An error occurred:</p><pre>`+Vf(n.message+``,!0)+`</pre>`;return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}};function rp(e,t){return np.parse(e,t)}rp.options=rp.setOptions=function(e){return np.setOptions(e),rp.defaults=np.defaults,Sd(rp.defaults),rp},rp.getDefaults=xd,rp.defaults=X;function ip(...e){return np.use(...e),rp.defaults=np.defaults,Sd(rp.defaults),rp}rp.use=ip,rp.walkTokens=function(e,t){return np.walkTokens(e,t)},rp.parseInline=np.parseInline,rp.Parser=ep,rp.parser=ep.parse,rp.Renderer=Qf,rp.TextRenderer=$f,rp.Lexer=Zf,rp.lexer=Zf.lex,rp.Tokenizer=Xf,rp.Hooks=tp,rp.parse=rp,rp.options,rp.setOptions,rp.walkTokens,rp.parseInline,ep.parse,Zf.lex,rp.setOptions({gfm:!0,breaks:!0});function ap(e){let t=rp.parse(e,{async:!1});return bd.sanitize(t)}function op(e){if(e.projectPath){let t=e.projectPath.replace(/\\/g,`/`).split(`/`).filter(e=>e);return t[t.length-1]||e.projectPath}return e.displayName||e.id}function sp(e){return{createdDate:Jl(e.createdAt),updatedDate:e.updatedAt&&e.updatedAt!==e.createdAt?Jl(e.updatedAt):null}}function cp(e,t){return e.similarity===void 0?null:t?`${Math.round(e.similarity*100)}%`:`${e.similarity}%`}function lp({variant:e,item:t,memory:n,prompt:r,selected:i=!1,onSelect:a,onPin:o,onUnpin:s,onEdit:c,onDeleteMemory:l,onDeletePrompt:u,activeKeyword:d,onKeywordClick:f}){let{t:p}=mr();if(e===`pair`&&n&&r){let e=n.isPinned||!1,t=sp(n),u=cp(n,!0);return(0,B.jsxs)(`div`,{className:`rounded-xl border border-border bg-card/60 p-3 space-y-3 ${i?`ring-1 ring-primary/50`:``} ${e?`border-primary/40`:``}`,"data-id":n.id,children:[(0,B.jsxs)(`div`,{className:`space-y-2 rounded-lg bg-muted/40 p-3`,children:[(0,B.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,B.jsx)(ql,{variant:`secondary`,children:p(`badge-prompt`)}),(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:Jl(r.createdAt)})]}),(0,B.jsx)(`p`,{className:`text-sm whitespace-pre-wrap break-words`,children:r.content})]}),(0,B.jsx)(`div`,{className:`flex justify-center text-muted-foreground`,children:(0,B.jsx)(O,{className:`size-4`})}),(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 min-w-0`,children:[(0,B.jsx)(qi,{checked:i,onCheckedChange:e=>a?.(n.id,e===!0)}),(0,B.jsx)(ql,{children:p(`badge-memory`)}),n.memoryType?(0,B.jsx)(ql,{variant:`outline`,children:n.memoryType}):null,u?(0,B.jsx)(`span`,{className:`text-xs text-primary`,children:u}):null,e?(0,B.jsx)(ql,{variant:`secondary`,children:p(`badge-pinned`)}):null,(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground truncate`,children:n.displayName||n.id})]}),(0,B.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[e?(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:`Unpin`,onClick:()=>s?.(n.id),children:(0,B.jsx)(ve,{className:`size-3.5 fill-current`})}):(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:`Pin`,onClick:()=>o?.(n.id),children:(0,B.jsx)(ve,{className:`size-3.5`})}),(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,onClick:()=>c?.(n.id),children:(0,B.jsx)(ge,{className:`size-3.5`})}),(0,B.jsx)(Gl,{content:p(`tooltip-delete-pair`),children:(0,B.jsx)(U,{variant:`destructive`,size:`icon-xs`,"aria-label":p(`btn-delete-pair`),onClick:()=>l?.(n.id,!0),children:(0,B.jsx)(ke,{className:`size-3.5`})})})]})]}),n.tags?.length?(0,B.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:n.tags.map(e=>(0,B.jsx)(Ul,{keyword:e,active:d?.toLowerCase()===e.toLowerCase(),title:p(`tooltip-filter-keyword`),onClick:f},e))}):null,(0,B.jsx)(`div`,{className:`markdown-content text-sm prose-invert max-w-none`,dangerouslySetInnerHTML:{__html:ap(n.content)}}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-3 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{children:[p(`date-created`),` `,t.createdDate]}),t.updatedDate?(0,B.jsxs)(`span`,{children:[p(`date-updated`),` `,t.updatedDate]}):null,(0,B.jsxs)(`span`,{children:[`ID: `,n.id]})]})]})]})}if(e===`prompt`&&t){let e=!!t.linkedMemoryId;return(0,B.jsxs)(`div`,{className:`rounded-xl border border-border bg-card/60 p-3 space-y-2 ${i?`ring-1 ring-primary/50`:``}`,"data-id":t.id,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:[(0,B.jsx)(qi,{checked:i,onCheckedChange:e=>a?.(t.id,e===!0)}),(0,B.jsx)(fe,{className:`size-3.5 text-muted-foreground`}),(0,B.jsx)(ql,{variant:`secondary`,children:p(`badge-prompt`)}),e?(0,B.jsxs)(ql,{variant:`outline`,children:[(0,B.jsx)(P,{className:`size-3`}),p(`badge-linked`)]}):null,(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:Jl(t.createdAt)})]}),e?(0,B.jsx)(Gl,{content:p(`tooltip-delete-prompt-pair`),children:(0,B.jsx)(U,{variant:`destructive`,size:`icon-xs`,"aria-label":p(e?`btn-delete-pair`:`btn-delete`),onClick:()=>u?.(t.id,e),children:(0,B.jsx)(ke,{className:`size-3.5`})})}):(0,B.jsx)(U,{variant:`destructive`,size:`icon-xs`,"aria-label":p(e?`btn-delete-pair`:`btn-delete`),title:p(`btn-delete`),onClick:()=>u?.(t.id,e),children:(0,B.jsx)(ke,{className:`size-3.5`})})]}),(0,B.jsx)(`p`,{className:`text-sm whitespace-pre-wrap break-words`,children:t.content}),e?(0,B.jsxs)(`div`,{className:`flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,B.jsx)(O,{className:`size-3`}),p(`text-generated-above`),(0,B.jsx)(re,{className:`size-3`})]}):null]})}if(e===`memory`&&t){let e=t.isPinned||!1,n=!!t.linkedPromptId,r=sp(t),u=cp(t,!1);return(0,B.jsxs)(`div`,{className:`rounded-xl border border-border bg-card/60 p-3 space-y-2 ${i?`ring-1 ring-primary/50`:``} ${e?`border-primary/40`:``}`,"data-id":t.id,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 min-w-0`,children:[(0,B.jsx)(qi,{checked:i,onCheckedChange:e=>a?.(t.id,e===!0)}),t.memoryType?(0,B.jsx)(ql,{variant:`outline`,children:t.memoryType}):null,n?(0,B.jsxs)(ql,{variant:`outline`,children:[(0,B.jsx)(P,{className:`size-3`}),p(`badge-linked`)]}):null,u?(0,B.jsx)(`span`,{className:`text-xs text-primary`,children:u}):null,e?(0,B.jsx)(ql,{variant:`secondary`,children:p(`badge-pinned`)}):null,(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground truncate`,children:op(t)}),t.projectPath?(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground/70 truncate w-full`,children:t.projectPath}):null]}),(0,B.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[e?(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:`Unpin`,onClick:()=>s?.(t.id),children:(0,B.jsx)(ve,{className:`size-3.5 fill-current`})}):(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:`Pin`,onClick:()=>o?.(t.id),children:(0,B.jsx)(ve,{className:`size-3.5`})}),(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,onClick:()=>c?.(t.id),children:(0,B.jsx)(ge,{className:`size-3.5`})}),n?(0,B.jsx)(Gl,{content:p(`tooltip-delete-pair`),children:(0,B.jsx)(U,{variant:`destructive`,size:`icon-xs`,"aria-label":p(n?`btn-delete-pair`:`btn-delete`),onClick:()=>l?.(t.id,n),children:(0,B.jsx)(ke,{className:`size-3.5`})})}):(0,B.jsx)(U,{variant:`destructive`,size:`icon-xs`,"aria-label":p(n?`btn-delete-pair`:`btn-delete`),title:p(`btn-delete`),onClick:()=>l?.(t.id,n),children:(0,B.jsx)(ke,{className:`size-3.5`})})]})]}),t.tags?.length?(0,B.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:t.tags.map(e=>(0,B.jsx)(Ul,{keyword:e,active:d?.toLowerCase()===e.toLowerCase(),title:p(`tooltip-filter-keyword`),onClick:f},e))}):null,(0,B.jsx)(`div`,{className:`markdown-content text-sm prose-invert max-w-none`,dangerouslySetInnerHTML:{__html:ap(t.content)}}),n?(0,B.jsxs)(`div`,{className:`flex items-center gap-1 text-xs text-muted-foreground`,children:[(0,B.jsx)(re,{className:`size-3`}),p(`text-from-below`),(0,B.jsx)(O,{className:`size-3`})]}):null,(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-3 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{children:[p(`date-created`),` `,r.createdDate]}),r.updatedDate?(0,B.jsxs)(`span`,{children:[p(`date-updated`),` `,r.updatedDate]}):null,(0,B.jsxs)(`span`,{children:[`ID: `,t.id]})]})]})}return null}function up(e){let t=new Map(e.map(e=>[e.id,e])),n=[],r=new Set;for(let i of e)if(!r.has(i.id)){if(i.type===`memory`&&i.linkedPromptId&&t.has(i.linkedPromptId)){let e=t.get(i.linkedPromptId);n.push({isPair:!0,memory:i,prompt:e}),r.add(i.id),r.add(e.id)}else if(i.type===`prompt`&&i.linkedMemoryId&&t.has(i.linkedMemoryId)){let e=t.get(i.linkedMemoryId);n.push({isPair:!0,memory:e,prompt:i}),r.add(i.id),r.add(e.id)}else n.push({isPair:!1,type:i.type,item:i}),r.add(i.id)}return n.sort((e,t)=>{let n=e.isPair?e.memory.createdAt:e.item.createdAt,r=t.isPair?t.memory.createdAt:t.item.createdAt;return new Date(r).getTime()-new Date(n).getTime()})}function dp({memories:e,selectedIds:t,currentPage:n,totalPages:r,loading:i=!1,error:a=null,onSelect:o,onPageChange:s,onPin:c,onUnpin:l,onEdit:u,onDeleteMemory:d,onDeletePrompt:f,activeKeyword:p,onKeywordClick:m}){let{t:h}=mr(),g=(0,_.useMemo)(()=>up(e),[e]),v=h(`text-page`,{current:n,total:r}),y=(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(U,{variant:`outline`,size:`icon-xs`,disabled:!(n>1),onClick:()=>s(-1),children:(0,B.jsx)(ae,{className:`size-3.5`})}),(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground tabular-nums`,children:v}),(0,B.jsx)(U,{variant:`outline`,size:`icon-xs`,disabled:!(n<r),onClick:()=>s(1),children:(0,B.jsx)(A,{className:`size-3.5`})})]});return(0,B.jsxs)(`div`,{className:`space-y-3`,children:[(0,B.jsx)(`div`,{className:`grid min-h-32 items-start gap-3 lg:grid-cols-2`,children:i&&e.length===0?(0,B.jsx)(`div`,{className:`text-sm text-muted-foreground py-8 text-center`,children:h(`loading-init`)}):a?(0,B.jsxs)(`div`,{className:`text-sm text-destructive py-8 text-center`,children:[`Error: `,a]}):g.length===0?(0,B.jsx)(`div`,{className:`text-sm text-muted-foreground py-8 text-center`,children:h(`empty-memories`)}):g.map(e=>e.isPair?(0,B.jsx)(lp,{variant:`pair`,memory:e.memory,prompt:e.prompt,selected:t.has(e.memory.id),onSelect:o,onPin:c,onUnpin:l,onEdit:u,onDeleteMemory:d,onDeletePrompt:f,activeKeyword:p,onKeywordClick:m},e.memory.id):e.type===`prompt`?(0,B.jsx)(lp,{variant:`prompt`,item:e.item,selected:t.has(e.item.id),onSelect:o,onPin:c,onUnpin:l,onEdit:u,onDeleteMemory:d,onDeletePrompt:f,activeKeyword:p,onKeywordClick:m},e.item.id):(0,B.jsx)(lp,{variant:`memory`,item:e.item,selected:t.has(e.item.id),onSelect:o,onPin:c,onUnpin:l,onEdit:u,onDeleteMemory:d,onDeletePrompt:f,activeKeyword:p,onKeywordClick:m},e.item.id))}),(0,B.jsx)(`div`,{className:`flex justify-end`,children:y})]})}var fp=Object.defineProperty,pp=(e,t)=>fp(e,`name`,{value:t,configurable:!0}),mp=_.createContext(void 0);function hp(e){let t=_.useContext(mp);return e||t||`ltr`}pp(hp,`useDirection`);var gp=Object.defineProperty,_p=(e,t)=>gp(e,`name`,{value:t,configurable:!0});function vp(e,[t,n]){return Math.min(n,Math.max(t,e))}_p(vp,`clamp`);var yp=Object.defineProperty,Q=(e,t)=>yp(e,`name`,{value:t,configurable:!0});function bp(e,t){return _.useReducer((e,n)=>t[e][n]??e,e)}Q(bp,`useStateMachine`);var xp=`ScrollArea`,[Sp,Cp]=Gr(xp),[wp,Tp]=Sp(xp),Ep=_.forwardRef(Q(function(e,t){let{__scopeScrollArea:n,type:r=`hover`,dir:i,scrollHideDelay:a=600,...o}=e,[s,c]=_.useState(null),[l,u]=_.useState(null),[d,f]=_.useState(null),[p,m]=_.useState(null),[h,g]=_.useState(null),[v,y]=_.useState(0),[b,x]=_.useState(0),[S,C]=_.useState(!1),[w,T]=_.useState(!1),E=xr(t,c),ee=hp(i);return(0,B.jsx)(wp,{scope:n,type:r,dir:ee,scrollHideDelay:a,scrollArea:s,viewport:l,onViewportChange:u,content:d,onContentChange:f,scrollbarX:p,onScrollbarXChange:m,scrollbarXEnabled:S,onScrollbarXEnabledChange:C,scrollbarY:h,onScrollbarYChange:g,scrollbarYEnabled:w,onScrollbarYEnabledChange:T,onCornerWidthChange:y,onCornerHeightChange:x,children:(0,B.jsx)(W.div,{dir:ee,...o,ref:E,style:{position:`relative`,"--radix-scroll-area-corner-width":v+`px`,"--radix-scroll-area-corner-height":b+`px`,...e.style}})})},`ScrollArea`)),Dp=`ScrollAreaViewport`,Op=_.forwardRef(Q(function(e,t){let{__scopeScrollArea:n,children:r,nonce:i,...a}=e,o=Tp(Dp,n),s=xr(t,_.useRef(null),o.onViewportChange);return(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(kp,{nonce:i}),(0,B.jsx)(W.div,{"data-radix-scroll-area-viewport":``,...a,ref:s,style:{overflowX:o.scrollbarXEnabled?`scroll`:`hidden`,overflowY:o.scrollbarYEnabled?`scroll`:`hidden`,...e.style},children:(0,B.jsx)(`div`,{ref:o.onContentChange,style:{minWidth:`100%`,display:`table`},children:r})})]})},`ScrollAreaViewport`)),kp=_.memo(Q(function({nonce:e}){return(0,B.jsx)(`style`,{dangerouslySetInnerHTML:{__html:`[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}`},nonce:e})},`ScrollAreaViewportStyle`),(e,t)=>e.nonce===t.nonce),Ap=`ScrollAreaScrollbar`,jp=_.forwardRef(Q(function(e,t){let{forceMount:n,...r}=e,i=Tp(Ap,e.__scopeScrollArea),{onScrollbarXEnabledChange:a,onScrollbarYEnabledChange:o}=i,s=e.orientation===`horizontal`;return _.useEffect(()=>(s?a(!0):o(!0),()=>{s?a(!1):o(!1)}),[s,a,o]),i.type===`hover`?(0,B.jsx)(Mp,{...r,ref:t,forceMount:n}):i.type===`scroll`?(0,B.jsx)(Np,{...r,ref:t,forceMount:n}):i.type===`auto`?(0,B.jsx)(Pp,{...r,ref:t,forceMount:n}):i.type===`always`?(0,B.jsx)(Fp,{...r,ref:t,"data-state":`visible`}):null},`ScrollAreaScrollbar`)),Mp=_.forwardRef(Q(function(e,t){let{forceMount:n,...r}=e,i=Tp(Ap,e.__scopeScrollArea),[a,o]=_.useState(!1);return _.useEffect(()=>{let e=i.scrollArea,t=0;if(e){let n=Q(()=>{window.clearTimeout(t),o(!0)},`handlePointerEnter`),r=Q(()=>{t=window.setTimeout(()=>o(!1),i.scrollHideDelay)},`handlePointerLeave`);return e.addEventListener(`pointerenter`,n),e.addEventListener(`pointerleave`,r),()=>{window.clearTimeout(t),e.removeEventListener(`pointerenter`,n),e.removeEventListener(`pointerleave`,r)}}},[i.scrollArea,i.scrollHideDelay]),(0,B.jsx)(xi,{present:n||a,children:(0,B.jsx)(Pp,{"data-state":a?`visible`:`hidden`,...r,ref:t})})},`ScrollAreaScrollbarHover`)),Np=_.forwardRef(Q(function(e,t){let{forceMount:n,...r}=e,i=Tp(Ap,e.__scopeScrollArea),a=e.orientation===`horizontal`,o=tm(()=>c(`SCROLL_END`),100),[s,c]=bp(`hidden`,{hidden:{SCROLL:`scrolling`},scrolling:{SCROLL_END:`idle`,POINTER_ENTER:`interacting`},interacting:{SCROLL:`interacting`,POINTER_LEAVE:`idle`},idle:{HIDE:`hidden`,SCROLL:`scrolling`,POINTER_ENTER:`interacting`}});return _.useEffect(()=>{if(s===`idle`){let e=window.setTimeout(()=>c(`HIDE`),i.scrollHideDelay);return()=>window.clearTimeout(e)}},[s,i.scrollHideDelay,c]),_.useEffect(()=>{let e=i.viewport,t=a?`scrollLeft`:`scrollTop`;if(e){let n=e[t],r=Q(()=>{let r=e[t];n!==r&&(c(`SCROLL`),o()),n=r},`handleScroll`);return e.addEventListener(`scroll`,r),()=>e.removeEventListener(`scroll`,r)}},[i.viewport,a,c,o]),(0,B.jsx)(xi,{present:n||s!==`hidden`,children:(0,B.jsx)(Fp,{"data-state":s===`hidden`?`hidden`:`visible`,...r,ref:t,onPointerEnter:Xr(e.onPointerEnter,()=>c(`POINTER_ENTER`)),onPointerLeave:Xr(e.onPointerLeave,()=>c(`POINTER_LEAVE`))})})},`ScrollAreaScrollbarScroll`)),Pp=_.forwardRef(Q(function(e,t){let n=Tp(Ap,e.__scopeScrollArea),{forceMount:r,...i}=e,[a,o]=_.useState(!1),s=e.orientation===`horizontal`,c=tm(()=>{if(n.viewport){let e=n.viewport.offsetWidth<n.viewport.scrollWidth,t=n.viewport.offsetHeight<n.viewport.scrollHeight;o(s?e:t)}},10);return nm(n.viewport,c),nm(n.content,c),(0,B.jsx)(xi,{present:r||a,children:(0,B.jsx)(Fp,{"data-state":a?`visible`:`hidden`,...i,ref:t})})},`ScrollAreaScrollbarAuto`)),Fp=_.forwardRef(Q(function(e,t){let{orientation:n=`vertical`,...r}=e,i=Tp(Ap,e.__scopeScrollArea),a=_.useRef(null),o=_.useRef(0),[s,c]=_.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),l=Jp(s.viewport,s.content),u={...r,sizes:s,onSizesChange:c,hasThumb:l>0&&l<1,onThumbChange:Q(e=>a.current=e,`onThumbChange`),onThumbPointerUp:Q(()=>o.current=0,`onThumbPointerUp`),onThumbPointerDown:Q(e=>o.current=e,`onThumbPointerDown`)};function d(e,t){return Xp(e,o.current,s,t)}return Q(d,`getScrollPosition`),n===`horizontal`?(0,B.jsx)(Ip,{...u,ref:t,onThumbPositionChange:()=>{if(i.viewport&&a.current){let e=i.viewport.scrollLeft,t=Zp(e,s,i.dir);a.current.style.transform=`translate3d(${t}px, 0, 0)`}},onWheelScroll:e=>{i.viewport&&(i.viewport.scrollLeft=e)},onDragScroll:e=>{i.viewport&&(i.viewport.scrollLeft=d(e,i.dir))}}):n===`vertical`?(0,B.jsx)(Lp,{...u,ref:t,onThumbPositionChange:()=>{if(i.viewport&&a.current){let e=i.viewport.scrollTop,t=Zp(e,s);a.current.style.transform=`translate3d(0, ${t}px, 0)`}},onWheelScroll:e=>{i.viewport&&(i.viewport.scrollTop=e)},onDragScroll:e=>{i.viewport&&(i.viewport.scrollTop=d(e))}}):null},`ScrollAreaScrollbarVisible`)),Ip=_.forwardRef(Q(function(e,t){let{sizes:n,onSizesChange:r,...i}=e,a=Tp(Ap,e.__scopeScrollArea),[o,s]=_.useState(),c=_.useRef(null),l=xr(t,c,a.onScrollbarXChange);return _.useEffect(()=>{c.current&&s(getComputedStyle(c.current))},[c]),(0,B.jsx)(Bp,{"data-orientation":`horizontal`,...i,ref:l,sizes:n,style:{bottom:0,left:a.dir===`rtl`?`var(--radix-scroll-area-corner-width)`:0,right:a.dir===`ltr`?`var(--radix-scroll-area-corner-width)`:0,"--radix-scroll-area-thumb-width":Yp(n)+`px`,...e.style},onThumbPointerDown:t=>e.onThumbPointerDown(t.x),onDragScroll:t=>e.onDragScroll(t.x),onWheelScroll:(t,n)=>{if(a.viewport){let r=a.viewport.scrollLeft+t.deltaX;e.onWheelScroll(r),$p(r,n)&&t.preventDefault()}},onResize:()=>{c.current&&a.viewport&&o&&r({content:a.viewport.scrollWidth,viewport:a.viewport.offsetWidth,scrollbar:{size:c.current.clientWidth,paddingStart:qp(o.paddingLeft),paddingEnd:qp(o.paddingRight)}})}})},`ScrollAreaScrollbarX`)),Lp=_.forwardRef(Q(function(e,t){let{sizes:n,onSizesChange:r,...i}=e,a=Tp(Ap,e.__scopeScrollArea),[o,s]=_.useState(),c=_.useRef(null),l=xr(t,c,a.onScrollbarYChange);return _.useEffect(()=>{c.current&&s(getComputedStyle(c.current))},[c]),(0,B.jsx)(Bp,{"data-orientation":`vertical`,...i,ref:l,sizes:n,style:{top:0,right:a.dir===`ltr`?0:void 0,left:a.dir===`rtl`?0:void 0,bottom:`var(--radix-scroll-area-corner-height)`,"--radix-scroll-area-thumb-height":Yp(n)+`px`,...e.style},onThumbPointerDown:t=>e.onThumbPointerDown(t.y),onDragScroll:t=>e.onDragScroll(t.y),onWheelScroll:(t,n)=>{if(a.viewport){let r=a.viewport.scrollTop+t.deltaY;e.onWheelScroll(r),$p(r,n)&&t.preventDefault()}},onResize:()=>{c.current&&a.viewport&&o&&r({content:a.viewport.scrollHeight,viewport:a.viewport.offsetHeight,scrollbar:{size:c.current.clientHeight,paddingStart:qp(o.paddingTop),paddingEnd:qp(o.paddingBottom)}})}})},`ScrollAreaScrollbarY`)),[Rp,zp]=Sp(Ap),Bp=_.forwardRef(Q(function(e,t){let{__scopeScrollArea:n,sizes:r,hasThumb:i,onThumbChange:a,onThumbPointerUp:o,onThumbPointerDown:s,onThumbPositionChange:c,onDragScroll:l,onWheelScroll:u,onResize:d,...f}=e,p=Tp(Ap,n),[m,h]=_.useState(null),g=xr(t,h),v=_.useRef(null),y=_.useRef(``),b=p.viewport,x=r.content-r.viewport,S=ta(u),C=ta(c),w=tm(d,10);function T(e){if(v.current){let t=e.clientX-v.current.left,n=e.clientY-v.current.top;l({x:t,y:n})}}return Q(T,`handleDragScroll`),_.useEffect(()=>{let e=Q(e=>{let t=e.target;m?.contains(t)&&S(e,x)},`handleWheel`);return document.addEventListener(`wheel`,e,{passive:!1}),()=>document.removeEventListener(`wheel`,e,{passive:!1})},[b,m,x,S]),_.useEffect(C,[r,C]),nm(m,w),nm(p.content,w),(0,B.jsx)(Rp,{scope:n,scrollbar:m,hasThumb:i,onThumbChange:ta(a),onThumbPointerUp:ta(o),onThumbPositionChange:C,onThumbPointerDown:ta(s),children:(0,B.jsx)(W.div,{...f,ref:g,style:{position:`absolute`,...f.style},onPointerDown:Xr(e.onPointerDown,e=>{e.button===0&&(e.target.setPointerCapture(e.pointerId),v.current=m.getBoundingClientRect(),y.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect=`none`,p.viewport&&(p.viewport.style.scrollBehavior=`auto`),T(e))}),onPointerMove:Xr(e.onPointerMove,T),onPointerUp:Xr(e.onPointerUp,e=>{let t=e.target;t.hasPointerCapture(e.pointerId)&&t.releasePointerCapture(e.pointerId),document.body.style.webkitUserSelect=y.current,p.viewport&&(p.viewport.style.scrollBehavior=``),v.current=null})})})},`ScrollAreaScrollbarImpl`)),Vp=`ScrollAreaThumb`,Hp=_.forwardRef(Q(function(e,t){let{forceMount:n,...r}=e,i=zp(Vp,e.__scopeScrollArea);return(0,B.jsx)(xi,{present:n||i.hasThumb,children:(0,B.jsx)(Up,{ref:t,...r})})},`ScrollAreaThumb`)),Up=_.forwardRef(Q(function(e,t){let{__scopeScrollArea:n,style:r,...i}=e,a=Tp(Vp,n),o=zp(Vp,n),{onThumbPositionChange:s}=o,c=xr(t,o.onThumbChange),l=_.useRef(void 0),u=tm(()=>{l.current&&=(l.current(),void 0)},100);return _.useEffect(()=>{let e=a.viewport;if(e){let t=Q(()=>{if(u(),!l.current){let t=em(e,s);l.current=t,s()}},`handleScroll`);return s(),e.addEventListener(`scroll`,t),()=>e.removeEventListener(`scroll`,t)}},[a.viewport,u,s]),(0,B.jsx)(W.div,{"data-state":o.hasThumb?`visible`:`hidden`,...i,ref:c,style:{width:`var(--radix-scroll-area-thumb-width)`,height:`var(--radix-scroll-area-thumb-height)`,...r},onPointerDownCapture:Xr(e.onPointerDownCapture,e=>{let t=e.target.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;o.onThumbPointerDown({x:n,y:r})}),onPointerUp:Xr(e.onPointerUp,o.onThumbPointerUp)})},`ScrollAreaThumbImpl`)),Wp=`ScrollAreaCorner`,Gp=_.forwardRef(Q(function(e,t){let n=Tp(Wp,e.__scopeScrollArea),r=!!(n.scrollbarX&&n.scrollbarY);return n.type!==`scroll`&&r?(0,B.jsx)(Kp,{...e,ref:t}):null},`ScrollAreaCorner`)),Kp=_.forwardRef(Q(function(e,t){let{__scopeScrollArea:n,...r}=e,i=Tp(Wp,n),[a,o]=_.useState(0),[s,c]=_.useState(0),l=!!(a&&s),{onCornerWidthChange:u,onCornerHeightChange:d}=i;return nm(i.scrollbarX,()=>{let e=i.scrollbarX?.offsetHeight||0;i.onCornerHeightChange(e),c(e)}),nm(i.scrollbarY,()=>{let e=i.scrollbarY?.offsetWidth||0;i.onCornerWidthChange(e),o(e)}),_.useEffect(()=>()=>{u(0),d(0)},[u,d]),l?(0,B.jsx)(W.div,{...r,ref:t,style:{width:a,height:s,position:`absolute`,right:i.dir===`ltr`?0:void 0,left:i.dir===`rtl`?0:void 0,bottom:0,...e.style}}):null},`ScrollAreaCornerImpl`));function qp(e){return e?parseInt(e,10):0}Q(qp,`toInt`);function Jp(e,t){let n=e/t;return isNaN(n)?0:n}Q(Jp,`getThumbRatio`);function Yp(e){let t=Jp(e.viewport,e.content),n=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,r=(e.scrollbar.size-n)*t;return Math.max(r,18)}Q(Yp,`getThumbSize`);function Xp(e,t,n,r=`ltr`){let i=Yp(n),a=i/2,o=t||a,s=i-o,c=n.scrollbar.paddingStart+o,l=n.scrollbar.size-n.scrollbar.paddingEnd-s,u=n.content-n.viewport,d=r===`ltr`?[0,u]:[u*-1,0];return Qp([c,l],d)(e)}Q(Xp,`getScrollPositionFromPointer`);function Zp(e,t,n=`ltr`){let r=Yp(t),i=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,a=t.scrollbar.size-i,o=t.content-t.viewport,s=a-r,c=vp(e,n===`ltr`?[0,o]:[o*-1,0]);return Qp([0,o],[0,s])(c)}Q(Zp,`getThumbOffsetFromScroll`);function Qp(e,t){return n=>{if(e[0]===e[1]||t[0]===t[1])return t[0];let r=(t[1]-t[0])/(e[1]-e[0]);return t[0]+r*(n-e[0])}}Q(Qp,`linearScale`);function $p(e,t){return e>0&&e<t}Q($p,`isScrollingWithinScrollbarBounds`);var em=Q((e,t=()=>{})=>{let n={left:e.scrollLeft,top:e.scrollTop},r=0;return Q((function i(){let a={left:e.scrollLeft,top:e.scrollTop},o=n.left!==a.left,s=n.top!==a.top;(o||s)&&t(),n=a,r=window.requestAnimationFrame(i)}),`loop`)(),()=>window.cancelAnimationFrame(r)},`addUnlinkedScrollListener`);function tm(e,t){let n=ta(e),r=_.useRef(0);return _.useEffect(()=>()=>window.clearTimeout(r.current),[]),_.useCallback(()=>{window.clearTimeout(r.current),r.current=window.setTimeout(n,t)},[n,t])}Q(tm,`useDebounceCallback`);function nm(e,t){let n=ta(t);ti(()=>{let t=0;if(e){let r=new ResizeObserver(()=>{cancelAnimationFrame(t),t=window.requestAnimationFrame(n)});return r.observe(e),()=>{window.cancelAnimationFrame(t),r.unobserve(e)}}},[e,n])}Q(nm,`useResizeObserver`);var rm=Ep,im=Op,am=Gp;function om({className:e,children:t,...n}){return(0,B.jsxs)(rm,{"data-slot":`scroll-area`,className:z(`relative`,e),...n,children:[(0,B.jsx)(im,{"data-slot":`scroll-area-viewport`,className:`focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1`,children:t}),(0,B.jsx)(sm,{}),(0,B.jsx)(am,{})]})}function sm({className:e,orientation:t=`vertical`,...n}){return(0,B.jsx)(jp,{"data-slot":`scroll-area-scrollbar`,orientation:t,className:z(`flex touch-none p-px transition-colors select-none`,t===`vertical`&&`h-full w-2.5 border-l border-l-transparent`,t===`horizontal`&&`h-2.5 flex-col border-t border-t-transparent`,e),...n,children:(0,B.jsx)(Hp,{"data-slot":`scroll-area-thumb`,className:`bg-border relative flex-1 rounded-full`})})}function cm({open:e=!1,profileId:t=``,onOpenChange:n}){let{t:r}=mr(),[i,a]=(0,_.useState)(!1),[o,s]=(0,_.useState)([]);(0,_.useEffect)(()=>{e&&t&&c(t)},[e,t]);async function c(e){a(!0),s([]);let t=await Gn(`/api/user-profile/changelog?profileId=${encodeURIComponent(e)}&limit=10`);a(!1),t.success&&t.data?s(t.data):s([])}return(0,B.jsx)(Ms,{open:e,onOpenChange:n,children:(0,B.jsxs)(Fs,{className:`sm:max-w-lg`,children:[(0,B.jsx)(Is,{children:(0,B.jsx)(Rs,{children:r(`modal-changelog-title`)})}),(0,B.jsx)(om,{className:`max-h-80`,children:i?(0,B.jsx)(`div`,{className:`text-sm text-muted-foreground py-6 text-center`,children:r(`loading-changelog`)}):o.length===0?(0,B.jsx)(`div`,{className:`text-sm text-muted-foreground py-6 text-center`,children:r(`empty-changelog`)}):(0,B.jsx)(`div`,{className:`space-y-3 pr-3`,children:o.map((e,t)=>(0,B.jsxs)(`div`,{className:`rounded-lg border border-border p-3 space-y-1`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-xs`,children:[(0,B.jsxs)(`span`,{className:`font-medium`,children:[`v`,e.version]}),(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:e.changeType}),(0,B.jsx)(`span`,{className:`text-muted-foreground ml-auto`,children:Jl(e.createdAt)})]}),(0,B.jsx)(`p`,{className:`text-sm`,children:e.changeSummary})]},`${e.version}-${t}`))})})]})})}function lm({className:e,type:t,...n}){return(0,B.jsx)(`input`,{type:t,"data-slot":`input`,className:z(`border-input file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 flex h-8 w-full min-w-0 rounded-lg border bg-transparent px-2.5 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50`,`focus-visible:border-ring focus-visible:ring-ring/30 focus-visible:ring-3`,`aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive`,e),...n})}function um({open:e=!1,type:t=null,index:n=0,action:r=`edit`,item:i=null,onOpenChange:a,onSaved:o}){let{t:s}=mr(),[c,l]=(0,_.useState)(``),[u,d]=(0,_.useState)(``),[f,p]=(0,_.useState)([``]),[m,h]=(0,_.useState)(`1`),[g,v]=(0,_.useState)(!1),y=r===`edit`,b=t===`workflows`;(0,_.useEffect)(()=>{e&&i&&(l(i.category||``),d(i.description||``),p(i.steps?.length?[...i.steps]:[``]),h(`1`))},[e,i]);let x=y?s(`btn-edit`)||`Edit Item`:m===`2`?s(`confirm-delete-title`)||`Confirm Delete`:s(`confirm-delete`)||`Delete Item?`;function S(e){a?.(e)}function C(){p(e=>[...e,``])}function w(e){p(t=>{let n=t.filter((t,n)=>n!==e);return n.length===0?[``]:n})}function T(e,t){p(n=>n.map((n,r)=>r===e?t:n))}async function E(e){if(e.preventDefault(),!t)return;if(r===`delete`){if(m===`1`){h(`2`);return}v(!0);let e=await Gn(`/api/user-profile/item`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify({type:t,index:n,action:`delete`})});v(!1),e.success?(V.success(s(`toast-delete-success`)||`Item deleted`),S(!1),o?.()):V.error(e.error||s(`toast-delete-failed`)||`Delete failed`);return}v(!0);let i={type:t,index:n,action:`edit`,category:b?void 0:c,description:u};t===`workflows`&&(i.steps=f.map(e=>e.trim()).filter(Boolean));let a=await Gn(`/api/user-profile/item`,{method:`PATCH`,headers:{"Content-Type":`application/json`},body:JSON.stringify(i)});v(!1),a.success?(V.success(s(`toast-update-success`)||`Item updated`),S(!1),o?.()):V.error(a.error||s(`toast-update-failed`)||`Update failed`)}return(0,B.jsx)(Ms,{open:e,onOpenChange:S,children:(0,B.jsxs)(Fs,{className:`sm:max-w-lg`,children:[(0,B.jsx)(Is,{children:(0,B.jsx)(Rs,{children:x})}),(0,B.jsxs)(`form`,{className:`space-y-4`,onSubmit:E,children:[y||m===`1`?(0,B.jsxs)(B.Fragment,{children:[b?null:(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsx)(J,{htmlFor:`profile-item-category`,children:s(`label-category`)}),(0,B.jsx)(lm,{id:`profile-item-category`,value:c,onChange:e=>l(e.target.value),disabled:!y})]}),(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsx)(J,{htmlFor:`profile-item-description`,children:s(`label-description`)}),(0,B.jsx)(Bl,{id:`profile-item-description`,rows:4,value:u,onChange:e=>d(e.target.value),disabled:!y})]}),b&&y?(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsx)(J,{children:s(`label-steps`)}),(0,B.jsx)(`div`,{className:`space-y-2`,children:f.map((e,t)=>(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground w-5 tabular-nums`,children:t+1}),(0,B.jsx)(lm,{value:e,placeholder:`Step ${t+1}...`,onChange:e=>T(t,e.target.value)}),(0,B.jsx)(U,{type:`button`,variant:`ghost`,size:`icon-xs`,onClick:()=>w(t),children:`×`})]},t))}),(0,B.jsx)(U,{type:`button`,variant:`secondary`,size:`sm`,onClick:C,children:s(`btn-add-step`)})]}):null]}):null,(0,B.jsxs)(Ls,{children:[(0,B.jsx)(U,{type:`button`,variant:`secondary`,onClick:()=>S(!1),children:s(`btn-cancel`)}),(0,B.jsx)(U,{type:`submit`,variant:y?`default`:`destructive`,disabled:g,children:y?s(`btn-save`)||`Save`:s(`btn-delete`)||`Delete`})]})]})]})})}var dm=20;function fm(e,t){let n=e.length,r=Math.max(1,Math.ceil(n/dm)),i=Math.min(t,r),a=(i-1)*dm;return{items:e.slice(a,a+dm),total:n,totalPages:r,page:i,start:a}}function pm(e){return Math.round((e.confidence||0)*100)}function mm(e){return e.evidence?Array.isArray(e.evidence)?e.evidence.join(`
122
122
  `):e.evidence:``}function hm(e){return e.evidence?Array.isArray(e.evidence)?e.evidence.length:1:0}function gm({profile:e,loading:t=!1,onRefresh:n,onCleanup:r}){let{t:i}=mr(),[a,o]=(0,_.useState)({pref:1,pat:1,wf:1}),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(!1),[d,f]=(0,_.useState)(null),[p,m]=(0,_.useState)(0),[h,g]=(0,_.useState)(`edit`),[v,y]=(0,_.useState)(null),b=(0,_.useMemo)(()=>{if(!e?.exists||!e.profileData)return null;let t=e.profileData;if(typeof t==`string`)try{t=JSON.parse(t)}catch{return null}return t},[e]),x=(0,_.useMemo)(()=>Mc(b?.preferences),[b]),S=(0,_.useMemo)(()=>Mc(b?.patterns),[b]),C=(0,_.useMemo)(()=>Mc(b?.workflows),[b]),w=(0,_.useMemo)(()=>C.map((e,t)=>({item:e,index:t})).sort((e,t)=>(t.item.frequency||0)-(e.item.frequency||0)),[C]),T=fm(x,a.pref),E=fm(S,a.pat),ee=fm(w,a.wf),D=C.length;function O(e,t,n){let r=(e===`preferences`?x:e===`patterns`?S:C)[t];r&&(f(e),m(t),g(n),y(r),u(!0))}function re(e,t){return e.indexOf(t)}function ie({page:e,pageKey:t}){return e.total<=dm?null:(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-1.5 pt-2`,children:[(0,B.jsxs)(`span`,{className:`text-xs text-muted-foreground mr-2`,children:[e.start+1,`-`,Math.min(e.start+dm,e.total),` / `,e.total]}),Array.from({length:e.totalPages},(e,t)=>t+1).map(n=>(0,B.jsx)(U,{size:`xs`,variant:n===e.page?`default`:`outline`,onClick:()=>o(e=>({...e,[t]:n})),children:n},n))]})}function k({item:e,type:t,fullList:n}){let r=re(n,e),a=pm(e);return(0,B.jsxs)(`div`,{className:`rounded-xl border border-border bg-card/50 p-3 space-y-2`,children:[(0,B.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,B.jsx)(ql,{variant:`outline`,children:e.category||`General`}),(0,B.jsxs)(`div`,{className:`flex items-center gap-0.5 ml-auto`,children:[(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:i(`btn-edit`)||`Edit`,onClick:()=>O(t,r,`edit`),children:(0,B.jsx)(_e,{className:`size-3`})}),(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,title:i(`btn-delete`)||`Delete`,onClick:()=>O(t,r,`delete`),children:(0,B.jsx)(ke,{className:`size-3`})})]}),(0,B.jsxs)(`div`,{className:z(`shrink-0 rounded-md border px-1.5 py-0.5 text-[10px] font-medium tabular-nums`,Ic[Fc(a)]),title:`${i(`label-confidence`)}: ${a}%`,children:[a,`%`]})]}),(0,B.jsx)(`p`,{className:`text-sm`,children:e.description||``}),e.evidence||e.frequency?(0,B.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{className:`inline-flex items-center gap-1`,title:i(`label-evidence-tooltip`,{count:e.frequency||1}),children:[(0,B.jsx)(Oe,{className:`size-3`}),e.frequency||1]}),hm(e)>0?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`span`,{children:`·`}),(0,B.jsxs)(`span`,{className:`inline-flex items-center gap-1`,title:mm(e),children:[(0,B.jsx)(N,{className:`size-3`}),hm(e),` evidence`]})]}):null]}):null]})}return t&&!e?(0,B.jsx)(`div`,{className:`text-sm text-muted-foreground py-8 text-center`,children:i(`loading-profile`)}):e?.exists?b?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`div`,{className:`space-y-6`,children:[(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsx)(`h3`,{className:`text-base font-medium`,children:e.displayName||e.userId}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsxs)(`span`,{className:`rounded-full bg-muted px-2.5 py-1 text-xs`,children:[(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:i(`profile-version`)}),(0,B.jsx)(`span`,{className:`ml-1`,children:e.version})]}),(0,B.jsxs)(`span`,{className:`rounded-full bg-muted px-2.5 py-1 text-xs`,children:[(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:i(`profile-prompts`)}),(0,B.jsx)(`span`,{className:`ml-1`,children:e.totalPromptsAnalyzed})]}),(0,B.jsxs)(`span`,{className:`rounded-full bg-muted px-2.5 py-1 text-xs`,children:[(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:i(`profile-updated`)}),(0,B.jsx)(`span`,{className:`ml-1`,children:e.lastAnalyzedAt?Jl(e.lastAnalyzedAt):`—`})]}),(0,B.jsxs)(`div`,{className:`ms-auto flex flex-wrap items-center gap-1.5`,children:[(0,B.jsxs)(U,{variant:`outline`,size:`sm`,onClick:()=>r?.(),children:[(0,B.jsx)(Ee,{className:`size-3.5`}),i(`btn-ai-cleanup`)]}),(0,B.jsxs)(U,{variant:`secondary`,size:`sm`,onClick:()=>n?.(),children:[(0,B.jsx)(Se,{className:`size-3.5`}),i(`btn-refresh`)]}),(0,B.jsxs)(U,{variant:`secondary`,size:`sm`,onClick:()=>c(!0),children:[(0,B.jsx)(Ce,{className:`size-3.5`}),`History`]})]})]})]}),(0,B.jsxs)(`div`,{className:`grid gap-6`,children:[(0,B.jsxs)(`section`,{id:`profile-preferences`,className:`scroll-mt-4 space-y-3`,children:[(0,B.jsxs)(`h4`,{className:`flex items-center gap-2 text-sm font-medium`,children:[(0,B.jsx)(M,{className:`size-4`}),i(`profile-preferences`),(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:x.length})]}),x.length===0?(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:i(`empty-preferences`)}):(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2 lg:grid-cols-3`,children:T.items.map(e=>(0,B.jsx)(k,{item:e,type:`preferences`,fullList:x},re(x,e)))}),(0,B.jsx)(ie,{page:T,pageKey:`pref`})]})]}),(0,B.jsxs)(`section`,{id:`profile-patterns`,className:`scroll-mt-4 space-y-3`,children:[(0,B.jsxs)(`h4`,{className:`flex items-center gap-2 text-sm font-medium`,children:[(0,B.jsx)(te,{className:`size-4`}),i(`profile-patterns`),(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:S.length})]}),S.length===0?(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:i(`empty-patterns`)}):(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`div`,{className:`grid gap-2 sm:grid-cols-2 lg:grid-cols-3`,children:E.items.map(e=>(0,B.jsx)(k,{item:e,type:`patterns`,fullList:S},re(S,e)))}),(0,B.jsx)(ie,{page:E,pageKey:`pat`})]})]}),(0,B.jsxs)(`section`,{id:`profile-workflows`,className:`scroll-mt-4 space-y-3`,children:[(0,B.jsxs)(`h4`,{className:`flex items-center gap-2 text-sm font-medium`,children:[(0,B.jsx)(Pe,{className:`size-4`}),i(`profile-workflows`),(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:D})]}),D===0?(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:i(`empty-workflows`)}):(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`div`,{className:`space-y-2`,children:ee.items.map(e=>{let t=e.item,n=e.index,r=pm(t);return(0,B.jsxs)(`div`,{className:`rounded-xl border border-border bg-card/50 p-3 space-y-2`,children:[(0,B.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,B.jsx)(`div`,{className:`text-sm font-medium flex-1`,children:t.description||``}),(0,B.jsxs)(`div`,{className:`flex items-center gap-0.5`,children:[(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,onClick:()=>O(`workflows`,n,`edit`),children:(0,B.jsx)(_e,{className:`size-3`})}),(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,onClick:()=>O(`workflows`,n,`delete`),children:(0,B.jsx)(ke,{className:`size-3`})})]}),(0,B.jsxs)(`div`,{className:`size-9 rounded-full border border-border grid place-items-center text-[10px] tabular-nums shrink-0`,children:[r,`%`]})]}),t.steps?.length?(0,B.jsx)(`div`,{className:`flex flex-wrap items-center gap-1.5`,children:t.steps.map((e,n)=>(0,B.jsxs)(`div`,{className:`contents`,children:[(0,B.jsxs)(`div`,{className:`inline-flex items-center gap-1.5 rounded-lg bg-muted px-2 py-1 text-xs`,children:[(0,B.jsx)(`span`,{className:`text-muted-foreground tabular-nums`,children:n+1}),(0,B.jsx)(`span`,{children:e})]}),n<(t.steps?.length||0)-1?(0,B.jsx)(ne,{className:`size-3 text-muted-foreground`}):null]},n))}):null,(0,B.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,B.jsxs)(`span`,{className:`inline-flex items-center gap-1`,title:i(`label-evidence-tooltip`,{count:t.frequency||1}),children:[(0,B.jsx)(Oe,{className:`size-3`}),t.frequency||1]}),hm(t)>0?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`span`,{children:`·`}),(0,B.jsxs)(`span`,{className:`inline-flex items-center gap-1`,title:mm(t),children:[(0,B.jsx)(N,{className:`size-3`}),hm(t),` evidence`]})]}):null]})]},e.index)})}),(0,B.jsx)(ie,{page:ee,pageKey:`wf`})]})]})]})]}),(0,B.jsx)(cm,{open:s,onOpenChange:c,profileId:e?.id||``}),(0,B.jsx)(um,{open:l,onOpenChange:u,type:d,index:p,action:h,item:v,onSaved:n})]}):null:(0,B.jsxs)(`div`,{className:`flex flex-col items-center gap-2 py-10 text-muted-foreground`,children:[(0,B.jsx)(Me,{className:`size-8`}),(0,B.jsx)(`p`,{className:`text-sm`,children:e?.message||i(`empty-preferences`)})]})}function _m({open:e=!1,count:t=0,onOpenChange:n,onComplete:r}){let{t:i}=mr(),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(0);(0,_.useEffect)(()=>{e&&!a&&(c(i(`migration-found-tags`,{count:t})),u(0))},[e,a,t,i]);function d(e){a&&!e||n?.(e)}async function f(){o(!0),c(i(`status-migration-init`)),u(0);let e=!0,t=0,n=1e3;for(;e&&t<n;){t++;let n=await Gn(`/api/migration/tags/run-batch`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({batchSize:3})});if(!n.success||!n.data){c(i(`toast-migration-failed`)+`: `+(n.error||``)),o(!1);return}let r=n.data.processed;e=n.data.hasMore;let a=n.data.total;u(a>0?Math.round(r/a*100):0),c(i(`status-migration-progress`,{current:r,total:a})),e&&await new Promise(e=>setTimeout(e,100))}if(t>=n){c(i(`migration-stopped`)),o(!1);return}u(100),c(i(`toast-migration-success`)),V.success(i(`toast-migration-success`)),setTimeout(()=>{o(!1),d(!1),r?.()},2e3)}return(0,B.jsx)(Ms,{open:e,onOpenChange:d,children:(0,B.jsxs)(Fs,{className:`sm:max-w-md`,showCloseButton:!a,children:[(0,B.jsx)(Is,{children:(0,B.jsx)(Rs,{children:i(`modal-migration-title`)})}),(0,B.jsxs)(`div`,{className:`space-y-3`,children:[(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:s}),(0,B.jsx)(`div`,{className:`h-2 rounded-full bg-muted overflow-hidden`,children:(0,B.jsx)(`div`,{className:`h-full bg-primary transition-all duration-200`,style:{width:`${l}%`}})}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:i(`migration-note`)})]}),a?null:(0,B.jsx)(Ls,{children:(0,B.jsxs)(U,{onClick:f,children:[(0,B.jsx)(ye,{className:`size-3.5`}),i(`btn-start-migration`)]})})]})})}var vm=[{id:`settings-section-external-api`,title:`External API`},{id:`settings-section-models`,title:`Models`},{id:`settings-section-embedding`,title:`Embedding`},{id:`settings-section-keys`,title:`Keys and access`},{id:`settings-section-diagnostics`,title:`Capture diagnostics`},{id:`settings-section-health`,title:`Health`},{id:`settings-section-claude-folder`,title:`Claude Code folder`},{id:`settings-section-import`,title:`Import and backfill`},{id:`settings-section-auto-import`,title:`Automatic import`},{id:`settings-section-profile`,title:`Profile learning`},{id:`settings-section-directory-maps`,title:`Directory maps`},{id:`settings-section-web-app`,title:`Web app`},{id:`settings-section-log`,title:`Log`}];async function $(e,t={}){let n=(t.method??`GET`).toUpperCase(),r=n!==`GET`&&n!==`HEAD`,i=await fetch(e,{...t,headers:{"x-omms-token":window.__OMMS_TOKEN__??``,...r||t.body?{"Content-Type":`application/json`}:{},...t.headers}}),a=await i.json();if(!i.ok)throw Error(a.error??`Request failed (${i.status})`);return a}var ym=new Set,bm=0;function xm(e){bm++;for(let t of ym)t(e)}function Sm(){let e=bm;return{isCurrent:()=>bm===e}}async function Cm(){try{let e=await $(`/api/settings`);return xm(e),e}catch{return null}}function wm(e){return ym.add(e),()=>{ym.delete(e)}}function Tm(e,t){return`${e.replace(/\.+$/,``)}. ${t}`}function Em(){let e=0;return{begin(){let t=++e;return()=>t===e}}}async function Dm(e,t){e(!0);try{return await t()}finally{e(!1)}}var Om={Models:[`模型`,`النماذج`],"External API fallback":[`外部 API 备用模型`,`النموذج الاحتياطي عبر واجهة API الخارجية`],none:[`无`,`لا يوجد`],ready:[`就绪`,`جاهز`],"not ready":[`未就绪`,`غير جاهز`],"Credentials (values hidden)":[`凭据(不显示内容)`,`بيانات الاعتماد (القيم مخفية)`],set:[`已设置`,`مضبوط`],"not set":[`未设置`,`غير مضبوط`],"Effective model":[`当前使用模型`,`النموذج المستخدم`],session:[`会话`,`الجلسة`],"external API":[`外部 API`,`واجهة API الخارجية`],unavailable:[`不可用`,`غير متاح`],"Project override is active. Changes to the global file may not take effect here.":[`项目设置优先。全局文件的更改可能不会在此生效。`,`إعدادات المشروع لها الأولوية. قد لا تسري تغييرات الملف العام هنا.`],"Model choice":[`模型选择`,`اختيار النموذج`],"Session model":[`会话模型`,`نموذج الجلسة`],"Manual model":[`手动选择模型`,`اختيار النموذج يدوياً`],"Manual provider/model":[`手动输入提供商/模型`,`إدخال المزوّد/النموذج يدوياً`],"Model list unavailable. Enter provider/model manually.":[`模型列表不可用。请手动输入提供商/模型。`,`قائمة النماذج غير متاحة. أدخل المزوّد/النموذج يدوياً.`],"OpenCode model list unavailable":[`OpenCode 模型列表不可用`,`قائمة نماذج OpenCode غير متاحة`],"OMMS could not find OpenCode on this computer, so it cannot list OpenCode's models here. Type the model as provider/model, for example zai-coding-plan/glm-5.3. If OpenCode is installed, open an OpenCode session and reload this page.":[`OMMS 在这台电脑上找不到 OpenCode,因此无法在此列出 OpenCode 的模型。请按 提供商/模型 格式输入模型,例如 zai-coding-plan/glm-5.3。如果已安装 OpenCode,请打开一个 OpenCode 会话,然后重新加载此页面。`,`لم يعثر OMMS على OpenCode في هذا الحاسوب، لذا لا يمكنه عرض نماذج OpenCode هنا. أدخل النموذج بصيغة المزوّد/النموذج، مثل zai-coding-plan/glm-5.3. إذا كان OpenCode مثبتاً، فافتح جلسة OpenCode ثم أعد تحميل هذه الصفحة.`],"OpenCode took too long to send its model list. Reload this page to try again, or type the model as provider/model.":[`OpenCode 发送模型列表的时间过长。请重新加载此页面重试,或按 提供商/模型 格式输入模型。`,`استغرق OpenCode وقتاً طويلاً لإرسال قائمة نماذجه. أعد تحميل هذه الصفحة للمحاولة مرة أخرى، أو أدخل النموذج بصيغة المزوّد/النموذج.`],"OpenCode has no signed-in models. Run `opencode auth login`, then reload this page.":["OpenCode 没有已登录的模型。请运行 `opencode auth login`,然后重新加载此页面。","لا توجد في OpenCode نماذج مسجَّل الدخول إليها. شغّل `opencode auth login` ثم أعد تحميل هذه الصفحة."],"This OpenCode version sent a model list OMMS cannot read. Type the model as provider/model. Update OMMS if this continues.":[`此版本的 OpenCode 发送的模型列表 OMMS 无法读取。请按 提供商/模型 格式输入模型。如果问题持续,请更新 OMMS。`,`أرسل هذا الإصدار من OpenCode قائمة نماذج لا يستطيع OMMS قراءتها. أدخل النموذج بصيغة المزوّد/النموذج. حدّث OMMS إذا استمرت المشكلة.`],"OMMS could not read Pi's model list. Type the model as provider/model.":[`OMMS 无法读取 Pi 的模型列表。请按 提供商/模型 格式输入模型。`,`تعذّر على OMMS قراءة قائمة نماذج Pi. أدخل النموذج بصيغة المزوّد/النموذج.`],"Pi has no signed-in models. Sign in to a provider in Pi, then reload this page.":[`Pi 没有已登录的模型。请在 Pi 中登录一个提供商,然后重新加载此页面。`,`لا توجد في Pi نماذج مسجَّل الدخول إليها. سجّل الدخول إلى مزوّد في Pi ثم أعد تحميل هذه الصفحة.`],"Save model":[`保存模型`,`حفظ النموذج`],"Enter a model as provider/model.":[`按 提供商/模型 格式输入。`,`أدخل النموذج بصيغة المزوّد/النموذج.`],"Saved. New capture and profile work uses these settings.":[`已保存。下一次捕获和用户画像将使用这些设置。`,`تم الحفظ. ستستخدم عمليات الالتقاط والملف الشخصي الجديدة هذه الإعدادات.`],"Saved. OMMS now reads ~/.config/omms/omms.jsonc. The legacy config was kept.":[`已保存。OMMS 现在读取 ~/.config/omms/omms.jsonc,旧配置保留。`,`تم الحفظ. يقرأ OMMS الآن الملف ~/.config/omms/omms.jsonc مع الاحتفاظ بالإعدادات القديمة.`],"Current settings were reloaded; check the values and save again.":[`已重新加载当前设置;检查数值后再次保存。`,`أُعيد تحميل الإعدادات الحالية. راجع القيم ثم احفظ مجدداً.`],"Capture diagnostics":[`捕获诊断`,`تشخيص الالتقاط`],"Time range":[`时间范围`,`الفترة الزمنية`],"24 hours":[`24 小时`,`24 ساعة`],"7 days":[`7 天`,`7 أيام`],"30 days":[`30 天`,`30 يوماً`],"90 days":[`90 天`,`90 يوماً`],"Host / model":[`主机 / 模型`,`المضيف / النموذج`],Saved:[`已保存`,`محفوظ`],Skipped:[`已跳过`,`متجاوز`],Failed:[`失败`,`فشل`],Total:[`总数`,`المجموع`],"Failure reasons":[`失败原因`,`أسباب الفشل`],"Recent attempts":[`最近尝试`,`المحاولات الأخيرة`],Time:[`时间`,`الوقت`],Host:[`主机`,`المضيف`],Source:[`来源`,`المصدر`],Session:[`会话`,`الجلسة`],Path:[`路径`,`المسار`],Model:[`模型`,`النموذج`],Stop:[`结束原因`,`سبب التوقف`],Blocks:[`区块`,`الكتل`],Prompt:[`提示词长度`,`طول الطلب`],Reply:[`回复长度`,`طول الرد`],Duration:[`耗时`,`المدة`],Outcome:[`结果`,`النتيجة`],Reason:[`原因`,`السبب`],"Save capture traces":[`保存捕获追踪`,`حفظ تتبعات الالتقاط`],"Traces can contain conversation content after redaction. Keep tracing off unless you need it for debugging.":[`追踪文件在脱敏后仍可能包含对话内容。仅在调试时开启。`,`قد تحتوي التتبعات على محتوى المحادثة بعد التنقيح. فعّلها عند التصحيح فقط.`],"This project turns tracing off. The global switch cannot turn it on here.":[`此项目已关闭追踪。全局开关无法在此开启。`,`أوقف هذا المشروع التتبع. لا يمكن للمفتاح العام تفعيله هنا.`],"Trace retention (days)":[`追踪保留天数`,`مدة حفظ التتبعات (بالأيام)`],"Attempt retention (days)":[`尝试记录保留天数`,`مدة حفظ المحاولات (بالأيام)`],"Retry retention (hours)":[`重试保留小时数`,`مدة حفظ إعادة المحاولة (بالساعات)`],"When the capture model cannot be reached, OMMS keeps the turn and tries again later. Queued turns can hold conversation content after redaction. 0 turns the queue off and deletes waiting turns.":[`捕获模型无法访问时,OMMS 会保留该轮对话并稍后重试。排队的对话在脱敏后仍可能包含对话内容。设为 0 会关闭队列并删除等待中的对话。`,`عندما يتعذر الوصول إلى نموذج الالتقاط، يحتفظ OMMS بالجولة ويعيد المحاولة لاحقاً. قد تحتوي الجولات المنتظرة على محتوى المحادثة بعد التنقيح. القيمة 0 توقف قائمة الانتظار وتحذف الجولات المنتظرة.`],"Turns waiting for retry":[`等待重试的对话`,`الجولات المنتظرة لإعادة المحاولة`],"Retry now":[`立即重试`,`أعد المحاولة الآن`],"Retrying now.":[`正在重试。`,`تجري إعادة المحاولة الآن.`],"A retry is already running.":[`重试已在运行。`,`إعادة المحاولة قيد التشغيل بالفعل.`],"These turns retry at the next Pi session start.":[`这些对话将在下次启动 Pi 会话时重试。`,`ستُعاد محاولة هذه الجولات عند بدء جلسة Pi التالية.`],"These turns retry at the next OpenCode session start.":[`这些对话将在下次启动 OpenCode 会话时重试。`,`ستُعاد محاولة هذه الجولات عند بدء جلسة OpenCode التالية.`],"These turns retry at the next Claude Code session start.":[`这些对话将在下次启动 Claude Code 会话时重试。`,`ستُعاد محاولة هذه الجولات عند بدء جلسة Claude Code التالية.`],"Claude Code capture uses the external API.":[`Claude Code 捕获使用外部 API。`,`يستخدم التقاط Claude Code واجهة API الخارجية.`],"Claude Code capture is off. Complete the external API settings.":[`Claude Code 捕获已关闭。请完成外部 API 设置。`,`التقاط Claude Code متوقف. أكمل إعدادات واجهة API الخارجية.`],"Missing settings":[`缺少的设置`,`الإعدادات الناقصة`],"memoryModel is not configured":[`未配置 memoryModel`,`لم يُضبط memoryModel`],"memoryApiUrl is not configured":[`未配置 memoryApiUrl`,`لم يُضبط memoryApiUrl`],"memoryApiKey is not configured":[`未配置 memoryApiKey`,`لم يُضبط memoryApiKey`],"memoryApiKey contains a placeholder value":[`memoryApiKey 包含占位值`,`يحتوي memoryApiKey على قيمة نائبة`],"Claude Code backfill always uses the external API. It has no backfill model setting.":[`Claude Code 回填始终使用外部 API,没有回填模型设置。`,`يستخدم استيراد Claude Code دائماً واجهة API الخارجية، ولا يوجد له إعداد لنموذج الاستيراد.`],"Claude Code transcripts folder":[`Claude Code 对话记录文件夹`,`مجلد سجلات محادثات Claude Code`],"Claude Code transcripts":[`Claude Code 对话记录`,`سجلات محادثات Claude Code`],found:[`已找到`,`موجود`],"not found":[`未找到`,`غير موجود`],"Claude Code imports always use the external API.":[`Claude Code 导入始终使用外部 API。`,`يستخدم استيراد Claude Code دائماً واجهة API الخارجية.`],"Claude Code imports use the external API. Complete the external API settings.":[`Claude Code 导入使用外部 API。请完成外部 API 设置。`,`يستخدم استيراد Claude Code واجهة API الخارجية. أكمل إعدادات واجهة API الخارجية.`],"Trace files":[`追踪文件`,`ملفات التتبع`],View:[`查看`,`عرض`],Delete:[`删除`,`حذف`],Health:[`健康检查`,`فحص الحالة`],"Config files":[`配置文件`,`ملفات الإعدادات`],"Memory store":[`记忆存储`,`مخزن الذاكرة`],Embedding:[`嵌入模型`,`نموذج التضمين`],"Web binding":[`网页服务绑定`,`ربط خادم الويب`],"OpenCode model":[`OpenCode 模型`,`نموذج OpenCode`],"Pi model":[`Pi 模型`,`نموذج Pi`],"Capture failures (24 hours)":[`捕获失败(24 小时)`,`فشل الالتقاط (24 ساعة)`],"OpenCode model test":[`OpenCode 模型测试`,`اختبار نموذج OpenCode`],"Pi model test":[`Pi 模型测试`,`اختبار نموذج Pi`],"Run checks":[`运行检查`,`تشغيل الفحوصات`],"Run checks and test models":[`运行检查并测试模型`,`تشغيل الفحوصات واختبار النماذج`],"Checking…":[`正在检查…`,`جارٍ الفحص…`],pass:[`通过`,`نجاح`],warn:[`警告`,`تحذير`],fail:[`失败`,`فشل`],"Import and backfill":[`导入和回填`,`الاستيراد والاستكمال`],"Automatic import":[`自动导入`,`الاستيراد التلقائي`],"Automatic import makes model calls. Changes apply at the next host start. Turning it off stops a running import after the current exchange.":[`自动导入会调用模型。更改在下次启动主机时生效。关闭后,正在运行的导入将在当前轮次结束后停止。`,`يستدعي الاستيراد التلقائي النموذج. تسري التغييرات عند بدء المضيف التالي. يوقف التعطيل الاستيراد بعد التبادل الحالي.`],"Import past chats automatically":[`自动导入过去的对话`,`استيراد المحادثات السابقة تلقائياً`],"Backfill model":[`历史导入模型`,`نموذج استيراد السجل`],"Same as live capture":[`与实时捕获相同`,`مثل الالتقاط المباشر`],"Saved. Changes apply at the next host start.":[`已保存。更改在下次启动主机时生效。`,`تم الحفظ. تسري التغييرات عند بدء المضيف التالي.`],State:[`状态`,`الحالة`],"not started":[`尚未开始`,`لم يبدأ`],"not-started":[`尚未开始`,`لم يبدأ`],Imported:[`已导入`,`مستورَد`],Pending:[`待处理`,`معلّق`],"Unresolved sessions":[`目录未解析的会话`,`جلسات بمجلدات غير محددة`],Cutoff:[`截止时间`,`وقت القطع`],stopped:[`已停止`,`توقف`],"Web app":[`网页应用`,`تطبيق الويب`],"Start web app at login":[`登录时启动网页应用`,`بدء تطبيق الويب عند تسجيل الدخول`],"Login item":[`登录启动项`,`عنصر بدء تسجيل الدخول`],"not installed":[`未安装`,`غير مثبّت`],"not-installed":[`未安装`,`غير مثبّت`],installed:[`已安装`,`مثبّت`],unsupported:[`不受支持`,`غير مدعوم`],"no-runtime":[`缺少运行环境`,`بيئة التشغيل غير متاحة`],"no-package":[`缺少软件包`,`الحزمة غير متاحة`],"Login items are unsupported on this platform.":[`此平台不支持登录启动项。`,`عناصر بدء تسجيل الدخول غير مدعومة على هذا النظام.`],"Install Node or Bun to start the web app at login.":[`安装 Node 或 Bun 后,网页应用才能在登录时启动。`,`ثبّت Node أو Bun لبدء تطبيق الويب عند تسجيل الدخول.`],"Use these commands to apply the change now:":[`使用以下命令立即应用更改:`,`استخدم هذه الأوامر لتطبيق التغيير الآن:`],"Saved. The login item changes at the next Pi or OpenCode start.":[`已保存。登录启动项将在下次启动 Pi 或 OpenCode 时更新。`,`تم الحفظ. يتغير عنصر بدء التشغيل عند بدء Pi أو OpenCode التالي.`],"History host":[`历史记录主机`,`مضيف السجل`],Scope:[`范围`,`النطاق`],"Current project":[`当前项目`,`المشروع الحالي`],"All projects":[`所有项目`,`كل المشاريع`],"Project directory":[`项目目录`,`مجلد المشروع`],"Current directory":[`当前目录`,`المجلد الحالي`],"Profile batch size":[`用户画像批量大小`,`حجم دفعة الملف الشخصي`],"Directory maps (old=new, one per line)":[`目录映射(旧=新,每行一条)`,`تعيين المجلدات (قديم=جديد، واحد في كل سطر)`],"Force reimport":[`强制重新导入`,`فرض إعادة الاستيراد`],"Skip memories":[`跳过记忆`,`تجاوز الذكريات`],"Skip profile":[`跳过用户画像`,`تجاوز الملف الشخصي`],"Import model":[`导入模型`,`نموذج الاستيراد`],"Saved external API":[`已保存的外部 API`,`واجهة API الخارجية المحفوظة`],"Preview (dry run)":[`预览(不写入)`,`معاينة (تشغيل تجريبي)`],"Start import":[`开始导入`,`بدء الاستيراد`],"Cancel after current unit":[`完成当前单元后取消`,`الإلغاء بعد الوحدة الحالية`],"Directory maps must be old=new, one per line":[`目录映射须为 旧=新,每行一条`,`يجب أن يكون تعيين المجلدات بصيغة قديم=جديد، واحد في كل سطر`],running:[`运行中`,`جارٍ التشغيل`],cancelling:[`正在取消`,`جارٍ الإلغاء`],cancelled:[`已取消`,`أُلغي`],done:[`已完成`,`اكتمل`],failed:[`失败`,`فشل`],units:[`单元`,`وحدات`],"List sessions":[`列出会话`,`عرض الجلسات`],"Refresh list":[`刷新列表`,`تحديث القائمة`],"Advanced options":[`高级选项`,`خيارات متقدمة`],"Hide advanced options":[`隐藏高级选项`,`إخفاء الخيارات المتقدمة`],"default location":[`默认位置`,`الموقع الافتراضي`],"Prompt date from":[`提示日期起`,`تاريخ الطلب من`],"Prompt date to":[`提示日期止`,`تاريخ الطلب إلى`],"Prompt dates are inclusive, use your time zone, and filter the turns inside each session, not the list. Empty dates include every turn.":[`提示日期包含首尾两天,按你所在时区计算,只筛选每个会话中的对话轮次,不筛选列表。留空则包含所有轮次。`,`تواريخ الطلب شاملة لليومين، وتُحسب بمنطقتك الزمنية، وتُصفّي الأدوار داخل كل جلسة لا القائمة. تركها فارغة يشمل كل الأدوار.`],"Sessions with directories that no longer exist":[`目录已不存在的会话`,`جلسات لم تعد مجلداتها موجودة`],"Show them and add a directory map":[`显示它们并添加目录映射`,`اعرضها وأضف تعيين مجلد`],Selected:[`已选择`,`المحدد`],"Select all matching":[`选择所有匹配项`,`تحديد كل المطابق`],"Clear selection":[`清除选择`,`مسح التحديد`],Select:[`选择`,`تحديد`],Created:[`创建时间`,`تاريخ الإنشاء`],"Resolved by":[`解析方式`,`طريقة التحديد`],recorded:[`记录的目录`,`المجلد المسجّل`],mapped:[`目录映射`,`تعيين مجلد`],"project root":[`项目根目录`,`جذر المشروع`],missing:[`缺失`,`مفقود`],"No sessions match.":[`没有匹配的会话。`,`لا توجد جلسات مطابقة.`],Previous:[`上一页`,`السابق`],Next:[`下一页`,`التالي`],None:[`无`,`لا شيء`],"Configured, not tested.":[`已配置,未测试。`,`مُعدّ، لم يُختبر.`],"An import with an OpenCode signed-in model runs from the terminal or with /import in OpenCode.":[`使用 OpenCode 已登录模型的导入需在终端运行,或在 OpenCode 中使用 /import。`,`يتم الاستيراد بنموذج OpenCode المسجَّل الدخول من الطرفية أو بالأمر /import داخل OpenCode.`],"The chosen OpenCode model is not connected here. An import with an OpenCode signed-in model runs from the terminal or with /import in OpenCode. Choose the external API for a web import.":[`所选 OpenCode 模型在此处未连接。使用 OpenCode 已登录模型的导入需在终端运行,或在 OpenCode 中使用 /import。网页导入请选择外部 API。`,`نموذج OpenCode المختار غير متصل هنا. يتم الاستيراد بنموذج OpenCode المسجَّل الدخول من الطرفية أو بالأمر /import داخل OpenCode. اختر واجهة API الخارجية للاستيراد من الصفحة.`],"Test models in Health":[`在健康检查中测试模型`,`اختبر النماذج في قسم السلامة`],Import:[`导入`,`استيراد`],sessions:[`个会话`,`جلسات`],"1 session":[`1 个会话`,`جلسة واحدة`],"List sessions first.":[`请先列出会话。`,`اعرض الجلسات أولاً.`],"Options changed. Refresh the session list first.":[`选项已更改。请先刷新会话列表。`,`تغيّرت الخيارات. حدّث قائمة الجلسات أولاً.`],"Select at least one session.":[`请至少选择一个会话。`,`حدّد جلسة واحدة على الأقل.`],"Select at most 1000 sessions one by one, or use Select all matching.":[`逐个选择最多 1000 个会话,或使用“选择所有匹配项”。`,`حدّد 1000 جلسة كحد أقصى واحدة تلو الأخرى، أو استخدم «تحديد كل المطابق».`],"Model readiness is unknown. Reload the page.":[`无法确定模型是否就绪。请重新加载页面。`,`حالة جاهزية النموذج غير معروفة. أعد تحميل الصفحة.`],"No import model is ready. Connect a model in OpenCode or complete the external API settings.":[`没有可用的导入模型。请在 OpenCode 中连接模型,或补全外部 API 设置。`,`لا يوجد نموذج استيراد جاهز. اربط نموذجاً في OpenCode أو أكمل إعدادات واجهة API الخارجية.`],"The external API is not ready":[`外部 API 未就绪`,`واجهة API الخارجية غير جاهزة`],"The external API has no memoryModel in the global config":[`全局配置中缺少外部 API 的 memoryModel`,`لا يحتوي الإعداد العام على memoryModel لواجهة API الخارجية`],"The external API has no memoryApiUrl in the global config":[`全局配置中缺少外部 API 的 memoryApiUrl`,`لا يحتوي الإعداد العام على memoryApiUrl لواجهة API الخارجية`],"The external API key is missing in the OpenCode process; check memoryApiKey and its env:// or file:// source":[`OpenCode 进程中缺少外部 API 密钥;请检查 memoryApiKey 及其 env:// 或 file:// 来源`,`مفتاح واجهة API الخارجية غير موجود في عملية OpenCode؛ تحقّق من memoryApiKey ومصدره env:// أو file://`],"The memoryProvider in the global config is not supported for imports":[`全局配置中的 memoryProvider 不支持导入`,`مزوّد memoryProvider في الإعداد العام غير مدعوم للاستيراد`],"Pi sessions folder or one .jsonl session file":[`Pi 会话文件夹或单个 .jsonl 会话文件`,`مجلد جلسات Pi أو ملف جلسة ‎.jsonl واحد`],"OpenCode database file":[`OpenCode 数据库文件`,`ملف قاعدة بيانات OpenCode`],"Absolute path, for example on a mounted volume":[`绝对路径,例如已挂载卷上的路径`,`مسار مطلق، مثلاً على وحدة تخزين مركّبة`],"Use this source":[`使用此来源`,`استخدم هذا المصدر`],Browse:[`浏览`,`استعراض`],"Use the default location":[`使用默认位置`,`استخدم الموقع الافتراضي`],"Chosen source":[`已选来源`,`المصدر المختار`],Choose:[`选择`,`اختيار`],"Only the first 500 entries are shown.":[`仅显示前 500 项。`,`تُعرض أول 500 عنصر فقط.`],"Reload the page before saving again.":[`再次保存前请重新加载页面。`,`أعد تحميل الصفحة قبل الحفظ مرة أخرى.`],"The current settings could not be reloaded. Reload the page.":[`无法重新加载当前设置。请重新加载页面。`,`تعذّر إعادة تحميل الإعدادات الحالية. أعد تحميل الصفحة.`],Log:[`日志`,`السجل`],"Capture attempts only":[`仅显示捕获尝试`,`محاولات الالتقاط فقط`],Refresh:[`刷新`,`تحديث`],"Copy log path":[`复制日志路径`,`نسخ مسار السجل`],"Log lines":[`日志行`,`أسطر السجل`],"No log has been written yet.":[`尚未写入日志。`,`لم يُكتب سجل بعد.`],"Loading log…":[`正在加载日志…`,`جارٍ تحميل السجل…`],"External API":[`外部 API`,`واجهة API الخارجية`],"An OpenAI- or Anthropic-compatible endpoint that either host can use for capture and backfill.":[`兼容 OpenAI 或 Anthropic 的端点,两个宿主都可用于捕获和回填。`,`نقطة نهاية متوافقة مع OpenAI أو Anthropic يمكن لأي مضيف استخدامها للالتقاط والاستيراد.`],Provider:[`提供商`,`المزوّد`],"API URL":[`API 地址`,`عنوان API`],"API key":[`API 密钥`,`مفتاح API`],"Save endpoint":[`保存端点`,`حفظ نقطة النهاية`],"Nothing to save.":[`没有需要保存的内容。`,`لا يوجد ما يُحفظ.`],"Key source":[`密钥来源`,`مصدر المفتاح`],"environment variable":[`环境变量`,`متغير البيئة`],"key file":[`密钥文件`,`ملف المفتاح`],"set in the config file":[`在配置文件中设置`,`مضبوط في ملف الإعدادات`],"resolves in the web app":[`可在网页应用中解析`,`يُقرأ في تطبيق الويب`],"does not resolve in the web app":[`无法在网页应用中解析`,`لا يُقرأ في تطبيق الويب`],"A login web app does not see variables set only in a shell profile; a key file works everywhere.":[`登录时启动的网页应用看不到仅在 shell 配置文件中设置的变量;密钥文件在任何地方都可用。`,`تطبيق الويب الذي يبدأ عند تسجيل الدخول لا يرى المتغيرات المضبوطة في ملف الصدفة فقط؛ ملف المفتاح يعمل في كل مكان.`],"The key does not resolve in this web app. Save it to a key file instead.":[`此网页应用无法解析该密钥。请改为保存到密钥文件。`,`لا يُقرأ المفتاح في تطبيق الويب هذا. احفظه في ملف مفتاح بدلاً من ذلك.`],"Environment variable":[`环境变量`,`متغير البيئة`],"Key file":[`密钥文件`,`ملف المفتاح`],"Save key to a private file":[`将密钥保存到私有文件`,`حفظ المفتاح في ملف خاص`],"Variable name":[`变量名`,`اسم المتغير`],"Key file path":[`密钥文件路径`,`مسار ملف المفتاح`],"Key file name":[`密钥文件名`,`اسم ملف المفتاح`],"The key is written to ~/.config/omms/secrets/ readable only by you. It is never shown again.":[`密钥写入 ~/.config/omms/secrets/,仅你可读,之后不再显示。`,`يُكتب المفتاح في ~/.config/omms/secrets/ ولا يقرؤه غيرك، ولن يُعرض مرة أخرى.`],"Save key source":[`保存密钥来源`,`حفظ مصدر المفتاح`],"Key source saved.":[`密钥来源已保存。`,`تم حفظ مصدر المفتاح.`],"A key file with this name exists. Replace it?":[`已存在同名密钥文件。要替换吗?`,`يوجد ملف مفتاح بهذا الاسم. هل تريد استبداله؟`],"Enter a variable name such as ZAI_API_KEY":[`请输入变量名,例如 ZAI_API_KEY`,`أدخل اسم متغير مثل ZAI_API_KEY`],"Enter the path of a key file":[`请输入密钥文件路径`,`أدخل مسار ملف المفتاح`],"Name the key file with letters, digits, dashes, or underscores":[`密钥文件名只能包含字母、数字、短横线或下划线`,`سمِّ ملف المفتاح بحروف أو أرقام أو شرطات أو شرطات سفلية`],"Paste the key":[`请粘贴密钥`,`الصق المفتاح`],Test:[`测试`,`اختبار`],"Test call succeeded":[`测试调用成功`,`نجح استدعاء الاختبار`],"Test call failed":[`测试调用失败`,`فشل استدعاء الاختبار`],"External API needs":[`外部 API 缺少`,`تحتاج واجهة API الخارجية إلى`],"Automatic import makes model calls. A model change applies at the next run. Turning it off stops a running import after the current exchange.":[`自动导入会调用模型。模型更改在下次运行时生效。关闭后,正在进行的导入会在当前对话完成后停止。`,`يستدعي الاستيراد التلقائي النماذج. يسري تغيير النموذج في التشغيل التالي. إيقافه يوقف الاستيراد الجاري بعد المحادثة الحالية.`],"Saved. Changes apply at the next run.":[`已保存。更改在下次运行时生效。`,`تم الحفظ. تسري التغييرات في التشغيل التالي.`],paused:[`已暂停`,`متوقف مؤقتاً`],"started from auto":[`自动启动`,`بدأ تلقائياً`],"started from web":[`从网页启动`,`بدأ من الويب`],"started from cli":[`从终端启动`,`بدأ من الطرفية`],"started from slash":[`从斜杠命令启动`,`بدأ من أمر الشرطة المائلة`],"Minutes left":[`剩余分钟`,`الدقائق المتبقية`],unknown:[`未知`,`غير معروف`],about:[`约`,`حوالي`],"Run now":[`立即运行`,`تشغيل الآن`],Pause:[`暂停`,`إيقاف مؤقت`],Resume:[`继续`,`استئناف`],"Pausing after the current exchange.":[`将在当前对话完成后暂停。`,`سيتوقف مؤقتاً بعد المحادثة الحالية.`],"Backfill started.":[`回填已开始。`,`بدأ الاستيراد.`],"Directory maps":[`目录映射`,`خرائط المجلدات`],"Map a directory that was moved or deleted to the project it belongs to. A change applies to the next import or backfill run.":[`将已移动或删除的目录映射到其所属项目。更改在下次导入或回填时生效。`,`اربط مجلداً نُقل أو حُذف بالمشروع الذي ينتمي إليه. يسري التغيير في الاستيراد التالي.`],"Saved maps":[`已保存的映射`,`الخرائط المحفوظة`],Keep:[`保留`,`إبقاء`],Remove:[`移除`,`إزالة`],"Unresolved directories":[`无法解析的目录`,`مجلدات غير محلولة`],"No unresolved directories in the latest run.":[`最近一次运行没有无法解析的目录。`,`لا توجد مجلدات غير محلولة في آخر تشغيل.`],"No suggestion found.":[`未找到建议。`,`لم يُعثر على اقتراح.`],"Target directory":[`目标目录`,`المجلد الهدف`],"Use this map":[`使用此映射`,`استخدام هذه الخريطة`],"Save maps":[`保存映射`,`حفظ الخرائط`],"Saved. Maps apply to the next import or backfill run.":[`已保存。映射在下次导入或回填时生效。`,`تم الحفظ. تسري الخرائط في الاستيراد التالي.`],"Claude Code folder":[`Claude Code 文件夹`,`مجلد Claude Code`],"Set this when Claude Code does not use ~/.claude, for example when you start it with CLAUDE_CONFIG_DIR. Leave it empty to use the default.":[`当 Claude Code 不使用 ~/.claude 时(例如用 CLAUDE_CONFIG_DIR 启动它),请设置此项。留空则使用默认文件夹。`,`اضبط هذا عندما لا يستخدم Claude Code المجلد ‎~/.claude، مثلاً عند تشغيله مع CLAUDE_CONFIG_DIR. اتركه فارغاً لاستخدام المجلد الافتراضي.`],"Save folder":[`保存文件夹`,`حفظ المجلد`],"Transcripts folder in use":[`正在使用的会话记录文件夹`,`مجلد سجلات الجلسات المستخدم`],From:[`来源`,`المصدر`],"this setting":[`此设置`,`هذا الإعداد`],"the CLAUDE_CONFIG_DIR variable of the web app":[`网页应用的 CLAUDE_CONFIG_DIR 变量`,`متغير CLAUDE_CONFIG_DIR لتطبيق الويب`],"the default folder":[`默认文件夹`,`المجلد الافتراضي`],"This folder does not exist. Claude Code capture and import will not work:":[`此文件夹不存在。Claude Code 的捕获和导入将无法工作:`,`هذا المجلد غير موجود. لن يعمل الالتقاط والاستيراد في Claude Code:`],"Enter a full path, or a path that starts with ~/.":[`请输入完整路径,或以 ~/ 开头的路径。`,`أدخل مساراً كاملاً، أو مساراً يبدأ بـ ‎~/.`],"Saved. Capture and import use this folder now.":[`已保存。捕获和导入现在使用此文件夹。`,`تم الحفظ. يستخدم الالتقاط والاستيراد هذا المجلد الآن.`],"Running version":[`运行版本`,`الإصدار الجاري`],"Global command":[`全局命令`,`الأمر العام`],"not installed globally":[`未全局安装`,`غير مثبت عمومياً`],"The global command's version differs from the running OMMS. Upgrade it:":[`全局命令的版本与正在运行的 OMMS 不同。请升级:`,`يختلف إصدار الأمر العام عن OMMS الجاري. حدّثه:`],"A global install is optional but recommended: the login item and the terminal commands then run without npx.":[`全局安装是可选的,但建议安装:这样登录项和终端命令无需 npx 即可运行。`,`التثبيت العام اختياري لكنه موصى به: يعمل عنصر تسجيل الدخول وأوامر الطرفية حينها دون npx.`],"Keys and access":[`密钥与访问`,`المفاتيح والوصول`],"not needed":[`不需要`,`غير مطلوب`],"External API key":[`外部 API 密钥`,`مفتاح واجهة API الخارجية`],"Embedding server key":[`嵌入服务器密钥`,`مفتاح خادم التضمين`],"Capture and profile learning through the external API. Claude Code always uses it.":[`通过外部 API 进行捕获和用户画像学习。Claude Code 始终使用它。`,`الالتقاط وتعلّم الملف الشخصي عبر واجهة API الخارجية. يستخدمه Claude Code دائماً.`],"Sent to an embedding server on another machine.":[`发送给另一台机器上的嵌入服务器。`,`يُرسَل إلى خادم تضمين على جهاز آخر.`],"Let scripts and other computers call the web app's API.":[`允许脚本和其他电脑调用网页应用的 API。`,`تتيح للبرامج النصية والحواسيب الأخرى استدعاء واجهة API لتطبيق الويب.`],"Asks for a user name and password before the page opens.":[`打开页面前要求输入用户名和密码。`,`يطلب اسم مستخدم وكلمة مرور قبل فتح الصفحة.`],"External API card":[`外部 API 卡片`,`بطاقة واجهة API الخارجية`],"Embedding card":[`嵌入卡片`,`بطاقة التضمين`],"Table below":[`下方表格`,`الجدول أدناه`],"Form below":[`下方表单`,`النموذج أدناه`],"API tokens":[`API 令牌`,`رموز API`],"Browser password":[`浏览器密码`,`كلمة مرور المتصفح`],"The config file still sets webServerApiToken. OMMS imported it once as the token “from config file” and no longer reads the key. Use the token table instead.":[`配置文件仍设置了 webServerApiToken。OMMS 已将其导入一次,作为令牌“from config file”,之后不再读取该键。请改用令牌表。`,`لا يزال ملف الإعدادات يضبط webServerApiToken. استورده OMMS مرة واحدة كرمز باسم “from config file” ولم يعد يقرأ هذا المفتاح. استخدم جدول الرموز بدلاً منه.`],"Open this page on the computer that runs OMMS to manage tokens and the password.":[`请在运行 OMMS 的电脑上打开此页面,以管理令牌和密码。`,`افتح هذه الصفحة على الحاسوب الذي يشغّل OMMS لإدارة الرموز وكلمة المرور.`],"Revoke this token? Scripts that use it stop working.":[`撤销此令牌?使用它的脚本将停止工作。`,`إلغاء هذا الرمز؟ ستتوقف البرامج النصية التي تستخدمه عن العمل.`],"No browser password is set.":[`未设置浏览器密码。`,`لم تُضبط كلمة مرور للمتصفح.`],"A browser password is set for user":[`已为以下用户设置浏览器密码:`,`ضُبطت كلمة مرور المتصفح للمستخدم`],"A browser password is set for your computer user name.":[`已为你的电脑用户名设置浏览器密码。`,`ضُبطت كلمة مرور المتصفح لاسم مستخدم حاسوبك.`],"User name":[`用户名`,`اسم المستخدم`],Password:[`密码`,`كلمة المرور`],"Save password":[`保存密码`,`حفظ كلمة المرور`],"Clear password":[`清除密码`,`مسح كلمة المرور`],"Saved. Restart the web app to use the new browser password.":[`已保存。重启网页应用以使用新的浏览器密码。`,`تم الحفظ. أعد تشغيل تطبيق الويب لاستخدام كلمة مرور المتصفح الجديدة.`],Name:[`名称`,`الاسم`],Expires:[`过期时间`,`تاريخ الانتهاء`],"Last used":[`上次使用`,`آخر استخدام`],Never:[`永不`,`أبداً`],Revoke:[`撤销`,`إلغاء`],Copy:[`复制`,`نسخ`],"Copy this token now. It will not be shown again.":[`请立即复制此令牌。它不会再次显示。`,`انسخ هذا الرمز الآن. لن يُعرض مرة أخرى.`],"Token name":[`令牌名称`,`اسم الرمز`],"Expires after":[`有效期`,`ينتهي بعد`],"Generate token":[`生成令牌`,`إنشاء رمز`],All:[`全部`,`الكل`],Kind:[`类型`,`النوع`],"Built-in model":[`内置模型`,`النموذج المدمج`],"OpenAI-compatible server":[`OpenAI 兼容服务器`,`خادم متوافق مع OpenAI`],"Server URL":[`服务器 URL`,`عنوان URL للخادم`],"Vector size":[`向量维度`,`حجم المتجه`],"Stored memories":[`已存储的记忆`,`الذكريات المخزنة`],"Re-embedding":[`正在重新嵌入`,`جارٍ إعادة التضمين`],"Re-embed finished.":[`重新嵌入已完成。`,`اكتملت إعادة التضمين.`],"Re-embed failed":[`重新嵌入失败`,`فشلت إعادة التضمين`],Retry:[`重试`,`إعادة المحاولة`],Lock:[`锁定`,`قفل`],"Unlock to change":[`解锁以更改`,`افتح القفل للتغيير`],"The model that turns memory text into search vectors. A change re-embeds every memory.":[`将记忆文本转换为搜索向量的模型。更改后会重新嵌入所有记忆。`,`النموذج الذي يحوّل نص الذكريات إلى متجهات بحث. يؤدي تغييره إلى إعادة تضمين كل الذكريات.`],Preset:[`预设`,`إعداد مسبق`],Custom:[`自定义`,`مخصص`],"No key":[`无密钥`,`بلا مفتاح`],"Keep the saved key":[`保留已保存的密钥`,`الاحتفاظ بالمفتاح المحفوظ`],Apply:[`应用`,`تطبيق`],Cancel:[`取消`,`إلغاء الأمر`],"Test passed. Vector size":[`测试通过。向量维度`,`نجح الاختبار. حجم المتجه`],"Test failed":[`测试失败`,`فشل الاختبار`],"Every stored memory will be re-embedded":[`所有已存储的记忆都将重新嵌入`,`ستُعاد عملية تضمين كل الذكريات المخزنة`],"The hosted server is called once for each memory, which may cost money.":[`托管服务器会为每条记忆调用一次,可能产生费用。`,`يُستدعى الخادم المستضاف مرة لكل ذكرى، وقد يكلّف ذلك مالاً.`],"Search results are poor until the re-embed ends.":[`在重新嵌入结束前,搜索结果质量较差。`,`تكون نتائج البحث ضعيفة حتى تنتهي إعادة التضمين.`],"Restart open OpenCode and Pi sessions after the change.":[`更改后请重启已打开的 OpenCode 和 Pi 会话。`,`أعد تشغيل جلسات OpenCode وPi المفتوحة بعد التغيير.`],"Profile learning":[`用户画像学习`,`تعلّم الملف الشخصي`],"Catch up analyses every waiting prompt with the saved external API, 50 prompts for each model call.":[`补齐会使用已保存的外部 API 分析所有等待中的提示词,每次模型调用处理 50 条。`,`يحلّل اللحاق كل الطلبات المنتظرة عبر واجهة API الخارجية المحفوظة، 50 طلباً لكل استدعاء للنموذج.`],"Open this page on the computer that runs OMMS to start a catch-up run.":[`请在运行 OMMS 的电脑上打开此页面以开始补齐。`,`افتح هذه الصفحة على الحاسوب الذي يشغّل OMMS لبدء اللحاق.`],"Prompts waiting for profile learning":[`等待用户画像学习的提示词`,`الطلبات المنتظرة لتعلّم الملف الشخصي`],"Model calls":[`模型调用次数`,`استدعاءات النموذج`],"Batches done":[`已完成批次`,`الدفعات المكتملة`],"Prompts waiting":[`等待中的提示词`,`الطلبات المنتظرة`],Paused:[`已暂停`,`متوقف مؤقتاً`],Finished:[`已完成`,`اكتمل`],Stopped:[`已停止`,`توقّف`],"Catch up profile":[`补齐用户画像`,`اللحاق بالملف الشخصي`],"Start profile learning for the waiting prompts? Model calls":[`为等待中的提示词开始用户画像学习?模型调用次数`,`بدء تعلّم الملف الشخصي للطلبات المنتظرة؟ عدد استدعاءات النموذج`],"never used before":[`从未使用`,`لم يُستخدم من قبل`],"A newer catch-up run took over.":[`较新的补齐任务已接管。`,`تولّت عملية لحاق أحدث المهمة.`],"Browser password cleared. Restart the web app to turn it off.":[`浏览器密码已清除。重启网页应用以关闭它。`,`تم مسح كلمة مرور المتصفح. أعد تشغيل تطبيق الويب لإيقافها.`],Actions:[`操作`,`الإجراءات`],"All exchanges are done. Learning the profile from the imported prompts":[`所有对话已完成。正在从导入的提示中学习画像`,`اكتملت كل المحادثات. يجري تعلّم الملف الشخصي من المطالبات المستوردة`],batches:[`批`,`دفعات`],"Change it in":[`修改位置`,`مكان التغيير`],"Check them, then press Save maps.":[`请检查后点击保存映射。`,`راجعها ثم اضغط حفظ الخرائط.`],Credential:[`凭据`,`بيانات الاعتماد`],Email:[`邮箱`,`البريد الإلكتروني`],Filled:[`已填写`,`تم الملء`],"Finds the project each missing directory belongs to, mostly the main repository of a deleted worktree, and fills it in for you to check. Nothing is saved until you press Save maps.":[`为每个缺失的目录找到所属项目(多为已删除工作树的主仓库),并填入供你检查。点击保存映射之前不会保存任何内容。`,`يعثر على المشروع الذي ينتمي إليه كل مجلد مفقود، وغالباً المستودع الرئيسي لشجرة عمل محذوفة، ويملؤه لتراجعه. لا يُحفظ شيء حتى تضغط حفظ الخرائط.`],Hosts:[`主机`,`المضيفات`],"Import status":[`导入状态`,`حالة الاستيراد`],"in use":[`使用中`,`قيد الاستخدام`],"Last run":[`上次运行`,`آخر تشغيل`],"Last update":[`最后更新`,`آخر تحديث`],"Learning profile":[`正在学习画像`,`يجري تعلّم الملف الشخصي`],"Merge into":[`合并到`,`دمج في`],"Merge this profile into the other one? The source profile is turned off, not deleted.":[`将此画像合并到另一个画像?源画像会被停用,不会被删除。`,`دمج هذا الملف الشخصي في الآخر؟ يُوقَف الملف المصدر ولا يُحذف.`],"Merged.":[`已合并。`,`تم الدمج.`],"model not recorded":[`未记录模型`,`لم يُسجَّل نموذج`],model:[`个模型`,`نموذج`],models:[`个模型`,`نماذج`],"No directory recorded":[`未记录目录`,`لم يُسجَّل مجلد`],"No suggestion":[`无建议`,`لا اقتراح`],"Not started":[`未开始`,`لم يبدأ`],"OMMS keeps one profile for each git email. A folder whose repository has its own email starts a second profile. Choose the profile that is yours, or merge the extra one into it.":[`OMMS 为每个 git 邮箱保留一个画像。若某文件夹的仓库设置了自己的邮箱,就会产生第二个画像。请选择属于你的画像,或把多余的画像合并进去。`,`يحتفظ OMMS بملف شخصي لكل بريد git. المجلد الذي يملك مستودعه بريداً خاصاً يبدأ ملفاً شخصياً ثانياً. اختر ملفك الشخصي، أو ادمج الملف الزائد فيه.`],"Outcomes by host":[`各主机结果`,`النتائج حسب المضيف`],"Partly imported":[`部分已导入`,`مستورد جزئياً`],Patterns:[`模式`,`الأنماط`],pending:[`待处理`,`معلّق`],Preferences:[`偏好`,`التفضيلات`],Profiles:[`画像`,`الملفات الشخصية`],"Prompts analysed":[`已分析提示`,`المطالبات المحلَّلة`],Running:[`运行中`,`قيد التشغيل`],"Saved maps apply to every host.":[`已保存的映射适用于所有主机。`,`تنطبق الخرائط المحفوظة على كل المضيفات.`],"Saved: a memory was stored. Skipped: the model or a rule found nothing worth keeping, or the turn was private or trivial. Failed: the attempt hit an error. Total: the three added up. Each percentage is a share of its row's total.":[`已保存:存储了一条记忆。已跳过:模型或规则认为没有值得保留的内容,或该轮为私密或琐碎内容。失败:尝试出错。总计:三者之和。每个百分比是该行总计中的占比。`,`محفوظ: خُزّنت ذاكرة. متجاوز: لم يجد النموذج أو قاعدة ما يستحق الحفظ، أو كانت الجولة خاصة أو تافهة. فشل: واجهت المحاولة خطأ. الإجمالي: مجموع الثلاثة. كل نسبة هي حصة من إجمالي صفها.`],"Saved. OMMS now uses this profile in every folder.":[`已保存。OMMS 现在在所有文件夹中使用此画像。`,`تم الحفظ. يستخدم OMMS هذا الملف الشخصي الآن في كل المجلدات.`],"Smart resolve directories":[`智能解析目录`,`حلّ المجلدات تلقائياً`],"No model was recorded for these attempts. This happens with records written by older OMMS versions, and when an attempt stops before a model is chosen.":[`这些尝试没有记录模型。旧版 OMMS 写入的记录,以及在选定模型之前就停止的尝试,会出现这种情况。`,`لم يُسجَّل نموذج لهذه المحاولات. يحدث ذلك في السجلات التي كتبتها إصدارات أقدم من OMMS، وعندما تتوقف المحاولة قبل اختيار نموذج.`],"These sessions cannot be mapped.":[`这些会话无法映射。`,`لا يمكن ربط هذه الجلسات.`],unresolved:[`未解析`,`غير محلول`],"Use this profile":[`使用此画像`,`استخدام هذا الملف الشخصي`],"Use this profile for every folder?":[`在所有文件夹中使用此画像?`,`استخدام هذا الملف الشخصي في كل المجلدات؟`],"Used for":[`用途`,`الاستخدام`],Workflows:[`工作流`,`سير العمل`]};function km(e,t){return t===`en`?e:Om[e]?.[t===`zh`?0:1]??e}function Am(){let{language:e}=mr();return t=>km(t,e)}function jm(e,t){if(e===`env`){let n=(t.name??``).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(n))throw Error(`Enter a variable name such as ZAI_API_KEY`);return{source:e,name:n}}if(e===`file`){let n=(t.path??``).trim();if(!n)throw Error(`Enter the path of a key file`);return{source:e,path:n}}let n=(t.name??``).trim()||`memory-api`;if(!/^[A-Za-z0-9_-]{1,64}$/.test(n))throw Error(`Name the key file with letters, digits, dashes, or underscores`);if(!(t.value??``).trim())throw Error(`Paste the key`);return{source:e,name:n,value:t.value??``,replace:t.replace===!0}}function Mm(e){let t=[],n=e.memoryProvider===`orcarouter`;return!n&&!e.memoryModel&&t.push(`memoryModel`),!n&&!e.memoryApiUrl&&t.push(`memoryApiUrl`),e.keySet||t.push(`memoryApiKey`),t}function Nm(e,t){if(t===`inherit`||t===`external`)return{[`${e}Model`]:t};let n=t.indexOf(`/`);if(n<1||n===t.length-1)throw Error(`Enter a model as provider/model.`);return{[`${e}Provider`]:t.slice(0,n),[`${e}Model`]:t.slice(n+1)}}function Pm(e){return e.global===null?{kind:`missing`,command:`npm i -g om-memory-system`}:e.global===e.running?{kind:`same`,command:null}:{kind:`different`,command:`npm i -g om-memory-system@latest`}}function Fm(e,t,n){let r=new Map;for(let n of e)t.has(n.from)||r.set(n.from,n);for(let e of n){let t=e.target.trim();e.accepted&&t&&r.set(e.directory,{from:e.directory,to:t})}return[...r.values()]}var Im={opencode:`OpenCode`,pi:`Pi`,"claude-code":`Claude Code`};function Lm(e){return Im[e]}function Rm(e){return Object.hasOwn(Im,e)?Im[e]:e}function zm({status:e}){let t=Am();return(0,B.jsxs)(`div`,{className:`space-y-1 rounded-lg border border-border p-3`,children:[(0,B.jsx)(`h3`,{className:`font-medium`,children:Lm(`claude-code`)}),e?.ready===!0&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:t(`Claude Code capture uses the external API.`)}),e?.ready===!1&&(0,B.jsxs)(`div`,{role:`alert`,className:`space-y-1 text-xs`,children:[(0,B.jsx)(`p`,{className:`text-amber-600`,children:t(`Claude Code capture is off. Complete the external API settings.`)}),(e.issues??[]).length>0&&(0,B.jsxs)(`p`,{children:[t(`Missing settings`),`: `,(e.issues??[]).map(e=>t(e)).join(`; `)]})]})]})}function Bm(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)({}),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let e=!0,t=Sm();$(`/api/settings`).then(r=>{e&&t.isCurrent()&&n(r)}).catch(t=>{e&&o(t.message)});for(let t of[`opencode`,`pi`])$(`/api/settings/models?host=${t}`).then(n=>{e&&i(e=>({...e,[t]:n}))}).catch(()=>{e&&i(e=>({...e,[t]:{available:!1}}))});let r=wm(t=>{e&&n(t)});return()=>{e=!1,r()}},[]);async function l(n,r){if(!t)return;let i;try{i=Nm(n,r)}catch(t){o(e(t.message));return}c(!0);let a,s;try{a=await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:i,revision:t.revision})})}catch(e){s=e}let l=await Cm()!==null;if(c(!1),a){let t=e(a.migratedLegacy?`Saved. OMMS now reads ~/.config/omms/omms.jsonc. The legacy config was kept.`:`Saved. New capture and profile work uses these settings.`);o(l?t:`${t} ${e(`Reload the page before saving again.`)}`)}else o(Tm(s?.message??``,e(l?`Current settings were reloaded; check the values and save again.`:`The current settings could not be reloaded. Reload the page.`)))}let u=Mm({memoryProvider:t?.settings.memoryProvider?.globalValue,memoryModel:t?.settings.memoryModel?.globalValue,memoryApiUrl:t?.settings.memoryApiUrl?.globalValue,keySet:!!t?.secrets.memoryApiKey?.set});return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Models`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Models`)}),(0,B.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[e(`External API fallback`),`: `,t?.fallback.model??e(`none`),` (`,e(t?.fallback.configured?`ready`:`not ready`),`).`]}),[`opencode`,`pi`].map(e=>(0,B.jsx)(Vm,{host:e,model:t?.settings[`${e}Model`],provider:t?.settings[`${e}Provider`],effective:e===`pi`?t?.effective.pi.kind:t?.effective.opencode.mode??`unready`,list:r[e],externalMissing:u,busy:s||!t,onSave:t=>l(e,t)},e)),(0,B.jsx)(zm,{status:t?.effective[`claude-code`]}),a&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:a})]})}function Vm({host:e,model:t,provider:n,effective:r,list:i,externalMissing:a,busy:o,onSave:s}){let c=Am(),l=t?.globalValue===`inherit`||!t?.globalValue?`inherit`:t.globalValue===`external`?`external`:`${n?.globalValue??``}/${t.globalValue}`,[u,d]=(0,_.useState)(),[f,p]=(0,_.useState)(),[m,h]=(0,_.useState)(),g=u??(l===`inherit`||l===`external`?l:`manual`),v=i?.models??[],y=l===`inherit`||l===`external`?``:l,b=m||y||(v[0]?`${v[0].provider}/${v[0].model}`:`typed`),x=!v.some(e=>`${e.provider}/${e.model}`===b),S=f??y;return(0,B.jsxs)(`div`,{className:`space-y-2 rounded-lg border border-border p-3`,children:[(0,B.jsx)(`h3`,{className:`font-medium`,children:Lm(e)}),(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[c(`Effective model`),`:`,` `,t?.value===`external`&&r===`manual`?c(`external API`):t?.value===`inherit`||r===`session`?c(`session`):r===`manual`?c(`external API`):r===`unready`?c(`unavailable`):`${n?.value??``}/${t?.value??``}`]}),(t?.source===`project`||n?.source===`project`)&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:c(`Project override is active. Changes to the global file may not take effect here.`)}),(0,B.jsx)(`label`,{className:`block text-sm`,htmlFor:`${e}-model`,children:c(`Model choice`)}),(0,B.jsxs)(fn,{id:`${e}-model`,className:`w-full rounded-lg border border-border bg-background p-2 text-sm`,value:g,onChange:e=>d(e.target.value),children:[(0,B.jsx)(`option`,{value:`inherit`,children:c(`Session model`)}),(0,B.jsx)(`option`,{value:`manual`,children:c(`Manual model`)}),(0,B.jsx)(`option`,{value:`external`,disabled:a.length>0,children:c(`External API`)})]}),a.length>0&&(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[c(`External API needs`),`: `,a.join(`, `)]}),g===`manual`&&i?.available&&v.length>0&&(0,B.jsxs)(fn,{className:`w-full rounded-lg border border-border bg-background p-2 text-sm`,"aria-label":`${Lm(e)} ${c(`Model`)}`,value:x?`typed`:b,onChange:e=>h(e.target.value),children:[v.map(e=>(0,B.jsxs)(`option`,{value:`${e.provider}/${e.model}`,children:[e.name,` (`,e.provider,`/`,e.model,`)`]},`${e.provider}/${e.model}`)),(0,B.jsx)(`option`,{value:`typed`,children:c(`Manual provider/model`)})]}),g===`manual`&&x&&(0,B.jsx)(`input`,{className:`w-full rounded-lg border border-border bg-background p-2 text-sm`,"aria-label":`${e} ${c(`Manual provider/model`)}`,placeholder:`provider/model`,value:S,onChange:e=>{p(e.target.value),h(`typed`)}}),g===`manual`&&i&&!i.available&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:i.reason?c(i.reason):c(`Model list unavailable. Enter provider/model manually.`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded-lg border border-border px-3 py-1.5 text-sm`,disabled:o,onClick:()=>s(g===`manual`?x?S.trim():b:g),children:c(`Save model`)})]})}var Hm=[`openai-chat`,`openai-responses`,`anthropic`,`minimax`,`orcarouter`,`google-gemini`];function Um(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)({}),[a,o]=(0,_.useState)(`file`),[s,c]=(0,_.useState)({name:``,path:``,value:``}),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let e=!0,t=Sm();$(`/api/settings`).then(r=>{e&&t.isCurrent()&&n(r)}).catch(t=>{e&&u(t.message)});let r=wm(t=>{e&&n(t)});return()=>{e=!1,r()}},[]);let p=e=>String(t?.settings[e]?.globalValue??``),m=e=>r[e]??p(e);async function h(){if(!t)return;let n={};for(let e of[`memoryProvider`,`memoryApiUrl`,`memoryModel`]){let t=m(e).trim();t&&t!==p(e)&&(n[e]=t)}if(!Object.keys(n).length){u(e(`Nothing to save.`));return}f(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:n,revision:t.revision})}),i({}),u(e(`Saved. New capture and profile work uses these settings.`))}catch(e){u(e.message)}await Cm(),f(!1)}async function g(n=!1){if(!t)return;let r;try{r=jm(a,{...s,replace:n})}catch(t){u(e(t.message));return}f(!0);try{await $(`/api/settings/external-api/key`,{method:`POST`,body:JSON.stringify({...r,revision:t.revision})}),c(e=>({...e,value:``})),u(e(`Key source saved.`))}catch(t){let r=t.message;if(a===`paste`&&!n&&r.includes(`Confirm to replace`)){f(!1),window.confirm(e(`A key file with this name exists. Replace it?`))&&await g(!0);return}u(r)}await Cm(),f(!1)}async function v(){f(!0);try{let t=await $(`/api/settings/external-api/test`,{method:`POST`,body:`{}`});u(t.ok?`${e(`Test call succeeded`)}: ${t.model??``}`:`${e(`Test call failed`)}: ${t.error??``}`)}catch(e){u(e.message)}f(!1)}let y=t?.externalKey;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`External API`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`External API`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`An OpenAI- or Anthropic-compatible endpoint that either host can use for capture and backfill.`)}),(0,B.jsxs)(`label`,{className:`block text-sm`,children:[e(`Provider`),(0,B.jsx)(fn,{"aria-label":e(`Provider`),className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:m(`memoryProvider`)||`openai-chat`,onChange:e=>i({...r,memoryProvider:e.target.value}),children:Hm.map(e=>(0,B.jsx)(`option`,{value:e,children:e},e))})]}),(0,B.jsxs)(`label`,{className:`block text-sm`,children:[e(`API URL`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,placeholder:`https://api.example.com/v1`,value:m(`memoryApiUrl`),onChange:e=>i({...r,memoryApiUrl:e.target.value})})]}),(0,B.jsxs)(`label`,{className:`block text-sm`,children:[e(`Model`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,placeholder:`glm-5-turbo`,value:m(`memoryModel`),onChange:e=>i({...r,memoryModel:e.target.value})})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d||!t,onClick:()=>void h(),children:e(`Save endpoint`)}),(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3 text-sm`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`API key`)}),(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e(`Key source`),`:`,` `,y?.source===`env`?`${e(`environment variable`)} ${y.reference}`:y?.source===`file`?`${e(`key file`)} ${y.reference}`:y?.source===`literal`?e(`set in the config file`):e(`not set`),y?.source&&` · ${e(y.resolvesInWebApp?`resolves in the web app`:`does not resolve in the web app`)}`]}),y?.source===`env`&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`A login web app does not see variables set only in a shell profile; a key file works everywhere.`)}),y?.source&&!y.resolvesInWebApp&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`The key does not resolve in this web app. Save it to a key file instead.`)}),[[`env`,`Environment variable`],[`file`,`Key file`],[`paste`,`Save key to a private file`]].map(([t,n])=>(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`radio`,name:`omms-key-source`,checked:a===t,onChange:()=>o(t)}),e(n)]},t)),a===`env`&&(0,B.jsx)(`input`,{"aria-label":e(`Variable name`),className:`w-full rounded border border-border bg-background p-2`,placeholder:`ZAI_API_KEY`,value:s.name,onChange:e=>c({...s,name:e.target.value})}),a===`file`&&(0,B.jsx)(`input`,{"aria-label":e(`Key file path`),className:`w-full rounded border border-border bg-background p-2`,placeholder:`~/.config/omms/secrets/zai.key`,value:s.path,onChange:e=>c({...s,path:e.target.value})}),a===`paste`&&(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`input`,{"aria-label":e(`Key file name`),className:`w-full rounded border border-border bg-background p-2`,placeholder:`memory-api`,value:s.name,onChange:e=>c({...s,name:e.target.value})}),(0,B.jsx)(`input`,{"aria-label":e(`API key`),type:`password`,autoComplete:`off`,className:`w-full rounded border border-border bg-background p-2`,value:s.value,onChange:e=>c({...s,value:e.target.value})}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`The key is written to ~/.config/omms/secrets/ readable only by you. It is never shown again.`)})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:d||!t,onClick:()=>void g(),children:e(`Save key source`)})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d,onClick:()=>void v(),children:e(`Test`)}),l&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:l})]})}var Wm=new Set([`localhost`,`127.0.0.1`,`::1`,`[::1]`,`0:0:0:0:0:0:0:1`]);function Gm(e){let t=e.trim().toLowerCase();return Wm.has(t)||/^127(?:\.\d{1,3}){3}$/.test(t)}function Km(e){try{return Gm(new URL(e).hostname)}catch{return!1}}function qm(e,t){return e?`set`:t?`missing`:`not-needed`}function Jm(e){let{access:t,secrets:n}=e,r=t.embeddingApiUrl;return{memoryApiKey:(e=>e===`not-needed`?`never-used`:e)(qm(!!n.memoryApiKey?.set,e.externalUsed||e.claudeCodeInUse)),embeddingApiKey:qm(!!n.embeddingApiKey?.set,!!r&&!Km(r)),apiTokens:qm(t.tokenAvailable,!Gm(t.host)&&!t.authEnabled),webPassword:qm(!!n.webServerAuthPassword?.set,!1)}}function Ym(e){return e?`Browser password cleared. Restart the web app to turn it off.`:`Saved. Restart the web app to use the new browser password.`}var Xm=[{id:`ollama`,label:`Ollama`,url:`http://localhost:11434/v1`},{id:`llamacpp`,label:`llama.cpp`,url:`http://localhost:8080/v1`},{id:`openrouter`,label:`OpenRouter`,url:`https://openrouter.ai/api/v1`},{id:`openai`,label:`OpenAI`,url:`https://api.openai.com/v1`},{id:`custom`,label:`Custom`,url:``}];function Zm(e,t){let n=Xm.find(t=>t.id===e);return n&&n.url?n.url:t}function Qm(e){if(e.kind===`builtin`)return{kind:`builtin`,model:e.model.trim()};let t=e.key===`none`||e.key===`saved`?{source:e.key}:jm(e.key,{...e.keyInput,name:e.keyInput.name||`embedding-api`});return{kind:`server`,url:e.url.trim(),model:e.model.trim(),key:t}}function $m(e){return JSON.stringify([e.kind,e.kind===`server`?e.url.trim():``,e.model.trim(),e.kind===`server`?e.key:`none`,e.kind===`server`?e.keyInput:null])}function eh(e,t){return e!==void 0&&e===$m(t)}function th(e,t){let n=t.kind===`server`&&!Km(t.url);return{count:e.toLocaleString(`en-US`),risks:[...n?[`The hosted server is called once for each memory, which may cost money.`]:[],`Search results are poor until the re-embed ends.`,`Restart open OpenCode and Pi sessions after the change.`]}}var nh=`Xenova/nomic-embed-text-v1`;function rh(e,t=nh){return e===`builtin`?{kind:e,model:t}:{kind:e}}function ih(e,t){return e===`server`&&t?`saved`:`none`}function ah({current:e,keySet:t}){let n=Am();return(0,B.jsxs)(`dl`,{className:`grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-sm`,children:[(0,B.jsx)(`dt`,{children:n(`Kind`)}),(0,B.jsx)(`dd`,{children:n(e.kind===`server`?`OpenAI-compatible server`:`Built-in model`)}),e.url&&(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`dt`,{children:n(`Server URL`)}),(0,B.jsx)(`dd`,{className:`break-all`,children:e.url})]}),(0,B.jsx)(`dt`,{children:n(`Model`)}),(0,B.jsx)(`dd`,{className:`break-all`,children:e.model}),(0,B.jsx)(`dt`,{children:n(`Vector size`)}),(0,B.jsx)(`dd`,{children:e.dimensions}),(0,B.jsx)(`dt`,{children:n(`API key`)}),(0,B.jsx)(`dd`,{children:n(t?`set`:`not set`)}),(0,B.jsx)(`dt`,{children:n(`Stored memories`)}),(0,B.jsx)(`dd`,{children:e.memoryCount.toLocaleString(`en-US`)})]})}function oh({run:e,onRetry:t}){let n=Am();return e.state===`idle`?null:(0,B.jsxs)(`div`,{role:`status`,className:`space-y-1 text-sm`,children:[e.state===`running`&&(0,B.jsxs)(`p`,{children:[n(`Re-embedding`),`: `,e.progress.processed,`/`,e.progress.total]}),e.state===`done`&&(0,B.jsx)(`p`,{children:n(`Re-embed finished.`)}),e.state===`failed`&&(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`p`,{className:`text-red-600`,children:[n(`Re-embed failed`),`: `,e.error??``]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,onClick:t,children:n(`Retry`)})]})]})}function sh(e,t){return{kind:e.kind,url:e.url??``,model:e.model,key:ih(e.kind,t),keyInput:{name:``,path:``,value:``}}}function ch(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(),[d,f]=(0,_.useState)(),[p,m]=(0,_.useState)({state:`idle`,progress:{processed:0,total:0}}),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(!1);async function b(){let e=await $(`/api/settings/embedding`);return n(e),m(e.run),e}(0,_.useEffect)(()=>{let e=!0,t=Sm();b().catch(t=>e&&g(t.message)),$(`/api/settings`).then(n=>e&&t.isCurrent()&&i(n)).catch(()=>{}),$(`/api/web/status`).then(t=>e&&o(!!t.isLocal)).catch(()=>{});let n=wm(t=>e&&i(t));return()=>{e=!1,n()}},[]),(0,_.useEffect)(()=>{if(p.state!==`running`)return;let e=setInterval(()=>{$(`/api/settings/embedding/run`).then(e=>{m(e),e.state!==`running`&&b()}).catch(()=>{})},1e3);return()=>clearInterval(e)},[p.state]);function x(){if(s||!t){c(!1),u(void 0),f(void 0);return}u(sh(t,!!r?.secrets.embeddingApiKey?.set)),c(!0)}let S=e=>u(t=>t&&{...t,...e});async function C(){l&&await Dm(y,async()=>{try{let t=await $(`/api/settings/embedding/test`,{method:`POST`,body:JSON.stringify(Qm(l))});t.ok&&t.dimensions?(f({key:$m(l),dimensions:t.dimensions}),g(`${e(`Test passed. Vector size`)}: ${t.dimensions}`)):(f(void 0),g(`${e(`Test failed`)}: ${t.reason??``}`))}catch(t){g(e(t.message))}})}async function w(){if(!l||!t||!r)return;let{count:n,risks:i}=th(t.memoryCount,l),a=[`${e(`Every stored memory will be re-embedded`)}: ${n}`,...i.map(t=>e(t))].join(`
123
- `);window.confirm(a)&&await Dm(y,async()=>{try{let e=await $(`/api/settings/embedding/apply`,{method:`POST`,body:JSON.stringify({candidate:Qm(l),revision:r.revision})});m(e),c(!1),u(void 0),f(void 0),g(``)}catch(e){g(e.message)}await Cm()})}async function T(){try{m(await $(`/api/settings/embedding/run`,{method:`POST`,body:`{}`}))}catch(e){g(e.message)}}let E=!!r?.secrets.embeddingApiKey?.set;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Embedding`),children:[(0,B.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Embedding`)}),a&&(0,B.jsx)(`button`,{type:`button`,"aria-label":e(s?`Lock`:`Unlock to change`),title:e(s?`Lock`:`Unlock to change`),className:`rounded border border-border px-2 py-1`,disabled:!t||p.state===`running`,onClick:x,children:s?`🔓`:`🔒`})]}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`The model that turns memory text into search vectors. A change re-embeds every memory.`)}),t&&!s&&(0,B.jsx)(ah,{current:t,keySet:E}),s&&l&&(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[[`builtin`,`server`].map(n=>(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`radio`,name:`omms-embedding-kind`,checked:l.kind===n,onChange:()=>S(rh(n,t?.kind===`builtin`?t.model:`Xenova/nomic-embed-text-v1`))}),e(n===`server`?`OpenAI-compatible server`:`Built-in model`)]},n)),l.kind===`server`&&(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`label`,{className:`block`,children:[e(`Preset`),(0,B.jsx)(fn,{"aria-label":e(`Preset`),className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:Xm.find(e=>e.url===l.url)?.id??`custom`,onChange:e=>S({url:Zm(e.target.value,l.url)}),children:Xm.map(t=>(0,B.jsx)(`option`,{value:t.id,children:t.id===`custom`?e(`Custom`):t.label},t.id))})]}),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Server URL`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:l.url,onChange:e=>S({url:e.target.value})})]})]}),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Model`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,placeholder:l.kind===`server`?`nomic-embed-text`:`Xenova/nomic-embed-text-v1`,value:l.model,onChange:e=>S({model:e.target.value})})]}),l.kind===`server`&&(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`API key`)}),[[`none`,`No key`],...E?[[`saved`,`Keep the saved key`]]:[],[`env`,`Environment variable`],[`file`,`Key file`],[`paste`,`Save key to a private file`]].map(([t,n])=>(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`radio`,name:`omms-embedding-key`,checked:l.key===t,onChange:()=>S({key:t})}),e(n)]},t)),l.key===`env`&&(0,B.jsx)(`input`,{"aria-label":e(`Variable name`),className:`w-full rounded border border-border bg-background p-2`,placeholder:`OPENROUTER_API_KEY`,value:l.keyInput.name,onChange:e=>S({keyInput:{...l.keyInput,name:e.target.value}})}),l.key===`file`&&(0,B.jsx)(`input`,{"aria-label":e(`Key file path`),className:`w-full rounded border border-border bg-background p-2`,value:l.keyInput.path,onChange:e=>S({keyInput:{...l.keyInput,path:e.target.value}})}),l.key===`paste`&&(0,B.jsx)(`input`,{"aria-label":e(`API key`),type:`password`,autoComplete:`off`,className:`w-full rounded border border-border bg-background p-2`,value:l.keyInput.value,onChange:e=>S({keyInput:{...l.keyInput,value:e.target.value}})})]}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:v||!l.model.trim(),onClick:()=>void C(),children:e(`Test`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:v||!eh(d?.key,l),onClick:()=>void w(),children:e(`Apply`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,onClick:x,children:e(`Cancel`)})]})]}),(0,B.jsx)(oh,{run:p,onRetry:()=>void T()}),h&&(0,B.jsx)(`p`,{className:`text-sm`,children:h})]})}async function lh(e,t){return e()?(await t(),!0):!1}var uh=[[`7`,`7 days`],[`30`,`30 days`],[`90`,`90 days`],[`never`,`Never`]];function dh({tokens:e,newValue:t,busy:n,onGenerate:r,onRevoke:i}){let a=Am(),[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(`30`),u=e=>e===null?a(`Never`):new Date(e).toLocaleDateString();return(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsxs)(`table`,{className:`w-full text-left text-xs`,children:[(0,B.jsx)(`thead`,{children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{children:a(`Name`)}),(0,B.jsx)(`th`,{children:a(`Created`)}),(0,B.jsx)(`th`,{children:a(`Expires`)}),(0,B.jsx)(`th`,{children:a(`Last used`)}),(0,B.jsx)(`th`,{})]})}),(0,B.jsx)(`tbody`,{children:e.map(e=>(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`td`,{children:e.name}),(0,B.jsx)(`td`,{children:u(e.createdAt)}),(0,B.jsx)(`td`,{children:u(e.expiresAt)}),(0,B.jsx)(`td`,{children:e.lastUsedAt===null?`-`:u(e.lastUsedAt)}),(0,B.jsx)(`td`,{children:(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5`,disabled:n,onClick:()=>i(e),children:a(`Revoke`)})})]},e.id))})]}),t&&(0,B.jsxs)(`div`,{role:`status`,className:`space-y-1 rounded border border-border p-2 text-xs`,children:[(0,B.jsx)(`code`,{className:`block break-all`,children:t}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5`,onClick:()=>void navigator.clipboard?.writeText(t),children:a(`Copy`)}),(0,B.jsx)(`p`,{className:`text-amber-600`,children:a(`Copy this token now. It will not be shown again.`)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2 text-sm`,children:[(0,B.jsxs)(`label`,{className:`block`,children:[a(`Token name`),(0,B.jsx)(`input`,{className:`mt-1 block rounded border border-border bg-background p-1.5`,placeholder:`ci`,value:o,onChange:e=>s(e.target.value)})]}),(0,B.jsxs)(`label`,{className:`block`,children:[a(`Expires after`),(0,B.jsx)(fn,{"aria-label":a(`Expires after`),className:`mt-1 block rounded border border-border bg-background p-1.5`,value:c,onChange:e=>l(e.target.value),children:uh.map(([e,t])=>(0,B.jsx)(`option`,{value:e,children:a(t)},e))})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:n||!o.trim(),onClick:()=>r(o.trim(),c===`never`?null:Number(c)),children:a(`Generate token`)})]})]})}var fh=`overflow-x-auto rounded-lg border border-border`,ph=`px-3 py-2 text-start font-medium`,mh=`bg-muted/50 text-xs text-muted-foreground`,hh=`px-3 py-2 text-start font-medium`,gh=`border-t border-border transition-colors hover:bg-muted/30`,_h=`px-3 py-1.5`;function vh(e){return{secrets:e.secrets??{},externalUsed:e.effective?.opencode?.mode===`manual`||e.effective?.pi?.kind===`manual`,claudeCodeInUse:!!(e.claudeCodeEvidence?.attempts||e.claudeCodeEvidence?.folderSet),access:e.access??{host:`127.0.0.1`,authEnabled:!1,tokenAvailable:!1,embeddingApiUrl:null}}}var yh=[{id:`memoryApiKey`,label:`External API key`,purpose:`Capture and profile learning through the external API. Claude Code always uses it.`,hosts:`OpenCode, Pi, Claude Code`,where:`External API card`},{id:`embeddingApiKey`,label:`Embedding server key`,purpose:`Sent to an embedding server on another machine.`,hosts:`OpenCode, Pi, Claude Code`,where:`Embedding card`},{id:`apiTokens`,label:`API tokens`,purpose:`Let scripts and other computers call the web app's API.`,hosts:`Web app`,where:`Table below`},{id:`webPassword`,label:`Browser password`,purpose:`Asks for a user name and password before the page opens.`,hosts:`Web app`,where:`Form below`}];function bh({state:e}){let t=Am();return e===`set`?(0,B.jsxs)(`span`,{children:[`✅ `,t(`set`)]}):e===`missing`?(0,B.jsxs)(`span`,{className:`text-red-600`,children:[`⛔️ `,t(`missing`)]}):e===`never-used`?(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:t(`never used before`)}):(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:t(`not needed`)})}function xh({states:e}){let t=Am();return(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:z(ph,`sr-only`),children:t(`Keys and access`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{className:hh,children:t(`Credential`)}),(0,B.jsx)(`th`,{className:hh,children:t(`State`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Used for`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Hosts`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Change it in`)})]})}),(0,B.jsx)(`tbody`,{children:yh.map(n=>(0,B.jsxs)(`tr`,{className:z(gh,`align-top`),children:[(0,B.jsx)(`td`,{className:z(_h,`font-medium`),children:t(n.label)}),(0,B.jsx)(`td`,{className:z(_h,`whitespace-nowrap`),children:(0,B.jsx)(bh,{state:e[n.id]})}),(0,B.jsx)(`td`,{className:_h,children:t(n.purpose)}),(0,B.jsx)(`td`,{className:_h,children:n.hosts===`Web app`?t(`Web app`):n.hosts}),(0,B.jsx)(`td`,{className:_h,children:t(n.where)})]},n.id))})]})})}function Sh({value:e,onChange:t}){let n=Am();return(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`label`,{className:`block`,children:[(0,B.jsx)(`span`,{children:n(`User name`)}),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,autoComplete:`username`,value:e.username,onChange:n=>t({...e,username:n.target.value})})]}),(0,B.jsxs)(`label`,{className:`block`,children:[(0,B.jsx)(`span`,{children:n(`Password`)}),(0,B.jsx)(`input`,{type:`password`,autoComplete:`new-password`,className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:e.value,onChange:n=>t({...e,value:n.target.value})})]})]})}function Ch(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(),[l,u]=(0,_.useState)({username:``,value:``}),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(!1);async function h(){let e=await $(`/api/settings/tokens`);o(e.tokens)}(0,_.useEffect)(()=>{let e=!0,t=Sm();$(`/api/settings`).then(r=>{e&&t.isCurrent()&&n(r)}).catch(t=>{e&&f(t.message)}),$(`/api/web/status`).then(async t=>{!e||!t.isLocal||(i(!0),await h())}).catch(()=>{});let r=wm(t=>{e&&n(t)});return()=>{e=!1,r()}},[]);async function g(e){await Dm(m,async()=>{try{await e()}catch(e){f(e.message)}await Cm()}).catch(()=>{})}let v=(e,t)=>g(async()=>{let n=await $(`/api/settings/tokens`,{method:`POST`,body:JSON.stringify({name:e,expiresInDays:t})});c(n.value),f(``),await h()}),y=t=>g(async()=>{c(void 0),await lh(()=>window.confirm(e(`Revoke this token? Scripts that use it stop working.`)),async()=>{await $(`/api/settings/tokens/${t.id}`,{method:`DELETE`}),await h()})}),b=n=>g(async()=>{t&&(await $(`/api/settings/web-password`,{method:`POST`,body:JSON.stringify(n?{clear:!0,revision:t.revision}:{password:l.value,username:l.username,revision:t.revision})}),u({username:``,value:``}),f(e(Ym(n))))}),x=t?.access;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Keys and access`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Keys and access`)}),t&&(0,B.jsx)(xh,{states:Jm(vh(t))}),x?.configTokenIgnored&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`The config file still sets webServerApiToken. OMMS imported it once as the token “from config file” and no longer reads the key. Use the token table instead.`)}),r?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`API tokens`)}),(0,B.jsx)(dh,{tokens:a,newValue:s,busy:p,onGenerate:(e,t)=>void v(e,t),onRevoke:e=>void y(e)}),(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3 text-sm`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`Browser password`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:x?.authEnabled?x.authUsername?`${e(`A browser password is set for user`)} ${x.authUsername}.`:e(`A browser password is set for your computer user name.`):e(`No browser password is set.`)}),(0,B.jsx)(Sh,{value:l,onChange:u}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:p||!t||!l.value,onClick:()=>void b(!1),children:e(`Save password`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:p||!t||!x?.authEnabled,onClick:()=>void b(!0),children:e(`Clear password`)})]})]})]}):(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Open this page on the computer that runs OMMS to manage tokens and the password.`)}),d&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:d})]})}function wh({preview:e,job:t,busy:n,onStart:r,onPause:i}){let a=Am(),o=t.state===`running`;return(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,B.jsxs)(`p`,{children:[a(`Prompts waiting for profile learning`),`: `,e.waiting,` · `,a(`Model calls`),`:`,` `,e.calls]}),t.state!==`idle`&&(0,B.jsxs)(`p`,{role:`status`,children:[a(`Batches done`),`: `,t.batchesBuilt,` · `,a(`Prompts waiting`),`: `,t.remaining,t.state===`paused`&&` · ${a(`Paused`)}`,t.state===`done`&&` · ${a(`Finished`)}`]}),t.state===`superseded`&&(0,B.jsx)(`p`,{children:a(`A newer catch-up run took over.`)}),t.state===`failed`&&(0,B.jsxs)(`p`,{className:`text-red-600`,children:[a(`Stopped`),`: `,t.reason??`error`]}),o?(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,onClick:i,children:a(`Pause`)}):(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:n||e.waiting===0,onClick:r,children:a(t.state===`idle`||t.state===`done`?`Catch up profile`:`Resume`)})]})}function Th(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)({state:`idle`,batchesBuilt:0,remaining:0}),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(``);async function d(){let e=await $(`/api/settings/profile/catch-up`);n(e.preview),i(e.job)}(0,_.useEffect)(()=>{d().catch(e=>u(e.message)),$(`/api/web/status`).then(e=>o(!!e.isLocal)).catch(()=>{})},[]),(0,_.useEffect)(()=>{if(r.state!==`running`)return;let e=setInterval(()=>void d().catch(()=>{}),2e3);return()=>clearInterval(e)},[r.state]);async function f(){if(!t)return;let n=r.state!==`idle`&&r.state!==`done`;if(window.confirm(`${e(`Start profile learning for the waiting prompts? Model calls`)}: ${t.calls}`)){c(!0);try{i(await $(`/api/settings/profile/catch-up/${n?`resume`:`start`}`,{method:`POST`,body:`{}`})),u(``)}catch(e){u(e.message)}c(!1)}}async function p(){try{i(await $(`/api/settings/profile/catch-up/pause`,{method:`POST`,body:`{}`}))}catch(e){u(e.message)}}return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Profile learning`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Profile learning`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Catch up analyses every waiting prompt with the saved external API, 50 prompts for each model call.`)}),t&&(a?(0,B.jsx)(wh,{preview:t,job:r,busy:s,onStart:()=>void f(),onPause:()=>void p()}):(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Open this page on the computer that runs OMMS to start a catch-up run.`)})),l&&(0,B.jsx)(`p`,{role:`alert`,children:l})]})}function Eh(){let e=Am(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)({}),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(``);async function l(){let e=await $(`/api/settings/profiles`);n(e.profiles)}if((0,_.useEffect)(()=>{l().catch(e=>c(e.message))},[]),t.length<2)return null;let u=t=>Dm(o,async()=>{if(window.confirm(`${e(`Use this profile for every folder?`)} ${t.userId}`))try{let n=await Cm();await $(`/api/settings/profiles/use`,{method:`POST`,body:JSON.stringify({userId:t.userId,revision:n?.revision})}),await Cm(),await l(),c(e(`Saved. OMMS now uses this profile in every folder.`))}catch(e){c(e.message)}}),d=n=>Dm(o,async()=>{let i=t.find(e=>e.id===(r[n.id]??t.find(e=>e.id!==n.id)?.id));if(i&&window.confirm(`${e(`Merge this profile into the other one? The source profile is turned off, not deleted.`)}\n${n.userId} → ${i.userId}`))try{await $(`/api/settings/profiles/merge`,{method:`POST`,body:JSON.stringify({sourceId:n.id,targetId:i.id})}),await l(),c(e(`Merged.`))}catch(e){c(e.message)}});return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Profiles`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Profiles`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`OMMS keeps one profile for each git email. A folder whose repository has its own email starts a second profile. Choose the profile that is yours, or merge the extra one into it.`)}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:z(ph,`sr-only`),children:e(`Profiles`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{className:hh,children:e(`Email`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Preferences`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Patterns`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Workflows`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Prompts analysed`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Last update`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Actions`)})]})}),(0,B.jsx)(`tbody`,{children:t.map(n=>(0,B.jsxs)(`tr`,{className:gh,children:[(0,B.jsxs)(`td`,{className:z(_h,`font-medium`),children:[n.userId,n.inUse&&(0,B.jsxs)(`span`,{className:`ms-2 text-xs text-green-700`,children:[`✅ `,e(`in use`)]})]}),(0,B.jsx)(`td`,{className:_h,children:n.preferences}),(0,B.jsx)(`td`,{className:_h,children:n.patterns}),(0,B.jsx)(`td`,{className:_h,children:n.workflows}),(0,B.jsx)(`td`,{className:_h,children:n.totalPromptsAnalyzed}),(0,B.jsx)(`td`,{className:_h,children:new Date(n.lastAnalyzedAt).toLocaleString()}),(0,B.jsxs)(`td`,{className:z(_h,`space-y-1`),children:[!n.inUse&&(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-1`,disabled:a,onClick:()=>void u(n),children:e(`Use this profile`)}),(0,B.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,B.jsx)(`label`,{className:`sr-only`,htmlFor:`merge-${n.id}`,children:e(`Merge into`)}),(0,B.jsx)(`select`,{id:`merge-${n.id}`,className:`rounded border border-border bg-background px-1 py-1 text-xs`,value:r[n.id]??``,onChange:e=>i(t=>({...t,[n.id]:e.target.value})),children:t.filter(e=>e.id!==n.id).map(e=>(0,B.jsx)(`option`,{value:e.id,children:e.userId},e.id))}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-1`,disabled:a,onClick:()=>void d(n),children:e(`Merge into`)})]})]})]},n.id))})]})}),s&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:s})]})}function Dh(e,t){let n={...t},r=0,i=0;for(let t of e)t.directory===``||n[t.directory]?.accepted||(t.suggestion?(n[t.directory]={directory:t.directory,target:t.suggestion,accepted:!0},r++):i++);return{decisions:n,filled:r,notFilled:i}}function Oh(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(),[a,o]=(0,_.useState)(new Set),[s,c]=(0,_.useState)({}),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)({}),h=()=>$(`/api/settings/import-maps`).then(e=>{i(e),o(new Set),c({})}).catch(e=>u(e.message));(0,_.useEffect)(()=>{let e=!0;$(`/api/settings`).then(t=>{e&&n(t)}).catch(t=>{e&&u(t.message)}),h();let t=wm(t=>{e&&n(t)});return()=>{e=!1,t()}},[]);function g(t,n){let r=Dh(n,s);c(r.decisions),m(n=>({...n,[t]:`${e(`Filled`)}: ${r.filled} · ${e(`No suggestion`)}: ${r.notFilled}. ${e(`Check them, then press Save maps.`)}`}))}function v(e,t){c(n=>{let r=n[e.directory]??{directory:e.directory,target:e.suggestion??``,accepted:!1};return{...n,[e.directory]:{...r,...t}}})}async function y(){if(!t||!r)return;let n=Fm(r.saved,a,Object.values(s));f(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:{importPathMaps:n},revision:t.revision})}),u(e(`Saved. Maps apply to the next import or backfill run.`))}catch(e){u(e.message)}await Cm(),await h(),f(!1)}return(0,B.jsxs)(`section`,{id:`directory-maps`,className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Directory maps`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Directory maps`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Map a directory that was moved or deleted to the project it belongs to. A change applies to the next import or backfill run.`)}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Saved maps`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Saved maps apply to every host.`)}),!r?.saved.length&&(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`none`)}),(0,B.jsx)(`ul`,{className:`space-y-1 text-sm`,children:r?.saved.map(t=>(0,B.jsxs)(`li`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsxs)(`span`,{className:a.has(t.from)?`line-through`:``,children:[(0,B.jsx)(`code`,{children:t.from}),` → `,(0,B.jsx)(`code`,{children:t.to})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5 text-xs`,onClick:()=>o(e=>{let n=new Set(e);return n.has(t.from)?n.delete(t.from):n.add(t.from),n}),children:a.has(t.from)?e(`Keep`):e(`Remove`)})]},t.from))}),[`pi`,`opencode`,`claude-code`].map(t=>{let n=r?.[t]??[],i=n.filter(e=>e.directory!==``);return(0,B.jsxs)(`div`,{className:`space-y-2 rounded-lg border border-border p-3`,children:[(0,B.jsxs)(`h3`,{className:`font-medium`,children:[Lm(t),`: `,e(`Unresolved directories`)]}),n.length===0?(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`No unresolved directories in the latest run.`)}):(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d||i.length===0,onClick:()=>g(t,n),children:e(`Smart resolve directories`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Finds the project each missing directory belongs to, mostly the main repository of a deleted worktree, and fills it in for you to check. Nothing is saved until you press Save maps.`)}),p[t]&&(0,B.jsx)(`p`,{role:`status`,className:`text-xs`,children:p[t]})]}),n.map(t=>{if(t.directory===``)return(0,B.jsxs)(`div`,{className:`rounded-lg border border-dashed border-border p-2 text-sm text-muted-foreground`,children:[e(`No directory recorded`),` ·`,` `,t.sessions===1?e(`1 session`):`${t.sessions} ${e(`sessions`)}`,` ·`,` `,e(`These sessions cannot be mapped.`)]},`no-directory`);let n=s[t.directory],r=n?.target??t.suggestion??``;return(0,B.jsxs)(`div`,{className:`space-y-1 rounded-lg border border-border p-2 text-sm`,children:[(0,B.jsxs)(`p`,{children:[(0,B.jsx)(`code`,{children:t.directory}),` ·`,` `,t.sessions===1?e(`1 session`):`${t.sessions} ${e(`sessions`)}`]}),!t.suggestion&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`No suggestion found.`)}),(0,B.jsx)(`input`,{"aria-label":`${t.directory} ${e(`Target directory`)}`,className:`w-full rounded border border-border bg-background p-2`,placeholder:e(`Target directory`),value:r,onChange:e=>v(t,{target:e.target.value})}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:n?.accepted??!1,onChange:e=>v(t,{accepted:e.target.checked})}),e(`Use this map`)]})]},t.directory)})]},t)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d||!t||!r,onClick:()=>void y(),children:e(`Save maps`)}),l&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:l})]})}var kh=[`opencode`,`pi`,`claude-code`];function Ah(e){return!e.provider&&!e.model?null:`${e.provider??``}/${e.model??``}`}function jh(e){let t=new Map;for(let n of e){let e=t.get(n.host)??{host:n.host,total:0,saved:0,skipped:0,failed:0,models:[]};e.total+=n.total,e.saved+=n.saved,e.skipped+=n.skipped,e.failed+=n.failed;let r=Ah(n),i=e.models.find(e=>e.label===r);i?(i.total+=n.total,i.saved+=n.saved,i.skipped+=n.skipped,i.failed+=n.failed):e.models.push({label:r,provider:n.provider,model:n.model,total:n.total,saved:n.saved,skipped:n.skipped,failed:n.failed}),t.set(n.host,e)}let n=e=>{let t=kh.indexOf(e);return t<0?kh.length:t};return[...t.values()].map(e=>({...e,models:e.models.sort((e,t)=>t.total-e.total)})).sort((e,t)=>n(e.host)-n(t.host))}function Mh(e,t){return t>0?Math.round(100*e/t):0}function Nh(e){let t=new Map;for(let n of e){let e=`${n.host}\u0000${n.reason}`,r=t.get(e)??{host:n.host,reason:n.reason,count:0};r.count+=n.count,t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count)}function Ph({row:e}){return(0,B.jsxs)(B.Fragment,{children:[[e.saved,e.skipped,e.failed].map((t,n)=>(0,B.jsxs)(`td`,{className:z(_h,`text-end tabular-nums`),children:[t,` `,(0,B.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[Mh(t,e.total),`%`]})]},n)),(0,B.jsx)(`td`,{className:z(_h,`text-end font-medium tabular-nums`),children:e.total})]})}function Fh(e,t){return`/api/settings/diagnostics?days=${e}${t===`all`?``:`&host=${t}`}`}function Ih(){let e=Am(),[t,n]=(0,_.useState)(7),[r,i]=(0,_.useState)(`all`),[a,o]=(0,_.useState)(()=>new Set),[s,c]=(0,_.useState)(),[l,u]=(0,_.useState)([]),[d,f]=(0,_.useState)(),[p,m]=(0,_.useState)(``),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(``),[b]=(0,_.useState)(Em),x=(0,_.useCallback)(async(e,t)=>{let n=Sm(),r=b.begin();try{let[i,a,o]=await Promise.all([$(Fh(e,t)),$(`/api/settings/traces`),$(`/api/settings`)]);if(!r())return;c(i),u(a.traces),n.isCurrent()&&f(o),g(``)}catch(e){if(!r())return;g(e.message)}},[b]);(0,_.useEffect)(()=>{x(t,r)},[t,r,x]),(0,_.useEffect)(()=>wm(e=>f(e)),[]);async function S(n){if(!d)return;let i;try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({revision:d.revision,edits:n})})}catch(e){i=e}let a=await Cm()!==null;if(!i){y(``),await x(t,r),a||g(e(`Reload the page before saving again.`));return}g(Tm(i.message,e(a?`Current settings were reloaded; check the values and save again.`:`The current settings could not be reloaded. Reload the page.`)))}async function C(e){try{let t=await $(`/api/settings/traces/${encodeURIComponent(e)}`);m(t.content)}catch(e){g(e.message)}}async function w(n){if(window.confirm(`${e(`Delete`)} ${n}?`))try{await $(`/api/settings/traces/${encodeURIComponent(n)}`,{method:`DELETE`}),m(``),await x(t,r)}catch(e){g(e.message)}}async function T(n){try{let{result:i}=await $(`/api/settings/capture-retry/${n}/run`,{method:`POST`,body:`{}`});y(e(i===`scheduled`?n===`pi`?`These turns retry at the next Pi session start.`:n===`claude-code`?`These turns retry at the next Claude Code session start.`:`These turns retry at the next OpenCode session start.`:i===`running`?`A retry is already running.`:`Retrying now.`)),await x(t,r)}catch(e){g(e.message)}}let E=d?.settings.captureTrace,ee=Number(d?.settings.captureRetryRetentionHours?.value??72);return(0,B.jsxs)(`section`,{className:`space-y-4 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Capture diagnostics`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Capture diagnostics`)}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2 pb-2 text-sm`,children:[e(`Time range`),(0,B.jsxs)(fn,{"aria-label":e(`Time range`),className:`rounded-lg border border-border bg-background px-2 py-1`,value:t,onChange:e=>n(Number(e.target.value)),children:[(0,B.jsx)(`option`,{value:1,children:e(`24 hours`)}),(0,B.jsx)(`option`,{value:7,children:e(`7 days`)}),(0,B.jsx)(`option`,{value:30,children:e(`30 days`)}),(0,B.jsx)(`option`,{value:90,children:e(`90 days`)})]}),e(`Host`),(0,B.jsxs)(fn,{"aria-label":e(`Host`),className:`rounded-lg border border-border bg-background px-2 py-1`,value:r,onChange:e=>i(e.target.value),children:[(0,B.jsx)(`option`,{value:`all`,children:e(`All`)}),[`opencode`,`pi`,`claude-code`].map(e=>(0,B.jsx)(`option`,{value:e,children:Lm(e)},e))]})]}),h&&(0,B.jsx)(`p`,{role:`alert`,children:h}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Saved: a memory was stored. Skipped: the model or a rule found nothing worth keeping, or the turn was private or trivial. Failed: the attempt hit an error. Total: the three added up. Each percentage is a share of its row's total.`)}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Outcomes by host`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsx)(`tr`,{children:[`Host / model`,`Saved`,`Skipped`,`Failed`,`Total`].map((t,n)=>(0,B.jsx)(`th`,{scope:`col`,className:z(hh,n>0&&`text-end`),children:e(t)},t))})}),(0,B.jsx)(`tbody`,{children:jh(s?.byModel??[]).map(t=>{let n=a.has(t.host);return(0,B.jsxs)(_.Fragment,{children:[(0,B.jsxs)(`tr`,{className:z(gh,`font-medium`),children:[(0,B.jsx)(`td`,{className:_h,children:(0,B.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1`,"aria-expanded":n,onClick:()=>o(e=>{let r=new Set(e);return n?r.delete(t.host):r.add(t.host),r}),children:[(0,B.jsx)(`span`,{"aria-hidden":!0,children:n?`▾`:`▸`}),Rm(t.host),(0,B.jsxs)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:[`(`,t.models.length,` `,e(t.models.length===1?`model`:`models`),`)`]})]})}),(0,B.jsx)(Ph,{row:t})]}),n&&t.models.map(n=>(0,B.jsxs)(`tr`,{className:`border-t border-border transition-colors hover:bg-muted/30`,children:[(0,B.jsx)(`td`,{className:z(`px-3 py-1.5`,`ps-8`),children:n.label?(0,B.jsx)(`span`,{className:`font-mono text-xs`,children:n.label}):(0,B.jsx)(`span`,{className:`text-xs italic text-muted-foreground`,title:e(`No model was recorded for these attempts. This happens with records written by older OMMS versions, and when an attempt stops before a model is chosen.`),children:e(`model not recorded`)})}),(0,B.jsx)(Ph,{row:n})]},`${t.host}-${n.label??`none`}`))]},t.host)})})]})}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Failure reasons`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(`Host`)}),(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(`Reason`)}),(0,B.jsx)(`th`,{scope:`col`,className:z(hh,`text-end`),children:e(`Total`)})]})}),(0,B.jsx)(`tbody`,{children:Nh(s?.byReason??[]).map((e,t)=>(0,B.jsxs)(`tr`,{className:gh,children:[(0,B.jsx)(`td`,{className:z(_h,`text-muted-foreground`),children:Rm(e.host)}),(0,B.jsx)(`td`,{className:z(_h,`font-mono text-xs`),children:e.reason}),(0,B.jsx)(`td`,{className:z(_h,`text-end tabular-nums`),children:e.count})]},`${e.host}-${e.reason}-${t}`))})]})}),(0,B.jsx)(`div`,{className:z(fh,`max-h-72 overflow-y-auto`),children:(0,B.jsxs)(`table`,{className:`w-full min-w-max text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Recent attempts`)}),(0,B.jsx)(`thead`,{className:z(mh,`sticky top-0`),children:(0,B.jsx)(`tr`,{children:[`Time`,`Host`,`Source`,`Session`,`Path`,`Model`,`Stop`,`Blocks`,`Prompt`,`Reply`,`Duration`,`Outcome`,`Reason`].map(t=>(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(t)},t))})}),(0,B.jsx)(`tbody`,{children:s?.recent.map((e,t)=>(0,B.jsx)(`tr`,{className:gh,children:[new Date(e.timestamp).toLocaleString(),Rm(e.host),e.sourceType,e.sessionId,e.path,`${e.provider??``}/${e.model??``}`,e.stopReason,e.blockTypes?.join(`, `),e.promptChars,e.replyChars,e.durationMs,e.outcome,e.reason].map((e,t)=>(0,B.jsx)(`td`,{className:z(_h,`whitespace-nowrap`),children:e??``},t))},`${e.timestamp}-${t}`))})]})}),(0,B.jsxs)(`div`,{className:`space-y-2 border-t border-border pt-3 text-sm`,children:[(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:E?.value===!0,disabled:!d,onChange:t=>{t.target.checked&&!window.confirm(e(`Traces can contain conversation content after redaction. Keep tracing off unless you need it for debugging.`))||S({captureTrace:t.target.checked})}}),` `,e(`Save capture traces`)]}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Traces can contain conversation content after redaction. Keep tracing off unless you need it for debugging.`)}),E?.source===`project`&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`This project turns tracing off. The global switch cannot turn it on here.`)}),[`captureTraceRetentionDays`,`captureAttemptRetentionDays`].map(t=>(0,B.jsxs)(`label`,{className:`block`,children:[e(t===`captureTraceRetentionDays`?`Trace retention (days)`:`Attempt retention (days)`),` `,(0,B.jsx)(`input`,{type:`number`,min:1,className:`ms-2 w-20 rounded border border-border bg-background p-1`,defaultValue:Number(d?.settings[t]?.value??30),onBlur:e=>{let n=Number(e.target.value);Number.isSafeInteger(n)&&n>0&&n!==d?.settings[t]?.value&&S({[t]:n})}},`${t}-${d?.settings[t]?.value}`)]},t)),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Retry retention (hours)`),` `,(0,B.jsx)(`input`,{type:`number`,min:0,max:720,className:`ms-2 w-20 rounded border border-border bg-background p-1`,defaultValue:ee,onBlur:e=>{let t=Number(e.target.value);Number.isSafeInteger(t)&&t>=0&&t<=720&&t!==ee&&S({captureRetryRetentionHours:t})}},`captureRetryRetentionHours-${ee}`)]}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`When the capture model cannot be reached, OMMS keeps the turn and tries again later. Queued turns can hold conversation content after redaction. 0 turns the queue off and deletes waiting turns.`)}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Turns waiting for retry`)}),[`pi`,`opencode`,`claude-code`].map(t=>{let n=s?.retryQueue?.[t]??0;return(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`span`,{className:`w-24`,children:Lm(t)}),(0,B.jsx)(`span`,{className:`tabular-nums`,children:n}),(0,B.jsx)(`button`,{type:`button`,disabled:n===0||ee===0,className:`disabled:opacity-50`,onClick:()=>void T(t),children:e(`Retry now`)})]},t)}),v&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:v}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Trace files`)}),l.map(t=>(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsxs)(`span`,{children:[t.file,` (`,t.size,` bytes)`]}),(0,B.jsx)(`button`,{type:`button`,onClick:()=>void C(t.file),children:e(`View`)}),(0,B.jsx)(`button`,{type:`button`,onClick:()=>void w(t.file),children:e(`Delete`)})]},t.file)),p&&(0,B.jsx)(`pre`,{className:`max-h-60 overflow-auto whitespace-pre-wrap break-words rounded bg-background p-2 text-xs`,children:p})]})]})}function Lh(){let e=Am(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(``);async function s(e){i(!0);try{let t=await $(`/api/settings/health`,{method:`POST`,body:JSON.stringify({testModels:e})});n(t.checks),o(``)}catch(e){o(e.message)}finally{i(!1)}}return(0,B.jsxs)(`section`,{id:`settings-health`,className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Health`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Health`)}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{className:`rounded-lg border border-border px-3 py-1.5 text-sm`,disabled:r,onClick:()=>void s(!1),children:e(`Run checks`)}),(0,B.jsx)(`button`,{className:`rounded-lg border border-border px-3 py-1.5 text-sm`,disabled:r,onClick:()=>void s(!0),children:e(`Run checks and test models`)})]}),r&&(0,B.jsx)(`p`,{role:`status`,children:e(`Checking…`)}),a&&(0,B.jsx)(`p`,{role:`alert`,children:a}),(0,B.jsx)(`ul`,{className:`space-y-2 text-sm`,children:t.map(t=>(0,B.jsxs)(`li`,{className:`rounded-lg border border-border p-2`,children:[(0,B.jsx)(`strong`,{className:t.status===`fail`?`text-red-600`:t.status===`warn`?`text-amber-600`:`text-green-600`,children:e(t.status).toUpperCase()}),` `,`· `,e(t.check),`: `,t.reason]},t.check))})]})}function Rh(e){let t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);return t?[Number(t[1]),Number(t[2])-1,Number(t[3])]:null}function zh(e){let t=Rh(e);return t?new Date(t[0],t[1],t[2],0,0,0,0).getTime():void 0}function Bh(e){let t=Rh(e);return t?new Date(t[0],t[1],t[2],23,59,59,999).getTime():void 0}function Vh(e,t,n){let r=!n&&e!==null&&e.revision===t.revision;return{page:r?{...t,listedAt:e.listedAt}:t,sameListing:r}}function Hh(e){let t=Am(),[n,r]=(0,_.useState)(``),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(``),f=`rounded border border-border px-3 py-1.5 text-sm disabled:opacity-50`;async function p(t){try{let n=await $(`/api/settings/imports/sources/validate`,{method:`POST`,body:JSON.stringify({host:e.host,path:t})});a(n),r(n.displayPath),e.onChoose(n),d(``)}catch(e){d(e.message)}}async function m(t){try{let n=await $(`/api/settings/imports/sources/browse`,{method:`POST`,body:JSON.stringify({host:e.host,...t?{path:t}:{}})});s(n),d(``)}catch(e){let t=e.message;/loopback/i.test(t)&&l(!0),d(t)}}function h(){a(null),r(``),s(null),e.onChoose(null)}return(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,B.jsxs)(`label`,{className:`block`,children:[e.host===`pi`?t(`Pi sessions folder or one .jsonl session file`):e.host===`claude-code`?t(`Claude Code transcripts folder`):t(`OpenCode database file`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2 font-mono`,value:n,placeholder:t(`Absolute path, for example on a mounted volume`),onChange:e=>r(e.target.value)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:f,disabled:!n.trim(),onClick:()=>void p(n.trim()),children:t(`Use this source`)}),!c&&(0,B.jsx)(`button`,{type:`button`,className:f,onClick:()=>void m(o?.path),children:t(`Browse`)}),i&&(0,B.jsx)(`button`,{type:`button`,className:f,onClick:h,children:t(`Use the default location`)})]}),i&&(0,B.jsxs)(`p`,{role:`status`,children:[t(`Chosen source`),`: `,(0,B.jsx)(`span`,{className:`font-mono`,children:i.displayPath})]}),u&&(0,B.jsx)(`p`,{role:`alert`,children:u}),o&&(0,B.jsxs)(`div`,{className:`rounded border border-border p-2`,children:[(0,B.jsx)(`p`,{className:`font-mono text-xs break-all`,children:o.path}),(0,B.jsxs)(`ul`,{className:`max-h-60 overflow-auto`,children:[o.parent&&(0,B.jsx)(`li`,{children:(0,B.jsx)(`button`,{type:`button`,className:`underline`,onClick:()=>void m(o.parent),children:`..`})}),o.entries.map(n=>(0,B.jsxs)(`li`,{className:`flex items-center gap-2`,children:[n.kind===`folder`?(0,B.jsxs)(`button`,{type:`button`,className:`underline`,onClick:()=>void m(n.path),children:[n.name,`/`]}):(0,B.jsx)(`span`,{className:`font-mono text-xs`,children:n.name}),(n.kind!==`folder`||e.host!==`opencode`)&&(0,B.jsx)(`button`,{type:`button`,className:`text-xs underline`,onClick:()=>void p(n.path),children:t(`Choose`)})]},n.path))]}),o.truncated&&(0,B.jsx)(`p`,{className:`text-xs`,children:t(`Only the first 500 entries are shown.`)})]})]})}function Uh(e){return Object.values(e).some(e=>e?.state===`running`)}function Wh(e){return!e||e.total<=0?null:{percent:e.percent,done:`${e.done.toLocaleString(`en-US`)} / ${e.total.toLocaleString(`en-US`)}`,minutesLeft:e.minutesLeft===null?`unknown`:`about ${e.minutesLeft}`}}function Gh(e,t){let n=e?.state===`running`,r=e?.paused===!0;return{runNow:!n&&!r&&!t,pause:n&&!r,resume:r&&!t}}function Kh(e,t){return e??!t}function qh(e,t){let n=t.indexOf(`/`);if(t!==`inherit`&&t!==`external`&&(n<1||n===t.length-1))throw Error(`Enter a model as provider/model.`);return{[`${e}BackfillModel`]:t}}function Jh(e,t){if(t?.state===`running`)return t.phase===`profile`?{kind:`learning-profile`,done:t.profileDone??0,total:t.profileTotal??0}:{kind:`running`};if(t?.paused)return{kind:`paused`};if(!e||e.state===`not-started`)return t?.state===`done`?{kind:`imported`}:{kind:`not-started`};let n=t?.state===`done`&&(e.counts.failed??0)>0;return e.state===`failed`&&!n?{kind:`failed`,error:e.error}:e.state===`running`?{kind:`running`}:e.counts.pending>0?{kind:`stopped`,pending:e.counts.pending}:e.counts.unresolved>0?{kind:`partly`,unresolved:e.counts.unresolved}:{kind:`imported`}}function Yh(e){return e?.state===`running`&&e.phase!==`profile`}function Xh(e){return!e||e.state===`running`||!e.state||!e.updatedAt||!e.surface?null:{finishedAt:e.updatedAt,surface:e.surface,imported:e.imported??0,skipped:e.skipped??0,failed:e.failed??0,state:e.state}}function Zh({badge:e}){let t=Am(),[n,r]=(()=>{switch(e.kind){case`imported`:return[`${t(`Imported`)} ✅`,`border-green-600/40 text-green-700`];case`partly`:return[`${t(`Partly imported`)} (${e.unresolved} ${t(`unresolved`)})`,`border-amber-500/50 text-amber-700`];case`running`:return[t(`Running`),`border-primary/50 text-primary`];case`learning-profile`:return[`${t(`Learning profile`)} ${e.done} / ${e.total}`,`border-primary/50 text-primary`];case`paused`:return[t(`Paused`),`border-border text-muted-foreground`];case`stopped`:return[`${t(`Stopped`)} (${e.pending} ${t(`pending`)})`,`border-amber-500/50 text-amber-700`];case`failed`:return[`${t(`Failed`)} ⛔️`,`border-red-600/40 text-red-700`];case`not-started`:return[t(`Not started`),`border-border text-muted-foreground`]}})();return(0,B.jsx)(`span`,{className:z(`inline-block rounded-full border px-2 py-0.5 text-xs font-medium`,r),title:e.kind===`failed`&&e.error?e.error:void 0,children:n})}var Qh=[`pi`,`opencode`,`claude-code`];function $h(){let e=Am(),[t,n]=(0,_.useState)({}),[r,i]=(0,_.useState)({});return(0,_.useEffect)(()=>{let e=()=>{$(`/api/settings/backfill`).then(n).catch(()=>{}),$(`/api/settings/backfill/runs`).then(i).catch(()=>{})};e();let t=setInterval(e,1e4);return()=>clearInterval(t)},[]),(0,B.jsx)(`div`,{className:`flex flex-wrap gap-2`,"aria-label":e(`Import status`),children:Qh.map(e=>(0,B.jsxs)(`div`,{className:`flex items-center gap-2 rounded-lg border border-border px-3 py-1.5 text-sm`,children:[(0,B.jsx)(`span`,{className:`font-medium`,children:Lm(e)}),(0,B.jsx)(Zh,{badge:Jh(t[e]??null,r[e]?.run??null)})]},e))})}var eg=50,tg=1e3,ng={"missing-model":`The external API has no memoryModel in the global config`,"missing-url":`The external API has no memoryApiUrl in the global config`,"missing-key":`The external API key is missing in the OpenCode process; check memoryApiKey and its env:// or file:// source`,"unsupported-provider":`The memoryProvider in the global config is not supported for imports`},rg=()=>({mode:`ids`,picked:new Map});function ig(e,t){return e.split(`
123
+ `);window.confirm(a)&&await Dm(y,async()=>{try{let e=await $(`/api/settings/embedding/apply`,{method:`POST`,body:JSON.stringify({candidate:Qm(l),revision:r.revision})});m(e),c(!1),u(void 0),f(void 0),g(``)}catch(e){g(e.message)}await Cm()})}async function T(){try{m(await $(`/api/settings/embedding/run`,{method:`POST`,body:`{}`}))}catch(e){g(e.message)}}let E=!!r?.secrets.embeddingApiKey?.set;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Embedding`),children:[(0,B.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Embedding`)}),a&&(0,B.jsx)(`button`,{type:`button`,"aria-label":e(s?`Lock`:`Unlock to change`),title:e(s?`Lock`:`Unlock to change`),className:`rounded border border-border px-2 py-1`,disabled:!t||p.state===`running`,onClick:x,children:s?`🔓`:`🔒`})]}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`The model that turns memory text into search vectors. A change re-embeds every memory.`)}),t&&!s&&(0,B.jsx)(ah,{current:t,keySet:E}),s&&l&&(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[[`builtin`,`server`].map(n=>(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`radio`,name:`omms-embedding-kind`,checked:l.kind===n,onChange:()=>S(rh(n,t?.kind===`builtin`?t.model:`Xenova/nomic-embed-text-v1`))}),e(n===`server`?`OpenAI-compatible server`:`Built-in model`)]},n)),l.kind===`server`&&(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`label`,{className:`block`,children:[e(`Preset`),(0,B.jsx)(fn,{"aria-label":e(`Preset`),className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:Xm.find(e=>e.url===l.url)?.id??`custom`,onChange:e=>S({url:Zm(e.target.value,l.url)}),children:Xm.map(t=>(0,B.jsx)(`option`,{value:t.id,children:t.id===`custom`?e(`Custom`):t.label},t.id))})]}),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Server URL`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:l.url,onChange:e=>S({url:e.target.value})})]})]}),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Model`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,placeholder:l.kind===`server`?`nomic-embed-text`:`Xenova/nomic-embed-text-v1`,value:l.model,onChange:e=>S({model:e.target.value})})]}),l.kind===`server`&&(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`API key`)}),[[`none`,`No key`],...E?[[`saved`,`Keep the saved key`]]:[],[`env`,`Environment variable`],[`file`,`Key file`],[`paste`,`Save key to a private file`]].map(([t,n])=>(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`radio`,name:`omms-embedding-key`,checked:l.key===t,onChange:()=>S({key:t})}),e(n)]},t)),l.key===`env`&&(0,B.jsx)(`input`,{"aria-label":e(`Variable name`),className:`w-full rounded border border-border bg-background p-2`,placeholder:`OPENROUTER_API_KEY`,value:l.keyInput.name,onChange:e=>S({keyInput:{...l.keyInput,name:e.target.value}})}),l.key===`file`&&(0,B.jsx)(`input`,{"aria-label":e(`Key file path`),className:`w-full rounded border border-border bg-background p-2`,value:l.keyInput.path,onChange:e=>S({keyInput:{...l.keyInput,path:e.target.value}})}),l.key===`paste`&&(0,B.jsx)(`input`,{"aria-label":e(`API key`),type:`password`,autoComplete:`off`,className:`w-full rounded border border-border bg-background p-2`,value:l.keyInput.value,onChange:e=>S({keyInput:{...l.keyInput,value:e.target.value}})})]}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:v||!l.model.trim(),onClick:()=>void C(),children:e(`Test`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:v||!eh(d?.key,l),onClick:()=>void w(),children:e(`Apply`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,onClick:x,children:e(`Cancel`)})]})]}),(0,B.jsx)(oh,{run:p,onRetry:()=>void T()}),h&&(0,B.jsx)(`p`,{className:`text-sm`,children:h})]})}async function lh(e,t){return e()?(await t(),!0):!1}var uh=[[`7`,`7 days`],[`30`,`30 days`],[`90`,`90 days`],[`never`,`Never`]];function dh({tokens:e,newValue:t,busy:n,onGenerate:r,onRevoke:i}){let a=Am(),[o,s]=(0,_.useState)(``),[c,l]=(0,_.useState)(`30`),u=e=>e===null?a(`Never`):new Date(e).toLocaleDateString();return(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsxs)(`table`,{className:`w-full text-left text-xs`,children:[(0,B.jsx)(`thead`,{children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{children:a(`Name`)}),(0,B.jsx)(`th`,{children:a(`Created`)}),(0,B.jsx)(`th`,{children:a(`Expires`)}),(0,B.jsx)(`th`,{children:a(`Last used`)}),(0,B.jsx)(`th`,{})]})}),(0,B.jsx)(`tbody`,{children:e.map(e=>(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`td`,{children:e.name}),(0,B.jsx)(`td`,{children:u(e.createdAt)}),(0,B.jsx)(`td`,{children:u(e.expiresAt)}),(0,B.jsx)(`td`,{children:e.lastUsedAt===null?`-`:u(e.lastUsedAt)}),(0,B.jsx)(`td`,{children:(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5`,disabled:n,onClick:()=>i(e),children:a(`Revoke`)})})]},e.id))})]}),t&&(0,B.jsxs)(`div`,{role:`status`,className:`space-y-1 rounded border border-border p-2 text-xs`,children:[(0,B.jsx)(`code`,{className:`block break-all`,children:t}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5`,onClick:()=>void navigator.clipboard?.writeText(t),children:a(`Copy`)}),(0,B.jsx)(`p`,{className:`text-amber-600`,children:a(`Copy this token now. It will not be shown again.`)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-end gap-2 text-sm`,children:[(0,B.jsxs)(`label`,{className:`block`,children:[a(`Token name`),(0,B.jsx)(`input`,{className:`mt-1 block rounded border border-border bg-background p-1.5`,placeholder:`ci`,value:o,onChange:e=>s(e.target.value)})]}),(0,B.jsxs)(`label`,{className:`block`,children:[a(`Expires after`),(0,B.jsx)(fn,{"aria-label":a(`Expires after`),className:`mt-1 block rounded border border-border bg-background p-1.5`,value:c,onChange:e=>l(e.target.value),children:uh.map(([e,t])=>(0,B.jsx)(`option`,{value:e,children:a(t)},e))})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:n||!o.trim(),onClick:()=>r(o.trim(),c===`never`?null:Number(c)),children:a(`Generate token`)})]})]})}var fh=`overflow-x-auto rounded-lg border border-border`,ph=`px-3 py-2 text-start font-medium`,mh=`bg-muted/50 text-xs text-muted-foreground`,hh=`px-3 py-2 text-start font-medium`,gh=`border-t border-border transition-colors hover:bg-muted/30`,_h=`px-3 py-1.5`;function vh(e){return{secrets:e.secrets??{},externalUsed:e.effective?.opencode?.mode===`manual`||e.effective?.pi?.kind===`manual`,claudeCodeInUse:!!(e.claudeCodeEvidence?.attempts||e.claudeCodeEvidence?.folderSet),access:e.access??{host:`127.0.0.1`,authEnabled:!1,tokenAvailable:!1,embeddingApiUrl:null}}}var yh=[{id:`memoryApiKey`,label:`External API key`,purpose:`Capture and profile learning through the external API. Claude Code always uses it.`,hosts:`OpenCode, Pi, Claude Code`,where:`External API card`},{id:`embeddingApiKey`,label:`Embedding server key`,purpose:`Sent to an embedding server on another machine.`,hosts:`OpenCode, Pi, Claude Code`,where:`Embedding card`},{id:`apiTokens`,label:`API tokens`,purpose:`Let scripts and other computers call the web app's API.`,hosts:`Web app`,where:`Table below`},{id:`webPassword`,label:`Browser password`,purpose:`Asks for a user name and password before the page opens.`,hosts:`Web app`,where:`Form below`}];function bh({state:e}){let t=Am();return e===`set`?(0,B.jsxs)(`span`,{children:[`✅ `,t(`set`)]}):e===`missing`?(0,B.jsxs)(`span`,{className:`text-red-600`,children:[`⛔️ `,t(`missing`)]}):e===`never-used`?(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:t(`never used before`)}):(0,B.jsx)(`span`,{className:`text-muted-foreground`,children:t(`not needed`)})}function xh({states:e}){let t=Am();return(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:z(ph,`sr-only`),children:t(`Keys and access`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{className:hh,children:t(`Credential`)}),(0,B.jsx)(`th`,{className:hh,children:t(`State`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Used for`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Hosts`)}),(0,B.jsx)(`th`,{className:hh,children:t(`Change it in`)})]})}),(0,B.jsx)(`tbody`,{children:yh.map(n=>(0,B.jsxs)(`tr`,{className:z(gh,`align-top`),children:[(0,B.jsx)(`td`,{className:z(_h,`font-medium`),children:t(n.label)}),(0,B.jsx)(`td`,{className:z(_h,`whitespace-nowrap`),children:(0,B.jsx)(bh,{state:e[n.id]})}),(0,B.jsx)(`td`,{className:_h,children:t(n.purpose)}),(0,B.jsx)(`td`,{className:_h,children:n.hosts===`Web app`?t(`Web app`):n.hosts}),(0,B.jsx)(`td`,{className:_h,children:t(n.where)})]},n.id))})]})})}function Sh({value:e,onChange:t}){let n=Am();return(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`label`,{className:`block`,children:[(0,B.jsx)(`span`,{children:n(`User name`)}),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2`,autoComplete:`username`,value:e.username,onChange:n=>t({...e,username:n.target.value})})]}),(0,B.jsxs)(`label`,{className:`block`,children:[(0,B.jsx)(`span`,{children:n(`Password`)}),(0,B.jsx)(`input`,{type:`password`,autoComplete:`new-password`,className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:e.value,onChange:n=>t({...e,value:n.target.value})})]})]})}function Ch(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)([]),[s,c]=(0,_.useState)(),[l,u]=(0,_.useState)({username:``,value:``}),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(!1);async function h(){let e=await $(`/api/settings/tokens`);o(e.tokens)}(0,_.useEffect)(()=>{let e=!0,t=Sm();$(`/api/settings`).then(r=>{e&&t.isCurrent()&&n(r)}).catch(t=>{e&&f(t.message)}),$(`/api/web/status`).then(async t=>{!e||!t.isLocal||(i(!0),await h())}).catch(()=>{});let r=wm(t=>{e&&n(t)});return()=>{e=!1,r()}},[]);async function g(e){await Dm(m,async()=>{try{await e()}catch(e){f(e.message)}await Cm()}).catch(()=>{})}let v=(e,t)=>g(async()=>{let n=await $(`/api/settings/tokens`,{method:`POST`,body:JSON.stringify({name:e,expiresInDays:t})});c(n.value),f(``),await h()}),y=t=>g(async()=>{c(void 0),await lh(()=>window.confirm(e(`Revoke this token? Scripts that use it stop working.`)),async()=>{await $(`/api/settings/tokens/${t.id}`,{method:`DELETE`}),await h()})}),b=n=>g(async()=>{t&&(await $(`/api/settings/web-password`,{method:`POST`,body:JSON.stringify(n?{clear:!0,revision:t.revision}:{password:l.value,username:l.username,revision:t.revision})}),u({username:``,value:``}),f(e(Ym(n))))}),x=t?.access;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Keys and access`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Keys and access`)}),t&&(0,B.jsx)(xh,{states:Jm(vh(t))}),x?.configTokenIgnored&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`The config file still sets webServerApiToken. OMMS imported it once as the token “from config file” and no longer reads the key. Use the token table instead.`)}),r?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3 text-sm`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`API tokens`)}),(0,B.jsx)(dh,{tokens:a,newValue:s,busy:p,onGenerate:(e,t)=>void v(e,t),onRevoke:e=>void y(e)})]}),(0,B.jsxs)(`fieldset`,{className:`space-y-2 rounded-lg border border-border p-3 text-sm`,children:[(0,B.jsx)(`legend`,{className:`px-1 font-medium`,children:e(`Browser password`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:x?.authEnabled?x.authUsername?`${e(`A browser password is set for user`)} ${x.authUsername}.`:e(`A browser password is set for your computer user name.`):e(`No browser password is set.`)}),(0,B.jsx)(Sh,{value:l,onChange:u}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:p||!t||!l.value,onClick:()=>void b(!1),children:e(`Save password`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:p||!t||!x?.authEnabled,onClick:()=>void b(!0),children:e(`Clear password`)})]})]})]}):(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Open this page on the computer that runs OMMS to manage tokens and the password.`)}),d&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:d})]})}function wh({preview:e,job:t,busy:n,onStart:r,onPause:i}){let a=Am(),o=t.state===`running`;return(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,B.jsxs)(`p`,{children:[a(`Prompts waiting for profile learning`),`: `,e.waiting,` · `,a(`Model calls`),`:`,` `,e.calls]}),t.state!==`idle`&&(0,B.jsxs)(`p`,{role:`status`,children:[a(`Batches done`),`: `,t.batchesBuilt,` · `,a(`Prompts waiting`),`: `,t.remaining,t.state===`paused`&&` · ${a(`Paused`)}`,t.state===`done`&&` · ${a(`Finished`)}`]}),t.state===`superseded`&&(0,B.jsx)(`p`,{children:a(`A newer catch-up run took over.`)}),t.state===`failed`&&(0,B.jsxs)(`p`,{className:`text-red-600`,children:[a(`Stopped`),`: `,t.reason??`error`]}),o?(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,onClick:i,children:a(`Pause`)}):(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:n||e.waiting===0,onClick:r,children:a(t.state===`idle`||t.state===`done`?`Catch up profile`:`Resume`)})]})}function Th(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)({state:`idle`,batchesBuilt:0,remaining:0}),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(!1),[l,u]=(0,_.useState)(``);async function d(){let e=await $(`/api/settings/profile/catch-up`);n(e.preview),i(e.job)}(0,_.useEffect)(()=>{d().catch(e=>u(e.message)),$(`/api/web/status`).then(e=>o(!!e.isLocal)).catch(()=>{})},[]),(0,_.useEffect)(()=>{if(r.state!==`running`)return;let e=setInterval(()=>void d().catch(()=>{}),2e3);return()=>clearInterval(e)},[r.state]);async function f(){if(!t)return;let n=r.state!==`idle`&&r.state!==`done`;if(window.confirm(`${e(`Start profile learning for the waiting prompts? Model calls`)}: ${t.calls}`)){c(!0);try{i(await $(`/api/settings/profile/catch-up/${n?`resume`:`start`}`,{method:`POST`,body:`{}`})),u(``)}catch(e){u(e.message)}c(!1)}}async function p(){try{i(await $(`/api/settings/profile/catch-up/pause`,{method:`POST`,body:`{}`}))}catch(e){u(e.message)}}return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Profile learning`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Profile learning`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Catch up analyses every waiting prompt with the saved external API, 50 prompts for each model call.`)}),t&&(a?(0,B.jsx)(wh,{preview:t,job:r,busy:s,onStart:()=>void f(),onPause:()=>void p()}):(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Open this page on the computer that runs OMMS to start a catch-up run.`)})),l&&(0,B.jsx)(`p`,{role:`alert`,children:l})]})}function Eh(){let e=Am(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)({}),[a,o]=(0,_.useState)(!1),[s,c]=(0,_.useState)(``);async function l(){let e=await $(`/api/settings/profiles`);n(e.profiles)}if((0,_.useEffect)(()=>{l().catch(e=>c(e.message))},[]),t.length<2)return null;let u=t=>Dm(o,async()=>{if(window.confirm(`${e(`Use this profile for every folder?`)} ${t.userId}`))try{let n=await Cm();await $(`/api/settings/profiles/use`,{method:`POST`,body:JSON.stringify({userId:t.userId,revision:n?.revision})}),await Cm(),await l(),c(e(`Saved. OMMS now uses this profile in every folder.`))}catch(e){c(e.message)}}),d=n=>Dm(o,async()=>{let i=t.find(e=>e.id===(r[n.id]??t.find(e=>e.id!==n.id)?.id));if(i&&window.confirm(`${e(`Merge this profile into the other one? The source profile is turned off, not deleted.`)}\n${n.userId} → ${i.userId}`))try{await $(`/api/settings/profiles/merge`,{method:`POST`,body:JSON.stringify({sourceId:n.id,targetId:i.id})}),await l(),c(e(`Merged.`))}catch(e){c(e.message)}});return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Profiles`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Profiles`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`OMMS keeps one profile for each git email. A folder whose repository has its own email starts a second profile. Choose the profile that is yours, or merge the extra one into it.`)}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:z(ph,`sr-only`),children:e(`Profiles`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{className:hh,children:e(`Email`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Preferences`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Patterns`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Workflows`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Prompts analysed`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Last update`)}),(0,B.jsx)(`th`,{className:hh,children:e(`Actions`)})]})}),(0,B.jsx)(`tbody`,{children:t.map(n=>(0,B.jsxs)(`tr`,{className:gh,children:[(0,B.jsxs)(`td`,{className:z(_h,`font-medium`),children:[n.userId,n.inUse&&(0,B.jsxs)(`span`,{className:`ms-2 text-xs text-green-700`,children:[`✅ `,e(`in use`)]})]}),(0,B.jsx)(`td`,{className:_h,children:n.preferences}),(0,B.jsx)(`td`,{className:_h,children:n.patterns}),(0,B.jsx)(`td`,{className:_h,children:n.workflows}),(0,B.jsx)(`td`,{className:_h,children:n.totalPromptsAnalyzed}),(0,B.jsx)(`td`,{className:_h,children:new Date(n.lastAnalyzedAt).toLocaleString()}),(0,B.jsxs)(`td`,{className:z(_h,`space-y-1`),children:[!n.inUse&&(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-1`,disabled:a,onClick:()=>void u(n),children:e(`Use this profile`)}),(0,B.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,B.jsx)(`label`,{className:`sr-only`,htmlFor:`merge-${n.id}`,children:e(`Merge into`)}),(0,B.jsx)(`select`,{id:`merge-${n.id}`,className:`rounded border border-border bg-background px-1 py-1 text-xs`,value:r[n.id]??``,onChange:e=>i(t=>({...t,[n.id]:e.target.value})),children:t.filter(e=>e.id!==n.id).map(e=>(0,B.jsx)(`option`,{value:e.id,children:e.userId},e.id))}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-1`,disabled:a,onClick:()=>void d(n),children:e(`Merge into`)})]})]})]},n.id))})]})}),s&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:s})]})}function Dh(e,t){let n={...t},r=0,i=0;for(let t of e)t.directory===``||n[t.directory]?.accepted||(t.suggestion?(n[t.directory]={directory:t.directory,target:t.suggestion,accepted:!0},r++):i++);return{decisions:n,filled:r,notFilled:i}}function Oh(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(),[a,o]=(0,_.useState)(new Set),[s,c]=(0,_.useState)({}),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(!1),[p,m]=(0,_.useState)({}),h=()=>$(`/api/settings/import-maps`).then(e=>{i(e),o(new Set),c({})}).catch(e=>u(e.message));(0,_.useEffect)(()=>{let e=!0;$(`/api/settings`).then(t=>{e&&n(t)}).catch(t=>{e&&u(t.message)}),h();let t=wm(t=>{e&&n(t)});return()=>{e=!1,t()}},[]);function g(t,n){let r=Dh(n,s);c(r.decisions),m(n=>({...n,[t]:`${e(`Filled`)}: ${r.filled} · ${e(`No suggestion`)}: ${r.notFilled}. ${e(`Check them, then press Save maps.`)}`}))}function v(e,t){c(n=>{let r=n[e.directory]??{directory:e.directory,target:e.suggestion??``,accepted:!1};return{...n,[e.directory]:{...r,...t}}})}async function y(){if(!t||!r)return;let n=Fm(r.saved,a,Object.values(s));f(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:{importPathMaps:n},revision:t.revision})}),u(e(`Saved. Maps apply to the next import or backfill run.`))}catch(e){u(e.message)}await Cm(),await h(),f(!1)}return(0,B.jsxs)(`section`,{id:`directory-maps`,className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Directory maps`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Directory maps`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Map a directory that was moved or deleted to the project it belongs to. A change applies to the next import or backfill run.`)}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Saved maps`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Saved maps apply to every host.`)}),!r?.saved.length&&(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`none`)}),(0,B.jsx)(`ul`,{className:`space-y-1 text-sm`,children:r?.saved.map(t=>(0,B.jsxs)(`li`,{className:`flex flex-wrap items-center gap-2`,children:[(0,B.jsxs)(`span`,{className:a.has(t.from)?`line-through`:``,children:[(0,B.jsx)(`code`,{children:t.from}),` → `,(0,B.jsx)(`code`,{children:t.to})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-2 py-0.5 text-xs`,onClick:()=>o(e=>{let n=new Set(e);return n.has(t.from)?n.delete(t.from):n.add(t.from),n}),children:a.has(t.from)?e(`Keep`):e(`Remove`)})]},t.from))}),[`pi`,`opencode`,`claude-code`].map(t=>{let n=r?.[t]??[],i=n.filter(e=>e.directory!==``);return(0,B.jsxs)(`div`,{className:`space-y-2 rounded-lg border border-border p-3`,children:[(0,B.jsxs)(`h3`,{className:`font-medium`,children:[Lm(t),`: `,e(`Unresolved directories`)]}),n.length===0?(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`No unresolved directories in the latest run.`)}):(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d||i.length===0,onClick:()=>g(t,n),children:e(`Smart resolve directories`)}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Finds the project each missing directory belongs to, mostly the main repository of a deleted worktree, and fills it in for you to check. Nothing is saved until you press Save maps.`)}),p[t]&&(0,B.jsx)(`p`,{role:`status`,className:`text-xs`,children:p[t]})]}),n.map(t=>{if(t.directory===``)return(0,B.jsxs)(`div`,{className:`rounded-lg border border-dashed border-border p-2 text-sm text-muted-foreground`,children:[e(`No directory recorded`),` ·`,` `,t.sessions===1?e(`1 session`):`${t.sessions} ${e(`sessions`)}`,` ·`,` `,e(`These sessions cannot be mapped.`)]},`no-directory`);let n=s[t.directory],r=n?.target??t.suggestion??``;return(0,B.jsxs)(`div`,{className:`space-y-1 rounded-lg border border-border p-2 text-sm`,children:[(0,B.jsxs)(`p`,{children:[(0,B.jsx)(`code`,{children:t.directory}),` ·`,` `,t.sessions===1?e(`1 session`):`${t.sessions} ${e(`sessions`)}`]}),!t.suggestion&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`No suggestion found.`)}),(0,B.jsx)(`input`,{"aria-label":`${t.directory} ${e(`Target directory`)}`,className:`w-full rounded border border-border bg-background p-2`,placeholder:e(`Target directory`),value:r,onChange:e=>v(t,{target:e.target.value})}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:n?.accepted??!1,onChange:e=>v(t,{accepted:e.target.checked})}),e(`Use this map`)]})]},t.directory)})]},t)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:d||!t||!r,onClick:()=>void y(),children:e(`Save maps`)}),l&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:l})]})}var kh=[`opencode`,`pi`,`claude-code`];function Ah(e){return!e.provider&&!e.model?null:`${e.provider??``}/${e.model??``}`}function jh(e){let t=new Map;for(let n of e){let e=t.get(n.host)??{host:n.host,total:0,saved:0,skipped:0,failed:0,models:[]};e.total+=n.total,e.saved+=n.saved,e.skipped+=n.skipped,e.failed+=n.failed;let r=Ah(n),i=e.models.find(e=>e.label===r);i?(i.total+=n.total,i.saved+=n.saved,i.skipped+=n.skipped,i.failed+=n.failed):e.models.push({label:r,provider:n.provider,model:n.model,total:n.total,saved:n.saved,skipped:n.skipped,failed:n.failed}),t.set(n.host,e)}let n=e=>{let t=kh.indexOf(e);return t<0?kh.length:t};return[...t.values()].map(e=>({...e,models:e.models.sort((e,t)=>t.total-e.total)})).sort((e,t)=>n(e.host)-n(t.host))}function Mh(e,t){return t>0?Math.round(100*e/t):0}function Nh(e){let t=new Map;for(let n of e){let e=`${n.host}\u0000${n.reason}`,r=t.get(e)??{host:n.host,reason:n.reason,count:0};r.count+=n.count,t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count)}function Ph({row:e}){return(0,B.jsxs)(B.Fragment,{children:[[e.saved,e.skipped,e.failed].map((t,n)=>(0,B.jsxs)(`td`,{className:z(_h,`text-end tabular-nums`),children:[t,` `,(0,B.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[Mh(t,e.total),`%`]})]},n)),(0,B.jsx)(`td`,{className:z(_h,`text-end font-medium tabular-nums`),children:e.total})]})}function Fh(e,t){return`/api/settings/diagnostics?days=${e}${t===`all`?``:`&host=${t}`}`}function Ih(){let e=Am(),[t,n]=(0,_.useState)(7),[r,i]=(0,_.useState)(`all`),[a,o]=(0,_.useState)(()=>new Set),[s,c]=(0,_.useState)(),[l,u]=(0,_.useState)([]),[d,f]=(0,_.useState)(),[p,m]=(0,_.useState)(``),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(``),[b]=(0,_.useState)(Em),x=(0,_.useCallback)(async(e,t)=>{let n=Sm(),r=b.begin();try{let[i,a,o]=await Promise.all([$(Fh(e,t)),$(`/api/settings/traces`),$(`/api/settings`)]);if(!r())return;c(i),u(a.traces),n.isCurrent()&&f(o),g(``)}catch(e){if(!r())return;g(e.message)}},[b]);(0,_.useEffect)(()=>{x(t,r)},[t,r,x]),(0,_.useEffect)(()=>wm(e=>f(e)),[]);async function S(n){if(!d)return;let i;try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({revision:d.revision,edits:n})})}catch(e){i=e}let a=await Cm()!==null;if(!i){y(``),await x(t,r),a||g(e(`Reload the page before saving again.`));return}g(Tm(i.message,e(a?`Current settings were reloaded; check the values and save again.`:`The current settings could not be reloaded. Reload the page.`)))}async function C(e){try{let t=await $(`/api/settings/traces/${encodeURIComponent(e)}`);m(t.content)}catch(e){g(e.message)}}async function w(n){if(window.confirm(`${e(`Delete`)} ${n}?`))try{await $(`/api/settings/traces/${encodeURIComponent(n)}`,{method:`DELETE`}),m(``),await x(t,r)}catch(e){g(e.message)}}async function T(n){try{let{result:i}=await $(`/api/settings/capture-retry/${n}/run`,{method:`POST`,body:`{}`});y(e(i===`scheduled`?n===`pi`?`These turns retry at the next Pi session start.`:n===`claude-code`?`These turns retry at the next Claude Code session start.`:`These turns retry at the next OpenCode session start.`:i===`running`?`A retry is already running.`:`Retrying now.`)),await x(t,r)}catch(e){g(e.message)}}let E=d?.settings.captureTrace,ee=Number(d?.settings.captureRetryRetentionHours?.value??72);return(0,B.jsxs)(`section`,{className:`space-y-4 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Capture diagnostics`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Capture diagnostics`)}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2 pb-2 text-sm`,children:[e(`Time range`),(0,B.jsxs)(fn,{"aria-label":e(`Time range`),className:`rounded-lg border border-border bg-background px-2 py-1`,value:t,onChange:e=>n(Number(e.target.value)),children:[(0,B.jsx)(`option`,{value:1,children:e(`24 hours`)}),(0,B.jsx)(`option`,{value:7,children:e(`7 days`)}),(0,B.jsx)(`option`,{value:30,children:e(`30 days`)}),(0,B.jsx)(`option`,{value:90,children:e(`90 days`)})]}),e(`Host`),(0,B.jsxs)(fn,{"aria-label":e(`Host`),className:`rounded-lg border border-border bg-background px-2 py-1`,value:r,onChange:e=>i(e.target.value),children:[(0,B.jsx)(`option`,{value:`all`,children:e(`All`)}),[`opencode`,`pi`,`claude-code`].map(e=>(0,B.jsx)(`option`,{value:e,children:Lm(e)},e))]})]}),h&&(0,B.jsx)(`p`,{role:`alert`,children:h}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Saved: a memory was stored. Skipped: the model or a rule found nothing worth keeping, or the turn was private or trivial. Failed: the attempt hit an error. Total: the three added up. Each percentage is a share of its row's total.`)}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Outcomes by host`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsx)(`tr`,{children:[`Host / model`,`Saved`,`Skipped`,`Failed`,`Total`].map((t,n)=>(0,B.jsx)(`th`,{scope:`col`,className:z(hh,n>0&&`text-end`),children:e(t)},t))})}),(0,B.jsx)(`tbody`,{children:jh(s?.byModel??[]).map(t=>{let n=a.has(t.host);return(0,B.jsxs)(_.Fragment,{children:[(0,B.jsxs)(`tr`,{className:z(gh,`font-medium`),children:[(0,B.jsx)(`td`,{className:_h,children:(0,B.jsxs)(`button`,{type:`button`,className:`inline-flex items-center gap-1`,"aria-expanded":n,onClick:()=>o(e=>{let r=new Set(e);return n?r.delete(t.host):r.add(t.host),r}),children:[(0,B.jsx)(`span`,{"aria-hidden":!0,children:n?`▾`:`▸`}),Rm(t.host),(0,B.jsxs)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:[`(`,t.models.length,` `,e(t.models.length===1?`model`:`models`),`)`]})]})}),(0,B.jsx)(Ph,{row:t})]}),n&&t.models.map(n=>(0,B.jsxs)(`tr`,{className:`border-t border-border transition-colors hover:bg-muted/30`,children:[(0,B.jsx)(`td`,{className:z(`px-3 py-1.5`,`ps-8`),children:n.label?(0,B.jsx)(`span`,{className:`font-mono text-xs`,children:n.label}):(0,B.jsx)(`span`,{className:`text-xs italic text-muted-foreground`,title:e(`No model was recorded for these attempts. This happens with records written by older OMMS versions, and when an attempt stops before a model is chosen.`),children:e(`model not recorded`)})}),(0,B.jsx)(Ph,{row:n})]},`${t.host}-${n.label??`none`}`))]},t.host)})})]})}),(0,B.jsx)(`div`,{className:fh,children:(0,B.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Failure reasons`)}),(0,B.jsx)(`thead`,{className:mh,children:(0,B.jsxs)(`tr`,{children:[(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(`Host`)}),(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(`Reason`)}),(0,B.jsx)(`th`,{scope:`col`,className:z(hh,`text-end`),children:e(`Total`)})]})}),(0,B.jsx)(`tbody`,{children:Nh(s?.byReason??[]).map((e,t)=>(0,B.jsxs)(`tr`,{className:gh,children:[(0,B.jsx)(`td`,{className:z(_h,`text-muted-foreground`),children:Rm(e.host)}),(0,B.jsx)(`td`,{className:z(_h,`font-mono text-xs`),children:e.reason}),(0,B.jsx)(`td`,{className:z(_h,`text-end tabular-nums`),children:e.count})]},`${e.host}-${e.reason}-${t}`))})]})}),(0,B.jsx)(`div`,{className:z(fh,`max-h-72 overflow-y-auto`),children:(0,B.jsxs)(`table`,{className:`w-full min-w-max text-sm`,children:[(0,B.jsx)(`caption`,{className:ph,children:e(`Recent attempts`)}),(0,B.jsx)(`thead`,{className:z(mh,`sticky top-0`),children:(0,B.jsx)(`tr`,{children:[`Time`,`Host`,`Source`,`Session`,`Path`,`Model`,`Stop`,`Blocks`,`Prompt`,`Reply`,`Duration`,`Outcome`,`Reason`].map(t=>(0,B.jsx)(`th`,{scope:`col`,className:hh,children:e(t)},t))})}),(0,B.jsx)(`tbody`,{children:s?.recent.map((e,t)=>(0,B.jsx)(`tr`,{className:gh,children:[new Date(e.timestamp).toLocaleString(),Rm(e.host),e.sourceType,e.sessionId,e.path,`${e.provider??``}/${e.model??``}`,e.stopReason,e.blockTypes?.join(`, `),e.promptChars,e.replyChars,e.durationMs,e.outcome,e.reason].map((e,t)=>(0,B.jsx)(`td`,{className:z(_h,`whitespace-nowrap`),children:e??``},t))},`${e.timestamp}-${t}`))})]})}),(0,B.jsxs)(`div`,{className:`space-y-2 border-t border-border pt-3 text-sm`,children:[(0,B.jsxs)(`label`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:E?.value===!0,disabled:!d,onChange:t=>{t.target.checked&&!window.confirm(e(`Traces can contain conversation content after redaction. Keep tracing off unless you need it for debugging.`))||S({captureTrace:t.target.checked})}}),` `,e(`Save capture traces`)]}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Traces can contain conversation content after redaction. Keep tracing off unless you need it for debugging.`)}),E?.source===`project`&&(0,B.jsx)(`p`,{className:`text-xs text-amber-600`,children:e(`This project turns tracing off. The global switch cannot turn it on here.`)}),[`captureTraceRetentionDays`,`captureAttemptRetentionDays`].map(t=>(0,B.jsxs)(`label`,{className:`block`,children:[e(t===`captureTraceRetentionDays`?`Trace retention (days)`:`Attempt retention (days)`),` `,(0,B.jsx)(`input`,{type:`number`,min:1,className:`ms-2 w-20 rounded border border-border bg-background p-1`,defaultValue:Number(d?.settings[t]?.value??30),onBlur:e=>{let n=Number(e.target.value);Number.isSafeInteger(n)&&n>0&&n!==d?.settings[t]?.value&&S({[t]:n})}},`${t}-${d?.settings[t]?.value}`)]},t)),(0,B.jsxs)(`label`,{className:`block`,children:[e(`Retry retention (hours)`),` `,(0,B.jsx)(`input`,{type:`number`,min:0,max:720,className:`ms-2 w-20 rounded border border-border bg-background p-1`,defaultValue:ee,onBlur:e=>{let t=Number(e.target.value);Number.isSafeInteger(t)&&t>=0&&t<=720&&t!==ee&&S({captureRetryRetentionHours:t})}},`captureRetryRetentionHours-${ee}`)]}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`When the capture model cannot be reached, OMMS keeps the turn and tries again later. Queued turns can hold conversation content after redaction. 0 turns the queue off and deletes waiting turns.`)}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Turns waiting for retry`)}),[`pi`,`opencode`,`claude-code`].map(t=>{let n=s?.retryQueue?.[t]??0;return(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsx)(`span`,{className:`w-24`,children:Lm(t)}),(0,B.jsx)(`span`,{className:`tabular-nums`,children:n}),(0,B.jsx)(`button`,{type:`button`,disabled:n===0||ee===0,className:`disabled:opacity-50`,onClick:()=>void T(t),children:e(`Retry now`)})]},t)}),v&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:v}),(0,B.jsx)(`h3`,{className:`font-medium`,children:e(`Trace files`)}),l.map(t=>(0,B.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,B.jsxs)(`span`,{children:[t.file,` (`,t.size,` bytes)`]}),(0,B.jsx)(`button`,{type:`button`,onClick:()=>void C(t.file),children:e(`View`)}),(0,B.jsx)(`button`,{type:`button`,onClick:()=>void w(t.file),children:e(`Delete`)})]},t.file)),p&&(0,B.jsx)(`pre`,{className:`max-h-60 overflow-auto whitespace-pre-wrap break-words rounded bg-background p-2 text-xs`,children:p})]})]})}function Lh(){let e=Am(),[t,n]=(0,_.useState)([]),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(``);async function s(e){i(!0);try{let t=await $(`/api/settings/health`,{method:`POST`,body:JSON.stringify({testModels:e})});n(t.checks),o(``)}catch(e){o(e.message)}finally{i(!1)}}return(0,B.jsxs)(`section`,{id:`settings-health`,className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Health`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Health`)}),(0,B.jsxs)(`div`,{className:`flex gap-2`,children:[(0,B.jsx)(`button`,{className:`rounded-lg border border-border px-3 py-1.5 text-sm`,disabled:r,onClick:()=>void s(!1),children:e(`Run checks`)}),(0,B.jsx)(`button`,{className:`rounded-lg border border-border px-3 py-1.5 text-sm`,disabled:r,onClick:()=>void s(!0),children:e(`Run checks and test models`)})]}),r&&(0,B.jsx)(`p`,{role:`status`,children:e(`Checking…`)}),a&&(0,B.jsx)(`p`,{role:`alert`,children:a}),(0,B.jsx)(`ul`,{className:`space-y-2 text-sm`,children:t.map(t=>(0,B.jsxs)(`li`,{className:`rounded-lg border border-border p-2`,children:[(0,B.jsx)(`strong`,{className:t.status===`fail`?`text-red-600`:t.status===`warn`?`text-amber-600`:`text-green-600`,children:e(t.status).toUpperCase()}),` `,`· `,e(t.check),`: `,t.reason]},t.check))})]})}function Rh(e){let t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);return t?[Number(t[1]),Number(t[2])-1,Number(t[3])]:null}function zh(e){let t=Rh(e);return t?new Date(t[0],t[1],t[2],0,0,0,0).getTime():void 0}function Bh(e){let t=Rh(e);return t?new Date(t[0],t[1],t[2],23,59,59,999).getTime():void 0}function Vh(e,t,n){let r=!n&&e!==null&&e.revision===t.revision;return{page:r?{...t,listedAt:e.listedAt}:t,sameListing:r}}function Hh(e){let t=Am(),[n,r]=(0,_.useState)(``),[i,a]=(0,_.useState)(null),[o,s]=(0,_.useState)(null),[c,l]=(0,_.useState)(!1),[u,d]=(0,_.useState)(``),f=`rounded border border-border px-3 py-1.5 text-sm disabled:opacity-50`;async function p(t){try{let n=await $(`/api/settings/imports/sources/validate`,{method:`POST`,body:JSON.stringify({host:e.host,path:t})});a(n),r(n.displayPath),e.onChoose(n),d(``)}catch(e){d(e.message)}}async function m(t){try{let n=await $(`/api/settings/imports/sources/browse`,{method:`POST`,body:JSON.stringify({host:e.host,...t?{path:t}:{}})});s(n),d(``)}catch(e){let t=e.message;/loopback/i.test(t)&&l(!0),d(t)}}function h(){a(null),r(``),s(null),e.onChoose(null)}return(0,B.jsxs)(`div`,{className:`space-y-2 text-sm`,children:[(0,B.jsxs)(`label`,{className:`block`,children:[e.host===`pi`?t(`Pi sessions folder or one .jsonl session file`):e.host===`claude-code`?t(`Claude Code transcripts folder`):t(`OpenCode database file`),(0,B.jsx)(`input`,{className:`mt-1 block w-full rounded border border-border bg-background p-2 font-mono`,value:n,placeholder:t(`Absolute path, for example on a mounted volume`),onChange:e=>r(e.target.value)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:f,disabled:!n.trim(),onClick:()=>void p(n.trim()),children:t(`Use this source`)}),!c&&(0,B.jsx)(`button`,{type:`button`,className:f,onClick:()=>void m(o?.path),children:t(`Browse`)}),i&&(0,B.jsx)(`button`,{type:`button`,className:f,onClick:h,children:t(`Use the default location`)})]}),i&&(0,B.jsxs)(`p`,{role:`status`,children:[t(`Chosen source`),`: `,(0,B.jsx)(`span`,{className:`font-mono`,children:i.displayPath})]}),u&&(0,B.jsx)(`p`,{role:`alert`,children:u}),o&&(0,B.jsxs)(`div`,{className:`rounded border border-border p-2`,children:[(0,B.jsx)(`p`,{className:`font-mono text-xs break-all`,children:o.path}),(0,B.jsxs)(`ul`,{className:`max-h-60 overflow-auto`,children:[o.parent&&(0,B.jsx)(`li`,{children:(0,B.jsx)(`button`,{type:`button`,className:`underline`,onClick:()=>void m(o.parent),children:`..`})}),o.entries.map(n=>(0,B.jsxs)(`li`,{className:`flex items-center gap-2`,children:[n.kind===`folder`?(0,B.jsxs)(`button`,{type:`button`,className:`underline`,onClick:()=>void m(n.path),children:[n.name,`/`]}):(0,B.jsx)(`span`,{className:`font-mono text-xs`,children:n.name}),(n.kind!==`folder`||e.host!==`opencode`)&&(0,B.jsx)(`button`,{type:`button`,className:`text-xs underline`,onClick:()=>void p(n.path),children:t(`Choose`)})]},n.path))]}),o.truncated&&(0,B.jsx)(`p`,{className:`text-xs`,children:t(`Only the first 500 entries are shown.`)})]})]})}function Uh(e){return Object.values(e).some(e=>e?.state===`running`)}function Wh(e){return!e||e.total<=0?null:{percent:e.percent,done:`${e.done.toLocaleString(`en-US`)} / ${e.total.toLocaleString(`en-US`)}`,minutesLeft:e.minutesLeft===null?`unknown`:`about ${e.minutesLeft}`}}function Gh(e,t){let n=e?.state===`running`,r=e?.paused===!0;return{runNow:!n&&!r&&!t,pause:n&&!r,resume:r&&!t}}function Kh(e,t){return e??!t}function qh(e,t){let n=t.indexOf(`/`);if(t!==`inherit`&&t!==`external`&&(n<1||n===t.length-1))throw Error(`Enter a model as provider/model.`);return{[`${e}BackfillModel`]:t}}function Jh(e,t){if(t?.state===`running`)return t.phase===`profile`?{kind:`learning-profile`,done:t.profileDone??0,total:t.profileTotal??0}:{kind:`running`};if(t?.paused)return{kind:`paused`};if(!e||e.state===`not-started`)return t?.state===`done`?{kind:`imported`}:{kind:`not-started`};let n=t?.state===`done`&&(e.counts.failed??0)>0;return e.state===`failed`&&!n?{kind:`failed`,error:e.error}:e.state===`running`?{kind:`running`}:e.counts.pending>0?{kind:`stopped`,pending:e.counts.pending}:e.counts.unresolved>0?{kind:`partly`,unresolved:e.counts.unresolved}:{kind:`imported`}}function Yh(e){return e?.state===`running`&&e.phase!==`profile`}function Xh(e){return!e||e.state===`running`||!e.state||!e.updatedAt||!e.surface?null:{finishedAt:e.updatedAt,surface:e.surface,imported:e.imported??0,skipped:e.skipped??0,failed:e.failed??0,state:e.state}}function Zh({badge:e}){let t=Am(),[n,r]=(()=>{switch(e.kind){case`imported`:return[`${t(`Imported`)} ✅`,`border-green-600/40 text-green-700`];case`partly`:return[`${t(`Partly imported`)} (${e.unresolved} ${t(`unresolved`)})`,`border-amber-500/50 text-amber-700`];case`running`:return[t(`Running`),`border-primary/50 text-primary`];case`learning-profile`:return[`${t(`Learning profile`)} ${e.done} / ${e.total}`,`border-primary/50 text-primary`];case`paused`:return[t(`Paused`),`border-border text-muted-foreground`];case`stopped`:return[`${t(`Stopped`)} (${e.pending} ${t(`pending`)})`,`border-amber-500/50 text-amber-700`];case`failed`:return[`${t(`Failed`)} ⛔️`,`border-red-600/40 text-red-700`];case`not-started`:return[t(`Not started`),`border-border text-muted-foreground`]}})();return(0,B.jsx)(`span`,{className:z(`inline-block rounded-full border px-2 py-0.5 text-xs font-medium`,r),title:e.kind===`failed`&&e.error?e.error:void 0,children:n})}var Qh=[`pi`,`opencode`,`claude-code`];function $h(){let e=Am(),[t,n]=(0,_.useState)({}),[r,i]=(0,_.useState)({});return(0,_.useEffect)(()=>{let e=()=>{$(`/api/settings/backfill`).then(n).catch(()=>{}),$(`/api/settings/backfill/runs`).then(i).catch(()=>{})};e();let t=setInterval(e,1e4);return()=>clearInterval(t)},[]),(0,B.jsx)(`div`,{className:`flex flex-wrap gap-2`,"aria-label":e(`Import status`),children:Qh.map(e=>(0,B.jsxs)(`div`,{className:`flex items-center gap-2 rounded-lg border border-border px-3 py-1.5 text-sm`,children:[(0,B.jsx)(`span`,{className:`font-medium`,children:Lm(e)}),(0,B.jsx)(Zh,{badge:Jh(t[e]??null,r[e]?.run??null)})]},e))})}var eg=50,tg=1e3,ng={"missing-model":`The external API has no memoryModel in the global config`,"missing-url":`The external API has no memoryApiUrl in the global config`,"missing-key":`The external API key is missing in the OpenCode process; check memoryApiKey and its env:// or file:// source`,"unsupported-provider":`The memoryProvider in the global config is not supported for imports`},rg=()=>({mode:`ids`,picked:new Map});function ig(e,t){return e.split(`
124
124
  `).map(e=>e.trim()).filter(Boolean).map(e=>{let n=e.indexOf(`=`);if(n<1||n===e.length-1)throw Error(t);return{from:e.slice(0,n),to:e.slice(n+1)}})}function ag(e){return wm(()=>e())}function og(e,t){let n=e&&e.external.state!==`ready`;return`${t(`Saved external API`)}${n?` — ${t(`not ready`)}`:``}`}function sg(){let e=Am(),[t,n]=(0,_.useState)(`pi`),[r,i]=(0,_.useState)(null),[a,o]=(0,_.useState)(`current-project`),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(``),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(``),[h,g]=(0,_.useState)(``),[v,y]=(0,_.useState)(!1),[b,x]=(0,_.useState)(!1),[S,C]=(0,_.useState)(!1),[w,T]=(0,_.useState)(!1),[E,ee]=(0,_.useState)(null),[D,te]=(0,_.useState)(``),[O,ne]=(0,_.useState)(!1),[re,ie]=(0,_.useState)(!1),[k,ae]=(0,_.useState)(rg),[A,j]=(0,_.useState)(null),[oe,se]=(0,_.useState)(``),ce=t===`claude-code`&&oe!==`external`?``:oe,[M,N]=(0,_.useState)(null),[P,le]=(0,_.useState)(``);(0,_.useEffect)(()=>($(`/api/settings/imports/readiness`).then(e=>{j(e);let t=e.opencode.models[0];se(t?`${t.provider}/${t.model}`:e.external.state===`ready`?`external`:``)}).catch(()=>j(null)),$(`/api/settings/imports/current`).then(e=>N(e.job)).catch(()=>{}),ag(()=>{$(`/api/settings/imports/readiness`).then(j).catch(()=>j(null))})),[]),(0,_.useEffect)(()=>{if(M?.state!==`running`&&M?.state!==`cancelling`)return;let e=setInterval(()=>{$(`/api/settings/imports/current`).then(e=>N(e.job)).catch(e=>le(e.message))},1e3);return()=>clearInterval(e)},[M?.state]);let ue=JSON.stringify([t,r?.sourceToken,a,s,l]),de=!!E&&(O||ue!==D);function fe(){let n=ig(l,e(`Directory maps must be old=new, one per line`));return{host:t,...r?{source:r.sourceToken}:{},scope:a,...a===`current-project`&&s?{project:s}:{},pathMaps:n}}async function pe(e,t){ie(!0);try{let n=await $(`/api/settings/imports/sessions`,{method:`POST`,body:JSON.stringify({...fe(),offset:e,limit:eg,refresh:t})}),r=Vh(E,n,t);r.sameListing||ae(rg()),ee(r.page),te(ue),ne(!1),le(``)}catch(e){le(e.message)}finally{ie(!1)}}let F=E?E.total-(a===`all-projects`?E.unresolvedCount:0):0,me=k.mode===`all`?F-k.excluded.size:k.picked.size,he=e=>k.mode===`all`?!k.excluded.has(e.key):k.picked.has(e.key);function ge(e){if(!(!e.selectable||!e.directory)){if(k.mode===`all`){let t=new Set(k.excluded);t.has(e.key)?t.delete(e.key):t.add(e.key),ae({mode:`all`,excluded:t})}else{let t=new Map(k.picked);t.has(e.key)?t.delete(e.key):t.set(e.key,e.directory),ae({mode:`ids`,picked:t})}}}let _e=!b||!S,ve=t===`pi`&&A?.piReader.available===!1,ye=_e?A?ce?ce===`external`&&A.external.state!==`ready`?e(ng[A.external.state]??`The external API is not ready`):null:e(t===`claude-code`?`Claude Code imports use the external API. Complete the external API settings.`:`No import model is ready. Connect a model in OpenCode or complete the external API settings.`):e(`Model readiness is unknown. Reload the page.`):null,be=E?de?e(`Options changed. Refresh the session list first.`):me===0?e(`Select at least one session.`):k.mode===`ids`&&k.picked.size>tg?e(`Select at most 1000 sessions one by one, or use Select all matching.`):null:e(`List sessions first.`),xe=M?.state===`running`||M?.state===`cancelling`;async function Se(n){if(E)try{let r=d?zh(d):void 0,i=p?Bh(p):void 0,o={host:t,source:E.source.sourceToken,selection:k.mode===`all`?{mode:`all`,excludedKeys:[...k.excluded],revision:E.revision,listedAt:E.listedAt}:{mode:`ids`,sessions:[...k.picked].map(([e,t])=>({key:e,directory:t})),listedAt:E.listedAt},options:{dryRun:n,force:v,skipMemories:b,skipProfile:S,scope:a,...a===`current-project`&&s?{project:s}:{},...r===void 0?{}:{since:r},...i===void 0?{}:{until:i},...h?{profileBatch:Number(h)}:{},pathMaps:ig(l,e(`Directory maps must be old=new, one per line`))},...ce?{modelChoice:ce}:{}},c=await $(`/api/settings/imports`,{method:`POST`,body:JSON.stringify(o)});N(c),le(``)}catch(e){let t=e.message;/out of date|changed|no longer/i.test(t)&&ne(!0),le(t)}}async function Ce(){try{let e=await $(`/api/settings/imports/current/cancel`,{method:`POST`,body:`{}`});N(e.job)}catch(e){le(e.message)}}function we(){o(`all-projects`),T(!0)}let Te={recorded:e(`recorded`),mapped:e(`mapped`),worktree:e(`project root`),unresolved:e(`missing`)},Ee=`mt-1 block w-full rounded border border-border bg-background p-2`,De=`rounded border border-border px-3 py-1.5 text-sm disabled:opacity-50`;return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Import and backfill`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Import and backfill`)}),(0,B.jsx)($h,{}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3`,children:[(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`History host`),(0,B.jsxs)(fn,{"aria-label":e(`History host`),className:Ee,value:t,onChange:e=>{let t=e.target.value;n(t),t===`claude-code`&&A?.external.state===`ready`&&se(`external`),i(null),ee(null),ae(rg())},children:[(0,B.jsx)(`option`,{value:`pi`,children:`Pi`}),(0,B.jsx)(`option`,{value:`opencode`,children:`OpenCode`}),(0,B.jsx)(`option`,{value:`claude-code`,children:`Claude Code`})]})]}),(0,B.jsx)(`button`,{type:`button`,className:De,disabled:re,onClick:()=>void pe(0,!0),children:e(E?`Refresh list`:`List sessions`)}),(0,B.jsx)(`button`,{type:`button`,className:De,onClick:()=>T(!w),children:e(w?`Hide advanced options`:`Advanced options`)})]}),(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e(`Source`),`: `,r?.displayPath??E?.source.displayPath??e(`default location`),` · `,e(a===`current-project`?`Current project`:`All projects`)]}),ve&&(0,B.jsx)(`p`,{role:`alert`,children:A?.piReader.reason}),t===`claude-code`&&A?.claudeCode&&(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e(`Claude Code transcripts`),`:`,` `,(0,B.jsx)(`span`,{className:`font-mono break-all`,children:A.claudeCode.defaultRoot}),` (`,A.claudeCode.defaultRootFound?e(`found`):e(`not found`),`).`,` `,e(`Claude Code imports always use the external API.`)]}),w&&(0,B.jsxs)(`div`,{className:`space-y-3 rounded-lg border border-border p-3`,children:[(0,B.jsx)(Hh,{host:t,onChoose:i}),(0,B.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`Scope`),(0,B.jsxs)(fn,{"aria-label":e(`Scope`),className:Ee,value:a,onChange:e=>o(e.target.value),children:[(0,B.jsx)(`option`,{value:`current-project`,children:e(`Current project`)}),(0,B.jsx)(`option`,{value:`all-projects`,children:e(`All projects`)})]})]}),a===`current-project`&&(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`Project directory`),(0,B.jsx)(`input`,{className:Ee,value:s,onChange:e=>c(e.target.value),placeholder:e(`Current directory`)})]}),(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`Prompt date from`),(0,B.jsx)(`input`,{type:`date`,className:Ee,value:d,onChange:e=>f(e.target.value)})]}),(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`Prompt date to`),(0,B.jsx)(`input`,{type:`date`,className:Ee,value:p,onChange:e=>m(e.target.value)})]}),(0,B.jsxs)(`label`,{className:`text-sm`,children:[e(`Profile batch size`),(0,B.jsx)(`input`,{inputMode:`numeric`,className:Ee,value:h,onChange:e=>g(e.target.value)})]})]}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Prompt dates are inclusive, use your time zone, and filter the turns inside each session, not the list. Empty dates include every turn.`)}),(0,B.jsxs)(`label`,{className:`block text-sm`,children:[e(`Directory maps (old=new, one per line)`),(0,B.jsx)(`textarea`,{className:Ee,rows:2,value:l,onChange:e=>u(e.target.value)})]}),(0,B.jsx)(`div`,{className:`flex flex-wrap gap-3 text-sm`,children:[[`Force reimport`,v,y],[`Skip memories`,b,x],[`Skip profile`,S,C]].map(([t,n,r])=>(0,B.jsxs)(`label`,{children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:n,onChange:e=>r(e.target.checked)}),` `,e(t)]},t))})]}),de&&E&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm text-amber-600`,children:e(`Options changed. Refresh the session list first.`)}),E&&a===`current-project`&&E.unresolvedCount>0&&(0,B.jsxs)(`p`,{className:`text-sm`,children:[e(`Sessions with directories that no longer exist`),`: `,E.unresolvedCount,`.`,` `,(0,B.jsx)(`button`,{type:`button`,className:`underline`,onClick:we,children:e(`Show them and add a directory map`)})]}),E&&(0,B.jsxs)(`div`,{className:`space-y-2`,children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2 text-sm`,children:[(0,B.jsxs)(`span`,{role:`status`,children:[e(`Selected`),`: `,me,` / `,F]}),(0,B.jsxs)(`button`,{type:`button`,className:De,disabled:F===0,onClick:()=>ae({mode:`all`,excluded:new Set}),children:[e(`Select all matching`),` (`,F,`)`]}),(0,B.jsx)(`button`,{type:`button`,className:De,onClick:()=>ae(rg()),children:e(`Clear selection`)})]}),(0,B.jsxs)(`div`,{className:`overflow-x-auto`,children:[(0,B.jsxs)(`table`,{className:`w-full text-left text-sm`,children:[(0,B.jsx)(`thead`,{children:(0,B.jsxs)(`tr`,{className:`text-muted-foreground`,children:[(0,B.jsx)(`th`,{className:`p-1`,children:(0,B.jsx)(`span`,{className:`sr-only`,children:e(`Select`)})}),(0,B.jsx)(`th`,{className:`p-1`,children:e(`Created`)}),(0,B.jsx)(`th`,{className:`p-1`,children:e(`Session`)}),(0,B.jsx)(`th`,{className:`p-1`,children:e(`Project directory`)}),(0,B.jsx)(`th`,{className:`p-1`,children:e(`Resolved by`)})]})}),(0,B.jsx)(`tbody`,{children:E.rows.map(t=>(0,B.jsxs)(`tr`,{className:`border-t border-border`,children:[(0,B.jsx)(`td`,{className:`p-1`,children:(0,B.jsx)(`input`,{type:`checkbox`,"aria-label":`${e(`Select`)} ${t.sessionId??t.key}`,checked:t.selectable&&he(t),disabled:!t.selectable,onChange:()=>ge(t)})}),(0,B.jsx)(`td`,{className:`p-1 whitespace-nowrap`,children:t.createdAt?new Date(t.createdAt).toLocaleString():`—`}),(0,B.jsx)(`td`,{className:`p-1 font-mono text-xs`,children:t.sessionId??t.key}),(0,B.jsx)(`td`,{className:`p-1 font-mono text-xs break-all`,children:t.directory??t.recordedDirectory??`—`}),(0,B.jsx)(`td`,{className:`p-1`,children:Te[t.via]})]},t.key))})]}),E.total===0&&(0,B.jsx)(`p`,{className:`text-sm`,children:e(`No sessions match.`)})]}),(0,B.jsxs)(`div`,{className:`flex items-center gap-2 text-sm`,children:[(0,B.jsx)(`button`,{type:`button`,className:De,disabled:re||E.offset===0,onClick:()=>void pe(Math.max(0,E.offset-eg),!1),children:e(`Previous`)}),(0,B.jsxs)(`span`,{children:[E.total?E.offset+1:0,`–`,Math.min(E.offset+eg,E.total),` /`,` `,E.total]}),(0,B.jsx)(`button`,{type:`button`,className:De,disabled:re||E.offset+eg>=E.total,onClick:()=>void pe(E.offset+eg,!1),children:e(`Next`)})]})]}),(0,B.jsxs)(`label`,{className:`block text-sm`,children:[e(`Import model`),(0,B.jsxs)(fn,{"aria-label":e(`Import model`),className:Ee,value:ce,onChange:e=>se(e.target.value),children:[(0,B.jsx)(`option`,{value:``,children:e(`None`)}),t!==`claude-code`&&A?.opencode.models.map(e=>(0,B.jsxs)(`option`,{value:`${e.provider}/${e.model}`,children:[e.name,` (`,e.provider,`/`,e.model,`)`]},`${e.provider}/${e.model}`)),(0,B.jsx)(`option`,{value:`external`,children:og(A,e)})]})]}),t!==`claude-code`&&A&&!A.opencode.available&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`An import with an OpenCode signed-in model runs from the terminal or with /import in OpenCode.`)}),(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e(`Configured, not tested.`),` `,(0,B.jsx)(`button`,{type:`button`,className:`underline`,onClick:()=>document.getElementById(`settings-health`)?.scrollIntoView(),children:e(`Test models in Health`)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:De,disabled:xe||ve||!!be,onClick:()=>void Se(!0),children:e(`Preview (dry run)`)}),(0,B.jsx)(`button`,{type:`button`,className:De,disabled:xe||ve||!!be||!!ye,onClick:()=>void Se(!1),children:e(`Start import`)}),xe&&(0,B.jsx)(`button`,{type:`button`,className:De,disabled:M?.state===`cancelling`,onClick:()=>void Ce(),children:e(`Cancel after current unit`)})]}),(be||ye)&&!xe&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:be??ye}),P&&(0,B.jsx)(`p`,{role:`alert`,children:P}),M&&(0,B.jsxs)(`div`,{role:`status`,className:`text-sm`,children:[M.host,` · `,M.dryRun?e(`Preview (dry run)`):e(`Import`),` · `,e(M.state),` ·`,` `,M.sessions===1?e(`1 session`):`${M.sessions} ${e(`sessions`)}`,` ·`,` `,M.processed,`/`,M.total,` `,e(`units`),M.error&&(0,B.jsx)(`p`,{role:`alert`,children:M.error}),M.report&&(0,B.jsx)(`pre`,{className:`mt-2 overflow-auto whitespace-pre-wrap rounded bg-background p-3 text-xs`,children:M.report})]})]})}var cg=[`pi`,`opencode`,`claude-code`];function lg(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)({pi:null,opencode:null,"claude-code":null}),[a,o]=(0,_.useState)(),[s,c]=(0,_.useState)({}),[l,u]=(0,_.useState)({}),[d,f]=(0,_.useState)({}),[p,m]=(0,_.useState)(``),[h,g]=(0,_.useState)(!1),v=Uh(r)||cg.some(e=>a?.[e]?.run?.state===`running`),y=()=>$(`/api/settings/backfill/runs`).then(o).catch(e=>m(e.message));(0,_.useEffect)(()=>{let e=!0;$(`/api/settings`).then(t=>{e&&n(t)}).catch(t=>{e&&m(t.message)}),$(`/api/settings/backfill`).then(t=>{e&&i(t)}).catch(t=>{e&&m(t.message)}),y();for(let t of[`pi`,`opencode`])$(`/api/settings/models?host=${t}`).then(n=>{e&&c(e=>({...e,[t]:n}))}).catch(()=>{e&&c(e=>({...e,[t]:{available:!1}}))});let t=wm(t=>{e&&n(t)});return()=>{e=!1,t()}},[]),(0,_.useEffect)(()=>{if(!v)return;let e=!0,t=setInterval(()=>{$(`/api/settings/backfill`).then(t=>{e&&i(t)}).catch(t=>{e&&m(t.message)}),e&&y()},3e3);return()=>{e=!1,clearInterval(t)}},[v]);async function b(n){if(t){g(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:n,revision:t.revision})}),m(e(`Saved. Changes apply at the next run.`))}catch(e){m(e.message)}await Cm(),g(!1)}}async function x(t,n){g(!0);try{await $(`/api/settings/backfill/${t}/${n}`,{method:`POST`,body:`{}`}),m(e(n===`pause`?`Pausing after the current exchange.`:`Backfill started.`))}catch(e){m(e.message)}await y(),g(!1)}function S(t,n){try{b(qh(t,n.trim()))}catch(t){m(e(t.message))}}return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Automatic import`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Automatic import`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Automatic import makes model calls. A model change applies at the next run. Turning it off stops a running import after the current exchange.`)}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:!!t?.settings.autoBackfill?.globalValue,disabled:h||!t,onChange:e=>void b({autoBackfill:e.target.checked})}),e(`Import past chats automatically`)]}),cg.map(n=>{let i=String(t?.settings[`${n}BackfillModel`]?.globalValue??`inherit`),o=l[n]??i,c=s[n]?.models??[],p=o===`inherit`||o===`external`||c.some(e=>`${e.provider}/${e.model}`===o),m=Mm({memoryProvider:t?.settings.memoryProvider?.globalValue,memoryModel:t?.settings.memoryModel?.globalValue,memoryApiUrl:t?.settings.memoryApiUrl?.globalValue,keySet:!!t?.secrets?.memoryApiKey?.set}),g=a?.[n]?.run??null,_=a?.[n]?.runNowUnavailable??null,v=Gh(g,_),y=Yh(g)?Wh(g):null,b=Xh(g),C=Jh(r[n],g),w=Kh(d[n],p);return(0,B.jsxs)(`div`,{className:`space-y-2 rounded-lg border border-border p-3 text-sm`,children:[(0,B.jsxs)(`h3`,{className:`flex items-center gap-2 font-medium`,children:[Lm(n),` `,(0,B.jsx)(Zh,{badge:C})]}),n===`claude-code`?(0,B.jsx)(`p`,{className:`text-muted-foreground`,children:e(`Claude Code backfill always uses the external API. It has no backfill model setting.`)}):(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`label`,{className:`block`,children:[e(`Backfill model`),(0,B.jsxs)(fn,{"aria-label":`${Lm(n)} ${e(`Backfill model`)}`,className:`mt-1 block w-full rounded border border-border bg-background p-2`,value:w?`typed`:o,onChange:e=>{let t=e.target.value;f(e=>({...e,[n]:t===`typed`})),u(e=>({...e,[n]:t}))},children:[(0,B.jsx)(`option`,{value:`inherit`,children:e(`Same as live capture`)}),(0,B.jsx)(`option`,{value:`external`,disabled:m.length>0,children:e(`External API`)}),c.map(e=>(0,B.jsxs)(`option`,{value:`${e.provider}/${e.model}`,children:[e.name,` (`,e.provider,`/`,e.model,`)`]},`${e.provider}/${e.model}`)),(0,B.jsx)(`option`,{value:`typed`,children:e(`Manual provider/model`)})]})]}),w&&(0,B.jsx)(`input`,{"aria-label":`${n} ${e(`Manual provider/model`)}`,className:`w-full rounded border border-border bg-background p-2`,placeholder:`provider/model`,value:o===`typed`?``:o,onChange:e=>u(t=>({...t,[n]:e.target.value}))}),m.length>0&&(0,B.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[e(`External API needs`),`: `,m.join(`, `)]}),s[n]?.available===!1&&(0,B.jsx)(`p`,{children:s[n].reason?e(s[n].reason):e(`Model list unavailable. Enter provider/model manually.`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:h||!t,onClick:()=>S(n,o),children:e(`Save model`)})]}),(0,B.jsxs)(`p`,{children:[e(`State`),`:`,` `,g?.paused?e(`paused`):e(g?.state??r[n]?.state??`not started`),g?.state===`running`&&g.surface&&` (${e(`started from ${g.surface}`)})`]}),C.kind===`learning-profile`&&(0,B.jsxs)(`p`,{className:`text-muted-foreground`,children:[e(`All exchanges are done. Learning the profile from the imported prompts`),`:`,` `,C.done,` / `,C.total,` `,e(`batches`)]}),y&&(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(`div`,{role:`progressbar`,"aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":y.percent,className:`h-2 w-full overflow-hidden rounded bg-muted`,children:(0,B.jsx)(`div`,{className:`h-full bg-primary`,style:{width:`${y.percent}%`}})}),(0,B.jsxs)(`p`,{className:`text-muted-foreground`,children:[y.percent,`% · `,y.done,` · `,e(`Minutes left`),`:`,` `,y.minutesLeft===`unknown`?e(`unknown`):y.minutesLeft.replace(`about`,e(`about`))]})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:h||!v.runNow,onClick:()=>void x(n,`run`),children:e(`Run now`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:h||!v.pause,onClick:()=>void x(n,`pause`),children:e(`Pause`)}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5`,disabled:h||!v.resume,onClick:()=>void x(n,`resume`),children:e(`Resume`)})]}),_&&(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:_}),b&&(0,B.jsxs)(`p`,{className:`text-muted-foreground`,children:[e(`Last run`),`: `,new Date(b.finishedAt).toLocaleString(),` ·`,` `,e(`started from ${b.surface}`),` · `,e(b.state),` · `,e(`Imported`),`:`,` `,b.imported,` · `,e(`Skipped`),`: `,b.skipped,` · `,e(`Failed`),`:`,` `,b.failed]}),r[n]&&(0,B.jsxs)(`div`,{className:`space-y-1 text-muted-foreground`,children:[!b&&(0,B.jsxs)(`p`,{children:[e(`Imported`),`: `,r[n].counts.imported,` · `,e(`Skipped`),`:`,` `,r[n].counts.skipped,` · `,e(`Failed`),`: `,r[n].counts.failed]}),(0,B.jsxs)(`p`,{children:[e(`Pending`),`: `,r[n].counts.pending,` · `,e(`Unresolved sessions`),`:`,` `,r[n].counts.unresolved,r[n].counts.unresolved>0&&(0,B.jsxs)(B.Fragment,{children:[` `,(0,B.jsx)(`a`,{className:`underline`,href:`#settings-section-directory-maps`,children:e(`Directory maps`)})]})]}),(0,B.jsxs)(`p`,{children:[e(`Model`),`: `,r[n].model??e(`none`)]}),(0,B.jsxs)(`p`,{children:[e(`Cutoff`),`: `,new Date(r[n].cutoff).toLocaleString()]}),r[n].error&&(0,B.jsx)(`p`,{role:`alert`,children:r[n].error})]})]},n)}),p&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:p})]})}function ug(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(),[a,o]=(0,_.useState)(),[s,c]=(0,_.useState)(``),[l,u]=(0,_.useState)(!1);(0,_.useEffect)(()=>{let e=!0;$(`/api/settings`).then(t=>{e&&n(t)}).catch(t=>{e&&c(t.message)}),$(`/api/settings/web-autostart`).then(t=>{e&&i(t)}).catch(t=>{e&&c(t.message)}),$(`/api/settings/version`).then(t=>{e&&o(t)}).catch(()=>{});let t=wm(t=>{e&&n(t)});return()=>{e=!1,t()}},[]);async function d(n){if(t){u(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:{webServerAutoStart:n},revision:t.revision})}),c(e(`Saved. The login item changes at the next Pi or OpenCode start.`))}catch(e){c(e.message)}await Cm(),u(!1)}}return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Web app`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Web app`)}),(0,B.jsxs)(`label`,{className:`flex items-center gap-2 text-sm`,children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:!!t?.settings.webServerAutoStart?.globalValue,disabled:l||!t,onChange:e=>void d(e.target.checked)}),e(`Start web app at login`)]}),(0,B.jsxs)(`p`,{className:`text-sm`,children:[e(`Login item`),`: `,e(r?.state??`not installed`)]}),r?.state===`unsupported`&&(0,B.jsx)(`p`,{role:`status`,children:e(`Login items are unsupported on this platform.`)}),r?.state===`no-runtime`&&(0,B.jsx)(`p`,{role:`status`,children:e(`Install Node or Bun to start the web app at login.`)}),a&&(0,B.jsx)(dg,{info:a}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e(`Use these commands to apply the change now:`)}),(0,B.jsxs)(`div`,{className:`space-y-1 font-mono text-xs`,children:[(0,B.jsx)(`p`,{children:`om-memory-system web`}),(0,B.jsx)(`p`,{children:`om-memory-system web install`}),(0,B.jsx)(`p`,{children:`om-memory-system web uninstall`}),(0,B.jsx)(`p`,{children:`om-memory-system web status`})]}),s&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:s})]})}function dg({info:e}){let t=Am(),n=Pm(e);return(0,B.jsxs)(`div`,{className:`space-y-1 text-sm`,children:[(0,B.jsxs)(`p`,{children:[t(`Running version`),`: `,e.running,` · `,t(`Global command`),`:`,` `,e.global??t(`not installed globally`)]}),n.kind===`different`&&(0,B.jsx)(`p`,{role:`status`,className:`text-amber-600`,children:t(`The global command's version differs from the running OMMS. Upgrade it:`)}),n.command&&(0,B.jsx)(`p`,{className:`font-mono text-xs`,children:n.command}),(0,B.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:t(`A global install is optional but recommended: the login item and the terminal commands then run without npx.`)})]})}function fg(e){let t=e.trim();return t===``||t.startsWith(`~/`)||t.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(t)||t.startsWith(`\\\\`)}function pg(e,t,n){return n?t:typeof e==`string`?e:``}function mg(){let e=Am(),[t,n]=(0,_.useState)(),[r,i]=(0,_.useState)(``),[a,o]=(0,_.useState)(``),[s,c]=(0,_.useState)(!1),l=(0,_.useRef)(!1);(0,_.useEffect)(()=>{let e=!0,t=t=>{e&&(n(t),i(e=>pg(t.settings.claudeConfigDir?.globalValue,e,l.current)))},r=Sm();$(`/api/settings`).then(e=>{r.isCurrent()&&t(e)}).catch(t=>{e&&o(t.message)});let a=wm(e=>t(e));return()=>{e=!1,a()}},[]);async function u(){if(t){if(!fg(r)){o(e(`Enter a full path, or a path that starts with ~/.`));return}c(!0);try{await $(`/api/settings`,{method:`PATCH`,body:JSON.stringify({edits:{claudeConfigDir:r.trim()},revision:t.revision})}),l.current=!1,o(e(`Saved. Capture and import use this folder now.`))}catch(e){o(e.message)}await Cm(),c(!1)}}return(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Claude Code folder`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Claude Code folder`)}),(0,B.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:e(`Set this when Claude Code does not use ~/.claude, for example when you start it with CLAUDE_CONFIG_DIR. Leave it empty to use the default.`)}),(0,B.jsxs)(`label`,{className:`block space-y-1 text-sm`,children:[(0,B.jsx)(`span`,{children:e(`Claude Code folder`)}),(0,B.jsx)(`input`,{className:`w-full rounded border border-border bg-background p-2 font-mono`,placeholder:`~/.claude`,value:r,disabled:s||!t,onChange:e=>{l.current=!0,i(e.target.value)}})]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded border border-border px-3 py-1.5 text-sm`,disabled:s||!t,onClick:()=>void u(),children:e(`Save folder`)}),(0,B.jsx)(hg,{folder:t?.claudeFolder}),a&&(0,B.jsx)(`p`,{role:`status`,className:`text-sm`,children:a})]})}function hg({folder:e}){let t=Am();if(!e)return null;let n={setting:t(`this setting`),env:t(`the CLAUDE_CONFIG_DIR variable of the web app`),default:t(`the default folder`)};return(0,B.jsxs)(`div`,{className:`space-y-1 text-sm`,children:[(0,B.jsxs)(`p`,{children:[t(`Transcripts folder in use`),`: `,(0,B.jsx)(`span`,{className:`font-mono`,children:e.root})]}),(0,B.jsxs)(`p`,{children:[t(`From`),`: `,n[e.source]]}),!e.exists&&(0,B.jsxs)(`p`,{role:`status`,className:`text-amber-600`,children:[t(`This folder does not exist. Claude Code capture and import will not work:`),` `,(0,B.jsx)(`span`,{className:`font-mono`,children:e.root})]})]})}function gg(){let e=Am(),[t,n]=(0,_.useState)(!1),[r,i]=(0,_.useState)(),[a,o]=(0,_.useState)(``);async function s(e){try{i(await $(`/api/settings/log?lines=200${e?`&filter=capture`:``}`)),o(``)}catch(e){o(e.message)}}return(0,_.useEffect)(()=>{s(t)},[t]),(0,B.jsxs)(`section`,{className:`space-y-3 rounded-xl border border-border bg-card p-4`,"aria-label":e(`Log`),children:[(0,B.jsx)(`h2`,{className:`text-lg font-medium`,children:e(`Log`)}),(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3 text-sm`,children:[(0,B.jsxs)(`label`,{children:[(0,B.jsx)(`input`,{type:`checkbox`,checked:t,onChange:e=>n(e.target.checked)}),` `,e(`Capture attempts only`)]}),(0,B.jsx)(`button`,{type:`button`,className:`rounded-lg border border-border px-3 py-1`,onClick:()=>void s(t),children:e(`Refresh`)}),r&&(0,B.jsx)(`button`,{type:`button`,className:`rounded-lg border border-border px-3 py-1`,onClick:()=>void navigator.clipboard.writeText(r.path),children:e(`Copy log path`)})]}),(0,B.jsx)(`p`,{className:`break-all text-xs text-muted-foreground`,children:r?.path}),a&&(0,B.jsx)(`p`,{role:`alert`,children:a}),(0,B.jsx)(`pre`,{className:`max-h-80 overflow-auto rounded-lg bg-background p-3 text-xs whitespace-pre-wrap break-words`,"aria-label":e(`Log lines`),children:r?r.lines.length?r.lines.join(`
125
125
  `):e(`No log has been written yet.`):e(`Loading log…`)})]})}var _g={"settings-section-external-api":Um,"settings-section-models":Bm,"settings-section-embedding":ch,"settings-section-keys":Ch,"settings-section-diagnostics":Ih,"settings-section-health":Lh,"settings-section-claude-folder":mg,"settings-section-import":sg,"settings-section-auto-import":lg,"settings-section-profile":vg,"settings-section-directory-maps":Oh,"settings-section-web-app":ug,"settings-section-log":gg};function vg(){return(0,B.jsxs)(`div`,{className:`space-y-6`,children:[(0,B.jsx)(Eh,{}),(0,B.jsx)(Th,{})]})}function yg(){return(0,B.jsx)(`div`,{className:`settings-view space-y-6`,children:vm.map(({id:e})=>{let t=_g[e];return(0,B.jsx)(`div`,{id:e,className:`scroll-mt-4`,children:(0,B.jsx)(t,{})},e)})})}var bg=Br(`grid gap-0.5 rounded-2xl border px-4 py-3 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4 group/alert relative w-full`,{variants:{variant:{default:`bg-card text-card-foreground`,destructive:`text-destructive bg-card *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current`}},defaultVariants:{variant:`default`}});function xg({className:e,variant:t,...n}){return(0,B.jsx)(`div`,{"data-slot":`alert`,role:`alert`,className:z(bg({variant:t}),e),...n})}function Sg({className:e,...t}){return(0,B.jsx)(`div`,{"data-slot":`alert-description`,className:z(`text-muted-foreground text-sm [&_p]:leading-relaxed col-start-2`,e),...t})}function Cg({...e}){let t=Ml();return(0,B.jsx)(Wn,{theme:t,className:`toaster group`,style:{"--normal-bg":`var(--color-popover)`,"--normal-text":`var(--color-popover-foreground)`,"--normal-border":`var(--color-border)`},icons:{loading:(0,B.jsx)(le,{className:`size-4 animate-spin`}),success:(0,B.jsx)(oe,{className:`size-4`}),error:(0,B.jsx)(F,{className:`size-4`}),info:(0,B.jsx)(N,{className:`size-4`}),warning:(0,B.jsx)(je,{className:`size-4`})},...e})}function wg(e,t,n){return e?t:n}var Tg=[``,`feature`,`bug-fix`,`refactor`,`architecture`,`rule`,`documentation`,`discussion`,`analysis`,`configuration`];function Eg(){let{t:e,language:t}=mr(),n=vl(),[r,i]=(0,_.useState)(!1),a=hr(),o=gr();(0,_.useEffect)(()=>{let e=gl();(async()=>{await a.loadTags(),await a.loadMemories(),await a.loadStats(),await a.checkMigrationStatus(),await a.checkAuthWarning()})();let t=setInterval(()=>{a.loadStats(),!a.isSearching&&n===`project`&&a.loadMemories()},3e4);return()=>{e(),clearInterval(t)}},[]);let s=o.loadUserProfile;(0,_.useEffect)(()=>{n===`profile`&&s()},[n,s]);function c(e){e!==t&&(ur(e),a.loadMemories(),a.loadStats(),n===`profile`&&o.loadUserProfile())}function l(e){e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey||(e.preventDefault(),hl(il.home))}return(0,B.jsxs)(B.Fragment,{children:[(0,B.jsx)(Cg,{richColors:!0,position:`bottom-right`}),(0,B.jsxs)(`div`,{className:`flex min-h-svh bg-background text-foreground`,children:[(0,B.jsx)(Rl,{open:r,onOpenChange:i,currentView:n,brand:e(`brand`),projectLabel:e(`tab-project`),profileLabel:e(`tab-profile`),profileSections:[{id:`profile-preferences`,label:e(`profile-preferences`)},{id:`profile-patterns`,label:e(`profile-patterns`)},{id:`profile-workflows`,label:e(`profile-workflows`)}],settingsSections:vm.map(e=>({id:e.id,label:km(e.title,t)})),langLabel:t.toUpperCase(),languageLabel:e(`nav-language`),themeLabel:e(`nav-theme`),settingsLabel:e(`nav-settings`),closeLabel:e(`nav-close`),collapseLabel:e(`nav-collapse`),expandLabel:e(`nav-expand`),onLanguageSelect:c}),(0,B.jsxs)(`div`,{className:`flex min-w-0 flex-1 flex-col`,children:[(0,B.jsxs)(`div`,{className:`sticky top-0 z-30 flex items-center gap-2 border-b border-border bg-background/95 px-3 py-2 backdrop-blur md:hidden`,children:[(0,B.jsx)(U,{variant:`ghost`,size:`icon-sm`,onClick:()=>i(!0),"aria-label":e(`nav-menu`),children:(0,B.jsx)(de,{className:`size-4`})}),(0,B.jsx)(`a`,{href:il.home,className:`truncate text-sm tracking-wide text-primary`,onClick:l,children:e(`brand`)})]}),(0,B.jsxs)(`div`,{className:`mx-auto w-full max-w-6xl flex-1 space-y-4 p-4 md:p-6`,children:[a.showAuthWarning?(0,B.jsxs)(xg,{variant:`destructive`,children:[(0,B.jsx)(je,{}),(0,B.jsx)(Sg,{children:e(`auth-warning-text`)})]}):null,(0,B.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,B.jsx)(`h1`,{className:`text-base tracking-wide text-primary`,children:e(n===`project`?`tab-project`:n===`profile`?`tab-profile`:`nav-settings`)}),n===`project`?(0,B.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground`,children:[(0,B.jsx)(`span`,{children:e(`text-total`,{count:wg(a.isSearching,a.totalItems,a.statsTotal)})}),a.refreshing?(0,B.jsx)(ue,{className:`size-3.5 animate-spin`}):null]}):null]}),n===`project`?(0,B.jsxs)(B.Fragment,{children:[(0,B.jsxs)(`div`,{className:`flex flex-wrap items-end gap-3 rounded-xl border border-border bg-card p-3`,children:[(0,B.jsxs)(`div`,{className:`min-w-0 max-w-full space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`tag-filter`,children:e(`label-tag`)}),(0,B.jsxs)(fn,{id:`tag-filter`,className:`flex h-8 w-64 max-w-full rounded-lg border border-border bg-background px-2 text-sm`,value:a.selectedTag,onChange:e=>a.onTagFilterChange(e.currentTarget.value),children:[(0,B.jsx)(`option`,{value:``,children:e(`opt-all-tags`)}),a.tags.map(e=>(0,B.jsx)(`option`,{value:e.tag,children:e.displayName||e.tag},e.tag))]})]}),a.selectedKeyword?(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(`span`,{className:`block text-sm font-medium`,children:e(`label-keyword`)}),(0,B.jsxs)(`div`,{className:`flex h-8 items-center gap-1`,children:[(0,B.jsx)(Ul,{keyword:a.selectedKeyword,active:!0}),(0,B.jsx)(U,{variant:`ghost`,size:`icon-xs`,onClick:()=>a.onKeywordFilterChange(``),"aria-label":e(`btn-clear-keyword`),title:e(`btn-clear-keyword`),children:(0,B.jsx)(Fe,{className:`size-3.5`})})]})]}):null,(0,B.jsxs)(`div`,{className:`flex flex-1 items-end gap-1.5 min-w-56`,children:[(0,B.jsxs)(`div`,{className:`flex-1 space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`search-input`,className:`sr-only`,children:e(`placeholder-search`)}),(0,B.jsx)(lm,{id:`search-input`,placeholder:e(`placeholder-search`),value:a.searchInput,onChange:e=>a.setSearchInput(e.target.value),onKeyDown:e=>e.key===`Enter`&&a.performSearch()})]}),(0,B.jsx)(U,{variant:`outline`,size:`icon`,onClick:a.performSearch,children:(0,B.jsx)(we,{className:`size-4`})}),a.isSearching?(0,B.jsx)(U,{variant:`outline`,size:`icon`,onClick:a.clearSearch,children:(0,B.jsx)(Fe,{className:`size-4`})}):null]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-1.5`,children:[(0,B.jsx)(Gl,{content:e(`tooltip-cleanup`),children:(0,B.jsxs)(U,{variant:`outline`,size:`sm`,onClick:a.runCleanup,children:[(0,B.jsx)(Ae,{className:`size-3.5`}),e(`btn-cleanup`)]})}),(0,B.jsx)(Gl,{content:e(`tooltip-deduplicate`),children:(0,B.jsxs)(U,{variant:`outline`,size:`sm`,onClick:a.runDeduplication,children:[(0,B.jsx)(Se,{className:`size-3.5`}),e(`btn-deduplicate`)]})})]}),a.selectedIds.size>0?(0,B.jsxs)(`div`,{className:`flex w-full flex-wrap items-center gap-2 border-t border-border pt-3`,children:[(0,B.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e(`text-selected`,{count:a.selectedIds.size})}),(0,B.jsx)(U,{variant:`secondary`,size:`xs`,onClick:a.selectAllCurrentPage,children:e(`btn-select-all`)}),(0,B.jsx)(U,{variant:`destructive`,size:`xs`,onClick:a.bulkDelete,children:e(`btn-delete-selected`)}),(0,B.jsx)(U,{variant:`ghost`,size:`xs`,onClick:a.deselectAll,children:e(`btn-deselect-all`)})]}):null]}),a.migrationNeeded?(0,B.jsxs)(xg,{variant:`destructive`,className:`space-y-3`,children:[(0,B.jsx)(je,{}),(0,B.jsxs)(Sg,{className:`space-y-3`,children:[(0,B.jsx)(`p`,{children:a.migrationMessage||e(`migration-mismatch`)}),(0,B.jsxs)(`label`,{className:`flex items-start gap-2 text-sm`,children:[(0,B.jsx)(qi,{checked:a.migrationConfirmed,onCheckedChange:e=>a.setMigrationConfirmed(e===!0),className:`mt-0.5`}),(0,B.jsx)(`span`,{children:e(`migration-understand`)})]}),(0,B.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,B.jsx)(U,{variant:`destructive`,size:`sm`,disabled:!a.migrationConfirmed,onClick:()=>a.runMigration(`fresh-start`),children:e(`btn-fresh-start`)}),(0,B.jsx)(U,{variant:`secondary`,size:`sm`,disabled:!a.migrationConfirmed,onClick:()=>a.runMigration(`re-embed`),children:e(`btn-reembed`)})]})]})]}):null,(0,B.jsx)(dp,{memories:a.memories,selectedIds:a.selectedIds,currentPage:a.currentPage,totalPages:a.totalPages,totalItems:a.totalItems,isSearching:a.isSearching,loading:a.loadingMemories,error:a.memoriesError,onSelect:a.onSelect,onPageChange:e=>{let t=a.currentPage+e;a.setCurrentPage(t),a.loadMemories({page:t})},onPin:a.pinMemory,onUnpin:a.unpinMemory,onEdit:a.openEdit,onDeleteMemory:a.deleteMemory,onDeletePrompt:a.deletePrompt,activeKeyword:a.selectedKeyword,onKeywordClick:e=>a.onKeywordFilterChange(a.selectedKeyword.toLowerCase()===e.toLowerCase()?``:e)}),(0,B.jsxs)(`section`,{className:`rounded-xl border border-border bg-card p-4 space-y-3`,children:[(0,B.jsx)(`h2`,{className:`text-sm text-muted-foreground`,children:e(`section-add`)}),(0,B.jsxs)(`form`,{className:`space-y-3`,onSubmit:a.addMemory,children:[(0,B.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-3`,children:[(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`add-tag`,children:e(`label-tag`)}),(0,B.jsxs)(fn,{id:`add-tag`,required:!0,className:`flex h-8 w-full rounded-lg border border-border bg-background px-2 text-sm`,value:a.addTag,onChange:e=>a.setAddTag(e.target.value),children:[(0,B.jsx)(`option`,{value:``,children:e(`opt-select-tag`)}),a.tags.map(e=>(0,B.jsx)(`option`,{value:e.tag,children:e.displayName||e.tag},e.tag))]})]}),(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`add-type`,children:e(`label-type`)}),(0,B.jsx)(fn,{id:`add-type`,className:`flex h-8 w-full rounded-lg border border-border bg-background px-2 text-sm`,value:a.addType,onChange:e=>a.setAddType(e.target.value),children:Tg.map(t=>(0,B.jsx)(`option`,{value:t,children:e(t?`opt-${t}`:`opt-other`)},t||`other`))})]}),(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`add-tags`,children:e(`label-tags`)}),(0,B.jsx)(lm,{id:`add-tags`,placeholder:e(`placeholder-tags`),value:a.addTags,onChange:e=>a.setAddTags(e.target.value)})]})]}),(0,B.jsxs)(`div`,{className:`space-y-1`,children:[(0,B.jsx)(J,{htmlFor:`add-content`,children:e(`label-content`)}),(0,B.jsx)(Bl,{id:`add-content`,rows:4,required:!0,placeholder:e(`placeholder-content`),value:a.addContent,onChange:e=>a.setAddContent(e.target.value)})]}),(0,B.jsxs)(U,{type:`submit`,children:[(0,B.jsx)(be,{className:`size-3.5`}),e(`btn-add-memory`)]})]})]})]}):n===`settings`?(0,B.jsx)(yg,{}):(0,B.jsx)(gm,{profile:o.userProfile,loading:o.loadingProfile,onRefresh:o.refreshProfile,onCleanup:()=>o.setAiCleanupOpen(!0)})]})]})]}),(0,B.jsx)(Vl,{open:a.editOpen,onOpenChange:a.setEditOpen,content:a.editContent,onSave:a.saveEdit}),(0,B.jsx)(_m,{open:a.tagMigrationOpen,onOpenChange:e=>{e||Xn(a.tagMigrationCount),a.setTagMigrationOpen(e)},count:a.tagMigrationCount,onComplete:()=>{Zn(),a.loadMemories(),a.loadStats()}}),(0,B.jsx)(Rc,{open:o.aiCleanupOpen,onOpenChange:o.setAiCleanupOpen,profile:o.userProfile,onApplied:o.loadUserProfile})]})}jl();var Dg=document.getElementById(`app`);if(!Dg)throw Error(`Root element #app not found`);(0,v.createRoot)(Dg).render((0,B.jsx)(_.StrictMode,{children:(0,B.jsx)(pr,{children:(0,B.jsx)(Eg,{})})}));
@@ -6,7 +6,7 @@
6
6
  <link rel="icon" type="image/svg+xml" href="/omms-icon.svg" />
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
8
  <title>omms Memory Explorer</title>
9
- <script type="module" crossorigin src="/assets/index-D2Gueurd.js"></script>
9
+ <script type="module" crossorigin src="/assets/index-45F5ouFN.js"></script>
10
10
  <link rel="stylesheet" crossorigin href="/assets/index-Bt9T_DDB.css">
11
11
  </head>
12
12
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "om-memory-system",
3
- "version": "4.4.0-next.65",
3
+ "version": "4.4.0-next.67",
4
4
  "description": "Opinionated modular memory system for coding agents (OpenCode + Pi)",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",