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.
Files changed (160) hide show
  1. package/README.md +14 -6
  2. package/README.zh-CN.md +9 -4
  3. package/dist/web/assets/{AboutPage-BAD0iPVX.js → AboutPage-Dized8Uz.js} +1 -1
  4. package/dist/web/assets/{AgentConversations-1iGTd4sz.js → AgentConversations-Ccy41mEA.js} +1 -1
  5. package/dist/web/assets/{AgentHand-D_RafKOM.js → AgentHand-UzVhbKUC.js} +1 -1
  6. package/dist/web/assets/{AgentName-B5LKQ09q.js → AgentName-DJpvkub2.js} +1 -1
  7. package/dist/web/assets/AgentProfilePage-CFViQ8kj.js +1 -0
  8. package/dist/web/assets/AgentsDirectoryPage-CBFTg_IE.js +1 -0
  9. package/dist/web/assets/AgentsDirectoryPage-Cv-vxw2C.css +1 -0
  10. package/dist/web/assets/{ConnectionsPage-Tr2rRVOZ.js → ConnectionsPage-uXcabab_.js} +1 -1
  11. package/dist/web/assets/EmployeeRecruitDialog-D8Hvhc-M.js +1 -0
  12. package/dist/web/assets/EmployeeWorkbenchPage-TBl_HNj6.js +3 -0
  13. package/dist/web/assets/KnowledgeEditDialog-HmiqLC-Y.js +1 -0
  14. package/dist/web/assets/KnowledgeInspector-Cj2yK4Qh.js +1 -0
  15. package/dist/web/assets/KnowledgeOrganizerPage-DT3BROZm.js +1 -0
  16. package/dist/web/assets/KnowledgePage-C4J4VueL.js +1 -0
  17. package/dist/web/assets/KnowledgeWorkspace-DA_dqVRG.js +4 -0
  18. package/dist/web/assets/{NotFoundPage-fetSnp0N.js → NotFoundPage-x_Yd59mm.js} +1 -1
  19. package/dist/web/assets/{OverviewPage-BD4yY2Xz.js → OverviewPage-3eZjQ26v.js} +1 -1
  20. package/dist/web/assets/OverviewPage-8LBN8Shi.css +1 -0
  21. package/dist/web/assets/PersonalProfilePage-CDQk096L.js +1 -0
  22. package/dist/web/assets/PersonalProjectsPage-CJxp4Wyz.js +1 -0
  23. package/dist/web/assets/{ProjectAgentFirstTask-BcxqmKXQ.js → ProjectAgentFirstTask-BkRJ0zwO.js} +1 -1
  24. package/dist/web/assets/{ProjectAgentsPage-BWDJBESb.js → ProjectAgentsPage-BuNNqSEy.js} +8 -8
  25. package/dist/web/assets/{ProjectScopePicker-yodM7lF_.js → ProjectScopePicker-CiDxM2Yx.js} +1 -1
  26. package/dist/web/assets/PublicProjectsPage-ByOT559r.js +1 -0
  27. package/dist/web/assets/{ReviewPage-Cy0Rt4CO.js → ReviewPage-C0Vdr9uq.js} +1 -1
  28. package/dist/web/assets/RoundtablesPage-Drou-B81.css +1 -0
  29. package/dist/web/assets/RoundtablesPage-L3ShEWS3.js +1 -0
  30. package/dist/web/assets/SettingsPage-BE8pWbI6.css +1 -0
  31. package/dist/web/assets/SettingsPage-McYuinGz.js +1 -0
  32. package/dist/web/assets/{SharedJefaReportPage-C56kPciB.js → SharedJefaReportPage-Bg6lIk3E.js} +1 -1
  33. package/dist/web/assets/UiButton-x8hiHNRM.js +1 -0
  34. package/dist/web/assets/UiDialog-mjletK0y.js +1 -0
  35. package/dist/web/assets/{UiDisclosure-D0iMTplF.js → UiDisclosure-_IxeiexW.js} +1 -1
  36. package/dist/web/assets/{UiSegmented-DIJW6wv3.js → UiSegmented-WFfz9Evl.js} +1 -1
  37. package/dist/web/assets/{UiSelect-CMR0QqF6.js → UiSelect-K29jnV-1.js} +1 -1
  38. package/dist/web/assets/{WritingTastePage-QgNzssfF.js → WritingTastePage-DCULB-d2.js} +1 -1
  39. package/dist/web/assets/agent-pins-DS4mNsNt.js +1 -0
  40. package/dist/web/assets/agent-profile-Bh3MJGvb.css +1 -0
  41. package/dist/web/assets/{attention-store-B1DI8wmd.js → attention-store-CA5y8j1R.js} +1 -1
  42. package/dist/web/assets/catalog-D0VEfOAV.js +1 -0
  43. package/dist/web/assets/{client-CR-W5Wzp.js → client-DnwnUBQV.js} +1 -1
  44. package/dist/web/assets/{console-D7GHOMEC.js → console-Cw7TzOSC.js} +1 -1
  45. package/dist/web/assets/conversation-launcher-settings-Yc13viwr.js +1 -0
  46. package/dist/web/assets/{i18n-CVFhT_k7.js → i18n-oJFlt8hW.js} +3 -3
  47. package/dist/web/assets/{identity-CM6Dmy00.js → identity-DSGS4CZc.js} +1 -1
  48. package/dist/web/assets/index-BfHCcUL2.css +1 -0
  49. package/dist/web/assets/index-CxNER7Oo.js +5 -0
  50. package/dist/web/assets/{judgment-types-CJBEyJs1.js → judgment-types-DR931cZ7.js} +1 -1
  51. package/dist/web/assets/{model-WFhQZ3v_.js → model-BJ-UF4cs.js} +1 -1
  52. package/dist/web/assets/{personal-profile-graph-BwCh2M9G.js → personal-profile-graph-SOK0BR0w.js} +1 -1
  53. package/dist/web/assets/project-team-api-C_0qJk_B.js +1 -0
  54. package/dist/web/assets/{shared-report-CeIvrL9a.js → shared-report-CiX64ZiD.js} +1 -1
  55. package/dist/web/assets/useAgentRoster-B84mzZIg.js +1 -0
  56. package/dist/web/assets/{useApi-CROJJdhE-BYhbjaZB.js → useApi-CROJJdhE-7gt0QyQ5.js} +1 -1
  57. package/dist/web/assets/{vue-router-DaxrQwX3.js → vue-router-CCvPGaLD.js} +1 -1
  58. package/dist/web/index.html +15 -14
  59. package/dist/web/licenses/ant-design-icons.txt +22 -0
  60. package/docs/agent-conversations-and-collaboration.md +3 -3
  61. package/docs/agent-roundtable.md +33 -0
  62. package/docs/client-connections.md +108 -0
  63. package/docs/employee-agents.md +3 -3
  64. package/docs/project-agent-memory.md +6 -6
  65. package/graph-provider/fuli_graph/default_project_lead.py +1 -1
  66. package/graph-provider/fuli_graph/project_agent_delegations.py +70 -2
  67. package/graph-provider/fuli_graph/project_agent_memory_routes.py +18 -1
  68. package/graph-provider/fuli_graph/project_agent_remote_origins.py +154 -0
  69. package/graph-provider/fuli_graph/project_agent_task_models.py +1 -1
  70. package/graph-provider/fuli_graph/runtime.py +7 -0
  71. package/graph-provider/fuli_graph/store_project_agent_context.py +3 -2
  72. package/graph-provider/fuli_graph/store_project_agent_coordination_policy.py +1 -1
  73. package/graph-provider/fuli_graph/store_project_agent_task_reads.py +1 -1
  74. package/graph-provider/fuli_graph/store_project_agent_task_recruitment.py +5 -5
  75. package/graph-provider/fuli_graph/store_project_agent_task_staffing.py +2 -2
  76. package/graph-provider/fuli_graph/store_project_agent_tasks.py +2 -2
  77. package/graph-provider/fuli_graph/store_project_agents.py +6 -6
  78. package/graph-provider/fuli_graph/system_agents.py +12 -2
  79. package/graph-provider/fuli_graph/system_hr_identity.py +2 -2
  80. package/graph-provider/pyproject.toml +2 -1
  81. package/npm-shrinkwrap.json +280 -5
  82. package/package.json +6 -2
  83. package/skills/operating-fuli/SKILL.md +3 -3
  84. package/src/agent-peer/coordinator-http.js +117 -0
  85. package/src/agent-peer/coordinator-service.js +258 -0
  86. package/src/agent-peer/coordinator-store.js +95 -0
  87. package/src/agent-peer/device-identity.js +70 -0
  88. package/src/agent-peer/http.js +47 -0
  89. package/src/agent-peer/node-store.js +127 -0
  90. package/src/agent-peer/origin-proof.js +56 -0
  91. package/src/agent-peer/peer-port.js +140 -0
  92. package/src/agent-peer/peer-runtime.js +298 -0
  93. package/src/agent-peer/peer-transport.js +78 -0
  94. package/src/agent-peer/protocol.js +161 -0
  95. package/src/agent-peer/runner.js +251 -0
  96. package/src/agent-roundtable/http.js +17 -3
  97. package/src/agent-roundtable/service.js +272 -43
  98. package/src/agent-roundtable/tools.js +15 -1
  99. package/src/agent-roundtable/wake.js +12 -3
  100. package/src/agent-tools/graph-definitions.js +14 -5
  101. package/src/agent-tools/graph-handlers.js +1 -0
  102. package/src/agent-tools/interface-catalog.js +10 -1
  103. package/src/agent-tools/project-agent-definitions.js +1 -1
  104. package/src/agents/identity-receipt.js +1 -1
  105. package/src/cli/command-registry.js +3 -0
  106. package/src/cli/connect-command.js +31 -0
  107. package/src/cli/mcp-command.js +101 -0
  108. package/src/cli/peer-command.js +100 -0
  109. package/src/cli/setup-agent-selection.js +2 -2
  110. package/src/cli/setup-command.js +12 -5
  111. package/src/cli.js +16 -0
  112. package/src/employees/catalog/bole.json +2 -2
  113. package/src/graphiti/federated-application.js +4 -1
  114. package/src/graphiti/project-agent-control-plane.js +7 -0
  115. package/src/graphiti/project-agent-task-entry.js +4 -4
  116. package/src/graphiti/project-agent-team-context.js +16 -18
  117. package/src/graphiti/project-team-view.js +82 -0
  118. package/src/graphiti/provider-client.js +9 -0
  119. package/src/graphiti/task-entry-preferences.js +1 -1
  120. package/src/http/api-router.js +10 -1
  121. package/src/http/graph-api-router.js +7 -0
  122. package/src/mcp/runtime.js +2 -1
  123. package/src/mcp/tool-annotations.js +4 -3
  124. package/src/mcp/tool-profiles.js +36 -0
  125. package/src/mcp-server.js +2 -100
  126. package/src/server.js +14 -2
  127. package/src/setup/agent-installation-status.js +5 -3
  128. package/src/setup/agents.js +23 -3
  129. package/src/setup/claude-desktop-config.js +60 -0
  130. package/src/setup/client-connection.js +25 -0
  131. package/src/setup/paths.js +3 -1
  132. package/src/setup/setup.js +1 -1
  133. package/src/setup/stable-package-root.js +29 -0
  134. package/src/system/system-service.js +5 -0
  135. package/dist/web/assets/AgentProfilePage-CioOdkBM.js +0 -1
  136. package/dist/web/assets/AgentsDirectoryPage--1A9nvNA.js +0 -1
  137. package/dist/web/assets/AgentsDirectoryPage-C7OUQH9v.css +0 -1
  138. package/dist/web/assets/EmployeeRecruitDialog-1QevD4Qv.js +0 -1
  139. package/dist/web/assets/EmployeeWorkbenchPage-B0vQIgwA.js +0 -3
  140. package/dist/web/assets/KnowledgeEditDialog-ClnrfPZi.js +0 -1
  141. package/dist/web/assets/KnowledgeInspector-Te1hJZbx.js +0 -1
  142. package/dist/web/assets/KnowledgeOrganizerPage-CCCrWl6Y.js +0 -1
  143. package/dist/web/assets/KnowledgePage-DGOcBwr8.js +0 -1
  144. package/dist/web/assets/KnowledgeWorkspace-cKn1NCRe.js +0 -4
  145. package/dist/web/assets/OverviewPage-By-fUzSG.css +0 -1
  146. package/dist/web/assets/PersonalProfilePage-DGJVP_VB.js +0 -1
  147. package/dist/web/assets/PersonalProjectsPage-D25HYMgD.js +0 -1
  148. package/dist/web/assets/PublicProjectsPage-CyNxVzW3.js +0 -1
  149. package/dist/web/assets/RoundtablesPage-BjVhvwMc.js +0 -1
  150. package/dist/web/assets/RoundtablesPage-Cb0R4GaM.css +0 -1
  151. package/dist/web/assets/SettingsPage-CCZqZtnH.js +0 -1
  152. package/dist/web/assets/SettingsPage-DYz5bTwa.css +0 -1
  153. package/dist/web/assets/UiDialog-CvDxg3B1.js +0 -1
  154. package/dist/web/assets/agent-pins-BcJ_qr8n.js +0 -1
  155. package/dist/web/assets/agent-profile-BZj3ezWe.css +0 -1
  156. package/dist/web/assets/catalog-DbXv0_bR.js +0 -1
  157. package/dist/web/assets/conversation-launcher-settings-Dj2GMzCI.js +0 -1
  158. package/dist/web/assets/index-CJ6Jmok9.css +0 -1
  159. package/dist/web/assets/index-CRa3GnYi.js +0 -5
  160. 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};
