fuli-context 0.12.0 → 0.12.2
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/README.md +14 -6
- package/README.zh-CN.md +9 -4
- package/dist/web/assets/{AboutPage-BAD0iPVX.js → AboutPage-Dized8Uz.js} +1 -1
- package/dist/web/assets/{AgentConversations-1iGTd4sz.js → AgentConversations-Ccy41mEA.js} +1 -1
- package/dist/web/assets/{AgentHand-D_RafKOM.js → AgentHand-UzVhbKUC.js} +1 -1
- package/dist/web/assets/{AgentName-B5LKQ09q.js → AgentName-DJpvkub2.js} +1 -1
- package/dist/web/assets/AgentProfilePage-CFViQ8kj.js +1 -0
- package/dist/web/assets/AgentsDirectoryPage-CBFTg_IE.js +1 -0
- package/dist/web/assets/AgentsDirectoryPage-Cv-vxw2C.css +1 -0
- package/dist/web/assets/{ConnectionsPage-Tr2rRVOZ.js → ConnectionsPage-uXcabab_.js} +1 -1
- package/dist/web/assets/EmployeeRecruitDialog-D8Hvhc-M.js +1 -0
- package/dist/web/assets/EmployeeWorkbenchPage-TBl_HNj6.js +3 -0
- package/dist/web/assets/KnowledgeEditDialog-HmiqLC-Y.js +1 -0
- package/dist/web/assets/KnowledgeInspector-Cj2yK4Qh.js +1 -0
- package/dist/web/assets/KnowledgeOrganizerPage-DT3BROZm.js +1 -0
- package/dist/web/assets/KnowledgePage-C4J4VueL.js +1 -0
- package/dist/web/assets/KnowledgeWorkspace-DA_dqVRG.js +4 -0
- package/dist/web/assets/{NotFoundPage-fetSnp0N.js → NotFoundPage-x_Yd59mm.js} +1 -1
- package/dist/web/assets/{OverviewPage-BD4yY2Xz.js → OverviewPage-3eZjQ26v.js} +1 -1
- package/dist/web/assets/OverviewPage-8LBN8Shi.css +1 -0
- package/dist/web/assets/PersonalProfilePage-CDQk096L.js +1 -0
- package/dist/web/assets/PersonalProjectsPage-CJxp4Wyz.js +1 -0
- package/dist/web/assets/{ProjectAgentFirstTask-BcxqmKXQ.js → ProjectAgentFirstTask-BkRJ0zwO.js} +1 -1
- package/dist/web/assets/{ProjectAgentsPage-BWDJBESb.js → ProjectAgentsPage-BuNNqSEy.js} +8 -8
- package/dist/web/assets/{ProjectScopePicker-yodM7lF_.js → ProjectScopePicker-CiDxM2Yx.js} +1 -1
- package/dist/web/assets/PublicProjectsPage-ByOT559r.js +1 -0
- package/dist/web/assets/{ReviewPage-Cy0Rt4CO.js → ReviewPage-C0Vdr9uq.js} +1 -1
- package/dist/web/assets/RoundtablesPage-Drou-B81.css +1 -0
- package/dist/web/assets/RoundtablesPage-L3ShEWS3.js +1 -0
- package/dist/web/assets/SettingsPage-BE8pWbI6.css +1 -0
- package/dist/web/assets/SettingsPage-McYuinGz.js +1 -0
- package/dist/web/assets/{SharedJefaReportPage-C56kPciB.js → SharedJefaReportPage-Bg6lIk3E.js} +1 -1
- package/dist/web/assets/UiButton-x8hiHNRM.js +1 -0
- package/dist/web/assets/UiDialog-mjletK0y.js +1 -0
- package/dist/web/assets/{UiDisclosure-D0iMTplF.js → UiDisclosure-_IxeiexW.js} +1 -1
- package/dist/web/assets/{UiSegmented-DIJW6wv3.js → UiSegmented-WFfz9Evl.js} +1 -1
- package/dist/web/assets/{UiSelect-CMR0QqF6.js → UiSelect-K29jnV-1.js} +1 -1
- package/dist/web/assets/{WritingTastePage-QgNzssfF.js → WritingTastePage-DCULB-d2.js} +1 -1
- package/dist/web/assets/agent-pins-DS4mNsNt.js +1 -0
- package/dist/web/assets/agent-profile-Bh3MJGvb.css +1 -0
- package/dist/web/assets/{attention-store-B1DI8wmd.js → attention-store-CA5y8j1R.js} +1 -1
- package/dist/web/assets/catalog-D0VEfOAV.js +1 -0
- package/dist/web/assets/{client-CR-W5Wzp.js → client-DnwnUBQV.js} +1 -1
- package/dist/web/assets/{console-D7GHOMEC.js → console-Cw7TzOSC.js} +1 -1
- package/dist/web/assets/conversation-launcher-settings-Yc13viwr.js +1 -0
- package/dist/web/assets/{i18n-CVFhT_k7.js → i18n-oJFlt8hW.js} +3 -3
- package/dist/web/assets/{identity-CM6Dmy00.js → identity-DSGS4CZc.js} +1 -1
- package/dist/web/assets/index-BfHCcUL2.css +1 -0
- package/dist/web/assets/index-CxNER7Oo.js +5 -0
- package/dist/web/assets/{judgment-types-CJBEyJs1.js → judgment-types-DR931cZ7.js} +1 -1
- package/dist/web/assets/{model-WFhQZ3v_.js → model-BJ-UF4cs.js} +1 -1
- package/dist/web/assets/{personal-profile-graph-BwCh2M9G.js → personal-profile-graph-SOK0BR0w.js} +1 -1
- package/dist/web/assets/project-team-api-C_0qJk_B.js +1 -0
- package/dist/web/assets/{shared-report-CeIvrL9a.js → shared-report-CiX64ZiD.js} +1 -1
- package/dist/web/assets/useAgentRoster-B84mzZIg.js +1 -0
- package/dist/web/assets/{useApi-CROJJdhE-BYhbjaZB.js → useApi-CROJJdhE-7gt0QyQ5.js} +1 -1
- package/dist/web/assets/{vue-router-DaxrQwX3.js → vue-router-CCvPGaLD.js} +1 -1
- package/dist/web/index.html +15 -14
- package/dist/web/licenses/ant-design-icons.txt +22 -0
- package/docs/agent-conversations-and-collaboration.md +3 -3
- package/docs/agent-roundtable.md +33 -0
- package/docs/client-connections.md +108 -0
- package/docs/employee-agents.md +3 -3
- package/docs/project-agent-memory.md +6 -6
- package/graph-provider/fuli_graph/default_project_lead.py +1 -1
- package/graph-provider/fuli_graph/project_agent_delegations.py +70 -2
- package/graph-provider/fuli_graph/project_agent_memory_routes.py +18 -1
- package/graph-provider/fuli_graph/project_agent_remote_origins.py +154 -0
- package/graph-provider/fuli_graph/project_agent_task_models.py +1 -1
- package/graph-provider/fuli_graph/runtime.py +7 -0
- package/graph-provider/fuli_graph/store_project_agent_context.py +3 -2
- package/graph-provider/fuli_graph/store_project_agent_coordination_policy.py +1 -1
- package/graph-provider/fuli_graph/store_project_agent_task_reads.py +1 -1
- package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +5 -5
- package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +2 -2
- package/graph-provider/fuli_graph/store_project_agent_tasks.py +2 -2
- package/graph-provider/fuli_graph/store_project_agents.py +6 -6
- package/graph-provider/fuli_graph/system_agents.py +12 -2
- package/graph-provider/fuli_graph/system_hr_identity.py +2 -2
- package/graph-provider/pyproject.toml +2 -1
- package/npm-shrinkwrap.json +280 -5
- package/package.json +6 -2
- package/skills/operating-fuli/SKILL.md +3 -3
- package/src/agent-peer/coordinator-http.js +117 -0
- package/src/agent-peer/coordinator-service.js +258 -0
- package/src/agent-peer/coordinator-store.js +95 -0
- package/src/agent-peer/device-identity.js +70 -0
- package/src/agent-peer/http.js +47 -0
- package/src/agent-peer/node-store.js +127 -0
- package/src/agent-peer/origin-proof.js +56 -0
- package/src/agent-peer/peer-port.js +140 -0
- package/src/agent-peer/peer-runtime.js +298 -0
- package/src/agent-peer/peer-transport.js +78 -0
- package/src/agent-peer/protocol.js +161 -0
- package/src/agent-peer/runner.js +251 -0
- package/src/agent-roundtable/http.js +17 -3
- package/src/agent-roundtable/service.js +272 -43
- package/src/agent-roundtable/tools.js +15 -1
- package/src/agent-roundtable/wake.js +12 -3
- package/src/agent-tools/graph-definitions.js +14 -5
- package/src/agent-tools/graph-handlers.js +1 -0
- package/src/agent-tools/interface-catalog.js +10 -1
- package/src/agent-tools/project-agent-definitions.js +1 -1
- package/src/agents/identity-receipt.js +1 -1
- package/src/cli/command-registry.js +3 -0
- package/src/cli/connect-command.js +31 -0
- package/src/cli/mcp-command.js +101 -0
- package/src/cli/peer-command.js +100 -0
- package/src/cli/setup-agent-selection.js +2 -2
- package/src/cli/setup-command.js +12 -5
- package/src/cli.js +16 -0
- package/src/employees/catalog/bole.json +2 -2
- package/src/graphiti/federated-application.js +4 -1
- package/src/graphiti/project-agent-control-plane.js +7 -0
- package/src/graphiti/project-agent-task-entry.js +4 -4
- package/src/graphiti/project-agent-team-context.js +16 -18
- package/src/graphiti/project-team-view.js +82 -0
- package/src/graphiti/provider-client.js +9 -0
- package/src/graphiti/task-entry-preferences.js +1 -1
- package/src/http/api-router.js +10 -1
- package/src/http/graph-api-router.js +7 -0
- package/src/mcp/runtime.js +2 -1
- package/src/mcp/tool-annotations.js +4 -3
- package/src/mcp/tool-profiles.js +36 -0
- package/src/mcp-server.js +2 -100
- package/src/server.js +14 -2
- package/src/setup/agent-installation-status.js +5 -3
- package/src/setup/agents.js +23 -3
- package/src/setup/claude-desktop-config.js +60 -0
- package/src/setup/client-connection.js +25 -0
- package/src/setup/paths.js +3 -1
- package/src/setup/setup.js +1 -1
- package/src/setup/stable-package-root.js +29 -0
- package/src/system/system-service.js +5 -0
- package/dist/web/assets/AgentProfilePage-CioOdkBM.js +0 -1
- package/dist/web/assets/AgentsDirectoryPage--1A9nvNA.js +0 -1
- package/dist/web/assets/AgentsDirectoryPage-C7OUQH9v.css +0 -1
- package/dist/web/assets/EmployeeRecruitDialog-1QevD4Qv.js +0 -1
- package/dist/web/assets/EmployeeWorkbenchPage-B0vQIgwA.js +0 -3
- package/dist/web/assets/KnowledgeEditDialog-ClnrfPZi.js +0 -1
- package/dist/web/assets/KnowledgeInspector-Te1hJZbx.js +0 -1
- package/dist/web/assets/KnowledgeOrganizerPage-CCCrWl6Y.js +0 -1
- package/dist/web/assets/KnowledgePage-DGOcBwr8.js +0 -1
- package/dist/web/assets/KnowledgeWorkspace-cKn1NCRe.js +0 -4
- package/dist/web/assets/OverviewPage-By-fUzSG.css +0 -1
- package/dist/web/assets/PersonalProfilePage-DGJVP_VB.js +0 -1
- package/dist/web/assets/PersonalProjectsPage-D25HYMgD.js +0 -1
- package/dist/web/assets/PublicProjectsPage-CyNxVzW3.js +0 -1
- package/dist/web/assets/RoundtablesPage-BjVhvwMc.js +0 -1
- package/dist/web/assets/RoundtablesPage-Cb0R4GaM.css +0 -1
- package/dist/web/assets/SettingsPage-CCZqZtnH.js +0 -1
- package/dist/web/assets/SettingsPage-DYz5bTwa.css +0 -1
- package/dist/web/assets/UiDialog-CvDxg3B1.js +0 -1
- package/dist/web/assets/agent-pins-BcJ_qr8n.js +0 -1
- package/dist/web/assets/agent-profile-BZj3ezWe.css +0 -1
- package/dist/web/assets/catalog-DbXv0_bR.js +0 -1
- package/dist/web/assets/conversation-launcher-settings-Dj2GMzCI.js +0 -1
- package/dist/web/assets/index-CJ6Jmok9.css +0 -1
- package/dist/web/assets/index-CRa3GnYi.js +0 -5
- package/dist/web/assets/useAgentRoster-DCArHlxK.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{$ as e,B as t,D as n,E as r,F as i,Q as a,X as o,et as s,j as c,k as l,rt as u,v as d}from"./i18n-CVFhT_k7.js";import{a as f,c as p,d as m,f as h,g,i as _,l as v,n as y,o as b,p as ee,r as x,s as S,t as C,u as w}from"./useApi-CROJJdhE-BYhbjaZB.js";var T=typeof document<`u`,E=/#/g,te=/&/g,ne=/\//g,re=/=/g,D=/\?/g,O=/\+/g,ie=/%5B/g,k=/%5D/g,ae=/%5E/g,oe=/%60/g,A=/%7B/g,se=/%7C/g,j=/%7D/g,M=/%20/g;function N(e){return e==null?``:encodeURI(``+e).replace(se,`|`).replace(ie,`[`).replace(k,`]`)}function ce(e){return N(e).replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function P(e){return N(e).replace(O,`%2B`).replace(M,`+`).replace(E,`%23`).replace(te,`%26`).replace(oe,"`").replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function F(e){return P(e).replace(re,`%3D`)}function le(e){return N(e).replace(E,`%23`).replace(D,`%3F`)}function ue(e){return le(e).replace(ne,`%2F`)}function I(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var L=/\/$/,R=e=>e.replace(L,``);function z(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=G(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:I(o)}}function de(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function B(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function fe(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&V(t.matched[r],n.matched[i])&&H(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function V(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function H(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!U(e[n],t[n]))return!1;return!0}function U(e,t){return _(e)?W(e,t):_(t)?W(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function W(e,t){return _(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function G(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o<r.length;o++)if(s=r[o],s!==`.`)if(s===`..`)a>1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var K={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function q(e){if(!e)if(T){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),R(e)}var J=/^[^#]+#/;function Y(e,t){return e.replace(J,`#`)+t}function X(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var Z=()=>({left:window.scrollX,top:window.scrollY});function pe(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=X(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function me(e,t){return(history.state?history.state.position-t:-1)+e}var he=new Map;function ge(e,t){he.set(e,t)}function _e(e){let t=he.get(e);return he.delete(e),t}function ve(e){return typeof e==`string`||e&&typeof e==`object`}function ye(e){return typeof e==`string`||typeof e==`symbol`}function be(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;e<n.length;++e){let r=n[e].replace(O,` `),i=r.indexOf(`=`),a=I(i<0?r:r.slice(0,i)),o=i<0?null:I(r.slice(i+1));if(a in t){let e=t[a];_(e)||(e=t[a]=[e]),e.push(o)}else t[a]=o}return t}function xe(e){let t=``;for(let n in e){let r=e[n];if(n=F(n),r==null){r!==void 0&&(t+=(t.length?`&`:``)+n);continue}(_(r)?r.map(e=>e&&P(e)):[r&&P(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function Se(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=_(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function Q(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function $(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(x(4,{from:n,to:t})):e instanceof Error?c(e):ve(e)?c(x(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function Ce(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(S(s)){let c=(s.__vccOpts||s)[t];c&&a.push($(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=f(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&$(c,n,r,o,e,i)()}))}}return a}function we(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o<a;o++){let a=t.matched[o];a&&(e.matched.find(e=>V(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>V(e,s))||i.push(s))}return[n,r,i]}var Te=()=>location.protocol+`//`+location.host;function Ee(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),B(n,``)}return B(n,e)+r+i}function De(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=Ee(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(y({},e.state,{scroll:Z()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function Oe(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?Z():null}}function ke(e){let{history:t,location:n}=window,r={value:Ee(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:Te()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,y({},t.state,Oe(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=y({},i.value,t.state,{forward:e,scroll:Z()});a(o.current,o,!0),a(e,y({},Oe(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function Ae(e){e=q(e);let t=ke(e),n=De(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=y({location:``,base:e,go:r,createHref:Y.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}var je={type:0,value:``},Me=/[a-zA-Z0-9_]/;function Ne(e){if(!e)return[[]];if(e===`/`)return[[je]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;s<e.length;)switch(c=e[s++],n){case 0:c===`\\`?(r=n,n=4):c===`/`?(l&&d(),o()):c===`:`?(d(),n=1):f();break;case 4:f(),n=r;break;case 1:c===`(`?n=2:Me.test(c)?f():(d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--);break;case 2:c===`)`?u[u.length-1]==`\\`?u=u.slice(0,-1)+c:n=3:u+=c;break;case 3:d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--,u=``;break;default:t(`Unknown state`);break}return n===2&&t(`Unfinished custom RegExp for param "${l}"`),d(),o(),i}var Pe=`[^/]+?`,Fe={sensitive:!1,strict:!1,start:!0,end:!0},Ie=/[.+*?^${}()[\]/\\]/g;function Le(e,t){let n=y({},Fe,t),r=[],i=n.start?`^`:``,a=[];for(let t of e){let e=t.length?[]:[90];n.strict&&!t.length&&(i+=`/`);for(let r=0;r<t.length;r++){let o=t[r],s=40+(n.sensitive?.25:0);if(o.type===0)r||(i+=`/`),i+=o.value.replace(Ie,`\\$&`),s+=40;else if(o.type===1){let{value:e,repeatable:n,optional:c,regexp:l}=o;a.push({name:e,repeatable:n,optional:c});let u=l||Pe;if(u!==Pe){s+=10;try{RegExp(`(${u})`)}catch(t){throw Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let d=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(d=c&&t.length<2?`(?:/${d})`:`/`+d),c&&(d+=`?`),i+=d,s+=20,c&&(s+=-8),n&&(s+=-20),u===`.*`&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){let e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(i+=`/?`),n.end?i+=`$`:n.strict&&!i.endsWith(`/`)&&(i+=`(?:/|$)`);let o=new RegExp(i,n.sensitive?``:`i`);function s(e){let t=e.match(o),n={};if(!t)return null;for(let e=1;e<t.length;e++){let r=t[e]||``,i=a[e-1];n[i.name]=r&&i.repeatable?r.split(`/`):r}return n}function c(t){let n=``,r=!1;for(let i of e){(!r||!n.endsWith(`/`))&&(n+=`/`),r=!1;for(let e of i)if(e.type===0)n+=e.value;else if(e.type===1){let{value:a,repeatable:o,optional:s}=e,c=a in t?t[a]:``;if(_(c)&&!o)throw Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);let l=_(c)?c.join(`/`):c;if(!l)if(s)i.length<2&&(n.endsWith(`/`)?n=n.slice(0,-1):r=!0);else throw Error(`Missing required param "${a}"`);n+=l}}return n||`/`}return{re:o,score:r,keys:a,parse:s,stringify:c}}function Re(e,t){let n=0;for(;n<e.length&&n<t.length;){let r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?e.length===1&&e[0]===80?-1:1:e.length>t.length?t.length===1&&t[0]===80?1:-1:0}function ze(e,t){let n=0,r=e.score,i=t.score;for(;n<r.length&&n<i.length;){let e=Re(r[n],i[n]);if(e)return e;n++}if(Math.abs(i.length-r.length)===1){if(Be(r))return 1;if(Be(i))return-1}return i.length-r.length}function Be(e){let t=e[e.length-1];return e.length>0&&t[t.length-1]<0}var Ve={strict:!1,end:!0,sensitive:!1};function He(e,t,n){let r=y(Le(Ne(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function Ue(e,t){let n=[],r=new Map;t=v(Ve,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=Ge(e);s.aliasOf=r&&r.record;let l=v(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(Ge(y({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=He(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!qe(d)&&o(e.name)),Ze(d)&&c(d),s.children){let e=s.children;for(let t=0;t<e.length;t++)a(e[t],d,r&&r.children[t])}r||=d}return f?()=>{o(f)}:w}function o(e){if(ye(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=Ye(e,n);n.splice(t,0,e),e.record.name&&!qe(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw x(1,{location:e});s=i.record.name,a=y(We(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&We(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw x(1,{location:e,currentLocation:t});s=i.record.name,a=y({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:Je(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function We(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function Ge(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Ke(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Ke(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function qe(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Je(e){return e.reduce((e,t)=>y(e,t.meta),{})}function Ye(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;ze(e,t[i])<0?r=i:n=i+1}let i=Xe(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function Xe(e){let t=e;for(;t=t.parent;)if(Ze(t)&&ze(e,t)===0)return t}function Ze({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Qe(e){let t=l(h),n=l(m),r=d(()=>{let n=u(e.to);return t.resolve(n)}),i=d(()=>{let{matched:e}=r.value,{length:t}=e,i=e[t-1],a=n.matched;if(!i||!a.length)return-1;let o=a.findIndex(V.bind(null,i));if(o>-1)return o;let s=rt(e[t-2]);return t>1&&rt(i)===s&&a[a.length-1].path!==s?a.findIndex(V.bind(null,e[t-2])):o}),a=d(()=>i.value>-1&&nt(n.params,r.value.params)),o=d(()=>i.value>-1&&i.value===n.matched.length-1&&H(n.params,r.value.params));function s(n={}){if(tt(n)){let n=t[u(e.replace)?`replace`:`push`](u(e.to)).catch(w);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:r,href:d(()=>r.value.href),isActive:a,isExactActive:o,navigate:s}}function $e(e){return e.length===1?e[0]:e}var et=r({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:Qe,setup(e,{slots:t}){let r=o(Qe(e)),{options:i}=l(h),a=d(()=>({[it(e.activeClass,i.linkActiveClass,`router-link-active`)]:r.isActive,[it(e.exactActiveClass,i.linkExactActiveClass,`router-link-exact-active`)]:r.isExactActive}));return()=>{let i=t.default&&$e(t.default(r));return e.custom?i:n(`a`,{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},i)}}});function tt(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function nt(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!_(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function rt(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var it=(e,t,n)=>e??t??n,at=r({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(e,{attrs:r,slots:o}){let s=l(ee),c=d(()=>e.route||s.value),f=l(g,0),m=d(()=>{let e=u(f),{matched:t}=c.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),h=d(()=>c.value.matched[m.value]);i(g,d(()=>m.value+1)),i(p,h),i(ee,c);let _=a();return t(()=>[_.value,h.value,e.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!V(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let t=c.value,i=e.name,a=h.value,s=a&&a.components[i];if(!s)return ot(o.default,{Component:s,route:t});let l=a.props[i],u=n(s,y({},l?l===!0?t.params:typeof l==`function`?l(t):l:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(a.instances[i]=null)},ref:_}));return ot(o.default,{Component:u,route:t})||u}}});function ot(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var st=at;function ct(t){let n=Ue(t.routes,t),r=t.parseQuery||be,i=t.stringifyQuery||xe,a=t.history,o=Q(),l=Q(),d=Q(),f=s(K),p=K;T&&t.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let g=C.bind(null,e=>``+e),v=C.bind(null,ue),S=C.bind(null,I);function E(e,t){let r,i;return ye(e)?(r=n.getRecordMatcher(e),i=t):i=e,n.addRoute(i,r)}function te(e){let t=n.getRecordMatcher(e);t&&n.removeRoute(t)}function ne(){return n.getRoutes().map(e=>e.record)}function re(e){return!!n.getRecordMatcher(e)}function D(e,t){if(t=y({},t||f.value),typeof e==`string`){let i=z(r,e,t.path),o=n.resolve({path:i.path},t),s=a.createHref(i.fullPath);return y(i,o,{params:S(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=y({},e,{path:z(r,e.path,t.path).path});else{let n=y({},e.params);for(let e in n)n[e]??delete n[e];o=y({},e,{params:v(n)}),t.params=v(t.params)}let s=n.resolve(o,t),c=e.hash||``;s.params=g(S(s.params));let l=de(i,y({},e,{hash:ce(c),path:s.path})),u=a.createHref(l);return y({fullPath:l,hash:c,query:i===xe?Se(e.query):e.query||{}},s,{redirectedFrom:void 0,href:u})}function O(e){return typeof e==`string`?z(r,e,f.value.path):y({},e)}function ie(e,t){if(p!==e)return x(8,{from:t,to:e})}function k(e){return A(e)}function ae(e){return k(y(O(e),{replace:!0}))}function oe(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=O(i):{path:i},i.params={}),y({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function A(e,t){let n=p=D(e),r=f.value,a=e.state,o=e.force,s=e.replace===!0,c=oe(n,r);if(c)return A(y(O(c),{state:typeof c==`object`?y({},a,c.state):a,force:o,replace:s}),t||n);let l=n;l.redirectedFrom=t;let u;return!o&&fe(i,r,n)&&(u=x(16,{to:l,from:r}),W(r,r,!0,!1)),(u?Promise.resolve(u):M(l,r)).catch(e=>b(e)?b(e,2)?e:U(e):V(e,l,r)).then(e=>{if(e){if(b(e,2))return A(y({replace:s},O(e.to),{state:typeof e.to==`object`?y({},a,e.to.state):a,force:o}),t||l)}else e=P(l,r,!0,s,a);return N(l,r,e),e})}function se(e,t){let n=ie(e,t);return n?Promise.reject(n):Promise.resolve()}function j(e){let t=J.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function M(e,t){let n,[r,i,a]=we(e,t);n=Ce(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push($(r,e,t))});let s=se.bind(null,e,t);return n.push(s),X(n).then(()=>{n=[];for(let r of o.list())n.push($(r,e,t));return n.push(s),X(n)}).then(()=>{n=Ce(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push($(r,e,t))});return n.push(s),X(n)}).then(()=>{n=[];for(let r of a)if(r.beforeEnter)if(_(r.beforeEnter))for(let i of r.beforeEnter)n.push($(i,e,t));else n.push($(r.beforeEnter,e,t));return n.push(s),X(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Ce(a,`beforeRouteEnter`,e,t,j),n.push(s),X(n))).then(()=>{n=[];for(let r of l.list())n.push($(r,e,t));return n.push(s),X(n)}).catch(e=>b(e,8)?e:Promise.reject(e))}function N(e,t,n){d.list().forEach(r=>j(()=>r(e,t,n)))}function P(e,t,n,r,i){let o=ie(e,t);if(o)return o;let s=t===K,c=T?history.state:{};n&&(r||s?a.replace(e.fullPath,y({scroll:s&&c&&c.scroll},i)):a.push(e.fullPath,i)),f.value=e,W(e,t,n,s),U()}let F;function le(){F||=a.listen((e,t,n)=>{if(!Y.listening)return;let r=D(e),i=oe(r,Y.currentRoute.value);if(i){A(y(i,{replace:!0,force:!0}),r).catch(w);return}p=r;let o=f.value;T&&ge(me(o.fullPath,n.delta),Z()),M(r,o).catch(e=>b(e,12)?e:b(e,2)?(A(y(O(e.to),{force:!0}),r).then(e=>{b(e,20)&&!n.delta&&n.type===`pop`&&a.go(-1,!1)}).catch(w),Promise.reject()):(n.delta&&a.go(-n.delta,!1),V(e,r,o))).then(e=>{e||=P(r,o,!1),e&&(n.delta&&!b(e,8)?a.go(-n.delta,!1):n.type===`pop`&&b(e,20)&&a.go(-1,!1)),N(r,o,e)}).catch(w)})}let L=Q(),R=Q(),B;function V(e,t,n){U(e);let r=R.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function H(){return B&&f.value!==K?Promise.resolve():new Promise((e,t)=>{L.add([e,t])})}function U(e){return B||(B=!e,le(),L.list().forEach(([t,n])=>e?n(e):t()),L.reset()),e}function W(e,n,r,i){let{scrollBehavior:a}=t;if(!T||!a)return Promise.resolve();let o=!r&&_e(me(e.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return c().then(()=>a(e,n,o)).then(t=>e===f.value&&t&&pe(t)).catch(t=>e===f.value&&V(t,e,n))}let G=e=>a.go(e),q,J=new Set,Y={currentRoute:f,listening:!0,addRoute:E,removeRoute:te,clearRoutes:n.clearRoutes,hasRoute:re,getRoutes:ne,resolve:D,options:t,push:k,replace:ae,go:G,back:()=>G(-1),forward:()=>G(1),beforeEach:o.add,beforeResolve:l.add,afterEach:d.add,onError:R.add,isReady:H,install(t){t.component(`RouterLink`,et),t.component(`RouterView`,st),t.config.globalProperties.$router=Y,Object.defineProperty(t.config.globalProperties,"$route",{enumerable:!0,get:()=>u(f)}),T&&!q&&f.value===K&&(q=!0,k(a.location).catch(e=>{}));let n={};for(let e in K)Object.defineProperty(n,e,{get:()=>f.value[e],enumerable:!0});t.provide(h,Y),t.provide(m,e(n)),t.provide(ee,f);let r=t.unmount;J.add(t),t.unmount=function(){J.delete(t),J.size<1&&(p=K,F&&F(),F=null,f.value=K,q=!1,B=!1),r()}}};function X(e){return e.reduce((e,t)=>e.then(()=>j(t)),Promise.resolve())}return Y}export{Ae as i,st as n,ct as r,et as t};
|
|
1
|
+
import{$ as e,B as t,D as n,E as r,F as i,Q as a,X as o,et as s,j as c,k as l,rt as u,v as d}from"./i18n-oJFlt8hW.js";import{a as f,c as p,d as m,f as h,g,i as _,l as v,n as y,o as b,p as ee,r as x,s as S,t as C,u as w}from"./useApi-CROJJdhE-7gt0QyQ5.js";var T=typeof document<`u`,E=/#/g,te=/&/g,ne=/\//g,re=/=/g,D=/\?/g,O=/\+/g,ie=/%5B/g,k=/%5D/g,ae=/%5E/g,oe=/%60/g,A=/%7B/g,se=/%7C/g,j=/%7D/g,M=/%20/g;function N(e){return e==null?``:encodeURI(``+e).replace(se,`|`).replace(ie,`[`).replace(k,`]`)}function ce(e){return N(e).replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function P(e){return N(e).replace(O,`%2B`).replace(M,`+`).replace(E,`%23`).replace(te,`%26`).replace(oe,"`").replace(A,`{`).replace(j,`}`).replace(ae,`^`)}function F(e){return P(e).replace(re,`%3D`)}function le(e){return N(e).replace(E,`%23`).replace(D,`%3F`)}function ue(e){return le(e).replace(ne,`%2F`)}function I(e){if(e==null)return null;try{return decodeURIComponent(``+e)}catch{}return``+e}var L=/\/$/,R=e=>e.replace(L,``);function z(e,t,n=`/`){let r,i={},a=``,o=``,s=t.indexOf(`#`),c=t.indexOf(`?`);return c=s>=0&&c>s?-1:c,c>=0&&(r=t.slice(0,c),a=t.slice(c,s>0?s:t.length),i=e(a.slice(1))),s>=0&&(r||=t.slice(0,s),o=t.slice(s,t.length)),r=G(r??t,n),{fullPath:r+a+o,path:r,query:i,hash:I(o)}}function de(e,t){let n=t.query?e(t.query):``;return t.path+(n&&`?`)+n+(t.hash||``)}function B(e,t){return!t||!e.toLowerCase().startsWith(t.toLowerCase())?e:e.slice(t.length)||`/`}function fe(e,t,n){let r=t.matched.length-1,i=n.matched.length-1;return r>-1&&r===i&&V(t.matched[r],n.matched[i])&&H(t.params,n.params)&&e(t.query)===e(n.query)&&t.hash===n.hash}function V(e,t){return(e.aliasOf||e)===(t.aliasOf||t)}function H(e,t){if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n in e)if(!U(e[n],t[n]))return!1;return!0}function U(e,t){return _(e)?W(e,t):_(t)?W(t,e):(e&&e.valueOf())===(t&&t.valueOf())}function W(e,t){return _(t)?e.length===t.length&&e.every((e,n)=>e===t[n]):e.length===1&&e[0]===t}function G(e,t){if(e.startsWith(`/`))return e;if(!e)return t;let n=t.split(`/`),r=e.split(`/`),i=r[r.length-1];(i===`..`||i===`.`)&&r.push(``);let a=n.length-1,o,s;for(o=0;o<r.length;o++)if(s=r[o],s!==`.`)if(s===`..`)a>1&&a--;else break;return n.slice(0,a).join(`/`)+`/`+r.slice(o).join(`/`)}var K={path:`/`,name:void 0,params:{},query:{},hash:``,fullPath:`/`,matched:[],meta:{},redirectedFrom:void 0};function q(e){if(!e)if(T){let t=document.querySelector(`base`);e=t&&t.getAttribute(`href`)||`/`,e=e.replace(/^\w+:\/\/[^/]+/,``)}else e=`/`;return e[0]!==`/`&&e[0]!==`#`&&(e=`/`+e),R(e)}var J=/^[^#]+#/;function Y(e,t){return e.replace(J,`#`)+t}function X(e,t){let n=document.documentElement.getBoundingClientRect(),r=e.getBoundingClientRect();return{behavior:t.behavior,left:r.left-n.left-(t.left||0),top:r.top-n.top-(t.top||0)}}var Z=()=>({left:window.scrollX,top:window.scrollY});function pe(e){let t;if(`el`in e){let n=e.el,r=typeof n==`string`&&n.startsWith(`#`),i=typeof n==`string`?r?document.getElementById(n.slice(1)):document.querySelector(n):n;if(!i)return;t=X(i,e)}else t=e;`scrollBehavior`in document.documentElement.style?window.scrollTo(t):window.scrollTo(t.left==null?window.scrollX:t.left,t.top==null?window.scrollY:t.top)}function me(e,t){return(history.state?history.state.position-t:-1)+e}var he=new Map;function ge(e,t){he.set(e,t)}function _e(e){let t=he.get(e);return he.delete(e),t}function ve(e){return typeof e==`string`||e&&typeof e==`object`}function ye(e){return typeof e==`string`||typeof e==`symbol`}function be(e){let t={};if(e===``||e===`?`)return t;let n=(e[0]===`?`?e.slice(1):e).split(`&`);for(let e=0;e<n.length;++e){let r=n[e].replace(O,` `),i=r.indexOf(`=`),a=I(i<0?r:r.slice(0,i)),o=i<0?null:I(r.slice(i+1));if(a in t){let e=t[a];_(e)||(e=t[a]=[e]),e.push(o)}else t[a]=o}return t}function xe(e){let t=``;for(let n in e){let r=e[n];if(n=F(n),r==null){r!==void 0&&(t+=(t.length?`&`:``)+n);continue}(_(r)?r.map(e=>e&&P(e)):[r&&P(r)]).forEach(e=>{e!==void 0&&(t+=(t.length?`&`:``)+n,e!=null&&(t+=`=`+e))})}return t}function Se(e){let t={};for(let n in e){let r=e[n];r!==void 0&&(t[n]=_(r)?r.map(e=>e==null?null:``+e):r==null?r:``+r)}return t}function Q(){let e=[];function t(t){return e.push(t),()=>{let n=e.indexOf(t);n>-1&&e.splice(n,1)}}function n(){e=[]}return{add:t,list:()=>e.slice(),reset:n}}function $(e,t,n,r,i,a=e=>e()){let o=r&&(r.enterCallbacks[i]=r.enterCallbacks[i]||[]);return()=>new Promise((s,c)=>{let l=e=>{e===!1?c(x(4,{from:n,to:t})):e instanceof Error?c(e):ve(e)?c(x(2,{from:t,to:e})):(o&&r.enterCallbacks[i]===o&&typeof e==`function`&&o.push(e),s())},u=a(()=>e.call(r&&r.instances[i],t,n,l)),d=Promise.resolve(u);e.length<3&&(d=d.then(l)),d.catch(e=>c(e))})}function Ce(e,t,n,r,i=e=>e()){let a=[];for(let o of e)for(let e in o.components){let s=o.components[e];if(!(t!==`beforeRouteEnter`&&!o.instances[e]))if(S(s)){let c=(s.__vccOpts||s)[t];c&&a.push($(c,n,r,o,e,i))}else{let c=s();a.push(()=>c.then(a=>{if(!a)throw Error(`Couldn't resolve component "${e}" at "${o.path}"`);let s=f(a)?a.default:a;o.mods[e]=a,o.components[e]=s;let c=(s.__vccOpts||s)[t];return c&&$(c,n,r,o,e,i)()}))}}return a}function we(e,t){let n=[],r=[],i=[],a=Math.max(t.matched.length,e.matched.length);for(let o=0;o<a;o++){let a=t.matched[o];a&&(e.matched.find(e=>V(e,a))?r.push(a):n.push(a));let s=e.matched[o];s&&(t.matched.find(e=>V(e,s))||i.push(s))}return[n,r,i]}var Te=()=>location.protocol+`//`+location.host;function Ee(e,t){let{pathname:n,search:r,hash:i}=t,a=e.indexOf(`#`);if(a>-1){let t=i.includes(e.slice(a))?e.slice(a).length:1,n=i.slice(t);return n[0]!==`/`&&(n=`/`+n),B(n,``)}return B(n,e)+r+i}function De(e,t,n,r){let i=[],a=[],o=null,s=({state:a})=>{let s=Ee(e,location),c=n.value,l=t.value,u=0;if(a){if(n.value=s,t.value=a,o&&o===c){o=null;return}u=l?a.position-l.position:0}else r(s);i.forEach(e=>{e(n.value,c,{delta:u,type:`pop`,direction:u?u>0?`forward`:`back`:``})})};function c(){o=n.value}function l(e){i.push(e);let t=()=>{let t=i.indexOf(e);t>-1&&i.splice(t,1)};return a.push(t),t}function u(){if(document.visibilityState===`hidden`){let{history:e}=window;if(!e.state)return;e.replaceState(y({},e.state,{scroll:Z()}),``)}}function d(){for(let e of a)e();a=[],window.removeEventListener(`popstate`,s),window.removeEventListener(`pagehide`,u),document.removeEventListener(`visibilitychange`,u)}return window.addEventListener(`popstate`,s),window.addEventListener(`pagehide`,u),document.addEventListener(`visibilitychange`,u),{pauseListeners:c,listen:l,destroy:d}}function Oe(e,t,n,r=!1,i=!1){return{back:e,current:t,forward:n,replaced:r,position:window.history.length,scroll:i?Z():null}}function ke(e){let{history:t,location:n}=window,r={value:Ee(e,n)},i={value:t.state};i.value||a(r.value,{back:null,current:r.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0);function a(r,a,o){let s=e.indexOf(`#`),c=s>-1?(n.host&&document.querySelector(`base`)?e:e.slice(s))+r:Te()+e+r;try{t[o?`replaceState`:`pushState`](a,``,c),i.value=a}catch(e){console.error(e),n[o?`replace`:`assign`](c)}}function o(e,n){a(e,y({},t.state,Oe(i.value.back,e,i.value.forward,!0),n,{position:i.value.position}),!0),r.value=e}function s(e,n){let o=y({},i.value,t.state,{forward:e,scroll:Z()});a(o.current,o,!0),a(e,y({},Oe(r.value,e,null),{position:o.position+1},n),!1),r.value=e}return{location:r,state:i,push:s,replace:o}}function Ae(e){e=q(e);let t=ke(e),n=De(e,t.state,t.location,t.replace);function r(e,t=!0){t||n.pauseListeners(),history.go(e)}let i=y({location:``,base:e,go:r,createHref:Y.bind(null,e)},t,n);return Object.defineProperty(i,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(i,"state",{enumerable:!0,get:()=>t.state.value}),i}var je={type:0,value:``},Me=/[a-zA-Z0-9_]/;function Ne(e){if(!e)return[[]];if(e===`/`)return[[je]];if(!e.startsWith(`/`))throw Error(`Invalid path "${e}"`);function t(e){throw Error(`ERR (${n})/"${l}": ${e}`)}let n=0,r=n,i=[],a;function o(){a&&i.push(a),a=[]}let s=0,c,l=``,u=``;function d(){l&&=(n===0?a.push({type:0,value:l}):n===1||n===2||n===3?(a.length>1&&(c===`*`||c===`+`)&&t(`A repeatable param (${l}) must be alone in its segment. eg: '/:ids+.`),a.push({type:1,value:l,regexp:u,repeatable:c===`*`||c===`+`,optional:c===`*`||c===`?`})):t(`Invalid state to consume buffer`),``)}function f(){l+=c}for(;s<e.length;)switch(c=e[s++],n){case 0:c===`\\`?(r=n,n=4):c===`/`?(l&&d(),o()):c===`:`?(d(),n=1):f();break;case 4:f(),n=r;break;case 1:c===`(`?n=2:Me.test(c)?f():(d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--);break;case 2:c===`)`?u[u.length-1]==`\\`?u=u.slice(0,-1)+c:n=3:u+=c;break;case 3:d(),n=0,c!==`*`&&c!==`?`&&c!==`+`&&s--,u=``;break;default:t(`Unknown state`);break}return n===2&&t(`Unfinished custom RegExp for param "${l}"`),d(),o(),i}var Pe=`[^/]+?`,Fe={sensitive:!1,strict:!1,start:!0,end:!0},Ie=/[.+*?^${}()[\]/\\]/g;function Le(e,t){let n=y({},Fe,t),r=[],i=n.start?`^`:``,a=[];for(let t of e){let e=t.length?[]:[90];n.strict&&!t.length&&(i+=`/`);for(let r=0;r<t.length;r++){let o=t[r],s=40+(n.sensitive?.25:0);if(o.type===0)r||(i+=`/`),i+=o.value.replace(Ie,`\\$&`),s+=40;else if(o.type===1){let{value:e,repeatable:n,optional:c,regexp:l}=o;a.push({name:e,repeatable:n,optional:c});let u=l||Pe;if(u!==Pe){s+=10;try{RegExp(`(${u})`)}catch(t){throw Error(`Invalid custom RegExp for param "${e}" (${u}): `+t.message)}}let d=n?`((?:${u})(?:/(?:${u}))*)`:`(${u})`;r||(d=c&&t.length<2?`(?:/${d})`:`/`+d),c&&(d+=`?`),i+=d,s+=20,c&&(s+=-8),n&&(s+=-20),u===`.*`&&(s+=-50)}e.push(s)}r.push(e)}if(n.strict&&n.end){let e=r.length-1;r[e][r[e].length-1]+=.7000000000000001}n.strict||(i+=`/?`),n.end?i+=`$`:n.strict&&!i.endsWith(`/`)&&(i+=`(?:/|$)`);let o=new RegExp(i,n.sensitive?``:`i`);function s(e){let t=e.match(o),n={};if(!t)return null;for(let e=1;e<t.length;e++){let r=t[e]||``,i=a[e-1];n[i.name]=r&&i.repeatable?r.split(`/`):r}return n}function c(t){let n=``,r=!1;for(let i of e){(!r||!n.endsWith(`/`))&&(n+=`/`),r=!1;for(let e of i)if(e.type===0)n+=e.value;else if(e.type===1){let{value:a,repeatable:o,optional:s}=e,c=a in t?t[a]:``;if(_(c)&&!o)throw Error(`Provided param "${a}" is an array but it is not repeatable (* or + modifiers)`);let l=_(c)?c.join(`/`):c;if(!l)if(s)i.length<2&&(n.endsWith(`/`)?n=n.slice(0,-1):r=!0);else throw Error(`Missing required param "${a}"`);n+=l}}return n||`/`}return{re:o,score:r,keys:a,parse:s,stringify:c}}function Re(e,t){let n=0;for(;n<e.length&&n<t.length;){let r=t[n]-e[n];if(r)return r;n++}return e.length<t.length?e.length===1&&e[0]===80?-1:1:e.length>t.length?t.length===1&&t[0]===80?1:-1:0}function ze(e,t){let n=0,r=e.score,i=t.score;for(;n<r.length&&n<i.length;){let e=Re(r[n],i[n]);if(e)return e;n++}if(Math.abs(i.length-r.length)===1){if(Be(r))return 1;if(Be(i))return-1}return i.length-r.length}function Be(e){let t=e[e.length-1];return e.length>0&&t[t.length-1]<0}var Ve={strict:!1,end:!0,sensitive:!1};function He(e,t,n){let r=y(Le(Ne(e.path),n),{record:e,parent:t,children:[],alias:[]});return t&&!r.record.aliasOf==!t.record.aliasOf&&t.children.push(r),r}function Ue(e,t){let n=[],r=new Map;t=v(Ve,t);function i(e){return r.get(e)}function a(e,n,r){let i=!r,s=Ge(e);s.aliasOf=r&&r.record;let l=v(t,e),u=[s];if(`alias`in e){let t=typeof e.alias==`string`?[e.alias]:e.alias;for(let e of t)u.push(Ge(y({},s,{components:r?r.record.components:s.components,path:e,aliasOf:r?r.record:s})))}let d,f;for(let t of u){let{path:u}=t;if(n&&u[0]!==`/`){let e=n.record.path,r=e[e.length-1]===`/`?``:`/`;t.path=n.record.path+(u&&r+u)}if(d=He(t,n,l),r?r.alias.push(d):(f||=d,f!==d&&f.alias.push(d),i&&e.name&&!qe(d)&&o(e.name)),Ze(d)&&c(d),s.children){let e=s.children;for(let t=0;t<e.length;t++)a(e[t],d,r&&r.children[t])}r||=d}return f?()=>{o(f)}:w}function o(e){if(ye(e)){let t=r.get(e);t&&(r.delete(e),n.splice(n.indexOf(t),1),t.children.forEach(o),t.alias.forEach(o))}else{let t=n.indexOf(e);t>-1&&(n.splice(t,1),e.record.name&&r.delete(e.record.name),e.children.forEach(o),e.alias.forEach(o))}}function s(){return n}function c(e){let t=Ye(e,n);n.splice(t,0,e),e.record.name&&!qe(e)&&r.set(e.record.name,e)}function l(e,t){let i,a={},o,s;if(`name`in e&&e.name){if(i=r.get(e.name),!i)throw x(1,{location:e});s=i.record.name,a=y(We(t.params,i.keys.filter(e=>!e.optional).concat(i.parent?i.parent.keys.filter(e=>e.optional):[]).map(e=>e.name)),e.params&&We(e.params,i.keys.map(e=>e.name))),o=i.stringify(a)}else if(e.path!=null)o=e.path,i=n.find(e=>e.re.test(o)),i&&(a=i.parse(o),s=i.record.name,i.keys.forEach(e=>{e.optional&&!a[e.name]&&delete a[e.name]}));else{if(i=t.name?r.get(t.name):n.find(e=>e.re.test(t.path)),!i)throw x(1,{location:e,currentLocation:t});s=i.record.name,a=y({},t.params,e.params),o=i.stringify(a)}let c=[],l=i;for(;l;)c.unshift(l.record),l=l.parent;return{name:s,path:o,params:a,matched:c,meta:Je(c)}}e.forEach(e=>a(e));function u(){n.length=0,r.clear()}return{addRoute:a,resolve:l,removeRoute:o,clearRoutes:u,getRoutes:s,getRecordMatcher:i}}function We(e,t){let n={};for(let r of t)r in e&&(n[r]=e[r]);return n}function Ge(e){let t={path:e.path,redirect:e.redirect,name:e.name,meta:e.meta||{},aliasOf:e.aliasOf,beforeEnter:e.beforeEnter,props:Ke(e),children:e.children||[],instances:{},leaveGuards:new Set,updateGuards:new Set,enterCallbacks:{},components:`components`in e?e.components||null:e.component&&{default:e.component}};return Object.defineProperty(t,"mods",{value:{}}),t}function Ke(e){let t={},n=e.props||!1;if(`component`in e)t.default=n;else for(let r in e.components)t[r]=typeof n==`object`?n[r]:n;return t}function qe(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function Je(e){return e.reduce((e,t)=>y(e,t.meta),{})}function Ye(e,t){let n=0,r=t.length;for(;n!==r;){let i=n+r>>1;ze(e,t[i])<0?r=i:n=i+1}let i=Xe(e);return i&&(r=t.lastIndexOf(i,r-1)),r}function Xe(e){let t=e;for(;t=t.parent;)if(Ze(t)&&ze(e,t)===0)return t}function Ze({record:e}){return!!(e.name||e.components&&Object.keys(e.components).length||e.redirect)}function Qe(e){let t=l(h),n=l(m),r=d(()=>{let n=u(e.to);return t.resolve(n)}),i=d(()=>{let{matched:e}=r.value,{length:t}=e,i=e[t-1],a=n.matched;if(!i||!a.length)return-1;let o=a.findIndex(V.bind(null,i));if(o>-1)return o;let s=rt(e[t-2]);return t>1&&rt(i)===s&&a[a.length-1].path!==s?a.findIndex(V.bind(null,e[t-2])):o}),a=d(()=>i.value>-1&&nt(n.params,r.value.params)),o=d(()=>i.value>-1&&i.value===n.matched.length-1&&H(n.params,r.value.params));function s(n={}){if(tt(n)){let n=t[u(e.replace)?`replace`:`push`](u(e.to)).catch(w);return e.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>n),n}return Promise.resolve()}return{route:r,href:d(()=>r.value.href),isActive:a,isExactActive:o,navigate:s}}function $e(e){return e.length===1?e[0]:e}var et=r({name:`RouterLink`,compatConfig:{MODE:3},props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:`page`},viewTransition:Boolean},useLink:Qe,setup(e,{slots:t}){let r=o(Qe(e)),{options:i}=l(h),a=d(()=>({[it(e.activeClass,i.linkActiveClass,`router-link-active`)]:r.isActive,[it(e.exactActiveClass,i.linkExactActiveClass,`router-link-exact-active`)]:r.isExactActive}));return()=>{let i=t.default&&$e(t.default(r));return e.custom?i:n(`a`,{"aria-current":r.isExactActive?e.ariaCurrentValue:null,href:r.href,onClick:r.navigate,class:a.value},i)}}});function tt(e){if(!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)&&!e.defaultPrevented&&!(e.button!==void 0&&e.button!==0)){if(e.currentTarget&&e.currentTarget.getAttribute){let t=e.currentTarget.getAttribute(`target`);if(/\b_blank\b/i.test(t))return}return e.preventDefault&&e.preventDefault(),!0}}function nt(e,t){for(let n in t){let r=t[n],i=e[n];if(typeof r==`string`){if(r!==i)return!1}else if(!_(i)||i.length!==r.length||r.some((e,t)=>e.valueOf()!==i[t].valueOf()))return!1}return!0}function rt(e){return e?e.aliasOf?e.aliasOf.path:e.path:``}var it=(e,t,n)=>e??t??n,at=r({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(e,{attrs:r,slots:o}){let s=l(ee),c=d(()=>e.route||s.value),f=l(g,0),m=d(()=>{let e=u(f),{matched:t}=c.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),h=d(()=>c.value.matched[m.value]);i(g,d(()=>m.value+1)),i(p,h),i(ee,c);let _=a();return t(()=>[_.value,h.value,e.name],([e,t,n],[r,i,a])=>{t&&(t.instances[n]=e,i&&i!==t&&e&&e===r&&(t.leaveGuards.size||(t.leaveGuards=i.leaveGuards),t.updateGuards.size||(t.updateGuards=i.updateGuards))),e&&t&&(!i||!V(t,i)||!r)&&(t.enterCallbacks[n]||[]).forEach(t=>t(e))},{flush:`post`}),()=>{let t=c.value,i=e.name,a=h.value,s=a&&a.components[i];if(!s)return ot(o.default,{Component:s,route:t});let l=a.props[i],u=n(s,y({},l?l===!0?t.params:typeof l==`function`?l(t):l:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(a.instances[i]=null)},ref:_}));return ot(o.default,{Component:u,route:t})||u}}});function ot(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var st=at;function ct(t){let n=Ue(t.routes,t),r=t.parseQuery||be,i=t.stringifyQuery||xe,a=t.history,o=Q(),l=Q(),d=Q(),f=s(K),p=K;T&&t.scrollBehavior&&`scrollRestoration`in history&&(history.scrollRestoration=`manual`);let g=C.bind(null,e=>``+e),v=C.bind(null,ue),S=C.bind(null,I);function E(e,t){let r,i;return ye(e)?(r=n.getRecordMatcher(e),i=t):i=e,n.addRoute(i,r)}function te(e){let t=n.getRecordMatcher(e);t&&n.removeRoute(t)}function ne(){return n.getRoutes().map(e=>e.record)}function re(e){return!!n.getRecordMatcher(e)}function D(e,t){if(t=y({},t||f.value),typeof e==`string`){let i=z(r,e,t.path),o=n.resolve({path:i.path},t),s=a.createHref(i.fullPath);return y(i,o,{params:S(o.params),redirectedFrom:void 0,href:s})}let o;if(e.path!=null)o=y({},e,{path:z(r,e.path,t.path).path});else{let n=y({},e.params);for(let e in n)n[e]??delete n[e];o=y({},e,{params:v(n)}),t.params=v(t.params)}let s=n.resolve(o,t),c=e.hash||``;s.params=g(S(s.params));let l=de(i,y({},e,{hash:ce(c),path:s.path})),u=a.createHref(l);return y({fullPath:l,hash:c,query:i===xe?Se(e.query):e.query||{}},s,{redirectedFrom:void 0,href:u})}function O(e){return typeof e==`string`?z(r,e,f.value.path):y({},e)}function ie(e,t){if(p!==e)return x(8,{from:t,to:e})}function k(e){return A(e)}function ae(e){return k(y(O(e),{replace:!0}))}function oe(e,t){let n=e.matched[e.matched.length-1];if(n&&n.redirect){let{redirect:r}=n,i=typeof r==`function`?r(e,t):r;return typeof i==`string`&&(i=i.includes(`?`)||i.includes(`#`)?i=O(i):{path:i},i.params={}),y({query:e.query,hash:e.hash,params:i.path==null?e.params:{}},i)}}function A(e,t){let n=p=D(e),r=f.value,a=e.state,o=e.force,s=e.replace===!0,c=oe(n,r);if(c)return A(y(O(c),{state:typeof c==`object`?y({},a,c.state):a,force:o,replace:s}),t||n);let l=n;l.redirectedFrom=t;let u;return!o&&fe(i,r,n)&&(u=x(16,{to:l,from:r}),W(r,r,!0,!1)),(u?Promise.resolve(u):M(l,r)).catch(e=>b(e)?b(e,2)?e:U(e):V(e,l,r)).then(e=>{if(e){if(b(e,2))return A(y({replace:s},O(e.to),{state:typeof e.to==`object`?y({},a,e.to.state):a,force:o}),t||l)}else e=P(l,r,!0,s,a);return N(l,r,e),e})}function se(e,t){let n=ie(e,t);return n?Promise.reject(n):Promise.resolve()}function j(e){let t=J.values().next().value;return t&&typeof t.runWithContext==`function`?t.runWithContext(e):e()}function M(e,t){let n,[r,i,a]=we(e,t);n=Ce(r.reverse(),`beforeRouteLeave`,e,t);for(let i of r)i.leaveGuards.forEach(r=>{n.push($(r,e,t))});let s=se.bind(null,e,t);return n.push(s),X(n).then(()=>{n=[];for(let r of o.list())n.push($(r,e,t));return n.push(s),X(n)}).then(()=>{n=Ce(i,`beforeRouteUpdate`,e,t);for(let r of i)r.updateGuards.forEach(r=>{n.push($(r,e,t))});return n.push(s),X(n)}).then(()=>{n=[];for(let r of a)if(r.beforeEnter)if(_(r.beforeEnter))for(let i of r.beforeEnter)n.push($(i,e,t));else n.push($(r.beforeEnter,e,t));return n.push(s),X(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Ce(a,`beforeRouteEnter`,e,t,j),n.push(s),X(n))).then(()=>{n=[];for(let r of l.list())n.push($(r,e,t));return n.push(s),X(n)}).catch(e=>b(e,8)?e:Promise.reject(e))}function N(e,t,n){d.list().forEach(r=>j(()=>r(e,t,n)))}function P(e,t,n,r,i){let o=ie(e,t);if(o)return o;let s=t===K,c=T?history.state:{};n&&(r||s?a.replace(e.fullPath,y({scroll:s&&c&&c.scroll},i)):a.push(e.fullPath,i)),f.value=e,W(e,t,n,s),U()}let F;function le(){F||=a.listen((e,t,n)=>{if(!Y.listening)return;let r=D(e),i=oe(r,Y.currentRoute.value);if(i){A(y(i,{replace:!0,force:!0}),r).catch(w);return}p=r;let o=f.value;T&&ge(me(o.fullPath,n.delta),Z()),M(r,o).catch(e=>b(e,12)?e:b(e,2)?(A(y(O(e.to),{force:!0}),r).then(e=>{b(e,20)&&!n.delta&&n.type===`pop`&&a.go(-1,!1)}).catch(w),Promise.reject()):(n.delta&&a.go(-n.delta,!1),V(e,r,o))).then(e=>{e||=P(r,o,!1),e&&(n.delta&&!b(e,8)?a.go(-n.delta,!1):n.type===`pop`&&b(e,20)&&a.go(-1,!1)),N(r,o,e)}).catch(w)})}let L=Q(),R=Q(),B;function V(e,t,n){U(e);let r=R.list();return r.length?r.forEach(r=>r(e,t,n)):console.error(e),Promise.reject(e)}function H(){return B&&f.value!==K?Promise.resolve():new Promise((e,t)=>{L.add([e,t])})}function U(e){return B||(B=!e,le(),L.list().forEach(([t,n])=>e?n(e):t()),L.reset()),e}function W(e,n,r,i){let{scrollBehavior:a}=t;if(!T||!a)return Promise.resolve();let o=!r&&_e(me(e.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return c().then(()=>a(e,n,o)).then(t=>e===f.value&&t&&pe(t)).catch(t=>e===f.value&&V(t,e,n))}let G=e=>a.go(e),q,J=new Set,Y={currentRoute:f,listening:!0,addRoute:E,removeRoute:te,clearRoutes:n.clearRoutes,hasRoute:re,getRoutes:ne,resolve:D,options:t,push:k,replace:ae,go:G,back:()=>G(-1),forward:()=>G(1),beforeEach:o.add,beforeResolve:l.add,afterEach:d.add,onError:R.add,isReady:H,install(t){t.component(`RouterLink`,et),t.component(`RouterView`,st),t.config.globalProperties.$router=Y,Object.defineProperty(t.config.globalProperties,"$route",{enumerable:!0,get:()=>u(f)}),T&&!q&&f.value===K&&(q=!0,k(a.location).catch(e=>{}));let n={};for(let e in K)Object.defineProperty(n,e,{get:()=>f.value[e],enumerable:!0});t.provide(h,Y),t.provide(m,e(n)),t.provide(ee,f);let r=t.unmount;J.add(t),t.unmount=function(){J.delete(t),J.size<1&&(p=K,F&&F(),F=null,f.value=K,q=!1,B=!1),r()}}};function X(e){return e.reduce((e,t)=>e.then(()=>j(t)),Promise.resolve())}return Y}export{Ae as i,st as n,ct as r,et as t};
|
package/dist/web/index.html
CHANGED
|
@@ -9,28 +9,29 @@
|
|
|
9
9
|
/>
|
|
10
10
|
<link rel="icon" type="image/png" href="/assets/fuli-logo-ER1wQ8Kk.png" />
|
|
11
11
|
<title>复利 · Context Graph</title>
|
|
12
|
-
<script type="module" crossorigin src="/assets/index-
|
|
13
|
-
<link rel="modulepreload" crossorigin href="/assets/i18n-
|
|
12
|
+
<script type="module" crossorigin src="/assets/index-CxNER7Oo.js"></script>
|
|
13
|
+
<link rel="modulepreload" crossorigin href="/assets/i18n-oJFlt8hW.js">
|
|
14
14
|
<link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BDNMzG2s.js">
|
|
15
|
-
<link rel="modulepreload" crossorigin href="/assets/client-
|
|
16
|
-
<link rel="modulepreload" crossorigin href="/assets/console-
|
|
17
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
18
|
-
<link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-
|
|
19
|
-
<link rel="modulepreload" crossorigin href="/assets/vue-router-
|
|
15
|
+
<link rel="modulepreload" crossorigin href="/assets/client-DnwnUBQV.js">
|
|
16
|
+
<link rel="modulepreload" crossorigin href="/assets/console-Cw7TzOSC.js">
|
|
17
|
+
<link rel="modulepreload" crossorigin href="/assets/UiButton-x8hiHNRM.js">
|
|
18
|
+
<link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-7gt0QyQ5.js">
|
|
19
|
+
<link rel="modulepreload" crossorigin href="/assets/vue-router-CCvPGaLD.js">
|
|
20
20
|
<link rel="modulepreload" crossorigin href="/assets/fuli-logo-Bu9WBuQe.js">
|
|
21
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
22
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
23
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
24
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
21
|
+
<link rel="modulepreload" crossorigin href="/assets/UiDialog-mjletK0y.js">
|
|
22
|
+
<link rel="modulepreload" crossorigin href="/assets/UiSelect-K29jnV-1.js">
|
|
23
|
+
<link rel="modulepreload" crossorigin href="/assets/attention-store-CA5y8j1R.js">
|
|
24
|
+
<link rel="modulepreload" crossorigin href="/assets/AgentHand-UzVhbKUC.js">
|
|
25
|
+
<link rel="modulepreload" crossorigin href="/assets/UiDisclosure-_IxeiexW.js">
|
|
25
26
|
<link rel="modulepreload" crossorigin href="/assets/profile-model-BQO4zNs9.js">
|
|
26
27
|
<link rel="modulepreload" crossorigin href="/assets/task-evidence-DTiPCs7r.js">
|
|
27
|
-
<link rel="modulepreload" crossorigin href="/assets/useAgentRoster-
|
|
28
|
-
<link rel="modulepreload" crossorigin href="/assets/agent-pins-
|
|
28
|
+
<link rel="modulepreload" crossorigin href="/assets/useAgentRoster-B84mzZIg.js">
|
|
29
|
+
<link rel="modulepreload" crossorigin href="/assets/agent-pins-DS4mNsNt.js">
|
|
29
30
|
<link rel="modulepreload" crossorigin href="/assets/paths-CDREouhi.js">
|
|
30
31
|
<link rel="stylesheet" crossorigin href="/assets/client-CIuQ1icy.css">
|
|
31
32
|
<link rel="stylesheet" crossorigin href="/assets/UiSelect-Bv6R0yr1.css">
|
|
32
33
|
<link rel="stylesheet" crossorigin href="/assets/AgentHand-Y83Oo36U.css">
|
|
33
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
34
|
+
<link rel="stylesheet" crossorigin href="/assets/index-BfHCcUL2.css">
|
|
34
35
|
</head>
|
|
35
36
|
<body>
|
|
36
37
|
<div id="app"></div>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2018-present Ant UED, https://xtech.antfin.com/
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -34,8 +34,8 @@ Neo4j Provider 的独立日志中;工作记忆继续保存经过整理的决
|
|
|
34
34
|
包含稳定 `@{agentId}`、项目 ID 和会话 ID;复制失败时可手动选中。生成的 ID 会编码特殊字符,
|
|
35
35
|
改名不影响接续。这是 FULI 的提示词匹配,不表示 Cursor、Codex 的原生 @ 下拉列表已注册此人。
|
|
36
36
|
|
|
37
|
-
开发者是持久负责人,Jefa/
|
|
38
|
-
隐式记到管理员名下;需要先通过
|
|
37
|
+
开发者是持久负责人,Jefa/AR 是同级协作角色。只有管理员成员的项目不会把开发任务
|
|
38
|
+
隐式记到管理员名下;需要先通过 AR 分配或招聘开发者。显式选中管理员及其本职任务仍可使用。
|
|
39
39
|
收尾将实际员工工具返回的协作回执合并展示,例如“Alex 负责实现;Jefa 整理看板”。
|
|
40
40
|
没有执行工具或 worker 的配置不能当成协作执行证据;不另起模型来生成这行回执。
|
|
41
41
|
派工前分别核对每位成员的客户端与执行器锁,并与任务策略取交集;负责人的推荐平台
|
|
@@ -47,7 +47,7 @@ Neo4j Provider 的独立日志中;工作记忆继续保存经过整理的决
|
|
|
47
47
|
|
|
48
48
|
用户的品味、协作性格和判断偏好继续按确认状态和全局/项目/Agent 作用域读取;入口精简
|
|
49
49
|
保留完整指令、画像分类和写作品味域。协作职责同时带上 Agent 自己的判断、品味、个性和期望。
|
|
50
|
-
工作摘要、
|
|
50
|
+
工作摘要、AR 配置的性格以及自动推断都不能伪装成人工确认的用户偏好。
|
|
51
51
|
|
|
52
52
|
## 采集与失败恢复
|
|
53
53
|
|
package/docs/agent-roundtable.md
CHANGED
|
@@ -75,3 +75,36 @@ Waking needs the client's CLI on this machine: `claude` for Claude Code, and `co
|
|
|
75
75
|
(or the CLI bundled with the Codex app) for Codex. Override the paths with
|
|
76
76
|
`FULI_CLAUDE_BIN` / `FULI_CODEX_BIN`. A recipient is only woken in clients its Agent
|
|
77
77
|
profile allows.
|
|
78
|
+
|
|
79
|
+
## LAN roundtable (Beta)
|
|
80
|
+
|
|
81
|
+
Devices on the same trusted local network can share project leads. Each computer
|
|
82
|
+
needs FULI 0.12.1 or later. Open **Settings → LAN roundtable (Beta)** on the computer
|
|
83
|
+
itself. Choose one computer to host, copy its one-use invitation to the other
|
|
84
|
+
computer, compare the displayed fingerprints, and join. Select the project leads
|
|
85
|
+
and local clients you want to share. Sharing is off until you choose it.
|
|
86
|
+
|
|
87
|
+
`find_agents` includes shared leads with their device and project names. Use the
|
|
88
|
+
returned `peer:` address with `message_agent`. Remote asks support `auto` or `new`
|
|
89
|
+
conversation selection, not a remote session ID or a caller-supplied folder.
|
|
90
|
+
`get_agent_message_status` checks an ask; `cancel_agent_message` cancels one you sent.
|
|
91
|
+
The console refreshes remote answers in the roundtable timeline.
|
|
92
|
+
|
|
93
|
+
The coordinator routes messages; the receiving computer makes outbound connections
|
|
94
|
+
and runs its own allowed, read-only client. The optional folder is verified against
|
|
95
|
+
that local project and never sent to the other device. A shared project needs an
|
|
96
|
+
active lead, an allowed installed client, and either a matching recent session
|
|
97
|
+
folder or a confirmed project folder. Generic MCP clients can send questions;
|
|
98
|
+
automatic answering currently uses the Codex or Claude Code adapters.
|
|
99
|
+
|
|
100
|
+
Turning sharing off cancels its active deliveries. Removing a device ends its trust.
|
|
101
|
+
If the coordinator is offline when a member leaves, that member stops immediately
|
|
102
|
+
and retries removal when the coordinator returns. A lost execution lease stops the
|
|
103
|
+
managed process; an uncertain attempt is shown as unknown and is not replayed.
|
|
104
|
+
Messages expire after at most 30 minutes. Devices verify transport certificates,
|
|
105
|
+
signed messages and the source Provider's project-lead proof before any execution.
|
|
106
|
+
The console's separate LAN-access switch does not turn this feature on.
|
|
107
|
+
|
|
108
|
+
The equivalent local controls are available with `fuli peer --help`. Full database
|
|
109
|
+
backups contain private device and origin-authority material; keep those backups
|
|
110
|
+
private. Public knowledge exports do not include those keys.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Connect a client
|
|
2
|
+
|
|
3
|
+
FULI works through standard MCP tool calls. A client's brand or model provider is
|
|
4
|
+
not an admission requirement. Installation and configuration generation do not
|
|
5
|
+
call a model. A model can help a user configure a client or diagnose an error,
|
|
6
|
+
but is never required to run the installer.
|
|
7
|
+
|
|
8
|
+
## Local connection
|
|
9
|
+
|
|
10
|
+
1. Install and initialize FULI with `npm install --global fuli-context` and
|
|
11
|
+
`fuli setup`. Setup can finish even when no known client is installed. Use
|
|
12
|
+
`fuli setup --skip-agents` to configure only FULI without changing any client.
|
|
13
|
+
2. Run `fuli connect`, or open **Settings → Client connection** in the console.
|
|
14
|
+
3. Merge the generated `fuli` entry into the client's MCP settings, keeping its
|
|
15
|
+
other servers. Reload and trust the connection as required by that client.
|
|
16
|
+
|
|
17
|
+
The generated configuration launches a local stdio server using the current
|
|
18
|
+
Node executable and installed package. It contains paths, not credentials. It
|
|
19
|
+
is for this machine; regenerate it after moving the installation or changing
|
|
20
|
+
the Node location. Use `fuli connect --data-dir PATH` for a separate FULI data
|
|
21
|
+
directory, or `--runtime-config FILE` for an explicit runtime configuration.
|
|
22
|
+
|
|
23
|
+
`fuli connect --format vscode` uses VS Code's `servers` envelope.
|
|
24
|
+
`fuli connect --format server` prints only the server's `type`, `command` and
|
|
25
|
+
`args` for clients with their own configuration editor. Paths with spaces remain
|
|
26
|
+
individual JSON arguments; do not paste them as an unquoted shell command.
|
|
27
|
+
|
|
28
|
+
## Claude Desktop and other chat apps
|
|
29
|
+
|
|
30
|
+
`fuli setup` detects Claude Desktop (Windows and macOS) and adds a `fuli` entry to
|
|
31
|
+
`claude_desktop_config.json`, keeping its other settings and servers and backing up the
|
|
32
|
+
file first. Quit and reopen Claude Desktop afterwards; it only reads the file at launch.
|
|
33
|
+
|
|
34
|
+
Chat apps load every tool schema into each conversation, so Claude Desktop gets the
|
|
35
|
+
**chat profile** (`--tool-profile chat`): 20 tools for preferences, project knowledge,
|
|
36
|
+
recording, completion checkpoints, conversation recovery and the Roundtable, about
|
|
37
|
+
40 KB of schema instead of about 200 KB for all 141 tools. Management (executors,
|
|
38
|
+
routing, publishing, recruitment) stays in the console. Its conversations are attributed
|
|
39
|
+
to `claude`. For another chat-style client, print the same entry with
|
|
40
|
+
`fuli connect --profile chat --source-application claude` (or the matching source).
|
|
41
|
+
|
|
42
|
+
Claude Desktop has no lifecycle hooks, so task entry and the closing attribution line
|
|
43
|
+
depend on the Agent following FULI's instructions, and visible conversations are not
|
|
44
|
+
captured automatically.
|
|
45
|
+
|
|
46
|
+
The generated paths go through the active Node location (for example nvm's
|
|
47
|
+
`C:\nvm4w\nodejs`) rather than a versioned install folder, so switching Node
|
|
48
|
+
versions with a version manager does not break client configuration.
|
|
49
|
+
|
|
50
|
+
Clients that only ask for a command can use `fuli mcp` if `fuli` is on their PATH.
|
|
51
|
+
`fuli mcp --tools` lists the available tool contract without starting a task.
|
|
52
|
+
Configuration export is read-only: it neither modifies client settings nor
|
|
53
|
+
claims the client has connected successfully.
|
|
54
|
+
|
|
55
|
+
## What a compatible client needs
|
|
56
|
+
|
|
57
|
+
- MCP **tool discovery and invocation**, using stdio or the remote transport
|
|
58
|
+
described below. A resource-only MCP viewer cannot run FULI workflows.
|
|
59
|
+
- Permission to connect to FULI and to use the relevant project and Agent.
|
|
60
|
+
- An Agent that receives and follows the server's task-entry and completion
|
|
61
|
+
instructions. If the client omits MCP server instructions, add the installed
|
|
62
|
+
FULI Skill or equivalent task instructions to that client's instruction field.
|
|
63
|
+
|
|
64
|
+
The generic connection uses the existing `other` client attribution and preserves
|
|
65
|
+
project, Agent and executor permissions. It does not impersonate a supported host.
|
|
66
|
+
To continue work, select the same FLA and authorized project against the same
|
|
67
|
+
accessible FULI data. FULI does not copy source files or native client tool state.
|
|
68
|
+
|
|
69
|
+
Verify a connection by checking that FULI tools appear, asking the Agent to load
|
|
70
|
+
the current project's context, completing a small task, and checking that the
|
|
71
|
+
same FLA can recover the saved result in a new conversation. Merely saving JSON
|
|
72
|
+
is not proof that task entry or completion ran.
|
|
73
|
+
|
|
74
|
+
## Optional client integration
|
|
75
|
+
|
|
76
|
+
| Capability | Generic MCP | Current dedicated adapters |
|
|
77
|
+
| --- | --- | --- |
|
|
78
|
+
| Tools, authorized preferences and working memory | Available through tool calls | Shared behavior |
|
|
79
|
+
| Automatic configuration and bundled instructions | Merge generated configuration | Codex, Claude Code, Cursor; Claude Desktop (configuration only, chat profile) |
|
|
80
|
+
| Task entry and completion hooks | Agent follows instructions; no guaranteed hook | Host-specific adapters; Cursor has a limited completion reminder |
|
|
81
|
+
| Automatic visible conversation capture | No | Supported Codex and Claude Code transcript formats |
|
|
82
|
+
| Roundtable wake/resume | Messages can wait for the recipient's next task | Codex and Claude Code CLIs |
|
|
83
|
+
|
|
84
|
+
VS Code/Copilot, Gemini CLI and Cline document compatible local MCP transports.
|
|
85
|
+
They are candidates for generic connection, not a claim of completed FULI
|
|
86
|
+
end-to-end acceptance. Other MCP clients and custom Agents can use the same
|
|
87
|
+
contract. Closed chat interfaces without tools or an extension interface cannot
|
|
88
|
+
connect directly.
|
|
89
|
+
|
|
90
|
+
New dedicated adapters belong behind the shared client ports. They should add
|
|
91
|
+
only host-specific configuration, hooks, transcript parsing or execution, never
|
|
92
|
+
a second version of FULI's knowledge and role rules. Missing enhancements must
|
|
93
|
+
remain explicit; a generic connection must not claim automatic capture or wake.
|
|
94
|
+
|
|
95
|
+
## Remote clients
|
|
96
|
+
|
|
97
|
+
FULI includes a project-bound Streamable HTTP MCP upstream via `fuli remote-mcp`.
|
|
98
|
+
It is separate from the console at port 2727. Cloud clients cannot reach a user's
|
|
99
|
+
loopback address. They need a reachable HTTPS endpoint with authentication and
|
|
100
|
+
the allowed project scope. The current upstream binds to loopback and requires
|
|
101
|
+
an authenticated proxy for cloud use; it is not a turnkey public service.
|
|
102
|
+
See the [remote connector setup](../README.md#remote-claude--cowork-connector-upstream).
|
|
103
|
+
|
|
104
|
+
## References
|
|
105
|
+
|
|
106
|
+
- [VS Code MCP configuration](https://code.visualstudio.com/docs/agent-customization/mcp-servers)
|
|
107
|
+
- [Gemini CLI MCP servers](https://geminicli.com/docs/tools/mcp-server/)
|
|
108
|
+
- [Cline MCP connections](https://docs.cline.bot/mcp/mcp-overview)
|
package/docs/employee-agents.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Specialist Agents
|
|
2
2
|
|
|
3
|
-
An employee template is a reusable role with an optional FULI-hosted or native workbench. Recruitment reuses the existing durable Project Agent identity and assignment model. Three roles are fixed: **Jefa**, the project manager, **Bole**, the
|
|
3
|
+
An employee template is a reusable role with an optional FULI-hosted or native workbench. Recruitment reuses the existing durable Project Agent identity and assignment model. Three roles are fixed: **Jefa**, the project manager, **Bole**, the AR (Agent Resources) Agent, and **Tonborg**, the judgment Agent. They exist in every personal space from the start, manage all projects by default, and are never offered for hire. They require no separate runtime package. See [judgment and autonomy](judgment-and-autonomy.md) for Tonborg's review, feedback, and execution-choice workflow.
|
|
4
4
|
|
|
5
5
|
## User flow
|
|
6
6
|
|
|
@@ -94,7 +94,7 @@ The optional built-in-only native workbench declaration is `workbench: { "kind":
|
|
|
94
94
|
|
|
95
95
|
The reserved identity is `employee.<template-id>`, recognized by the generic `fuli.employee:<template-id>` capability. Preserve this marker when customizing employee profiles. The actual role, history, memory and project assignments remain in FULI's existing Agent model.
|
|
96
96
|
|
|
97
|
-
`employee.bole` is additionally reserved as the only system
|
|
97
|
+
`employee.bole` is additionally reserved as the only system AR identity. Its Provider type is `hr`; other identities cannot claim that type. Recruitment history records the coordinating and AR Agent IDs, time, reason, proposed identity and final recruited identity, which powers Bole's people panel without inventing activity.
|
|
98
98
|
|
|
99
99
|
## HTTP and MCP
|
|
100
100
|
|
|
@@ -172,7 +172,7 @@ Signing, remote catalog distribution, a runtime sandbox, database migration/unin
|
|
|
172
172
|
|
|
173
173
|
### Bole identity upgrades
|
|
174
174
|
|
|
175
|
-
Local startup calls the idempotent system-
|
|
175
|
+
Local startup calls the idempotent system-AR endpoint for both fresh and existing installs.
|
|
176
176
|
It consolidates the reserved legacy `fuli-project-hr` identity into `employee.bole` in one
|
|
177
177
|
transaction. Names never identify merge targets. The legacy node remains an audit alias;
|
|
178
178
|
assignments, recruitment references, attention and task history follow the canonical Bole.
|
|
@@ -6,12 +6,12 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
|
|
|
6
6
|
## 人员目录与个人主页
|
|
7
7
|
|
|
8
8
|
`/project-agents` 是简洁的人员目录,点击姓名进入 `/agents/:spaceId/:agentId`。
|
|
9
|
-
个人主页展示
|
|
9
|
+
个人主页展示 AR 配置的判断、品味、个性、用户期望,以及有来源的任职、招聘、
|
|
10
10
|
工作和合作记录。未填写的风格不自动编造;角色描述不等于实际成长证据。
|
|
11
11
|
合作次数只统计双方实际参与过的任务,不把排队或仅被分配算作已合作。
|
|
12
12
|
|
|
13
|
-
组织关系来自各项目的协调策略。
|
|
14
|
-
模糊检索,在本地完成,不额外调用模型。也可让客户端中的
|
|
13
|
+
组织关系来自各项目的协调策略。AR 人员目录支持名字、技能、职责、项目和任务
|
|
14
|
+
模糊检索,在本地完成,不额外调用模型。也可让客户端中的 AR 通过人员工具查询。
|
|
15
15
|
主页设置可修改执行平台偏好和期望;锁定的执行平台仍受原策略约束。
|
|
16
16
|
技术性配置保留在 `/project-agents/manage` 高级管理入口。
|
|
17
17
|
|
|
@@ -21,7 +21,7 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
|
|
|
21
21
|
| --- | --- | --- |
|
|
22
22
|
| 身份 | 姓名、职责、能力、客户端与执行器偏好 | 个人空间中的稳定 Agent ID |
|
|
23
23
|
| 任职 | 负责的项目、职责及任职历史 | 精确的空间、项目和 Agent |
|
|
24
|
-
| 项目小组 | 小组长、长期成员、自动归组策略 | 项目协调策略;
|
|
24
|
+
| 项目小组 | 小组长、长期成员、自动归组策略 | 项目协调策略;AR、项目经理保持同级 |
|
|
25
25
|
| 工作记录 | 本次结果、状态、来源客户端和时间 | Provider 中的任务生命周期记录 |
|
|
26
26
|
| 可见对话 | 用户消息、助手回复和工具记录 | 同一数据库中独立日志;按空间、项目、Agent 隔离 |
|
|
27
27
|
| 私有工作记忆 | 摘要、决策、未完成问题、下一步 | Neo4j 中按空间、项目、Agent 隔离的版本记录 |
|
|
@@ -32,7 +32,7 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
|
|
|
32
32
|
|
|
33
33
|
## 小组随项目成长
|
|
34
34
|
|
|
35
|
-
新项目可以没有专业员工。
|
|
35
|
+
新项目可以没有专业员工。AR 按任务需要招募长期员工;默认首位成为小组长,
|
|
36
36
|
后续新员工加入小组。归组与招聘处于同一个事务中,失败时一起回滚。
|
|
37
37
|
临时协作者只参加任务,不进入固定小组。
|
|
38
38
|
|
|
@@ -42,7 +42,7 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
|
|
|
42
42
|
|
|
43
43
|
自动沿用开启时,项目小组长是默认沟通负责人。显式指定有效员工仍然优先;
|
|
44
44
|
关闭自动沿用后需要手动选择。角色、职能、模型策略和执行器偏好仍由用户配置。
|
|
45
|
-
小组策略不改变
|
|
45
|
+
小组策略不改变 AR 与项目经理的管理权限,也不授权启动任意 worker。
|
|
46
46
|
|
|
47
47
|
## 任务入口与首次接管
|
|
48
48
|
|
|
@@ -83,6 +83,6 @@ class StoreDefaultProjectLead:
|
|
|
83
83
|
break
|
|
84
84
|
return ProjectAgentContextResolution(
|
|
85
85
|
status='ready', reason='default_project_lead',
|
|
86
|
-
match_basis=['
|
|
86
|
+
match_basis=['AR hired the project lead for its first task'],
|
|
87
87
|
candidate_count=1, agent=lead,
|
|
88
88
|
)
|
|
@@ -20,6 +20,23 @@ class AgentDelegationIssue(StrictModel):
|
|
|
20
20
|
lifetime_seconds: int = Field(default=300, ge=30, le=900)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
class AgentRemoteDelegationIssue(StrictModel):
|
|
24
|
+
"""One attempt of a signed ask from another paired device.
|
|
25
|
+
|
|
26
|
+
The local runner has already verified the device signature and the owner's
|
|
27
|
+
share. This authority still decides project, receiver, client and lifetime.
|
|
28
|
+
"""
|
|
29
|
+
personal_space_id: str = Field(min_length=1, max_length=128)
|
|
30
|
+
personal_project_id: str = Field(min_length=1, max_length=128)
|
|
31
|
+
agent_id: str = Field(min_length=1, max_length=128)
|
|
32
|
+
target_application: SourceApplication
|
|
33
|
+
target_session_id: str | None = Field(default=None, min_length=1, max_length=256)
|
|
34
|
+
lifetime_seconds: int = Field(default=300, ge=30, le=900)
|
|
35
|
+
origin_node: str = Field(pattern=r'^[0-9a-f]{64}$')
|
|
36
|
+
origin_message_id: str = Field(min_length=1, max_length=128, pattern=r'^[A-Za-z0-9][A-Za-z0-9._:-]*$')
|
|
37
|
+
origin_attempt_id: str = Field(min_length=1, max_length=128, pattern=r'^[A-Za-z0-9][A-Za-z0-9._:-]*$')
|
|
38
|
+
|
|
39
|
+
|
|
23
40
|
class AgentDelegationCheck(StrictModel):
|
|
24
41
|
personal_space_id: str = Field(min_length=1, max_length=128)
|
|
25
42
|
token: str = Field(min_length=32, max_length=128)
|
|
@@ -66,6 +83,51 @@ class StoreAgentDelegations:
|
|
|
66
83
|
lead=lead, lifetime=request.lifetime_seconds)
|
|
67
84
|
return {'token': token}
|
|
68
85
|
|
|
86
|
+
async def issue_remote_agent_delegation(self, actor, request):
|
|
87
|
+
self._require_personal()
|
|
88
|
+
space = await self.authorize(actor, request.personal_space_id, 'maintainer')
|
|
89
|
+
await authorize_personal_project(self, actor, space, request.personal_project_id)
|
|
90
|
+
policy = await self.get_project_agent_coordination_policy(
|
|
91
|
+
actor, request.personal_space_id, request.personal_project_id)
|
|
92
|
+
lead = policy.team_lead_agent_id
|
|
93
|
+
# Remote asks keep the receiving project's accountable lead: in this
|
|
94
|
+
# version only that lead can be woken, never a member directly.
|
|
95
|
+
if not lead or request.agent_id != lead:
|
|
96
|
+
raise HTTPException(403, 'Remote devices can only ask the project lead')
|
|
97
|
+
target = await self.get_project_agent(
|
|
98
|
+
actor, request.personal_space_id, request.personal_project_id, request.agent_id)
|
|
99
|
+
if (target.profile.status != 'active'
|
|
100
|
+
or request.target_application not in target.profile.allowed_clients):
|
|
101
|
+
raise HTTPException(403, 'The receiving Agent is unavailable in this client')
|
|
102
|
+
token = token_urlsafe(32)
|
|
103
|
+
await self.runtime.driver.execute_query(
|
|
104
|
+
'''MATCH (old:FuliAgentDelegation {space_id: $space_id})
|
|
105
|
+
WHERE old.expires_at <= datetime() DELETE old''', space_id=request.personal_space_id)
|
|
106
|
+
# The attempt record is durable history and is never deleted, so one
|
|
107
|
+
# claimed attempt can obtain authority at most once.
|
|
108
|
+
rows, _, _ = await self.runtime.driver.execute_query(
|
|
109
|
+
'''MERGE (attempt:FuliRemoteDelegationAttempt {space_id: $space_id, origin_node: $origin_node,
|
|
110
|
+
origin_message_id: $message_id, origin_attempt_id: $attempt_id})
|
|
111
|
+
ON CREATE SET attempt.issued_at = datetime(), attempt.project_id = $project_id,
|
|
112
|
+
attempt.agent_id = $agent_id, attempt._created = true
|
|
113
|
+
WITH attempt, coalesce(attempt._created, false) AS created
|
|
114
|
+
REMOVE attempt._created
|
|
115
|
+
WITH attempt, created WHERE created
|
|
116
|
+
CREATE (:FuliAgentDelegation {token_hash: $token_hash, space_id: $space_id,
|
|
117
|
+
project_id: $project_id, agent_id: $agent_id, source_application: $application,
|
|
118
|
+
session_id: $session_id, sender_token: null, lead_agent_id: $lead, origin: 'remote',
|
|
119
|
+
origin_node: $origin_node, origin_message_id: $message_id, origin_attempt_id: $attempt_id,
|
|
120
|
+
expires_at: datetime() + duration({seconds: $lifetime}), redeemed: false})
|
|
121
|
+
RETURN attempt.issued_at AS issued_at''',
|
|
122
|
+
space_id=request.personal_space_id, origin_node=request.origin_node,
|
|
123
|
+
message_id=request.origin_message_id, attempt_id=request.origin_attempt_id,
|
|
124
|
+
project_id=request.personal_project_id, agent_id=request.agent_id,
|
|
125
|
+
token_hash=token_hash(token), application=request.target_application,
|
|
126
|
+
session_id=request.target_session_id, lead=lead, lifetime=request.lifetime_seconds)
|
|
127
|
+
if not rows:
|
|
128
|
+
raise HTTPException(409, 'This remote delivery attempt already received authority')
|
|
129
|
+
return {'token': token}
|
|
130
|
+
|
|
69
131
|
async def redeem_agent_delegation(self, request, lead):
|
|
70
132
|
if not request.delegation_token or not request.delegation_session_id or not request.agent_id:
|
|
71
133
|
return False
|
|
@@ -85,11 +147,17 @@ class StoreAgentDelegations:
|
|
|
85
147
|
WITH grant
|
|
86
148
|
WHERE grant.expires_at > datetime()
|
|
87
149
|
AND (grant.session_id IS NULL OR grant.session_id = $session_id)
|
|
88
|
-
MATCH (session:FuliTaskContextSession)-[:HAS_CONTEXT]->(task:FuliTaskContext)
|
|
89
|
-
WHERE
|
|
150
|
+
OPTIONAL MATCH (session:FuliTaskContextSession)-[:HAS_CONTEXT]->(task:FuliTaskContext)
|
|
151
|
+
WHERE grant.origin IS NULL
|
|
152
|
+
AND task.token = grant.sender_token AND session.current_token = task.token
|
|
90
153
|
AND NOT task.completed AND task.personal_space_id = grant.space_id
|
|
91
154
|
AND task.personal_project_id = grant.project_id
|
|
92
155
|
AND (task.project_agent_id = grant.lead_agent_id OR grant.agent_id = grant.lead_agent_id)
|
|
156
|
+
WITH grant, count(task) AS live_sender
|
|
157
|
+
// A local grant needs its live sender task; a remote grant has no
|
|
158
|
+
// local sender and may only ever restore the current lead.
|
|
159
|
+
WHERE (grant.origin IS NULL AND live_sender > 0)
|
|
160
|
+
OR (grant.origin = 'remote' AND grant.agent_id = grant.lead_agent_id)
|
|
93
161
|
SET grant.session_id = $session_id, grant.redeemed = true
|
|
94
162
|
RETURN grant.token_hash AS token_hash''',
|
|
95
163
|
token_hash=token_hash(request.delegation_token), space_id=request.personal_space_id,
|
|
@@ -15,7 +15,10 @@ from .project_agent_context_models import (
|
|
|
15
15
|
from .agent_conversation_routes import register_agent_conversation_routes
|
|
16
16
|
from .default_project_lead import DefaultProjectLeadRequest
|
|
17
17
|
from .task_context_routes import register_task_context_routes
|
|
18
|
-
from .project_agent_delegations import
|
|
18
|
+
from .project_agent_delegations import (
|
|
19
|
+
AgentDelegationCheck, AgentDelegationIssue, AgentRemoteDelegationIssue,
|
|
20
|
+
)
|
|
21
|
+
from .project_agent_remote_origins import AgentRemoteOriginIssue
|
|
19
22
|
|
|
20
23
|
|
|
21
24
|
def register_project_agent_memory_routes(application, store, Actor):
|
|
@@ -31,6 +34,20 @@ def register_project_agent_memory_routes(application, store, Actor):
|
|
|
31
34
|
async def issue_delegation(request: AgentDelegationIssue, actor: Actor):
|
|
32
35
|
return await store.issue_agent_delegation(actor, request)
|
|
33
36
|
|
|
37
|
+
@application.post('/v1/project-agent-context/remote-delegations')
|
|
38
|
+
async def issue_remote_delegation(request: AgentRemoteDelegationIssue, actor: Actor):
|
|
39
|
+
return await store.issue_remote_agent_delegation(actor, request)
|
|
40
|
+
|
|
41
|
+
@application.post('/v1/project-agent-context/remote-origins')
|
|
42
|
+
async def issue_remote_origin(request: AgentRemoteOriginIssue, actor: Actor):
|
|
43
|
+
return await store.issue_remote_agent_origin(actor, request)
|
|
44
|
+
|
|
45
|
+
@application.get('/v1/project-agent-context/remote-origin-authority')
|
|
46
|
+
async def remote_origin_authority(
|
|
47
|
+
actor: Actor, personal_space_id: Annotated[str, Query(min_length=1, max_length=128)],
|
|
48
|
+
):
|
|
49
|
+
return await store.remote_origin_authority(actor, personal_space_id)
|
|
50
|
+
|
|
34
51
|
@application.post('/v1/project-agent-context/delegations/verify')
|
|
35
52
|
async def verify_delegation(request: AgentDelegationCheck, actor: Actor):
|
|
36
53
|
return await store.verify_agent_delegation(actor, request)
|