fuli-context 0.9.0-beta.2 → 0.10.0

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 (162) hide show
  1. package/README.md +17 -43
  2. package/README.zh-CN.md +14 -40
  3. package/dist/web/assets/AboutPage-D-GyJNv1.js +1 -0
  4. package/dist/web/assets/AboutPage-c4dQpUiP.css +1 -0
  5. package/dist/web/assets/AgentConversations-DOuZgUeA.js +2 -0
  6. package/dist/web/assets/AgentConversations-DS8h3yKn.css +1 -0
  7. package/dist/web/assets/AgentHand-Y83Oo36U.css +1 -0
  8. package/dist/web/assets/AgentHand-eGsXoGSq.js +1 -0
  9. package/dist/web/assets/AgentName-BQTFCWn0.css +1 -0
  10. package/dist/web/assets/AgentName-Dtmu9Ff5.js +1 -0
  11. package/dist/web/assets/AgentProfilePage-D8Tvayn7.js +1 -0
  12. package/dist/web/assets/AgentsDirectoryPage-BTEfKZjF.js +1 -0
  13. package/dist/web/assets/ConnectionsPage-C1w99yN3.css +1 -0
  14. package/dist/web/assets/ConnectionsPage-DwOIcvl9.js +1 -0
  15. package/dist/web/assets/EmployeeRecruitDialog-BrIMRblq.css +1 -0
  16. package/dist/web/assets/EmployeeRecruitDialog-D11blfwU.js +1 -0
  17. package/dist/web/assets/EmployeeWorkbenchPage-BcEzYt65.css +1 -0
  18. package/dist/web/assets/EmployeeWorkbenchPage-CK2BAoGt.js +3 -0
  19. package/dist/web/assets/GrowthLoading-CIuQ1icy.css +1 -0
  20. package/dist/web/assets/GrowthLoading-KTjE2e50.js +1 -0
  21. package/dist/web/assets/KnowledgeEditDialog-B3x8vs3c.css +1 -0
  22. package/dist/web/assets/KnowledgeEditDialog-n9trHQ5d.js +1 -0
  23. package/dist/web/assets/KnowledgeInspector-BcNjgw9H.js +1 -0
  24. package/dist/web/assets/KnowledgeInspector-pgDELOEf.css +1 -0
  25. package/dist/web/assets/KnowledgeOrganizerPage-BzgxP-nG.css +1 -0
  26. package/dist/web/assets/KnowledgeOrganizerPage-DMBpGxLr.js +1 -0
  27. package/dist/web/assets/KnowledgePage-POkCMW8f.js +1 -0
  28. package/dist/web/assets/KnowledgeWorkspace-2FvQadhB.js +4 -0
  29. package/dist/web/assets/NotFoundPage-BCMZbeB8.js +1 -0
  30. package/dist/web/assets/OverviewPage-0CFWCG9-.css +1 -0
  31. package/dist/web/assets/OverviewPage-0mYifpjp.js +1 -0
  32. package/dist/web/assets/PersonalProfilePage-Chv2a2pi.css +1 -0
  33. package/dist/web/assets/PersonalProfilePage-JW6Muix6.js +1 -0
  34. package/dist/web/assets/PersonalProjectsPage-CRbi64JP.js +1 -0
  35. package/dist/web/assets/ProjectAgentFirstTask-DJ0wTbh8.js +1 -0
  36. package/dist/web/assets/ProjectAgentsPage-CPgKVLgg.js +12 -0
  37. package/dist/web/assets/ProjectAgentsPage-DeuRkMp1.css +1 -0
  38. package/dist/web/assets/ProjectScopePicker-BwB7gK-7.js +1 -0
  39. package/dist/web/assets/ProjectScopePicker-DYA7L1Ex.css +1 -0
  40. package/dist/web/assets/PublicProjectsPage-CB272Sq-.js +1 -0
  41. package/dist/web/assets/ReviewPage-CelTZU4C.js +1 -0
  42. package/dist/web/assets/RoundtablesPage-C9dXfWCl.js +2 -0
  43. package/dist/web/assets/{SearchableSelect-Do6X3fXi.js → SearchableSelect-f7EHbyDL.js} +1 -1
  44. package/dist/web/assets/SettingsPage-5g7mRN2F.css +1 -0
  45. package/dist/web/assets/SettingsPage-nAijmm5f.js +1 -0
  46. package/dist/web/assets/SharedJefaReportPage-CjpJ9bkk.js +1 -0
  47. package/dist/web/assets/SharedJefaReportPage-D92FSPru.css +1 -0
  48. package/dist/web/assets/UiDisclosure-CWlC91Zt.js +1 -0
  49. package/dist/web/assets/WritingTastePage-DaHWY61P.js +1 -0
  50. package/dist/web/assets/WritingTastePage-SMGF39mf.css +1 -0
  51. package/dist/web/assets/agent-profile-CBvJHGjt.css +1 -0
  52. package/dist/web/assets/{task-evidence-DTiPCs7r.js → agent-work-summary-LeW-Al_S.js} +1 -1
  53. package/dist/web/assets/attention-store-Dk-_P4Oi.js +1 -0
  54. package/dist/web/assets/{catalog-JmKyJnKL.js → catalog-DN72452f.js} +1 -1
  55. package/dist/web/assets/{client-DTQ_tUr2.js → client-B2cRl-7c.js} +1 -1
  56. package/dist/web/assets/console-BtPqo79j.js +1 -0
  57. package/dist/web/assets/{conversation-launcher-settings-fUWCt3XG.js → conversation-launcher-settings-jkHRmWai.js} +1 -1
  58. package/dist/web/assets/{copy-CX6pyzAG.js → copy-D2LqwtPZ.js} +1 -1
  59. package/dist/web/assets/{i18n-CIIxzhPZ.js → i18n-D2CJkEYK.js} +2 -2
  60. package/dist/web/assets/{identity-CdFITIOu.js → identity-B3zEw-1u.js} +1 -1
  61. package/dist/web/assets/index-CNp0tRNp.css +1 -0
  62. package/dist/web/assets/index-ulISYH02.js +5 -0
  63. package/dist/web/assets/{model-CJsrDUNb.js → model-S7ehAjky.js} +1 -1
  64. package/dist/web/assets/{personal-profile-graph-CQLOait6.js → personal-profile-graph--GG3Mizo.js} +1 -1
  65. package/dist/web/assets/shared-report-CGlCpmNd.css +1 -0
  66. package/dist/web/assets/shared-report-DEK9wvhl.js +1 -0
  67. package/dist/web/assets/useAgentRoster-BAPKWZ9y.js +1 -0
  68. package/dist/web/assets/{useApi-CROJJdhE-fcdVGInY.js → useApi-CROJJdhE-BtFMXFjw.js} +1 -1
  69. package/dist/web/assets/{useModalDialog-B-45idX9.js → useModalDialog-D8tiJfbc.js} +1 -1
  70. package/dist/web/assets/{vue-router-BUX6njIv.js → vue-router-DkaTtPn0.js} +1 -1
  71. package/dist/web/index.html +16 -15
  72. package/docs/project-agent-memory.md +6 -0
  73. package/docs/roundtable.md +46 -0
  74. package/graph-provider/fuli_graph/app.py +3 -1
  75. package/graph-provider/pyproject.toml +1 -1
  76. package/npm-shrinkwrap.json +2 -2
  77. package/package.json +2 -4
  78. package/skills/capturing-session-knowledge/SKILL.md +5 -1
  79. package/skills/operating-fuli/SKILL.md +4 -0
  80. package/src/agent-tools/graph-definitions.js +2 -2
  81. package/src/agents/claude-code/lifecycle-hook.js +6 -19
  82. package/src/agents/codex/lifecycle-hook.js +58 -27
  83. package/src/agents/codex/roundtable-config.js +3 -0
  84. package/src/agents/codex/token-usage.js +235 -0
  85. package/src/agents/cursor/lifecycle-hook.js +4 -9
  86. package/src/agents/identity-receipt.js +11 -4
  87. package/src/agents/token-usage-resolver.js +147 -0
  88. package/src/conversations/current-task-lookup.js +40 -0
  89. package/src/conversations/sync-transcript.js +4 -2
  90. package/src/graphiti/federated-application.js +6 -1
  91. package/src/graphiti/project-agent-mapping.js +1 -1
  92. package/src/graphiti/project-agent-workflows.js +6 -1
  93. package/src/graphiti/provider-client.js +7 -4
  94. package/src/graphiti/task-entry-preferences.js +6 -7
  95. package/src/http/static-handler.js +3 -1
  96. package/src/mcp/instructions.js +8 -7
  97. package/src/mcp/session-id.js +1 -1
  98. package/src/mcp/tool-annotations.js +3 -1
  99. package/src/mcp/tool-result.js +20 -8
  100. package/src/native-runtime/runtime.js +41 -6
  101. package/src/roundtables/domain.js +3 -3
  102. package/src/roundtables/http-router.js +5 -3
  103. package/src/roundtables/mcp-server.js +15 -8
  104. package/src/roundtables/profiles.js +84 -0
  105. package/src/roundtables/service.js +86 -2
  106. package/src/roundtables/store.js +4 -0
  107. package/src/roundtables/tool-contract.js +22 -5
  108. package/src/roundtables/turn-prompt.js +3 -0
  109. package/dist/web/assets/AboutPage-u2Bv6cO-.js +0 -1
  110. package/dist/web/assets/AboutPage-vYIBifKw.css +0 -1
  111. package/dist/web/assets/AgentHand-CsMcNXUm.js +0 -1
  112. package/dist/web/assets/AgentHand-D9sQu2vc.css +0 -1
  113. package/dist/web/assets/AgentName-BboCA-Fd.js +0 -1
  114. package/dist/web/assets/AgentName-Cydd0UI4.css +0 -1
  115. package/dist/web/assets/AgentProfilePage-Dyux6qE3.js +0 -1
  116. package/dist/web/assets/AgentsDirectoryPage-BEJdvmX7.js +0 -1
  117. package/dist/web/assets/ConnectionsPage-CBHAdZXT.css +0 -1
  118. package/dist/web/assets/ConnectionsPage-Dw_hK_EM.js +0 -1
  119. package/dist/web/assets/EmployeeRecruitDialog-B59X3rOi.css +0 -1
  120. package/dist/web/assets/EmployeeRecruitDialog-DP_ktv3w.js +0 -1
  121. package/dist/web/assets/EmployeeWorkbenchPage-CAt8lVnr.js +0 -3
  122. package/dist/web/assets/EmployeeWorkbenchPage-CQwZnTA0.css +0 -1
  123. package/dist/web/assets/GrowthLoading-B_Hh0CRS.css +0 -1
  124. package/dist/web/assets/GrowthLoading-DIwqGFSc.js +0 -1
  125. package/dist/web/assets/KnowledgeEditDialog-D9NuRHvp.css +0 -1
  126. package/dist/web/assets/KnowledgeEditDialog-Degd9AGD.js +0 -1
  127. package/dist/web/assets/KnowledgeInspector--1NujtXW.css +0 -1
  128. package/dist/web/assets/KnowledgeInspector-yms1ysZ4.js +0 -1
  129. package/dist/web/assets/KnowledgeOrganizerPage-C64wNn8a.js +0 -1
  130. package/dist/web/assets/KnowledgeOrganizerPage-h2iKvQpO.css +0 -1
  131. package/dist/web/assets/KnowledgePage-BTFEXzgi.js +0 -1
  132. package/dist/web/assets/KnowledgeWorkspace-BsF1X4Aq.js +0 -4
  133. package/dist/web/assets/NotFoundPage-DfaNTiD1.js +0 -1
  134. package/dist/web/assets/OverviewPage-VXMfcWFI.js +0 -1
  135. package/dist/web/assets/PersonalProfilePage-C1LBhcYu.js +0 -1
  136. package/dist/web/assets/PersonalProfilePage-L8T5xMEC.css +0 -1
  137. package/dist/web/assets/PersonalProjectsPage-B5lV4ZJW.js +0 -1
  138. package/dist/web/assets/ProjectAgentFirstTask-DF-IvEqp.js +0 -1
  139. package/dist/web/assets/ProjectAgentsPage-CgL92gng.js +0 -13
  140. package/dist/web/assets/ProjectAgentsPage-CoJ4qQlA.css +0 -1
  141. package/dist/web/assets/ProjectScopePicker-BvaGTMFx.css +0 -1
  142. package/dist/web/assets/ProjectScopePicker-CZUMdyYz.js +0 -1
  143. package/dist/web/assets/PublicProjectsPage-e4CpxHk9.js +0 -1
  144. package/dist/web/assets/ReviewPage-DugEaFvI.js +0 -1
  145. package/dist/web/assets/RoundtablesPage-642YtZBC.js +0 -2
  146. package/dist/web/assets/SettingsPage-Brl-SL33.css +0 -1
  147. package/dist/web/assets/SettingsPage-wqYxDPyu.js +0 -1
  148. package/dist/web/assets/SharedJefaReportPage-CNQDezJr.js +0 -1
  149. package/dist/web/assets/SharedJefaReportPage-DXbj_JhO.css +0 -1
  150. package/dist/web/assets/WritingTastePage-Bzg6AvnB.css +0 -1
  151. package/dist/web/assets/WritingTastePage-CAUvbDlL.js +0 -1
  152. package/dist/web/assets/agent-profile-CdKOh5xw.css +0 -1
  153. package/dist/web/assets/agent-profile.css_vue_type_style_index_0_src_true_lang-DHOcWSe_.js +0 -1
  154. package/dist/web/assets/console-CrhIK67Y.js +0 -1
  155. package/dist/web/assets/employee-dialog-Bh5ccIbK.css +0 -1
  156. package/dist/web/assets/index-CYZi7E1e.css +0 -1
  157. package/dist/web/assets/index-Dsgn8o4-.js +0 -2
  158. package/dist/web/assets/shared-report-Cll2Yj8W.js +0 -1
  159. package/dist/web/assets/shared-report-ezeb8dW4.css +0 -1
  160. package/docs/roundtable-beta-testing.md +0 -102
  161. package/docs/roundtable-beta-validation.md +0 -133
  162. package/docs/roundtable-research.md +0 -142