@@ -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-CRa3GnYi.js"></script>
13
- <link rel="modulepreload" crossorigin href="/assets/i18n-CVFhT_k7.js">
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-CR-W5Wzp.js">
16
- <link rel="modulepreload" crossorigin href="/assets/console-D7GHOMEC.js">
17
- <link rel="modulepreload" crossorigin href="/assets/UiDialog-CvDxg3B1.js">
18
- <link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-BYhbjaZB.js">
19
- <link rel="modulepreload" crossorigin href="/assets/vue-router-DaxrQwX3.js">
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/UiSelect-CMR0QqF6.js">
22
- <link rel="modulepreload" crossorigin href="/assets/attention-store-B1DI8wmd.js">
23
- <link rel="modulepreload" crossorigin href="/assets/AgentHand-D_RafKOM.js">
24
- <link rel="modulepreload" crossorigin href="/assets/UiDisclosure-D0iMTplF.js">
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-DCArHlxK.js">
28
- <link rel="modulepreload" crossorigin href="/assets/agent-pins-BcJ_qr8n.js">
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-CJ6Jmok9.css">
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/HR 是同级协作角色。只有管理员成员的项目不会把开发任务
38
- 隐式记到管理员名下;需要先通过 HR 分配或招聘开发者。显式选中管理员及其本职任务仍可使用。
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
- 工作摘要、HR 配置的性格以及自动推断都不能伪装成人工确认的用户偏好。
50
+ 工作摘要、AR 配置的性格以及自动推断都不能伪装成人工确认的用户偏好。
51
51
 
