forge-openclaw-plugin 0.2.100 → 0.2.101
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-5oyCFOns.js → activity-page-CpjuNSHw.js} +1 -1
- package/dist/assets/{ai-surface-workspace-qgk_B57-.js → ai-surface-workspace-DEAFZruS.js} +1 -1
- package/dist/assets/{atlas-panel-rfH2qOez.js → atlas-panel-CdVNPotj.js} +1 -1
- package/dist/assets/{calendar-page-Bo2iua-a.js → calendar-page-DNNt6lfz.js} +1 -1
- package/dist/assets/{calendar-rules-DA1g3QUk.js → calendar-rules-DNJFNsxi.js} +1 -1
- package/dist/assets/{calendar-week-toolbar-DU1Q4RYj.js → calendar-week-toolbar-BbPwYeN0.js} +1 -1
- package/dist/assets/{companion-sync-lab-page-CosNknOK.js → companion-sync-lab-page-KxEDigM6.js} +1 -1
- package/dist/assets/{daily-metrics-dashboard-LjuGAB3f.js → daily-metrics-dashboard-B3cqJgDt.js} +1 -1
- package/dist/assets/{entity-note-count-link-BmGDB572.js → entity-note-count-link-DrhjJZ4i.js} +1 -1
- package/dist/assets/{entity-notes-surface-DgEgicaE.js → entity-notes-surface-CkcRsKJQ.js} +1 -1
- package/dist/assets/{execution-board-CDRXQB85.js → execution-board-D07gOocB.js} +1 -1
- package/dist/assets/{faceted-token-search-CE1YauRd.js → faceted-token-search-BxRRcM3q.js} +1 -1
- package/dist/assets/{flagship-signal-deck-DDds90Gl.js → flagship-signal-deck-cmy82b8_.js} +1 -1
- package/dist/assets/{floating-action-menu-CJkI2iFy.js → floating-action-menu-Fs_ZiUMo.js} +1 -1
- package/dist/assets/{goal-detail-page-cJvHaLMQ.js → goal-detail-page-CqLiNz4f.js} +1 -1
- package/dist/assets/{goals-page-f_39hvUV.js → goals-page-BTk7mg_T.js} +1 -1
- package/dist/assets/{habits-page-DKb96_mj.js → habits-page-BJxagdzx.js} +1 -1
- package/dist/assets/{index-BHTUu_4M.js → index-CF4J4R9L.js} +2 -2
- package/dist/assets/{insight-flow-dialog-pzAzyayN.js → insight-flow-dialog-8f3D0GuC.js} +1 -1
- package/dist/assets/{insights-page-Dc9oFltJ.js → insights-page-D6rOa7uk.js} +1 -1
- package/dist/assets/{kanban-page-JAxerYh6.js → kanban-page-XQ7Se6dH.js} +1 -1
- package/dist/assets/{knowledge-graph-page-UQ3skqEi.js → knowledge-graph-page-BtAg8iv3.js} +1 -1
- package/dist/assets/{life-force-page-BGDbQuVh.js → life-force-page-Dy0JTS2G.js} +1 -1
- package/dist/assets/{life-force-workspace-B1fYSXRC.js → life-force-workspace-OfyB9HJM.js} +1 -1
- package/dist/assets/{metric-tile-DX6TclqM.js → metric-tile-DKpo-8xw.js} +1 -1
- package/dist/assets/{movement-page-6HP6nGJx.js → movement-page-Bg_T_Stx.js} +1 -1
- package/dist/assets/{note-markdown-DiW2-5d3.js → note-markdown-N-uxD3Xt.js} +1 -1
- package/dist/assets/{note-tags-input-DDLXf54U.js → note-tags-input-Cdu7wiw6.js} +1 -1
- package/dist/assets/{notes-page-BuguDjhz.js → notes-page-CKXnF_KU.js} +1 -1
- package/dist/assets/{open-in-graph-button-Cg5VrKsC.js → open-in-graph-button-IXe9SGth.js} +1 -1
- package/dist/assets/{orbit-map-GD05-0oS.js → orbit-map-Dzi6KliQ.js} +1 -1
- package/dist/assets/{overview-page-DuOs2OCB.js → overview-page-1miYqaVS.js} +1 -1
- package/dist/assets/{page-hero-CQWo1Mm_.js → page-hero-DRy5b2MU.js} +1 -1
- package/dist/assets/{pill-cluster-BJogDRDJ.js → pill-cluster-C9QczVJ2.js} +1 -1
- package/dist/assets/{preference-entity-handoff-button-D4WAs9pC.js → preference-entity-handoff-button-5PzUn42S.js} +1 -1
- package/dist/assets/{preferences-page-BaJTMU1I.js → preferences-page-DtNaF5Q3.js} +1 -1
- package/dist/assets/{project-collections-DvaX20q_.js → project-collections-xPz2mlRr.js} +1 -1
- package/dist/assets/{project-detail-page-drPIFZGb.js → project-detail-page-BXK5-4xW.js} +1 -1
- package/dist/assets/{project-management-hierarchy-page-BUbRXvny.js → project-management-hierarchy-page-DtRpMABw.js} +1 -1
- package/dist/assets/{project-management-section-nav-C2Ud8Zdd.js → project-management-section-nav-P3ixzPa-.js} +1 -1
- package/dist/assets/{projects-page-BGzEZUtg.js → projects-page-C5ViRuf4.js} +1 -1
- package/dist/assets/{psyche-behaviors-page-Dmm_Io9D.js → psyche-behaviors-page-Dco46sC4.js} +1 -1
- package/dist/assets/{psyche-flashcards-page-BgNKJ6QJ.js → psyche-flashcards-page-ZcoEB8gV.js} +1 -1
- package/dist/assets/{psyche-goal-map-page-DXJs98Vr.js → psyche-goal-map-page-CLBAQOI0.js} +1 -1
- package/dist/assets/{psyche-graph-CFgs_Bqc.js → psyche-graph-k4tX2tdp.js} +1 -1
- package/dist/assets/{psyche-metrics-page-zYTJDbyZ.js → psyche-metrics-page-CuR9oqEy.js} +1 -1
- package/dist/assets/{psyche-mode-guide-page-XPgRfCOf.js → psyche-mode-guide-page-hIVXcCnE.js} +1 -1
- package/dist/assets/{psyche-modes-page-B-GA8oRF.js → psyche-modes-page-0lYtBlhO.js} +1 -1
- package/dist/assets/{psyche-page--r6a3e1t.js → psyche-page-VZ9k9ISp.js} +1 -1
- package/dist/assets/{psyche-patterns-page-BM5-3bMm.js → psyche-patterns-page-gx5nmdGq.js} +1 -1
- package/dist/assets/{psyche-questionnaire-builder-page-CJshQ-mg.js → psyche-questionnaire-builder-page-Bn0TOISd.js} +1 -1
- package/dist/assets/{psyche-questionnaire-detail-page-USmR5G5A.js → psyche-questionnaire-detail-page-CmVzSd_s.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-detail-page-D7iBCmTi.js → psyche-questionnaire-run-detail-page-BsMbmXCG.js} +1 -1
- package/dist/assets/{psyche-questionnaire-run-page-Cpil-kDh.js → psyche-questionnaire-run-page-CgkRL2vi.js} +1 -1
- package/dist/assets/{psyche-questionnaires-page-C-_y3VwS.js → psyche-questionnaires-page-D7V8uLXM.js} +1 -1
- package/dist/assets/{psyche-report-detail-page--dkSPRaj.js → psyche-report-detail-page-OlFq57eL.js} +1 -1
- package/dist/assets/{psyche-reports-page-CUaOXmIN.js → psyche-reports-page-dVUZjna1.js} +1 -1
- package/dist/assets/{psyche-schemas-beliefs-page-BX6xaap3.js → psyche-schemas-beliefs-page-BCgc8FUd.js} +1 -1
- package/dist/assets/{psyche-screen-time-page-CAAI4mD7.js → psyche-screen-time-page-B_6BT_WN.js} +1 -1
- package/dist/assets/{psyche-self-observation-page-BZ6FLuwa.js → psyche-self-observation-page-CEG5mluK.js} +1 -1
- package/dist/assets/{psyche-values-page-yEV6MGt8.js → psyche-values-page-DRbRfEd6.js} +1 -1
- package/dist/assets/{report-chain-fields-fZ8Xd4H6.js → report-chain-fields-CALCV3V5.js} +1 -1
- package/dist/assets/{rewards-page-C2HQjIAf.js → rewards-page-DmC4R_Ps.js} +1 -1
- package/dist/assets/{scheduling-rules-editor-BHOpHOrV.js → scheduling-rules-editor-D02s70hr.js} +1 -1
- package/dist/assets/{schema-badge-DyKbxb51.js → schema-badge-BZO-qNhO.js} +1 -1
- package/dist/assets/{select-menu-BX-pZNqL.js → select-menu-fYyreSdQ.js} +1 -1
- package/dist/assets/{settings-agents-page-VuYXTiyc.js → settings-agents-page-C_v_hMJF.js} +1 -1
- package/dist/assets/{settings-bin-page-BNzvYaOk.js → settings-bin-page-DY5bg81n.js} +1 -1
- package/dist/assets/{settings-calendar-page-CjSFB53S.js → settings-calendar-page-D1CzE6cg.js} +1 -1
- package/dist/assets/{settings-data-page-CGSlryuI.js → settings-data-page-CHRQFU9H.js} +1 -1
- package/dist/assets/{settings-logs-page-BTK5fine.js → settings-logs-page-B04pUwEv.js} +1 -1
- package/dist/assets/{settings-mobile-page-CRaObOGo.js → settings-mobile-page-D9kTlYDS.js} +1 -1
- package/dist/assets/{settings-models-page-DFshpYF8.js → settings-models-page-D26270R2.js} +1 -1
- package/dist/assets/{settings-page-BP81Mb5R.js → settings-page-DYDTFlnv.js} +1 -1
- package/dist/assets/{settings-rewards-page-CDJ1PH2G.js → settings-rewards-page-cl4vqqO_.js} +1 -1
- package/dist/assets/{settings-section-nav-CCFm27r2.js → settings-section-nav-DSOuht_F.js} +1 -1
- package/dist/assets/{settings-users-page-TdUocFPa.js → settings-users-page-BU79JB_T.js} +1 -1
- package/dist/assets/{settings-wiki-page-B2zX0QQG.js → settings-wiki-page-DwAUlyA3.js} +1 -1
- package/dist/assets/{sleep-page-cI1GMVzk.js → sleep-page-D8NbdhyS.js} +1 -1
- package/dist/assets/{sports-page-06LTqp0V.js → sports-page-CV4Cnzwn.js} +1 -1
- package/dist/assets/{strategies-page-DXP9Kx8s.js → strategies-page-C4qvXnql.js} +1 -1
- package/dist/assets/{strategy-detail-page-D6mx_Mik.js → strategy-detail-page-DJLo5rfy.js} +1 -1
- package/dist/assets/{strategy-dialog-BvzomTaF.js → strategy-dialog-D3AuUlVz.js} +1 -1
- package/dist/assets/{task-detail-page-BIWIggdp.js → task-detail-page-z-9u9rF0.js} +1 -1
- package/dist/assets/{timebox-planning-dialog-CaCnoslG.js → timebox-planning-dialog-DB6FLqmI.js} +1 -1
- package/dist/assets/{today-page-DO2mRPT2.js → today-page-BKlu6gx5.js} +1 -1
- package/dist/assets/{training-load-page-CyZ0mlEr.js → training-load-page-CyJQqo_3.js} +1 -1
- package/dist/assets/{vitals-page-BQvEjTc6.js → vitals-page-qre17Nw8.js} +1 -1
- package/dist/assets/{weekly-review-page-Tp6Q9CRj.js → weekly-review-page-Cz4vkRcx.js} +1 -1
- package/dist/assets/weight-loss-page-BQrnOI0y.js +1 -0
- package/dist/assets/{wiki-article-markdown-DQYohmW2.js → wiki-article-markdown-DdiR2TJE.js} +1 -1
- package/dist/assets/{wiki-editor-page-Dem_3eZv.js → wiki-editor-page-DqwoqVFb.js} +1 -1
- package/dist/assets/{wiki-ingest-history-page-BxoOcCoJ.js → wiki-ingest-history-page--evBLbOw.js} +1 -1
- package/dist/assets/{wiki-ingest-modal-DhguKk3J.js → wiki-ingest-modal--ohzFnj2.js} +1 -1
- package/dist/assets/{wiki-page-BLRxVXkl.js → wiki-page-B_VJFBPA.js} +1 -1
- package/dist/assets/{workbench-flow-page-DqMkCCTy.js → workbench-flow-page-Du62mtJU.js} +1 -1
- package/dist/assets/{workbench-page-BWd02wPw.js → workbench-page-4MKr3iRm.js} +1 -1
- package/dist/assets/{workout-detail-page-BD8u7GyL.js → workout-detail-page-DfUbYYw1.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/server/server/src/watch-mobile.js +22 -10
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/dist/assets/weight-loss-page-BBzlhLVV.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as j,j as e,aD as pe,d9 as xe,aC as ue,aG as ge,bl as he,da as be,aQ as fe}from"./vendor-DHkYh85p.js";import{j as ye,i as _,k as $}from"./state-B-4sS1xO.js";import{u as ve}from"./forms-BFlTgZ3W.js";import{Q as we,de as Y,F as L,I as F,j as je,df as Ne,T as ke,dg as D,B as N,dh as ee,P as Se,aF as Ce,di as Fe,dj as I,dk as Te,dl as Pe,dm as De,dn as Ae,dp as X,S as Ee,E as Z,C as T,dq as _e,dr as $e,ds as Ie,dt as Le,du as Me,dv as Qe,dw as Re,dx as qe,b$ as ze,dy as Je,dz as Ke}from"./index-BHTUu_4M.js";import{S as Oe}from"./settings-section-nav-CCFm27r2.js";import{P as Ge}from"./page-hero-CQWo1Mm_.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./graph-D6JLqDbD.js";function R({theme:s,title:l,description:n}){return e.jsx("div",{className:"overflow-hidden rounded-[24px] border border-white/10",style:{background:`linear-gradient(180deg, ${s.panelHigh}, ${s.panelLow})`,color:s.ink},children:e.jsxs("div",{className:"px-4 py-4",style:{background:`radial-gradient(circle at top left, ${s.primary}33, transparent 42%), radial-gradient(circle at top right, ${s.secondary}2a, transparent 36%), linear-gradient(180deg, ${s.panel}, ${s.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:[s.primary,s.secondary,s.tertiary,s.panelHigh].map(i=>e.jsx("div",{className:"h-9 flex-1 rounded-[14px] border border-black/10",style:{background:i}},i))})]})})}function w({label:s,value:l,onChange:n,description:i}){return e.jsx(L,{label:s,description:i,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-white/10 bg-transparent p-1"}),e.jsx(F,{value:l,onChange:d=>n(d.target.value),placeholder:"#7cc7ff"})]})})}function He({open:s,onOpenChange:l,value:n,onSave:i}){const[d,p]=j.useState(n),[u,m]=j.useState(""),[y,f]=j.useState(null),k=j.useRef(null),c=a=>{const r=Y.parse(JSON.parse(a));p(r),m(JSON.stringify(r,null,2)),f(null)},g=a=>{const r=ee(a);p({...r,label:d.label.trim().length>0?d.label:`${r.label} Custom`})},S=async a=>{var o;const r=(o=a.target.files)==null?void 0:o[0];if(r)try{c(await r.text())}catch(C){f(C instanceof Error?C.message:"Forge could not parse that JSON theme.")}finally{a.target.value=""}},A=[{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:(a,r)=>e.jsxs("div",{className:"grid gap-5",children:[e.jsx(L,{label:"Theme label",description:"This label appears in Settings when the custom theme is active.",children:e.jsx(F,{value:a.label,onChange:o=>r({label:o.target.value}),placeholder:"Midnight Circuit"})}),e.jsx(L,{label:"Starter preset",children:e.jsx(je,{value:"",onChange:o=>g(o),options:Object.entries(Ne).map(([o,C])=>({value:o,label:C.label,description:C.description})),columns:2})}),e.jsx(R,{theme:a,title:a.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:(a,r)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(w,{label:"Primary",description:"Main emphasis color for actions and active state.",value:a.primary,onChange:o=>r({primary:o})}),e.jsx(w,{label:"Secondary",description:"Support accent for positive or secondary emphasis.",value:a.secondary,onChange:o=>r({secondary:o})}),e.jsx(w,{label:"Tertiary",description:"Warm contrast color for warnings, highlights, and supporting metrics.",value:a.tertiary,onChange:o=>r({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:(a,r)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(w,{label:"Canvas",description:"Primary app background.",value:a.canvas,onChange:o=>r({canvas:o})}),e.jsx(w,{label:"Panel",description:"Default card and rail background.",value:a.panel,onChange:o=>r({panel:o})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(w,{label:"Panel high",description:"Raised highlights and stronger sections.",value:a.panelHigh,onChange:o=>r({panelHigh:o})}),e.jsx(w,{label:"Panel low",description:"Lower contrast and deeper card areas.",value:a.panelLow,onChange:o=>r({panelLow:o})})]}),e.jsx(w,{label:"Ink",description:"Main text and readable foreground color.",value:a.ink,onChange:o=>r({ink:o})}),e.jsx(R,{theme:a,title:a.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:a=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(L,{label:"Direct JSON",description:"Paste a full custom theme object, then click Apply JSON.",children:e.jsx(ke,{value:u,onChange:r=>m(r.target.value),className:"min-h-52 font-mono text-[13px] leading-6",placeholder:JSON.stringify(D,null,2)})}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(N,{type:"button",variant:"secondary",onClick:()=>{try{c(u)}catch(r){f(r instanceof Error?r.message:"Forge could not parse that JSON theme.")}},children:"Apply JSON"}),e.jsx(N,{type:"button",variant:"ghost",onClick:()=>{var r;return(r=k.current)==null?void 0:r.click()},children:"Upload JSON file"}),e.jsx("input",{ref:k,type:"file",accept:"application/json,.json",className:"hidden",onChange:S})]}),e.jsx(R,{theme:a,title:a.label,description:"Preview of the theme that will be saved if you submit now."})]})}];return e.jsx(we,{open:s,onOpenChange:a=>{a&&(p(n),m(""),f(null)),l(a)},eyebrow:"Settings",title:"Forge custom theme",description:"Build a dark Forge palette visually, or import one directly as JSON.",value:d,onChange:a=>{p(a),f(null)},draftPersistenceKey:"settings.theme-customizer",steps:A,error:y,onSubmit:async()=>{try{const a=Y.parse(d);i(a),l(!1)}catch(a){f(a instanceof Error?a.message:"Forge could not save that custom theme.")}},submitLabel:"Save custom theme",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]"})}function Ue({theme:s}){return e.jsx("div",{className:"mt-3 grid grid-cols-4 gap-2",children:[s.primary,s.secondary,s.tertiary,s.panelHigh].map(l=>e.jsx("div",{className:"h-6 rounded-[10px] border border-black/10",style:{background:l}},l))})}function Be({selected:s,theme:l}){return e.jsxs("div",{className:"relative min-h-[138px] overflow-hidden rounded-[18px] border border-white/10 bg-[radial-gradient(circle_at_24%_10%,rgba(255,199,104,0.22),transparent_30%),radial-gradient(circle_at_88%_12%,rgba(84,191,255,0.16),transparent_32%),linear-gradient(145deg,rgba(255,255,255,0.08),rgba(255,255,255,0.025))]",children:[e.jsx("div",{className:"absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-black/42 to-transparent"}),e.jsx("img",{src:Me(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_rgba(0,0,0,0.34)]"}),e.jsxs("div",{className:"absolute left-3 top-3 flex items-center gap-2 rounded-full border border-white/10 bg-black/28 px-2.5 py-1 text-[9px] font-semibold uppercase tracking-[0.14em] text-white/78 backdrop-blur-md",children:[e.jsx(ge,{className:"size-3 text-amber-200"}),"Live rewards"]}),e.jsx("div",{className:"absolute bottom-3 left-3 flex items-center gap-1.5",children:Qe.map(n=>e.jsx("span",{className:"grid size-11 place-items-center overflow-hidden rounded-[12px] border border-white/12 bg-black/26 p-1 shadow-[0_12px_22px_rgba(0,0,0,0.22)] backdrop-blur-md",children:e.jsx("img",{src:Re(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 ${s?"border-emerald-200/55 bg-emerald-300/18 text-emerald-100":"border-white/15 bg-black/20 text-white/40"}`,children:s?e.jsx(he,{className:"size-4"}):null})]})}function V({healthy:s}){return e.jsx(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Mobile companion"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:s?"iPhone bridge is syncing":"Connect the iPhone bridge"}),e.jsx("div",{className:"mt-1 max-w-3xl text-sm leading-6 text-white/58",children:s?"Review HealthKit, movement, and background sync permissions.":"Pair or refresh the native companion before relying on HealthKit, movement, or watch signals."})]}),e.jsx(ue,{to:"/settings/mobile",className:"inline-flex min-h-10 items-center rounded-[14px] bg-white/[0.08] px-3 py-2 text-sm text-white transition hover:bg-white/[0.12]",children:"Open mobile settings"})]})})}function M(s){return new Date(s).toLocaleString()}function te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i}){return i?[i.integrity.headline,i.integrity.topIssues.length>0?i.integrity.topIssues[0].summary:"No active Doctor warnings are holding back integrity.",`Storage mode: ${l}. Latest Doctor run: ${M(i.integrity.lastCheckedAt)}.`]:s>=100?["All currently reported settings and storage checks passed.",`Latest audit: ${M(n)}.`]:[`Forge is holding back ${Math.max(0,100-s)}% 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: ${M(n)}.`]}function se({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i}){const d=(i==null?void 0:i.integrity.score)??s,p=te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i});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-white/10 bg-white/[0.05] px-2.5 py-1 text-[11px] font-medium normal-case tracking-normal text-white/72 transition marker:hidden hover:border-white/18 hover:bg-white/[0.08] hover:text-white/88 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgba(192,193,255,0.35)] [&::-webkit-details-marker]:hidden",onKeyDown:u=>{var m;u.key==="Escape"&&((m=u.currentTarget.parentElement)==null||m.removeAttribute("open"))},children:[e.jsx(xe,{className:"size-3.5","aria-hidden":"true"}),d,"% integrity"]}),e.jsxs("span",{role:"tooltip",className:"absolute right-0 top-[calc(100%+0.55rem)] z-50 hidden w-[min(19rem,calc(100vw-2rem))] rounded-[16px] border border-white/10 bg-[rgba(10,15,27,0.98)] px-3 py-2.5 text-left text-xs leading-5 tracking-normal text-white/70 normal-case shadow-[0_18px_48px_rgba(3,8,18,0.46)] group-open:block",children:[e.jsx("span",{className:"block font-medium text-white/88",children:d>=100?"Integrity is complete":`Why this is ${d}%`}),p.map(u=>e.jsx("span",{className:"mt-1 block",children:u},u))]})]})}function We({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i,doctorLoading:d,onRefreshDoctor:p,onApplyFix:u,applyingFixId:m}){const y=(i==null?void 0:i.integrity.score)??s,f=(i==null?void 0:i.integrity.lastCheckedAt)??n,k=(i==null?void 0:i.issues.filter(g=>g.severity!=="info").slice(0,4))??[],[c]=te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i});return e.jsxs(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Security posture"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/58",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 text-xs leading-5 text-white/50",children:c})]}),e.jsx(se,{integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i})]}),e.jsxs("div",{className:"mt-3 grid gap-2 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[14px] bg-white/[0.04] px-3 py-3",children:[e.jsx("div",{className:"text-xs text-white/54",children:"Storage mode"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:l})]}),e.jsxs("div",{className:"rounded-[14px] bg-white/[0.04] px-3 py-3",children:[e.jsx("div",{className:"text-xs text-white/54",children:"Last Doctor run"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:M(f)})]})]}),e.jsxs("div",{className:"mt-3 rounded-[14px] border border-white/8 bg-white/[0.035] 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-white",children:[e.jsx(be,{className:"size-4 text-cyan-200"}),"Forge Doctor"]}),e.jsxs(N,{type:"button",variant:"secondary",pending:d,onClick:p,children:[e.jsx(fe,{className:"size-4"}),"Run"]})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:i?`${y}% integrity. ${i.integrity.headline}`:"Run Doctor to check settings, storage, entities, rewards, and runtime consistency."}),k.length>0?e.jsx("div",{className:"mt-3 grid gap-2",children:k.map(g=>{var S;return e.jsx(Ye,{issue:g,applying:m===((S=g.fix)==null?void 0:S.id),onApplyFix:u},g.id)})}):i?e.jsx("div",{className:"mt-3 rounded-[12px] border border-emerald-200/12 bg-emerald-300/8 px-3 py-2 text-sm text-emerald-100",children:"No active consistency warnings."}):null]})]})}function Ye({issue:s,applying:l,onApplyFix:n}){var i;return e.jsx("div",{className:"rounded-[12px] border border-white/8 bg-black/12 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-white/42",children:[s.group," / ",s.severity]}),e.jsx("div",{className:"mt-1 text-sm text-white/78",children:s.summary})]}),((i=s.fix)==null?void 0:i.kind)==="safe_auto_fix"?e.jsx(N,{type:"button",variant:"secondary",pending:l,onClick:()=>n(s.fix.id),children:"Apply fix"}):null]})})}function lt(){var G,H,U,B,W;const{t:s}=Se(),l=Ce(),n=ye(),[i,d]=j.useState(!1),p=_({queryKey:["forge-operator-session"],queryFn:qe}),u=p.isSuccess,m=_({queryKey:["forge-settings"],queryFn:ze,enabled:u}),y=Fe(void 0,{skip:!u}),f=_({queryKey:["forge-companion-overview"],queryFn:async()=>(await Je()).overview,enabled:u,staleTime:3e4}),k=_({queryKey:["forge-gamification-assets"],queryFn:Ke,enabled:u,staleTime:3e4}),c=ve({defaultValues:{profile:{operatorName:"",operatorEmail:"",operatorTitle:""},notifications:{goalDriftAlerts:!0,dailyQuestReminders:!0,achievementCelebrations:!0},execution:{maxActiveTasks:2,timeAccountingMode:"split"},themePreference:"obsidian",gamificationTheme:"dramatic-smithie",customTheme:D,localePreference:"en"}}),g=async()=>{await Promise.all([n.invalidateQueries({queryKey:["forge-operator-session"]}),n.invalidateQueries({queryKey:["forge-settings"]})])},S=$({mutationFn:t=>I(t),onSuccess:g}),A=$({mutationFn:t=>I(t),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await g()}}),a=$({mutationFn:t=>I(t),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await g()}}),r=$({mutationFn:async t=>(await Te(t),I({gamificationTheme:t})),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await Promise.all([n.invalidateQueries({queryKey:["forge-settings"]}),n.invalidateQueries({queryKey:["forge-gamification-assets"]})])}}),[o,C]=Pe(),[ae,ie]=De(),[re,q]=j.useState(),ne=async()=>{await o().unwrap(),l(Ie([])),l(Le.util.resetApiState()),n.removeQueries({predicate:t=>{const[b]=t.queryKey;return typeof b=="string"&&b.startsWith("forge-")}}),await Promise.all([g(),p.refetch()])};j.useEffect(()=>{var t;(t=m.data)!=null&&t.settings&&c.reset(Ae.parse(m.data.settings))},[m.data,c]);const x=(G=m.data)==null?void 0:G.settings,le=(H=y.data)==null?void 0:H.doctor,P=c.watch("themePreference"),z=c.watch("gamificationTheme"),J=((U=k.data)==null?void 0:U.assets.styles)??[],Q=J.find(t=>t.id===z),v=c.watch("customTheme")??D,K=((B=f.data)==null?void 0:B.healthState)==="healthy_sync",oe=async t=>{if(window.confirm("Apply this Forge Doctor fix? Forge will only run the selected safe repair.")){q(t);try{await ae({fixIds:[t]}).unwrap(),await Promise.all([m.refetch(),y.refetch()])}finally{q(void 0)}}},O=async(t,b=v)=>{c.setValue("themePreference",t,{shouldDirty:!0}),c.setValue("customTheme",b??D,{shouldDirty:!0}),await A.mutateAsync({themePreference:t,customTheme:b??D})},ce=async t=>{c.setValue("gamificationTheme",t,{shouldDirty:!0}),await a.mutateAsync({gamificationTheme:t})};return j.useEffect(()=>{if(x)return X(P,v),()=>{X(x.themePreference,x.customTheme??null)}},[v,P,x,x==null?void 0:x.customTheme,x==null?void 0:x.themePreference]),p.isLoading||m.isLoading?e.jsx(Ee,{eyebrow:"Settings",title:"Loading settings",description:"Establishing the operator session and fetching current configuration.",columns:2,blocks:6}):p.isError?e.jsx(Z,{eyebrow:"Settings",error:p.error,onRetry:()=>void p.refetch()}):m.isError||!x?e.jsx(Z,{eyebrow:"Settings",error:m.error??new Error("Forge returned an empty settings payload."),onRetry:()=>void m.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(Ge,{title:"Settings",description:"Tune execution policy, timer behaviour, and personal preferences.",badge:e.jsx(se,{integrityScore:x.security.integrityScore,storageMode:x.security.storageMode,lastAuditAt:x.security.lastAuditAt})}),null,e.jsx(Oe,{}),(W=p.data)!=null&&W.session?e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[18px] border border-emerald-400/20 bg-emerald-500/[0.08] px-4 py-3 text-sm text-emerald-100/88",children:[e.jsxs("div",{children:["Operator session active as"," ",e.jsx("span",{className:"font-medium text-white",children:p.data.session.actorLabel}),"."]}),e.jsx(N,{variant:"secondary",size:"sm",pending:C.isLoading,pendingLabel:"Resetting session",onClick:()=>void ne(),children:"Reset operator session"})]}):null,e.jsxs("div",{className:"grid gap-4",children:[K?null:e.jsx(V,{healthy:!1}),e.jsxs("form",{className:"grid gap-4",onSubmit:c.handleSubmit(async t=>{await S.mutateAsync(t)}),children:[e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",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-white/58",children:"Name"}),e.jsx(F,{...c.register("profile.operatorName")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Email"}),e.jsx(F,{...c.register("profile.operatorEmail")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Title"}),e.jsx(F,{...c.register("profile.operatorTitle")})]}),e.jsx("div",{className:"mt-2 font-label text-[11px] uppercase tracking-[0.18em] text-white/45",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-white/58",children:"Maximum active tasks"}),e.jsx(F,{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-white/58",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(t=>e.jsxs("label",{className:"grid gap-2 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsxs("span",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"radio",value:t.value,...c.register("execution.timeAccountingMode")}),e.jsx("span",{className:"text-white/82",children:t.label})]}),e.jsx("span",{className:"text-xs leading-5 text-white/56",children:t.description})]},t.value))})]})]}),e.jsx("div",{className:"mt-2 font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Notification rules"}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Goal drift alerts"}),e.jsx("input",{type:"checkbox",...c.register("notifications.goalDriftAlerts")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Daily quest reminders"}),e.jsx("input",{type:"checkbox",...c.register("notifications.dailyQuestReminders")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Achievement celebrations"}),e.jsx("input",{type:"checkbox",...c.register("notifications.achievementCelebrations")})]})]}),e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Theme calibration"}),e.jsx("p",{className:"text-sm text-white/58",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:_e.map(t=>{const b=ee(t.value,v),h=P===t.value;return e.jsxs("button",{type:"button",onClick:()=>void O(t.value,(t.value==="custom",v)),className:`rounded-[18px] border px-3 py-3 text-left transition ${h?"border-[rgba(192,193,255,0.28)] bg-[rgba(192,193,255,0.14)] shadow-[0_18px_36px_rgba(5,12,24,0.24)]":"border-white/8 bg-white/[0.04] hover:bg-white/[0.07]"}`,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-white",children:t.value==="custom"?v.label:t.label}),e.jsx("div",{className:"mt-1 line-clamp-2 text-xs leading-5 text-white/58",children:t.description})]}),e.jsx("div",{className:`mt-1 size-4 rounded-full border ${h?"border-[rgba(192,193,255,0.65)] bg-[var(--primary)]":"border-white/25"}`})]}),e.jsx(Ue,{theme:b})]},t.value)})}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-3 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Custom theme editor"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/58",children:"Save a custom Forge palette through a guided modal, or paste and upload JSON directly."})]}),e.jsx(N,{type:"button",variant:P==="custom"?"secondary":"ghost",onClick:()=>d(!0),pending:A.isPending,children:P==="custom"?"Edit custom theme":"Create custom theme"})]})]}),e.jsxs(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Gamification style"}),e.jsx("p",{className:"text-sm text-white/58",children:"Choose the reward art style and download its optional trophy, unlock, and mascot sprites."})]}),Q!=null&&Q.installed?e.jsx("span",{className:"inline-flex rounded-full border border-emerald-200/18 bg-emerald-300/10 px-3 py-1 text-xs font-medium text-emerald-100",children:"Selected style downloaded"}):e.jsx("span",{className:"inline-flex rounded-full border border-amber-200/18 bg-amber-300/10 px-3 py-1 text-xs font-medium text-amber-100",children:"Selected style not downloaded"})]}),e.jsx("div",{className:"mt-3 grid gap-2 xl:grid-cols-3",children:$e.map(t=>{const b=z===t.value,h=J.find(me=>me.id===t.value),E=(h==null?void 0:h.installed)??!1,de=r.isPending&&r.variables===t.value;return e.jsxs("div",{className:`grid gap-2 rounded-[18px] border p-2.5 text-left transition ${b?"border-amber-200/28 bg-amber-300/[0.09] shadow-[0_18px_42px_rgba(0,0,0,0.26)]":"border-white/8 bg-white/[0.035] hover:border-white/16 hover:bg-white/[0.065]"}`,children:[e.jsx("button",{type:"button",onClick:()=>void ce(t.value),className:"grid gap-2 text-left","aria-label":`Select ${t.label}`,"aria-pressed":b,children:e.jsx(Be,{selected:b,theme:t.value})}),e.jsxs("span",{className:"grid gap-1 px-1 pb-1",children:[e.jsx("span",{className:"text-sm font-semibold text-white",children:t.label}),e.jsx("span",{className:"line-clamp-2 text-xs leading-5 text-white/58",children:t.description}),e.jsx("span",{className:"mt-1 text-[11px] uppercase tracking-[0.14em] text-white/42",children:E?`Downloaded ${(h==null?void 0:h.spriteCount)??0}/${(h==null?void 0:h.expectedSpriteCount)??0}`:"Not downloaded"}),e.jsxs(N,{type:"button",variant:E?"secondary":"primary",pending:de,disabled:E||r.isPending,onClick:()=>r.mutate(t.value),children:[e.jsx(pe,{className:"size-4"}),E?"Downloaded":"Download"]})]})]},t.value)})}),a.isPending?e.jsx("div",{className:"text-sm text-white/48",children:"Saving reward style…"}):null,r.isError?e.jsx("div",{className:"mt-3 rounded-[14px] border border-red-300/20 bg-red-500/10 px-3 py-2 text-sm text-red-100",children:r.error instanceof Error?r.error.message:"Could not download the selected reward art."}):null]}),e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:s("common.settings.localeLabel")}),e.jsx("p",{className:"text-sm text-white/58",children:s("common.settings.localeDescription")}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:[{value:"en",label:s("common.settings.localeEnglish")},{value:"fr",label:s("common.settings.localeFrench")}].map(t=>e.jsxs("label",{className:"flex items-center gap-3 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsx("input",{type:"radio",value:t.value,...c.register("localePreference")}),e.jsx("span",{className:"text-white/72",children:t.label})]},t.value))}),e.jsx(N,{type:"submit",pending:S.isPending,pendingLabel:"Saving settings",children:"Save settings"})]})]}),K?e.jsx(V,{healthy:!0}):null,e.jsx(We,{integrityScore:x.security.integrityScore,storageMode:x.security.storageMode,lastAuditAt:x.security.lastAuditAt,doctor:le,doctorLoading:y.isFetching||ie.isLoading,onRefreshDoctor:()=>void y.refetch(),onApplyFix:t=>void oe(t),applyingFixId:re})]}),e.jsx(He,{open:i,onOpenChange:d,value:v,onSave:t=>void O("custom",t)})]})}export{lt as SettingsPage};
|
|
1
|
+
import{r as j,j as e,aD as pe,d9 as xe,aC as ue,aG as ge,bl as he,da as be,aQ as fe}from"./vendor-DHkYh85p.js";import{j as ye,i as _,k as $}from"./state-B-4sS1xO.js";import{u as ve}from"./forms-BFlTgZ3W.js";import{Q as we,de as Y,F as L,I as F,j as je,df as Ne,T as ke,dg as D,B as N,dh as ee,P as Se,aF as Ce,di as Fe,dj as I,dk as Te,dl as Pe,dm as De,dn as Ae,dp as X,S as Ee,E as Z,C as T,dq as _e,dr as $e,ds as Ie,dt as Le,du as Me,dv as Qe,dw as Re,dx as qe,b$ as ze,dy as Je,dz as Ke}from"./index-CF4J4R9L.js";import{S as Oe}from"./settings-section-nav-DSOuht_F.js";import{P as Ge}from"./page-hero-DRy5b2MU.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./graph-D6JLqDbD.js";function R({theme:s,title:l,description:n}){return e.jsx("div",{className:"overflow-hidden rounded-[24px] border border-white/10",style:{background:`linear-gradient(180deg, ${s.panelHigh}, ${s.panelLow})`,color:s.ink},children:e.jsxs("div",{className:"px-4 py-4",style:{background:`radial-gradient(circle at top left, ${s.primary}33, transparent 42%), radial-gradient(circle at top right, ${s.secondary}2a, transparent 36%), linear-gradient(180deg, ${s.panel}, ${s.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:[s.primary,s.secondary,s.tertiary,s.panelHigh].map(i=>e.jsx("div",{className:"h-9 flex-1 rounded-[14px] border border-black/10",style:{background:i}},i))})]})})}function w({label:s,value:l,onChange:n,description:i}){return e.jsx(L,{label:s,description:i,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-white/10 bg-transparent p-1"}),e.jsx(F,{value:l,onChange:d=>n(d.target.value),placeholder:"#7cc7ff"})]})})}function He({open:s,onOpenChange:l,value:n,onSave:i}){const[d,p]=j.useState(n),[u,m]=j.useState(""),[y,f]=j.useState(null),k=j.useRef(null),c=a=>{const r=Y.parse(JSON.parse(a));p(r),m(JSON.stringify(r,null,2)),f(null)},g=a=>{const r=ee(a);p({...r,label:d.label.trim().length>0?d.label:`${r.label} Custom`})},S=async a=>{var o;const r=(o=a.target.files)==null?void 0:o[0];if(r)try{c(await r.text())}catch(C){f(C instanceof Error?C.message:"Forge could not parse that JSON theme.")}finally{a.target.value=""}},A=[{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:(a,r)=>e.jsxs("div",{className:"grid gap-5",children:[e.jsx(L,{label:"Theme label",description:"This label appears in Settings when the custom theme is active.",children:e.jsx(F,{value:a.label,onChange:o=>r({label:o.target.value}),placeholder:"Midnight Circuit"})}),e.jsx(L,{label:"Starter preset",children:e.jsx(je,{value:"",onChange:o=>g(o),options:Object.entries(Ne).map(([o,C])=>({value:o,label:C.label,description:C.description})),columns:2})}),e.jsx(R,{theme:a,title:a.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:(a,r)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(w,{label:"Primary",description:"Main emphasis color for actions and active state.",value:a.primary,onChange:o=>r({primary:o})}),e.jsx(w,{label:"Secondary",description:"Support accent for positive or secondary emphasis.",value:a.secondary,onChange:o=>r({secondary:o})}),e.jsx(w,{label:"Tertiary",description:"Warm contrast color for warnings, highlights, and supporting metrics.",value:a.tertiary,onChange:o=>r({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:(a,r)=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(w,{label:"Canvas",description:"Primary app background.",value:a.canvas,onChange:o=>r({canvas:o})}),e.jsx(w,{label:"Panel",description:"Default card and rail background.",value:a.panel,onChange:o=>r({panel:o})}),e.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[e.jsx(w,{label:"Panel high",description:"Raised highlights and stronger sections.",value:a.panelHigh,onChange:o=>r({panelHigh:o})}),e.jsx(w,{label:"Panel low",description:"Lower contrast and deeper card areas.",value:a.panelLow,onChange:o=>r({panelLow:o})})]}),e.jsx(w,{label:"Ink",description:"Main text and readable foreground color.",value:a.ink,onChange:o=>r({ink:o})}),e.jsx(R,{theme:a,title:a.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:a=>e.jsxs("div",{className:"grid gap-4",children:[e.jsx(L,{label:"Direct JSON",description:"Paste a full custom theme object, then click Apply JSON.",children:e.jsx(ke,{value:u,onChange:r=>m(r.target.value),className:"min-h-52 font-mono text-[13px] leading-6",placeholder:JSON.stringify(D,null,2)})}),e.jsxs("div",{className:"flex flex-wrap gap-3",children:[e.jsx(N,{type:"button",variant:"secondary",onClick:()=>{try{c(u)}catch(r){f(r instanceof Error?r.message:"Forge could not parse that JSON theme.")}},children:"Apply JSON"}),e.jsx(N,{type:"button",variant:"ghost",onClick:()=>{var r;return(r=k.current)==null?void 0:r.click()},children:"Upload JSON file"}),e.jsx("input",{ref:k,type:"file",accept:"application/json,.json",className:"hidden",onChange:S})]}),e.jsx(R,{theme:a,title:a.label,description:"Preview of the theme that will be saved if you submit now."})]})}];return e.jsx(we,{open:s,onOpenChange:a=>{a&&(p(n),m(""),f(null)),l(a)},eyebrow:"Settings",title:"Forge custom theme",description:"Build a dark Forge palette visually, or import one directly as JSON.",value:d,onChange:a=>{p(a),f(null)},draftPersistenceKey:"settings.theme-customizer",steps:A,error:y,onSubmit:async()=>{try{const a=Y.parse(d);i(a),l(!1)}catch(a){f(a instanceof Error?a.message:"Forge could not save that custom theme.")}},submitLabel:"Save custom theme",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]"})}function Ue({theme:s}){return e.jsx("div",{className:"mt-3 grid grid-cols-4 gap-2",children:[s.primary,s.secondary,s.tertiary,s.panelHigh].map(l=>e.jsx("div",{className:"h-6 rounded-[10px] border border-black/10",style:{background:l}},l))})}function Be({selected:s,theme:l}){return e.jsxs("div",{className:"relative min-h-[138px] overflow-hidden rounded-[18px] border border-white/10 bg-[radial-gradient(circle_at_24%_10%,rgba(255,199,104,0.22),transparent_30%),radial-gradient(circle_at_88%_12%,rgba(84,191,255,0.16),transparent_32%),linear-gradient(145deg,rgba(255,255,255,0.08),rgba(255,255,255,0.025))]",children:[e.jsx("div",{className:"absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-black/42 to-transparent"}),e.jsx("img",{src:Me(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_rgba(0,0,0,0.34)]"}),e.jsxs("div",{className:"absolute left-3 top-3 flex items-center gap-2 rounded-full border border-white/10 bg-black/28 px-2.5 py-1 text-[9px] font-semibold uppercase tracking-[0.14em] text-white/78 backdrop-blur-md",children:[e.jsx(ge,{className:"size-3 text-amber-200"}),"Live rewards"]}),e.jsx("div",{className:"absolute bottom-3 left-3 flex items-center gap-1.5",children:Qe.map(n=>e.jsx("span",{className:"grid size-11 place-items-center overflow-hidden rounded-[12px] border border-white/12 bg-black/26 p-1 shadow-[0_12px_22px_rgba(0,0,0,0.22)] backdrop-blur-md",children:e.jsx("img",{src:Re(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 ${s?"border-emerald-200/55 bg-emerald-300/18 text-emerald-100":"border-white/15 bg-black/20 text-white/40"}`,children:s?e.jsx(he,{className:"size-4"}):null})]})}function V({healthy:s}){return e.jsx(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Mobile companion"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:s?"iPhone bridge is syncing":"Connect the iPhone bridge"}),e.jsx("div",{className:"mt-1 max-w-3xl text-sm leading-6 text-white/58",children:s?"Review HealthKit, movement, and background sync permissions.":"Pair or refresh the native companion before relying on HealthKit, movement, or watch signals."})]}),e.jsx(ue,{to:"/settings/mobile",className:"inline-flex min-h-10 items-center rounded-[14px] bg-white/[0.08] px-3 py-2 text-sm text-white transition hover:bg-white/[0.12]",children:"Open mobile settings"})]})})}function M(s){return new Date(s).toLocaleString()}function te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i}){return i?[i.integrity.headline,i.integrity.topIssues.length>0?i.integrity.topIssues[0].summary:"No active Doctor warnings are holding back integrity.",`Storage mode: ${l}. Latest Doctor run: ${M(i.integrity.lastCheckedAt)}.`]:s>=100?["All currently reported settings and storage checks passed.",`Latest audit: ${M(n)}.`]:[`Forge is holding back ${Math.max(0,100-s)}% 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: ${M(n)}.`]}function se({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i}){const d=(i==null?void 0:i.integrity.score)??s,p=te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i});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-white/10 bg-white/[0.05] px-2.5 py-1 text-[11px] font-medium normal-case tracking-normal text-white/72 transition marker:hidden hover:border-white/18 hover:bg-white/[0.08] hover:text-white/88 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgba(192,193,255,0.35)] [&::-webkit-details-marker]:hidden",onKeyDown:u=>{var m;u.key==="Escape"&&((m=u.currentTarget.parentElement)==null||m.removeAttribute("open"))},children:[e.jsx(xe,{className:"size-3.5","aria-hidden":"true"}),d,"% integrity"]}),e.jsxs("span",{role:"tooltip",className:"absolute right-0 top-[calc(100%+0.55rem)] z-50 hidden w-[min(19rem,calc(100vw-2rem))] rounded-[16px] border border-white/10 bg-[rgba(10,15,27,0.98)] px-3 py-2.5 text-left text-xs leading-5 tracking-normal text-white/70 normal-case shadow-[0_18px_48px_rgba(3,8,18,0.46)] group-open:block",children:[e.jsx("span",{className:"block font-medium text-white/88",children:d>=100?"Integrity is complete":`Why this is ${d}%`}),p.map(u=>e.jsx("span",{className:"mt-1 block",children:u},u))]})]})}function We({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i,doctorLoading:d,onRefreshDoctor:p,onApplyFix:u,applyingFixId:m}){const y=(i==null?void 0:i.integrity.score)??s,f=(i==null?void 0:i.integrity.lastCheckedAt)??n,k=(i==null?void 0:i.issues.filter(g=>g.severity!=="info").slice(0,4))??[],[c]=te({integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i});return e.jsxs(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Security posture"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/58",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 text-xs leading-5 text-white/50",children:c})]}),e.jsx(se,{integrityScore:s,storageMode:l,lastAuditAt:n,doctor:i})]}),e.jsxs("div",{className:"mt-3 grid gap-2 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[14px] bg-white/[0.04] px-3 py-3",children:[e.jsx("div",{className:"text-xs text-white/54",children:"Storage mode"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:l})]}),e.jsxs("div",{className:"rounded-[14px] bg-white/[0.04] px-3 py-3",children:[e.jsx("div",{className:"text-xs text-white/54",children:"Last Doctor run"}),e.jsx("div",{className:"mt-1 text-base font-medium text-white",children:M(f)})]})]}),e.jsxs("div",{className:"mt-3 rounded-[14px] border border-white/8 bg-white/[0.035] 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-white",children:[e.jsx(be,{className:"size-4 text-cyan-200"}),"Forge Doctor"]}),e.jsxs(N,{type:"button",variant:"secondary",pending:d,onClick:p,children:[e.jsx(fe,{className:"size-4"}),"Run"]})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:i?`${y}% integrity. ${i.integrity.headline}`:"Run Doctor to check settings, storage, entities, rewards, and runtime consistency."}),k.length>0?e.jsx("div",{className:"mt-3 grid gap-2",children:k.map(g=>{var S;return e.jsx(Ye,{issue:g,applying:m===((S=g.fix)==null?void 0:S.id),onApplyFix:u},g.id)})}):i?e.jsx("div",{className:"mt-3 rounded-[12px] border border-emerald-200/12 bg-emerald-300/8 px-3 py-2 text-sm text-emerald-100",children:"No active consistency warnings."}):null]})]})}function Ye({issue:s,applying:l,onApplyFix:n}){var i;return e.jsx("div",{className:"rounded-[12px] border border-white/8 bg-black/12 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-white/42",children:[s.group," / ",s.severity]}),e.jsx("div",{className:"mt-1 text-sm text-white/78",children:s.summary})]}),((i=s.fix)==null?void 0:i.kind)==="safe_auto_fix"?e.jsx(N,{type:"button",variant:"secondary",pending:l,onClick:()=>n(s.fix.id),children:"Apply fix"}):null]})})}function lt(){var G,H,U,B,W;const{t:s}=Se(),l=Ce(),n=ye(),[i,d]=j.useState(!1),p=_({queryKey:["forge-operator-session"],queryFn:qe}),u=p.isSuccess,m=_({queryKey:["forge-settings"],queryFn:ze,enabled:u}),y=Fe(void 0,{skip:!u}),f=_({queryKey:["forge-companion-overview"],queryFn:async()=>(await Je()).overview,enabled:u,staleTime:3e4}),k=_({queryKey:["forge-gamification-assets"],queryFn:Ke,enabled:u,staleTime:3e4}),c=ve({defaultValues:{profile:{operatorName:"",operatorEmail:"",operatorTitle:""},notifications:{goalDriftAlerts:!0,dailyQuestReminders:!0,achievementCelebrations:!0},execution:{maxActiveTasks:2,timeAccountingMode:"split"},themePreference:"obsidian",gamificationTheme:"dramatic-smithie",customTheme:D,localePreference:"en"}}),g=async()=>{await Promise.all([n.invalidateQueries({queryKey:["forge-operator-session"]}),n.invalidateQueries({queryKey:["forge-settings"]})])},S=$({mutationFn:t=>I(t),onSuccess:g}),A=$({mutationFn:t=>I(t),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await g()}}),a=$({mutationFn:t=>I(t),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await g()}}),r=$({mutationFn:async t=>(await Te(t),I({gamificationTheme:t})),onSuccess:async t=>{n.setQueryData(["forge-settings"],t),await Promise.all([n.invalidateQueries({queryKey:["forge-settings"]}),n.invalidateQueries({queryKey:["forge-gamification-assets"]})])}}),[o,C]=Pe(),[ae,ie]=De(),[re,q]=j.useState(),ne=async()=>{await o().unwrap(),l(Ie([])),l(Le.util.resetApiState()),n.removeQueries({predicate:t=>{const[b]=t.queryKey;return typeof b=="string"&&b.startsWith("forge-")}}),await Promise.all([g(),p.refetch()])};j.useEffect(()=>{var t;(t=m.data)!=null&&t.settings&&c.reset(Ae.parse(m.data.settings))},[m.data,c]);const x=(G=m.data)==null?void 0:G.settings,le=(H=y.data)==null?void 0:H.doctor,P=c.watch("themePreference"),z=c.watch("gamificationTheme"),J=((U=k.data)==null?void 0:U.assets.styles)??[],Q=J.find(t=>t.id===z),v=c.watch("customTheme")??D,K=((B=f.data)==null?void 0:B.healthState)==="healthy_sync",oe=async t=>{if(window.confirm("Apply this Forge Doctor fix? Forge will only run the selected safe repair.")){q(t);try{await ae({fixIds:[t]}).unwrap(),await Promise.all([m.refetch(),y.refetch()])}finally{q(void 0)}}},O=async(t,b=v)=>{c.setValue("themePreference",t,{shouldDirty:!0}),c.setValue("customTheme",b??D,{shouldDirty:!0}),await A.mutateAsync({themePreference:t,customTheme:b??D})},ce=async t=>{c.setValue("gamificationTheme",t,{shouldDirty:!0}),await a.mutateAsync({gamificationTheme:t})};return j.useEffect(()=>{if(x)return X(P,v),()=>{X(x.themePreference,x.customTheme??null)}},[v,P,x,x==null?void 0:x.customTheme,x==null?void 0:x.themePreference]),p.isLoading||m.isLoading?e.jsx(Ee,{eyebrow:"Settings",title:"Loading settings",description:"Establishing the operator session and fetching current configuration.",columns:2,blocks:6}):p.isError?e.jsx(Z,{eyebrow:"Settings",error:p.error,onRetry:()=>void p.refetch()}):m.isError||!x?e.jsx(Z,{eyebrow:"Settings",error:m.error??new Error("Forge returned an empty settings payload."),onRetry:()=>void m.refetch()}):e.jsxs("div",{className:"mx-auto grid w-full max-w-[1220px] gap-5",children:[e.jsx(Ge,{title:"Settings",description:"Tune execution policy, timer behaviour, and personal preferences.",badge:e.jsx(se,{integrityScore:x.security.integrityScore,storageMode:x.security.storageMode,lastAuditAt:x.security.lastAuditAt})}),null,e.jsx(Oe,{}),(W=p.data)!=null&&W.session?e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3 rounded-[18px] border border-emerald-400/20 bg-emerald-500/[0.08] px-4 py-3 text-sm text-emerald-100/88",children:[e.jsxs("div",{children:["Operator session active as"," ",e.jsx("span",{className:"font-medium text-white",children:p.data.session.actorLabel}),"."]}),e.jsx(N,{variant:"secondary",size:"sm",pending:C.isLoading,pendingLabel:"Resetting session",onClick:()=>void ne(),children:"Reset operator session"})]}):null,e.jsxs("div",{className:"grid gap-4",children:[K?null:e.jsx(V,{healthy:!1}),e.jsxs("form",{className:"grid gap-4",onSubmit:c.handleSubmit(async t=>{await S.mutateAsync(t)}),children:[e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",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-white/58",children:"Name"}),e.jsx(F,{...c.register("profile.operatorName")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Email"}),e.jsx(F,{...c.register("profile.operatorEmail")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Title"}),e.jsx(F,{...c.register("profile.operatorTitle")})]}),e.jsx("div",{className:"mt-2 font-label text-[11px] uppercase tracking-[0.18em] text-white/45",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-white/58",children:"Maximum active tasks"}),e.jsx(F,{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-white/58",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(t=>e.jsxs("label",{className:"grid gap-2 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsxs("span",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"radio",value:t.value,...c.register("execution.timeAccountingMode")}),e.jsx("span",{className:"text-white/82",children:t.label})]}),e.jsx("span",{className:"text-xs leading-5 text-white/56",children:t.description})]},t.value))})]})]}),e.jsx("div",{className:"mt-2 font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Notification rules"}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Goal drift alerts"}),e.jsx("input",{type:"checkbox",...c.register("notifications.goalDriftAlerts")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Daily quest reminders"}),e.jsx("input",{type:"checkbox",...c.register("notifications.dailyQuestReminders")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[16px] bg-white/[0.04] px-3 py-2.5",children:[e.jsx("span",{className:"text-white/72",children:"Achievement celebrations"}),e.jsx("input",{type:"checkbox",...c.register("notifications.achievementCelebrations")})]})]}),e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Theme calibration"}),e.jsx("p",{className:"text-sm text-white/58",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:_e.map(t=>{const b=ee(t.value,v),h=P===t.value;return e.jsxs("button",{type:"button",onClick:()=>void O(t.value,(t.value==="custom",v)),className:`rounded-[18px] border px-3 py-3 text-left transition ${h?"border-[rgba(192,193,255,0.28)] bg-[rgba(192,193,255,0.14)] shadow-[0_18px_36px_rgba(5,12,24,0.24)]":"border-white/8 bg-white/[0.04] hover:bg-white/[0.07]"}`,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-white",children:t.value==="custom"?v.label:t.label}),e.jsx("div",{className:"mt-1 line-clamp-2 text-xs leading-5 text-white/58",children:t.description})]}),e.jsx("div",{className:`mt-1 size-4 rounded-full border ${h?"border-[rgba(192,193,255,0.65)] bg-[var(--primary)]":"border-white/25"}`})]}),e.jsx(Ue,{theme:b})]},t.value)})}),e.jsxs("div",{className:"mt-3 flex flex-wrap items-center justify-between gap-3 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Custom theme editor"}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/58",children:"Save a custom Forge palette through a guided modal, or paste and upload JSON directly."})]}),e.jsx(N,{type:"button",variant:P==="custom"?"secondary":"ghost",onClick:()=>d(!0),pending:A.isPending,children:P==="custom"?"Edit custom theme":"Create custom theme"})]})]}),e.jsxs(T,{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:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Gamification style"}),e.jsx("p",{className:"text-sm text-white/58",children:"Choose the reward art style and download its optional trophy, unlock, and mascot sprites."})]}),Q!=null&&Q.installed?e.jsx("span",{className:"inline-flex rounded-full border border-emerald-200/18 bg-emerald-300/10 px-3 py-1 text-xs font-medium text-emerald-100",children:"Selected style downloaded"}):e.jsx("span",{className:"inline-flex rounded-full border border-amber-200/18 bg-amber-300/10 px-3 py-1 text-xs font-medium text-amber-100",children:"Selected style not downloaded"})]}),e.jsx("div",{className:"mt-3 grid gap-2 xl:grid-cols-3",children:$e.map(t=>{const b=z===t.value,h=J.find(me=>me.id===t.value),E=(h==null?void 0:h.installed)??!1,de=r.isPending&&r.variables===t.value;return e.jsxs("div",{className:`grid gap-2 rounded-[18px] border p-2.5 text-left transition ${b?"border-amber-200/28 bg-amber-300/[0.09] shadow-[0_18px_42px_rgba(0,0,0,0.26)]":"border-white/8 bg-white/[0.035] hover:border-white/16 hover:bg-white/[0.065]"}`,children:[e.jsx("button",{type:"button",onClick:()=>void ce(t.value),className:"grid gap-2 text-left","aria-label":`Select ${t.label}`,"aria-pressed":b,children:e.jsx(Be,{selected:b,theme:t.value})}),e.jsxs("span",{className:"grid gap-1 px-1 pb-1",children:[e.jsx("span",{className:"text-sm font-semibold text-white",children:t.label}),e.jsx("span",{className:"line-clamp-2 text-xs leading-5 text-white/58",children:t.description}),e.jsx("span",{className:"mt-1 text-[11px] uppercase tracking-[0.14em] text-white/42",children:E?`Downloaded ${(h==null?void 0:h.spriteCount)??0}/${(h==null?void 0:h.expectedSpriteCount)??0}`:"Not downloaded"}),e.jsxs(N,{type:"button",variant:E?"secondary":"primary",pending:de,disabled:E||r.isPending,onClick:()=>r.mutate(t.value),children:[e.jsx(pe,{className:"size-4"}),E?"Downloaded":"Download"]})]})]},t.value)})}),a.isPending?e.jsx("div",{className:"text-sm text-white/48",children:"Saving reward style…"}):null,r.isError?e.jsx("div",{className:"mt-3 rounded-[14px] border border-red-300/20 bg-red-500/10 px-3 py-2 text-sm text-red-100",children:r.error instanceof Error?r.error.message:"Could not download the selected reward art."}):null]}),e.jsxs(T,{className:"p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:s("common.settings.localeLabel")}),e.jsx("p",{className:"text-sm text-white/58",children:s("common.settings.localeDescription")}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:[{value:"en",label:s("common.settings.localeEnglish")},{value:"fr",label:s("common.settings.localeFrench")}].map(t=>e.jsxs("label",{className:"flex items-center gap-3 rounded-[16px] bg-white/[0.04] px-3 py-3",children:[e.jsx("input",{type:"radio",value:t.value,...c.register("localePreference")}),e.jsx("span",{className:"text-white/72",children:t.label})]},t.value))}),e.jsx(N,{type:"submit",pending:S.isPending,pendingLabel:"Saving settings",children:"Save settings"})]})]}),K?e.jsx(V,{healthy:!0}):null,e.jsx(We,{integrityScore:x.security.integrityScore,storageMode:x.security.storageMode,lastAuditAt:x.security.lastAuditAt,doctor:le,doctorLoading:y.isFetching||ie.isLoading,onRefreshDoctor:()=>void y.refetch(),onApplyFix:t=>void oe(t),applyingFixId:re})]}),e.jsx(He,{open:i,onOpenChange:d,value:v,onSave:t=>void O("custom",t)})]})}export{lt as SettingsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{j as e,r as w}from"./vendor-DHkYh85p.js";import{j as $,i as v,k as K}from"./state-B-4sS1xO.js";import{u as D}from"./forms-BFlTgZ3W.js";import{S as H}from"./settings-section-nav-CCFm27r2.js";import{c as u,Z as S,W as B,f as z,u as U,eq as Y,er as ee,S as se,E as te,C as ae,I as P,T as E,B as V,dx as re,cZ as ie,es as le,et as ne,ad as de}from"./index-BHTUu_4M.js";import{m as G}from"./motion-BeD44FeG.js";import{P as ce}from"./page-hero-CQWo1Mm_.js";import{M as W}from"./metric-tile-DX6TclqM.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./graph-D6JLqDbD.js";function oe(a){switch(a){case"platinum":return"text-cyan-200";case"gold":return"text-amber-200";case"silver":return"text-slate-200";default:return"text-orange-200"}}function me(a){switch(a){case"surging":return"from-[rgba(192,193,255,0.3)] via-[rgba(78,222,163,0.22)] to-[rgba(255,185,95,0.22)]";case"steady":return"from-[rgba(192,193,255,0.24)] via-[rgba(192,193,255,0.14)] to-[rgba(78,222,163,0.18)]";default:return"from-[rgba(255,185,95,0.2)] via-[rgba(255,185,95,0.12)] to-[rgba(192,193,255,0.16)]"}}function xe({profile:a,achievements:o,milestoneRewards:n,momentumPulse:m,recentLedger:R=[],className:j,tone:k="core"}){const y=o.filter(r=>r.unlocked),h=(y.length>0?y:o).slice(0,3),X=n.slice(0,3),L=R.slice(0,3),I=Math.min(100,Math.round(a.currentLevelXp/a.nextLevelXp*100));return e.jsxs("section",{className:S("min-w-0 overflow-hidden rounded-[30px] border border-white/6 bg-[linear-gradient(180deg,rgba(18,24,40,0.96),rgba(11,16,28,0.94))] shadow-[0_24px_70px_rgba(4,8,18,0.3)]",k==="psyche"&&"bg-[linear-gradient(180deg,rgba(18,27,35,0.96),rgba(12,20,26,0.94))]",j),children:[e.jsx("div",{className:S("bg-gradient-to-r px-5 py-5",me(m.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:"font-label text-[11px] uppercase tracking-[0.2em] text-white/55",children:"Weekly progress"}),e.jsx("h2",{className:"mt-3 font-display text-3xl leading-none text-white lg:text-4xl",children:m.headline}),e.jsx("p",{className:"mt-3 max-w-3xl text-sm leading-7 text-white/68",children:m.detail})]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap gap-2",children:[e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:["Level ",a.level]}),e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:[a.streakDays," day streak"]}),e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:[a.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(G.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{duration:.24,ease:"easeOut"},className:"overflow-hidden rounded-[24px] bg-white/[0.04] 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 flex-1",children:[e.jsx("div",{className:"font-medium text-white",children:"Next reward"}),e.jsx("div",{className:"mt-2 text-sm text-white/60",children:m.nextMilestoneLabel})]}),e.jsx(u,{wrap:!0,className:"max-w-[12rem] shrink-0 self-start text-[var(--tertiary)]",children:m.celebrationLabel})]}),e.jsx("div",{className:"mt-5",children:e.jsx(B,{value:I})}),e.jsxs("div",{className:"mt-3 flex items-center justify-between gap-3 text-xs uppercase tracking-[0.16em] text-white/38",children:[e.jsxs("span",{children:[a.currentLevelXp,"/",a.nextLevelXp," XP"]}),e.jsxs("span",{children:[a.comboMultiplier.toFixed(2),"x combo"]})]})]}),e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:h.map((r,d)=>e.jsxs(G.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.24,delay:.04*d,ease:"easeOut"},className:"overflow-hidden rounded-[22px] bg-white/[0.04] p-4",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 text-white",children:r.title}),e.jsx(u,{wrap:!0,className:S("max-w-[8rem] shrink-0 self-start",oe(r.tier)),children:r.tier})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:r.summary}),e.jsx("div",{className:"mt-4 text-xs uppercase tracking-[0.16em] text-white/40",children:r.progressLabel})]},r.id))})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"overflow-hidden rounded-[24px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Rewards in progress"}),e.jsx("div",{className:"mt-4 grid gap-3",children:X.map(r=>{const d=Math.min(100,Math.round(r.current/r.target*100));return e.jsxs("div",{className:"overflow-hidden rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",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 text-white",children:r.title}),e.jsx(u,{wrap:!0,className:S("max-w-[10.5rem] shrink-0 self-start",r.completed?"text-emerald-300":"text-white/68"),children:r.rewardLabel})]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:r.summary}),e.jsx("div",{className:"mt-4",children:e.jsx(B,{value:d})}),e.jsx("div",{className:"mt-3 text-xs uppercase tracking-[0.16em] text-white/38",children:r.progressLabel})]},r.id)})})]}),L.length>0?e.jsxs("div",{className:"overflow-hidden rounded-[24px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Recent XP changes"}),e.jsx("div",{className:"mt-4 grid gap-3",children:L.map(r=>e.jsxs("div",{className:"overflow-hidden rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",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 text-white",children:r.reasonTitle}),e.jsxs(u,{wrap:!0,className:S("max-w-[8rem] shrink-0 self-start",r.deltaXp>=0?"text-emerald-300":"text-amber-300"),children:[r.deltaXp>0?"+":"",r.deltaXp," XP"]})]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:r.reasonSummary}),e.jsx("div",{className:"mt-3 text-xs uppercase tracking-[0.16em] text-white/38",children:z(r.createdAt)})]},r.id))})]}):null]})]})]})}function pe(a){return JSON.stringify(a,null,2)}function Z(a){const o=a.trim();if(!o)return{};const n=JSON.parse(o);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("Expected a JSON object.");return n}function ke(){var F,_,A;const a=U(),o=$(),[n,m]=w.useState(""),[R,j]=w.useState(null),[k,y]=w.useState(null),h=v({queryKey:["forge-operator-session"],queryFn:re}),X=h.isSuccess,L=v({queryKey:["forge-xp-metrics"],queryFn:ie}),I=v({queryKey:["forge-reward-rules"],queryFn:le,enabled:X}),r=v({queryKey:["forge-reward-ledger"],queryFn:()=>ne(30),enabled:X}),d=v({queryKey:["forge-psyche-overview"],queryFn:async()=>(await de()).overview}),g=D({defaultValues:{title:"",description:"",active:!0,configJson:"{}"}}),l=D({defaultValues:{entityType:"task",entityId:"",deltaXp:15,reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"}}),q=async()=>{await Promise.all([o.invalidateQueries({queryKey:["forge-xp-metrics"]}),o.invalidateQueries({queryKey:["forge-reward-rules"]}),o.invalidateQueries({queryKey:["forge-reward-ledger"]})])},O=K({mutationFn:s=>Y(s.ruleId,{title:s.title,description:s.description,active:s.active,config:s.config}),onSuccess:q}),b=K({mutationFn:ee,onSuccess:q}),x=((F=I.data)==null?void 0:F.rules)??[],M=w.useMemo(()=>{var s,i,f,N,T,C,Q;return{system:[{id:"operator_manual_reward",label:"Operator reward ledger"}],goal:a.snapshot.goals.map(t=>({id:t.id,label:t.title})),project:a.snapshot.dashboard.projects.map(t=>({id:t.id,label:t.title})),task:a.snapshot.tasks.map(t=>({id:t.id,label:t.title})),habit:a.snapshot.habits.map(t=>({id:t.id,label:t.title})),tag:a.snapshot.tags.map(t=>({id:t.id,label:t.name})),note:[],insight:[],psyche_value:(((s=d.data)==null?void 0:s.values)??[]).map(t=>({id:t.id,label:t.title})),behavior_pattern:(((i=d.data)==null?void 0:i.patterns)??[]).map(t=>({id:t.id,label:t.title})),behavior:(((f=d.data)==null?void 0:f.behaviors)??[]).map(t=>({id:t.id,label:t.title})),belief_entry:(((N=d.data)==null?void 0:N.beliefs)??[]).map(t=>({id:t.id,label:t.statement})),mode_profile:(((T=d.data)==null?void 0:T.modes)??[]).map(t=>({id:t.id,label:t.title})),flashcard:(((C=d.data)==null?void 0:C.flashcards)??[]).map(t=>({id:t.id,label:t.title||t.message})),trigger_report:(((Q=d.data)==null?void 0:Q.reports)??[]).map(t=>({id:t.id,label:t.title}))}},[d.data,a.snapshot.dashboard.projects,a.snapshot.goals,a.snapshot.habits,a.snapshot.tags,a.snapshot.tasks]);w.useEffect(()=>{var N;const s=l.getValues("entityType"),i=l.getValues("entityId"),f=M[s]??[];i&&f.some(T=>T.id===i)||l.setValue("entityId",((N=f[0])==null?void 0:N.id)??"")},[l,M]),w.useEffect(()=>{x.length&&(!n||!x.some(s=>s.id===n))&&m(x[0].id)},[x,n]);const p=x.find(s=>s.id===n)??x[0]??null;w.useEffect(()=>{p&&(g.reset({title:p.title,description:p.description,active:p.active,configJson:pe(p.config)}),j(null))},[p,g]);const c=(_=L.data)==null?void 0:_.metrics,J=(((A=r.data)==null?void 0:A.ledger)??[]).filter(s=>s.metadata.manual===!0).slice(0,8);return h.isLoading?e.jsx(se,{eyebrow:"Settings · Rewards",title:"Loading reward controls",description:"Establishing the operator session and fetching reward configuration.",columns:2,blocks:6}):h.isError?e.jsx(te,{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(ce,{title:"Rewards",description:"XP command deck, reward rule editor, manual bonus grants, and ledger history."}),e.jsx(H,{}),e.jsx("div",{className:"grid gap-5",children:e.jsxs(ae,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Reward operations"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[c?e.jsx(xe,{profile:c.profile,achievements:c.achievements,milestoneRewards:c.milestoneRewards,momentumPulse:c.momentumPulse,recentLedger:c.recentLedger}):null,c?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(W,{label:"Total XP",value:c.profile.totalXp,tone:"core"}),e.jsx(W,{label:"Daily ambient",value:`${c.dailyAmbientXp} / ${c.dailyAmbientCap}`,tone:"core"})]}):null,e.jsxs("div",{className:"grid gap-4 xl:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Reward rule editor"}),x.length>0?e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:g.handleSubmit(async s=>{try{j(null);const i=Z(s.configJson);if(!p)return;await O.mutateAsync({ruleId:p.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 text-white/58",children:"Rule"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",value:n,onChange:s=>m(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 text-white/58",children:"Title"}),e.jsx(P,{...g.register("title")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Description"}),e.jsx(E,{className:"min-h-24",...g.register("description")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[18px] bg-[rgba(8,13,28,0.68)] px-4 py-3",children:[e.jsx("span",{className:"text-white/72",children:"Rule is active"}),e.jsx("input",{type:"checkbox",...g.register("active")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Config JSON"}),e.jsx(E,{className:"min-h-28 font-mono text-xs",...g.register("configJson")})]}),R?e.jsx("div",{className:"text-sm text-amber-300",children:R}):null,e.jsx(V,{type:"submit",pending:O.isPending,pendingLabel:"Saving rule",children:"Save reward rule"})]}):e.jsx("div",{className:"mt-4 text-sm text-white/58",children:"Loading reward rules…"})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Manual bonus XP"}),e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:l.handleSubmit(async s=>{try{y(null);const i=Z(s.metadataJson);await b.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){y(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 text-white/58",children:"Entity type"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",...l.register("entityType"),children:Object.keys(M).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 text-white/58",children:"Entity id"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",...l.register("entityId"),children:(M[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 text-white/58",children:"Delta XP"}),e.jsx(P,{type:"number",...l.register("deltaXp",{valueAsNumber:!0})})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Reason title"}),e.jsx(P,{...l.register("reasonTitle")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",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 text-white/58",children:"Metadata JSON"}),e.jsx(E,{className:"min-h-24 font-mono text-xs",...l.register("metadataJson")})]}),k?e.jsx("div",{className:"text-sm text-amber-300",children:k}):null,e.jsx(V,{type:"submit",pending:b.isPending,pendingLabel:"Issuing bonus",children:"Issue bonus XP"})]}),b.data?e.jsxs("div",{className:"mt-4 rounded-[18px] bg-[rgba(192,193,255,0.12)] p-4 text-sm text-white",children:["Granted ",b.data.reward.deltaXp>0?"+":"",b.data.reward.deltaXp," XP for ",e.jsx("strong",{children:b.data.reward.reasonTitle}),"."]}):null]})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Manual bonus history"}),e.jsx("div",{className:"mt-4 grid gap-3",children:J.length===0?e.jsx("div",{className:"rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4 text-sm text-white/58",children:"No manual bonus grants yet."}):J.map(s=>e.jsxs("div",{className:"rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:s.reasonTitle}),e.jsxs(u,{className:s.deltaXp>=0?"text-emerald-300":"text-amber-300",children:[s.deltaXp>0?"+":"",s.deltaXp," XP"]})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:s.reasonSummary||"No summary supplied."}),e.jsxs("div",{className:"mt-2 text-xs uppercase tracking-[0.16em] text-white/38",children:[s.entityType," · ",s.entityId," · ",new Date(s.createdAt).toLocaleString()]})]},s.id))})]})]})]})})]})}export{ke as SettingsRewardsPage};
|
|
1
|
+
import{j as e,r as w}from"./vendor-DHkYh85p.js";import{j as $,i as v,k as K}from"./state-B-4sS1xO.js";import{u as D}from"./forms-BFlTgZ3W.js";import{S as H}from"./settings-section-nav-DSOuht_F.js";import{c as u,Z as S,W as B,f as z,u as U,eq as Y,er as ee,S as se,E as te,C as ae,I as P,T as E,B as V,dx as re,cZ as ie,es as le,et as ne,ad as de}from"./index-CF4J4R9L.js";import{m as G}from"./motion-BeD44FeG.js";import{P as ce}from"./page-hero-DRy5b2MU.js";import{M as W}from"./metric-tile-DKpo-8xw.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./graph-D6JLqDbD.js";function oe(a){switch(a){case"platinum":return"text-cyan-200";case"gold":return"text-amber-200";case"silver":return"text-slate-200";default:return"text-orange-200"}}function me(a){switch(a){case"surging":return"from-[rgba(192,193,255,0.3)] via-[rgba(78,222,163,0.22)] to-[rgba(255,185,95,0.22)]";case"steady":return"from-[rgba(192,193,255,0.24)] via-[rgba(192,193,255,0.14)] to-[rgba(78,222,163,0.18)]";default:return"from-[rgba(255,185,95,0.2)] via-[rgba(255,185,95,0.12)] to-[rgba(192,193,255,0.16)]"}}function xe({profile:a,achievements:o,milestoneRewards:n,momentumPulse:m,recentLedger:R=[],className:j,tone:k="core"}){const y=o.filter(r=>r.unlocked),h=(y.length>0?y:o).slice(0,3),X=n.slice(0,3),L=R.slice(0,3),I=Math.min(100,Math.round(a.currentLevelXp/a.nextLevelXp*100));return e.jsxs("section",{className:S("min-w-0 overflow-hidden rounded-[30px] border border-white/6 bg-[linear-gradient(180deg,rgba(18,24,40,0.96),rgba(11,16,28,0.94))] shadow-[0_24px_70px_rgba(4,8,18,0.3)]",k==="psyche"&&"bg-[linear-gradient(180deg,rgba(18,27,35,0.96),rgba(12,20,26,0.94))]",j),children:[e.jsx("div",{className:S("bg-gradient-to-r px-5 py-5",me(m.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:"font-label text-[11px] uppercase tracking-[0.2em] text-white/55",children:"Weekly progress"}),e.jsx("h2",{className:"mt-3 font-display text-3xl leading-none text-white lg:text-4xl",children:m.headline}),e.jsx("p",{className:"mt-3 max-w-3xl text-sm leading-7 text-white/68",children:m.detail})]}),e.jsxs("div",{className:"flex min-w-0 flex-wrap gap-2",children:[e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:["Level ",a.level]}),e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:[a.streakDays," day streak"]}),e.jsxs(u,{wrap:!0,className:"bg-black/20 text-white/84",children:[a.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(G.div,{initial:{opacity:0,y:8},animate:{opacity:1,y:0},transition:{duration:.24,ease:"easeOut"},className:"overflow-hidden rounded-[24px] bg-white/[0.04] 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 flex-1",children:[e.jsx("div",{className:"font-medium text-white",children:"Next reward"}),e.jsx("div",{className:"mt-2 text-sm text-white/60",children:m.nextMilestoneLabel})]}),e.jsx(u,{wrap:!0,className:"max-w-[12rem] shrink-0 self-start text-[var(--tertiary)]",children:m.celebrationLabel})]}),e.jsx("div",{className:"mt-5",children:e.jsx(B,{value:I})}),e.jsxs("div",{className:"mt-3 flex items-center justify-between gap-3 text-xs uppercase tracking-[0.16em] text-white/38",children:[e.jsxs("span",{children:[a.currentLevelXp,"/",a.nextLevelXp," XP"]}),e.jsxs("span",{children:[a.comboMultiplier.toFixed(2),"x combo"]})]})]}),e.jsx("div",{className:"grid gap-3 md:grid-cols-3",children:h.map((r,d)=>e.jsxs(G.div,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},transition:{duration:.24,delay:.04*d,ease:"easeOut"},className:"overflow-hidden rounded-[22px] bg-white/[0.04] p-4",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 text-white",children:r.title}),e.jsx(u,{wrap:!0,className:S("max-w-[8rem] shrink-0 self-start",oe(r.tier)),children:r.tier})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:r.summary}),e.jsx("div",{className:"mt-4 text-xs uppercase tracking-[0.16em] text-white/40",children:r.progressLabel})]},r.id))})]}),e.jsxs("div",{className:"grid gap-4",children:[e.jsxs("div",{className:"overflow-hidden rounded-[24px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Rewards in progress"}),e.jsx("div",{className:"mt-4 grid gap-3",children:X.map(r=>{const d=Math.min(100,Math.round(r.current/r.target*100));return e.jsxs("div",{className:"overflow-hidden rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",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 text-white",children:r.title}),e.jsx(u,{wrap:!0,className:S("max-w-[10.5rem] shrink-0 self-start",r.completed?"text-emerald-300":"text-white/68"),children:r.rewardLabel})]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:r.summary}),e.jsx("div",{className:"mt-4",children:e.jsx(B,{value:d})}),e.jsx("div",{className:"mt-3 text-xs uppercase tracking-[0.16em] text-white/38",children:r.progressLabel})]},r.id)})})]}),L.length>0?e.jsxs("div",{className:"overflow-hidden rounded-[24px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Recent XP changes"}),e.jsx("div",{className:"mt-4 grid gap-3",children:L.map(r=>e.jsxs("div",{className:"overflow-hidden rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",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 text-white",children:r.reasonTitle}),e.jsxs(u,{wrap:!0,className:S("max-w-[8rem] shrink-0 self-start",r.deltaXp>=0?"text-emerald-300":"text-amber-300"),children:[r.deltaXp>0?"+":"",r.deltaXp," XP"]})]}),e.jsx("div",{className:"mt-2 text-sm text-white/58",children:r.reasonSummary}),e.jsx("div",{className:"mt-3 text-xs uppercase tracking-[0.16em] text-white/38",children:z(r.createdAt)})]},r.id))})]}):null]})]})]})}function pe(a){return JSON.stringify(a,null,2)}function Z(a){const o=a.trim();if(!o)return{};const n=JSON.parse(o);if(!n||typeof n!="object"||Array.isArray(n))throw new Error("Expected a JSON object.");return n}function ke(){var F,_,A;const a=U(),o=$(),[n,m]=w.useState(""),[R,j]=w.useState(null),[k,y]=w.useState(null),h=v({queryKey:["forge-operator-session"],queryFn:re}),X=h.isSuccess,L=v({queryKey:["forge-xp-metrics"],queryFn:ie}),I=v({queryKey:["forge-reward-rules"],queryFn:le,enabled:X}),r=v({queryKey:["forge-reward-ledger"],queryFn:()=>ne(30),enabled:X}),d=v({queryKey:["forge-psyche-overview"],queryFn:async()=>(await de()).overview}),g=D({defaultValues:{title:"",description:"",active:!0,configJson:"{}"}}),l=D({defaultValues:{entityType:"task",entityId:"",deltaXp:15,reasonTitle:"Operator bonus",reasonSummary:"Manual boost for a meaningful action captured with good provenance.",metadataJson:"{}"}}),q=async()=>{await Promise.all([o.invalidateQueries({queryKey:["forge-xp-metrics"]}),o.invalidateQueries({queryKey:["forge-reward-rules"]}),o.invalidateQueries({queryKey:["forge-reward-ledger"]})])},O=K({mutationFn:s=>Y(s.ruleId,{title:s.title,description:s.description,active:s.active,config:s.config}),onSuccess:q}),b=K({mutationFn:ee,onSuccess:q}),x=((F=I.data)==null?void 0:F.rules)??[],M=w.useMemo(()=>{var s,i,f,N,T,C,Q;return{system:[{id:"operator_manual_reward",label:"Operator reward ledger"}],goal:a.snapshot.goals.map(t=>({id:t.id,label:t.title})),project:a.snapshot.dashboard.projects.map(t=>({id:t.id,label:t.title})),task:a.snapshot.tasks.map(t=>({id:t.id,label:t.title})),habit:a.snapshot.habits.map(t=>({id:t.id,label:t.title})),tag:a.snapshot.tags.map(t=>({id:t.id,label:t.name})),note:[],insight:[],psyche_value:(((s=d.data)==null?void 0:s.values)??[]).map(t=>({id:t.id,label:t.title})),behavior_pattern:(((i=d.data)==null?void 0:i.patterns)??[]).map(t=>({id:t.id,label:t.title})),behavior:(((f=d.data)==null?void 0:f.behaviors)??[]).map(t=>({id:t.id,label:t.title})),belief_entry:(((N=d.data)==null?void 0:N.beliefs)??[]).map(t=>({id:t.id,label:t.statement})),mode_profile:(((T=d.data)==null?void 0:T.modes)??[]).map(t=>({id:t.id,label:t.title})),flashcard:(((C=d.data)==null?void 0:C.flashcards)??[]).map(t=>({id:t.id,label:t.title||t.message})),trigger_report:(((Q=d.data)==null?void 0:Q.reports)??[]).map(t=>({id:t.id,label:t.title}))}},[d.data,a.snapshot.dashboard.projects,a.snapshot.goals,a.snapshot.habits,a.snapshot.tags,a.snapshot.tasks]);w.useEffect(()=>{var N;const s=l.getValues("entityType"),i=l.getValues("entityId"),f=M[s]??[];i&&f.some(T=>T.id===i)||l.setValue("entityId",((N=f[0])==null?void 0:N.id)??"")},[l,M]),w.useEffect(()=>{x.length&&(!n||!x.some(s=>s.id===n))&&m(x[0].id)},[x,n]);const p=x.find(s=>s.id===n)??x[0]??null;w.useEffect(()=>{p&&(g.reset({title:p.title,description:p.description,active:p.active,configJson:pe(p.config)}),j(null))},[p,g]);const c=(_=L.data)==null?void 0:_.metrics,J=(((A=r.data)==null?void 0:A.ledger)??[]).filter(s=>s.metadata.manual===!0).slice(0,8);return h.isLoading?e.jsx(se,{eyebrow:"Settings · Rewards",title:"Loading reward controls",description:"Establishing the operator session and fetching reward configuration.",columns:2,blocks:6}):h.isError?e.jsx(te,{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(ce,{title:"Rewards",description:"XP command deck, reward rule editor, manual bonus grants, and ledger history."}),e.jsx(H,{}),e.jsx("div",{className:"grid gap-5",children:e.jsxs(ae,{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Reward operations"}),e.jsxs("div",{className:"mt-4 grid gap-4",children:[c?e.jsx(xe,{profile:c.profile,achievements:c.achievements,milestoneRewards:c.milestoneRewards,momentumPulse:c.momentumPulse,recentLedger:c.recentLedger}):null,c?e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(W,{label:"Total XP",value:c.profile.totalXp,tone:"core"}),e.jsx(W,{label:"Daily ambient",value:`${c.dailyAmbientXp} / ${c.dailyAmbientCap}`,tone:"core"})]}):null,e.jsxs("div",{className:"grid gap-4 xl:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Reward rule editor"}),x.length>0?e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:g.handleSubmit(async s=>{try{j(null);const i=Z(s.configJson);if(!p)return;await O.mutateAsync({ruleId:p.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 text-white/58",children:"Rule"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",value:n,onChange:s=>m(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 text-white/58",children:"Title"}),e.jsx(P,{...g.register("title")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Description"}),e.jsx(E,{className:"min-h-24",...g.register("description")})]}),e.jsxs("label",{className:"flex items-center justify-between rounded-[18px] bg-[rgba(8,13,28,0.68)] px-4 py-3",children:[e.jsx("span",{className:"text-white/72",children:"Rule is active"}),e.jsx("input",{type:"checkbox",...g.register("active")})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Config JSON"}),e.jsx(E,{className:"min-h-28 font-mono text-xs",...g.register("configJson")})]}),R?e.jsx("div",{className:"text-sm text-amber-300",children:R}):null,e.jsx(V,{type:"submit",pending:O.isPending,pendingLabel:"Saving rule",children:"Save reward rule"})]}):e.jsx("div",{className:"mt-4 text-sm text-white/58",children:"Loading reward rules…"})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Manual bonus XP"}),e.jsxs("form",{className:"mt-4 grid gap-4",onSubmit:l.handleSubmit(async s=>{try{y(null);const i=Z(s.metadataJson);await b.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){y(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 text-white/58",children:"Entity type"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",...l.register("entityType"),children:Object.keys(M).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 text-white/58",children:"Entity id"}),e.jsx("select",{className:"rounded-[14px] bg-white/[0.06] px-3 py-3 text-white",...l.register("entityId"),children:(M[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 text-white/58",children:"Delta XP"}),e.jsx(P,{type:"number",...l.register("deltaXp",{valueAsNumber:!0})})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",children:"Reason title"}),e.jsx(P,{...l.register("reasonTitle")})]})]}),e.jsxs("label",{className:"grid gap-2",children:[e.jsx("span",{className:"text-sm text-white/58",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 text-white/58",children:"Metadata JSON"}),e.jsx(E,{className:"min-h-24 font-mono text-xs",...l.register("metadataJson")})]}),k?e.jsx("div",{className:"text-sm text-amber-300",children:k}):null,e.jsx(V,{type:"submit",pending:b.isPending,pendingLabel:"Issuing bonus",children:"Issue bonus XP"})]}),b.data?e.jsxs("div",{className:"mt-4 rounded-[18px] bg-[rgba(192,193,255,0.12)] p-4 text-sm text-white",children:["Granted ",b.data.reward.deltaXp>0?"+":"",b.data.reward.deltaXp," XP for ",e.jsx("strong",{children:b.data.reward.reasonTitle}),"."]}):null]})]}),e.jsxs("div",{className:"rounded-[22px] bg-white/[0.04] p-4",children:[e.jsx("div",{className:"font-medium text-white",children:"Manual bonus history"}),e.jsx("div",{className:"mt-4 grid gap-3",children:J.length===0?e.jsx("div",{className:"rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4 text-sm text-white/58",children:"No manual bonus grants yet."}):J.map(s=>e.jsxs("div",{className:"rounded-[18px] bg-[rgba(8,13,28,0.68)] p-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-medium text-white",children:s.reasonTitle}),e.jsxs(u,{className:s.deltaXp>=0?"text-emerald-300":"text-amber-300",children:[s.deltaXp>0?"+":"",s.deltaXp," XP"]})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:s.reasonSummary||"No summary supplied."}),e.jsxs("div",{className:"mt-2 text-xs uppercase tracking-[0.16em] text-white/38",children:[s.entityType," · ",s.entityId," · ",new Date(s.createdAt).toLocaleString()]})]},s.id))})]})]})]})})]})}export{ke as SettingsRewardsPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{aJ as b,r as d,cm as v,cr as f,bO as g,aV as h,cZ as y,c_ as j,b2 as k,ba as N,c$ as w,aF as S,d0 as C,j as e,bz as x,o as z,aK as E}from"./vendor-DHkYh85p.js";import{C as T,Z as i}from"./index-
|
|
1
|
+
import{aJ as b,r as d,cm as v,cr as f,bO as g,aV as h,cZ as y,c_ as j,b2 as k,ba as N,c$ as w,aF as S,d0 as C,j as e,bz as x,o as z,aK as E}from"./vendor-DHkYh85p.js";import{C as T,Z as i}from"./index-CF4J4R9L.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 O({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-white",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{O as S};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as p,j as e,aC as ee}from"./vendor-DHkYh85p.js";import{i as te,k as $}from"./state-B-4sS1xO.js";import{S as se}from"./settings-section-nav-CCFm27r2.js";import{P as ie}from"./page-hero-CQWo1Mm_.js";import{i as ae,C as ne,B as re,M as le}from"./graph-D6JLqDbD.js";import{C as S,aq as ce,c as f,U as C,Q as K,F as M,j as T,I as R,T as oe,W as de,u as he,eu as xe,ev as ue,ew as pe,B as X,ex as ge}from"./index-BHTUu_4M.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";const Q=[{id:"visibility",label:"Discovery and visibility",description:"What the source user can discover, inspect, and pull into read flows on the target side.",rights:[{key:"discoverable",label:"Discoverable",description:"The target appears as a reachable collaborator in the source user's graph and pickers."},{key:"canListUsers",label:"List users",description:"The source user can include the target in directory, comparison, and routing surfaces."},{key:"canReadProfile",label:"Read profile",description:"The source user can inspect the target's identity card, handle, type, and description."},{key:"canReadEntities",label:"Read entities",description:"The source user can read the target's goals, projects, tasks, notes, strategies, and related records."},{key:"canSearchEntities",label:"Search entities",description:"The source user can find the target's work through Forge search and entity pickers."}]},{id:"coordination",label:"Messaging, context, and handoff",description:"What the source user can message, connect, and coordinate on the target side before changing execution.",rights:[{key:"canLinkEntities",label:"Share context",description:"The source user can attach the target's records into shared notes, strategies, calendar context, and cross-owner plans."},{key:"canCoordinate",label:"Message and coordinate",description:"The source user can communicate with the target through Forge, hand off work, and coordinate execution."},{key:"canViewMetrics",label:"View metrics",description:"The source user can inspect the target's XP, alignment, and progress metrics."},{key:"canViewActivity",label:"View activity",description:"The source user can inspect the target's activity stream, evidence, and execution trail."}]},{id:"execution",label:"Plan and execution control",description:"What the source user can actually change on the target side once collaboration is trusted.",rights:[{key:"canManageStrategies",label:"Manage strategies",description:"The source user can draft and update strategies that belong to the target."},{key:"canCreateOnBehalf",label:"Create on behalf",description:"The source user can intentionally create new target-owned entities."},{key:"canAffectEntities",label:"Affect entities",description:"The source user can mutate work that belongs to the target."}]}],me=[{id:"full_collab",label:"Full collaboration",description:"Use when two humans or agents can see, coordinate, plan, and change each other's work.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!0,canCoordinate:!0,canAffectEntities:!0,canManageStrategies:!0,canCreateOnBehalf:!0,canViewMetrics:!0,canViewActivity:!0}},{id:"coordination_only",label:"Coordinate only",description:"Use when the source user may see and coordinate with the target but should not directly mutate target-owned work.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!0,canCoordinate:!0,canAffectEntities:!1,canManageStrategies:!0,canCreateOnBehalf:!1,canViewMetrics:!0,canViewActivity:!0}},{id:"observe_only",label:"Observe only",description:"Use when the source user should keep visibility into the target without planning or execution control.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!1,canCoordinate:!1,canAffectEntities:!1,canManageStrategies:!1,canCreateOnBehalf:!1,canViewMetrics:!0,canViewActivity:!0}},{id:"hidden",label:"Hidden edge",description:"Use when this direction should stop discovering, reading, or acting on the target.",rights:{discoverable:!1,canListUsers:!1,canReadProfile:!1,canReadEntities:!1,canSearchEntities:!1,canLinkEntities:!1,canCoordinate:!1,canAffectEntities:!1,canManageStrategies:!1,canCreateOnBehalf:!1,canViewMetrics:!1,canViewActivity:!1}}],I=Q.reduce((t,r)=>t+r.rights.length,0);function F(t){return Object.values(t.config.rights).filter(Boolean).length}function q(t){const r=[];return t.config.rights.canReadEntities&&r.push("See"),t.config.rights.canCoordinate&&r.push("Message"),t.config.rights.canManageStrategies&&r.push("Plan"),t.config.rights.canAffectEntities&&r.push("Affect"),r.join(" · ")||"Hidden"}function be(t){return!t.config.rights.discoverable&&!t.config.rights.canReadEntities?"Hidden":t.config.rights.canAffectEntities&&t.config.rights.canManageStrategies?"Trusted":t.config.rights.canCoordinate||t.config.rights.canLinkEntities?"Coordinated":"Observed"}function Z(t){return[{id:"see",label:"See",enabled:t.config.rights.discoverable&&t.config.rights.canReadEntities&&t.config.rights.canSearchEntities},{id:"message",label:"Message",enabled:t.config.rights.canCoordinate},{id:"share",label:"Share context",enabled:t.config.rights.canLinkEntities},{id:"plan",label:"Plan",enabled:t.config.rights.canManageStrategies},{id:"affect",label:"Affect",enabled:t.config.rights.canAffectEntities||t.config.rights.canCreateOnBehalf}]}function fe(t,r){return Object.entries(r.rights).every(([i,x])=>t.config.rights[i]===x)}function we(t,r){const i=t.filter(a=>a.kind==="human"),x=t.filter(a=>a.kind==="bot"),u={x:560,y:360},g={width:226,height:132},d=i[0]??null,v=[...i.slice(d?1:0).map(a=>({user:a,radius:245,offset:-90})),...x.map(a=>({user:a,radius:390,offset:-90}))],b=v.length,N=[...d?[{user:d,position:{x:u.x-g.width/2,y:u.y-g.height/2}}]:[],...v.map((a,o)=>{const h=(a.offset+360/Math.max(b,1)*o)*Math.PI/180;return{user:a.user,position:{x:u.x+Math.cos(h)*a.radius-g.width/2,y:u.y+Math.sin(h)*a.radius-g.height/2}}})],U=new Set(r.selectedGrant?[r.selectedGrant.subjectUserId,r.selectedGrant.targetUserId]:r.selectedUserId?[r.selectedUserId]:[]);return N.map(({user:a,position:o})=>{const h=U.has(a.id),s=a.id===r.selectedUserId;return{id:a.id,position:o,draggable:!1,selectable:!1,data:{label:e.jsxs("div",{className:`min-w-[206px] rounded-[22px] border px-4 py-4 shadow-[0_24px_60px_rgba(0,0,0,0.28)] transition ${s?"border-[rgba(244,185,122,0.45)] bg-[rgba(27,16,10,0.92)]":h?"border-white/18 bg-[rgba(14,20,34,0.94)]":"border-white/10 bg-[rgba(9,15,28,0.92)]"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx(C,{user:a}),e.jsx(f,{className:"bg-white/[0.08] text-white/65",children:a.kind})]}),e.jsxs("div",{className:"mt-3 text-xs text-white/52",children:["@",a.handle]}),e.jsx("div",{className:"mt-2 line-clamp-2 text-xs leading-5 text-white/46",children:a.description||"No user description yet."})]})},style:{background:"transparent",border:"none",padding:0}}})}function je(t,r,i){return t.filter(x=>x.subjectUserId!==x.targetUserId).map(x=>{const u=r===x.id,g=i!==null&&(x.subjectUserId===i||x.targetUserId===i),d=F(x),w=u?"#f4b97a":!x.config.rights.discoverable&&!x.config.rights.canReadEntities?"rgba(248,113,113,0.55)":g?"rgba(192,193,255,0.78)":"rgba(255,255,255,0.32)";return{id:x.id,source:x.subjectUserId,target:x.targetUserId,label:`${q(x)} · ${d}/${I}`,markerEnd:{type:le.ArrowClosed,color:w},labelStyle:{fill:u?"#f4b97a":"rgba(255,255,255,0.68)",fontSize:11,fontWeight:600},labelBgStyle:{fill:u?"rgba(34,23,16,0.96)":"rgba(8,13,24,0.94)",stroke:u?"rgba(244,185,122,0.36)":"rgba(255,255,255,0.14)",strokeWidth:1},labelBgPadding:[7,5],labelBgBorderRadius:8,style:{stroke:w,strokeWidth:u?2.5:g?1.8:1.25},animated:u}})}function ve({users:t,grants:r,selectedGrantId:i=null,selectedUserId:x=null,onOpenGrant:u,onOpenUser:g}){const d=r.find(o=>o.id===i)??null,w=p.useMemo(()=>we(t,{selectedUserId:x,selectedGrant:d}),[d,x,t]),v=p.useMemo(()=>je(r,i,x),[r,i,x]),b=p.useMemo(()=>r.filter(o=>o.subjectUserId!==o.targetUserId),[r]),N=b.filter(o=>F(o)===I).length,U=b.filter(o=>o.config.rights.canCoordinate).length,a=b.filter(o=>o.config.rights.canAffectEntities||o.config.rights.canCreateOnBehalf).length;return e.jsxs(S,{className:"overflow-hidden p-0",children:[e.jsxs("div",{className:"grid gap-4 border-b border-white/8 px-5 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Directed relationship graph"}),e.jsx(ce,{content:"Keep Forge, OpenClaw, Hermes, and the browser on the same runtime and storage root when these arrows should describe one shared human and bot system.",label:"Explain the shared runtime rule"})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"Click a user card to open that user's settings. Click any arrow to open the exact directional relationship flow for that lane."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[b.length," edges"]}),e.jsxs(f,{className:"bg-emerald-500/12 text-emerald-200",children:[N," fully open"]})]})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Full collaboration"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:N}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions still running with the default fully open posture."})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Coordination lanes"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:U}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions allowed to coordinate directly through Forge."})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Execution control"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:a}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions allowed to create or mutate target-owned work."})]})]})]}),e.jsx("div",{className:"h-[min(72vh,54rem)] min-h-[34rem] bg-[radial-gradient(circle_at_top,rgba(244,185,122,0.08),transparent_34%),linear-gradient(180deg,rgba(6,10,20,0.97),rgba(8,14,26,0.94))]",children:e.jsxs(ae,{className:"user-relationship-flow",nodes:w,edges:v,fitView:!0,fitViewOptions:{padding:.18,maxZoom:.95},nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,onNodeClick:(o,h)=>{g(h.id)},onEdgeClick:(o,h)=>{u(h.id)},attributionPosition:"bottom-left",children:[e.jsx(ne,{showInteractive:!1}),e.jsx(re,{gap:28,size:1,color:"rgba(255,255,255,0.06)"})]})})]})}const Ne={kind:"human",handle:"",displayName:"",description:"",accentColor:"#c0c1ff"};function W(t){return t?{kind:t.kind,handle:t.handle,displayName:t.displayName,description:t.description,accentColor:t.accentColor}:Ne}function ye({open:t,onOpenChange:r,user:i,grants:x,ownership:u,xp:g,pending:d=!1,onSubmit:w,onOpenRelationship:v}){const[b,N]=p.useState(()=>W(i)),[U,a]=p.useState(null);p.useEffect(()=>{t&&(N(W(i)),a(null))},[t,i]);const o=p.useMemo(()=>x.filter(c=>c.subjectUserId!==c.targetUserId),[x]),h=p.useMemo(()=>i?o.filter(c=>c.subjectUserId===i.id):[],[o,i]),s=p.useMemo(()=>i?o.filter(c=>c.targetUserId===i.id):[],[o,i]),y=[{id:"identity",eyebrow:i?"Edit user":"Create user",title:i?"Update the user identity":"Add a human or bot user",description:"Set the owner type and the public identity Forge will use across ownership, routing, and collaboration surfaces.",render:(c,m)=>e.jsxs(e.Fragment,{children:[e.jsx(M,{label:"Kind",description:"Humans represent real people. Bots represent agents or automations with their own ownership lane.",children:e.jsx(T,{columns:2,value:c.kind,onChange:k=>m({kind:k}),options:[{value:"human",label:"Human",description:"Use for a real person in the Forge runtime."},{value:"bot",label:"Bot",description:"Use for an agent, assistant, or automation actor."}]})}),e.jsx(M,{label:"Handle",description:"This becomes the stable short id shown as @handle.",hint:"Use lowercase and a durable label, for example forge-operator or planner-bot.",children:e.jsx(R,{value:c.handle,onChange:k=>m({handle:k.target.value}),placeholder:"forge-operator"})}),e.jsx(M,{label:"Display name",description:"This is the human-readable label used across the UI.",children:e.jsx(R,{value:c.displayName,onChange:k=>m({displayName:k.target.value}),placeholder:"Forge Operator"})})]})},{id:"profile",eyebrow:"Profile",title:"Describe the user lane",description:"Capture what this user represents in the shared Forge runtime and pick the accent color that helps the lane stay recognizable.",render:(c,m)=>e.jsxs(e.Fragment,{children:[e.jsx(M,{label:"Description",description:"Explain what this user is responsible for and what side of the system it represents.",children:e.jsx(oe,{value:c.description,onChange:k=>m({description:k.target.value}),className:"min-h-36",placeholder:"Primary human operator for strategy, execution, and review."})}),e.jsx(M,{label:"Accent color",description:"Forge uses this accent to help the user stand out in ownership and collaboration surfaces.",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(R,{value:c.accentColor,onChange:k=>m({accentColor:k.target.value}),placeholder:"#c0c1ff"}),e.jsx("div",{className:"size-10 shrink-0 rounded-full border border-white/10",style:{backgroundColor:c.accentColor||"#c0c1ff"}})]})}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Owned records"}),e.jsx("div",{className:"mt-2 text-white",children:(u==null?void 0:u.totalOwnedEntities)??0})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Total XP"}),e.jsx("div",{className:"mt-2 text-white",children:(g==null?void 0:g.totalXp)??0})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Weekly XP"}),e.jsx("div",{className:"mt-2 text-white",children:(g==null?void 0:g.weeklyXp)??0})]})]})]})},{id:"relationships",eyebrow:"Relationships",title:"Open directional relationship settings",description:"Each arrow is a separate contract. Open the exact lane you want to adjust and Forge will take you into the relationship flow.",render:()=>i?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx(C,{user:i}),e.jsxs("div",{className:"mt-3 text-sm leading-6 text-white/56",children:["@",i.handle," · ",i.description||"No description yet."]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Outbound lanes"}),h.length>0?h.map(c=>e.jsxs("button",{type:"button",className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-left transition hover:bg-white/[0.05]",onClick:()=>v(c.id),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:c.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:c.targetUser})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(f,{className:"bg-white/[0.08] text-white/74",children:q(c)}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:[F(c),"/",I," rights"]})]})]},c.id)):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm text-white/52",children:"No outbound relationship lanes yet."})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Inbound lanes"}),s.length>0?s.map(c=>e.jsxs("button",{type:"button",className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-left transition hover:bg-white/[0.05]",onClick:()=>v(c.id),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:c.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:c.targetUser})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:Z(c).map(m=>e.jsx(f,{className:m.enabled?"bg-white/[0.08] text-white/74":"bg-white/[0.04] text-white/38",children:m.label},`${c.id}-${m.id}`))})]},c.id)):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm text-white/52",children:"No inbound relationship lanes yet."})]})]})]}):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm leading-6 text-white/52",children:"Create the user first, then Forge will generate the directional relationship lanes you can tune from here."})}];return e.jsx(K,{open:t,onOpenChange:r,eyebrow:i?"User settings":"Create user",title:i?"User settings":"Create user",description:"Edit the user identity, clarify what this lane represents, and jump into relationship settings without crowding the page.",value:b,onChange:N,draftPersistenceKey:i?`users.settings.${i.id}`:"users.settings.new",steps:y,submitLabel:i?"Save user":"Create user",pending:d,pendingLabel:i?"Saving user":"Creating user",error:U,contentClassName:"lg:w-[min(58rem,calc(100vw-1.5rem))]",onSubmit:async()=>{const c=b.handle.trim(),m=b.displayName.trim();if(c.length===0){a("Add a handle before saving this user.");return}if(m.length===0){a("Add a display name before saving this user.");return}await w({userId:i==null?void 0:i.id,input:{kind:b.kind,handle:c,displayName:m,description:b.description.trim(),accentColor:b.accentColor.trim()||"#c0c1ff"}}),r(!1)}})}function z(t,r){return{accessLevel:(t==null?void 0:t.accessLevel)??"manage",applyScope:"this_arrow",rights:{discoverable:(t==null?void 0:t.config.rights.discoverable)??!0,canListUsers:(t==null?void 0:t.config.rights.canListUsers)??!0,canReadProfile:(t==null?void 0:t.config.rights.canReadProfile)??!0,canReadEntities:(t==null?void 0:t.config.rights.canReadEntities)??!0,canSearchEntities:(t==null?void 0:t.config.rights.canSearchEntities)??!0,canLinkEntities:(t==null?void 0:t.config.rights.canLinkEntities)??!0,canCoordinate:(t==null?void 0:t.config.rights.canCoordinate)??!0,canAffectEntities:(t==null?void 0:t.config.rights.canAffectEntities)??!0,canManageStrategies:(t==null?void 0:t.config.rights.canManageStrategies)??!0,canCreateOnBehalf:(t==null?void 0:t.config.rights.canCreateOnBehalf)??!0,canViewMetrics:(t==null?void 0:t.config.rights.canViewMetrics)??!0,canViewActivity:(t==null?void 0:t.config.rights.canViewActivity)??!0}}}function ke({open:t,onOpenChange:r,grant:i,grants:x,pending:u=!1,onSubmit:g}){const d=p.useMemo(()=>i?x.find(a=>a.subjectUserId===i.targetUserId&&a.targetUserId===i.subjectUserId)??null:null,[i,x]),[w,v]=p.useState(()=>z(i,!!d));p.useEffect(()=>{t&&v(z(i,!!d))},[i,t,d]);const b=p.useMemo(()=>Object.values(w.rights).filter(Boolean).length,[w.rights]),N=Math.round(b/I*100),U=[{id:"posture",eyebrow:"Relationship posture",title:"Set the trust mode for this arrow",description:"Each arrow is directional. Decide whether you want to tune only this lane or mirror the same contract onto both directions.",render:(a,o)=>e.jsxs(e.Fragment,{children:[i?e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:i.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:i.targetUser})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(f,{className:"bg-white/[0.08] text-white/74",children:be(i)}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:[F(i),"/",I," rights"]})]})]}):null,e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Access level"}),e.jsx(T,{columns:2,value:a.accessLevel,onChange:h=>o({accessLevel:h}),options:[{value:"view",label:"View",description:"Use when this lane should stay mostly observational."},{value:"manage",label:"Manage",description:"Use when the source side can actively collaborate or act."}]})]}),d?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Apply scope"}),e.jsx(T,{columns:2,value:a.applyScope,onChange:h=>o({applyScope:h}),options:[{value:"this_arrow",label:"This arrow",description:"Only change the exact direction you opened."},{value:"both_arrows",label:"Both arrows",description:"Mirror the same contract onto the reverse direction too."}]})]}):null]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Quick preset"}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:me.map(h=>e.jsxs("button",{type:"button",className:`rounded-[22px] border p-4 text-left transition ${i&&fe(i,h)?"border-[rgba(244,185,122,0.35)] bg-[rgba(244,185,122,0.08)]":"border-white/8 bg-white/[0.03] hover:bg-white/[0.05]"}`,onClick:()=>o({rights:{...a.rights,...h.rights}}),children:[e.jsx("div",{className:"text-sm font-medium text-white",children:h.label}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/56",children:h.description})]},h.id))})]})]})},{id:"rights",eyebrow:"Rights",title:"Tune the individual permissions",description:"Use the preset as the starting point, then sharpen the exact boundaries only where this relationship needs them.",render:(a,o)=>e.jsx(e.Fragment,{children:Q.map(h=>e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:h.label}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/54",children:h.description})]}),e.jsx("div",{className:"grid gap-2",children:h.rights.map(s=>e.jsxs("label",{className:"flex items-start justify-between gap-3 rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:s.label}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-white/50",children:s.description})]}),e.jsx("input",{type:"checkbox",checked:a.rights[s.key],onChange:y=>o({rights:{...a.rights,[s.key]:y.target.checked}})})]},s.key))})]},h.id))})},{id:"review",eyebrow:"Review",title:"Review the final relationship contract",description:"Check the enabled capabilities, confirm whether both directions should match, and then save the relationship.",render:a=>{var o,h;return e.jsx(e.Fragment,{children:e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Capability coverage"}),e.jsx("div",{className:"mt-4",children:e.jsx(de,{value:N})}),e.jsxs("div",{className:"mt-3 text-sm text-white/62",children:[b,"/",I," rights enabled"]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:Z({...i??{id:"draft",subjectUserId:"",targetUserId:"",accessLevel:a.accessLevel,config:{self:!1,mutable:!0,linkedEntities:!0,rights:a.rights},createdAt:"",updatedAt:"",subjectUser:null,targetUser:null},accessLevel:a.accessLevel,config:{...(i==null?void 0:i.config)??{self:!1,mutable:!0,linkedEntities:!0},rights:a.rights}}).map(s=>e.jsx(f,{className:s.enabled?"bg-white/[0.08] text-white/74":"bg-white/[0.04] text-white/38",children:s.label},s.id))})]}),e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Save scope"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/58",children:a.applyScope==="both_arrows"&&d?"Forge will apply the same access level and rights to both directions of this pair.":"Forge will only update the exact arrow you opened."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:["access ",a.accessLevel]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:["scope"," ",a.applyScope==="both_arrows"&&d?"both arrows":"this arrow"]})]}),d?e.jsxs("div",{className:"mt-4 rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3 text-sm text-white/54",children:["Reverse arrow available:"," ",((o=d.subjectUser)==null?void 0:o.displayName)??d.subjectUserId," ","→"," ",((h=d.targetUser)==null?void 0:h.displayName)??d.targetUserId]}):null]})]})})}}];return e.jsx(K,{open:t,onOpenChange:r,eyebrow:"Relationship settings",title:"Relationship settings",description:"Edit the exact directional contract between two users without keeping the full rights editor pinned on the page.",value:w,onChange:v,draftPersistenceKey:i?`users.relationship.${i.id}`:"users.relationship.new",steps:U,submitLabel:"Save relationship",pending:u,pendingLabel:"Saving relationship",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]",onSubmit:async()=>{i&&(await g({grantId:i.id,patch:{accessLevel:w.accessLevel,rights:w.rights},reverseGrantId:(d==null?void 0:d.id)??null,applyToReverse:w.applyScope==="both_arrows"&&d!==null}),r(!1))}})}function Le(){var P;const t=he(),[r,i]=p.useState(null),[x,u]=p.useState(null),[g,d]=p.useState(!1),[w,v]=p.useState(!1),[b,N]=p.useState(""),U=te({queryKey:["forge-user-directory"],queryFn:ge}),a=async()=>{await Promise.all([t.refresh(),U.refetch()])},o=$({mutationFn:async({input:n,userId:l})=>l?(await xe(l,n)).user:(await ue(n)).user,onSuccess:async()=>{i(null),d(!1),await a()}}),h=$({mutationFn:async({grantId:n,patch:l})=>(await pe(n,l)).grant,onSuccess:a}),s=(P=U.data)==null?void 0:P.directory,y=(s==null?void 0:s.grants.find(n=>n.id===x))??null,c=p.useMemo(()=>new Map(((s==null?void 0:s.ownership)??[]).map(n=>[n.userId,n])),[s==null?void 0:s.ownership]),m=p.useMemo(()=>new Map(((s==null?void 0:s.xp)??[]).map(n=>[n.userId,n])),[s==null?void 0:s.xp]),k=p.useMemo(()=>{const n=new Map;for(const l of(s==null?void 0:s.grants)??[]){if(!l.targetUser||l.subjectUserId===l.targetUserId)continue;const j=n.get(l.subjectUserId)??[];j.push(l.targetUser),n.set(l.subjectUserId,j)}return n},[s==null?void 0:s.grants]),O=p.useMemo(()=>{const n=((s==null?void 0:s.grants)??[]).filter(l=>l.subjectUserId!==l.targetUserId);return{totalEdges:n.length,fullyOpenEdges:n.filter(l=>Object.values(l.config.rights).every(Boolean)).length,coordinationEdges:n.filter(l=>l.config.rights.canCoordinate).length,executionEdges:n.filter(l=>l.config.rights.canAffectEntities||l.config.rights.canCreateOnBehalf).length}},[s==null?void 0:s.grants]),A=b.trim().toLowerCase(),B=p.useMemo(()=>{const l=((s==null?void 0:s.users)??t.snapshot.users).filter(j=>A?[j.displayName,j.handle,j.kind,j.description].join(" ").toLowerCase().includes(A):!0);return{humans:l.filter(j=>j.kind==="human"),bots:l.filter(j=>j.kind==="bot")}},[s==null?void 0:s.users,A,t.snapshot.users]),J=(y==null?void 0:y.subjectUserId)??(r==null?void 0:r.id)??null,Y=(y==null?void 0:y.id)??null;return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1440px] gap-5",children:[e.jsx(ie,{title:"Users",description:"Forge users can be human or bot. Ownership, search, and routing are prepared so work can move across both sides of the system.",badge:`${t.snapshot.users.length} users`}),e.jsx(se,{}),e.jsx(ye,{open:g,onOpenChange:d,user:r,grants:(s==null?void 0:s.grants)??[],ownership:r?c.get(r.id)??null:null,xp:r?m.get(r.id)??null:null,pending:o.isPending,onSubmit:async n=>{await o.mutateAsync(n)},onOpenRelationship:n=>{d(!1),u(n),v(!0)}}),e.jsx(ke,{open:w,onOpenChange:v,grant:y,grants:(s==null?void 0:s.grants)??[],pending:h.isPending,onSubmit:async n=>{await h.mutateAsync({grantId:n.grantId,patch:n.patch}),n.applyToReverse&&n.reverseGrantId&&await h.mutateAsync({grantId:n.reverseGrantId,patch:n.patch})}}),e.jsxs(S,{className:"grid gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Multi-user posture"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:(s==null?void 0:s.posture.summary)??"Forge is preparing modular user access while keeping the current posture permissive."})]}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:(s==null?void 0:s.posture.accessModel)??"permissive"})]}),e.jsx("div",{className:"flex items-center gap-3 rounded-[18px] bg-white/[0.04] px-4 py-3",children:e.jsx(R,{value:b,onChange:n=>N(n.target.value),placeholder:"Search human, bot, @handle, or description"})})]}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(S,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Multi-agent onboarding"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:"Forge now treats the users graph as the collaboration control plane. Create each human or bot here, keep the runtime shared, then narrow only the specific arrows that should stop seeing, coordinating, planning, or affecting another user."})]}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:"default open"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Directional edges"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.totalEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Fully open"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.fullyOpenEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Coordination"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.coordinationEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Execution control"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.executionEdges})]})]}),e.jsxs("div",{className:"grid gap-2 text-sm leading-6 text-white/56",children:[e.jsx("div",{children:"1. Create the human and bot users that should exist in the shared Forge system."}),e.jsx("div",{children:"2. Point OpenClaw, Hermes, and the browser at the same Forge runtime and storage root."}),e.jsx("div",{children:"3. Use the graph below to decide what each direction can see, message, plan, or change."}),e.jsx("div",{children:"4. Keep strategy drafting open while the plan is negotiated, then lock the strategy once it becomes the contract."})]})]}),e.jsx(ve,{users:(s==null?void 0:s.users)??t.snapshot.users,grants:(s==null?void 0:s.grants)??[],selectedGrantId:Y,selectedUserId:J,onOpenUser:n=>{const l=((s==null?void 0:s.users)??t.snapshot.users).find(j=>j.id===n)??null;u(null),i(l),d(!0)},onOpenGrant:n=>{i(null),u(n),v(!0)}}),e.jsxs(S,{className:"grid gap-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Agent onboarding"}),e.jsx("div",{className:"text-sm leading-6 text-white/60",children:"OpenClaw, Hermes, and the Forge UI all read this same multi-user graph. Keep the defaults open while you are still wiring collaboration, then narrow specific arrows when one user or agent should stop seeing, messaging, planning, or changing another user's work."}),e.jsx("div",{className:"text-sm leading-6 text-white/52",children:"Forge now treats every owner as either human or bot, keeps search cross-user by default, and allows cross-owner links plus explicit coordination lanes between projects, tasks, notes, and strategies."}),e.jsx("div",{children:e.jsx(ee,{to:"/settings/agents",className:"inline-flex min-h-10 items-center justify-center rounded-[var(--radius-control)] bg-white/8 px-3 py-2 text-[13px] font-medium text-white transition hover:bg-white/12",children:"Open agent onboarding"})})]})]}),e.jsx(S,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"User directory"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:"Open any user to edit its identity and jump into the exact directional relationship lanes from the user settings flow."})]}),e.jsx(X,{onClick:()=>{u(null),i(null),d(!0)},children:"Create user"})]})}),e.jsx("div",{className:"grid gap-5",children:[{title:"Human users",users:B.humans},{title:"Bot users",users:B.bots}].map(n=>e.jsxs(S,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:n.title}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:n.users.length})]}),e.jsx("div",{className:"mt-4 grid gap-3",children:n.users.map(l=>{var j,D,G,_,H,V;return e.jsx("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx(C,{user:l}),e.jsxs("div",{className:"mt-3 text-sm text-white/58",children:["@",l.handle]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:l.description||"No description yet."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:[((j=m.get(l.id))==null?void 0:j.totalXp)??0," XP"]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((D=m.get(l.id))==null?void 0:D.weeklyXp)??0," weekly"]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((G=m.get(l.id))==null?void 0:G.rewardEventCount)??0," ","rewards"]}),Object.entries(((_=c.get(l.id))==null?void 0:_.entityCounts)??{}).sort((E,L)=>L[1]-E[1]).slice(0,4).map(([E,L])=>e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[L," ",E]},`${l.id}-${E}`)),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((H=c.get(l.id))==null?void 0:H.totalOwnedEntities)??0," ","owned"]})]}),e.jsxs("div",{className:"mt-3 text-xs leading-5 text-white/50",children:["Can currently read:"," ",(k.get(l.id)??[]).map(E=>`${E.displayName} (${E.kind})`).join(", ")||"no other users"]}),(V=m.get(l.id))!=null&&V.lastRewardAt?e.jsxs("div",{className:"mt-2 text-xs leading-5 text-white/45",children:["Last XP movement:"," ",new Date(m.get(l.id).lastRewardAt).toLocaleString()]}):null]}),e.jsx("div",{className:"flex gap-2",children:e.jsx(X,{variant:"secondary",onClick:()=>{u(null),i(l),d(!0)},children:"Open settings"})})]})},l.id)})})]},n.title))})]})]})}export{Le as SettingsUsersPage};
|
|
1
|
+
import{r as p,j as e,aC as ee}from"./vendor-DHkYh85p.js";import{i as te,k as $}from"./state-B-4sS1xO.js";import{S as se}from"./settings-section-nav-DSOuht_F.js";import{P as ie}from"./page-hero-DRy5b2MU.js";import{i as ae,C as ne,B as re,M as le}from"./graph-D6JLqDbD.js";import{C as S,aq as ce,c as f,U as C,Q as K,F as M,j as T,I as R,T as oe,W as de,u as he,eu as xe,ev as ue,ew as pe,B as X,ex as ge}from"./index-CF4J4R9L.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";const Q=[{id:"visibility",label:"Discovery and visibility",description:"What the source user can discover, inspect, and pull into read flows on the target side.",rights:[{key:"discoverable",label:"Discoverable",description:"The target appears as a reachable collaborator in the source user's graph and pickers."},{key:"canListUsers",label:"List users",description:"The source user can include the target in directory, comparison, and routing surfaces."},{key:"canReadProfile",label:"Read profile",description:"The source user can inspect the target's identity card, handle, type, and description."},{key:"canReadEntities",label:"Read entities",description:"The source user can read the target's goals, projects, tasks, notes, strategies, and related records."},{key:"canSearchEntities",label:"Search entities",description:"The source user can find the target's work through Forge search and entity pickers."}]},{id:"coordination",label:"Messaging, context, and handoff",description:"What the source user can message, connect, and coordinate on the target side before changing execution.",rights:[{key:"canLinkEntities",label:"Share context",description:"The source user can attach the target's records into shared notes, strategies, calendar context, and cross-owner plans."},{key:"canCoordinate",label:"Message and coordinate",description:"The source user can communicate with the target through Forge, hand off work, and coordinate execution."},{key:"canViewMetrics",label:"View metrics",description:"The source user can inspect the target's XP, alignment, and progress metrics."},{key:"canViewActivity",label:"View activity",description:"The source user can inspect the target's activity stream, evidence, and execution trail."}]},{id:"execution",label:"Plan and execution control",description:"What the source user can actually change on the target side once collaboration is trusted.",rights:[{key:"canManageStrategies",label:"Manage strategies",description:"The source user can draft and update strategies that belong to the target."},{key:"canCreateOnBehalf",label:"Create on behalf",description:"The source user can intentionally create new target-owned entities."},{key:"canAffectEntities",label:"Affect entities",description:"The source user can mutate work that belongs to the target."}]}],me=[{id:"full_collab",label:"Full collaboration",description:"Use when two humans or agents can see, coordinate, plan, and change each other's work.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!0,canCoordinate:!0,canAffectEntities:!0,canManageStrategies:!0,canCreateOnBehalf:!0,canViewMetrics:!0,canViewActivity:!0}},{id:"coordination_only",label:"Coordinate only",description:"Use when the source user may see and coordinate with the target but should not directly mutate target-owned work.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!0,canCoordinate:!0,canAffectEntities:!1,canManageStrategies:!0,canCreateOnBehalf:!1,canViewMetrics:!0,canViewActivity:!0}},{id:"observe_only",label:"Observe only",description:"Use when the source user should keep visibility into the target without planning or execution control.",rights:{discoverable:!0,canListUsers:!0,canReadProfile:!0,canReadEntities:!0,canSearchEntities:!0,canLinkEntities:!1,canCoordinate:!1,canAffectEntities:!1,canManageStrategies:!1,canCreateOnBehalf:!1,canViewMetrics:!0,canViewActivity:!0}},{id:"hidden",label:"Hidden edge",description:"Use when this direction should stop discovering, reading, or acting on the target.",rights:{discoverable:!1,canListUsers:!1,canReadProfile:!1,canReadEntities:!1,canSearchEntities:!1,canLinkEntities:!1,canCoordinate:!1,canAffectEntities:!1,canManageStrategies:!1,canCreateOnBehalf:!1,canViewMetrics:!1,canViewActivity:!1}}],I=Q.reduce((t,r)=>t+r.rights.length,0);function F(t){return Object.values(t.config.rights).filter(Boolean).length}function q(t){const r=[];return t.config.rights.canReadEntities&&r.push("See"),t.config.rights.canCoordinate&&r.push("Message"),t.config.rights.canManageStrategies&&r.push("Plan"),t.config.rights.canAffectEntities&&r.push("Affect"),r.join(" · ")||"Hidden"}function be(t){return!t.config.rights.discoverable&&!t.config.rights.canReadEntities?"Hidden":t.config.rights.canAffectEntities&&t.config.rights.canManageStrategies?"Trusted":t.config.rights.canCoordinate||t.config.rights.canLinkEntities?"Coordinated":"Observed"}function Z(t){return[{id:"see",label:"See",enabled:t.config.rights.discoverable&&t.config.rights.canReadEntities&&t.config.rights.canSearchEntities},{id:"message",label:"Message",enabled:t.config.rights.canCoordinate},{id:"share",label:"Share context",enabled:t.config.rights.canLinkEntities},{id:"plan",label:"Plan",enabled:t.config.rights.canManageStrategies},{id:"affect",label:"Affect",enabled:t.config.rights.canAffectEntities||t.config.rights.canCreateOnBehalf}]}function fe(t,r){return Object.entries(r.rights).every(([i,x])=>t.config.rights[i]===x)}function we(t,r){const i=t.filter(a=>a.kind==="human"),x=t.filter(a=>a.kind==="bot"),u={x:560,y:360},g={width:226,height:132},d=i[0]??null,v=[...i.slice(d?1:0).map(a=>({user:a,radius:245,offset:-90})),...x.map(a=>({user:a,radius:390,offset:-90}))],b=v.length,N=[...d?[{user:d,position:{x:u.x-g.width/2,y:u.y-g.height/2}}]:[],...v.map((a,o)=>{const h=(a.offset+360/Math.max(b,1)*o)*Math.PI/180;return{user:a.user,position:{x:u.x+Math.cos(h)*a.radius-g.width/2,y:u.y+Math.sin(h)*a.radius-g.height/2}}})],U=new Set(r.selectedGrant?[r.selectedGrant.subjectUserId,r.selectedGrant.targetUserId]:r.selectedUserId?[r.selectedUserId]:[]);return N.map(({user:a,position:o})=>{const h=U.has(a.id),s=a.id===r.selectedUserId;return{id:a.id,position:o,draggable:!1,selectable:!1,data:{label:e.jsxs("div",{className:`min-w-[206px] rounded-[22px] border px-4 py-4 shadow-[0_24px_60px_rgba(0,0,0,0.28)] transition ${s?"border-[rgba(244,185,122,0.45)] bg-[rgba(27,16,10,0.92)]":h?"border-white/18 bg-[rgba(14,20,34,0.94)]":"border-white/10 bg-[rgba(9,15,28,0.92)]"}`,children:[e.jsxs("div",{className:"flex items-center justify-between gap-2",children:[e.jsx(C,{user:a}),e.jsx(f,{className:"bg-white/[0.08] text-white/65",children:a.kind})]}),e.jsxs("div",{className:"mt-3 text-xs text-white/52",children:["@",a.handle]}),e.jsx("div",{className:"mt-2 line-clamp-2 text-xs leading-5 text-white/46",children:a.description||"No user description yet."})]})},style:{background:"transparent",border:"none",padding:0}}})}function je(t,r,i){return t.filter(x=>x.subjectUserId!==x.targetUserId).map(x=>{const u=r===x.id,g=i!==null&&(x.subjectUserId===i||x.targetUserId===i),d=F(x),w=u?"#f4b97a":!x.config.rights.discoverable&&!x.config.rights.canReadEntities?"rgba(248,113,113,0.55)":g?"rgba(192,193,255,0.78)":"rgba(255,255,255,0.32)";return{id:x.id,source:x.subjectUserId,target:x.targetUserId,label:`${q(x)} · ${d}/${I}`,markerEnd:{type:le.ArrowClosed,color:w},labelStyle:{fill:u?"#f4b97a":"rgba(255,255,255,0.68)",fontSize:11,fontWeight:600},labelBgStyle:{fill:u?"rgba(34,23,16,0.96)":"rgba(8,13,24,0.94)",stroke:u?"rgba(244,185,122,0.36)":"rgba(255,255,255,0.14)",strokeWidth:1},labelBgPadding:[7,5],labelBgBorderRadius:8,style:{stroke:w,strokeWidth:u?2.5:g?1.8:1.25},animated:u}})}function ve({users:t,grants:r,selectedGrantId:i=null,selectedUserId:x=null,onOpenGrant:u,onOpenUser:g}){const d=r.find(o=>o.id===i)??null,w=p.useMemo(()=>we(t,{selectedUserId:x,selectedGrant:d}),[d,x,t]),v=p.useMemo(()=>je(r,i,x),[r,i,x]),b=p.useMemo(()=>r.filter(o=>o.subjectUserId!==o.targetUserId),[r]),N=b.filter(o=>F(o)===I).length,U=b.filter(o=>o.config.rights.canCoordinate).length,a=b.filter(o=>o.config.rights.canAffectEntities||o.config.rights.canCreateOnBehalf).length;return e.jsxs(S,{className:"overflow-hidden p-0",children:[e.jsxs("div",{className:"grid gap-4 border-b border-white/8 px-5 py-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"max-w-3xl",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Directed relationship graph"}),e.jsx(ce,{content:"Keep Forge, OpenClaw, Hermes, and the browser on the same runtime and storage root when these arrows should describe one shared human and bot system.",label:"Explain the shared runtime rule"})]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/58",children:"Click a user card to open that user's settings. Click any arrow to open the exact directional relationship flow for that lane."})]}),e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[b.length," edges"]}),e.jsxs(f,{className:"bg-emerald-500/12 text-emerald-200",children:[N," fully open"]})]})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Full collaboration"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:N}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions still running with the default fully open posture."})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Coordination lanes"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:U}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions allowed to coordinate directly through Forge."})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Execution control"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:a}),e.jsx("div",{className:"text-xs leading-5 text-white/48",children:"Directions allowed to create or mutate target-owned work."})]})]})]}),e.jsx("div",{className:"h-[min(72vh,54rem)] min-h-[34rem] bg-[radial-gradient(circle_at_top,rgba(244,185,122,0.08),transparent_34%),linear-gradient(180deg,rgba(6,10,20,0.97),rgba(8,14,26,0.94))]",children:e.jsxs(ae,{className:"user-relationship-flow",nodes:w,edges:v,fitView:!0,fitViewOptions:{padding:.18,maxZoom:.95},nodesDraggable:!1,nodesConnectable:!1,elementsSelectable:!0,onNodeClick:(o,h)=>{g(h.id)},onEdgeClick:(o,h)=>{u(h.id)},attributionPosition:"bottom-left",children:[e.jsx(ne,{showInteractive:!1}),e.jsx(re,{gap:28,size:1,color:"rgba(255,255,255,0.06)"})]})})]})}const Ne={kind:"human",handle:"",displayName:"",description:"",accentColor:"#c0c1ff"};function W(t){return t?{kind:t.kind,handle:t.handle,displayName:t.displayName,description:t.description,accentColor:t.accentColor}:Ne}function ye({open:t,onOpenChange:r,user:i,grants:x,ownership:u,xp:g,pending:d=!1,onSubmit:w,onOpenRelationship:v}){const[b,N]=p.useState(()=>W(i)),[U,a]=p.useState(null);p.useEffect(()=>{t&&(N(W(i)),a(null))},[t,i]);const o=p.useMemo(()=>x.filter(c=>c.subjectUserId!==c.targetUserId),[x]),h=p.useMemo(()=>i?o.filter(c=>c.subjectUserId===i.id):[],[o,i]),s=p.useMemo(()=>i?o.filter(c=>c.targetUserId===i.id):[],[o,i]),y=[{id:"identity",eyebrow:i?"Edit user":"Create user",title:i?"Update the user identity":"Add a human or bot user",description:"Set the owner type and the public identity Forge will use across ownership, routing, and collaboration surfaces.",render:(c,m)=>e.jsxs(e.Fragment,{children:[e.jsx(M,{label:"Kind",description:"Humans represent real people. Bots represent agents or automations with their own ownership lane.",children:e.jsx(T,{columns:2,value:c.kind,onChange:k=>m({kind:k}),options:[{value:"human",label:"Human",description:"Use for a real person in the Forge runtime."},{value:"bot",label:"Bot",description:"Use for an agent, assistant, or automation actor."}]})}),e.jsx(M,{label:"Handle",description:"This becomes the stable short id shown as @handle.",hint:"Use lowercase and a durable label, for example forge-operator or planner-bot.",children:e.jsx(R,{value:c.handle,onChange:k=>m({handle:k.target.value}),placeholder:"forge-operator"})}),e.jsx(M,{label:"Display name",description:"This is the human-readable label used across the UI.",children:e.jsx(R,{value:c.displayName,onChange:k=>m({displayName:k.target.value}),placeholder:"Forge Operator"})})]})},{id:"profile",eyebrow:"Profile",title:"Describe the user lane",description:"Capture what this user represents in the shared Forge runtime and pick the accent color that helps the lane stay recognizable.",render:(c,m)=>e.jsxs(e.Fragment,{children:[e.jsx(M,{label:"Description",description:"Explain what this user is responsible for and what side of the system it represents.",children:e.jsx(oe,{value:c.description,onChange:k=>m({description:k.target.value}),className:"min-h-36",placeholder:"Primary human operator for strategy, execution, and review."})}),e.jsx(M,{label:"Accent color",description:"Forge uses this accent to help the user stand out in ownership and collaboration surfaces.",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(R,{value:c.accentColor,onChange:k=>m({accentColor:k.target.value}),placeholder:"#c0c1ff"}),e.jsx("div",{className:"size-10 shrink-0 rounded-full border border-white/10",style:{backgroundColor:c.accentColor||"#c0c1ff"}})]})}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Owned records"}),e.jsx("div",{className:"mt-2 text-white",children:(u==null?void 0:u.totalOwnedEntities)??0})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Total XP"}),e.jsx("div",{className:"mt-2 text-white",children:(g==null?void 0:g.totalXp)??0})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Weekly XP"}),e.jsx("div",{className:"mt-2 text-white",children:(g==null?void 0:g.weeklyXp)??0})]})]})]})},{id:"relationships",eyebrow:"Relationships",title:"Open directional relationship settings",description:"Each arrow is a separate contract. Open the exact lane you want to adjust and Forge will take you into the relationship flow.",render:()=>i?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx(C,{user:i}),e.jsxs("div",{className:"mt-3 text-sm leading-6 text-white/56",children:["@",i.handle," · ",i.description||"No description yet."]})]}),e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Outbound lanes"}),h.length>0?h.map(c=>e.jsxs("button",{type:"button",className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-left transition hover:bg-white/[0.05]",onClick:()=>v(c.id),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:c.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:c.targetUser})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(f,{className:"bg-white/[0.08] text-white/74",children:q(c)}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:[F(c),"/",I," rights"]})]})]},c.id)):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm text-white/52",children:"No outbound relationship lanes yet."})]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Inbound lanes"}),s.length>0?s.map(c=>e.jsxs("button",{type:"button",className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-4 text-left transition hover:bg-white/[0.05]",onClick:()=>v(c.id),children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:c.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:c.targetUser})]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:Z(c).map(m=>e.jsx(f,{className:m.enabled?"bg-white/[0.08] text-white/74":"bg-white/[0.04] text-white/38",children:m.label},`${c.id}-${m.id}`))})]},c.id)):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm text-white/52",children:"No inbound relationship lanes yet."})]})]})]}):e.jsx("div",{className:"rounded-[20px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-4 text-sm leading-6 text-white/52",children:"Create the user first, then Forge will generate the directional relationship lanes you can tune from here."})}];return e.jsx(K,{open:t,onOpenChange:r,eyebrow:i?"User settings":"Create user",title:i?"User settings":"Create user",description:"Edit the user identity, clarify what this lane represents, and jump into relationship settings without crowding the page.",value:b,onChange:N,draftPersistenceKey:i?`users.settings.${i.id}`:"users.settings.new",steps:y,submitLabel:i?"Save user":"Create user",pending:d,pendingLabel:i?"Saving user":"Creating user",error:U,contentClassName:"lg:w-[min(58rem,calc(100vw-1.5rem))]",onSubmit:async()=>{const c=b.handle.trim(),m=b.displayName.trim();if(c.length===0){a("Add a handle before saving this user.");return}if(m.length===0){a("Add a display name before saving this user.");return}await w({userId:i==null?void 0:i.id,input:{kind:b.kind,handle:c,displayName:m,description:b.description.trim(),accentColor:b.accentColor.trim()||"#c0c1ff"}}),r(!1)}})}function z(t,r){return{accessLevel:(t==null?void 0:t.accessLevel)??"manage",applyScope:"this_arrow",rights:{discoverable:(t==null?void 0:t.config.rights.discoverable)??!0,canListUsers:(t==null?void 0:t.config.rights.canListUsers)??!0,canReadProfile:(t==null?void 0:t.config.rights.canReadProfile)??!0,canReadEntities:(t==null?void 0:t.config.rights.canReadEntities)??!0,canSearchEntities:(t==null?void 0:t.config.rights.canSearchEntities)??!0,canLinkEntities:(t==null?void 0:t.config.rights.canLinkEntities)??!0,canCoordinate:(t==null?void 0:t.config.rights.canCoordinate)??!0,canAffectEntities:(t==null?void 0:t.config.rights.canAffectEntities)??!0,canManageStrategies:(t==null?void 0:t.config.rights.canManageStrategies)??!0,canCreateOnBehalf:(t==null?void 0:t.config.rights.canCreateOnBehalf)??!0,canViewMetrics:(t==null?void 0:t.config.rights.canViewMetrics)??!0,canViewActivity:(t==null?void 0:t.config.rights.canViewActivity)??!0}}}function ke({open:t,onOpenChange:r,grant:i,grants:x,pending:u=!1,onSubmit:g}){const d=p.useMemo(()=>i?x.find(a=>a.subjectUserId===i.targetUserId&&a.targetUserId===i.subjectUserId)??null:null,[i,x]),[w,v]=p.useState(()=>z(i,!!d));p.useEffect(()=>{t&&v(z(i,!!d))},[i,t,d]);const b=p.useMemo(()=>Object.values(w.rights).filter(Boolean).length,[w.rights]),N=Math.round(b/I*100),U=[{id:"posture",eyebrow:"Relationship posture",title:"Set the trust mode for this arrow",description:"Each arrow is directional. Decide whether you want to tune only this lane or mirror the same contract onto both directions.",render:(a,o)=>e.jsxs(e.Fragment,{children:[i?e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx(C,{user:i.subjectUser}),e.jsx("span",{className:"text-white/45",children:"→"}),e.jsx(C,{user:i.targetUser})]}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsx(f,{className:"bg-white/[0.08] text-white/74",children:be(i)}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:[F(i),"/",I," rights"]})]})]}):null,e.jsxs("div",{className:"grid gap-4 lg:grid-cols-2",children:[e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Access level"}),e.jsx(T,{columns:2,value:a.accessLevel,onChange:h=>o({accessLevel:h}),options:[{value:"view",label:"View",description:"Use when this lane should stay mostly observational."},{value:"manage",label:"Manage",description:"Use when the source side can actively collaborate or act."}]})]}),d?e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Apply scope"}),e.jsx(T,{columns:2,value:a.applyScope,onChange:h=>o({applyScope:h}),options:[{value:"this_arrow",label:"This arrow",description:"Only change the exact direction you opened."},{value:"both_arrows",label:"Both arrows",description:"Mirror the same contract onto the reverse direction too."}]})]}):null]}),e.jsxs("div",{className:"grid gap-3",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Quick preset"}),e.jsx("div",{className:"grid gap-3 md:grid-cols-2",children:me.map(h=>e.jsxs("button",{type:"button",className:`rounded-[22px] border p-4 text-left transition ${i&&fe(i,h)?"border-[rgba(244,185,122,0.35)] bg-[rgba(244,185,122,0.08)]":"border-white/8 bg-white/[0.03] hover:bg-white/[0.05]"}`,onClick:()=>o({rights:{...a.rights,...h.rights}}),children:[e.jsx("div",{className:"text-sm font-medium text-white",children:h.label}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/56",children:h.description})]},h.id))})]})]})},{id:"rights",eyebrow:"Rights",title:"Tune the individual permissions",description:"Use the preset as the starting point, then sharpen the exact boundaries only where this relationship needs them.",render:(a,o)=>e.jsx(e.Fragment,{children:Q.map(h=>e.jsxs("div",{className:"grid gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:h.label}),e.jsx("div",{className:"mt-1 text-sm leading-6 text-white/54",children:h.description})]}),e.jsx("div",{className:"grid gap-2",children:h.rights.map(s=>e.jsxs("label",{className:"flex items-start justify-between gap-3 rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-sm font-medium text-white",children:s.label}),e.jsx("div",{className:"mt-1 text-xs leading-5 text-white/50",children:s.description})]}),e.jsx("input",{type:"checkbox",checked:a.rights[s.key],onChange:y=>o({rights:{...a.rights,[s.key]:y.target.checked}})})]},s.key))})]},h.id))})},{id:"review",eyebrow:"Review",title:"Review the final relationship contract",description:"Check the enabled capabilities, confirm whether both directions should match, and then save the relationship.",render:a=>{var o,h;return e.jsx(e.Fragment,{children:e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Capability coverage"}),e.jsx("div",{className:"mt-4",children:e.jsx(de,{value:N})}),e.jsxs("div",{className:"mt-3 text-sm text-white/62",children:[b,"/",I," rights enabled"]}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-2",children:Z({...i??{id:"draft",subjectUserId:"",targetUserId:"",accessLevel:a.accessLevel,config:{self:!1,mutable:!0,linkedEntities:!0,rights:a.rights},createdAt:"",updatedAt:"",subjectUser:null,targetUser:null},accessLevel:a.accessLevel,config:{...(i==null?void 0:i.config)??{self:!1,mutable:!0,linkedEntities:!0},rights:a.rights}}).map(s=>e.jsx(f,{className:s.enabled?"bg-white/[0.08] text-white/74":"bg-white/[0.04] text-white/38",children:s.label},s.id))})]}),e.jsxs("div",{className:"rounded-[22px] border border-white/8 bg-white/[0.03] p-4",children:[e.jsx("div",{className:"text-sm font-medium text-white",children:"Save scope"}),e.jsx("div",{className:"mt-3 text-sm leading-6 text-white/58",children:a.applyScope==="both_arrows"&&d?"Forge will apply the same access level and rights to both directions of this pair.":"Forge will only update the exact arrow you opened."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:["access ",a.accessLevel]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/74",children:["scope"," ",a.applyScope==="both_arrows"&&d?"both arrows":"this arrow"]})]}),d?e.jsxs("div",{className:"mt-4 rounded-[18px] border border-white/8 bg-white/[0.03] px-4 py-3 text-sm text-white/54",children:["Reverse arrow available:"," ",((o=d.subjectUser)==null?void 0:o.displayName)??d.subjectUserId," ","→"," ",((h=d.targetUser)==null?void 0:h.displayName)??d.targetUserId]}):null]})]})})}}];return e.jsx(K,{open:t,onOpenChange:r,eyebrow:"Relationship settings",title:"Relationship settings",description:"Edit the exact directional contract between two users without keeping the full rights editor pinned on the page.",value:w,onChange:v,draftPersistenceKey:i?`users.relationship.${i.id}`:"users.relationship.new",steps:U,submitLabel:"Save relationship",pending:u,pendingLabel:"Saving relationship",contentClassName:"lg:w-[min(62rem,calc(100vw-1.5rem))]",onSubmit:async()=>{i&&(await g({grantId:i.id,patch:{accessLevel:w.accessLevel,rights:w.rights},reverseGrantId:(d==null?void 0:d.id)??null,applyToReverse:w.applyScope==="both_arrows"&&d!==null}),r(!1))}})}function Le(){var P;const t=he(),[r,i]=p.useState(null),[x,u]=p.useState(null),[g,d]=p.useState(!1),[w,v]=p.useState(!1),[b,N]=p.useState(""),U=te({queryKey:["forge-user-directory"],queryFn:ge}),a=async()=>{await Promise.all([t.refresh(),U.refetch()])},o=$({mutationFn:async({input:n,userId:l})=>l?(await xe(l,n)).user:(await ue(n)).user,onSuccess:async()=>{i(null),d(!1),await a()}}),h=$({mutationFn:async({grantId:n,patch:l})=>(await pe(n,l)).grant,onSuccess:a}),s=(P=U.data)==null?void 0:P.directory,y=(s==null?void 0:s.grants.find(n=>n.id===x))??null,c=p.useMemo(()=>new Map(((s==null?void 0:s.ownership)??[]).map(n=>[n.userId,n])),[s==null?void 0:s.ownership]),m=p.useMemo(()=>new Map(((s==null?void 0:s.xp)??[]).map(n=>[n.userId,n])),[s==null?void 0:s.xp]),k=p.useMemo(()=>{const n=new Map;for(const l of(s==null?void 0:s.grants)??[]){if(!l.targetUser||l.subjectUserId===l.targetUserId)continue;const j=n.get(l.subjectUserId)??[];j.push(l.targetUser),n.set(l.subjectUserId,j)}return n},[s==null?void 0:s.grants]),O=p.useMemo(()=>{const n=((s==null?void 0:s.grants)??[]).filter(l=>l.subjectUserId!==l.targetUserId);return{totalEdges:n.length,fullyOpenEdges:n.filter(l=>Object.values(l.config.rights).every(Boolean)).length,coordinationEdges:n.filter(l=>l.config.rights.canCoordinate).length,executionEdges:n.filter(l=>l.config.rights.canAffectEntities||l.config.rights.canCreateOnBehalf).length}},[s==null?void 0:s.grants]),A=b.trim().toLowerCase(),B=p.useMemo(()=>{const l=((s==null?void 0:s.users)??t.snapshot.users).filter(j=>A?[j.displayName,j.handle,j.kind,j.description].join(" ").toLowerCase().includes(A):!0);return{humans:l.filter(j=>j.kind==="human"),bots:l.filter(j=>j.kind==="bot")}},[s==null?void 0:s.users,A,t.snapshot.users]),J=(y==null?void 0:y.subjectUserId)??(r==null?void 0:r.id)??null,Y=(y==null?void 0:y.id)??null;return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1440px] gap-5",children:[e.jsx(ie,{title:"Users",description:"Forge users can be human or bot. Ownership, search, and routing are prepared so work can move across both sides of the system.",badge:`${t.snapshot.users.length} users`}),e.jsx(se,{}),e.jsx(ye,{open:g,onOpenChange:d,user:r,grants:(s==null?void 0:s.grants)??[],ownership:r?c.get(r.id)??null:null,xp:r?m.get(r.id)??null:null,pending:o.isPending,onSubmit:async n=>{await o.mutateAsync(n)},onOpenRelationship:n=>{d(!1),u(n),v(!0)}}),e.jsx(ke,{open:w,onOpenChange:v,grant:y,grants:(s==null?void 0:s.grants)??[],pending:h.isPending,onSubmit:async n=>{await h.mutateAsync({grantId:n.grantId,patch:n.patch}),n.applyToReverse&&n.reverseGrantId&&await h.mutateAsync({grantId:n.reverseGrantId,patch:n.patch})}}),e.jsxs(S,{className:"grid gap-3",children:[e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Multi-user posture"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:(s==null?void 0:s.posture.summary)??"Forge is preparing modular user access while keeping the current posture permissive."})]}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:(s==null?void 0:s.posture.accessModel)??"permissive"})]}),e.jsx("div",{className:"flex items-center gap-3 rounded-[18px] bg-white/[0.04] px-4 py-3",children:e.jsx(R,{value:b,onChange:n=>N(n.target.value),placeholder:"Search human, bot, @handle, or description"})})]}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(S,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Multi-agent onboarding"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:"Forge now treats the users graph as the collaboration control plane. Create each human or bot here, keep the runtime shared, then narrow only the specific arrows that should stop seeing, coordinating, planning, or affecting another user."})]}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:"default open"})]}),e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2 xl:grid-cols-4",children:[e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Directional edges"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.totalEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Fully open"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.fullyOpenEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Coordination"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.coordinationEdges})]}),e.jsxs("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Execution control"}),e.jsx("div",{className:"mt-2 text-lg text-white",children:O.executionEdges})]})]}),e.jsxs("div",{className:"grid gap-2 text-sm leading-6 text-white/56",children:[e.jsx("div",{children:"1. Create the human and bot users that should exist in the shared Forge system."}),e.jsx("div",{children:"2. Point OpenClaw, Hermes, and the browser at the same Forge runtime and storage root."}),e.jsx("div",{children:"3. Use the graph below to decide what each direction can see, message, plan, or change."}),e.jsx("div",{children:"4. Keep strategy drafting open while the plan is negotiated, then lock the strategy once it becomes the contract."})]})]}),e.jsx(ve,{users:(s==null?void 0:s.users)??t.snapshot.users,grants:(s==null?void 0:s.grants)??[],selectedGrantId:Y,selectedUserId:J,onOpenUser:n=>{const l=((s==null?void 0:s.users)??t.snapshot.users).find(j=>j.id===n)??null;u(null),i(l),d(!0)},onOpenGrant:n=>{i(null),u(n),v(!0)}}),e.jsxs(S,{className:"grid gap-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"Agent onboarding"}),e.jsx("div",{className:"text-sm leading-6 text-white/60",children:"OpenClaw, Hermes, and the Forge UI all read this same multi-user graph. Keep the defaults open while you are still wiring collaboration, then narrow specific arrows when one user or agent should stop seeing, messaging, planning, or changing another user's work."}),e.jsx("div",{className:"text-sm leading-6 text-white/52",children:"Forge now treats every owner as either human or bot, keeps search cross-user by default, and allows cross-owner links plus explicit coordination lanes between projects, tasks, notes, and strategies."}),e.jsx("div",{children:e.jsx(ee,{to:"/settings/agents",className:"inline-flex min-h-10 items-center justify-center rounded-[var(--radius-control)] bg-white/8 px-3 py-2 text-[13px] font-medium text-white transition hover:bg-white/12",children:"Open agent onboarding"})})]})]}),e.jsx(S,{children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:"User directory"}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:"Open any user to edit its identity and jump into the exact directional relationship lanes from the user settings flow."})]}),e.jsx(X,{onClick:()=>{u(null),i(null),d(!0)},children:"Create user"})]})}),e.jsx("div",{className:"grid gap-5",children:[{title:"Human users",users:B.humans},{title:"Bot users",users:B.bots}].map(n=>e.jsxs(S,{children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"font-label text-[11px] uppercase tracking-[0.18em] text-white/45",children:n.title}),e.jsx(f,{className:"bg-white/[0.08] text-white/72",children:n.users.length})]}),e.jsx("div",{className:"mt-4 grid gap-3",children:n.users.map(l=>{var j,D,G,_,H,V;return e.jsx("div",{className:"rounded-[18px] bg-white/[0.04] px-4 py-4",children:e.jsxs("div",{className:"flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx(C,{user:l}),e.jsxs("div",{className:"mt-3 text-sm text-white/58",children:["@",l.handle]}),e.jsx("div",{className:"mt-2 text-sm leading-6 text-white/60",children:l.description||"No description yet."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2",children:[e.jsxs(f,{className:"bg-[var(--primary)]/14 text-[var(--primary)]",children:[((j=m.get(l.id))==null?void 0:j.totalXp)??0," XP"]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((D=m.get(l.id))==null?void 0:D.weeklyXp)??0," weekly"]}),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((G=m.get(l.id))==null?void 0:G.rewardEventCount)??0," ","rewards"]}),Object.entries(((_=c.get(l.id))==null?void 0:_.entityCounts)??{}).sort((E,L)=>L[1]-E[1]).slice(0,4).map(([E,L])=>e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[L," ",E]},`${l.id}-${E}`)),e.jsxs(f,{className:"bg-white/[0.08] text-white/70",children:[((H=c.get(l.id))==null?void 0:H.totalOwnedEntities)??0," ","owned"]})]}),e.jsxs("div",{className:"mt-3 text-xs leading-5 text-white/50",children:["Can currently read:"," ",(k.get(l.id)??[]).map(E=>`${E.displayName} (${E.kind})`).join(", ")||"no other users"]}),(V=m.get(l.id))!=null&&V.lastRewardAt?e.jsxs("div",{className:"mt-2 text-xs leading-5 text-white/45",children:["Last XP movement:"," ",new Date(m.get(l.id).lastRewardAt).toLocaleString()]}):null]}),e.jsx("div",{className:"flex gap-2",children:e.jsx(X,{variant:"secondary",onClick:()=>{u(null),i(l),d(!0)},children:"Open settings"})})]})},l.id)})})]},n.title))})]})]})}export{Le as SettingsUsersPage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r,j as e,aC as W,bg as H,c7 as T,cD as Y,cE as Z}from"./vendor-DHkYh85p.js";import{j as X,i as Q,k as x}from"./state-B-4sS1xO.js";import{S as J}from"./settings-section-nav-CCFm27r2.js";import{P as ee}from"./page-hero-CQWo1Mm_.js";import{bV as ie,bW as se,bX as te,bY as ae,bZ as ne,L as re,E as q,B as p,C as w,c as j,aq as de,I as l,b_ as le,b$ as ce}from"./index-BHTUu_4M.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";const R=[{value:"gpt-5.4",label:"GPT-5.4",description:"Highest quality drafting for long, connected wiki pages."},{value:"gpt-5.4-mini",label:"GPT-5.4 mini",description:"Balanced speed and quality for regular ingest jobs."},{value:"gpt-5.4-nano",label:"GPT-5.4 nano",description:"Fastest and cheapest option for smaller imports."}];R[1].value;const oe="medium",me="medium";function he(s){const t=s==null?void 0:s.reasoningEffort;return t==="none"||t==="low"||t==="medium"||t==="high"||t==="xhigh"?t:oe}function xe(s){const t=s==null?void 0:s.verbosity;return t==="low"||t==="medium"||t==="high"?t:me}function z(s){var m;return{model:((m=R.find(g=>g.value===s.model))==null?void 0:m.label)??s.model,reasoning:he(s.metadata),verbosity:xe(s.metadata),hasKey:!!s.secretId}}function ke(){var F,O;const s=X(),[t,m]=r.useState(""),[g,y]=r.useState(""),[N,f]=r.useState("personal"),[u,U]=r.useState("Fast wiki search"),[b,B]=r.useState("text-embedding-3-small"),[k,_]=r.useState("https://api.openai.com/v1"),[S,C]=r.useState(""),[L,D]=r.useState("1200"),[P,G]=r.useState("200"),c=Q({queryKey:["forge-wiki-settings"],queryFn:le}),V=Q({queryKey:["forge-settings"],queryFn:ce}),h=async()=>{await Promise.all([s.invalidateQueries({queryKey:["forge-wiki-settings"]}),s.invalidateQueries({queryKey:["forge-wiki-pages"]}),s.invalidateQueries({queryKey:["forge-wiki-page"]}),s.invalidateQueries({queryKey:["forge-wiki-search"]})])},K=x({mutationFn:()=>ie({label:t.trim(),description:g.trim(),visibility:N}),onSuccess:async()=>{m(""),y(""),f("personal"),await h()}}),A=x({mutationFn:()=>se({label:u.trim(),model:b.trim(),baseUrl:k.trim(),apiKey:S.trim()||void 0,chunkSize:Number(L),chunkOverlap:Number(P)}),onSuccess:async()=>{C(""),await h()}}),I=x({mutationFn:({kind:i,profileId:o})=>te(i,o),onSuccess:h}),E=x({mutationFn:()=>ae(),onSuccess:h}),M=x({mutationFn:()=>ne(),onSuccess:h});if(c.isLoading)return e.jsx(re,{eyebrow:"KarpaWiki settings",title:"Loading KarpaWiki controls",description:"Fetching spaces and profile configuration for KarpaWiki."});if(c.isError)return e.jsx(q,{eyebrow:"KarpaWiki settings",error:c.error,onRetry:()=>void c.refetch()});const n=(F=c.data)==null?void 0:F.settings;if(!n)return e.jsx(q,{eyebrow:"KarpaWiki settings",error:new Error("Forge returned an empty KarpaWiki settings payload."),onRetry:()=>void c.refetch()});const d=n.llmProfiles.find(i=>i.enabled)??n.llmProfiles[0]??null,v=d?z(d):null,$="Canonical knowledge lives in SQLite notes, with Forge maintaining metadata, links, search, and optional embedding indexes in the database. Text search and entity-linked search work without embeddings, while semantic search stays additive and profile-driven. Ingest jobs can create pages and media assets now, with room for richer OCR, transcription, and multimodal compilation later.",a=(O=V.data)==null?void 0:O.settings.modelSettings.forgeAgent.wiki;return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1440px] gap-5",children:[e.jsx(ee,{eyebrow:"SQLite memory",title:"KarpaWiki Settings",titleText:"KarpaWiki Settings",description:"Configure SQLite-backed spaces, parse models, and embedding profiles for the KarpaWiki memory system.",badge:`${n.spaces.length} spaces · ${n.embeddingProfiles.length} embedding profiles`,actions:e.jsxs(e.Fragment,{children:[e.jsx(p,{variant:"secondary",pending:E.isPending,pendingLabel:"Syncing",onClick:()=>void E.mutateAsync(),children:"Refresh indexes"}),e.jsx(p,{pending:M.isPending,pendingLabel:"Reindexing",onClick:()=>void M.mutateAsync(),disabled:n.embeddingProfiles.length===0,children:"Reindex embeddings"})]})}),e.jsx(J,{}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-white",children:"Auto-ingest model"}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"KarpaWiki ingest now reads its credentials and model slot from the dedicated Models settings page instead of owning the OpenAI setup flow here."})]})}),e.jsxs("div",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.8fr)_minmax(24rem,0.9fr)]",children:[e.jsxs("div",{className:"grid gap-5 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(22,32,49,0.9),rgba(12,18,31,0.9))] p-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Current profile"}),e.jsx("div",{className:"mt-2 text-xl font-semibold text-white",children:(a==null?void 0:a.connectionLabel)??(d==null?void 0:d.label)??"No external KarpaWiki model selected"}),e.jsx("div",{className:"mt-2 max-w-3xl text-sm leading-6 text-white/58",children:a!=null&&a.connectionLabel?"Forge now resolves wiki ingest through the selected Models connection and syncs the managed wiki profile automatically.":"Pick a Models connection when you want Forge wiki ingest to run through the OpenAI API or a local compatible endpoint."})]}),e.jsx(W,{to:"/settings/models",className:"inline-flex min-h-11 items-center rounded-[16px] bg-white/[0.08] px-4 py-3 text-sm text-white transition hover:bg-white/[0.12]",children:"Open model settings"})]}),e.jsxs("div",{className:"grid gap-3 lg:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Model"}),e.jsx("div",{className:"mt-2 text-white",children:(a==null?void 0:a.model)??(v==null?void 0:v.model)??"Not set"})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Provider"}),e.jsx("div",{className:"mt-2 text-white",children:(a==null?void 0:a.connectionLabel)??"Not set"})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Endpoint"}),e.jsx("div",{className:"mt-2 flex items-center gap-2 text-white",children:(a==null?void 0:a.baseUrl)??(d==null?void 0:d.baseUrl)??"Not set"})]})]})]}),e.jsxs("div",{className:"grid gap-3 rounded-[28px] border border-white/8 bg-white/[0.03] p-6",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Supported controls"}),e.jsxs("div",{className:"text-sm leading-6 text-white/58",children:["OpenAI API and local compatible endpoints are configured under Settings ","->"," Models. OpenAI Codex OAuth lives there as a chat agent path, while Wiki keeps the SQLite memory controls here and consumes the selected ingest model slot."]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:["GPT-5.4","GPT-5.4 mini","GPT-5.4 nano"].map(i=>e.jsx(j,{className:"bg-white/[0.06] text-white/78",children:i},i))}),e.jsxs(W,{to:"/settings/models",className:"inline-flex min-h-11 items-center rounded-[16px] bg-white/[0.08] px-4 py-3 text-sm text-white transition hover:bg-white/[0.12]",children:["Open model settings",e.jsx(H,{className:"ml-2 size-4"})]})]})]}),e.jsxs("div",{className:"grid gap-3",children:[n.llmProfiles.length===0?e.jsx("div",{className:"rounded-[18px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-5 text-sm leading-6 text-white/58",children:"No LLM profile yet. Set up OpenAI once, test it, and Forge will use it for wiki auto-ingest."}):null,n.llmProfiles.map(i=>{const o=z(i);return e.jsxs("div",{className:"grid gap-3 rounded-[18px] bg-white/[0.04] 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:"text-white",children:i.label}),e.jsxs("div",{className:"mt-1 text-xs text-white/46",children:[o.model," · thinking ",o.reasoning," · verbosity ",o.verbosity]})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("button",{type:"button",className:"rounded-full p-2 text-white/48 transition hover:bg-white/[0.08] hover:text-white",onClick:()=>void I.mutateAsync({kind:"llm",profileId:i.id}),children:e.jsx(T,{className:"size-4"})})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 text-xs text-white/58",children:[e.jsx(j,{className:"bg-white/[0.06] text-white/76",children:i.baseUrl}),e.jsx(j,{className:"bg-white/[0.06] text-white/76",children:o.hasKey?"key saved":"key missing"})]})]},i.id)})]})]}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Y,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"text-sm text-white",children:"Spaces"}),e.jsx(de,{content:$,label:"Explain the wiki operating model"})]}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"Personal and shared wiki spaces map to explicit SQLite namespaces."})]})]}),e.jsx("div",{className:"grid gap-3",children:n.spaces.map(i=>e.jsxs("div",{className:"grid gap-1 rounded-[18px] bg-white/[0.04] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-white",children:i.label}),e.jsx("div",{className:"text-xs uppercase tracking-[0.16em] text-white/42",children:i.visibility})]}),e.jsx("div",{className:"text-xs text-white/46",children:i.slug}),e.jsx("div",{className:"text-sm text-white/60",children:i.description||"No description yet."})]},i.id))}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsx(l,{value:t,onChange:i=>m(i.target.value),placeholder:"New space label"}),e.jsx(l,{value:g,onChange:i=>y(i.target.value),placeholder:"Description"}),e.jsxs("select",{className:"rounded-[16px] border border-white/10 bg-white/[0.04] px-3 py-3 text-sm text-white",value:N,onChange:i=>f(i.target.value),children:[e.jsx("option",{value:"personal",children:"Personal"}),e.jsx("option",{value:"shared",children:"Shared"})]}),e.jsx(p,{pending:K.isPending,pendingLabel:"Creating",disabled:!t.trim(),onClick:()=>void K.mutateAsync(),children:"Create space"})]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Z,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-white",children:"Embedding profiles"}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"Semantic search stays opt-in. The recommended starter is fast and cheap, with heading-aware chunking for agent memory retrieval."})]})]}),e.jsx("div",{className:"grid gap-3",children:n.embeddingProfiles.map(i=>e.jsxs("div",{className:"grid gap-2 rounded-[18px] bg-white/[0.04] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-white",children:i.label}),e.jsx("button",{type:"button",className:"rounded-full p-2 text-white/48 transition hover:bg-white/[0.08] hover:text-white",onClick:()=>void I.mutateAsync({kind:"embedding",profileId:i.id}),children:e.jsx(T,{className:"size-4"})})]}),e.jsxs("div",{className:"text-xs text-white/46",children:[i.model," · ",i.baseUrl]}),e.jsxs("div",{className:"text-sm text-white/60",children:["chunkSize ",i.chunkSize," · overlap"," ",i.chunkOverlap]})]},i.id))}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsx(l,{value:u,onChange:i=>U(i.target.value),placeholder:"Profile label"}),e.jsx(l,{value:b,onChange:i=>B(i.target.value),placeholder:"Model"}),e.jsx(l,{value:k,onChange:i=>_(i.target.value),placeholder:"Base URL"}),e.jsx(l,{value:S,onChange:i=>C(i.target.value),placeholder:"API key (optional)",type:"password"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(l,{value:L,onChange:i=>D(i.target.value),placeholder:"Chunk size",type:"number"}),e.jsx(l,{value:P,onChange:i=>G(i.target.value),placeholder:"Chunk overlap",type:"number"})]}),e.jsx(p,{pending:A.isPending,pendingLabel:"Saving",disabled:!u.trim()||!b.trim(),onClick:()=>void A.mutateAsync(),children:"Save embedding profile"})]})]})]})]})]})}export{ke as SettingsWikiPage};
|
|
1
|
+
import{r,j as e,aC as W,bg as H,c7 as T,cD as Y,cE as Z}from"./vendor-DHkYh85p.js";import{j as X,i as Q,k as x}from"./state-B-4sS1xO.js";import{S as J}from"./settings-section-nav-DSOuht_F.js";import{P as ee}from"./page-hero-DRy5b2MU.js";import{bV as ie,bW as se,bX as te,bY as ae,bZ as ne,L as re,E as q,B as p,C as w,c as j,aq as de,I as l,b_ as le,b$ as ce}from"./index-CF4J4R9L.js";import"./board-BkDRaMp6.js";import"./ui-C13Nbgas.js";import"./motion-BeD44FeG.js";import"./forms-BFlTgZ3W.js";import"./graph-D6JLqDbD.js";const R=[{value:"gpt-5.4",label:"GPT-5.4",description:"Highest quality drafting for long, connected wiki pages."},{value:"gpt-5.4-mini",label:"GPT-5.4 mini",description:"Balanced speed and quality for regular ingest jobs."},{value:"gpt-5.4-nano",label:"GPT-5.4 nano",description:"Fastest and cheapest option for smaller imports."}];R[1].value;const oe="medium",me="medium";function he(s){const t=s==null?void 0:s.reasoningEffort;return t==="none"||t==="low"||t==="medium"||t==="high"||t==="xhigh"?t:oe}function xe(s){const t=s==null?void 0:s.verbosity;return t==="low"||t==="medium"||t==="high"?t:me}function z(s){var m;return{model:((m=R.find(g=>g.value===s.model))==null?void 0:m.label)??s.model,reasoning:he(s.metadata),verbosity:xe(s.metadata),hasKey:!!s.secretId}}function ke(){var F,O;const s=X(),[t,m]=r.useState(""),[g,y]=r.useState(""),[N,f]=r.useState("personal"),[u,U]=r.useState("Fast wiki search"),[b,B]=r.useState("text-embedding-3-small"),[k,_]=r.useState("https://api.openai.com/v1"),[S,C]=r.useState(""),[L,D]=r.useState("1200"),[P,G]=r.useState("200"),c=Q({queryKey:["forge-wiki-settings"],queryFn:le}),V=Q({queryKey:["forge-settings"],queryFn:ce}),h=async()=>{await Promise.all([s.invalidateQueries({queryKey:["forge-wiki-settings"]}),s.invalidateQueries({queryKey:["forge-wiki-pages"]}),s.invalidateQueries({queryKey:["forge-wiki-page"]}),s.invalidateQueries({queryKey:["forge-wiki-search"]})])},K=x({mutationFn:()=>ie({label:t.trim(),description:g.trim(),visibility:N}),onSuccess:async()=>{m(""),y(""),f("personal"),await h()}}),A=x({mutationFn:()=>se({label:u.trim(),model:b.trim(),baseUrl:k.trim(),apiKey:S.trim()||void 0,chunkSize:Number(L),chunkOverlap:Number(P)}),onSuccess:async()=>{C(""),await h()}}),I=x({mutationFn:({kind:i,profileId:o})=>te(i,o),onSuccess:h}),E=x({mutationFn:()=>ae(),onSuccess:h}),M=x({mutationFn:()=>ne(),onSuccess:h});if(c.isLoading)return e.jsx(re,{eyebrow:"KarpaWiki settings",title:"Loading KarpaWiki controls",description:"Fetching spaces and profile configuration for KarpaWiki."});if(c.isError)return e.jsx(q,{eyebrow:"KarpaWiki settings",error:c.error,onRetry:()=>void c.refetch()});const n=(F=c.data)==null?void 0:F.settings;if(!n)return e.jsx(q,{eyebrow:"KarpaWiki settings",error:new Error("Forge returned an empty KarpaWiki settings payload."),onRetry:()=>void c.refetch()});const d=n.llmProfiles.find(i=>i.enabled)??n.llmProfiles[0]??null,v=d?z(d):null,$="Canonical knowledge lives in SQLite notes, with Forge maintaining metadata, links, search, and optional embedding indexes in the database. Text search and entity-linked search work without embeddings, while semantic search stays additive and profile-driven. Ingest jobs can create pages and media assets now, with room for richer OCR, transcription, and multimodal compilation later.",a=(O=V.data)==null?void 0:O.settings.modelSettings.forgeAgent.wiki;return e.jsxs("div",{className:"mx-auto grid w-full max-w-[1440px] gap-5",children:[e.jsx(ee,{eyebrow:"SQLite memory",title:"KarpaWiki Settings",titleText:"KarpaWiki Settings",description:"Configure SQLite-backed spaces, parse models, and embedding profiles for the KarpaWiki memory system.",badge:`${n.spaces.length} spaces · ${n.embeddingProfiles.length} embedding profiles`,actions:e.jsxs(e.Fragment,{children:[e.jsx(p,{variant:"secondary",pending:E.isPending,pendingLabel:"Syncing",onClick:()=>void E.mutateAsync(),children:"Refresh indexes"}),e.jsx(p,{pending:M.isPending,pendingLabel:"Reindexing",onClick:()=>void M.mutateAsync(),disabled:n.embeddingProfiles.length===0,children:"Reindex embeddings"})]})}),e.jsx(J,{}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsx("div",{className:"flex items-center gap-3",children:e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-white",children:"Auto-ingest model"}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"KarpaWiki ingest now reads its credentials and model slot from the dedicated Models settings page instead of owning the OpenAI setup flow here."})]})}),e.jsxs("div",{className:"grid gap-4 xl:grid-cols-[minmax(0,1.8fr)_minmax(24rem,0.9fr)]",children:[e.jsxs("div",{className:"grid gap-5 rounded-[28px] border border-white/8 bg-[linear-gradient(180deg,rgba(22,32,49,0.9),rgba(12,18,31,0.9))] p-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Current profile"}),e.jsx("div",{className:"mt-2 text-xl font-semibold text-white",children:(a==null?void 0:a.connectionLabel)??(d==null?void 0:d.label)??"No external KarpaWiki model selected"}),e.jsx("div",{className:"mt-2 max-w-3xl text-sm leading-6 text-white/58",children:a!=null&&a.connectionLabel?"Forge now resolves wiki ingest through the selected Models connection and syncs the managed wiki profile automatically.":"Pick a Models connection when you want Forge wiki ingest to run through the OpenAI API or a local compatible endpoint."})]}),e.jsx(W,{to:"/settings/models",className:"inline-flex min-h-11 items-center rounded-[16px] bg-white/[0.08] px-4 py-3 text-sm text-white transition hover:bg-white/[0.12]",children:"Open model settings"})]}),e.jsxs("div",{className:"grid gap-3 lg:grid-cols-3",children:[e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Model"}),e.jsx("div",{className:"mt-2 text-white",children:(a==null?void 0:a.model)??(v==null?void 0:v.model)??"Not set"})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Provider"}),e.jsx("div",{className:"mt-2 text-white",children:(a==null?void 0:a.connectionLabel)??"Not set"})]}),e.jsxs("div",{className:"rounded-[20px] border border-white/8 bg-white/[0.03] px-4 py-3",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.16em] text-white/40",children:"Endpoint"}),e.jsx("div",{className:"mt-2 flex items-center gap-2 text-white",children:(a==null?void 0:a.baseUrl)??(d==null?void 0:d.baseUrl)??"Not set"})]})]})]}),e.jsxs("div",{className:"grid gap-3 rounded-[28px] border border-white/8 bg-white/[0.03] p-6",children:[e.jsx("div",{className:"text-[11px] uppercase tracking-[0.18em] text-white/42",children:"Supported controls"}),e.jsxs("div",{className:"text-sm leading-6 text-white/58",children:["OpenAI API and local compatible endpoints are configured under Settings ","->"," Models. OpenAI Codex OAuth lives there as a chat agent path, while Wiki keeps the SQLite memory controls here and consumes the selected ingest model slot."]}),e.jsx("div",{className:"flex flex-wrap gap-2",children:["GPT-5.4","GPT-5.4 mini","GPT-5.4 nano"].map(i=>e.jsx(j,{className:"bg-white/[0.06] text-white/78",children:i},i))}),e.jsxs(W,{to:"/settings/models",className:"inline-flex min-h-11 items-center rounded-[16px] bg-white/[0.08] px-4 py-3 text-sm text-white transition hover:bg-white/[0.12]",children:["Open model settings",e.jsx(H,{className:"ml-2 size-4"})]})]})]}),e.jsxs("div",{className:"grid gap-3",children:[n.llmProfiles.length===0?e.jsx("div",{className:"rounded-[18px] border border-dashed border-white/10 bg-white/[0.02] px-4 py-5 text-sm leading-6 text-white/58",children:"No LLM profile yet. Set up OpenAI once, test it, and Forge will use it for wiki auto-ingest."}):null,n.llmProfiles.map(i=>{const o=z(i);return e.jsxs("div",{className:"grid gap-3 rounded-[18px] bg-white/[0.04] 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:"text-white",children:i.label}),e.jsxs("div",{className:"mt-1 text-xs text-white/46",children:[o.model," · thinking ",o.reasoning," · verbosity ",o.verbosity]})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsx("button",{type:"button",className:"rounded-full p-2 text-white/48 transition hover:bg-white/[0.08] hover:text-white",onClick:()=>void I.mutateAsync({kind:"llm",profileId:i.id}),children:e.jsx(T,{className:"size-4"})})})]}),e.jsxs("div",{className:"flex flex-wrap gap-2 text-xs text-white/58",children:[e.jsx(j,{className:"bg-white/[0.06] text-white/76",children:i.baseUrl}),e.jsx(j,{className:"bg-white/[0.06] text-white/76",children:o.hasKey?"key saved":"key missing"})]})]},i.id)})]})]}),e.jsxs("div",{className:"grid gap-5",children:[e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Y,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"text-sm text-white",children:"Spaces"}),e.jsx(de,{content:$,label:"Explain the wiki operating model"})]}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"Personal and shared wiki spaces map to explicit SQLite namespaces."})]})]}),e.jsx("div",{className:"grid gap-3",children:n.spaces.map(i=>e.jsxs("div",{className:"grid gap-1 rounded-[18px] bg-white/[0.04] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-white",children:i.label}),e.jsx("div",{className:"text-xs uppercase tracking-[0.16em] text-white/42",children:i.visibility})]}),e.jsx("div",{className:"text-xs text-white/46",children:i.slug}),e.jsx("div",{className:"text-sm text-white/60",children:i.description||"No description yet."})]},i.id))}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsx(l,{value:t,onChange:i=>m(i.target.value),placeholder:"New space label"}),e.jsx(l,{value:g,onChange:i=>y(i.target.value),placeholder:"Description"}),e.jsxs("select",{className:"rounded-[16px] border border-white/10 bg-white/[0.04] px-3 py-3 text-sm text-white",value:N,onChange:i=>f(i.target.value),children:[e.jsx("option",{value:"personal",children:"Personal"}),e.jsx("option",{value:"shared",children:"Shared"})]}),e.jsx(p,{pending:K.isPending,pendingLabel:"Creating",disabled:!t.trim(),onClick:()=>void K.mutateAsync(),children:"Create space"})]})]}),e.jsxs(w,{className:"grid gap-4",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(Z,{className:"size-4 text-[var(--secondary)]"}),e.jsxs("div",{children:[e.jsx("div",{className:"text-sm text-white",children:"Embedding profiles"}),e.jsx("div",{className:"text-xs leading-5 text-white/50",children:"Semantic search stays opt-in. The recommended starter is fast and cheap, with heading-aware chunking for agent memory retrieval."})]})]}),e.jsx("div",{className:"grid gap-3",children:n.embeddingProfiles.map(i=>e.jsxs("div",{className:"grid gap-2 rounded-[18px] bg-white/[0.04] px-4 py-4",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3",children:[e.jsx("div",{className:"text-white",children:i.label}),e.jsx("button",{type:"button",className:"rounded-full p-2 text-white/48 transition hover:bg-white/[0.08] hover:text-white",onClick:()=>void I.mutateAsync({kind:"embedding",profileId:i.id}),children:e.jsx(T,{className:"size-4"})})]}),e.jsxs("div",{className:"text-xs text-white/46",children:[i.model," · ",i.baseUrl]}),e.jsxs("div",{className:"text-sm text-white/60",children:["chunkSize ",i.chunkSize," · overlap"," ",i.chunkOverlap]})]},i.id))}),e.jsxs("div",{className:"grid gap-3 rounded-[20px] bg-white/[0.03] p-4",children:[e.jsx(l,{value:u,onChange:i=>U(i.target.value),placeholder:"Profile label"}),e.jsx(l,{value:b,onChange:i=>B(i.target.value),placeholder:"Model"}),e.jsx(l,{value:k,onChange:i=>_(i.target.value),placeholder:"Base URL"}),e.jsx(l,{value:S,onChange:i=>C(i.target.value),placeholder:"API key (optional)",type:"password"}),e.jsxs("div",{className:"grid gap-3 md:grid-cols-2",children:[e.jsx(l,{value:L,onChange:i=>D(i.target.value),placeholder:"Chunk size",type:"number"}),e.jsx(l,{value:P,onChange:i=>G(i.target.value),placeholder:"Chunk overlap",type:"number"})]}),e.jsx(p,{pending:A.isPending,pendingLabel:"Saving",disabled:!u.trim()||!b.trim(),onClick:()=>void A.mutateAsync(),children:"Save embedding profile"})]})]})]})]})]})}export{ke as SettingsWikiPage};
|