@@ -1 +1 @@
1
- import{$ as e,A as t,E as n,O as r,P as i,Q as a,T as o,Y as s,Z as c,_ as l,nt as u,z as d}from"./i18n-CIIxzhPZ.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-fcdVGInY.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=r(h),n=r(m),i=l(()=>{let n=u(e.to);return t.resolve(n)}),a=l(()=>{let{matched:e}=i.value,{length:t}=e,r=e[t-1],a=n.matched;if(!r||!a.length)return-1;let o=a.findIndex(V.bind(null,r));if(o>-1)return o;let s=rt(e[t-2]);return t>1&&rt(r)===s&&a[a.length-1].path!==s?a.findIndex(V.bind(null,e[t-2])):o}),o=l(()=>a.value>-1&&nt(n.params,i.value.params)),s=l(()=>a.value>-1&&a.value===n.matched.length-1&&H(n.params,i.value.params));function c(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:i,href:l(()=>i.value.href),isActive:o,isExactActive:s,navigate:c}}function $e(e){return e.length===1?e[0]:e}var et=o({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 i=s(Qe(e)),{options:a}=r(h),o=l(()=>({[it(e.activeClass,a.linkActiveClass,`router-link-active`)]:i.isActive,[it(e.exactActiveClass,a.linkExactActiveClass,`router-link-exact-active`)]:i.isExactActive}));return()=>{let r=t.default&&$e(t.default(i));return e.custom?r:n(`a`,{"aria-current":i.isExactActive?e.ariaCurrentValue:null,href:i.href,onClick:i.navigate,class:o.value},r)}}});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=o({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(e,{attrs:t,slots:a}){let o=r(ee),s=l(()=>e.route||o.value),f=r(g,0),m=l(()=>{let e=u(f),{matched:t}=s.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),h=l(()=>s.value.matched[m.value]);i(g,l(()=>m.value+1)),i(p,h),i(ee,s);let _=c();return d(()=>[_.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 r=s.value,i=e.name,o=h.value,c=o&&o.components[i];if(!c)return ot(a.default,{Component:c,route:r});let l=o.props[i],u=n(c,y({},l?l===!0?r.params:typeof l==`function`?l(r):l:null,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(o.instances[i]=null)},ref:_}));return ot(a.default,{Component:u,route:r})||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(n){let r=Ue(n.routes,n),i=n.parseQuery||be,o=n.stringifyQuery||xe,s=n.history,c=Q(),l=Q(),d=Q(),f=e(K),p=K;T&&n.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 n,i;return ye(e)?(n=r.getRecordMatcher(e),i=t):i=e,r.addRoute(i,n)}function te(e){let t=r.getRecordMatcher(e);t&&r.removeRoute(t)}function ne(){return r.getRoutes().map(e=>e.record)}function re(e){return!!r.getRecordMatcher(e)}function D(e,t){if(t=y({},t||f.value),typeof e==`string`){let n=z(i,e,t.path),a=r.resolve({path:n.path},t),o=s.createHref(n.fullPath);return y(n,a,{params:S(a.params),redirectedFrom:void 0,href:o})}let n;if(e.path!=null)n=y({},e,{path:z(i,e.path,t.path).path});else{let r=y({},e.params);for(let e in r)r[e]??delete r[e];n=y({},e,{params:v(r)}),t.params=v(t.params)}let a=r.resolve(n,t),c=e.hash||``;a.params=g(S(a.params));let l=de(o,y({},e,{hash:ce(c),path:a.path})),u=s.createHref(l);return y({fullPath:l,hash:c,query:o===xe?Se(e.query):e.query||{}},a,{redirectedFrom:void 0,href:u})}function O(e){return typeof e==`string`?z(i,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,i=e.state,a=e.force,s=e.replace===!0,c=oe(n,r);if(c)return A(y(O(c),{state:typeof c==`object`?y({},i,c.state):i,force:a,replace:s}),t||n);let l=n;l.redirectedFrom=t;let u;return!a&&fe(o,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({},i,e.to.state):i,force:a}),t||l)}else e=P(l,r,!0,s,i);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 o=se.bind(null,e,t);return n.push(o),X(n).then(()=>{n=[];for(let r of c.list())n.push($(r,e,t));return n.push(o),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(o),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(o),X(n)}).then(()=>(e.matched.forEach(e=>e.enterCallbacks={}),n=Ce(a,`beforeRouteEnter`,e,t,j),n.push(o),X(n))).then(()=>{n=[];for(let r of l.list())n.push($(r,e,t));return n.push(o),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 a=ie(e,t);if(a)return a;let o=t===K,c=T?history.state:{};n&&(r||o?s.replace(e.fullPath,y({scroll:o&&c&&c.scroll},i)):s.push(e.fullPath,i)),f.value=e,W(e,t,n,o),U()}let F;function le(){F||=s.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 a=f.value;T&&ge(me(a.fullPath,n.delta),Z()),M(r,a).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`&&s.go(-1,!1)}).catch(w),Promise.reject()):(n.delta&&s.go(-n.delta,!1),V(e,r,a))).then(e=>{e||=P(r,a,!1),e&&(n.delta&&!b(e,8)?s.go(-n.delta,!1):n.type===`pop`&&b(e,20)&&s.go(-1,!1)),N(r,a,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,r,i,a){let{scrollBehavior:o}=n;if(!T||!o)return Promise.resolve();let s=!i&&_e(me(e.fullPath,0))||(a||!i)&&history.state&&history.state.scroll||null;return t().then(()=>o(e,r,s)).then(t=>e===f.value&&t&&pe(t)).catch(t=>e===f.value&&V(t,e,r))}let G=e=>s.go(e),q,J=new Set,Y={currentRoute:f,listening:!0,addRoute:E,removeRoute:te,clearRoutes:r.clearRoutes,hasRoute:re,getRoutes:ne,resolve:D,options:n,push:k,replace:ae,go:G,back:()=>G(-1),forward:()=>G(1),beforeEach:c.add,beforeResolve:l.add,afterEach:d.add,onError:R.add,isReady:H,install(e){e.component(`RouterLink`,et),e.component(`RouterView`,st),e.config.globalProperties.$router=Y,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>u(f)}),T&&!q&&f.value===K&&(q=!0,k(s.location).catch(e=>{}));let t={};for(let e in K)Object.defineProperty(t,e,{get:()=>f.value[e],enumerable:!0});e.provide(h,Y),e.provide(m,a(t)),e.provide(ee,f);let n=e.unmount;J.add(e),e.unmount=function(){J.delete(e),J.size<1&&(p=K,F&&F(),F=null,f.value=K,q=!1,B=!1),n()}}};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{D as e,J as t,N as n,Q as r,R as i,T as a,X as o,Z as s,_ as c,k as l,tt as u,w as d}from"./i18n-D2CJkEYK.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-BtFMXFjw.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(t){let n=e(h),r=e(m),i=c(()=>{let e=u(t.to);return n.resolve(e)}),a=c(()=>{let{matched:e}=i.value,{length:t}=e,n=e[t-1],a=r.matched;if(!n||!a.length)return-1;let o=a.findIndex(V.bind(null,n));if(o>-1)return o;let s=rt(e[t-2]);return t>1&&rt(n)===s&&a[a.length-1].path!==s?a.findIndex(V.bind(null,e[t-2])):o}),o=c(()=>a.value>-1&&nt(r.params,i.value.params)),s=c(()=>a.value>-1&&a.value===r.matched.length-1&&H(r.params,i.value.params));function l(e={}){if(tt(e)){let e=n[u(t.replace)?`replace`:`push`](u(t.to)).catch(w);return t.viewTransition&&typeof document<`u`&&`startViewTransition`in document&&document.startViewTransition(()=>e),e}return Promise.resolve()}return{route:i,href:c(()=>i.value.href),isActive:o,isExactActive:s,navigate:l}}function $e(e){return e.length===1?e[0]:e}var et=d({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(n,{slots:r}){let i=t(Qe(n)),{options:o}=e(h),s=c(()=>({[it(n.activeClass,o.linkActiveClass,`router-link-active`)]:i.isActive,[it(n.exactActiveClass,o.linkExactActiveClass,`router-link-exact-active`)]:i.isExactActive}));return()=>{let e=r.default&&$e(r.default(i));return n.custom?e:a(`a`,{"aria-current":i.isExactActive?n.ariaCurrentValue:null,href:i.href,onClick:i.navigate,class:s.value},e)}}});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=d({name:`RouterView`,inheritAttrs:!1,props:{name:{type:String,default:`default`},route:Object},compatConfig:{MODE:3},setup(t,{attrs:r,slots:s}){let l=e(ee),d=c(()=>t.route||l.value),f=e(g,0),m=c(()=>{let e=u(f),{matched:t}=d.value,n;for(;(n=t[e])&&!n.components;)e++;return e}),h=c(()=>d.value.matched[m.value]);n(g,c(()=>m.value+1)),n(p,h),n(ee,d);let _=o();return i(()=>[_.value,h.value,t.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 e=d.value,n=t.name,i=h.value,o=i&&i.components[n];if(!o)return ot(s.default,{Component:o,route:e});let c=i.props[n],l=a(o,y({},c?c===!0?e.params:typeof c==`function`?c(e):c:null,r,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[n]=null)},ref:_}));return ot(s.default,{Component:l,route:e})||l}}});function ot(e,t){if(!e)return null;let n=e(t);return n.length===1?n[0]:n}var st=at;function ct(e){let t=Ue(e.routes,e),n=e.parseQuery||be,i=e.stringifyQuery||xe,a=e.history,o=Q(),c=Q(),d=Q(),f=r(K),p=K;T&&e.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,n){let r,i;return ye(e)?(r=t.getRecordMatcher(e),i=n):i=e,t.addRoute(i,r)}function te(e){let n=t.getRecordMatcher(e);n&&t.removeRoute(n)}function ne(){return t.getRoutes().map(e=>e.record)}function re(e){return!!t.getRecordMatcher(e)}function D(e,r){if(r=y({},r||f.value),typeof e==`string`){let i=z(n,e,r.path),o=t.resolve({path:i.path},r),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(n,e.path,r.path).path});else{let t=y({},e.params);for(let e in t)t[e]??delete t[e];o=y({},e,{params:v(t)}),r.params=v(r.params)}let s=t.resolve(o,r),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(n,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 c.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(t,n,r,i){let{scrollBehavior:a}=e;if(!T||!a)return Promise.resolve();let o=!r&&_e(me(t.fullPath,0))||(i||!r)&&history.state&&history.state.scroll||null;return l().then(()=>a(t,n,o)).then(e=>t===f.value&&e&&pe(e)).catch(e=>t===f.value&&V(e,t,n))}let G=e=>a.go(e),q,J=new Set,Y={currentRoute:f,listening:!0,addRoute:E,removeRoute:te,clearRoutes:t.clearRoutes,hasRoute:re,getRoutes:ne,resolve:D,options:e,push:k,replace:ae,go:G,back:()=>G(-1),forward:()=>G(1),beforeEach:o.add,beforeResolve:c.add,afterEach:d.add,onError:R.add,isReady:H,install(e){e.component(`RouterLink`,et),e.component(`RouterView`,st),e.config.globalProperties.$router=Y,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>u(f)}),T&&!q&&f.value===K&&(q=!0,k(a.location).catch(e=>{}));let t={};for(let e in K)Object.defineProperty(t,e,{get:()=>f.value[e],enumerable:!0});e.provide(h,Y),e.provide(m,s(t)),e.provide(ee,f);let n=e.unmount;J.add(e),e.unmount=function(){J.delete(e),J.size<1&&(p=K,F&&F(),F=null,f.value=K,q=!1,B=!1),n()}}};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,25 +9,26 @@
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-Dsgn8o4-.js"></script>
13
- <link rel="modulepreload" crossorigin href="/assets/i18n-CIIxzhPZ.js">
14
- <link rel="modulepreload" crossorigin href="/assets/client-DTQ_tUr2.js">
15
- <link rel="modulepreload" crossorigin href="/assets/console-CrhIK67Y.js">
12
+ <script type="module" crossorigin src="/assets/index-ulISYH02.js"></script>
13
+ <link rel="modulepreload" crossorigin href="/assets/i18n-D2CJkEYK.js">
14
+ <link rel="modulepreload" crossorigin href="/assets/client-B2cRl-7c.js">
15
+ <link rel="modulepreload" crossorigin href="/assets/console-BtPqo79j.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/_plugin-vue_export-helper-BDNMzG2s.js">
17
- <link rel="modulepreload" crossorigin href="/assets/GrowthLoading-DIwqGFSc.js">
18
- <link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-fcdVGInY.js">
19
- <link rel="modulepreload" crossorigin href="/assets/vue-router-BUX6njIv.js">
17
+ <link rel="modulepreload" crossorigin href="/assets/GrowthLoading-KTjE2e50.js">
18
+ <link rel="modulepreload" crossorigin href="/assets/useApi-CROJJdhE-BtFMXFjw.js">
19
+ <link rel="modulepreload" crossorigin href="/assets/vue-router-DkaTtPn0.js">
20
20
  <link rel="modulepreload" crossorigin href="/assets/fuli-logo-Bu9WBuQe.js">