52
52
  ## 采集与失败恢复
53
53
 
@@ -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)
@@ -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 HR 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.
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 HR identity. Its Provider type is `hr`; other identities cannot claim that type. Recruitment history records the coordinating and HR Agent IDs, time, reason, proposed identity and final recruited identity, which powers Bole's people panel without inventing activity.
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-HR endpoint for both fresh and existing installs.
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
- 个人主页展示 HR 配置的判断、品味、个性、用户期望,以及有来源的任职、招聘、
9
+ 个人主页展示 AR 配置的判断、品味、个性、用户期望,以及有来源的任职、招聘、
10
10
  工作和合作记录。未填写的风格不自动编造;角色描述不等于实际成长证据。
11
11
  合作次数只统计双方实际参与过的任务,不把排队或仅被分配算作已合作。
12
12
 
13
- 组织关系来自各项目的协调策略。HR 人员目录支持名字、技能、职责、项目和任务
14
- 模糊检索,在本地完成,不额外调用模型。也可让客户端中的 HR 通过人员工具查询。
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
- | 项目小组 | 小组长、长期成员、自动归组策略 | 项目协调策略;HR、项目经理保持同级 |
24
+ | 项目小组 | 小组长、长期成员、自动归组策略 | 项目协调策略;AR、项目经理保持同级 |
25
25
  | 工作记录 | 本次结果、状态、来源客户端和时间 | Provider 中的任务生命周期记录 |
