PageSourceSearch

https://app.agenticlover.ai/assets/ChasterExtension-B3F47RJq.js

js agenticlover.ai collected 2026-09-25 22:30:57 UTC 18,704 bytes, 1 lines download raw bytes

1import{o as e,r as t,n,by as s,bz as r,bA as o,bB as a,d as c,e as i,f as l}from"./index-DCpYiqWz.js";function d(e){if(null==e||!Number.isFinite(e))return"unknown";if(e<=0)return"0m";const t=Math.floor(e/60),n=Math.floor(e/3600),s=Math.floor(e/86400);if(s>=14){const e=Math.floor(s/7),t=s%7;return t>0?`${e}w ${t}d`:`${e}w`}if(s>=2){const t=Math.floor(e%86400/3600);return t>0?`${s}d ${t}h`:`${s}d`}if(n>=1){const t=Math.floor(e%3600/60);return t>0?`${n}h ${t}m`:`${n}h`}return`${t}m`}const u={connected:!1,status:"disconnected",username:null,chaster_user_id:null,last_error:null},m=Object.freeze({selectedLockId:"",toolUnit:"minutes",maxPerCall:5,maxPerHour:20,maxPerDay:60});function x(e,t){const n=Number(e);return!Number.isInteger(n)||n<=0?t:n}function h(e){const t=e&&"object"==typeof e?e:{};return{selectedLockId:"string"==typeof t.selectedLockId?t.selectedLockId.trim():"",toolUnit:"seconds"===t.toolUnit||"minutes"===t.toolUnit||"hours"===t.toolUnit?t.toolUnit:m.toolUnit,maxPerCall:x(t.maxPerCall,m.maxPerCall),maxPerHour:x(t.maxPerHour,m.maxPerHour),maxPerDay:x(t.maxPerDay,m.maxPerDay)}}const p={loading:!1,lastError:"",account:{...u},lock:null,settings:{...m},usage:null,listeners:new Set,refreshPromise:null,tickTimerId:null,safetyTimerId:null,listenersAttached:!1,consecutiveFailures:0,lastRefreshAt:0};let g=y();function y(){return{loading:p.loading,lastError:p.lastError,account:{...p.account},lock:p.lock?{...p.lock}:null,settings:{...p.settings},usage:p.usage?{...p.usage}:null}}function f(){g=y();for(const t of p.listeners)try{t()}catch(e){console.error("[Chaster] listener error",e)}}function b(){return g}function k(e){return p.listeners.add(e),()=>{p.listeners.delete(e)}}function v(e){return p.settings=h(e),f(),p.settings}async function w(){return p.refreshPromise||(p.refreshPromise=(async()=>{p.loading=!0,p.lastRefreshAt=Date.now(),f();let t=!1;try{const s=await e.getChasterAccountStatus();if(p.account=s,p.lastError=s.last_error||"",s.connected&&p.settings.selectedLockId)try{const{lock:t}=await e.getChasterLock(p.settings.selectedLockId);p.lock=t}catch(n){t=!0,p.lock=null,p.lastError=n instanceof Error?n.message:"Failed to load Chaster lock"}else p.lock=null}catch(n){t=!0,p.lastError=n instanceof Error?n.message:"Failed to refresh Chaster status.",p.account.connected||(p.lock=null)}finally{p.consecutiveFailures=t?p.consecutiveFailures+1:0,p.loading=!1,f(),p.refreshPromise=null,S()}return g})()),p.refreshPromise}function C(){return p.account.connected&&!!p.settings.selectedLockId}function j(){const e=3e5*Math.pow(2,p.consecutiveFailures);return Math.min(e,18e5)}function N(){if(!p.lock)return;const e=function(e){if(!e.endDate||e.timeHidden||"unlocked"===e.status)return e;const t=Math.max(0,Math.floor((new Date(e.endDate).getTime()-Date.now())/1e3));return t===e.remainingSeconds?e:{...e,remainingSeconds:t,remainingLabel:t<=0?"0s left":`${d(t)} left`}}(p.lock);e!==p.lock&&e.remainingLabel!==p.lock.remainingLabel&&(p.lock=e,f())}function S(){"undefined"!=typeof window&&(p.safetyTimerId&&(clearTimeout(p.safetyTimerId),p.safetyTimerId=null),"hidden"!==document.visibilityState&&C()&&(p.safetyTimerId=setTimeout(()=>{p.safetyTimerId=null,C()&&w()},j())))}function I(){if(!C())return;const e=Math.max(6e4,p.consecutiveFailures>0?j():0);Date.now()-p.lastRefreshAt<e||w()}function P(){"visible"===document.visibilityState?(I(),S()):p.safetyTimerId&&(clearTimeout(p.safetyTimerId),p.safetyTimerId=null)}function E(){"undefined"!=typeof window&&(p.tickTimerId||(p.tickTimerId=setInterval(N,1e3)),p.listenersAttached||"undefined"==typeof window||(window.addEventListener("focus",I),document.addEventListener("visibilitychange",P),p.listenersAttached=!0),S())}function L(){p.tickTimerId&&(clearInterval(p.tickTimerId),p.tickTimerId=null),p.safetyTimerId&&(clearTimeout(p.safetyTimerId),p.safetyTimerId=null),p.listenersAttached&&"undefined"!=typeof window&&(window.removeEventListener("focus",I),document.removeEventListener("visibilitychange",P),p.listenersAttached=!1)}function T(e){if("unlocked"===e.status)return"Unlocked";if(e.timeHidden||!e.endDate)return e.remainingLabel;const t=Math.max(0,Math.floor((new Date(e.endDate).getTime()-Date.now())/1e3));return t<=0?"0s left":`${d(t)} left`}function $({disabled:e,onClick:t,children:r,tone:o="default"}){return n.jsx("button",{type:"button",onClick:t,disabled:e,className:s("roun
1ded-md border px-3 py-2 text-xs transition disabled:opacity-50","danger"===o?"border-rose-500/25 bg-rose-500/10 text-rose-200 hover:bg-rose-500/20":"border-orchid-500/25 bg-bg-deep text-text-secondary hover:border-orchid-500/40 hover:text-text-primary"),children:r})}function A({notice:e}){return e?n.jsx("div",{className:s("rounded-lg border px-3 py-2 text-xs","error"===e.type?"border-rose-500/25 bg-rose-500/10 text-rose-200":"border-eucalyptus-500/25 bg-eucalyptus-500/10 text-eucalyptus-200"),children:e.text}):null}const U="add_time_to_chastity";const D="chaster";function M(e){const t=e.toolUnit;return[`Add time to the user's Chaster chastity lock in ${t}.`,"Use a positive integer amount only.",`Maximum per call: ${e.maxPerCall} ${t}.`,`Maximum per rolling hour: ${e.maxPerHour} ${t}.`,`Maximum per rolling day: ${e.maxPerDay} ${t}.`].join(" ")}const _={manifest:{apiVersion:5,version:"1.0.0",source:"builtin",key:D,name:"Chaster",category:"integration",icon:"Lock",description:"AI-controlled chastity lock time via Chaster.app, with per-add / per-hour / per-day caps.",showInTopBar:!0,chatFooter:{order:60},supportsPromptContributions:!0,settings:{fields:{selectedLockId:{id:"selectedLockId",type:"text",scope:"global",title:"Selected lock"},toolUnit:{id:"toolUnit",type:"select",scope:"global",title:"Tool unit",options:[{label:"seconds",value:"seconds"},{label:"minutes",value:"minutes"},{label:"hours",value:"hours"}],default:"minutes"},maxPerCall:{id:"maxPerCall",type:"number",scope:"global",title:"Max per call",min:1,step:1,default:5},maxPerHour:{id:"maxPerHour",type:"number",scope:"global",title:"Max per hour",min:1,step:1,default:20},maxPerDay:{id:"maxPerDay",type:"number",scope:"global",title:"Max per day",min:1,step:1,default:60}},mainLayout:[],quickLayout:[]},SettingsComponent:function({extension:o,onUpdate:a}){const c=t.useSyncExternalStore(k,b,b),[i,l]=t.useState(()=>h(o.resolvedSettings||m)),[d,x]=t.useState([]),[g,y]=t.useState(!1),[C,j]=t.useState(null),[,N]=t.useState(0);t.useEffect(()=>{const e=setInterval(()=>N(e=>(e+1)%1e6),1e3);return()=>clearInterval(e)},[]);const S=t.useCallback(async()=>{try{const{locks:t}=await e.listChasterLocks();x(t)}catch(t){x([]),j({type:"error",text:t instanceof Error?t.message:"Failed to load locks."})}},[]);t.useEffect(()=>{l(h(o.resolvedSettings||m))},[o.resolvedSettings]),t.useEffect(()=>{w().then(e=>{e.account.connected&&S()})},[S]);const I=(e,t)=>{const n=Number(t);!Number.isInteger(n)||n<=0||l(t=>({...t,[e]:n}))};return n.jsxs("div",{className:"space-y-6",children:[n.jsx(A,{notice:C}),n.jsxs("section",{className:"rounded-lg border border-orchid-500/20 bg-bg-deepest p-4 space-y-3",children:[n.jsx("div",{className:"space-y-1",children:n.jsx("div",{className:"text-sm font-semibold text-text-primary",children:"Chaster account"})}),n.jsx("div",{className:"text-sm text-text-secondary",children:c.account.connected?`Connected as ${c.account.username||"your Chaster account"}.`:c.account.last_error||"No Chaster account connected."}),n.jsxs("div",{className:"flex flex-wrap gap-2",children:[n.jsx($,{onClick:async()=>{j(null);const t=window.open("about:blank","agenticdomme-chaster-oauth","width=640,height=760");if(!t)return void j({type:"error",text:"Popup blocked. Allow popups to connect Chaster."});y(!0);const n=new URL(r()).origin;let s=!1,o=null;const a=async e=>{if(!e.data||"agenticdomme:chaster-oauth"!==e.data.type)return;if(e.origin!==n)return;s=!0,c(),y(!1);const t=!!e.data.ok;j({type:t?"success":"error",text:e.data.message||(t?"Chaster connected.":"Failed to connect Chaster.")}),await w(),t&&await S()};function c(){window.removeEventListener("message",a),o&&(clearInterval(o),o=null)}window.addEventListener("message",a),o=setInterval(()=>{t.closed&&!s&&(s=!0,c(),y(!1),j({type:"error",text:"Chaster connection was cancelled."}))},500);try{const{url:n}=await e.getChasterOAuthUrl();t.location.href=n}catch(i){s=!0,c(),t.close(),y(!1),j({type:"error",text:i instanceof Error?i.message:"Failed to start Chaster OAuth."})}},disabled:g,children:c.account.connected?"Reconnect":"Connect Chaster"}),c.account.connected?n.jsx($,{onClick:async()=>{y(!0),j(null);try{await e.disconnectChasterAccount(),p.account={...u},p.lock=null,p.usage=null,p.lastError="",p.consecutiveFailures=0,p.lastRefreshAt=0,f(),x([]),j({type:"success",text:"Disconnected your Chaster account."})}catch(t){j({type:"error",text:t instanceof Error?t.message:"Failed to disconnect Chaster."})}finally{y(!1)}},disabled:g,tone:"danger",children:"Disconnect"}):null,c.account.connected?n.jsx($,{onClick:()=>{S()},disabled:g,children:"Refresh locks"}):null]})]}),n.jsxs("section",{className:"rounded-lg border border-orchid-500/20 bg-bg-deepest p-4 space-y-3",children:[n.jsxs("div",{className:"space-y-1",children:[n.jsx("div",{className:"text-sm font-semibold text-text-primary",children:"Selected lock"}),n.jsx("div",{className:"text-xs text-text-muted",children:"Pick the running lock the AI is allowed to affect."})]}),c.account.connected?0===d.length?n.jsx("div",{className:"text-sm text-text-muted",children:"No active locks returned by Chaster."}):n.jsx("div",{className:"space-y-2",children:d.map(e=>n.jsxs("label",{className:s("flex cursor-pointer items-start gap-3 rounded-lg border px-3 py-3",i.selectedLockId===e.id?"border-orchid-500/40 bg-orchid-500/10":"border-orchid-500/15 bg-bg-deep"),children:[n.jsx("input",{type:"radio",name:"chaster-selected-lock",checked:i.selectedLockId===e.id,onChange:()=>l(t=>({...t,selectedLockId:e.id}))}),n.jsxs("div",{className:"space-y-1 text-sm",children:[n.jsx("div",{className:"font-medium text-text-primary",children:e.title}),n.jsxs("div",{className:"text-xs text-text-secondary",children:[T(e)," • ",e.role||"unknown role"]})]})]},e.id))}):n.jsx("div",{className:"text-sm text-text-muted",children:"Connect Chaster first to load your active locks."})]}),n.jsxs("section",{className:"rounded-lg border border-orchid-500/20 bg-bg-deepest p-4 space-y-1",children:[n.jsx("div",{className:"text-sm font-semibold text-text-primary",children:"Allowed personas"}),n.jsx("div",{className:"text-xs text-text-muted",children:"Use the “Enable by Persona” toggles above to choose which personas can control the lock. The add-time tool is only offered to personas where Chaster is enabled."})]}),n.jsxs("section",{className:"rounded-lg border border-orchid-500/20 bg-bg-deepest p-4 space-y-3",children:[n.jsxs("div",{className:"space-y-1",children:[n.jsx("div",{className:"text-sm font-semibold text-text-primary",children:"AI tool limits (advanced)"}),n.jsx("div",{className:"text-xs text-text-muted",children:"The AI sees only one unit. Backend enforces all three caps."})]}),n.jsxs("div",{className:"grid gap-3 md:grid-cols-4",children:[n.jsxs("label",{className:"space-y-1 text-sm text-text-secondary",children:[n.jsx("div",{className:"text-xs uppercase tracking-wide text-text-muted",children:"Unit"}),n.jsxs("select",{value:i.toolUnit,onChange:e=>l(t=>({...t,toolUnit:e.target.value})),className:"w-full rounded-md border border-orchid-500/20 bg-bg-deep px-3 py-2 text-sm text-text-primary",children:[n.jsx("option",{value:"seconds",children:"seconds"}),n.jsx("option",{value:"minutes",children:"minutes"}),n.jsx("option",{value:"hours",children:"hours"})]})]}),n.jsxs("label",{className:"space-y-1 text-sm text-text-secondary",children:[n.jsx("div",{className:"text-xs uppercase tracking-wide text-text-muted",children:"Max per call"}),n.jsx("input",{type:"number",min:1,step:1,value:i.maxPerCall,onChange:e=>I("maxPerCall",e.target.value),className:"w-full rounded-md border border-orchid-500/20 bg-bg-deep px-3 py-2 text-sm text-text-primary"})]}),n.jsxs("label",{className:"space-y-1 text-sm text-text-secondary",children:[n.jsx("div",{className:"text-xs uppercase tracking-wide text-text-muted",children:"Max per hour"}),n.jsx("input",{type:"number",min:1,step:1,value:i.maxPerHour,onCh
1ange:e=>I("maxPerHour",e.target.value),className:"w-full rounded-md border border-orchid-500/20 bg-bg-deep px-3 py-2 text-sm text-text-primary"})]}),n.jsxs("label",{className:"space-y-1 text-sm text-text-secondary",children:[n.jsx("div",{className:"text-xs uppercase tracking-wide text-text-muted",children:"Max per day"}),n.jsx("input",{type:"number",min:1,step:1,value:i.maxPerDay,onChange:e=>I("maxPerDay",e.target.value),className:"w-full rounded-md border border-orchid-500/20 bg-bg-deep px-3 py-2 text-sm text-text-primary"})]})]})]}),n.jsxs("div",{className:"flex flex-wrap gap-2",children:[n.jsx($,{onClick:async()=>{y(!0),j(null);try{const e=h(i);await a(e),v(e),await w(),j({type:"success",text:"Saved Chaster settings."})}catch(e){j({type:"error",text:e instanceof Error?e.message:"Failed to save settings."})}finally{y(!1)}},disabled:g,children:g?"Saving…":"Save settings"}),n.jsx($,{onClick:()=>{w()},disabled:g,children:"Refresh status"})]})]})},StatusComponent:function(e){const s=t.useSyncExternalStore(k,b,b);return n.jsxs("div",{className:"space-y-3 text-sm text-text-secondary",children:[n.jsxs("div",{className:"space-y-1",children:[n.jsx("div",{className:"font-medium text-text-primary",children:s.account.connected?"Connected to Chaster":"Chaster not connected"}),n.jsx("div",{className:"text-xs text-text-muted",children:s.account.connected?s.account.username?`Account: ${s.account.username}`:"Account connected":s.account.last_error||"Open Settings to connect your Chaster account."})]}),s.lock?n.jsxs("div",{className:"rounded-lg border border-orchid-500/20 bg-bg-deep p-3",children:[n.jsx("div",{className:"font-medium text-text-primary",children:s.lock.title}),n.jsxs("div",{className:"mt-1 text-xs text-text-secondary",children:["Remaining: ",s.lock.remainingLabel]}),n.jsxs("div",{className:"mt-1 text-xs text-text-muted",children:["Role: ",s.lock.role||"unknown"]})]}):null]})},FooterComponent:function(){const e=t.useSyncExternalStore(k,b,b);if(!e.account.connected)return null;if(!e.lock)return null;const r="unlocked"!==e.lock.status,c=r?o:a,i=e.lock.timeHidden?"Time hidden":r?d(e.lock.remainingSeconds):"Unlocked";return n.jsxs("div",{title:`${e.lock.title} · ${e.lock.remainingLabel}`,className:s("flex shrink-0 items-center gap-1.5 border px-3 py-1.5 text-xs",r?"border-orchid-500/30 bg-orchid-500/10 text-orchid-100":"border-[rgb(var(--color-border)/0.08)] bg-[var(--bg-raised)] text-text-muted"),children:[n.jsx(c,{className:"h-3.5 w-3.5"}),n.jsx("span",{className:"text-text-tertiary",children:"Locked"}),n.jsx("span",{className:"font-medium text-text-primary",children:i})]})}},useExtension:function(){const e=t.useSyncExternalStore(k,b,b),n=i(e=>e.currentPersonaId),s=c(e=>e.isAuthenticated);t.useEffect(()=>{if(s)return E(),()=>{L()}},[s]),t.useEffect(()=>{s&&w()},[s,e.account.connected,e.settings.selectedLockId]),t.useEffect(()=>{if(!s||!n)return;let e=!1;return l.ensure(D,n,{onUpdate:t=>{if(e)return;v(t?.runtime?.resolved_settings||t?.global_settings||{})}}).then(t=>{if(e||!t)return;v(t.runtime?.resolved_settings||t.global_settings||{}),w()}).catch(e=>console.error("[Chaster] Failed to load extension state:",e)),()=>{e=!0}},[s,n]);const r=t.useMemo(()=>function(e){return e.loading?{color:"yellow",label:"Refreshing",description:"Checking Chaster status."}:e.lastError?{color:"red",label:"Needs attention",description:e.lastError}:e.account.connected?e.lock?{color:"green",label:e.lock.timeHidden?"Locked":d(e.lock.remainingSeconds),description:e.lock.title}:{color:"yellow",label:"Select a lock",description:"Account connected; pick an active lock."}:{color:"white",label:"invalid"===e.account.status?"Reconnect Chaster":"Not connected",description:e.account.last_error||"Open settings to connect Chaster."}}(e),[e]);return{isInstalled:!1,isAvailable:!0,isEnabled:e.account.connected,isActive:e.account.connected&&!!e.lock,statusIndicator:r,globalSettings:e.settings,personaSettings:{},resolvedSettings:e.settings,promptState:void 0,enable:async()=>{},disable:async()=>{},updateGlobalSettings:async e=>{v(e)},updatePersonaSettings:async()=>{},updateSettings:async e=>{v(e)}}},getTools:()=>{const e=b();return e.account.connected&&e.lock?[(t=e.settings,{type:"function",function:{name:U,description:M(t),parameters:{type:"object",properties:{amount:{type:"integer",minimum:1,description:`How many ${t.toolUnit} to add to the user's chastity lock.`}},required:["amount"]}},displayLabels:{pending:"Adding time to the lock…",success:"Added time to the lock",error:"Couldn't add time to the lock"}})]:[];var t},getPromptContributions:e=>{v(h(e.extensionState.resolvedSettings));return function(e,t){const n=b(),s=h(e.extensionState.resolvedSettings||n.settings);if(!n.account.connected||!n.lock)return[];if(n.lock.timeHidden||null===n.lock.remainingSeconds)return[];const r=d(n.lock.remainingSeconds),o=t?.trim()||"The user",a=s.toolUnit;return[{id:"chaster-context",placement:"system_pre",priority:10,text:[`${o} is in chastity for ${r} more.`,`You can add up to ${s.maxPerCall} ${a} at a time, ${s.maxPerHour} ${a} per hour, and ${s.maxPerDay} ${a} per day.`,`Call the add_time_to_chastity tool in ${a}
1 only. Amounts must be positive integers.`].join(" ")},{id:"chaster-tool-guidance",placement:"tool_guidance",priority:20,text:"Only use add_time_to_chastity when adding time clearly serves the scene and stays within the configured caps."}]}(e,c.getState().user?.username||null)},executeTool:async(t,n,s)=>{if(t!==U)throw new Error(`Unknown Chaster tool: ${t}`);if(!s.personaId)throw new Error("Chaster requires an active persona for tool execution.");const r=b(),o=r.settings;if(!r.account.connected)throw new Error("Chaster account is not connected.");if(!o.selectedLockId)throw new Error("No Chaster lock is selected.");const a=Number(n?.amount);if(!Number.isInteger(a)||a<=0)throw new Error("The Chaster tool requires a positive integer amount.");const c=await e.addTimeToChasterLock({lockId:o.selectedLockId,personaId:s.personaId,amount:a,unit:o.toolUnit});var i,l,d;return i=c.rollingWindowUsageSeconds,l=c.dailyUsageSeconds,p.usage={hourSeconds:i,daySeconds:l,updatedAt:Date.now()},f(),c.lock&&(d=c.lock,p.lock=d,p.consecutiveFailures=0,f()),{ok:!0,amountSeconds:c.amountSeconds,rollingWindowUsageSeconds:c.rollingWindowUsageSeconds,dailyUsageSeconds:c.dailyUsageSeconds,remainingLabel:c.lock?.remainingLabel||null}}};export{_ as chasterExtension,_ as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.