21
- <link rel="modulepreload" crossorigin href="/assets/copy-CX6pyzAG.js">
22
- <link rel="modulepreload" crossorigin href="/assets/catalog-JmKyJnKL.js">
23
- <link rel="modulepreload" crossorigin href="/assets/AgentHand-CsMcNXUm.js">
21
+ <link rel="modulepreload" crossorigin href="/assets/copy-D2LqwtPZ.js">
22
+ <link rel="modulepreload" crossorigin href="/assets/catalog-DN72452f.js">
23
+ <link rel="modulepreload" crossorigin href="/assets/attention-store-Dk-_P4Oi.js">
24
+ <link rel="modulepreload" crossorigin href="/assets/AgentHand-eGsXoGSq.js">
24
25
  <link rel="modulepreload" crossorigin href="/assets/profile-model-BQO4zNs9.js">
25
- <link rel="modulepreload" crossorigin href="/assets/useModalDialog-B-45idX9.js">
26
+ <link rel="modulepreload" crossorigin href="/assets/useModalDialog-D8tiJfbc.js">
27
+ <link rel="modulepreload" crossorigin href="/assets/UiDisclosure-CWlC91Zt.js">
26
28
  <link rel="modulepreload" crossorigin href="/assets/paths-CDREouhi.js">
27
- <link rel="stylesheet" crossorigin href="/assets/GrowthLoading-B_Hh0CRS.css">
28
- <link rel="stylesheet" crossorigin href="/assets/AgentHand-D9sQu2vc.css">
29
- <link rel="stylesheet" crossorigin href="/assets/index-CYZi7E1e.css">
30
- <link rel="stylesheet" crossorigin href="/assets/employee-dialog-Bh5ccIbK.css">
29
+ <link rel="stylesheet" crossorigin href="/assets/GrowthLoading-CIuQ1icy.css">
30
+ <link rel="stylesheet" crossorigin href="/assets/AgentHand-Y83Oo36U.css">
31
+ <link rel="stylesheet" crossorigin href="/assets/index-CNp0tRNp.css">
31
32
  </head>