26
26
  | 可见对话 | 用户消息、助手回复和工具记录 | 同一数据库中独立日志;按空间、项目、Agent 隔离 |
27
27
  | 私有工作记忆 | 摘要、决策、未完成问题、下一步 | Neo4j 中按空间、项目、Agent 隔离的版本记录 |
@@ -32,7 +32,7 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
32
32
 
33
33
  ## 小组随项目成长
34
34
 
35
- 新项目可以没有专业员工。HR 按任务需要招募长期员工;默认首位成为小组长,
35
+ 新项目可以没有专业员工。AR 按任务需要招募长期员工;默认首位成为小组长,
36
36
  后续新员工加入小组。归组与招聘处于同一个事务中,失败时一起回滚。
37
37
  临时协作者只参加任务,不进入固定小组。
38
38
 
@@ -42,7 +42,7 @@ Provider 读取已授权的员工和项目记录。切换客户端不会复制
42
42
 
43
43
  自动沿用开启时,项目小组长是默认沟通负责人。显式指定有效员工仍然优先;
44
44
  关闭自动沿用后需要手动选择。角色、职能、模型策略和执行器偏好仍由用户配置。
45
- 小组策略不改变 HR 与项目经理的管理权限,也不授权启动任意 worker。
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=['HR hired the project lead for its first task'],
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 task.token = grant.sender_token AND session.current_token = task.token
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 AgentDelegationIssue, AgentDelegationCheck
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)