forge-openclaw-plugin 0.2.107 → 0.2.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{activity-page-Dv6X5ZCV.js → activity-page-DWHZ8_sJ.js} +1 -1
- package/dist/assets/{ai-surface-workspace-CutiG6uS.js → ai-surface-workspace-DPygfyhc.js} +1 -1
- package/dist/assets/{atlas-panel-jgMRyaHn.js → atlas-panel-D261RUQF.js} +1 -1
- package/dist/assets/{calendar-page-q7Nm5E2U.js → calendar-page-BQbJkdPF.js} +1 -1
- package/dist/assets/{calendar-rules-DPFsfiRl.js → calendar-rules-BoFsuvZ8.js} +1 -1
- package/dist/assets/{calendar-week-toolbar-nVhgB-0s.js → calendar-week-toolbar-LetevPI7.js} +1 -1
- package/dist/assets/{companion-sync-lab-page-CJ8UTij8.js → companion-sync-lab-page-Bid-4B8W.js} +1 -1
- package/dist/assets/{daily-metrics-dashboard-CiJkkkd1.js → daily-metrics-dashboard-CqnGJNeI.js} +1 -1
- package/dist/assets/{entity-note-count-link-RzBB6ujx.js → entity-note-count-link-VMURwBMi.js} +1 -1
- package/dist/assets/{entity-notes-surface-Djz50HvD.js → entity-notes-surface-DGXcyNzo.js} +1 -1
- package/dist/assets/{execution-board-CtPhI-58.js → execution-board-BGf6zZqJ.js} +1 -1
- package/dist/assets/{faceted-token-search-DEC6ANa9.js → faceted-token-search-CAsZrhZ4.js} +1 -1
- package/dist/assets/{flagship-signal-deck-CtHC3mql.js → flagship-signal-deck-DJsq3jn2.js} +1 -1
- package/dist/assets/{floating-action-menu-CKQRhff9.js → floating-action-menu-B3tQStUN.js} +1 -1
- package/dist/assets/{goal-detail-page-CF5fNQeR.js → goal-detail-page-DBs-9wpk.js} +1 -1
- package/dist/assets/{goals-page-fsY8NzGB.js → goals-page-CPmhjsG-.js} +1 -1
- package/dist/assets/{habits-page-COoGz4kj.js → habits-page-DkW8zT6_.js} +1 -1
- package/dist/assets/index-BhkubYaC.js +19 -0
- package/dist/assets/{insight-flow-dialog-DtX_5W7g.js → insight-flow-dialog-BvgRjkPi.js} +1 -1
- package/dist/assets/{insights-page-cBd74ObU.js → insights-page-Dtij6pm5.js} +1 -1
- package/dist/assets/{kanban-page-CYav9THw.js → kanban-page-R1x5hUU-.js} +1 -1
- package/dist/assets/{knowledge-graph-page-D2A-W1jE.js → knowledge-graph-page-BRBB5Vvz.js} +1 -1
- package/dist/assets/{life-force-page-CACGlNhq.js → life-force-page-DGPWKM9I.js} +1 -1
- package/dist/assets/{life-force-workspace-BJ4N1I78.js → life-force-workspace-DoRIQoU_.js} +1 -1
- package/dist/assets/{metric-tile-CMadwnGz.js → metric-tile-NJiFcFxW.js} +1 -1
- package/dist/assets/{movement-page-D5VqFd2q.js → movement-page-Dk8aV737.js} +1 -1
- package/dist/assets/{note-markdown-BzK2Qlgr.js → note-markdown-CZHjJDve.js} +1 -1
- package/dist/assets/{note-tags-input-CZzqJMLc.js → note-tags-input-DFpxZHPg.js} +1 -1
- package/dist/assets/{notes-page-D3Hsh90C.js → notes-page-r3kymlqg.js} +1 -1
- package/dist/assets/{open-in-graph-button-BFPKfyK3.js → open-in-graph-button-B_XHtHZD.js} +1 -1
- package/dist/assets/{orbit-map-CnyfSmOG.js → orbit-map-C_xy4kYC.js} +1 -1
- package/dist/assets/{overview-page-CXdWrOV1.js → overview-page-Dwg4uYe9.js} +1 -1
- package/dist/assets/{page-hero-ffKzgyW3.js → page-hero-DzEsy8i5.js} +1 -1
- package/dist/assets/{pill-cluster-C2D0h3lx.js → pill-cluster-DcBUeEMT.js} +1 -1
- package/dist/assets/{preference-entity-handoff-button-Dj3V6VxL.js → preference-entity-handoff-button-BX2n07ob.js} +1 -1
- package/dist/assets/{preferences-page-Jo8Gw386.js → preferences-page-BSnwiWBt.js} +1 -1
- package/dist/assets/{project-collections-qSqp90HN.js → project-collections-BR6YdlCZ.js} +1 -1
- package/dist/assets/{project-detail-page-BifhiLQX.js → project-detail-page-DeYshcCb.js} +1 -1
- package/dist/assets/{project-management-hierarchy-page-DZ_9klIc.js → project-management-hierarchy-page-Bhdt79Ea.js} +1 -1
- package/dist/assets/{project-management-section-nav-BImLCVvf.js → project-management-section-nav-DnXuWUfe.js} +1 -1
- package/dist/assets/{projects-page-ptcx6H38.js → projects-page-BA9W0ZPk.js} +1 -1
- package/dist/assets/{psyche-behaviors-page-BDwXyDta.js → psyche-behaviors-page-DpTj53GI.js} +1 -1
- package/dist/assets/{psyche-flashcards-page-DL1BP1jX.js → psyche-flashcards-page-CV58hAJA.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-ovcpisx1.js → psyche-goal-map-page-C07CALFg.js} +1 -1
- package/dist/assets/{psyche-graph-EP5GL612.js → psyche-graph-CP7mxfMP.js} +1 -1
- package/dist/assets/{psyche-metrics-page-Bcu813Rg.js → psyche-metrics-page-CY8e9R0D.js} +1 -1
- package/dist/assets/{psyche-mode-guide-page-C0g27Xpt.js → psyche-mode-guide-page-DYt6AmHl.js} +1 -1
- package/dist/assets/{psyche-modes-page-BjKjX5MR.js → psyche-modes-page-Dd77kTtJ.js} +1 -1
- package/dist/assets/{psyche-page-F4tF2W70.js → psyche-page-DNXZjIKp.js} +1 -1
- package/dist/assets/{psyche-patterns-page-B-14hukK.js → psyche-patterns-page-DxGzpeT5.js} +1 -1
- package/dist/assets/{psyche-questionnaire-builder-page-BdXmoHvK.js → psyche-questionnaire-builder-page-5EQctRHO.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-Cu5uwlJu.js → psyche-questionnaire-detail-page-W8nhUGAc.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-detail-page-C3R4PClg.js → psyche-questionnaire-run-detail-page-DVwzSuqg.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-page-Div3iDdt.js → psyche-questionnaire-run-page-BHResQgL.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-DpqAPQCp.js → psyche-questionnaires-page-DFTOXpyp.js} +1 -1
- package/dist/assets/{psyche-report-detail-page-BvWVDKP3.js → psyche-report-detail-page-BqDE_tf7.js} +1 -1
- package/dist/assets/{psyche-reports-page-BrbWUlAq.js → psyche-reports-page-B75pDz0l.js} +1 -1
- package/dist/assets/{psyche-schemas-beliefs-page-DYKvAtSD.js → psyche-schemas-beliefs-page-BjSO4tYL.js} +1 -1
- package/dist/assets/{psyche-screen-time-page-CAOKCyQw.js → psyche-screen-time-page-B7lKf1g7.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-F0MVA0UH.js → psyche-self-observation-page-C6RMThwc.js} +1 -1
- package/dist/assets/{psyche-values-page-DyvX-d0o.js → psyche-values-page-1O158mIJ.js} +1 -1
- package/dist/assets/{report-chain-fields-CeC1cJFS.js → report-chain-fields-CyJ_VFY5.js} +1 -1
- package/dist/assets/{rewards-page-C2loyODo.js → rewards-page-sPlDYuVo.js} +1 -1
- package/dist/assets/{scheduling-rules-editor-D40AC2jR.js → scheduling-rules-editor-DGgcBs1W.js} +1 -1
- package/dist/assets/{schema-badge-FY7818qB.js → schema-badge-Do-YvNHm.js} +1 -1
- package/dist/assets/{select-menu-DJsCG6rM.js → select-menu-CAM7rMdO.js} +1 -1
- package/dist/assets/{settings-agents-page-BFkJ5AAD.js → settings-agents-page-BsZY71kz.js} +1 -1
- package/dist/assets/{settings-bin-page-D3-Ab-iA.js → settings-bin-page-kB3jtHo_.js} +1 -1
- package/dist/assets/{settings-calendar-page-ly_mSTAD.js → settings-calendar-page-C-IGNk3_.js} +1 -1
- package/dist/assets/{settings-data-page-D7QOqNf-.js → settings-data-page-CFGSL9g3.js} +1 -1
- package/dist/assets/{settings-logs-page-Ca87HEUx.js → settings-logs-page-C7e9FIN_.js} +1 -1
- package/dist/assets/{settings-mobile-page-D0jejZot.js → settings-mobile-page-DzKeZQDM.js} +1 -1
- package/dist/assets/{settings-models-page-DPDsZjSc.js → settings-models-page-dFhaOV3E.js} +1 -1
- package/dist/assets/{settings-page-1cArlSPM.js → settings-page-C0fSyYUx.js} +1 -1
- package/dist/assets/{settings-rewards-page-Db4BV1DC.js → settings-rewards-page-D-LuZHhv.js} +1 -1
- package/dist/assets/{settings-section-nav-DP9o4peU.js → settings-section-nav-kFFQSJEe.js} +1 -1
- package/dist/assets/{settings-users-page-BHFyDSsd.js → settings-users-page-CX797HPB.js} +1 -1
- package/dist/assets/{settings-wiki-page-BNaiupBm.js → settings-wiki-page-CWLAvcsf.js} +1 -1
- package/dist/assets/{sleep-page-BmOPF0yD.js → sleep-page-QgBkKyk_.js} +1 -1
- package/dist/assets/{sports-page-BldIiclr.js → sports-page-C8tLMl7V.js} +1 -1
- package/dist/assets/{strategies-page-CaTN99qj.js → strategies-page-CGgh-KXu.js} +1 -1
- package/dist/assets/{strategy-detail-page-DsgFTd-U.js → strategy-detail-page-CnzqjjoD.js} +1 -1
- package/dist/assets/{strategy-dialog-7X7peRzu.js → strategy-dialog-C6AThZ9L.js} +1 -1
- package/dist/assets/{surface-CJI17F3n.js → surface-CIDhCEsF.js} +1 -1
- package/dist/assets/{task-detail-page-M1sIIPA8.js → task-detail-page-Dp0r_qZP.js} +1 -1
- package/dist/assets/{timebox-planning-dialog-ByojN0AN.js → timebox-planning-dialog-B3uaSsWI.js} +1 -1
- package/dist/assets/{today-page-BjDijtn8.js → today-page-CTnMYrPi.js} +1 -1
- package/dist/assets/{training-load-page-BPRmaWmF.js → training-load-page-D0WB5_Tq.js} +1 -1
- package/dist/assets/{vitals-page-CE9zdGLF.js → vitals-page-0vg8nqwj.js} +1 -1
- package/dist/assets/{weekly-review-page-CzhTv90n.js → weekly-review-page-CSSKlkbH.js} +1 -1
- package/dist/assets/{weight-loss-page-Bp_cIk78.js → weight-loss-page-Dcr4wjjy.js} +1 -1
- package/dist/assets/{wiki-article-markdown-Dok2uy2p.js → wiki-article-markdown-CBFvfJx_.js} +1 -1
- package/dist/assets/{wiki-editor-page-BuW32Y3f.js → wiki-editor-page-CL1uxpih.js} +1 -1
- package/dist/assets/{wiki-ingest-history-page-DZKSBNHV.js → wiki-ingest-history-page-XX8DeNCC.js} +1 -1
- package/dist/assets/{wiki-ingest-modal-DyqBEZcC.js → wiki-ingest-modal-j-ftDmzp.js} +1 -1
- package/dist/assets/{wiki-page-DqxlbLKG.js → wiki-page-B46TQYpy.js} +1 -1
- package/dist/assets/{workbench-flow-page-C4nc9jUg.js → workbench-flow-page-CicEuBKq.js} +1 -1
- package/dist/assets/{workbench-page-BnyR7SL0.js → workbench-page-tXezYLh_.js} +1 -1
- package/dist/assets/{workout-detail-page-DT-c5cHL.js → workout-detail-page-BTO5X0Of.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/server/server/src/discovery-advertiser.js +5 -2
- package/dist/server/server/src/repositories/agent-runtime-sessions.js +0 -26
- package/dist/server/server/src/services/devrage-scanner.js +948 -0
- package/dist/server/server/src/services/devrage.js +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/assets/index-EqQsXoat.js +0 -19
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as n,j as e,b2 as le,dq as fe,c7 as ce,dr as ke,aG as ye,bn as Ne,de as Ce}from"./vendor-Dnkkx2co.js";import{j as we,i as I,k as h}from"./state-vCcAT5Hq.js";import{S as Ae}from"./settings-section-nav-DP9o4peU.js";import{P as Se}from"./page-hero-ffKzgyW3.js";import{dg as Oe,ef as Ie,eg as Me,eh as Pe,ei as Le,ej as Ee,ek as Ke,el as Fe,L as Ue,E as _e,C as w,B as d,c as l,dv as ze,bY as $e,em as Be}from"./index-EqQsXoat.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./forms-hB0SqEh-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";const ue="grid min-w-0 gap-2 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",M="grid min-w-0 gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",P="rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-5 text-sm leading-6 text-[var(--ui-ink-soft)]",o="min-w-0 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-3 text-sm text-[var(--ui-ink-strong)] outline-none placeholder:text-[var(--ui-ink-faint)] transition focus:border-[var(--primary)]/35 focus:bg-[var(--ui-surface-3)]",j="text-sm text-[var(--ui-ink-strong)]",L="text-[var(--ui-ink-soft)]",m="text-[var(--ui-ink-faint)]",We="text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",g="bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]",qe="bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",Qe="rounded-[20px] border border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] px-4 py-5 text-sm leading-6 text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]";function E(i="openai-api"){return{label:i==="openai-codex"?"OpenAI Codex":i==="openai-compatible"?"Local compatible endpoint":i==="mock"?"Workbench mock runtime":"OpenAI API",provider:i,baseUrl:i==="openai-codex"?"https://chatgpt.com/backend-api":i==="openai-compatible"?"http://127.0.0.1:11434/v1":i==="mock"?"mock://workbench":"https://api.openai.com/v1",model:i==="mock"?"mock-echo":"gpt-5.4-mini",apiKey:""}}function Te(i){return{id:i.id,label:i.label,provider:i.provider,baseUrl:i.baseUrl,model:i.model,apiKey:""}}function aa(){var ie,te,ne,re,oe;const i=we(),[s,x]=n.useState(()=>E()),[K,F]=n.useState(""),[U,_]=n.useState("gpt-5.4-mini"),[z,$]=n.useState(""),[B,W]=n.useState("gpt-5.4-mini"),[A,me]=n.useState("Fast wiki search"),[S,ge]=n.useState("text-embedding-3-small"),[q,he]=n.useState("https://api.openai.com/v1"),[Q,T]=n.useState(""),[R,xe]=n.useState("1200"),[D,pe]=n.useState("200"),[O,y]=n.useState(""),[c,N]=n.useState(null),[G,v]=n.useState(null),u=I({queryKey:["forge-settings"],queryFn:ze}),C=I({queryKey:["forge-wiki-settings"],queryFn:$e}),ve=I({queryKey:["forge-openai-codex-oauth",c],queryFn:async()=>{if(!c)throw new Error("Missing OAuth session id");return await Be(c)},enabled:!!c,refetchInterval:a=>{var de;const r=(de=a.state.data)==null?void 0:de.session.status;return r&&["authorized","error","consumed","expired"].includes(r)?!1:1500}}),f=async()=>{await i.invalidateQueries({queryKey:["forge-settings"]}),await i.invalidateQueries({queryKey:["forge-wiki-settings"]}),await i.invalidateQueries({queryKey:["forge-wiki-search"]}),await i.invalidateQueries({queryKey:["forge-openai-codex-oauth",c]})},Z=h({mutationFn:()=>Oe({modelSettings:{forgeAgent:{basicChat:{connectionId:K||null,model:U},wiki:{connectionId:z||null,model:B}}}}),onSuccess:f}),H=h({mutationFn:()=>Ie({id:s.id,label:s.label,provider:s.provider,authMode:s.provider==="openai-codex"?"oauth":"api_key",baseUrl:s.baseUrl,model:s.model,apiKey:s.provider==="openai-codex"?void 0:s.apiKey||void 0,oauthSessionId:s.provider==="openai-codex"?c??void 0:void 0}),onSuccess:async()=>{v("Connection saved."),s.provider==="openai-codex"&&(N(null),y("")),x(E(s.provider)),await f()},onError:a=>{v(a instanceof Error?a.message:"Connection save failed.")}}),Y=h({mutationFn:Me,onSuccess:f}),J=h({mutationFn:()=>Pe({label:A.trim(),model:S.trim(),baseUrl:q.trim(),apiKey:Q.trim()||void 0,chunkSize:Number(R),chunkOverlap:Number(D)}),onSuccess:async()=>{T(""),await f()}}),V=h({mutationFn:a=>Le("embedding",a),onSuccess:f}),X=h({mutationFn:async()=>Ee({connectionId:s.id,provider:s.provider,baseUrl:s.baseUrl,model:s.model,apiKey:s.provider==="openai-codex"?void 0:s.apiKey||void 0}),onSuccess:({result:a})=>{v(`Connection test succeeded: ${a.outputPreview}`)},onError:a=>{v(a instanceof Error?a.message:"Connection test failed.")}}),ee=h({mutationFn:Ke,onSuccess:({session:a})=>{N(a.id),v("OpenAI Codex OAuth started."),a.authUrl&&window.open(a.authUrl,"_blank","noopener,noreferrer")}}),ae=h({mutationFn:async()=>{if(!c)throw new Error("No OAuth session started yet.");return await Fe(c,O)},onSuccess:({session:a})=>{v(a.status==="authorized"?"OpenAI Codex OAuth authorized.":"Manual OAuth code submitted.")}});n.useEffect(()=>{var r;const a=(r=u.data)==null?void 0:r.settings;a&&(F(a.modelSettings.forgeAgent.basicChat.connectionId??""),_(a.modelSettings.forgeAgent.basicChat.model),$(a.modelSettings.forgeAgent.wiki.provider==="openai-codex"?a.modelSettings.forgeAgent.wiki.connectionId??"":""),W(a.modelSettings.forgeAgent.wiki.model))},[u.data]);const p=((ie=u.data)==null?void 0:ie.settings.modelSettings.connections)??[],se=p.filter(a=>a.provider==="openai-codex"&&a.authMode==="oauth"),be=se.filter(a=>a.hasStoredCredential),t=((te=ve.data)==null?void 0:te.session)??null,b=s.id?p.find(a=>a.id===s.id):null,je=n.useMemo(()=>!s.label.trim()||!s.model.trim()?!1:s.provider==="openai-codex"?!!((t==null?void 0:t.status)==="authorized"||s.id&&(b!=null&&b.hasStoredCredential)):s.provider==="mock"?!0:s.apiKey.trim().length>0||!!s.id,[s,b==null?void 0:b.hasStoredCredential,t==null?void 0:t.status]);if(u.isLoading)return e.jsx(Ue,{eyebrow:"Models",title:"Loading model settings",description:"Fetching Forge agent defaults and configured AI connections."});if(u.isError||!((ne=u.data)!=null&&ne.settings))return e.jsx(_e,{eyebrow:"Models",error:u.error??new Error("Forge returned an empty model settings payload."),onRetry:()=>void u.refetch()});const k=u.data.settings;return e.jsxs("div",{className:"mx-auto grid min-w-0 w-full max-w-[1440px] gap-5",children:[e.jsx(Se,{eyebrow:"AI runtime",title:"Model Settings",description:"Manage Forge Agent defaults, OpenAI OAuth/API connections, and local OpenAI-compatible endpoints as first-class chat agents.",badge:`${p.length} model connection${p.length===1?"":"s"}`}),e.jsx(Ae,{}),e.jsxs(w,{className:"grid gap-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(le,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Forge Agent defaults"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Forge Agent stays the default system agent. Choose which model connection powers basic chat and the managed wiki workflow."})]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("label",{className:ue,children:[e.jsx("span",{className:`text-sm ${L}`,children:"Basic chat connection"}),e.jsxs("select",{className:o,value:K,onChange:a=>F(a.target.value),children:[e.jsx("option",{value:"",children:"No external connection"}),p.map(a=>e.jsxs("option",{value:a.id,children:[a.label," (",a.agentLabel,")"]},a.id))]}),e.jsx("input",{className:o,value:U,onChange:a=>_(a.target.value),placeholder:"Model"})]}),e.jsxs("label",{className:ue,children:[e.jsx("span",{className:`text-sm ${L}`,children:"KarpaWiki Codex OAuth connection"}),e.jsxs("select",{className:o,value:z,onChange:a=>$(a.target.value),children:[e.jsx("option",{value:"",children:"No Codex OAuth connection"}),se.map(a=>e.jsxs("option",{value:a.id,disabled:!a.hasStoredCredential,children:[a.label," (",a.accountLabel??a.agentLabel,")",a.hasStoredCredential?"":" · needs OAuth"]},a.id))]}),e.jsx("input",{className:o,value:B,onChange:a=>W(a.target.value),placeholder:"Model"}),e.jsx("span",{className:`text-xs leading-5 ${m}`,children:"KarpaWiki smart ingest uses ChatGPT/Codex OAuth only. It does not use metered OpenAI Platform API keys."})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(d,{pending:Z.isPending,pendingLabel:"Saving defaults",onClick:()=>void Z.mutateAsync(),children:"Save Forge Agent defaults"}),e.jsxs(l,{className:g,children:["Forge Agent",k.modelSettings.forgeAgent.basicChat.connectionLabel?` basic chat: ${k.modelSettings.forgeAgent.basicChat.connectionLabel}`:" basic chat stays local"]}),e.jsx(l,{className:g,children:k.modelSettings.forgeAgent.wiki.connectionLabel?`KarpaWiki OAuth: ${k.modelSettings.forgeAgent.wiki.connectionLabel}`:"KarpaWiki: no Codex OAuth model selected"}),be.length===0?e.jsx(l,{className:qe,children:"Add OpenAI Codex OAuth before smart ingest"}):null]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(fe,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"KarpaWiki embeddings"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Semantic search profiles live with model settings. They remain optional; KarpaWiki text search and entity-linked search still work without embeddings."})]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(20rem,0.9fr)]",children:[e.jsxs("div",{className:"grid gap-3",children:[C.isLoading?e.jsx("div",{className:P,children:"Loading embedding profiles."}):null,C.isError?e.jsx("div",{className:Qe,children:"Could not load KarpaWiki embedding profiles."}):null,((re=C.data)==null?void 0:re.settings.embeddingProfiles.length)===0?e.jsx("div",{className:P,children:"No embedding profile yet. Add one only if you want semantic wiki search in addition to exact search and links."}):null,(oe=C.data)==null?void 0:oe.settings.embeddingProfiles.map(a=>e.jsxs("div",{className:"grid min-w-0 gap-2 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-[var(--ui-ink-strong)]",children:a.label}),e.jsxs("div",{className:`mt-1 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[a.model," · ",a.baseUrl]})]}),e.jsx(d,{variant:"secondary",pending:V.isPending,pendingLabel:"Deleting",onClick:()=>void V.mutateAsync(a.id),children:e.jsx(ce,{className:"size-4"})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(l,{className:g,children:["chunk ",a.chunkSize]}),e.jsxs(l,{className:g,children:["overlap ",a.chunkOverlap]}),e.jsx(l,{className:g,children:a.enabled?"enabled":"disabled"})]})]},a.id))]}),e.jsxs("div",{className:M,children:[e.jsx("input",{className:o,value:A,onChange:a=>me(a.target.value),placeholder:"Profile label"}),e.jsx("input",{className:o,value:S,onChange:a=>ge(a.target.value),placeholder:"Embedding model"}),e.jsx("input",{className:o,value:q,onChange:a=>he(a.target.value),placeholder:"Embedding base URL"}),e.jsx("input",{className:o,value:Q,onChange:a=>T(a.target.value),placeholder:"Embedding API key (optional)",type:"password"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx("input",{className:o,value:R,onChange:a=>xe(a.target.value),placeholder:"Chunk size",type:"number"}),e.jsx("input",{className:o,value:D,onChange:a=>pe(a.target.value),placeholder:"Chunk overlap",type:"number"})]}),e.jsx(d,{pending:J.isPending,pendingLabel:"Saving",disabled:!A.trim()||!S.trim(),onClick:()=>void J.mutateAsync(),children:"Save embedding profile"})]})]})]}),e.jsxs("div",{className:"grid min-w-0 gap-5 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ke,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Connection editor"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Every saved connection becomes a first-class agent layered on top of Forge Agent."})]})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx("div",{className:We,children:"Provider"}),e.jsx("div",{className:"grid gap-2 md:grid-cols-3",children:[["openai-api","OpenAI API"],["openai-codex","OpenAI Codex OAuth"],["openai-compatible","OpenAI-compatible"]].map(([a,r])=>e.jsx("button",{type:"button",className:`rounded-[18px] px-4 py-3 text-left text-sm transition ${s.provider===a?"border border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)] shadow-[var(--ui-shadow-soft)]":"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]"}`,onClick:()=>{x(E(a)),N(null),y("")},children:r},a))})]}),e.jsx("input",{className:o,value:s.label,onChange:a=>x(r=>({...r,label:a.target.value})),placeholder:"Connection label"}),e.jsx("input",{className:o,value:s.model,onChange:a=>x(r=>({...r,model:a.target.value})),placeholder:"Model"}),s.provider==="mock"?e.jsxs("div",{className:M,children:[e.jsx("div",{className:j,children:"The Workbench mock runtime is only meant for local development and test workflows."}),e.jsxs("div",{className:`text-xs leading-5 ${m}`,children:["Use mock models like ",e.jsx("code",{children:"mock-echo"}),","," ",e.jsx("code",{children:"mock-json"}),",",e.jsx("code",{children:"mock-tool-search"}),","," ",e.jsx("code",{children:"mock-tool-note"}),", or",e.jsx("code",{children:"mock-chat-memory"})," to exercise deterministic flow behavior without a real external model."]})]}):s.provider!=="openai-codex"?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:o,value:s.baseUrl,onChange:a=>x(r=>({...r,baseUrl:a.target.value})),placeholder:"Base URL"}),e.jsx("input",{className:o,value:s.apiKey,onChange:a=>x(r=>({...r,apiKey:a.target.value})),placeholder:s.id?"Leave blank to keep the stored key":"API key",type:"password"})]}):e.jsxs("div",{className:M,children:[e.jsxs("div",{className:j,children:["OpenAI Codex uses the documented PKCE flow with the local callback at"," ",e.jsx("span",{className:"break-words [overflow-wrap:anywhere]",children:k.modelSettings.oauth.openAiCodex.callbackUrl})]}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Start OAuth, finish the browser sign-in, then save the resulting connection as a chat agent backed by the ChatGPT Codex runtime."}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(d,{variant:"secondary",pending:ee.isPending,pendingLabel:"Starting OAuth",onClick:()=>void ee.mutateAsync(),children:[e.jsx(ye,{className:"size-4"}),"Start OAuth"]}),t!=null&&t.authUrl?e.jsxs(d,{variant:"secondary",onClick:()=>window.open(t.authUrl??"","_blank","noopener,noreferrer"),children:["Open sign-in",e.jsx(Ne,{className:"size-4"})]}):null]}),t?e.jsxs("div",{className:"grid min-w-0 gap-2 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bg)] p-3 text-sm text-[var(--ui-code-text)]",children:[e.jsxs("div",{children:["Status: ",t.status]}),t.accountLabel?e.jsxs("div",{children:["Account: ",t.accountLabel]}):null,t.error?e.jsx("div",{className:"text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]",children:t.error}):null]}):null,e.jsxs("div",{className:"grid gap-2",children:[e.jsx("input",{className:o,value:O,onChange:a=>y(a.target.value),placeholder:"Paste the authorization code or full redirect URL"}),e.jsx(d,{variant:"secondary",disabled:!O.trim()||!c,pending:ae.isPending,pendingLabel:"Submitting",onClick:()=>void ae.mutateAsync(),children:"Submit manual code"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(d,{pending:H.isPending,pendingLabel:"Saving connection",disabled:!je,onClick:()=>void H.mutateAsync(),children:"Save connection"}),e.jsxs(d,{variant:"secondary",pending:X.isPending,pendingLabel:"Testing",disabled:s.provider==="openai-codex"?!s.id:s.provider==="mock"?!1:!s.id&&!s.apiKey.trim(),onClick:()=>void X.mutateAsync(),children:[e.jsx(Ce,{className:"size-4"}),"Test connection"]})]}),G?e.jsx("div",{className:`rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-3 text-sm ${L}`,children:G}):null]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(le,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Connected agents"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Each connection registers its own chat-facing agent identity."})]})]}),e.jsxs("div",{className:"grid gap-3",children:[p.length===0?e.jsx("div",{className:P,children:"No external model connection yet. Add one with OAuth or API credentials and Forge will expose it as a first-class agent."}):null,p.map(a=>e.jsxs("div",{className:"grid min-w-0 gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:a.label}),e.jsxs("div",{className:`mt-1 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[a.agentLabel," · ",a.provider," ·"," ",a.model]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(d,{variant:"secondary",onClick:()=>{x(Te(a)),N(null),y("")},children:"Edit"}),e.jsx(d,{variant:"secondary",pending:Y.isPending,pendingLabel:"Deleting",onClick:()=>void Y.mutateAsync(a.id),children:e.jsx(ce,{className:"size-4"})})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{className:g,children:a.authMode==="oauth"?"OAuth":"API key"}),e.jsx(l,{className:g,children:a.status}),e.jsx(l,{className:g,wrap:!0,children:a.baseUrl}),a.accountLabel?e.jsx(l,{className:g,wrap:!0,children:a.accountLabel}):null]})]},a.id))]})]})]})]})}export{aa as SettingsModelsPage};
|
|
1
|
+
import{r as n,j as e,b2 as le,dq as fe,c7 as ce,dr as ke,aG as ye,bn as Ne,de as Ce}from"./vendor-Dnkkx2co.js";import{j as we,i as I,k as h}from"./state-vCcAT5Hq.js";import{S as Ae}from"./settings-section-nav-kFFQSJEe.js";import{P as Se}from"./page-hero-DzEsy8i5.js";import{dg as Oe,ef as Ie,eg as Me,eh as Pe,ei as Le,ej as Ee,ek as Ke,el as Fe,L as Ue,E as _e,C as w,B as d,c as l,dv as ze,bY as $e,em as Be}from"./index-BhkubYaC.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./forms-hB0SqEh-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";const ue="grid min-w-0 gap-2 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",M="grid min-w-0 gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",P="rounded-[20px] border border-dashed border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-5 text-sm leading-6 text-[var(--ui-ink-soft)]",o="min-w-0 rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-3 text-sm text-[var(--ui-ink-strong)] outline-none placeholder:text-[var(--ui-ink-faint)] transition focus:border-[var(--primary)]/35 focus:bg-[var(--ui-surface-3)]",j="text-sm text-[var(--ui-ink-strong)]",L="text-[var(--ui-ink-soft)]",m="text-[var(--ui-ink-faint)]",We="text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",g="bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]",qe="bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",Qe="rounded-[20px] border border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] px-4 py-5 text-sm leading-6 text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]";function E(i="openai-api"){return{label:i==="openai-codex"?"OpenAI Codex":i==="openai-compatible"?"Local compatible endpoint":i==="mock"?"Workbench mock runtime":"OpenAI API",provider:i,baseUrl:i==="openai-codex"?"https://chatgpt.com/backend-api":i==="openai-compatible"?"http://127.0.0.1:11434/v1":i==="mock"?"mock://workbench":"https://api.openai.com/v1",model:i==="mock"?"mock-echo":"gpt-5.4-mini",apiKey:""}}function Te(i){return{id:i.id,label:i.label,provider:i.provider,baseUrl:i.baseUrl,model:i.model,apiKey:""}}function aa(){var ie,te,ne,re,oe;const i=we(),[s,x]=n.useState(()=>E()),[K,F]=n.useState(""),[U,_]=n.useState("gpt-5.4-mini"),[z,$]=n.useState(""),[B,W]=n.useState("gpt-5.4-mini"),[A,me]=n.useState("Fast wiki search"),[S,ge]=n.useState("text-embedding-3-small"),[q,he]=n.useState("https://api.openai.com/v1"),[Q,T]=n.useState(""),[R,xe]=n.useState("1200"),[D,pe]=n.useState("200"),[O,y]=n.useState(""),[c,N]=n.useState(null),[G,v]=n.useState(null),u=I({queryKey:["forge-settings"],queryFn:ze}),C=I({queryKey:["forge-wiki-settings"],queryFn:$e}),ve=I({queryKey:["forge-openai-codex-oauth",c],queryFn:async()=>{if(!c)throw new Error("Missing OAuth session id");return await Be(c)},enabled:!!c,refetchInterval:a=>{var de;const r=(de=a.state.data)==null?void 0:de.session.status;return r&&["authorized","error","consumed","expired"].includes(r)?!1:1500}}),f=async()=>{await i.invalidateQueries({queryKey:["forge-settings"]}),await i.invalidateQueries({queryKey:["forge-wiki-settings"]}),await i.invalidateQueries({queryKey:["forge-wiki-search"]}),await i.invalidateQueries({queryKey:["forge-openai-codex-oauth",c]})},Z=h({mutationFn:()=>Oe({modelSettings:{forgeAgent:{basicChat:{connectionId:K||null,model:U},wiki:{connectionId:z||null,model:B}}}}),onSuccess:f}),H=h({mutationFn:()=>Ie({id:s.id,label:s.label,provider:s.provider,authMode:s.provider==="openai-codex"?"oauth":"api_key",baseUrl:s.baseUrl,model:s.model,apiKey:s.provider==="openai-codex"?void 0:s.apiKey||void 0,oauthSessionId:s.provider==="openai-codex"?c??void 0:void 0}),onSuccess:async()=>{v("Connection saved."),s.provider==="openai-codex"&&(N(null),y("")),x(E(s.provider)),await f()},onError:a=>{v(a instanceof Error?a.message:"Connection save failed.")}}),Y=h({mutationFn:Me,onSuccess:f}),J=h({mutationFn:()=>Pe({label:A.trim(),model:S.trim(),baseUrl:q.trim(),apiKey:Q.trim()||void 0,chunkSize:Number(R),chunkOverlap:Number(D)}),onSuccess:async()=>{T(""),await f()}}),V=h({mutationFn:a=>Le("embedding",a),onSuccess:f}),X=h({mutationFn:async()=>Ee({connectionId:s.id,provider:s.provider,baseUrl:s.baseUrl,model:s.model,apiKey:s.provider==="openai-codex"?void 0:s.apiKey||void 0}),onSuccess:({result:a})=>{v(`Connection test succeeded: ${a.outputPreview}`)},onError:a=>{v(a instanceof Error?a.message:"Connection test failed.")}}),ee=h({mutationFn:Ke,onSuccess:({session:a})=>{N(a.id),v("OpenAI Codex OAuth started."),a.authUrl&&window.open(a.authUrl,"_blank","noopener,noreferrer")}}),ae=h({mutationFn:async()=>{if(!c)throw new Error("No OAuth session started yet.");return await Fe(c,O)},onSuccess:({session:a})=>{v(a.status==="authorized"?"OpenAI Codex OAuth authorized.":"Manual OAuth code submitted.")}});n.useEffect(()=>{var r;const a=(r=u.data)==null?void 0:r.settings;a&&(F(a.modelSettings.forgeAgent.basicChat.connectionId??""),_(a.modelSettings.forgeAgent.basicChat.model),$(a.modelSettings.forgeAgent.wiki.provider==="openai-codex"?a.modelSettings.forgeAgent.wiki.connectionId??"":""),W(a.modelSettings.forgeAgent.wiki.model))},[u.data]);const p=((ie=u.data)==null?void 0:ie.settings.modelSettings.connections)??[],se=p.filter(a=>a.provider==="openai-codex"&&a.authMode==="oauth"),be=se.filter(a=>a.hasStoredCredential),t=((te=ve.data)==null?void 0:te.session)??null,b=s.id?p.find(a=>a.id===s.id):null,je=n.useMemo(()=>!s.label.trim()||!s.model.trim()?!1:s.provider==="openai-codex"?!!((t==null?void 0:t.status)==="authorized"||s.id&&(b!=null&&b.hasStoredCredential)):s.provider==="mock"?!0:s.apiKey.trim().length>0||!!s.id,[s,b==null?void 0:b.hasStoredCredential,t==null?void 0:t.status]);if(u.isLoading)return e.jsx(Ue,{eyebrow:"Models",title:"Loading model settings",description:"Fetching Forge agent defaults and configured AI connections."});if(u.isError||!((ne=u.data)!=null&&ne.settings))return e.jsx(_e,{eyebrow:"Models",error:u.error??new Error("Forge returned an empty model settings payload."),onRetry:()=>void u.refetch()});const k=u.data.settings;return e.jsxs("div",{className:"mx-auto grid min-w-0 w-full max-w-[1440px] gap-5",children:[e.jsx(Se,{eyebrow:"AI runtime",title:"Model Settings",description:"Manage Forge Agent defaults, OpenAI OAuth/API connections, and local OpenAI-compatible endpoints as first-class chat agents.",badge:`${p.length} model connection${p.length===1?"":"s"}`}),e.jsx(Ae,{}),e.jsxs(w,{className:"grid gap-5",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(le,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Forge Agent defaults"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Forge Agent stays the default system agent. Choose which model connection powers basic chat and the managed wiki workflow."})]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("label",{className:ue,children:[e.jsx("span",{className:`text-sm ${L}`,children:"Basic chat connection"}),e.jsxs("select",{className:o,value:K,onChange:a=>F(a.target.value),children:[e.jsx("option",{value:"",children:"No external connection"}),p.map(a=>e.jsxs("option",{value:a.id,children:[a.label," (",a.agentLabel,")"]},a.id))]}),e.jsx("input",{className:o,value:U,onChange:a=>_(a.target.value),placeholder:"Model"})]}),e.jsxs("label",{className:ue,children:[e.jsx("span",{className:`text-sm ${L}`,children:"KarpaWiki Codex OAuth connection"}),e.jsxs("select",{className:o,value:z,onChange:a=>$(a.target.value),children:[e.jsx("option",{value:"",children:"No Codex OAuth connection"}),se.map(a=>e.jsxs("option",{value:a.id,disabled:!a.hasStoredCredential,children:[a.label," (",a.accountLabel??a.agentLabel,")",a.hasStoredCredential?"":" · needs OAuth"]},a.id))]}),e.jsx("input",{className:o,value:B,onChange:a=>W(a.target.value),placeholder:"Model"}),e.jsx("span",{className:`text-xs leading-5 ${m}`,children:"KarpaWiki smart ingest uses ChatGPT/Codex OAuth only. It does not use metered OpenAI Platform API keys."})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(d,{pending:Z.isPending,pendingLabel:"Saving defaults",onClick:()=>void Z.mutateAsync(),children:"Save Forge Agent defaults"}),e.jsxs(l,{className:g,children:["Forge Agent",k.modelSettings.forgeAgent.basicChat.connectionLabel?` basic chat: ${k.modelSettings.forgeAgent.basicChat.connectionLabel}`:" basic chat stays local"]}),e.jsx(l,{className:g,children:k.modelSettings.forgeAgent.wiki.connectionLabel?`KarpaWiki OAuth: ${k.modelSettings.forgeAgent.wiki.connectionLabel}`:"KarpaWiki: no Codex OAuth model selected"}),be.length===0?e.jsx(l,{className:qe,children:"Add OpenAI Codex OAuth before smart ingest"}):null]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(fe,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"KarpaWiki embeddings"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Semantic search profiles live with model settings. They remain optional; KarpaWiki text search and entity-linked search still work without embeddings."})]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-[minmax(0,1fr)_minmax(20rem,0.9fr)]",children:[e.jsxs("div",{className:"grid gap-3",children:[C.isLoading?e.jsx("div",{className:P,children:"Loading embedding profiles."}):null,C.isError?e.jsx("div",{className:Qe,children:"Could not load KarpaWiki embedding profiles."}):null,((re=C.data)==null?void 0:re.settings.embeddingProfiles.length)===0?e.jsx("div",{className:P,children:"No embedding profile yet. Add one only if you want semantic wiki search in addition to exact search and links."}):null,(oe=C.data)==null?void 0:oe.settings.embeddingProfiles.map(a=>e.jsxs("div",{className:"grid min-w-0 gap-2 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-[var(--ui-ink-strong)]",children:a.label}),e.jsxs("div",{className:`mt-1 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[a.model," · ",a.baseUrl]})]}),e.jsx(d,{variant:"secondary",pending:V.isPending,pendingLabel:"Deleting",onClick:()=>void V.mutateAsync(a.id),children:e.jsx(ce,{className:"size-4"})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(l,{className:g,children:["chunk ",a.chunkSize]}),e.jsxs(l,{className:g,children:["overlap ",a.chunkOverlap]}),e.jsx(l,{className:g,children:a.enabled?"enabled":"disabled"})]})]},a.id))]}),e.jsxs("div",{className:M,children:[e.jsx("input",{className:o,value:A,onChange:a=>me(a.target.value),placeholder:"Profile label"}),e.jsx("input",{className:o,value:S,onChange:a=>ge(a.target.value),placeholder:"Embedding model"}),e.jsx("input",{className:o,value:q,onChange:a=>he(a.target.value),placeholder:"Embedding base URL"}),e.jsx("input",{className:o,value:Q,onChange:a=>T(a.target.value),placeholder:"Embedding API key (optional)",type:"password"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx("input",{className:o,value:R,onChange:a=>xe(a.target.value),placeholder:"Chunk size",type:"number"}),e.jsx("input",{className:o,value:D,onChange:a=>pe(a.target.value),placeholder:"Chunk overlap",type:"number"})]}),e.jsx(d,{pending:J.isPending,pendingLabel:"Saving",disabled:!A.trim()||!S.trim(),onClick:()=>void J.mutateAsync(),children:"Save embedding profile"})]})]})]}),e.jsxs("div",{className:"grid min-w-0 gap-5 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)]",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(ke,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Connection editor"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Every saved connection becomes a first-class agent layered on top of Forge Agent."})]})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx("div",{className:We,children:"Provider"}),e.jsx("div",{className:"grid gap-2 md:grid-cols-3",children:[["openai-api","OpenAI API"],["openai-codex","OpenAI Codex OAuth"],["openai-compatible","OpenAI-compatible"]].map(([a,r])=>e.jsx("button",{type:"button",className:`rounded-[18px] px-4 py-3 text-left text-sm transition ${s.provider===a?"border border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)] shadow-[var(--ui-shadow-soft)]":"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] text-[var(--ui-ink-soft)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]"}`,onClick:()=>{x(E(a)),N(null),y("")},children:r},a))})]}),e.jsx("input",{className:o,value:s.label,onChange:a=>x(r=>({...r,label:a.target.value})),placeholder:"Connection label"}),e.jsx("input",{className:o,value:s.model,onChange:a=>x(r=>({...r,model:a.target.value})),placeholder:"Model"}),s.provider==="mock"?e.jsxs("div",{className:M,children:[e.jsx("div",{className:j,children:"The Workbench mock runtime is only meant for local development and test workflows."}),e.jsxs("div",{className:`text-xs leading-5 ${m}`,children:["Use mock models like ",e.jsx("code",{children:"mock-echo"}),","," ",e.jsx("code",{children:"mock-json"}),",",e.jsx("code",{children:"mock-tool-search"}),","," ",e.jsx("code",{children:"mock-tool-note"}),", or",e.jsx("code",{children:"mock-chat-memory"})," to exercise deterministic flow behavior without a real external model."]})]}):s.provider!=="openai-codex"?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:o,value:s.baseUrl,onChange:a=>x(r=>({...r,baseUrl:a.target.value})),placeholder:"Base URL"}),e.jsx("input",{className:o,value:s.apiKey,onChange:a=>x(r=>({...r,apiKey:a.target.value})),placeholder:s.id?"Leave blank to keep the stored key":"API key",type:"password"})]}):e.jsxs("div",{className:M,children:[e.jsxs("div",{className:j,children:["OpenAI Codex uses the documented PKCE flow with the local callback at"," ",e.jsx("span",{className:"break-words [overflow-wrap:anywhere]",children:k.modelSettings.oauth.openAiCodex.callbackUrl})]}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Start OAuth, finish the browser sign-in, then save the resulting connection as a chat agent backed by the ChatGPT Codex runtime."}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsxs(d,{variant:"secondary",pending:ee.isPending,pendingLabel:"Starting OAuth",onClick:()=>void ee.mutateAsync(),children:[e.jsx(ye,{className:"size-4"}),"Start OAuth"]}),t!=null&&t.authUrl?e.jsxs(d,{variant:"secondary",onClick:()=>window.open(t.authUrl??"","_blank","noopener,noreferrer"),children:["Open sign-in",e.jsx(Ne,{className:"size-4"})]}):null]}),t?e.jsxs("div",{className:"grid min-w-0 gap-2 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bg)] p-3 text-sm text-[var(--ui-code-text)]",children:[e.jsxs("div",{children:["Status: ",t.status]}),t.accountLabel?e.jsxs("div",{children:["Account: ",t.accountLabel]}):null,t.error?e.jsx("div",{className:"text-[color-mix(in_srgb,var(--danger)_76%,var(--ui-ink-strong)_24%)]",children:t.error}):null]}):null,e.jsxs("div",{className:"grid gap-2",children:[e.jsx("input",{className:o,value:O,onChange:a=>y(a.target.value),placeholder:"Paste the authorization code or full redirect URL"}),e.jsx(d,{variant:"secondary",disabled:!O.trim()||!c,pending:ae.isPending,pendingLabel:"Submitting",onClick:()=>void ae.mutateAsync(),children:"Submit manual code"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(d,{pending:H.isPending,pendingLabel:"Saving connection",disabled:!je,onClick:()=>void H.mutateAsync(),children:"Save connection"}),e.jsxs(d,{variant:"secondary",pending:X.isPending,pendingLabel:"Testing",disabled:s.provider==="openai-codex"?!s.id:s.provider==="mock"?!1:!s.id&&!s.apiKey.trim(),onClick:()=>void X.mutateAsync(),children:[e.jsx(Ce,{className:"size-4"}),"Test connection"]})]}),G?e.jsx("div",{className:`rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-4 py-3 text-sm ${L}`,children:G}):null]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(le,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:j,children:"Connected agents"}),e.jsx("div",{className:`text-xs leading-5 ${m}`,children:"Each connection registers its own chat-facing agent identity."})]})]}),e.jsxs("div",{className:"grid gap-3",children:[p.length===0?e.jsx("div",{className:P,children:"No external model connection yet. Add one with OAuth or API credentials and Forge will expose it as a first-class agent."}):null,p.map(a=>e.jsxs("div",{className:"grid min-w-0 gap-3 rounded-[20px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"break-words text-[var(--ui-ink-strong)] [overflow-wrap:anywhere]",children:a.label}),e.jsxs("div",{className:`mt-1 break-words text-xs [overflow-wrap:anywhere] ${m}`,children:[a.agentLabel," · ",a.provider," ·"," ",a.model]})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx(d,{variant:"secondary",onClick:()=>{x(Te(a)),N(null),y("")},children:"Edit"}),e.jsx(d,{variant:"secondary",pending:Y.isPending,pendingLabel:"Deleting",onClick:()=>void Y.mutateAsync(a.id),children:e.jsx(ce,{className:"size-4"})})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(l,{className:g,children:a.authMode==="oauth"?"OAuth":"API key"}),e.jsx(l,{className:g,children:a.status}),e.jsx(l,{className:g,wrap:!0,children:a.baseUrl}),a.accountLabel?e.jsx(l,{className:g,wrap:!0,children:a.accountLabel}):null]})]},a.id))]})]})]})]})}export{aa as SettingsModelsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as w,j as e,aD as ve,d8 as be,aC as fe,aG as ye,bl as je,d9 as Ne,aQ as we}from"./vendor-Dnkkx2co.js";import{j as ke,i as L,k as M}from"./state-vCcAT5Hq.js";import{u as Se}from"./forms-hB0SqEh-.js";import{Q as Ce,db as ee,F as R,I as _,j as Te,dc as Fe,T as Pe,dd as A,B as k,de as te,P as _e,aI as $e,df as De,dg as Q,dh as Ae,di as Ee,dj as Ie,dk as Le,dl as se,S as Me,E as ae,C as $,dm as Qe,dn as Re,dp as qe,dq as ze,dr as Je,ds as Ke,dt as Oe,du as Ge,dv as He,dw as Ue,dx as Be}from"./index-EqQsXoat.js";import{S as We}from"./settings-section-nav-DP9o4peU.js";import{P as Ye}from"./page-hero-ffKzgyW3.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";function K({theme:a,title:l,description:n}){return e.jsx("div",{className:"overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)]",style:{background:`linear-gradient(180deg, ${a.panelHigh}, ${a.panelLow})`,color:a.ink},children:e.jsxs("div",{className:"px-4 py-4",style:{background:`radial-gradient(circle at top left, ${a.primary}33, transparent 42%), radial-gradient(circle at top right, ${a.secondary}2a, transparent 36%), linear-gradient(180deg, ${a.panel}, ${a.canvas})`},children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.2em] opacity-60",children:"Preview"}),e.jsx("div",{className:"mt-2 font-display text-xl",children:l}),e.jsx("div",{className:"mt-2 text-sm leading-6 opacity-72",children:n}),e.jsx("div",{className:"mt-5 flex gap-2",children:[a.primary,a.secondary,a.tertiary,a.panelHigh].map(t=>e.jsx("div",{className:"h-9 flex-1 rounded-[14px] border border-[var(--ui-border-subtle)]",style:{background:t}},t))})]})})}function j({label:a,value:l,onChange:n,description:t}){return e.jsx(R,{label:a,description:t,children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-[5.5rem_minmax(0,1fr)]",children:[e.jsx("input",{type:"color",value:l,onChange:d=>n(d.target.value),className:"h-12 w-full cursor-pointer rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-1"}),e.jsx(_,{value:l,onChange:d=>n(d.target.value),placeholder:"#7cc7ff"})]})})}function Xe({open:a,onOpenChange:l,value:n,onSave:t}){const[d,m]=w.useState(n),[g,u]=w.useState(""),[f,b]=w.useState(null),S=w.useRef(null),c=r=>{const i=ee.parse(JSON.parse(r));m(i),u(JSON.stringify(i,null,2)),b(null)},x=r=>{const i=te(r);m({...i,label:d.label.trim().length>0?d.label:`${i.label} Custom`})},C=async r=>{var o;const i=(o=r.target.files)==null?void 0:o[0];if(i)try{c(await i.text())}catch(T){b(T instanceof Error?T.message:"Forge could not parse that JSON theme.")}finally{r.target.value=""}},E=[{id:"identity",eyebrow:"Custom theme",title:"Name the mood and choose a starting point",description:"Start from a Forge preset, then tune the accents and surfaces in the next steps.",render:(r,i)=>e.jsxs("div",{className:"grid gap-5",children:[e.jsx(R,{label:"Theme label",description:"This label appears in Settings when the custom theme is active.",children:e.jsx(_,{value:r.label,onChange:o=>i({label:o.target.value}),placeholder:"Midnight Circuit"})}),e.jsx(R,{label:"Starter preset",children:e.jsx(Te,{value:"",onChange:o=>x(o),options:Object.entries(Fe).map(([o,T])=>({value:o,label:T.label,description:T.description})),columns:2})}),e.jsx(K,{theme:r,title:r.label,description:"Live preview of the current custom theme draft."})]})},{id:"accents",eyebrow:"Custom theme",title:"Set the accent colors",description:"These colors drive buttons, highlights, charts, and the ambient shell lighting.",render:(r,i)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(j,{label:"Primary",description:"Main emphasis color for actions and active state.",value:r.primary,onChange:o=>i({primary:o})}),e.jsx(j,{label:"Secondary",description:"Support accent for positive or secondary emphasis.",value:r.secondary,onChange:o=>i({secondary:o})}),e.jsx(j,{label:"Tertiary",description:"Warm contrast color for warnings, highlights, and supporting metrics.",value:r.tertiary,onChange:o=>i({tertiary:o})})]})},{id:"surfaces",eyebrow:"Custom theme",title:"Tune the shell surfaces",description:"Forge currently assumes a dark shell, so these should remain fairly deep colors for legibility.",render:(r,i)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(j,{label:"Canvas",description:"Primary app background.",value:r.canvas,onChange:o=>i({canvas:o})}),e.jsx(j,{label:"Panel",description:"Default card and rail background.",value:r.panel,onChange:o=>i({panel:o})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(j,{label:"Panel high",description:"Raised highlights and stronger sections.",value:r.panelHigh,onChange:o=>i({panelHigh:o})}),e.jsx(j,{label:"Panel low",description:"Lower contrast and deeper card areas.",value:r.panelLow,onChange:o=>i({panelLow:o})})]}),e.jsx(j,{label:"Ink",description:"Main text and readable foreground color.",value:r.ink,onChange:o=>i({ink:o})}),e.jsx(K,{theme:r,title:r.label,description:"Live preview after the current surface edits."})]})},{id:"import",eyebrow:"Custom theme",title:"Import or paste JSON directly",description:"You can skip the picker workflow entirely by uploading a JSON file or pasting a valid theme object.",render:r=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(R,{label:"Direct JSON",description:"Paste a full custom theme object, then click Apply JSON.",children:e.jsx(Pe,{value:g,onChange:i=>u(i.target.value),className:"min-h-52 font-mono text-[13px] leading-6",placeholder:JSON.stringify(A,null,2)})}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(k,{type:"button",variant:"secondary",onClick:()=>{try{c(g)}catch(i){b(i instanceof Error?i.message:"Forge could not parse that JSON theme.")}},children:"Apply JSON"}),e.jsx(k,{type:"button",variant:"ghost",onClick:()=>{var i;return(i=S.current)==null?void 0:i.click()},children:"Upload JSON file"}),e.jsx("input",{ref:S,type:"file",accept:"application/json,.json",className:"hidden",onChange:C})]}),e.jsx(K,{theme:r,title:r.label,description:"Preview of the theme that will be saved if you submit now."})]})}];return e.jsx(Ce,{open:a,onOpenChange:r=>{r&&(m(n),u(""),b(null)),l(r)},eyebrow:"Settings",title:"Forge custom theme",description:"Build a dark Forge palette visually, or import one directly as JSON.",value:d,onChange:r=>{m(r),b(null)},draftPersistenceKey:"settings.theme-customizer",steps:E,error:f,onSubmit:async()=>{try{const r=ee.parse(d);t(r),l(!1)}catch(r){b(r instanceof Error?r.message:"Forge could not save that custom theme.")}},submitLabel:"Save custom theme",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]"})}const N="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",F="text-sm leading-6 text-[var(--ui-ink-soft)]",ie="text-xs leading-5 text-[var(--ui-ink-faint)]",P="rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]",q="rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]";function Ze({theme:a}){return e.jsx("div",{className:"mt-3 grid grid-cols-4 gap-2",children:[a.primary,a.secondary,a.tertiary,a.panelHigh].map(l=>e.jsx("div",{className:"h-6 rounded-[10px] border border-[var(--ui-border-subtle)]",style:{background:l}},l))})}function Ve({selected:a,theme:l}){return e.jsxs("div",{className:"relative min-h-[138px] overflow-hidden rounded-[18px] border border-[var(--ui-border-subtle)] bg-[linear-gradient(145deg,var(--ui-surface-2),var(--ui-surface-1))]",children:[e.jsx("div",{className:"absolute inset-x-0 bottom-0 h-16 bg-[linear-gradient(0deg,color-mix(in_srgb,var(--ui-surface-3)_82%,transparent),transparent)]"}),e.jsx("img",{src:Je(l),alt:`${l} neutral Forge Smith mascot preview`,className:"absolute bottom-1 left-1/2 h-[124px] w-[124px] -translate-x-1/2 object-contain drop-shadow-[0_18px_30px_color-mix(in_srgb,var(--ui-shadow-color)_30%,transparent)]"}),e.jsxs("div",{className:"absolute left-3 top-3 flex items-center gap-2 rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] px-2.5 py-1 text-[9px] font-semibold uppercase tracking-[0.14em] text-[var(--ui-ink-medium)] backdrop-blur-md",children:[e.jsx(ye,{className:"size-3 text-[var(--warning)]"}),"Live rewards"]}),e.jsx("div",{className:"absolute bottom-3 left-3 flex items-center gap-1.5",children:Ke.map(n=>e.jsx("span",{className:"grid size-11 place-items-center overflow-hidden rounded-[12px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] p-1 shadow-[var(--ui-shadow-soft)] backdrop-blur-md",children:e.jsx("img",{src:Oe(l,n),alt:`${l} reward thumbnail`,className:"size-full object-contain"})},n))}),e.jsx("span",{className:`absolute right-3 top-3 grid size-7 place-items-center rounded-full border ${a?"border-[color-mix(in_srgb,var(--success)_42%,var(--ui-border-subtle)_58%)] bg-[var(--ui-success-soft)] text-[var(--success)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] text-[var(--ui-ink-faint)]"}`,children:a?e.jsx(je,{className:"size-4"}):null})]})}function re({healthy:a}){return e.jsx($,{className:"p-4",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:N,children:"Mobile companion"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:a?"iPhone bridge is syncing":"Connect the iPhone bridge"}),e.jsx("div",{className:`mt-1 max-w-3xl ${F}`,children:a?"Review HealthKit, movement, and background sync permissions.":"Pair or refresh the native companion before relying on HealthKit, movement, or watch signals."})]}),e.jsx(fe,{to:"/settings/mobile",className:"inline-flex min-h-10 items-center rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 py-2 text-sm text-[var(--ui-ink-strong)] transition hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]",children:"Open mobile settings"})]})})}function z(a){return new Date(a).toLocaleString()}function ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t}){return t?[t.integrity.headline,t.integrity.topIssues.length>0?t.integrity.topIssues[0].summary:"No active Doctor warnings are holding back integrity.",`Storage mode: ${l}. Latest Doctor run: ${z(t.integrity.lastCheckedAt)}.`]:a>=100?["All currently reported settings and storage checks passed.",`Latest audit: ${z(n)}.`]:[`Forge is holding back ${Math.max(0,100-a)}% because the latest settings and storage audit reported a consistency warning.`,"The current audit only exposes the aggregate score, so per-check details are not available yet.",`Storage mode: ${l}. Latest audit: ${z(n)}.`]}function le({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t}){const d=(t==null?void 0:t.integrity.score)??a,m=ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t});return e.jsxs("details",{className:"group relative inline-flex",children:[e.jsxs("summary",{className:"inline-flex cursor-pointer list-none items-center gap-1 rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-2.5 py-1 text-[11px] font-medium normal-case tracking-normal text-[var(--ui-ink-soft)] transition marker:hidden hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--primary)_32%,transparent)] [&::-webkit-details-marker]:hidden",onKeyDown:g=>{var u;g.key==="Escape"&&((u=g.currentTarget.parentElement)==null||u.removeAttribute("open"))},children:[e.jsx(be,{className:"size-3.5","aria-hidden":"true"}),d,"% integrity"]}),e.jsxs("span",{role:"tooltip",className:"surface-modal-panel absolute right-0 top-[calc(100%+0.55rem)] z-50 hidden w-[min(19rem,calc(100vw-2rem))] rounded-[16px] border px-3 py-2.5 text-left text-xs leading-5 tracking-normal text-[var(--ui-ink-soft)] normal-case shadow-[var(--ui-shadow-strong)] group-open:block",children:[e.jsx("span",{className:"block font-medium text-[var(--ui-ink-strong)]",children:d>=100?"Integrity is complete":`Why this is ${d}%`}),m.map(g=>e.jsx("span",{className:"mt-1 block",children:g},g))]})]})}function es({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t,doctorLoading:d,onRefreshDoctor:m,onApplyFix:g,applyingFixId:u}){const f=(t==null?void 0:t.integrity.score)??a,b=(t==null?void 0:t.integrity.lastCheckedAt)??n,S=(t==null?void 0:t.issues.filter(x=>x.severity!=="info").slice(0,4))??[],[c]=ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t});return e.jsxs($,{className:"p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:N,children:"Security posture"}),e.jsx("div",{className:`mt-1 ${F}`,children:"Local-first means Forge stores its runtime data on this machine. Integrity is the latest internal consistency score from settings and data checks."}),e.jsx("div",{className:`mt-2 ${ie}`,children:c})]}),e.jsx(le,{integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t})]}),e.jsxs("div",{className:"mt-3 grid gap-2 md:grid-cols-2",children:[e.jsxs("div",{className:`${q} px-3 py-3`,children:[e.jsx("div",{className:"text-xs text-[var(--ui-ink-soft)]",children:"Storage mode"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:l})]}),e.jsxs("div",{className:`${q} px-3 py-3`,children:[e.jsx("div",{className:"text-xs text-[var(--ui-ink-soft)]",children:"Last Doctor run"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:z(b)})]})]}),e.jsxs("div",{className:`mt-3 ${q} p-3`,children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium text-[var(--ui-ink-strong)]",children:[e.jsx(Ne,{className:"size-4 text-[var(--info)]"}),"Forge Doctor"]}),e.jsxs(k,{type:"button",variant:"secondary",pending:d,onClick:m,children:[e.jsx(we,{className:"size-4"}),"Run"]})]}),e.jsx("div",{className:`mt-2 ${F}`,children:t?`${f}% integrity. ${t.integrity.headline}`:"Run Doctor to check settings, storage, entities, rewards, and runtime consistency."}),S.length>0?e.jsx("div",{className:"mt-3 grid gap-2",children:S.map(x=>{var C;return e.jsx(ss,{issue:x,applying:u===((C=x.fix)==null?void 0:C.id),onApplyFix:g},x.id)})}):t?e.jsx("div",{className:"mt-3 rounded-[12px] border border-[color-mix(in_srgb,var(--success)_24%,var(--ui-border-subtle)_76%)] bg-[var(--ui-success-soft)] px-3 py-2 text-sm text-[var(--success)]",children:"No active consistency warnings."}):null]})]})}function ss({issue:a,applying:l,onApplyFix:n}){var t;return e.jsx("div",{className:`${q} px-3 py-2`,children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-faint)]",children:[a.group," / ",a.severity]}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-medium)]",children:a.summary})]}),((t=a.fix)==null?void 0:t.kind)==="safe_auto_fix"?e.jsx(k,{type:"button",variant:"secondary",pending:l,onClick:()=>n(a.fix.id),children:"Apply fix"}):null]})})}function ms(){var W,Y,X,Z,V;const{t:a}=_e(),l=$e(),n=ke(),[t,d]=w.useState(!1),m=L({queryKey:["forge-operator-session"],queryFn:Ge}),g=m.isSuccess,u=L({queryKey:["forge-settings"],queryFn:He,enabled:g}),f=De(void 0,{skip:!g}),b=L({queryKey:["forge-companion-overview"],queryFn:async()=>(await Ue()).overview,enabled:g,staleTime:3e4}),S=L({queryKey:["forge-gamification-assets"],queryFn:Be,enabled:g,staleTime:3e4}),c=Se({defaultValues:{profile:{operatorName:"",operatorEmail:"",operatorTitle:""},notifications:{goalDriftAlerts:!0,dailyQuestReminders:!0,achievementCelebrations:!0},execution:{maxActiveTasks:2,timeAccountingMode:"split"},themePreference:"obsidian",gamificationTheme:"dramatic-smithie",customTheme:A,localePreference:"en"}}),x=async()=>{await Promise.all([n.invalidateQueries({queryKey:["forge-operator-session"]}),n.invalidateQueries({queryKey:["forge-settings"]})])},C=M({mutationFn:s=>Q(s),onSuccess:x}),E=M({mutationFn:s=>Q(s),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await x()}}),r=M({mutationFn:s=>Q(s),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await x()}}),i=M({mutationFn:async s=>(await Ae(s),Q({gamificationTheme:s})),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await Promise.all([n.invalidateQueries({queryKey:["forge-settings"]}),n.invalidateQueries({queryKey:["forge-gamification-assets"]})])}}),[o,T]=Ee(),[oe,ce]=Ie(),[de,O]=w.useState(),ue=async()=>{await o().unwrap(),l(qe([])),l(ze.util.resetApiState()),n.removeQueries({predicate:s=>{const[v]=s.queryKey;return typeof v=="string"&&v.startsWith("forge-")}}),await Promise.all([x(),m.refetch()])};w.useEffect(()=>{var s;(s=u.data)!=null&&s.settings&&c.reset(Le.parse(u.data.settings))},[u.data,c]);const p=(W=u.data)==null?void 0:W.settings,me=(Y=f.data)==null?void 0:Y.doctor,D=c.watch("themePreference"),G=c.watch("gamificationTheme"),H=((X=S.data)==null?void 0:X.assets.styles)??[],J=H.find(s=>s.id===G),y=c.watch("customTheme")??A,U=((Z=b.data)==null?void 0:Z.healthState)==="healthy_sync",pe=async s=>{if(window.confirm("Apply this Forge Doctor fix? Forge will only run the selected safe repair.")){O(s);try{await oe({fixIds:[s]}).unwrap(),await Promise.all([u.refetch(),f.refetch()])}finally{O(void 0)}}},B=async(s,v=y)=>{c.setValue("themePreference",s,{shouldDirty:!0}),c.setValue("customTheme",v??A,{shouldDirty:!0}),await E.mutateAsync({themePreference:s,customTheme:v??A})},ge=async s=>{c.setValue("gamificationTheme",s,{shouldDirty:!0}),await r.mutateAsync({gamificationTheme:s})};return w.useEffect(()=>{if(p)return se(D,y),()=>{se(p.themePreference,p.customTheme??null)}},[y,D,p,p==null?void 0:p.customTheme,p==null?void 0:p.themePreference]),m.isLoading||u.isLoading?e.jsx(Me,{eyebrow:"Settings",title:"Loading settings",description:"Establishing the operator session and fetching current configuration.",columns:2,blocks:6}):m.isError?e.jsx(ae,{eyebrow:"Settings",error:m.error,onRetry:()=>void m.refetch()}):u.isError||!p?e.jsx(ae,{eyebrow:"Settings",error:u.error??new Error("Forge returned an empty settings payload."),onRetry:()=>void u.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(Ye,{title:"Settings",description:"Tune execution policy, timer behaviour, and personal preferences.",badge:e.jsx(le,{integrityScore:p.security.integrityScore,storageMode:p.security.storageMode,lastAuditAt:p.security.lastAuditAt})}),null,e.jsx(We,{}),(V=m.data)!=null&&V.session?e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[18px] border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:[e.jsxs("div",{children:["Operator session active as"," ",e.jsx("span",{className:"font-medium text-[var(--ui-ink-strong)]",children:m.data.session.actorLabel}),"."]}),e.jsx(k,{variant:"secondary",size:"sm",pending:T.isLoading,pendingLabel:"Resetting session",onClick:()=>void ue(),children:"Reset operator session"})]}):null,e.jsxs("div",{className:"grid gap-4",children:[U?null:e.jsx(re,{healthy:!1}),e.jsxs("form",{className:"grid gap-4",onSubmit:c.handleSubmit(async s=>{await C.mutateAsync(s)}),children:[e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:"Operator profile"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Name"}),e.jsx(_,{...c.register("profile.operatorName")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Email"}),e.jsx(_,{...c.register("profile.operatorEmail")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Title"}),e.jsx(_,{...c.register("profile.operatorTitle")})]}),e.jsx("div",{className:`mt-2 ${N}`,children:"Execution policy"}),e.jsxs("div",{className:"grid gap-3 lg:grid-cols-[minmax(0,0.7fr)_minmax(0,1.3fr)]",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Maximum active tasks"}),e.jsx(_,{type:"number",min:1,max:8,...c.register("execution.maxActiveTasks",{valueAsNumber:!0})})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Time accounting mode"}),e.jsx("div",{className:"grid gap-2 md:grid-cols-3",children:[{value:"split",label:"Split",description:"Multitasking divides credited time across active tasks."},{value:"parallel",label:"Parallel",description:"Every active task receives full credited wall time."},{value:"primary_only",label:"Primary only",description:"Only the highlighted task earns credited time during overlap."}].map(s=>e.jsxs("label",{className:`grid gap-2 ${P} px-3 py-3`,children:[e.jsxs("span",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"radio",value:s.value,...c.register("execution.timeAccountingMode")}),e.jsx("span",{className:"text-[var(--ui-ink-strong)]",children:s.label})]}),e.jsx("span",{className:ie,children:s.description})]},s.value))})]})]}),e.jsx("div",{className:`mt-2 ${N}`,children:"Notification rules"}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Goal drift alerts"}),e.jsx("input",{type:"checkbox",...c.register("notifications.goalDriftAlerts")})]}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Daily quest reminders"}),e.jsx("input",{type:"checkbox",...c.register("notifications.dailyQuestReminders")})]}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Achievement celebrations"}),e.jsx("input",{type:"checkbox",...c.register("notifications.achievementCelebrations")})]})]}),e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:"Theme calibration"}),e.jsx("p",{className:F,children:"Switch between Forge dark and light presets, follow the system palette, or save your own shell theme."}),e.jsx("div",{className:"grid gap-2 xl:grid-cols-3",children:Qe.map(s=>{const v=te(s.value,y),h=D===s.value;return e.jsxs("button",{type:"button",onClick:()=>void B(s.value,(s.value==="custom",y)),className:`rounded-[18px] border px-3 py-3 text-left transition ${h?"border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]"}`,children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:s.value==="custom"?y.label:s.label}),e.jsx("div",{className:"mt-1 line-clamp-2 text-xs leading-5 text-[var(--ui-ink-soft)]",children:s.description})]}),e.jsx("div",{className:`mt-1 size-4 rounded-full border ${h?"border-[color-mix(in_srgb,var(--primary)_65%,var(--ui-border-subtle)_35%)] bg-[var(--primary)]":"border-[var(--ui-border-strong)]"}`})]}),e.jsx(Ze,{theme:v})]},s.value)})}),e.jsxs("div",{className:`mt-3 flex flex-wrap items-center justify-between gap-3 ${P} px-3 py-3`,children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Custom theme editor"}),e.jsx("div",{className:`mt-1 ${F}`,children:"Save a custom Forge palette through a guided modal, or paste and upload JSON directly."})]}),e.jsx(k,{type:"button",variant:D==="custom"?"secondary":"ghost",onClick:()=>d(!0),pending:E.isPending,children:D==="custom"?"Edit custom theme":"Create custom theme"})]})]}),e.jsxs($,{className:"p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:N,children:"Gamification style"}),e.jsx("p",{className:F,children:"Choose the reward art style and download its optional trophy, unlock, and mascot sprites."})]}),J!=null&&J.installed?e.jsx("span",{className:"inline-flex rounded-full border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-3 py-1 text-xs font-medium text-[var(--success)]",children:"Selected style downloaded"}):e.jsx("span",{className:"inline-flex rounded-full border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] px-3 py-1 text-xs font-medium text-[var(--warning)]",children:"Selected style not downloaded"})]}),e.jsx("div",{className:"mt-3 grid gap-2 xl:grid-cols-3",children:Re.map(s=>{const v=G===s.value,h=H.find(he=>he.id===s.value),I=(h==null?void 0:h.installed)??!1,xe=i.isPending&&i.variables===s.value;return e.jsxs("div",{className:`grid gap-2 rounded-[18px] border p-2.5 text-left transition ${v?"border-[color-mix(in_srgb,var(--warning)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-warning-soft)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]"}`,children:[e.jsx("button",{type:"button",onClick:()=>void ge(s.value),className:"grid gap-2 text-left","aria-label":`Select ${s.label}`,"aria-pressed":v,children:e.jsx(Ve,{selected:v,theme:s.value})}),e.jsxs("span",{className:"grid gap-1 px-1 pb-1",children:[e.jsx("span",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:s.label}),e.jsx("span",{className:"line-clamp-2 text-xs leading-5 text-[var(--ui-ink-soft)]",children:s.description}),e.jsx("span",{className:"mt-1 text-[11px] uppercase tracking-[0.14em] text-[var(--ui-ink-faint)]",children:I?`Downloaded ${(h==null?void 0:h.spriteCount)??0}/${(h==null?void 0:h.expectedSpriteCount)??0}`:"Not downloaded"}),e.jsxs(k,{type:"button",variant:I?"secondary":"primary",pending:xe,disabled:I||i.isPending,onClick:()=>i.mutate(s.value),children:[e.jsx(ve,{className:"size-4"}),I?"Downloaded":"Download"]})]})]},s.value)})}),r.isPending?e.jsx("div",{className:"text-sm text-[var(--ui-ink-faint)]",children:"Saving reward style…"}):null,i.isError?e.jsx("div",{className:"mt-3 rounded-[14px] border border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] px-3 py-2 text-sm text-[var(--danger)]",children:i.error instanceof Error?i.error.message:"Could not download the selected reward art."}):null]}),e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:a("common.settings.localeLabel")}),e.jsx("p",{className:F,children:a("common.settings.localeDescription")}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:[{value:"en",label:a("common.settings.localeEnglish")},{value:"fr",label:a("common.settings.localeFrench")}].map(s=>e.jsxs("label",{className:`flex items-center gap-3 ${P} px-3 py-3`,children:[e.jsx("input",{type:"radio",value:s.value,...c.register("localePreference")}),e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:s.label})]},s.value))}),e.jsx(k,{type:"submit",pending:C.isPending,pendingLabel:"Saving settings",children:"Save settings"})]})]}),U?e.jsx(re,{healthy:!0}):null,e.jsx(es,{integrityScore:p.security.integrityScore,storageMode:p.security.storageMode,lastAuditAt:p.security.lastAuditAt,doctor:me,doctorLoading:f.isFetching||ce.isLoading,onRefreshDoctor:()=>void f.refetch(),onApplyFix:s=>void pe(s),applyingFixId:de})]}),e.jsx(Xe,{open:t,onOpenChange:d,value:y,onSave:s=>void B("custom",s)})]})}export{ms as SettingsPage};
|
|
1
|
+
import{r as w,j as e,aD as ve,d8 as be,aC as fe,aG as ye,bl as je,d9 as Ne,aQ as we}from"./vendor-Dnkkx2co.js";import{j as ke,i as L,k as M}from"./state-vCcAT5Hq.js";import{u as Se}from"./forms-hB0SqEh-.js";import{Q as Ce,db as ee,F as R,I as _,j as Te,dc as Fe,T as Pe,dd as A,B as k,de as te,P as _e,aI as $e,df as De,dg as Q,dh as Ae,di as Ee,dj as Ie,dk as Le,dl as se,S as Me,E as ae,C as $,dm as Qe,dn as Re,dp as qe,dq as ze,dr as Je,ds as Ke,dt as Oe,du as Ge,dv as He,dw as Ue,dx as Be}from"./index-BhkubYaC.js";import{S as We}from"./settings-section-nav-kFFQSJEe.js";import{P as Ye}from"./page-hero-DzEsy8i5.js";import"./motion-Lt5B1XuE.js";import"./ui-C1iwpj2-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";function K({theme:a,title:l,description:n}){return e.jsx("div",{className:"overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)]",style:{background:`linear-gradient(180deg, ${a.panelHigh}, ${a.panelLow})`,color:a.ink},children:e.jsxs("div",{className:"px-4 py-4",style:{background:`radial-gradient(circle at top left, ${a.primary}33, transparent 42%), radial-gradient(circle at top right, ${a.secondary}2a, transparent 36%), linear-gradient(180deg, ${a.panel}, ${a.canvas})`},children:[e.jsx("div",{className:"text-xs uppercase tracking-[0.2em] opacity-60",children:"Preview"}),e.jsx("div",{className:"mt-2 font-display text-xl",children:l}),e.jsx("div",{className:"mt-2 text-sm leading-6 opacity-72",children:n}),e.jsx("div",{className:"mt-5 flex gap-2",children:[a.primary,a.secondary,a.tertiary,a.panelHigh].map(t=>e.jsx("div",{className:"h-9 flex-1 rounded-[14px] border border-[var(--ui-border-subtle)]",style:{background:t}},t))})]})})}function j({label:a,value:l,onChange:n,description:t}){return e.jsx(R,{label:a,description:t,children:e.jsxs("div",{className:"grid gap-3 sm:grid-cols-[5.5rem_minmax(0,1fr)]",children:[e.jsx("input",{type:"color",value:l,onChange:d=>n(d.target.value),className:"h-12 w-full cursor-pointer rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-1"}),e.jsx(_,{value:l,onChange:d=>n(d.target.value),placeholder:"#7cc7ff"})]})})}function Xe({open:a,onOpenChange:l,value:n,onSave:t}){const[d,m]=w.useState(n),[g,u]=w.useState(""),[f,b]=w.useState(null),S=w.useRef(null),c=r=>{const i=ee.parse(JSON.parse(r));m(i),u(JSON.stringify(i,null,2)),b(null)},x=r=>{const i=te(r);m({...i,label:d.label.trim().length>0?d.label:`${i.label} Custom`})},C=async r=>{var o;const i=(o=r.target.files)==null?void 0:o[0];if(i)try{c(await i.text())}catch(T){b(T instanceof Error?T.message:"Forge could not parse that JSON theme.")}finally{r.target.value=""}},E=[{id:"identity",eyebrow:"Custom theme",title:"Name the mood and choose a starting point",description:"Start from a Forge preset, then tune the accents and surfaces in the next steps.",render:(r,i)=>e.jsxs("div",{className:"grid gap-5",children:[e.jsx(R,{label:"Theme label",description:"This label appears in Settings when the custom theme is active.",children:e.jsx(_,{value:r.label,onChange:o=>i({label:o.target.value}),placeholder:"Midnight Circuit"})}),e.jsx(R,{label:"Starter preset",children:e.jsx(Te,{value:"",onChange:o=>x(o),options:Object.entries(Fe).map(([o,T])=>({value:o,label:T.label,description:T.description})),columns:2})}),e.jsx(K,{theme:r,title:r.label,description:"Live preview of the current custom theme draft."})]})},{id:"accents",eyebrow:"Custom theme",title:"Set the accent colors",description:"These colors drive buttons, highlights, charts, and the ambient shell lighting.",render:(r,i)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(j,{label:"Primary",description:"Main emphasis color for actions and active state.",value:r.primary,onChange:o=>i({primary:o})}),e.jsx(j,{label:"Secondary",description:"Support accent for positive or secondary emphasis.",value:r.secondary,onChange:o=>i({secondary:o})}),e.jsx(j,{label:"Tertiary",description:"Warm contrast color for warnings, highlights, and supporting metrics.",value:r.tertiary,onChange:o=>i({tertiary:o})})]})},{id:"surfaces",eyebrow:"Custom theme",title:"Tune the shell surfaces",description:"Forge currently assumes a dark shell, so these should remain fairly deep colors for legibility.",render:(r,i)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(j,{label:"Canvas",description:"Primary app background.",value:r.canvas,onChange:o=>i({canvas:o})}),e.jsx(j,{label:"Panel",description:"Default card and rail background.",value:r.panel,onChange:o=>i({panel:o})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(j,{label:"Panel high",description:"Raised highlights and stronger sections.",value:r.panelHigh,onChange:o=>i({panelHigh:o})}),e.jsx(j,{label:"Panel low",description:"Lower contrast and deeper card areas.",value:r.panelLow,onChange:o=>i({panelLow:o})})]}),e.jsx(j,{label:"Ink",description:"Main text and readable foreground color.",value:r.ink,onChange:o=>i({ink:o})}),e.jsx(K,{theme:r,title:r.label,description:"Live preview after the current surface edits."})]})},{id:"import",eyebrow:"Custom theme",title:"Import or paste JSON directly",description:"You can skip the picker workflow entirely by uploading a JSON file or pasting a valid theme object.",render:r=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(R,{label:"Direct JSON",description:"Paste a full custom theme object, then click Apply JSON.",children:e.jsx(Pe,{value:g,onChange:i=>u(i.target.value),className:"min-h-52 font-mono text-[13px] leading-6",placeholder:JSON.stringify(A,null,2)})}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(k,{type:"button",variant:"secondary",onClick:()=>{try{c(g)}catch(i){b(i instanceof Error?i.message:"Forge could not parse that JSON theme.")}},children:"Apply JSON"}),e.jsx(k,{type:"button",variant:"ghost",onClick:()=>{var i;return(i=S.current)==null?void 0:i.click()},children:"Upload JSON file"}),e.jsx("input",{ref:S,type:"file",accept:"application/json,.json",className:"hidden",onChange:C})]}),e.jsx(K,{theme:r,title:r.label,description:"Preview of the theme that will be saved if you submit now."})]})}];return e.jsx(Ce,{open:a,onOpenChange:r=>{r&&(m(n),u(""),b(null)),l(r)},eyebrow:"Settings",title:"Forge custom theme",description:"Build a dark Forge palette visually, or import one directly as JSON.",value:d,onChange:r=>{m(r),b(null)},draftPersistenceKey:"settings.theme-customizer",steps:E,error:f,onSubmit:async()=>{try{const r=ee.parse(d);t(r),l(!1)}catch(r){b(r instanceof Error?r.message:"Forge could not save that custom theme.")}},submitLabel:"Save custom theme",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]"})}const N="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",F="text-sm leading-6 text-[var(--ui-ink-soft)]",ie="text-xs leading-5 text-[var(--ui-ink-faint)]",P="rounded-[16px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]",q="rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)]";function Ze({theme:a}){return e.jsx("div",{className:"mt-3 grid grid-cols-4 gap-2",children:[a.primary,a.secondary,a.tertiary,a.panelHigh].map(l=>e.jsx("div",{className:"h-6 rounded-[10px] border border-[var(--ui-border-subtle)]",style:{background:l}},l))})}function Ve({selected:a,theme:l}){return e.jsxs("div",{className:"relative min-h-[138px] overflow-hidden rounded-[18px] border border-[var(--ui-border-subtle)] bg-[linear-gradient(145deg,var(--ui-surface-2),var(--ui-surface-1))]",children:[e.jsx("div",{className:"absolute inset-x-0 bottom-0 h-16 bg-[linear-gradient(0deg,color-mix(in_srgb,var(--ui-surface-3)_82%,transparent),transparent)]"}),e.jsx("img",{src:Je(l),alt:`${l} neutral Forge Smith mascot preview`,className:"absolute bottom-1 left-1/2 h-[124px] w-[124px] -translate-x-1/2 object-contain drop-shadow-[0_18px_30px_color-mix(in_srgb,var(--ui-shadow-color)_30%,transparent)]"}),e.jsxs("div",{className:"absolute left-3 top-3 flex items-center gap-2 rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] px-2.5 py-1 text-[9px] font-semibold uppercase tracking-[0.14em] text-[var(--ui-ink-medium)] backdrop-blur-md",children:[e.jsx(ye,{className:"size-3 text-[var(--warning)]"}),"Live rewards"]}),e.jsx("div",{className:"absolute bottom-3 left-3 flex items-center gap-1.5",children:Ke.map(n=>e.jsx("span",{className:"grid size-11 place-items-center overflow-hidden rounded-[12px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] p-1 shadow-[var(--ui-shadow-soft)] backdrop-blur-md",children:e.jsx("img",{src:Oe(l,n),alt:`${l} reward thumbnail`,className:"size-full object-contain"})},n))}),e.jsx("span",{className:`absolute right-3 top-3 grid size-7 place-items-center rounded-full border ${a?"border-[color-mix(in_srgb,var(--success)_42%,var(--ui-border-subtle)_58%)] bg-[var(--ui-success-soft)] text-[var(--success)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-glass)] text-[var(--ui-ink-faint)]"}`,children:a?e.jsx(je,{className:"size-4"}):null})]})}function re({healthy:a}){return e.jsx($,{className:"p-4",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-4",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:N,children:"Mobile companion"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:a?"iPhone bridge is syncing":"Connect the iPhone bridge"}),e.jsx("div",{className:`mt-1 max-w-3xl ${F}`,children:a?"Review HealthKit, movement, and background sync permissions.":"Pair or refresh the native companion before relying on HealthKit, movement, or watch signals."})]}),e.jsx(fe,{to:"/settings/mobile",className:"inline-flex min-h-10 items-center rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-3 py-2 text-sm text-[var(--ui-ink-strong)] transition hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]",children:"Open mobile settings"})]})})}function z(a){return new Date(a).toLocaleString()}function ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t}){return t?[t.integrity.headline,t.integrity.topIssues.length>0?t.integrity.topIssues[0].summary:"No active Doctor warnings are holding back integrity.",`Storage mode: ${l}. Latest Doctor run: ${z(t.integrity.lastCheckedAt)}.`]:a>=100?["All currently reported settings and storage checks passed.",`Latest audit: ${z(n)}.`]:[`Forge is holding back ${Math.max(0,100-a)}% because the latest settings and storage audit reported a consistency warning.`,"The current audit only exposes the aggregate score, so per-check details are not available yet.",`Storage mode: ${l}. Latest audit: ${z(n)}.`]}function le({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t}){const d=(t==null?void 0:t.integrity.score)??a,m=ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t});return e.jsxs("details",{className:"group relative inline-flex",children:[e.jsxs("summary",{className:"inline-flex cursor-pointer list-none items-center gap-1 rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-2.5 py-1 text-[11px] font-medium normal-case tracking-normal text-[var(--ui-ink-soft)] transition marker:hidden hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[color-mix(in_srgb,var(--primary)_32%,transparent)] [&::-webkit-details-marker]:hidden",onKeyDown:g=>{var u;g.key==="Escape"&&((u=g.currentTarget.parentElement)==null||u.removeAttribute("open"))},children:[e.jsx(be,{className:"size-3.5","aria-hidden":"true"}),d,"% integrity"]}),e.jsxs("span",{role:"tooltip",className:"surface-modal-panel absolute right-0 top-[calc(100%+0.55rem)] z-50 hidden w-[min(19rem,calc(100vw-2rem))] rounded-[16px] border px-3 py-2.5 text-left text-xs leading-5 tracking-normal text-[var(--ui-ink-soft)] normal-case shadow-[var(--ui-shadow-strong)] group-open:block",children:[e.jsx("span",{className:"block font-medium text-[var(--ui-ink-strong)]",children:d>=100?"Integrity is complete":`Why this is ${d}%`}),m.map(g=>e.jsx("span",{className:"mt-1 block",children:g},g))]})]})}function es({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t,doctorLoading:d,onRefreshDoctor:m,onApplyFix:g,applyingFixId:u}){const f=(t==null?void 0:t.integrity.score)??a,b=(t==null?void 0:t.integrity.lastCheckedAt)??n,S=(t==null?void 0:t.issues.filter(x=>x.severity!=="info").slice(0,4))??[],[c]=ne({integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t});return e.jsxs($,{className:"p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:N,children:"Security posture"}),e.jsx("div",{className:`mt-1 ${F}`,children:"Local-first means Forge stores its runtime data on this machine. Integrity is the latest internal consistency score from settings and data checks."}),e.jsx("div",{className:`mt-2 ${ie}`,children:c})]}),e.jsx(le,{integrityScore:a,storageMode:l,lastAuditAt:n,doctor:t})]}),e.jsxs("div",{className:"mt-3 grid gap-2 md:grid-cols-2",children:[e.jsxs("div",{className:`${q} px-3 py-3`,children:[e.jsx("div",{className:"text-xs text-[var(--ui-ink-soft)]",children:"Storage mode"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:l})]}),e.jsxs("div",{className:`${q} px-3 py-3`,children:[e.jsx("div",{className:"text-xs text-[var(--ui-ink-soft)]",children:"Last Doctor run"}),e.jsx("div",{className:"mt-1 text-base font-medium text-[var(--ui-ink-strong)]",children:z(b)})]})]}),e.jsxs("div",{className:`mt-3 ${q} p-3`,children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-2",children:[e.jsxs("div",{className:"flex items-center gap-2 text-sm font-medium text-[var(--ui-ink-strong)]",children:[e.jsx(Ne,{className:"size-4 text-[var(--info)]"}),"Forge Doctor"]}),e.jsxs(k,{type:"button",variant:"secondary",pending:d,onClick:m,children:[e.jsx(we,{className:"size-4"}),"Run"]})]}),e.jsx("div",{className:`mt-2 ${F}`,children:t?`${f}% integrity. ${t.integrity.headline}`:"Run Doctor to check settings, storage, entities, rewards, and runtime consistency."}),S.length>0?e.jsx("div",{className:"mt-3 grid gap-2",children:S.map(x=>{var C;return e.jsx(ss,{issue:x,applying:u===((C=x.fix)==null?void 0:C.id),onApplyFix:g},x.id)})}):t?e.jsx("div",{className:"mt-3 rounded-[12px] border border-[color-mix(in_srgb,var(--success)_24%,var(--ui-border-subtle)_76%)] bg-[var(--ui-success-soft)] px-3 py-2 text-sm text-[var(--success)]",children:"No active consistency warnings."}):null]})]})}function ss({issue:a,applying:l,onApplyFix:n}){var t;return e.jsx("div",{className:`${q} px-3 py-2`,children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-2",children:[e.jsxs("div",{children:[e.jsxs("div",{className:"text-xs uppercase tracking-[0.14em] text-[var(--ui-ink-faint)]",children:[a.group," / ",a.severity]}),e.jsx("div",{className:"mt-1 text-sm text-[var(--ui-ink-medium)]",children:a.summary})]}),((t=a.fix)==null?void 0:t.kind)==="safe_auto_fix"?e.jsx(k,{type:"button",variant:"secondary",pending:l,onClick:()=>n(a.fix.id),children:"Apply fix"}):null]})})}function ms(){var W,Y,X,Z,V;const{t:a}=_e(),l=$e(),n=ke(),[t,d]=w.useState(!1),m=L({queryKey:["forge-operator-session"],queryFn:Ge}),g=m.isSuccess,u=L({queryKey:["forge-settings"],queryFn:He,enabled:g}),f=De(void 0,{skip:!g}),b=L({queryKey:["forge-companion-overview"],queryFn:async()=>(await Ue()).overview,enabled:g,staleTime:3e4}),S=L({queryKey:["forge-gamification-assets"],queryFn:Be,enabled:g,staleTime:3e4}),c=Se({defaultValues:{profile:{operatorName:"",operatorEmail:"",operatorTitle:""},notifications:{goalDriftAlerts:!0,dailyQuestReminders:!0,achievementCelebrations:!0},execution:{maxActiveTasks:2,timeAccountingMode:"split"},themePreference:"obsidian",gamificationTheme:"dramatic-smithie",customTheme:A,localePreference:"en"}}),x=async()=>{await Promise.all([n.invalidateQueries({queryKey:["forge-operator-session"]}),n.invalidateQueries({queryKey:["forge-settings"]})])},C=M({mutationFn:s=>Q(s),onSuccess:x}),E=M({mutationFn:s=>Q(s),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await x()}}),r=M({mutationFn:s=>Q(s),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await x()}}),i=M({mutationFn:async s=>(await Ae(s),Q({gamificationTheme:s})),onSuccess:async s=>{n.setQueryData(["forge-settings"],s),await Promise.all([n.invalidateQueries({queryKey:["forge-settings"]}),n.invalidateQueries({queryKey:["forge-gamification-assets"]})])}}),[o,T]=Ee(),[oe,ce]=Ie(),[de,O]=w.useState(),ue=async()=>{await o().unwrap(),l(qe([])),l(ze.util.resetApiState()),n.removeQueries({predicate:s=>{const[v]=s.queryKey;return typeof v=="string"&&v.startsWith("forge-")}}),await Promise.all([x(),m.refetch()])};w.useEffect(()=>{var s;(s=u.data)!=null&&s.settings&&c.reset(Le.parse(u.data.settings))},[u.data,c]);const p=(W=u.data)==null?void 0:W.settings,me=(Y=f.data)==null?void 0:Y.doctor,D=c.watch("themePreference"),G=c.watch("gamificationTheme"),H=((X=S.data)==null?void 0:X.assets.styles)??[],J=H.find(s=>s.id===G),y=c.watch("customTheme")??A,U=((Z=b.data)==null?void 0:Z.healthState)==="healthy_sync",pe=async s=>{if(window.confirm("Apply this Forge Doctor fix? Forge will only run the selected safe repair.")){O(s);try{await oe({fixIds:[s]}).unwrap(),await Promise.all([u.refetch(),f.refetch()])}finally{O(void 0)}}},B=async(s,v=y)=>{c.setValue("themePreference",s,{shouldDirty:!0}),c.setValue("customTheme",v??A,{shouldDirty:!0}),await E.mutateAsync({themePreference:s,customTheme:v??A})},ge=async s=>{c.setValue("gamificationTheme",s,{shouldDirty:!0}),await r.mutateAsync({gamificationTheme:s})};return w.useEffect(()=>{if(p)return se(D,y),()=>{se(p.themePreference,p.customTheme??null)}},[y,D,p,p==null?void 0:p.customTheme,p==null?void 0:p.themePreference]),m.isLoading||u.isLoading?e.jsx(Me,{eyebrow:"Settings",title:"Loading settings",description:"Establishing the operator session and fetching current configuration.",columns:2,blocks:6}):m.isError?e.jsx(ae,{eyebrow:"Settings",error:m.error,onRetry:()=>void m.refetch()}):u.isError||!p?e.jsx(ae,{eyebrow:"Settings",error:u.error??new Error("Forge returned an empty settings payload."),onRetry:()=>void u.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(Ye,{title:"Settings",description:"Tune execution policy, timer behaviour, and personal preferences.",badge:e.jsx(le,{integrityScore:p.security.integrityScore,storageMode:p.security.storageMode,lastAuditAt:p.security.lastAuditAt})}),null,e.jsx(We,{}),(V=m.data)!=null&&V.session?e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[18px] border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-4 py-3 text-sm text-[var(--ui-ink-medium)]",children:[e.jsxs("div",{children:["Operator session active as"," ",e.jsx("span",{className:"font-medium text-[var(--ui-ink-strong)]",children:m.data.session.actorLabel}),"."]}),e.jsx(k,{variant:"secondary",size:"sm",pending:T.isLoading,pendingLabel:"Resetting session",onClick:()=>void ue(),children:"Reset operator session"})]}):null,e.jsxs("div",{className:"grid gap-4",children:[U?null:e.jsx(re,{healthy:!1}),e.jsxs("form",{className:"grid gap-4",onSubmit:c.handleSubmit(async s=>{await C.mutateAsync(s)}),children:[e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:"Operator profile"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Name"}),e.jsx(_,{...c.register("profile.operatorName")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Email"}),e.jsx(_,{...c.register("profile.operatorEmail")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Title"}),e.jsx(_,{...c.register("profile.operatorTitle")})]}),e.jsx("div",{className:`mt-2 ${N}`,children:"Execution policy"}),e.jsxs("div",{className:"grid gap-3 lg:grid-cols-[minmax(0,0.7fr)_minmax(0,1.3fr)]",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Maximum active tasks"}),e.jsx(_,{type:"number",min:1,max:8,...c.register("execution.maxActiveTasks",{valueAsNumber:!0})})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm text-[var(--ui-ink-soft)]",children:"Time accounting mode"}),e.jsx("div",{className:"grid gap-2 md:grid-cols-3",children:[{value:"split",label:"Split",description:"Multitasking divides credited time across active tasks."},{value:"parallel",label:"Parallel",description:"Every active task receives full credited wall time."},{value:"primary_only",label:"Primary only",description:"Only the highlighted task earns credited time during overlap."}].map(s=>e.jsxs("label",{className:`grid gap-2 ${P} px-3 py-3`,children:[e.jsxs("span",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"radio",value:s.value,...c.register("execution.timeAccountingMode")}),e.jsx("span",{className:"text-[var(--ui-ink-strong)]",children:s.label})]}),e.jsx("span",{className:ie,children:s.description})]},s.value))})]})]}),e.jsx("div",{className:`mt-2 ${N}`,children:"Notification rules"}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Goal drift alerts"}),e.jsx("input",{type:"checkbox",...c.register("notifications.goalDriftAlerts")})]}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Daily quest reminders"}),e.jsx("input",{type:"checkbox",...c.register("notifications.dailyQuestReminders")})]}),e.jsxs("label",{className:`flex items-center justify-between ${P} px-3 py-2.5`,children:[e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:"Achievement celebrations"}),e.jsx("input",{type:"checkbox",...c.register("notifications.achievementCelebrations")})]})]}),e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:"Theme calibration"}),e.jsx("p",{className:F,children:"Switch between Forge dark and light presets, follow the system palette, or save your own shell theme."}),e.jsx("div",{className:"grid gap-2 xl:grid-cols-3",children:Qe.map(s=>{const v=te(s.value,y),h=D===s.value;return e.jsxs("button",{type:"button",onClick:()=>void B(s.value,(s.value==="custom",y)),className:`rounded-[18px] border px-3 py-3 text-left transition ${h?"border-[color-mix(in_srgb,var(--primary)_34%,var(--ui-border-subtle)_66%)] bg-[var(--ui-accent-soft)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]"}`,children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:s.value==="custom"?y.label:s.label}),e.jsx("div",{className:"mt-1 line-clamp-2 text-xs leading-5 text-[var(--ui-ink-soft)]",children:s.description})]}),e.jsx("div",{className:`mt-1 size-4 rounded-full border ${h?"border-[color-mix(in_srgb,var(--primary)_65%,var(--ui-border-subtle)_35%)] bg-[var(--primary)]":"border-[var(--ui-border-strong)]"}`})]}),e.jsx(Ze,{theme:v})]},s.value)})}),e.jsxs("div",{className:`mt-3 flex flex-wrap items-center justify-between gap-3 ${P} px-3 py-3`,children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-[var(--ui-ink-strong)]",children:"Custom theme editor"}),e.jsx("div",{className:`mt-1 ${F}`,children:"Save a custom Forge palette through a guided modal, or paste and upload JSON directly."})]}),e.jsx(k,{type:"button",variant:D==="custom"?"secondary":"ghost",onClick:()=>d(!0),pending:E.isPending,children:D==="custom"?"Edit custom theme":"Create custom theme"})]})]}),e.jsxs($,{className:"p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:N,children:"Gamification style"}),e.jsx("p",{className:F,children:"Choose the reward art style and download its optional trophy, unlock, and mascot sprites."})]}),J!=null&&J.installed?e.jsx("span",{className:"inline-flex rounded-full border border-[color-mix(in_srgb,var(--success)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-success-soft)] px-3 py-1 text-xs font-medium text-[var(--success)]",children:"Selected style downloaded"}):e.jsx("span",{className:"inline-flex rounded-full border border-[color-mix(in_srgb,var(--warning)_26%,var(--ui-border-subtle)_74%)] bg-[var(--ui-warning-soft)] px-3 py-1 text-xs font-medium text-[var(--warning)]",children:"Selected style not downloaded"})]}),e.jsx("div",{className:"mt-3 grid gap-2 xl:grid-cols-3",children:Re.map(s=>{const v=G===s.value,h=H.find(he=>he.id===s.value),I=(h==null?void 0:h.installed)??!1,xe=i.isPending&&i.variables===s.value;return e.jsxs("div",{className:`grid gap-2 rounded-[18px] border p-2.5 text-left transition ${v?"border-[color-mix(in_srgb,var(--warning)_30%,var(--ui-border-subtle)_70%)] bg-[var(--ui-warning-soft)] shadow-[var(--ui-shadow-soft)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]"}`,children:[e.jsx("button",{type:"button",onClick:()=>void ge(s.value),className:"grid gap-2 text-left","aria-label":`Select ${s.label}`,"aria-pressed":v,children:e.jsx(Ve,{selected:v,theme:s.value})}),e.jsxs("span",{className:"grid gap-1 px-1 pb-1",children:[e.jsx("span",{className:"text-sm font-semibold text-[var(--ui-ink-strong)]",children:s.label}),e.jsx("span",{className:"line-clamp-2 text-xs leading-5 text-[var(--ui-ink-soft)]",children:s.description}),e.jsx("span",{className:"mt-1 text-[11px] uppercase tracking-[0.14em] text-[var(--ui-ink-faint)]",children:I?`Downloaded ${(h==null?void 0:h.spriteCount)??0}/${(h==null?void 0:h.expectedSpriteCount)??0}`:"Not downloaded"}),e.jsxs(k,{type:"button",variant:I?"secondary":"primary",pending:xe,disabled:I||i.isPending,onClick:()=>i.mutate(s.value),children:[e.jsx(ve,{className:"size-4"}),I?"Downloaded":"Download"]})]})]},s.value)})}),r.isPending?e.jsx("div",{className:"text-sm text-[var(--ui-ink-faint)]",children:"Saving reward style…"}):null,i.isError?e.jsx("div",{className:"mt-3 rounded-[14px] border border-[color-mix(in_srgb,var(--danger)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-danger-soft)] px-3 py-2 text-sm text-[var(--danger)]",children:i.error instanceof Error?i.error.message:"Could not download the selected reward art."}):null]}),e.jsxs($,{className:"p-4",children:[e.jsx("div",{className:N,children:a("common.settings.localeLabel")}),e.jsx("p",{className:F,children:a("common.settings.localeDescription")}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:[{value:"en",label:a("common.settings.localeEnglish")},{value:"fr",label:a("common.settings.localeFrench")}].map(s=>e.jsxs("label",{className:`flex items-center gap-3 ${P} px-3 py-3`,children:[e.jsx("input",{type:"radio",value:s.value,...c.register("localePreference")}),e.jsx("span",{className:"text-[var(--ui-ink-medium)]",children:s.label})]},s.value))}),e.jsx(k,{type:"submit",pending:C.isPending,pendingLabel:"Saving settings",children:"Save settings"})]})]}),U?e.jsx(re,{healthy:!0}):null,e.jsx(es,{integrityScore:p.security.integrityScore,storageMode:p.security.storageMode,lastAuditAt:p.security.lastAuditAt,doctor:me,doctorLoading:f.isFetching||ce.isLoading,onRefreshDoctor:()=>void f.refetch(),onApplyFix:s=>void pe(s),applyingFixId:de})]}),e.jsx(Xe,{open:t,onOpenChange:d,value:y,onSave:s=>void B("custom",s)})]})}export{ms as SettingsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,r as v}from"./vendor-Dnkkx2co.js";import{j as de,i as k,k as U}from"./state-vCcAT5Hq.js";import{u as Y}from"./forms-hB0SqEh-.js";import{S as ce}from"./settings-section-nav-DP9o4peU.js";import{c as p,Z as _,W as ee,f as oe,u as me,eq as ue,er as xe,S as ge,E as pe,C as he,I as J,T as E,B as se,du as be,cW as ve,es as fe,et as je,ad as we}from"./index-EqQsXoat.js";import{m as ae}from"./motion-Lt5B1XuE.js";import{P as ye}from"./page-hero-ffKzgyW3.js";import{M as re}from"./metric-tile-CMadwnGz.js";import"./ui-C1iwpj2-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";function Ne(r){switch(r){case"platinum":return"bg-[var(--ui-accent-soft)] text-[var(--primary)]";case"gold":return"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]";case"silver":return"bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]";default:return"bg-[var(--ui-warning-soft)] text-[var(--warning)]"}}function ke(r){switch(r){case"surging":return"bg-[color-mix(in_srgb,var(--ui-accent-soft)_62%,var(--ui-success-soft)_38%)]";case"steady":return"bg-[var(--ui-accent-soft)]";default:return"bg-[color-mix(in_srgb,var(--ui-warning-soft)_54%,var(--ui-accent-soft)_46%)]"}}const P="min-w-0 overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",te="min-w-0 overflow-hidden rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",A="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",S="text-[var(--ui-ink-strong)]",$="text-[var(--ui-ink-soft)]",I="text-[var(--ui-ink-faint)]",q="bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]";function _e({profile:r,achievements:m,milestoneRewards:d,momentumPulse:u,recentLedger:R=[],className:j,tone:X="core"}){const w=m.filter(t=>t.unlocked),h=(w.length>0?w:m).slice(0,3),C=d.slice(0,3),M=R.slice(0,3),F=Math.min(100,Math.round(r.currentLevelXp/r.nextLevelXp*100));return e.jsxs("section",{className:_("min-w-0 overflow-hidden rounded-[30px] border border-[var(--ui-border-subtle)] bg-[var(--card-gradient)] shadow-[var(--card-shadow)]",X==="psyche"&&"border-[color-mix(in_srgb,var(--success)_18%,var(--ui-border-subtle)_82%)]",j),children:[e.jsx("div",{className:_("px-5 py-5",ke(u.status)),children:e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:A,children:"Weekly progress"}),e.jsx("h2",{className:`mt-3 font-display text-3xl leading-none lg:text-4xl ${S}`,children:u.headline}),e.jsx("p",{className:`mt-3 max-w-3xl text-sm leading-7 ${$}`,children:u.detail})]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap gap-2",children:[e.jsxs(p,{wrap:!0,className:q,children:["Level ",r.level]}),e.jsxs(p,{wrap:!0,className:q,children:[r.streakDays," day streak"]}),e.jsxs(p,{wrap:!0,className:q,children:[r.weeklyXp," weekly XP"]})]})]})}),e.jsxs("div",{className:"grid gap-5 px-5 py-5 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]",children:[e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(ae.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{duration:.24,ease:"easeOut"},className:P,children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:`font-medium ${S}`,children:"Next reward"}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:u.nextMilestoneLabel})]}),e.jsx(p,{wrap:!0,className:"max-w-[12rem] shrink-0 self-start text-[var(--tertiary)]",children:u.celebrationLabel})]}),e.jsx("div",{className:"mt-5",children:e.jsx(ee,{value:F})}),e.jsxs("div",{className:`mt-3 flex flex-wrap items-center justify-between gap-3 text-xs uppercase tracking-[0.16em] ${I}`,children:[e.jsxs("span",{children:[r.currentLevelXp,"/",r.nextLevelXp," XP"]}),e.jsxs("span",{children:[r.comboMultiplier.toFixed(2),"x combo"]})]})]}),e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:h.map((t,c)=>e.jsxs(ae.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.24,delay:.04*c,ease:"easeOut"},className:P,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.title}),e.jsx(p,{wrap:!0,className:_("max-w-[8rem] shrink-0 self-start",Ne(t.tier)),children:t.tier})]}),e.jsx("div",{className:`mt-2 text-sm leading-6 ${$}`,children:t.summary}),e.jsx("div",{className:`mt-4 text-xs uppercase tracking-[0.16em] ${I}`,children:t.progressLabel})]},t.id))})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:P,children:[e.jsx("div",{className:A,children:"Rewards in progress"}),e.jsx("div",{className:"mt-4 grid gap-3",children:C.map(t=>{const c=Math.min(100,Math.round(t.current/t.target*100));return e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.title}),e.jsx(p,{wrap:!0,className:_("max-w-[10.5rem] shrink-0 self-start",t.completed?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":q),children:t.rewardLabel})]}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:t.summary}),e.jsx("div",{className:"mt-4",children:e.jsx(ee,{value:c})}),e.jsx("div",{className:`mt-3 text-xs uppercase tracking-[0.16em] ${I}`,children:t.progressLabel})]},t.id)})})]}),M.length>0?e.jsxs("div",{className:P,children:[e.jsx("div",{className:A,children:"Recent XP changes"}),e.jsx("div",{className:"mt-4 grid gap-3",children:M.map(t=>e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.reasonTitle}),e.jsxs(p,{wrap:!0,className:_("max-w-[8rem] shrink-0 self-start",t.deltaXp>=0?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]"),children:[t.deltaXp>0?"+":"",t.deltaXp," XP"]})]}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:t.reasonSummary}),e.jsx("div",{className:`mt-3 text-xs uppercase tracking-[0.16em] ${I}`,children:oe(t.createdAt)})]},t.id))})]}):null]})]})]})}const Q="min-w-0 rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",ie="min-w-0 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",B="min-w-0 rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]/35 focus:bg-[var(--ui-surface-3)]",Se="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",O="text-[var(--ui-ink-strong)]",n="text-[var(--ui-ink-soft)]",$e="text-[var(--ui-ink-faint)]",ne="text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",Re="mt-4 rounded-[18px] border border-[color-mix(in_srgb,var(--success)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-success-soft)] p-4 text-sm text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]";function Xe(r){return JSON.stringify(r,null,2)}function le(r){const m=r.trim();if(!m)return{};const d=JSON.parse(m);if(!d||typeof d!="object"||Array.isArray(d))throw new Error("Expected a JSON object.");return d}function Qe(){var W,G,H;const r=me(),m=de(),[d,u]=v.useState(""),[R,j]=v.useState(null),[X,w]=v.useState(null),h=k({queryKey:["forge-operator-session"],queryFn:be}),C=h.isSuccess,M=k({queryKey:["forge-xp-metrics"],queryFn:ve}),F=k({queryKey:["forge-reward-rules"],queryFn:fe,enabled:C}),t=k({queryKey:["forge-reward-ledger"],queryFn:()=>je(30),enabled:C}),c=k({queryKey:["forge-psyche-overview"],queryFn:async()=>(await we()).overview}),b=Y({defaultValues:{title:"",description:"",active:!0,configJson:"{}"}}),l=Y({defaultValues:{entityType:"task",entityId:"",deltaXp:15,reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"}}),K=async()=>{await Promise.all([m.invalidateQueries({queryKey:["forge-xp-metrics"]}),m.invalidateQueries({queryKey:["forge-reward-rules"]}),m.invalidateQueries({queryKey:["forge-reward-ledger"]})])},D=U({mutationFn:s=>ue(s.ruleId,{title:s.title,description:s.description,active:s.active,config:s.config}),onSuccess:K}),f=U({mutationFn:xe,onSuccess:K}),x=((W=F.data)==null?void 0:W.rules)??[],T=v.useMemo(()=>{var s,i,y,N,L,Z,z;return{system:[{id:"operator_manual_reward",label:"Operator reward ledger"}],goal:r.snapshot.goals.map(a=>({id:a.id,label:a.title})),project:r.snapshot.dashboard.projects.map(a=>({id:a.id,label:a.title})),task:r.snapshot.tasks.map(a=>({id:a.id,label:a.title})),habit:r.snapshot.habits.map(a=>({id:a.id,label:a.title})),tag:r.snapshot.tags.map(a=>({id:a.id,label:a.name})),note:[],insight:[],psyche_value:(((s=c.data)==null?void 0:s.values)??[]).map(a=>({id:a.id,label:a.title})),behavior_pattern:(((i=c.data)==null?void 0:i.patterns)??[]).map(a=>({id:a.id,label:a.title})),behavior:(((y=c.data)==null?void 0:y.behaviors)??[]).map(a=>({id:a.id,label:a.title})),belief_entry:(((N=c.data)==null?void 0:N.beliefs)??[]).map(a=>({id:a.id,label:a.statement})),mode_profile:(((L=c.data)==null?void 0:L.modes)??[]).map(a=>({id:a.id,label:a.title})),flashcard:(((Z=c.data)==null?void 0:Z.flashcards)??[]).map(a=>({id:a.id,label:a.title||a.message})),trigger_report:(((z=c.data)==null?void 0:z.reports)??[]).map(a=>({id:a.id,label:a.title}))}},[c.data,r.snapshot.dashboard.projects,r.snapshot.goals,r.snapshot.habits,r.snapshot.tags,r.snapshot.tasks]);v.useEffect(()=>{var N;const s=l.getValues("entityType"),i=l.getValues("entityId"),y=T[s]??[];i&&y.some(L=>L.id===i)||l.setValue("entityId",((N=y[0])==null?void 0:N.id)??"")},[l,T]),v.useEffect(()=>{x.length&&(!d||!x.some(s=>s.id===d))&&u(x[0].id)},[x,d]);const g=x.find(s=>s.id===d)??x[0]??null;v.useEffect(()=>{g&&(b.reset({title:g.title,description:g.description,active:g.active,configJson:Xe(g.config)}),j(null))},[g,b]);const o=(G=M.data)==null?void 0:G.metrics,V=(((H=t.data)==null?void 0:H.ledger)??[]).filter(s=>s.metadata.manual===!0).slice(0,8);return h.isLoading?e.jsx(ge,{eyebrow:"Settings · Rewards",title:"Loading reward controls",description:"Establishing the operator session and fetching reward configuration.",columns:2,blocks:6}):h.isError?e.jsx(pe,{eyebrow:"Settings · Rewards",error:h.error,onRetry:()=>void h.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(ye,{title:"Rewards",description:"XP command deck, reward rule editor, manual bonus grants, and ledger history."}),e.jsx(ce,{}),e.jsx("div",{className:"grid gap-5",children:e.jsxs(he,{children:[e.jsx("div",{className:Se,children:"Reward operations"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[o?e.jsx(_e,{profile:o.profile,achievements:o.achievements,milestoneRewards:o.milestoneRewards,momentumPulse:o.momentumPulse,recentLedger:o.recentLedger}):null,o?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(re,{label:"Total XP",value:o.profile.totalXp,tone:"core"}),e.jsx(re,{label:"Daily ambient",value:`${o.dailyAmbientXp} / ${o.dailyAmbientCap}`,tone:"core"})]}):null,e.jsxs("div",{className:"grid gap-4 xl:grid-cols-2",children:[e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Reward rule editor"}),x.length>0?e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:b.handleSubmit(async s=>{try{j(null);const i=le(s.configJson);if(!g)return;await D.mutateAsync({ruleId:g.id,title:s.title,description:s.description,active:s.active,config:i})}catch(i){j(i instanceof Error?i.message:"Invalid reward rule config.")}}),children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Rule"}),e.jsx("select",{className:B,value:d,onChange:s=>u(s.target.value),children:x.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Title"}),e.jsx(J,{...b.register("title")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Description"}),e.jsx(E,{className:"min-h-24",...b.register("description")})]}),e.jsxs("label",{className:"flex min-w-0 items-center justify-between gap-3 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("span",{className:n,children:"Rule is active"}),e.jsx("input",{type:"checkbox",...b.register("active")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Config JSON"}),e.jsx(E,{className:"min-h-28 font-mono text-xs",...b.register("configJson")})]}),R?e.jsx("div",{className:`text-sm ${ne}`,children:R}):null,e.jsx(se,{type:"submit",pending:D.isPending,pendingLabel:"Saving rule",children:"Save reward rule"})]}):e.jsx("div",{className:`mt-4 text-sm ${n}`,children:"Loading reward rules..."})]}),e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Manual bonus XP"}),e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:l.handleSubmit(async s=>{try{w(null);const i=le(s.metadataJson);await f.mutateAsync({entityType:s.entityType,entityId:s.entityId,deltaXp:s.deltaXp,reasonTitle:s.reasonTitle,reasonSummary:s.reasonSummary,metadata:i}),l.reset({...s,entityId:"",reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"})}catch(i){w(i instanceof Error?i.message:"Invalid metadata payload.")}}),children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Entity type"}),e.jsx("select",{className:B,...l.register("entityType"),children:Object.keys(T).map(s=>e.jsx("option",{value:s,children:s.replaceAll("_"," ")},s))})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Entity id"}),e.jsx("select",{className:B,...l.register("entityId"),children:(T[l.watch("entityType")]??[]).map(s=>e.jsx("option",{value:s.id,children:s.label},s.id))})]})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Delta XP"}),e.jsx(J,{type:"number",...l.register("deltaXp",{valueAsNumber:!0})})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Reason title"}),e.jsx(J,{...l.register("reasonTitle")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Reason summary"}),e.jsx(E,{className:"min-h-24",...l.register("reasonSummary")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Metadata JSON"}),e.jsx(E,{className:"min-h-24 font-mono text-xs",...l.register("metadataJson")})]}),X?e.jsx("div",{className:`text-sm ${ne}`,children:X}):null,e.jsx(se,{type:"submit",pending:f.isPending,pendingLabel:"Issuing bonus",children:"Issue bonus XP"})]}),f.data?e.jsxs("div",{className:Re,children:["Granted ",f.data.reward.deltaXp>0?"+":"",f.data.reward.deltaXp," XP for"," ",e.jsx("strong",{children:f.data.reward.reasonTitle}),"."]}):null]})]}),e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Manual bonus history"}),e.jsx("div",{className:"mt-4 grid gap-3",children:V.length===0?e.jsx("div",{className:`${ie} text-sm ${n}`,children:"No manual bonus grants yet."}):V.map(s=>e.jsxs("div",{className:ie,children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 break-words font-medium ${O}`,children:s.reasonTitle}),e.jsxs(p,{wrap:!0,className:s.deltaXp>=0?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",children:[s.deltaXp>0?"+":"",s.deltaXp," XP"]})]}),e.jsx("div",{className:`mt-2 text-sm leading-6 ${n}`,children:s.reasonSummary||"No summary supplied."}),e.jsxs("div",{className:`mt-2 break-words text-xs uppercase tracking-[0.16em] [overflow-wrap:anywhere] ${$e}`,children:[s.entityType," · ",s.entityId," ·"," ",new Date(s.createdAt).toLocaleString()]})]},s.id))})]})]})]})})]})}export{Qe as SettingsRewardsPage};
|
|
1
|
+
import{j as e,r as v}from"./vendor-Dnkkx2co.js";import{j as de,i as k,k as U}from"./state-vCcAT5Hq.js";import{u as Y}from"./forms-hB0SqEh-.js";import{S as ce}from"./settings-section-nav-kFFQSJEe.js";import{c as p,Z as _,W as ee,f as oe,u as me,eq as ue,er as xe,S as ge,E as pe,C as he,I as J,T as E,B as se,du as be,cW as ve,es as fe,et as je,ad as we}from"./index-BhkubYaC.js";import{m as ae}from"./motion-Lt5B1XuE.js";import{P as ye}from"./page-hero-DzEsy8i5.js";import{M as re}from"./metric-tile-NJiFcFxW.js";import"./ui-C1iwpj2-.js";import"./board-dIX6etHh.js";import"./graph-DDUZNRsO.js";function Ne(r){switch(r){case"platinum":return"bg-[var(--ui-accent-soft)] text-[var(--primary)]";case"gold":return"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]";case"silver":return"bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]";default:return"bg-[var(--ui-warning-soft)] text-[var(--warning)]"}}function ke(r){switch(r){case"surging":return"bg-[color-mix(in_srgb,var(--ui-accent-soft)_62%,var(--ui-success-soft)_38%)]";case"steady":return"bg-[var(--ui-accent-soft)]";default:return"bg-[color-mix(in_srgb,var(--ui-warning-soft)_54%,var(--ui-accent-soft)_46%)]"}}const P="min-w-0 overflow-hidden rounded-[24px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",te="min-w-0 overflow-hidden rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",A="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",S="text-[var(--ui-ink-strong)]",$="text-[var(--ui-ink-soft)]",I="text-[var(--ui-ink-faint)]",q="bg-[var(--ui-surface-3)] text-[var(--ui-ink-medium)]";function _e({profile:r,achievements:m,milestoneRewards:d,momentumPulse:u,recentLedger:R=[],className:j,tone:X="core"}){const w=m.filter(t=>t.unlocked),h=(w.length>0?w:m).slice(0,3),C=d.slice(0,3),M=R.slice(0,3),F=Math.min(100,Math.round(r.currentLevelXp/r.nextLevelXp*100));return e.jsxs("section",{className:_("min-w-0 overflow-hidden rounded-[30px] border border-[var(--ui-border-subtle)] bg-[var(--card-gradient)] shadow-[var(--card-shadow)]",X==="psyche"&&"border-[color-mix(in_srgb,var(--success)_18%,var(--ui-border-subtle)_82%)]",j),children:[e.jsx("div",{className:_("px-5 py-5",ke(u.status)),children:e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:A,children:"Weekly progress"}),e.jsx("h2",{className:`mt-3 font-display text-3xl leading-none lg:text-4xl ${S}`,children:u.headline}),e.jsx("p",{className:`mt-3 max-w-3xl text-sm leading-7 ${$}`,children:u.detail})]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap gap-2",children:[e.jsxs(p,{wrap:!0,className:q,children:["Level ",r.level]}),e.jsxs(p,{wrap:!0,className:q,children:[r.streakDays," day streak"]}),e.jsxs(p,{wrap:!0,className:q,children:[r.weeklyXp," weekly XP"]})]})]})}),e.jsxs("div",{className:"grid gap-5 px-5 py-5 xl:grid-cols-[minmax(0,1.2fr)_minmax(0,0.8fr)]",children:[e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(ae.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{duration:.24,ease:"easeOut"},className:P,children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:`font-medium ${S}`,children:"Next reward"}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:u.nextMilestoneLabel})]}),e.jsx(p,{wrap:!0,className:"max-w-[12rem] shrink-0 self-start text-[var(--tertiary)]",children:u.celebrationLabel})]}),e.jsx("div",{className:"mt-5",children:e.jsx(ee,{value:F})}),e.jsxs("div",{className:`mt-3 flex flex-wrap items-center justify-between gap-3 text-xs uppercase tracking-[0.16em] ${I}`,children:[e.jsxs("span",{children:[r.currentLevelXp,"/",r.nextLevelXp," XP"]}),e.jsxs("span",{children:[r.comboMultiplier.toFixed(2),"x combo"]})]})]}),e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:h.map((t,c)=>e.jsxs(ae.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.24,delay:.04*c,ease:"easeOut"},className:P,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.title}),e.jsx(p,{wrap:!0,className:_("max-w-[8rem] shrink-0 self-start",Ne(t.tier)),children:t.tier})]}),e.jsx("div",{className:`mt-2 text-sm leading-6 ${$}`,children:t.summary}),e.jsx("div",{className:`mt-4 text-xs uppercase tracking-[0.16em] ${I}`,children:t.progressLabel})]},t.id))})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:P,children:[e.jsx("div",{className:A,children:"Rewards in progress"}),e.jsx("div",{className:"mt-4 grid gap-3",children:C.map(t=>{const c=Math.min(100,Math.round(t.current/t.target*100));return e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.title}),e.jsx(p,{wrap:!0,className:_("max-w-[10.5rem] shrink-0 self-start",t.completed?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":q),children:t.rewardLabel})]}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:t.summary}),e.jsx("div",{className:"mt-4",children:e.jsx(ee,{value:c})}),e.jsx("div",{className:`mt-3 text-xs uppercase tracking-[0.16em] ${I}`,children:t.progressLabel})]},t.id)})})]}),M.length>0?e.jsxs("div",{className:P,children:[e.jsx("div",{className:A,children:"Recent XP changes"}),e.jsx("div",{className:"mt-4 grid gap-3",children:M.map(t=>e.jsxs("div",{className:te,children:[e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 flex-1 font-medium ${S}`,children:t.reasonTitle}),e.jsxs(p,{wrap:!0,className:_("max-w-[8rem] shrink-0 self-start",t.deltaXp>=0?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]"),children:[t.deltaXp>0?"+":"",t.deltaXp," XP"]})]}),e.jsx("div",{className:`mt-2 text-sm ${$}`,children:t.reasonSummary}),e.jsx("div",{className:`mt-3 text-xs uppercase tracking-[0.16em] ${I}`,children:oe(t.createdAt)})]},t.id))})]}):null]})]})]})}const Q="min-w-0 rounded-[22px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] p-4",ie="min-w-0 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] p-4",B="min-w-0 rounded-[14px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-2)] px-3 py-3 text-sm text-[var(--ui-ink-strong)] outline-none transition focus:border-[var(--primary)]/35 focus:bg-[var(--ui-surface-3)]",Se="font-label text-[11px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",O="text-[var(--ui-ink-strong)]",n="text-[var(--ui-ink-soft)]",$e="text-[var(--ui-ink-faint)]",ne="text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",Re="mt-4 rounded-[18px] border border-[color-mix(in_srgb,var(--success)_28%,var(--ui-border-subtle)_72%)] bg-[var(--ui-success-soft)] p-4 text-sm text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]";function Xe(r){return JSON.stringify(r,null,2)}function le(r){const m=r.trim();if(!m)return{};const d=JSON.parse(m);if(!d||typeof d!="object"||Array.isArray(d))throw new Error("Expected a JSON object.");return d}function Qe(){var W,G,H;const r=me(),m=de(),[d,u]=v.useState(""),[R,j]=v.useState(null),[X,w]=v.useState(null),h=k({queryKey:["forge-operator-session"],queryFn:be}),C=h.isSuccess,M=k({queryKey:["forge-xp-metrics"],queryFn:ve}),F=k({queryKey:["forge-reward-rules"],queryFn:fe,enabled:C}),t=k({queryKey:["forge-reward-ledger"],queryFn:()=>je(30),enabled:C}),c=k({queryKey:["forge-psyche-overview"],queryFn:async()=>(await we()).overview}),b=Y({defaultValues:{title:"",description:"",active:!0,configJson:"{}"}}),l=Y({defaultValues:{entityType:"task",entityId:"",deltaXp:15,reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"}}),K=async()=>{await Promise.all([m.invalidateQueries({queryKey:["forge-xp-metrics"]}),m.invalidateQueries({queryKey:["forge-reward-rules"]}),m.invalidateQueries({queryKey:["forge-reward-ledger"]})])},D=U({mutationFn:s=>ue(s.ruleId,{title:s.title,description:s.description,active:s.active,config:s.config}),onSuccess:K}),f=U({mutationFn:xe,onSuccess:K}),x=((W=F.data)==null?void 0:W.rules)??[],T=v.useMemo(()=>{var s,i,y,N,L,Z,z;return{system:[{id:"operator_manual_reward",label:"Operator reward ledger"}],goal:r.snapshot.goals.map(a=>({id:a.id,label:a.title})),project:r.snapshot.dashboard.projects.map(a=>({id:a.id,label:a.title})),task:r.snapshot.tasks.map(a=>({id:a.id,label:a.title})),habit:r.snapshot.habits.map(a=>({id:a.id,label:a.title})),tag:r.snapshot.tags.map(a=>({id:a.id,label:a.name})),note:[],insight:[],psyche_value:(((s=c.data)==null?void 0:s.values)??[]).map(a=>({id:a.id,label:a.title})),behavior_pattern:(((i=c.data)==null?void 0:i.patterns)??[]).map(a=>({id:a.id,label:a.title})),behavior:(((y=c.data)==null?void 0:y.behaviors)??[]).map(a=>({id:a.id,label:a.title})),belief_entry:(((N=c.data)==null?void 0:N.beliefs)??[]).map(a=>({id:a.id,label:a.statement})),mode_profile:(((L=c.data)==null?void 0:L.modes)??[]).map(a=>({id:a.id,label:a.title})),flashcard:(((Z=c.data)==null?void 0:Z.flashcards)??[]).map(a=>({id:a.id,label:a.title||a.message})),trigger_report:(((z=c.data)==null?void 0:z.reports)??[]).map(a=>({id:a.id,label:a.title}))}},[c.data,r.snapshot.dashboard.projects,r.snapshot.goals,r.snapshot.habits,r.snapshot.tags,r.snapshot.tasks]);v.useEffect(()=>{var N;const s=l.getValues("entityType"),i=l.getValues("entityId"),y=T[s]??[];i&&y.some(L=>L.id===i)||l.setValue("entityId",((N=y[0])==null?void 0:N.id)??"")},[l,T]),v.useEffect(()=>{x.length&&(!d||!x.some(s=>s.id===d))&&u(x[0].id)},[x,d]);const g=x.find(s=>s.id===d)??x[0]??null;v.useEffect(()=>{g&&(b.reset({title:g.title,description:g.description,active:g.active,configJson:Xe(g.config)}),j(null))},[g,b]);const o=(G=M.data)==null?void 0:G.metrics,V=(((H=t.data)==null?void 0:H.ledger)??[]).filter(s=>s.metadata.manual===!0).slice(0,8);return h.isLoading?e.jsx(ge,{eyebrow:"Settings · Rewards",title:"Loading reward controls",description:"Establishing the operator session and fetching reward configuration.",columns:2,blocks:6}):h.isError?e.jsx(pe,{eyebrow:"Settings · Rewards",error:h.error,onRetry:()=>void h.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(ye,{title:"Rewards",description:"XP command deck, reward rule editor, manual bonus grants, and ledger history."}),e.jsx(ce,{}),e.jsx("div",{className:"grid gap-5",children:e.jsxs(he,{children:[e.jsx("div",{className:Se,children:"Reward operations"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[o?e.jsx(_e,{profile:o.profile,achievements:o.achievements,milestoneRewards:o.milestoneRewards,momentumPulse:o.momentumPulse,recentLedger:o.recentLedger}):null,o?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(re,{label:"Total XP",value:o.profile.totalXp,tone:"core"}),e.jsx(re,{label:"Daily ambient",value:`${o.dailyAmbientXp} / ${o.dailyAmbientCap}`,tone:"core"})]}):null,e.jsxs("div",{className:"grid gap-4 xl:grid-cols-2",children:[e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Reward rule editor"}),x.length>0?e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:b.handleSubmit(async s=>{try{j(null);const i=le(s.configJson);if(!g)return;await D.mutateAsync({ruleId:g.id,title:s.title,description:s.description,active:s.active,config:i})}catch(i){j(i instanceof Error?i.message:"Invalid reward rule config.")}}),children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Rule"}),e.jsx("select",{className:B,value:d,onChange:s=>u(s.target.value),children:x.map(s=>e.jsx("option",{value:s.id,children:s.title},s.id))})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Title"}),e.jsx(J,{...b.register("title")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Description"}),e.jsx(E,{className:"min-h-24",...b.register("description")})]}),e.jsxs("label",{className:"flex min-w-0 items-center justify-between gap-3 rounded-[18px] border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-4 py-3",children:[e.jsx("span",{className:n,children:"Rule is active"}),e.jsx("input",{type:"checkbox",...b.register("active")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Config JSON"}),e.jsx(E,{className:"min-h-28 font-mono text-xs",...b.register("configJson")})]}),R?e.jsx("div",{className:`text-sm ${ne}`,children:R}):null,e.jsx(se,{type:"submit",pending:D.isPending,pendingLabel:"Saving rule",children:"Save reward rule"})]}):e.jsx("div",{className:`mt-4 text-sm ${n}`,children:"Loading reward rules..."})]}),e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Manual bonus XP"}),e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:l.handleSubmit(async s=>{try{w(null);const i=le(s.metadataJson);await f.mutateAsync({entityType:s.entityType,entityId:s.entityId,deltaXp:s.deltaXp,reasonTitle:s.reasonTitle,reasonSummary:s.reasonSummary,metadata:i}),l.reset({...s,entityId:"",reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"})}catch(i){w(i instanceof Error?i.message:"Invalid metadata payload.")}}),children:[e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Entity type"}),e.jsx("select",{className:B,...l.register("entityType"),children:Object.keys(T).map(s=>e.jsx("option",{value:s,children:s.replaceAll("_"," ")},s))})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Entity id"}),e.jsx("select",{className:B,...l.register("entityId"),children:(T[l.watch("entityType")]??[]).map(s=>e.jsx("option",{value:s.id,children:s.label},s.id))})]})]}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Delta XP"}),e.jsx(J,{type:"number",...l.register("deltaXp",{valueAsNumber:!0})})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Reason title"}),e.jsx(J,{...l.register("reasonTitle")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Reason summary"}),e.jsx(E,{className:"min-h-24",...l.register("reasonSummary")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:`text-sm ${n}`,children:"Metadata JSON"}),e.jsx(E,{className:"min-h-24 font-mono text-xs",...l.register("metadataJson")})]}),X?e.jsx("div",{className:`text-sm ${ne}`,children:X}):null,e.jsx(se,{type:"submit",pending:f.isPending,pendingLabel:"Issuing bonus",children:"Issue bonus XP"})]}),f.data?e.jsxs("div",{className:Re,children:["Granted ",f.data.reward.deltaXp>0?"+":"",f.data.reward.deltaXp," XP for"," ",e.jsx("strong",{children:f.data.reward.reasonTitle}),"."]}):null]})]}),e.jsxs("div",{className:Q,children:[e.jsx("div",{className:`font-medium ${O}`,children:"Manual bonus history"}),e.jsx("div",{className:"mt-4 grid gap-3",children:V.length===0?e.jsx("div",{className:`${ie} text-sm ${n}`,children:"No manual bonus grants yet."}):V.map(s=>e.jsxs("div",{className:ie,children:[e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center justify-between gap-3",children:[e.jsx("div",{className:`min-w-0 break-words font-medium ${O}`,children:s.reasonTitle}),e.jsxs(p,{wrap:!0,className:s.deltaXp>=0?"bg-[var(--ui-success-soft)] text-[color-mix(in_srgb,var(--success)_76%,var(--ui-ink-strong)_24%)]":"bg-[var(--ui-warning-soft)] text-[color-mix(in_srgb,var(--warning)_78%,var(--ui-ink-strong)_22%)]",children:[s.deltaXp>0?"+":"",s.deltaXp," XP"]})]}),e.jsx("div",{className:`mt-2 text-sm leading-6 ${n}`,children:s.reasonSummary||"No summary supplied."}),e.jsxs("div",{className:`mt-2 break-words text-xs uppercase tracking-[0.16em] [overflow-wrap:anywhere] ${$e}`,children:[s.entityType," · ",s.entityId," ·"," ",new Date(s.createdAt).toLocaleString()]})]},s.id))})]})]})]})})]})}export{Qe as SettingsRewardsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aJ as b,r as d,cm as v,cr as f,bP as g,aV as h,cY as y,cZ as j,b2 as k,ba as N,c_ as w,aF as S,c$ as C,j as e,bB as x,F as z,aK as E}from"./vendor-Dnkkx2co.js";import{C as T,Z as i}from"./index-
|
|
1
|
+
import{aJ as b,r as d,cm as v,cr as f,bP as g,aV as h,cY as y,cZ as j,b2 as k,ba as N,c_ as w,aF as S,c$ as C,j as e,bB as x,F as z,aK as E}from"./vendor-Dnkkx2co.js";import{C as T,Z as i}from"./index-BhkubYaC.js";const o=[{to:"/settings",label:"General",icon:v},{to:"/settings/data",label:"Data",icon:f},{to:"/settings/users",label:"Users",icon:g},{to:"/settings/calendar",label:"Calendar",icon:h},{to:"/settings/mobile",label:"Mobile",icon:y},{to:"/settings/models",label:"Models",icon:j},{to:"/settings/agents",label:"Agents",icon:k},{to:"/settings/wiki",label:"KarpaWiki",icon:N},{to:"/settings/logs",label:"Logs",icon:w},{to:"/settings/rewards",label:"Rewards",icon:S},{to:"/settings/bin",label:"Bin",icon:C}];function m(t,a){return a==="/settings"?t==="/settings":t===a||t.startsWith(`${a}/`)}function L({className:t}){const a=b(),[l,n]=d.useState(!1),c=d.useMemo(()=>[...o].sort((r,s)=>s.to.length-r.to.length).find(r=>m(a.pathname,r.to))??o[0],[a.pathname]);return d.useEffect(()=>{if(!l)return;const r=document.body.style.overflow,s=document.body.style.touchAction,u=p=>{p.key==="Escape"&&n(!1)};return document.body.style.overflow="hidden",document.body.style.touchAction="none",window.addEventListener("keydown",u),()=>{document.body.style.overflow=r,document.body.style.touchAction=s,window.removeEventListener("keydown",u)}},[l]),e.jsxs(e.Fragment,{children:[e.jsxs(T,{className:i("surface-shell-panel overflow-hidden p-2",t),children:[e.jsx("div",{className:"hidden items-center gap-3 lg:flex",children:e.jsx("div",{className:"flex flex-wrap gap-2",children:o.map(r=>e.jsxs(x,{to:r.to,end:r.to==="/settings",className:({isActive:s})=>i("inline-flex items-center gap-2 whitespace-nowrap rounded-full px-3 py-1.5 text-[11px] font-semibold uppercase tracking-[0.14em] transition",s||m(a.pathname,r.to)?"border border-[var(--primary)]/14 bg-[var(--ui-accent-soft)] text-[var(--primary)]":"border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]"),children:[e.jsx(r.icon,{className:"size-3.5"}),e.jsx("span",{children:r.label})]},r.to))})}),e.jsx("div",{className:"flex items-center justify-between gap-3 lg:hidden",children:e.jsxs("button",{type:"button",className:"surface-shell-panel inline-flex min-w-0 flex-1 items-center justify-between gap-3 rounded-[22px] border px-3.5 py-2.5 text-left transition hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]",onClick:()=>n(!0),children:[e.jsxs("span",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("span",{className:"flex size-9 shrink-0 items-center justify-center rounded-2xl border border-[var(--primary)]/20 bg-[var(--primary)]/12",children:e.jsx(c.icon,{className:"size-4 text-[var(--primary)]"})}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block text-[10px] uppercase tracking-[0.18em] text-[var(--ui-ink-faint)]",children:"Settings section"}),e.jsx("span",{className:"mt-0.5 block truncate text-sm font-medium text-[var(--ui-ink-strong)]",children:c.label})]})]}),e.jsx("span",{className:"rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] px-2.5 py-1 text-[10px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:"Browse"})]})})]}),l&&typeof document<"u"?z.createPortal(e.jsxs("div",{className:"lg:hidden",children:[e.jsx("div",{className:"surface-overlay fixed inset-0 z-50 backdrop-blur-xl"}),e.jsx("button",{type:"button","aria-label":"Close settings sections",className:"fixed inset-0 z-[51]",onClick:()=>n(!1)}),e.jsx("div",{className:"pointer-events-none fixed inset-0 z-[52] flex items-end justify-center px-3 pt-3 sm:px-4 sm:pt-4",style:{paddingLeft:"max(0.75rem, calc(var(--forge-safe-area-left) + 0.75rem))",paddingRight:"max(0.75rem, calc(var(--forge-safe-area-right) + 0.75rem))",paddingTop:"max(0.75rem, calc(env(safe-area-inset-top) + 0.75rem))",paddingBottom:"calc(var(--forge-mobile-nav-clearance) - 0.25rem)"},children:e.jsxs("div",{role:"dialog","aria-modal":"true","aria-label":"Settings sections",className:"surface-modal-panel pointer-events-auto flex max-h-[min(34rem,calc(100dvh-var(--forge-mobile-nav-clearance)-1rem))] w-full max-w-xl min-h-0 flex-col overflow-hidden rounded-[30px] border",children:[e.jsx("div",{className:"shrink-0 border-b border-[var(--ui-border-subtle)] px-4 pb-3 pt-4 sm:px-5",children:e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"font-label text-[10px] uppercase tracking-[0.22em] text-[var(--ui-ink-faint)]",children:"Settings"}),e.jsxs("div",{className:"mt-1 flex min-w-0 flex-wrap items-center gap-2",children:[e.jsx("div",{className:"truncate text-base font-semibold text-[var(--ui-ink-strong)]",children:"Tune Forge"}),e.jsx("span",{className:"rounded-full border border-[var(--primary)]/20 bg-[var(--primary)]/12 px-2.5 py-1 text-[10px] uppercase tracking-[0.16em] text-[var(--primary)]",children:c.label})]}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-[var(--ui-ink-soft)]",children:"Jump between users, calendar, models, rewards, and more."})]}),e.jsx("button",{type:"button","aria-label":"Close settings sections",className:"inline-flex size-10 shrink-0 items-center justify-center rounded-full border border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)] transition hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)] hover:text-[var(--ui-ink-strong)]",onClick:()=>n(!1),children:e.jsx(E,{className:"size-4"})})]})}),e.jsx("div",{className:"min-h-0 overflow-y-auto p-3 overscroll-contain sm:p-4",children:e.jsx("div",{className:"grid gap-2",children:o.map(r=>{const s=m(a.pathname,r.to);return e.jsxs(x,{to:r.to,end:r.to==="/settings",onClick:()=>n(!1),className:i("group flex items-center justify-between gap-3 rounded-[22px] border px-3.5 py-3 transition-[transform,border-color,background-color,color] duration-150 hover:-translate-y-[1px] hover:text-[var(--ui-ink-strong)]",s?"border-[var(--primary)]/18 bg-[var(--ui-accent-soft)] text-[var(--ui-ink-strong)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-medium)] hover:border-[var(--ui-border-strong)] hover:bg-[var(--ui-surface-hover)]"),children:[e.jsxs("span",{className:"flex min-w-0 items-center gap-3",children:[e.jsx("span",{className:i("flex size-10 shrink-0 items-center justify-center rounded-2xl border transition",s?"border-[var(--primary)]/18 bg-[var(--primary)]/14 text-[var(--primary)]":"border-[var(--ui-border-subtle)] bg-[var(--ui-surface-1)] text-[var(--ui-ink-soft)] group-hover:border-[var(--ui-border-strong)] group-hover:text-[var(--ui-ink-strong)]"),children:e.jsx(r.icon,{className:"size-4"})}),e.jsxs("span",{className:"min-w-0",children:[e.jsx("span",{className:"block truncate text-sm font-semibold text-[var(--ui-ink-strong)]",children:r.label}),e.jsx("span",{className:"mt-0.5 block text-[10px] uppercase tracking-[0.16em] text-[var(--ui-ink-faint)]",children:"Forge settings"})]})]}),e.jsx("span",{className:i("rounded-full px-2.5 py-1 text-[10px] uppercase tracking-[0.16em]",s?"bg-[var(--primary)]/16 text-[var(--primary)]":"bg-[var(--ui-surface-1)] text-[var(--ui-ink-faint)]"),children:s?"Current":"Open"})]},r.to)})})})]})})]}),document.body):null]})}export{L as S};
|