32
33
  <body>
33
34
  <div id="app"></div>
@@ -130,3 +130,9 @@ MCP 上下文有长度上限。被截断时必须显式补读完整记忆后再
130
130
 
131
131
  可见对话的 7 天归档、跨客户端接续、借调与验证升级见
132
132
  [对话与协作](agent-conversations-and-collaboration.md)。
133
+
134
+ ## 必需的回复身份回执
135
+
136
+ `begin_task_context` 和 `get_collaboration_preferences` 始终返回 `agent_receipt`,其中 `required: true` 和 `markdown` 构成统一的回复契约。宿主 Agent 必须在每次最终回复中原样显示一次这行身份与个人页面链接;问候、失败、没有可沉淀知识或关闭自动沉淀都不例外。无可用授权身份时返回 `FULI Agent:未选定`,不借用上次任务的身份。旧版本入口没有回执时应明确说明身份不可用。
137
+
138
+ MCP 与 Hook 交付会为完整回执保留空间,其他上下文超长时也不截断回执;预算不足以容纳回执时返回明确错误。该要求通过共享 MCP 指令、入口说明和操作 Skill 交付;外部宿主最终生成的文字仍由该宿主负责遵守,Fuli 不伪称能拦截所有客户端输出。身份回执不证明模型工作者已经启动,也不证明知识或会话已经保存。
@@ -0,0 +1,46 @@
1
+ # Agent Roundtable
2
+
3
+ Roundtable gives invited AI participants a shared goal, public responsibilities, addressed messages, and an ordered workflow from discussion to implementation and review.
4
+
5
+ ## Start
6
+
7
+ Requires Node.js 24.12 or newer.
8
+
9
+ ```sh
10
+ npm install -g fuli-context@latest
11
+ fl roundtable serve --data-dir ./roundtable-data --port 3738
12
+ ```
13
+
14
+ Open the local Roundtable page, create a goal, select 2–6 seats and issue an invitation for each participant. Each room has one moderator; collaboration rooms also have an implementer and an independent reviewer. Room history persists in the selected data directory.
15
+
16
+ ## AI onboarding
17
+
18
+ Connect the invited client to the room MCP URL shown by the invitation dialog, with its seat credential in the client's Bearer authentication setting. The MCP server supplies onboarding instructions and tools:
19
+
20
+ 1. `discover_roundtable` identifies the participant's seat, workflow, roster and next action.
21
+ 2. `join_roundtable` accepts the participant's own introduction, responsibilities and capabilities.
22
+ 3. `discover_roundtable` finds matching peers; `message_roundtable` sends a room-visible question or handoff to a selected seat.
23
+ 4. `read_roundtable` retrieves shared messages and tasks.
24
+ 5. `claim_roundtable_turn` claims the participant's assigned turn. `submit_roundtable_turn` records the result, artifacts and review verdict.
25
+
26
+ The room-specific MCP connection supplies its room ID automatically. When using these tools through the general FULI MCP server, supply the room ID and seat credential explicitly.
27
+
28
+ Self-descriptions help peers choose collaborators. They do not change the seat's execution grants. Peer messages are shared task material; room ownership and permissions remain with the user.
29
+
30
+ ## Local workers
31
+
32
+ Store the invitation in `FULI_ROUNDTABLE_TOKEN`, then run a worker with an already configured client:
33
+
34
+ ```sh
35
+ fl roundtable worker --url https://COORDINATOR --room ROOM_ID --runtime codex --workspace ./project
36
+ ```
37
+
38
+ Use `claude-code`, `pi`, `grok` or `a2a` for the corresponding adapter. Workers default to read only. Implementation requires both an owner-granted workspace and `--allow-write`. Reviews remain read only.
39
+
40
+ Grok uses `XAI_API_KEY` and `XAI_MODEL`. A2A uses `--a2a-url` and, when needed, `FULI_A2A_TOKEN`. Pi uses an installed Ollama model selected with `--model`; it is an experimental adapter and requires a tool-capable model with sufficient context.
41
+
42
+ ## Sharing a coordinator
43
+
44
+ Use a reachable HTTPS endpoint and `--public-url https://COORDINATOR`. Expose `/roundtable-peer/` through the proxy; retain the owner console on local loopback. Each invitation is limited to one room and seat and can be revoked.
45
+
46
+ Roundtable shares task messages and artifact references. Give reviewers authorized access to the actual artifacts through the shared workspace or referenced revision. Pause, resume, stop and completion remain available to the room owner.
@@ -1,5 +1,6 @@
1
1
  from contextlib import asynccontextmanager
2
2
  from typing import Annotated
3
+ from importlib.metadata import version
3
4
 
4
5
  from fastapi import Depends, FastAPI, Header, HTTPException, Query
5
6
 
@@ -238,7 +239,8 @@ def create_app(settings: Settings | None = None) -> FastAPI:
238
239
 
239
240
  @application.get('/health')
240
241
  async def health() -> dict:
241
- return await store.health()
242
+ return {**await store.health(), 'provider_version': version('fuli-graph-provider'),
243
+ 'transcript_contract': 1}
242
244
 
243
245
  @application.post('/v1/bootstrap', response_model=BootstrapResult)
244
246
  async def bootstrap(
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "fuli-graph-provider"
3
- version = "0.8.3"
3
+ version = "0.10.0"
4
4
  description = "Graphiti-backed personal and shared project provider for Fuli."
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "fuli-context",
3
- "version": "0.9.0-beta.2",
3
+ "version": "0.10.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "fuli-context",
9
- "version": "0.9.0-beta.2",
9
+ "version": "0.10.0",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@a2a-js/sdk": "1.3.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fuli-context",
3
- "version": "0.9.0-beta.2",
3
+ "version": "0.10.0",
4
4
  "description": "Local-first collaboration relationship graph for AI agents.",
5
5
  "type": "module",
6
6
  "files": [
@@ -14,9 +14,7 @@
14
14
  "docs/agent-conversations-and-collaboration.md",
15
15
  "docs/employee-agents.md",
16
16
  "docs/agent-interface-architecture.md",
17
- "docs/roundtable-beta-testing.md",
18
- "docs/roundtable-beta-validation.md",
19
- "docs/roundtable-research.md",
17
+ "docs/roundtable.md",
20
18
  "examples/external-knowledge/markdown-folder.mjs",
21
19
  "graph-provider/Dockerfile",
22
20
  "graph-provider/pyproject.toml",
@@ -31,6 +31,10 @@ for Agents without an equivalent lifecycle hook. Fuli uses both only for this lo
31
31
  never stores or returns them, and resolves the exact local personal project itself. Do not infer
32
32
  or guess `personalProjectId` in the Agent.
33
33
 
34
+ ## Mandatory reply identity
35
+
36
+ Every final user-visible reply MUST include the current task’s `agent_receipt.markdown` unchanged exactly once. This includes greetings, status-only replies, failures, `retain_nothing`, and capture-disabled tasks. The receipt is independent of whether a memory checkpoint was saved. Never substitute a client name, configured peer, or an earlier task’s owner. If a legacy/unavailable entry supplies no receipt, explicitly state that the FULI Agent identity is unavailable. A receipt with no authorized owner already supplies the correct neutral text.
37
+
34
38
  Apply only `effective_preferences`. Personal-global preferences apply in every user task;
35
39
  project-scoped preferences layer on only for the exact selected project. Do not apply items
36
40
  listed as conflicts, and do not borrow preferences from a related, similarly named, or guessed
@@ -284,7 +288,7 @@ worker session (`workerRuntime.sessionId`, or a worker session link only when su
284
288
  Label `sourceApplication` and `sourceSessionId` separately as the reporting host. They do not
285
289
  identify an external worker; do not substitute them for missing worker evidence.
286
290
  Use only the source-labelled cumulative `tokenUsage` reported for that worker. If it is absent,
287
- show `not reported`; never estimate it or copy a conversation-wide total into a worker row. If no
291
+ show `-`; never estimate it or copy a conversation-wide total into a worker row. If no
288
292
  worker session link exists, show `workerRuntime.sessionId` or `not reported`; never invent a link. This applies only
289
293
  to Provider-reported actual workers. When empty `executionSummary` is returned, omit rows; an absent
290
294
  `executionSummary` also omits rows. Configured, allowed, or available clients/executors are not evidence
@@ -50,6 +50,10 @@ Read each returned worker's `context.agent.profile.allowedClients` and `executor
50
50
  - On partial external sync, preserve the binding, report per-target/source failures, and let the user choose whether to retry.
51
51
  - On an unknown tool or missing parity mapping, record the missing capability as a product defect instead of substituting browser automation.
52
52
 
53
+ ## Mandatory reply identity
54
+
55
+ Every final user-visible reply MUST include the current task’s `agent_receipt.markdown` unchanged exactly once. This includes greetings, status-only replies, failures, `retain_nothing`, and capture-disabled tasks. The receipt is independent of whether a memory checkpoint was saved. Never substitute a client name, configured peer, or an earlier task’s owner. If a legacy/unavailable entry supplies no receipt, explicitly state that the FULI Agent identity is unavailable. A receipt with no authorized owner already supplies the correct neutral text.
56
+
53
57
  ## Completion response
54
58
 
55
59
  State what changed, the exact project or item scope, the verification result, and any remaining human-only action. Do not claim success from a configured capability or submitted request alone.
@@ -290,7 +290,7 @@ export const GRAPH_TOOL_DEFINITIONS = [
290
290
  {
291
291
  name: 'begin_task_context',
292
292
  title: 'LIFECYCLE · Begin a Fuli-aware task',
293
- description: 'Lifecycle entry used by supported Agent hooks before the model processes a user prompt. It resolves the exact local project from projectPath, loads effective collaboration preferences, and uses taskPrompt transiently for bounded automatic recall when the request signals a stable prior fact, runbook, URL, decision, release, deployment, or authentication method. It never stores or returns projectPath or taskPrompt. Inspect task_knowledge_recall before asking the user to repeat stable context. Returns an opaque taskContextToken. Fuli setup generates Claude Code and Codex UserPromptSubmit hook configuration and a Cursor task-entry adapter. Configuration is not proof of host loading, trust, or execution. Use supplied hook context without repeating the preference fallback; Cursor retrieves context through the Agent when its hook cannot inject it.',
293
+ description: 'Lifecycle entry used by supported Agent hooks before the model processes a user prompt. It resolves the exact local project from projectPath, loads effective collaboration preferences, and uses taskPrompt transiently for bounded automatic recall when the request signals a stable prior fact, runbook, URL, decision, release, deployment, or authentication method. It never stores or returns projectPath or taskPrompt. Inspect task_knowledge_recall before asking the user to repeat stable context. Returns an opaque taskContextToken and a required agent_receipt. Include agent_receipt.markdown unchanged exactly once in every final user-visible reply, including greetings and capture-disabled tasks. Fuli setup generates Claude Code and Codex UserPromptSubmit hook configuration and a Cursor task-entry adapter. Configuration is not proof of host loading, trust, or execution. Use supplied hook context without repeating the preference fallback; Cursor retrieves context through the Agent when its hook cannot inject it.',
294
294
  inputSchema: objectSchema({
295
295
  sessionId: id,
296
296
  turnId: id,
@@ -330,7 +330,7 @@ export const GRAPH_TOOL_DEFINITIONS = [
330
330
  {
331
331
  name: 'get_collaboration_preferences',
332
332
  title: 'READ FIRST · Load task collaboration preferences',
333
- description: 'Fallback for Agents or tasks without begin_task_context hook context. When no hook context was supplied, call this exact tool name at the start of every user task before any other tool or answer; never substitute a project action tool. Do not call it redundantly when the entry hook already supplied preferences. Pass projectPath as the current working directory and taskPrompt as the current user request. Fuli uses both transiently, never stores or returns them, resolves one exact registered local project, and performs bounded automatic recall only when the request signals stable prior context. Inspect task_knowledge_recall before asking the user to repeat a project fact or method. On a miss, search_current_project_knowledge with one to four focused action, artifact, target-system, or identifier queries; never use the full conversational request as the only query. Apply effective_preferences before answering or constructing tool arguments. Resolve only relevant deferred_conflicts first. For write tools, enforce preferences in the actual payload; the final answer is not compliance. Personal-global preferences always apply; conflicted, pending, invalid, ambiguous-project, and unrelated-project items never auto-apply. Automatic injection does not count as usage evidence. personalProjectId remains an explicit compatibility override.',
333
+ description: 'Fallback for Agents or tasks without begin_task_context hook context. When no hook context was supplied, call this exact tool name at the start of every user task before any other tool or answer; never substitute a project action tool. Do not call it redundantly when the entry hook already supplied preferences. Pass projectPath as the current working directory and taskPrompt as the current user request. Fuli uses both transiently, never stores or returns them, resolves one exact registered local project, and performs bounded automatic recall only when the request signals stable prior context. Inspect task_knowledge_recall before asking the user to repeat a project fact or method. On a miss, search_current_project_knowledge with one to four focused action, artifact, target-system, or identifier queries; never use the full conversational request as the only query. Apply effective_preferences before answering or constructing tool arguments. Resolve only relevant deferred_conflicts first. For write tools, enforce preferences in the actual payload; the final answer is not compliance. Personal-global preferences always apply; conflicted, pending, invalid, ambiguous-project, and unrelated-project items never auto-apply. Automatic injection does not count as usage evidence. personalProjectId remains an explicit compatibility override. Include the returned agent_receipt.markdown unchanged exactly once in every final reply, including greetings and capture-disabled tasks; never reuse an earlier owner.',
334
334
  inputSchema: objectSchema({
335
335
  sessionId: id,
336
336
  projectPath: boundedString(4096),
@@ -37,19 +37,7 @@ export async function claudeLifecycleOutput(event, input, invoke) {
37
37
  const check = await invoke('verify_task_checkpoint', { sessionId, ...source });
38
38
  const reason = boundedHookMessage(check?.reason);
39
39
  if (check?.decision !== 'block' || !reason.trim()) return {};
40
- if (input.stop_hook_active === true) {
41
- if (typeof check.task_context_token === 'string' && check.task_context_token.trim()) {
42
- await invoke('checkpoint_task_knowledge', {
43
- taskContextToken: check.task_context_token,
44
- disposition: 'retain_nothing',
45
- reason: 'Claude Code Stop hook fallback after one checkpoint continuation.',
46
- workLog: { status: 'incomplete', summary: 'The host stopped before the employee submitted a work summary. Review the prior task before resuming.' },
47
- ...source
48
- });
49
- }
50
- return {};
51
- }
52
- return { decision: 'block', reason };
40
+ return { systemMessage: reason };
53
41
  }
54
42
 
55
43
  export function claudeLifecycleUnavailable(event) {
@@ -80,7 +68,7 @@ export async function runClaudeLifecycleHook(args, dependencies = {}) {
80
68
  let sync = await syncConversationTranscript(app, input, 'claude_code', {
81
69
  normalize: normalizeClaudeRecord, verify: verifyClaudeTranscript
82
70
  }, guard);
83
- if (event === 'UserPromptSubmit' && sync.entryBlocked) return { decision: 'block', reason: sync.reason };
71
+ if (event === 'UserPromptSubmit' && sync.entryBlocked) return { systemMessage: boundedHookMessage(sync.reason) };
84
72
  const entryGuard = sync.status === 'capture_disabled' ? null : guard;
85
73
  if (event === 'UserPromptSubmit' && entryGuard?.value) await entryGuard.write({ ...entryGuard.value, phase: 'beginning' });
86
74
  const output = await claudeLifecycleOutput(event, input, async (name, parameters) => {
@@ -91,12 +79,12 @@ export async function runClaudeLifecycleHook(args, dependencies = {}) {
91
79
  if (event === 'UserPromptSubmit') sync = await claimTranscriptBoundary(app, input, 'claude_code', sync, {
92
80
  normalize: normalizeClaudeRecord, verify: verifyClaudeTranscript
93
81
  }, entryGuard);
94
- if (event === 'UserPromptSubmit' && sync.entryBlocked) return { decision: 'block', reason: sync.reason };
82
+ if (event === 'UserPromptSubmit' && sync.entryBlocked) return { systemMessage: boundedHookMessage(sync.reason) };
95
83
  return withTranscriptNotice(output, sync);
96
84
  });
97
85
  } catch (error) {
98
86
  if (event !== 'UserPromptSubmit' || !app.getCapturePolicy?.().enabled || !input.transcript_path) throw error;
99
- return { decision: 'block', reason: error.code === 'EADDRINUSE'
87
+ return { systemMessage: error.code === 'EADDRINUSE'
100
88
  ? 'The session handoff lock is occupied. Retry after the current hook finishes; if it persists, start a new host session and resume the intended Agent.'
101
89
  : 'Fuli transcript handoff could not be completed safely. Retry task entry; no previous Agent context was supplied.' };
102
90
  }
@@ -127,7 +115,6 @@ async function main() {
127
115
  ? configured : 28000;
128
116
  const controller = new AbortController();
129
117
  let emitted = false;
130
- let guarded = false;
131
118
  const emit = (output, callback) => {
132
119
  if (emitted) return;
133
120
  emitted = true;
@@ -137,11 +124,11 @@ async function main() {
137
124
  // No prompt, transcript, path or raw exception is written to diagnostics.
138
125
  const deadline = setTimeout(() => {
139
126
  controller.abort();
140
- emit(guarded && event === 'UserPromptSubmit' ? { decision: 'block', reason: 'Fuli transcript handoff timed out. Retry task entry; the previous Agent context was not supplied.' } : claudeLifecycleUnavailable(event), () => process.exit(0));
127
+ emit(claudeLifecycleUnavailable(event), () => process.exit(0));
141
128
  }, timeoutMs);
142
129
  const abort = setTimeout(() => controller.abort(), Math.max(1, timeoutMs - 1500));
143
130
  try {
144
- const output = await runClaudeLifecycleHook(args, { signal: controller.signal, onTranscriptGuard: () => { guarded = true; } });
131
+ const output = await runClaudeLifecycleHook(args, { signal: controller.signal });
145
132
  emit(output);
146
133
  } catch {
147
134
  emit(claudeLifecycleUnavailable(event));
@@ -26,20 +26,9 @@ export async function codexStopLifecycleOutput(input, invoke) {
26
26
  if (check?.decision !== 'block' || typeof check.reason !== 'string' || !check.reason.trim()) {
27
27
  return {};
28
28
  }
29
- if (input.stop_hook_active === true) {
30
- if (typeof check.task_context_token === 'string' && check.task_context_token.trim()) {
31
- await invoke('checkpoint_task_knowledge', {
32
- taskContextToken: check.task_context_token,
33
- disposition: 'retain_nothing',
34
- reason: 'Codex Stop hook fallback after one checkpoint continuation.',
35
- workLog: { status: 'incomplete', summary: 'The host stopped before the employee submitted a work summary. Review the prior task before resuming.' },
36
- sourceApplication: 'codex',
37
- sourceSessionId: sessionId
38
- });
39
- }
40
- return {};
41
- }
42
- return { decision: 'block', reason: boundedHookMessage(check.reason) };
29
+ // Checkpoints are advisory to the host. Never force another model turn or
30
+ // fabricate a work log merely because the user is ending the conversation.
31
+ return { systemMessage: boundedHookMessage(check.reason) };
43
32
  }
44
33
 
45
34
  export async function codexLifecycleOutput(event, input, invoke) {
@@ -73,6 +62,9 @@ export async function runCodexLifecycleHook(args, dependencies = {}) {
73
62
  );
74
63
  let app;
75
64
  let leases;
65
+ let closing;
66
+ const cleanup = () => closing ??= Promise.allSettled([closeQuietly(leases), closeQuietly(app)]);
67
+ dependencies.onCleanup?.(cleanup);
76
68
  try {
77
69
  app = (dependencies.openApplication ?? openFederatedGraphApplication)({
78
70
  runtimeConfigPath
@@ -87,32 +79,38 @@ export async function runCodexLifecycleHook(args, dependencies = {}) {
87
79
  let sync = await syncConversationTranscript(app, input, 'codex', {
88
80
  normalize: normalizeCodexRecord, verify: verifyCodexTranscript
89
81
  }, guard);
90
- if (event === 'UserPromptSubmit' && sync.entryBlocked) return { decision: 'block', reason: sync.reason };
82
+ if (event === 'UserPromptSubmit' && !guard?.value
83
+ && ['current_task_endpoint_unavailable', 'current_task_lookup_unavailable'].includes(sync.code)) {
84
+ // Before any ownership was read, let the native message proceed
85
+ // without beginning a Fuli task or restoring/importing history.
86
+ // Existing guards and all later failures remain fail-closed.
87
+ return { systemMessage: `Fuli: ${sync.reason}. Message submission is allowed; no saved Agent context was loaded or changed.` };
88
+ }
89
+ if (event === 'UserPromptSubmit' && sync.entryBlocked) return { systemMessage: boundedHookMessage(sync.reason) };
91
90
  const entryGuard = sync.status === 'capture_disabled' ? null : guard;
92
91
  if (event === 'UserPromptSubmit' && entryGuard?.value) await entryGuard.write({ ...entryGuard.value, phase: 'beginning' });
93
92
  const result = await codexLifecycleOutput(event, input, async (name, parameters) => {
94
- const context = await invokeTool(app, name, parameters);
93
+ const context = await invokeTool(app, name, parameters, { signal: dependencies.signal });
95
94
  if (name === 'begin_task_context') await recordTranscriptTaskEntry(entryGuard, context);
96
95
  return context;
97
96
  });
98
97
  if (event === 'UserPromptSubmit') sync = await claimTranscriptBoundary(app, input, 'codex', sync, {
99
98
  normalize: normalizeCodexRecord, verify: verifyCodexTranscript
100
99
  }, entryGuard);
101
- if (event === 'UserPromptSubmit' && sync.entryBlocked) return { decision: 'block', reason: sync.reason };
100
+ if (event === 'UserPromptSubmit' && sync.entryBlocked) return { systemMessage: boundedHookMessage(sync.reason) };
102
101
  return withTranscriptNotice(result, sync);
103
102
  });
104
103
  } catch (error) {
105
104
  if (event !== 'UserPromptSubmit' || !app.getCapturePolicy?.().enabled || !input.transcript_path) throw error;
106
- return { decision: 'block', reason: error.code === 'EADDRINUSE'
105
+ return { systemMessage: error.code === 'EADDRINUSE'
107
106
  ? 'The session handoff lock is occupied. Retry after the current hook finishes; if it persists, start a new host session and resume the intended Agent.'
108
107
  : 'Fuli transcript handoff could not be completed safely. Retry task entry; no previous Agent context was supplied.' };
109
108
  }
110
- });
109
+ }, { signal: dependencies.signal });
111
110
  write(`${JSON.stringify(output)}\n`);
112
111
  return output;
113
112
  } finally {
114
- await closeQuietly(leases);
115
- await closeQuietly(app);
113
+ await cleanup();
116
114
  }
117
115
  }
118
116
 
@@ -135,13 +133,46 @@ async function readHookInput() {
135
133
  return JSON.parse(Buffer.concat(chunks).toString('utf8'));
136
134
  }
137
135
 
138
- async function main() {
136
+ export async function runCodexLifecycleCommand(args, dependencies = {}) {
137
+ const configured = Number(args[args.indexOf('--timeout-ms') + 1]);
138
+ const timeoutMs = args.includes('--timeout-ms') && Number.isSafeInteger(configured) && configured > 0
139
+ ? Math.min(configured, 5000) : 5000;
140
+ const controller = new AbortController();
141
+ let emitted = false;
142
+ const write = value => {
143
+ if (emitted) return;
144
+ emitted = true;
145
+ (dependencies.write ?? (value => process.stdout.write(value)))(value);
146
+ };
147
+ const unavailable = JSON.stringify({ systemMessage: 'Fuli context is unavailable. Continue with the user request; saved context and checkpoint were not verified.' }) + '\n';
148
+ let cleanup = async () => {};
149
+ let deadline;
150
+ const expired = new Promise(resolve => {
151
+ deadline = setTimeout(async () => {
152
+ controller.abort();
153
+ write(unavailable);
154
+ // A broken dependency must not hold the host open. Give opened leases
155
+ // and connections a bounded chance to close before the process exits.
156
+ let grace;
157
+ await Promise.race([cleanup(), new Promise(done => { grace = setTimeout(done, 250); })]);
158
+ clearTimeout(grace);
159
+ resolve({ timedOut: true });
160
+ }, timeoutMs);
161
+ });
139
162
  try {
140
- await runCodexLifecycleHook(process.argv.slice(2));
141
- } catch {
142
- // Fail open without printing prompts, transcripts, paths or credentials.
143
- process.stdout.write('{}\n');
163
+ const running = runCodexLifecycleHook(args, { ...dependencies, signal: controller.signal, write,
164
+ onCleanup: close => { cleanup = close; } }).then(() => ({ timedOut: false }), () => {
165
+ // Never print prompts, transcripts, paths or credentials.
166
+ write(unavailable);
167
+ return { timedOut: false };
168
+ });
169
+ return await Promise.race([running, expired]);
170
+ } finally {
171
+ clearTimeout(deadline);
144
172
  }
145
173
  }
146
174
 
147
- if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) await main();
175
+ if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
176
+ const result = await runCodexLifecycleCommand(process.argv.slice(2));
177
+ if (result.timedOut) process.exit(0);
178
+ }
@@ -1,9 +1,12 @@
1
+ import { ROUNDTABLE_WORKER_BOUNDARY } from '../../roundtables/turn-prompt.js';
2
+
1
3
  // Discover the effective MCP configuration, then disable and verify every entry.
2
4
  // Empty TOML tables merge recursively and cannot clear inherited servers.
3
5
  export async function prepareCodexRoundtableConfig({ command, workspace, env, signal, runProcess,
4
6
  platform = process.platform }) {
5
7
  const options = ['--disable', 'plugins', '--disable', 'apps', '--disable', 'multi_agent',
6
8
  '-c', 'hooks.enabled=false', '-c', 'notify=[]', '-c', 'project_doc_max_bytes=0',
9
+ '-c', `developer_instructions=${JSON.stringify(ROUNDTABLE_WORKER_BOUNDARY)}`,
7
10
  '-c', 'sandbox_workspace_write.writable_roots=[]', '-c', 'sandbox_workspace_write.network_access=false',
8
11
  '-c', 'approval_policy="never"', '-c', 'approvals_reviewer="user"',
9
12
  '-c', 'features.browser_use=false', '-c', 'features.computer_use=false',