pikiloop 0.4.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 (154) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +353 -0
  3. package/README.v2.md +287 -0
  4. package/README.zh-CN.md +352 -0
  5. package/dashboard/dist/assets/AgentTab-UZPIhlkr.js +1 -0
  6. package/dashboard/dist/assets/DirBrowser-Ckcmi-Pi.js +1 -0
  7. package/dashboard/dist/assets/ExtensionsTab-KZhEDrdu.js +1 -0
  8. package/dashboard/dist/assets/IMAccessTab-Bd_IY1GQ.js +1 -0
  9. package/dashboard/dist/assets/Modal-CTeL0y7P.js +1 -0
  10. package/dashboard/dist/assets/Modals-axftHasy.js +1 -0
  11. package/dashboard/dist/assets/Select-C8tOdPhe.js +1 -0
  12. package/dashboard/dist/assets/SessionPanel-C1geSRxw.js +1 -0
  13. package/dashboard/dist/assets/SystemTab-DBDkaPiO.js +1 -0
  14. package/dashboard/dist/assets/anthropic-BAdojD7P.ico +0 -0
  15. package/dashboard/dist/assets/codex-DYadqqp0.png +0 -0
  16. package/dashboard/dist/assets/deepseek-BeYNZEk0.ico +0 -0
  17. package/dashboard/dist/assets/doubao-DloFDuFR.png +0 -0
  18. package/dashboard/dist/assets/feishu-C4OMrjCW.ico +0 -0
  19. package/dashboard/dist/assets/gemini-BYkEpiWr.svg +1 -0
  20. package/dashboard/dist/assets/hermes-BAarh-tH.png +0 -0
  21. package/dashboard/dist/assets/index-CpM4CqZJ.js +23 -0
  22. package/dashboard/dist/assets/index-DXSohzrE.js +3 -0
  23. package/dashboard/dist/assets/index-reSbuley.css +1 -0
  24. package/dashboard/dist/assets/markdown-DxQYQFeH.js +29 -0
  25. package/dashboard/dist/assets/minimax-PuEGTfrF.ico +0 -0
  26. package/dashboard/dist/assets/mlx-DhWwjtMw.png +0 -0
  27. package/dashboard/dist/assets/ollama-Bt9O-2K_.png +0 -0
  28. package/dashboard/dist/assets/openrouter-CsJ_bD5Q.ico +0 -0
  29. package/dashboard/dist/assets/playwright-BldPFZgC.ico +0 -0
  30. package/dashboard/dist/assets/qwen-xykkX0_y.png +0 -0
  31. package/dashboard/dist/assets/react-vendor-C7Sl8SE7.js +9 -0
  32. package/dashboard/dist/assets/router-DHISdpPk.js +3 -0
  33. package/dashboard/dist/assets/shared-BIP_4k4I.js +1 -0
  34. package/dashboard/dist/favicon.svg +28 -0
  35. package/dashboard/dist/index.html +17 -0
  36. package/dist/agent/acp-client.js +261 -0
  37. package/dist/agent/auto-update.js +432 -0
  38. package/dist/agent/await-resume.js +50 -0
  39. package/dist/agent/cli/auth.js +325 -0
  40. package/dist/agent/cli/catalog.js +40 -0
  41. package/dist/agent/cli/detector.js +136 -0
  42. package/dist/agent/cli/index.js +7 -0
  43. package/dist/agent/cli/registry.js +33 -0
  44. package/dist/agent/driver.js +39 -0
  45. package/dist/agent/drivers/claude-tui.js +2297 -0
  46. package/dist/agent/drivers/claude.js +2689 -0
  47. package/dist/agent/drivers/codex.js +2210 -0
  48. package/dist/agent/drivers/gemini.js +1059 -0
  49. package/dist/agent/drivers/hermes.js +795 -0
  50. package/dist/agent/goal.js +274 -0
  51. package/dist/agent/handover.js +130 -0
  52. package/dist/agent/images.js +355 -0
  53. package/dist/agent/index.js +50 -0
  54. package/dist/agent/mcp/bridge.js +791 -0
  55. package/dist/agent/mcp/extensions.js +637 -0
  56. package/dist/agent/mcp/oauth.js +353 -0
  57. package/dist/agent/mcp/registry.js +119 -0
  58. package/dist/agent/mcp/session-server.js +229 -0
  59. package/dist/agent/mcp/tools/ask-user.js +113 -0
  60. package/dist/agent/mcp/tools/await-resume.js +77 -0
  61. package/dist/agent/mcp/tools/goal.js +144 -0
  62. package/dist/agent/mcp/tools/types.js +12 -0
  63. package/dist/agent/mcp/tools/workspace.js +212 -0
  64. package/dist/agent/npm.js +31 -0
  65. package/dist/agent/session.js +1206 -0
  66. package/dist/agent/skill-installer.js +160 -0
  67. package/dist/agent/skills.js +257 -0
  68. package/dist/agent/stream.js +743 -0
  69. package/dist/agent/types.js +13 -0
  70. package/dist/agent/utils.js +687 -0
  71. package/dist/bot/bot.js +2499 -0
  72. package/dist/bot/command-ui.js +633 -0
  73. package/dist/bot/commands.js +513 -0
  74. package/dist/bot/headless-bot.js +36 -0
  75. package/dist/bot/host.js +192 -0
  76. package/dist/bot/human-loop.js +168 -0
  77. package/dist/bot/menu.js +48 -0
  78. package/dist/bot/orchestration.js +79 -0
  79. package/dist/bot/render-shared.js +309 -0
  80. package/dist/bot/session-hub.js +361 -0
  81. package/dist/bot/session-status.js +55 -0
  82. package/dist/bot/streaming.js +309 -0
  83. package/dist/browser-profile.js +579 -0
  84. package/dist/browser-supervisor.js +249 -0
  85. package/dist/catalog/cli-tools.js +421 -0
  86. package/dist/catalog/index.js +21 -0
  87. package/dist/catalog/local-models.js +94 -0
  88. package/dist/catalog/mcp-servers.js +315 -0
  89. package/dist/catalog/skill-repos.js +173 -0
  90. package/dist/channels/base.js +55 -0
  91. package/dist/channels/dingtalk/bot.js +549 -0
  92. package/dist/channels/dingtalk/channel.js +268 -0
  93. package/dist/channels/discord/bot.js +552 -0
  94. package/dist/channels/discord/channel.js +245 -0
  95. package/dist/channels/feishu/bot.js +1275 -0
  96. package/dist/channels/feishu/channel.js +911 -0
  97. package/dist/channels/feishu/markdown.js +91 -0
  98. package/dist/channels/feishu/render.js +619 -0
  99. package/dist/channels/health.js +109 -0
  100. package/dist/channels/slack/bot.js +554 -0
  101. package/dist/channels/slack/channel.js +283 -0
  102. package/dist/channels/states.js +6 -0
  103. package/dist/channels/telegram/bot.js +1310 -0
  104. package/dist/channels/telegram/channel.js +820 -0
  105. package/dist/channels/telegram/directory.js +111 -0
  106. package/dist/channels/telegram/live-preview.js +220 -0
  107. package/dist/channels/telegram/render.js +384 -0
  108. package/dist/channels/wecom/bot.js +558 -0
  109. package/dist/channels/wecom/channel.js +479 -0
  110. package/dist/channels/weixin/api.js +520 -0
  111. package/dist/channels/weixin/bot.js +1000 -0
  112. package/dist/channels/weixin/channel.js +222 -0
  113. package/dist/cli/autostart.js +262 -0
  114. package/dist/cli/channel-supervisor.js +313 -0
  115. package/dist/cli/channels.js +54 -0
  116. package/dist/cli/main.js +726 -0
  117. package/dist/cli/onboarding.js +227 -0
  118. package/dist/cli/run.js +308 -0
  119. package/dist/cli/setup-wizard.js +235 -0
  120. package/dist/core/config/runtime-config.js +201 -0
  121. package/dist/core/config/user-config.js +510 -0
  122. package/dist/core/config/validation.js +521 -0
  123. package/dist/core/constants.js +400 -0
  124. package/dist/core/git.js +145 -0
  125. package/dist/core/legacy-compat.js +60 -0
  126. package/dist/core/logging.js +101 -0
  127. package/dist/core/platform.js +59 -0
  128. package/dist/core/process-control.js +315 -0
  129. package/dist/core/secrets/index.js +42 -0
  130. package/dist/core/secrets/inline-seal.js +60 -0
  131. package/dist/core/secrets/ref.js +33 -0
  132. package/dist/core/secrets/resolver.js +65 -0
  133. package/dist/core/secrets/store.js +63 -0
  134. package/dist/core/utils.js +233 -0
  135. package/dist/core/version.js +15 -0
  136. package/dist/dashboard/platform.js +219 -0
  137. package/dist/dashboard/routes/agents.js +450 -0
  138. package/dist/dashboard/routes/cli.js +174 -0
  139. package/dist/dashboard/routes/config.js +523 -0
  140. package/dist/dashboard/routes/extensions.js +745 -0
  141. package/dist/dashboard/routes/local-models.js +290 -0
  142. package/dist/dashboard/routes/models.js +324 -0
  143. package/dist/dashboard/routes/sessions.js +838 -0
  144. package/dist/dashboard/runtime.js +410 -0
  145. package/dist/dashboard/server.js +237 -0
  146. package/dist/dashboard/session-control.js +347 -0
  147. package/dist/model/catalog.js +104 -0
  148. package/dist/model/index.js +20 -0
  149. package/dist/model/injector.js +272 -0
  150. package/dist/model/provider-models.js +112 -0
  151. package/dist/model/store.js +212 -0
  152. package/dist/model/types.js +13 -0
  153. package/dist/model/validation.js +203 -0
  154. package/package.json +82 -0
@@ -0,0 +1,3 @@
1
+ import{r as i}from"./react-vendor-C7Sl8SE7.js";var ue="popstate";function ce(e){return typeof e=="object"&&e!=null&&"pathname"in e&&"search"in e&&"hash"in e&&"state"in e&&"key"in e}function _e(e={}){function t(n,a){let o=a.state?.masked,{pathname:l,search:u,hash:s}=o||n.location;return Z("",{pathname:l,search:u,hash:s},a.state&&a.state.usr||null,a.state&&a.state.key||"default",o?{pathname:n.location.pathname,search:n.location.search,hash:n.location.hash}:void 0)}function r(n,a){return typeof a=="string"?a:U(a)}return Ue(t,r,null,e)}function E(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function S(e,t){if(!e){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function Me(){return Math.random().toString(36).substring(2,10)}function de(e,t){return{usr:e.state,key:e.key,idx:t,masked:e.unstable_mask?{pathname:e.pathname,search:e.search,hash:e.hash}:void 0}}function Z(e,t,r=null,n,a){return{pathname:typeof e=="string"?e:e.pathname,search:"",hash:"",...typeof t=="string"?O(t):t,state:r,key:t&&t.key||n||Me(),unstable_mask:a}}function U({pathname:e="/",search:t="",hash:r=""}){return t&&t!=="?"&&(e+=t.charAt(0)==="?"?t:"?"+t),r&&r!=="#"&&(e+=r.charAt(0)==="#"?r:"#"+r),e}function O(e){let t={};if(e){let r=e.indexOf("#");r>=0&&(t.hash=e.substring(r),e=e.substring(0,r));let n=e.indexOf("?");n>=0&&(t.search=e.substring(n),e=e.substring(0,n)),e&&(t.pathname=e)}return t}function Ue(e,t,r,n={}){let{window:a=document.defaultView,v5Compat:o=!1}=n,l=a.history,u="POP",s=null,d=f();d==null&&(d=0,l.replaceState({...l.state,idx:d},""));function f(){return(l.state||{idx:null}).idx}function c(){u="POP";let h=f(),v=h==null?null:h-d;d=h,s&&s({action:u,location:m.location,delta:v})}function p(h,v){u="PUSH";let R=ce(h)?h:Z(m.location,h,v);d=f()+1;let w=de(R,d),C=m.createHref(R.unstable_mask||R);try{l.pushState(w,"",C)}catch(x){if(x instanceof DOMException&&x.name==="DataCloneError")throw x;a.location.assign(C)}o&&s&&s({action:u,location:m.location,delta:1})}function g(h,v){u="REPLACE";let R=ce(h)?h:Z(m.location,h,v);d=f();let w=de(R,d),C=m.createHref(R.unstable_mask||R);l.replaceState(w,"",C),o&&s&&s({action:u,location:m.location,delta:0})}function y(h){return Ae(h)}let m={get action(){return u},get location(){return e(a,l)},listen(h){if(s)throw new Error("A history only accepts one active listener");return a.addEventListener(ue,c),s=h,()=>{a.removeEventListener(ue,c),s=null}},createHref(h){return t(a,h)},createURL:y,encodeLocation(h){let v=y(h);return{pathname:v.pathname,search:v.search,hash:v.hash}},push:p,replace:g,go(h){return l.go(h)}};return m}function Ae(e,t=!1){let r="http://localhost";typeof window<"u"&&(r=window.location.origin!=="null"?window.location.origin:window.location.href),E(r,"No window.location.(origin|href) available to create URL");let n=typeof e=="string"?e:U(e);return n=n.replace(/ $/,"%20"),!t&&n.startsWith("//")&&(n=r+n),new URL(n,r)}function ye(e,t,r="/"){return We(e,t,r,!1)}function We(e,t,r,n){let a=typeof t=="string"?O(t):t,o=k(a.pathname||"/",r);if(o==null)return null;let l=ge(e);He(l);let u=null;for(let s=0;u==null&&s<l.length;++s){let d=Ze(o);u=Xe(l[s],d,n)}return u}function ge(e,t=[],r=[],n="",a=!1){let o=(l,u,s=a,d)=>{let f={relativePath:d===void 0?l.path||"":d,caseSensitive:l.caseSensitive===!0,childrenIndex:u,route:l};if(f.relativePath.startsWith("/")){if(!f.relativePath.startsWith(n)&&s)return;E(f.relativePath.startsWith(n),`Absolute route path "${f.relativePath}" nested under path "${n}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),f.relativePath=f.relativePath.slice(n.length)}let c=P([n,f.relativePath]),p=r.concat(f);l.children&&l.children.length>0&&(E(l.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${c}".`),ge(l.children,t,p,c,s)),!(l.path==null&&!l.index)&&t.push({path:c,score:Ge(c,l.index),routesMeta:p})};return e.forEach((l,u)=>{if(l.path===""||!l.path?.includes("?"))o(l,u);else for(let s of ve(l.path))o(l,u,!0,s)}),t}function ve(e){let t=e.split("/");if(t.length===0)return[];let[r,...n]=t,a=r.endsWith("?"),o=r.replace(/\?$/,"");if(n.length===0)return a?[o,""]:[o];let l=ve(n.join("/")),u=[];return u.push(...l.map(s=>s===""?o:[o,s].join("/"))),a&&u.push(...l),u.map(s=>e.startsWith("/")&&s===""?"/":s)}function He(e){e.sort((t,r)=>t.score!==r.score?r.score-t.score:qe(t.routesMeta.map(n=>n.childrenIndex),r.routesMeta.map(n=>n.childrenIndex)))}var je=/^:[\w-]+$/,ze=3,Ve=2,Je=1,Ke=10,Ye=-2,fe=e=>e==="*";function Ge(e,t){let r=e.split("/"),n=r.length;return r.some(fe)&&(n+=Ye),t&&(n+=Ve),r.filter(a=>!fe(a)).reduce((a,o)=>a+(je.test(o)?ze:o===""?Je:Ke),n)}function qe(e,t){return e.length===t.length&&e.slice(0,-1).every((n,a)=>n===t[a])?e[e.length-1]-t[t.length-1]:0}function Xe(e,t,r=!1){let{routesMeta:n}=e,a={},o="/",l=[];for(let u=0;u<n.length;++u){let s=n[u],d=u===n.length-1,f=o==="/"?t:t.slice(o.length)||"/",c=V({path:s.relativePath,caseSensitive:s.caseSensitive,end:d},f),p=s.route;if(!c&&d&&r&&!n[n.length-1].route.index&&(c=V({path:s.relativePath,caseSensitive:s.caseSensitive,end:!1},f)),!c)return null;Object.assign(a,c.params),l.push({params:a,pathname:P([o,c.pathname]),pathnameBase:nt(P([o,c.pathnameBase])),route:p}),c.pathnameBase!=="/"&&(o=P([o,c.pathnameBase]))}return l}function V(e,t){typeof e=="string"&&(e={path:e,caseSensitive:!1,end:!0});let[r,n]=Qe(e.path,e.caseSensitive,e.end),a=t.match(r);if(!a)return null;let o=a[0],l=o.replace(/(.)\/+$/,"$1"),u=a.slice(1);return{params:n.reduce((d,{paramName:f,isOptional:c},p)=>{if(f==="*"){let y=u[p]||"";l=o.slice(0,o.length-y.length).replace(/(.)\/+$/,"$1")}const g=u[p];return c&&!g?d[f]=void 0:d[f]=(g||"").replace(/%2F/g,"/"),d},{}),pathname:o,pathnameBase:l,pattern:e}}function Qe(e,t=!1,r=!0){S(e==="*"||!e.endsWith("*")||e.endsWith("/*"),`Route path "${e}" will be treated as if it were "${e.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${e.replace(/\*$/,"/*")}".`);let n=[],a="^"+e.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(l,u,s,d,f)=>{if(n.push({paramName:u,isOptional:s!=null}),s){let c=f.charAt(d+l.length);return c&&c!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return e.endsWith("*")?(n.push({paramName:"*"}),a+=e==="*"||e==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):r?a+="\\/*$":e!==""&&e!=="/"&&(a+="(?:(?=\\/|$))"),[new RegExp(a,t?void 0:"i"),n]}function Ze(e){try{return e.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return S(!1,`The URL path "${e}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),e}}function k(e,t){if(t==="/")return e;if(!e.toLowerCase().startsWith(t.toLowerCase()))return null;let r=t.endsWith("/")?t.length-1:t.length,n=e.charAt(r);return n&&n!=="/"?null:e.slice(r)||"/"}var et=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function tt(e,t="/"){let{pathname:r,search:n="",hash:a=""}=typeof e=="string"?O(e):e,o;return r?(r=r.replace(/\/\/+/g,"/"),r.startsWith("/")?o=he(r.substring(1),"/"):o=he(r,t)):o=t,{pathname:o,search:at(n),hash:ot(a)}}function he(e,t){let r=t.replace(/\/+$/,"").split("/");return e.split("/").forEach(a=>{a===".."?r.length>1&&r.pop():a!=="."&&r.push(a)}),r.length>1?r.join("/"):"/"}function q(e,t,r,n){return`Cannot include a '${e}' character in a manually specified \`to.${t}\` field [${JSON.stringify(n)}]. Please separate it out to the \`to.${r}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function rt(e){return e.filter((t,r)=>r===0||t.route.path&&t.route.path.length>0)}function te(e){let t=rt(e);return t.map((r,n)=>n===t.length-1?r.pathname:r.pathnameBase)}function J(e,t,r,n=!1){let a;typeof e=="string"?a=O(e):(a={...e},E(!a.pathname||!a.pathname.includes("?"),q("?","pathname","search",a)),E(!a.pathname||!a.pathname.includes("#"),q("#","pathname","hash",a)),E(!a.search||!a.search.includes("#"),q("#","search","hash",a)));let o=e===""||a.pathname==="",l=o?"/":a.pathname,u;if(l==null)u=r;else{let c=t.length-1;if(!n&&l.startsWith("..")){let p=l.split("/");for(;p[0]==="..";)p.shift(),c-=1;a.pathname=p.join("/")}u=c>=0?t[c]:"/"}let s=tt(a,u),d=l&&l!=="/"&&l.endsWith("/"),f=(o||l===".")&&r.endsWith("/");return!s.pathname.endsWith("/")&&(d||f)&&(s.pathname+="/"),s}var P=e=>e.join("/").replace(/\/\/+/g,"/"),nt=e=>e.replace(/\/+$/,"").replace(/^\/*/,"/"),at=e=>!e||e==="?"?"":e.startsWith("?")?e:"?"+e,ot=e=>!e||e==="#"?"":e.startsWith("#")?e:"#"+e,lt=class{constructor(e,t,r,n=!1){this.status=e,this.statusText=t||"",this.internal=n,r instanceof Error?(this.data=r.toString(),this.error=r):this.data=r}};function it(e){return e!=null&&typeof e.status=="number"&&typeof e.statusText=="string"&&typeof e.internal=="boolean"&&"data"in e}function st(e){return e.map(t=>t.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var Re=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function we(e,t){let r=e;if(typeof r!="string"||!et.test(r))return{absoluteURL:void 0,isExternal:!1,to:r};let n=r,a=!1;if(Re)try{let o=new URL(window.location.href),l=r.startsWith("//")?new URL(o.protocol+r):new URL(r),u=k(l.pathname,t);l.origin===o.origin&&u!=null?r=u+l.search+l.hash:a=!0}catch{S(!1,`<Link to="${r}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:n,isExternal:a,to:r}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var Ee=["POST","PUT","PATCH","DELETE"];new Set(Ee);var ut=["GET",...Ee];new Set(ut);var I=i.createContext(null);I.displayName="DataRouter";var K=i.createContext(null);K.displayName="DataRouterState";var ct=i.createContext(!1),xe=i.createContext({isTransitioning:!1});xe.displayName="ViewTransition";var dt=i.createContext(new Map);dt.displayName="Fetchers";var ft=i.createContext(null);ft.displayName="Await";var b=i.createContext(null);b.displayName="Navigation";var A=i.createContext(null);A.displayName="Location";var L=i.createContext({outlet:null,matches:[],isDataRoute:!1});L.displayName="Route";var re=i.createContext(null);re.displayName="RouteError";var Ce="REACT_ROUTER_ERROR",ht="REDIRECT",pt="ROUTE_ERROR_RESPONSE";function mt(e){if(e.startsWith(`${Ce}:${ht}:{`))try{let t=JSON.parse(e.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function yt(e){if(e.startsWith(`${Ce}:${pt}:{`))try{let t=JSON.parse(e.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new lt(t.status,t.statusText,t.data)}catch{}}function gt(e,{relative:t}={}){E(B(),"useHref() may be used only in the context of a <Router> component.");let{basename:r,navigator:n}=i.useContext(b),{hash:a,pathname:o,search:l}=W(e,{relative:t}),u=o;return r!=="/"&&(u=o==="/"?r:P([r,o])),n.createHref({pathname:u,search:l,hash:a})}function B(){return i.useContext(A)!=null}function $(){return E(B(),"useLocation() may be used only in the context of a <Router> component."),i.useContext(A).location}var be="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function Se(e){i.useContext(b).static||i.useLayoutEffect(e)}function Pe(){let{isDataRoute:e}=i.useContext(L);return e?Tt():vt()}function vt(){E(B(),"useNavigate() may be used only in the context of a <Router> component.");let e=i.useContext(I),{basename:t,navigator:r}=i.useContext(b),{matches:n}=i.useContext(L),{pathname:a}=$(),o=JSON.stringify(te(n)),l=i.useRef(!1);return Se(()=>{l.current=!0}),i.useCallback((s,d={})=>{if(S(l.current,be),!l.current)return;if(typeof s=="number"){r.go(s);return}let f=J(s,JSON.parse(o),a,d.relative==="path");e==null&&t!=="/"&&(f.pathname=f.pathname==="/"?t:P([t,f.pathname])),(d.replace?r.replace:r.push)(f,d.state,d)},[t,r,o,a,e])}i.createContext(null);function W(e,{relative:t}={}){let{matches:r}=i.useContext(L),{pathname:n}=$(),a=JSON.stringify(te(r));return i.useMemo(()=>J(e,JSON.parse(a),n,t==="path"),[e,a,n,t])}function Rt(e,t){return Le(e,t)}function Le(e,t,r){E(B(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:n}=i.useContext(b),{matches:a}=i.useContext(L),o=a[a.length-1],l=o?o.params:{},u=o?o.pathname:"/",s=o?o.pathnameBase:"/",d=o&&o.route;{let h=d&&d.path||"";$e(u,!d||h.endsWith("*")||h.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${u}" (under <Route path="${h}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
2
+
3
+ Please change the parent <Route path="${h}"> to <Route path="${h==="/"?"*":`${h}/*`}">.`)}let f=$(),c;if(t){let h=typeof t=="string"?O(t):t;E(s==="/"||h.pathname?.startsWith(s),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${s}" but pathname "${h.pathname}" was given in the \`location\` prop.`),c=h}else c=f;let p=c.pathname||"/",g=p;if(s!=="/"){let h=s.replace(/^\//,"").split("/");g="/"+p.replace(/^\//,"").split("/").slice(h.length).join("/")}let y=ye(e,{pathname:g});S(d||y!=null,`No routes matched location "${c.pathname}${c.search}${c.hash}" `),S(y==null||y[y.length-1].route.element!==void 0||y[y.length-1].route.Component!==void 0||y[y.length-1].route.lazy!==void 0,`Matched leaf route at location "${c.pathname}${c.search}${c.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let m=bt(y&&y.map(h=>Object.assign({},h,{params:Object.assign({},l,h.params),pathname:P([s,n.encodeLocation?n.encodeLocation(h.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathname]),pathnameBase:h.pathnameBase==="/"?s:P([s,n.encodeLocation?n.encodeLocation(h.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:h.pathnameBase])})),a,r);return t&&m?i.createElement(A.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...c},navigationType:"POP"}},m):m}function wt(){let e=$t(),t=it(e)?`${e.status} ${e.statusText}`:e instanceof Error?e.message:JSON.stringify(e),r=e instanceof Error?e.stack:null,n="rgba(200,200,200, 0.5)",a={padding:"0.5rem",backgroundColor:n},o={padding:"2px 4px",backgroundColor:n},l=null;return console.error("Error handled by React Router default ErrorBoundary:",e),l=i.createElement(i.Fragment,null,i.createElement("p",null,"💿 Hey developer 👋"),i.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",i.createElement("code",{style:o},"ErrorBoundary")," or"," ",i.createElement("code",{style:o},"errorElement")," prop on your route.")),i.createElement(i.Fragment,null,i.createElement("h2",null,"Unexpected Application Error!"),i.createElement("h3",{style:{fontStyle:"italic"}},t),r?i.createElement("pre",{style:a},r):null,l)}var Et=i.createElement(wt,null),ke=class extends i.Component{constructor(e){super(e),this.state={location:e.location,revalidation:e.revalidation,error:e.error}}static getDerivedStateFromError(e){return{error:e}}static getDerivedStateFromProps(e,t){return t.location!==e.location||t.revalidation!=="idle"&&e.revalidation==="idle"?{error:e.error,location:e.location,revalidation:e.revalidation}:{error:e.error!==void 0?e.error:t.error,location:t.location,revalidation:e.revalidation||t.revalidation}}componentDidCatch(e,t){this.props.onError?this.props.onError(e,t):console.error("React Router caught the following error during render",e)}render(){let e=this.state.error;if(this.context&&typeof e=="object"&&e&&"digest"in e&&typeof e.digest=="string"){const r=yt(e.digest);r&&(e=r)}let t=e!==void 0?i.createElement(L.Provider,{value:this.props.routeContext},i.createElement(re.Provider,{value:e,children:this.props.component})):this.props.children;return this.context?i.createElement(xt,{error:e},t):t}};ke.contextType=ct;var X=new WeakMap;function xt({children:e,error:t}){let{basename:r}=i.useContext(b);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let n=mt(t.digest);if(n){let a=X.get(t);if(a)throw a;let o=we(n.location,r);if(Re&&!X.get(t))if(o.isExternal||n.reloadDocument)window.location.href=o.absoluteURL||o.to;else{const l=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:n.replace}));throw X.set(t,l),l}return i.createElement("meta",{httpEquiv:"refresh",content:`0;url=${o.absoluteURL||o.to}`})}}return e}function Ct({routeContext:e,match:t,children:r}){let n=i.useContext(I);return n&&n.static&&n.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(n.staticContext._deepestRenderedBoundaryId=t.route.id),i.createElement(L.Provider,{value:e},r)}function bt(e,t=[],r){let n=r?.state;if(e==null){if(!n)return null;if(n.errors)e=n.matches;else if(t.length===0&&!n.initialized&&n.matches.length>0)e=n.matches;else return null}let a=e,o=n?.errors;if(o!=null){let f=a.findIndex(c=>c.route.id&&o?.[c.route.id]!==void 0);E(f>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),a=a.slice(0,Math.min(a.length,f+1))}let l=!1,u=-1;if(r&&n){l=n.renderFallback;for(let f=0;f<a.length;f++){let c=a[f];if((c.route.HydrateFallback||c.route.hydrateFallbackElement)&&(u=f),c.route.id){let{loaderData:p,errors:g}=n,y=c.route.loader&&!p.hasOwnProperty(c.route.id)&&(!g||g[c.route.id]===void 0);if(c.route.lazy||y){r.isStatic&&(l=!0),u>=0?a=a.slice(0,u+1):a=[a[0]];break}}}}let s=r?.onError,d=n&&s?(f,c)=>{s(f,{location:n.location,params:n.matches?.[0]?.params??{},unstable_pattern:st(n.matches),errorInfo:c})}:void 0;return a.reduceRight((f,c,p)=>{let g,y=!1,m=null,h=null;n&&(g=o&&c.route.id?o[c.route.id]:void 0,m=c.route.errorElement||Et,l&&(u<0&&p===0?($e("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),y=!0,h=null):u===p&&(y=!0,h=c.route.hydrateFallbackElement||null)));let v=t.concat(a.slice(0,p+1)),R=()=>{let w;return g?w=m:y?w=h:c.route.Component?w=i.createElement(c.route.Component,null):c.route.element?w=c.route.element:w=f,i.createElement(Ct,{match:c,routeContext:{outlet:f,matches:v,isDataRoute:n!=null},children:w})};return n&&(c.route.ErrorBoundary||c.route.errorElement||p===0)?i.createElement(ke,{location:n.location,revalidation:n.revalidation,component:m,error:g,children:R(),routeContext:{outlet:null,matches:v,isDataRoute:!0},onError:d}):R()},null)}function ne(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function St(e){let t=i.useContext(I);return E(t,ne(e)),t}function Pt(e){let t=i.useContext(K);return E(t,ne(e)),t}function Lt(e){let t=i.useContext(L);return E(t,ne(e)),t}function ae(e){let t=Lt(e),r=t.matches[t.matches.length-1];return E(r.route.id,`${e} can only be used on routes that contain a unique "id"`),r.route.id}function kt(){return ae("useRouteId")}function $t(){let e=i.useContext(re),t=Pt("useRouteError"),r=ae("useRouteError");return e!==void 0?e:t.errors?.[r]}function Tt(){let{router:e}=St("useNavigate"),t=ae("useNavigate"),r=i.useRef(!1);return Se(()=>{r.current=!0}),i.useCallback(async(a,o={})=>{S(r.current,be),r.current&&(typeof a=="number"?await e.navigate(a):await e.navigate(a,{fromRouteId:t,...o}))},[e,t])}var pe={};function $e(e,t,r){!t&&!pe[e]&&(pe[e]=!0,S(!1,r))}i.memo(Ft);function Ft({routes:e,future:t,state:r,isStatic:n,onError:a}){return Le(e,void 0,{state:r,isStatic:n,onError:a})}function hr({to:e,replace:t,state:r,relative:n}){E(B(),"<Navigate> may be used only in the context of a <Router> component.");let{static:a}=i.useContext(b);S(!a,"<Navigate> must not be used on the initial render in a <StaticRouter>. This is a no-op, but you should modify your code so the <Navigate> is only ever rendered in response to some user interaction or state change.");let{matches:o}=i.useContext(L),{pathname:l}=$(),u=Pe(),s=J(e,te(o),l,n==="path"),d=JSON.stringify(s);return i.useEffect(()=>{u(JSON.parse(d),{replace:t,state:r,relative:n})},[u,d,n,t,r]),null}function Nt(e){E(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function Dt({basename:e="/",children:t=null,location:r,navigationType:n="POP",navigator:a,static:o=!1,unstable_useTransitions:l}){E(!B(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let u=e.replace(/^\/*/,"/"),s=i.useMemo(()=>({basename:u,navigator:a,static:o,unstable_useTransitions:l,future:{}}),[u,a,o,l]);typeof r=="string"&&(r=O(r));let{pathname:d="/",search:f="",hash:c="",state:p=null,key:g="default",unstable_mask:y}=r,m=i.useMemo(()=>{let h=k(d,u);return h==null?null:{location:{pathname:h,search:f,hash:c,state:p,key:g,unstable_mask:y},navigationType:n}},[u,d,f,c,p,g,n,y]);return S(m!=null,`<Router basename="${u}"> is not able to match the URL "${d}${f}${c}" because it does not start with the basename, so the <Router> won't render anything.`),m==null?null:i.createElement(b.Provider,{value:s},i.createElement(A.Provider,{children:t,value:m}))}function pr({children:e,location:t}){return Rt(ee(e),t)}function ee(e,t=[]){let r=[];return i.Children.forEach(e,(n,a)=>{if(!i.isValidElement(n))return;let o=[...t,a];if(n.type===i.Fragment){r.push.apply(r,ee(n.props.children,o));return}E(n.type===Nt,`[${typeof n.type=="string"?n.type:n.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),E(!n.props.index||!n.props.children,"An index route cannot have child routes.");let l={id:n.props.id||o.join("-"),caseSensitive:n.props.caseSensitive,element:n.props.element,Component:n.props.Component,index:n.props.index,path:n.props.path,middleware:n.props.middleware,loader:n.props.loader,action:n.props.action,hydrateFallbackElement:n.props.hydrateFallbackElement,HydrateFallback:n.props.HydrateFallback,errorElement:n.props.errorElement,ErrorBoundary:n.props.ErrorBoundary,hasErrorBoundary:n.props.hasErrorBoundary===!0||n.props.ErrorBoundary!=null||n.props.errorElement!=null,shouldRevalidate:n.props.shouldRevalidate,handle:n.props.handle,lazy:n.props.lazy};n.props.children&&(l.children=ee(n.props.children,o)),r.push(l)}),r}var j="get",z="application/x-www-form-urlencoded";function Y(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement}function Ot(e){return Y(e)&&e.tagName.toLowerCase()==="button"}function It(e){return Y(e)&&e.tagName.toLowerCase()==="form"}function Bt(e){return Y(e)&&e.tagName.toLowerCase()==="input"}function _t(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function Mt(e,t){return e.button===0&&(!t||t==="_self")&&!_t(e)}var H=null;function Ut(){if(H===null)try{new FormData(document.createElement("form"),0),H=!1}catch{H=!0}return H}var At=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Q(e){return e!=null&&!At.has(e)?(S(!1,`"${e}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${z}"`),null):e}function Wt(e,t){let r,n,a,o,l;if(It(e)){let u=e.getAttribute("action");n=u?k(u,t):null,r=e.getAttribute("method")||j,a=Q(e.getAttribute("enctype"))||z,o=new FormData(e)}else if(Ot(e)||Bt(e)&&(e.type==="submit"||e.type==="image")){let u=e.form;if(u==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let s=e.getAttribute("formaction")||u.getAttribute("action");if(n=s?k(s,t):null,r=e.getAttribute("formmethod")||u.getAttribute("method")||j,a=Q(e.getAttribute("formenctype"))||Q(u.getAttribute("enctype"))||z,o=new FormData(u,e),!Ut()){let{name:d,type:f,value:c}=e;if(f==="image"){let p=d?`${d}.`:"";o.append(`${p}x`,"0"),o.append(`${p}y`,"0")}else d&&o.append(d,c)}}else{if(Y(e))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');r=j,n=null,a=z,l=e}return o&&a==="text/plain"&&(l=o,o=void 0),{action:n,method:r.toLowerCase(),encType:a,formData:o,body:l}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function oe(e,t){if(e===!1||e===null||typeof e>"u")throw new Error(t)}function Ht(e,t,r,n){let a=typeof e=="string"?new URL(e,typeof window>"u"?"server://singlefetch/":window.location.origin):e;return r?a.pathname.endsWith("/")?a.pathname=`${a.pathname}_.${n}`:a.pathname=`${a.pathname}.${n}`:a.pathname==="/"?a.pathname=`_root.${n}`:t&&k(a.pathname,t)==="/"?a.pathname=`${t.replace(/\/$/,"")}/_root.${n}`:a.pathname=`${a.pathname.replace(/\/$/,"")}.${n}`,a}async function jt(e,t){if(e.id in t)return t[e.id];try{let r=await import(e.module);return t[e.id]=r,r}catch(r){return console.error(`Error loading route module \`${e.module}\`, reloading page...`),console.error(r),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function zt(e){return e==null?!1:e.href==null?e.rel==="preload"&&typeof e.imageSrcSet=="string"&&typeof e.imageSizes=="string":typeof e.rel=="string"&&typeof e.href=="string"}async function Vt(e,t,r){let n=await Promise.all(e.map(async a=>{let o=t.routes[a.route.id];if(o){let l=await jt(o,r);return l.links?l.links():[]}return[]}));return Gt(n.flat(1).filter(zt).filter(a=>a.rel==="stylesheet"||a.rel==="preload").map(a=>a.rel==="stylesheet"?{...a,rel:"prefetch",as:"style"}:{...a,rel:"prefetch"}))}function me(e,t,r,n,a,o){let l=(s,d)=>r[d]?s.route.id!==r[d].route.id:!0,u=(s,d)=>r[d].pathname!==s.pathname||r[d].route.path?.endsWith("*")&&r[d].params["*"]!==s.params["*"];return o==="assets"?t.filter((s,d)=>l(s,d)||u(s,d)):o==="data"?t.filter((s,d)=>{let f=n.routes[s.route.id];if(!f||!f.hasLoader)return!1;if(l(s,d)||u(s,d))return!0;if(s.route.shouldRevalidate){let c=s.route.shouldRevalidate({currentUrl:new URL(a.pathname+a.search+a.hash,window.origin),currentParams:r[0]?.params||{},nextUrl:new URL(e,window.origin),nextParams:s.params,defaultShouldRevalidate:!0});if(typeof c=="boolean")return c}return!0}):[]}function Jt(e,t,{includeHydrateFallback:r}={}){return Kt(e.map(n=>{let a=t.routes[n.route.id];if(!a)return[];let o=[a.module];return a.clientActionModule&&(o=o.concat(a.clientActionModule)),a.clientLoaderModule&&(o=o.concat(a.clientLoaderModule)),r&&a.hydrateFallbackModule&&(o=o.concat(a.hydrateFallbackModule)),a.imports&&(o=o.concat(a.imports)),o}).flat(1))}function Kt(e){return[...new Set(e)]}function Yt(e){let t={},r=Object.keys(e).sort();for(let n of r)t[n]=e[n];return t}function Gt(e,t){let r=new Set;return new Set(t),e.reduce((n,a)=>{let o=JSON.stringify(Yt(a));return r.has(o)||(r.add(o),n.push({key:o,link:a})),n},[])}function Te(){let e=i.useContext(I);return oe(e,"You must render this element inside a <DataRouterContext.Provider> element"),e}function qt(){let e=i.useContext(K);return oe(e,"You must render this element inside a <DataRouterStateContext.Provider> element"),e}var le=i.createContext(void 0);le.displayName="FrameworkContext";function Fe(){let e=i.useContext(le);return oe(e,"You must render this element inside a <HydratedRouter> element"),e}function Xt(e,t){let r=i.useContext(le),[n,a]=i.useState(!1),[o,l]=i.useState(!1),{onFocus:u,onBlur:s,onMouseEnter:d,onMouseLeave:f,onTouchStart:c}=t,p=i.useRef(null);i.useEffect(()=>{if(e==="render"&&l(!0),e==="viewport"){let m=v=>{v.forEach(R=>{l(R.isIntersecting)})},h=new IntersectionObserver(m,{threshold:.5});return p.current&&h.observe(p.current),()=>{h.disconnect()}}},[e]),i.useEffect(()=>{if(n){let m=setTimeout(()=>{l(!0)},100);return()=>{clearTimeout(m)}}},[n]);let g=()=>{a(!0)},y=()=>{a(!1),l(!1)};return r?e!=="intent"?[o,p,{}]:[o,p,{onFocus:M(u,g),onBlur:M(s,y),onMouseEnter:M(d,g),onMouseLeave:M(f,y),onTouchStart:M(c,g)}]:[!1,p,{}]}function M(e,t){return r=>{e&&e(r),r.defaultPrevented||t(r)}}function Qt({page:e,...t}){let{router:r}=Te(),n=i.useMemo(()=>ye(r.routes,e,r.basename),[r.routes,e,r.basename]);return n?i.createElement(er,{page:e,matches:n,...t}):null}function Zt(e){let{manifest:t,routeModules:r}=Fe(),[n,a]=i.useState([]);return i.useEffect(()=>{let o=!1;return Vt(e,t,r).then(l=>{o||a(l)}),()=>{o=!0}},[e,t,r]),n}function er({page:e,matches:t,...r}){let n=$(),{future:a,manifest:o,routeModules:l}=Fe(),{basename:u}=Te(),{loaderData:s,matches:d}=qt(),f=i.useMemo(()=>me(e,t,d,o,n,"data"),[e,t,d,o,n]),c=i.useMemo(()=>me(e,t,d,o,n,"assets"),[e,t,d,o,n]),p=i.useMemo(()=>{if(e===n.pathname+n.search+n.hash)return[];let m=new Set,h=!1;if(t.forEach(R=>{let w=o.routes[R.route.id];!w||!w.hasLoader||(!f.some(C=>C.route.id===R.route.id)&&R.route.id in s&&l[R.route.id]?.shouldRevalidate||w.hasClientLoader?h=!0:m.add(R.route.id))}),m.size===0)return[];let v=Ht(e,u,a.unstable_trailingSlashAwareDataRequests,"data");return h&&m.size>0&&v.searchParams.set("_routes",t.filter(R=>m.has(R.route.id)).map(R=>R.route.id).join(",")),[v.pathname+v.search]},[u,a.unstable_trailingSlashAwareDataRequests,s,n,o,f,t,e,l]),g=i.useMemo(()=>Jt(c,o),[c,o]),y=Zt(c);return i.createElement(i.Fragment,null,p.map(m=>i.createElement("link",{key:m,rel:"prefetch",as:"fetch",href:m,...r})),g.map(m=>i.createElement("link",{key:m,rel:"modulepreload",href:m,...r})),y.map(({key:m,link:h})=>i.createElement("link",{key:m,nonce:r.nonce,...h,crossOrigin:h.crossOrigin??r.crossOrigin})))}function tr(...e){return t=>{e.forEach(r=>{typeof r=="function"?r(t):r!=null&&(r.current=t)})}}var rr=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{rr&&(window.__reactRouterVersion="7.13.2")}catch{}function mr({basename:e,children:t,unstable_useTransitions:r,window:n}){let a=i.useRef();a.current==null&&(a.current=_e({window:n,v5Compat:!0}));let o=a.current,[l,u]=i.useState({action:o.action,location:o.location}),s=i.useCallback(d=>{r===!1?u(d):i.startTransition(()=>u(d))},[r]);return i.useLayoutEffect(()=>o.listen(s),[o,s]),i.createElement(Dt,{basename:e,children:t,location:l.location,navigationType:l.action,navigator:o,unstable_useTransitions:r})}var Ne=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,De=i.forwardRef(function({onClick:t,discover:r="render",prefetch:n="none",relative:a,reloadDocument:o,replace:l,unstable_mask:u,state:s,target:d,to:f,preventScrollReset:c,viewTransition:p,unstable_defaultShouldRevalidate:g,...y},m){let{basename:h,navigator:v,unstable_useTransitions:R}=i.useContext(b),w=typeof f=="string"&&Ne.test(f),C=we(f,h);f=C.to;let x=gt(f,{relative:a}),T=$(),F=null;if(u){let N=J(u,[],T.unstable_mask?T.unstable_mask.pathname:"/",!0);h!=="/"&&(N.pathname=N.pathname==="/"?h:P([h,N.pathname])),F=v.createHref(N)}let[D,_,G]=Xt(n,y),Ie=lr(f,{replace:l,unstable_mask:u,state:s,target:d,preventScrollReset:c,relative:a,viewTransition:p,unstable_defaultShouldRevalidate:g,unstable_useTransitions:R});function Be(N){t&&t(N),N.defaultPrevented||Ie(N)}let ie=!(C.isExternal||o),se=i.createElement("a",{...y,...G,href:(ie?F:void 0)||C.absoluteURL||x,onClick:ie?Be:t,ref:tr(m,_),target:d,"data-discover":!w&&r==="render"?"true":void 0});return D&&!w?i.createElement(i.Fragment,null,se,i.createElement(Qt,{page:x})):se});De.displayName="Link";var nr=i.forwardRef(function({"aria-current":t="page",caseSensitive:r=!1,className:n="",end:a=!1,style:o,to:l,viewTransition:u,children:s,...d},f){let c=W(l,{relative:d.relative}),p=$(),g=i.useContext(K),{navigator:y,basename:m}=i.useContext(b),h=g!=null&&dr(c)&&u===!0,v=y.encodeLocation?y.encodeLocation(c).pathname:c.pathname,R=p.pathname,w=g&&g.navigation&&g.navigation.location?g.navigation.location.pathname:null;r||(R=R.toLowerCase(),w=w?w.toLowerCase():null,v=v.toLowerCase()),w&&m&&(w=k(w,m)||w);const C=v!=="/"&&v.endsWith("/")?v.length-1:v.length;let x=R===v||!a&&R.startsWith(v)&&R.charAt(C)==="/",T=w!=null&&(w===v||!a&&w.startsWith(v)&&w.charAt(v.length)==="/"),F={isActive:x,isPending:T,isTransitioning:h},D=x?t:void 0,_;typeof n=="function"?_=n(F):_=[n,x?"active":null,T?"pending":null,h?"transitioning":null].filter(Boolean).join(" ");let G=typeof o=="function"?o(F):o;return i.createElement(De,{...d,"aria-current":D,className:_,ref:f,style:G,to:l,viewTransition:u},typeof s=="function"?s(F):s)});nr.displayName="NavLink";var ar=i.forwardRef(({discover:e="render",fetcherKey:t,navigate:r,reloadDocument:n,replace:a,state:o,method:l=j,action:u,onSubmit:s,relative:d,preventScrollReset:f,viewTransition:c,unstable_defaultShouldRevalidate:p,...g},y)=>{let{unstable_useTransitions:m}=i.useContext(b),h=ur(),v=cr(u,{relative:d}),R=l.toLowerCase()==="get"?"get":"post",w=typeof u=="string"&&Ne.test(u),C=x=>{if(s&&s(x),x.defaultPrevented)return;x.preventDefault();let T=x.nativeEvent.submitter,F=T?.getAttribute("formmethod")||l,D=()=>h(T||x.currentTarget,{fetcherKey:t,method:F,navigate:r,replace:a,state:o,relative:d,preventScrollReset:f,viewTransition:c,unstable_defaultShouldRevalidate:p});m&&r!==!1?i.startTransition(()=>D()):D()};return i.createElement("form",{ref:y,method:R,action:v,onSubmit:n?s:C,...g,"data-discover":!w&&e==="render"?"true":void 0})});ar.displayName="Form";function or(e){return`${e} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function Oe(e){let t=i.useContext(I);return E(t,or(e)),t}function lr(e,{target:t,replace:r,unstable_mask:n,state:a,preventScrollReset:o,relative:l,viewTransition:u,unstable_defaultShouldRevalidate:s,unstable_useTransitions:d}={}){let f=Pe(),c=$(),p=W(e,{relative:l});return i.useCallback(g=>{if(Mt(g,t)){g.preventDefault();let y=r!==void 0?r:U(c)===U(p),m=()=>f(e,{replace:y,unstable_mask:n,state:a,preventScrollReset:o,relative:l,viewTransition:u,unstable_defaultShouldRevalidate:s});d?i.startTransition(()=>m()):m()}},[c,f,p,r,n,a,t,e,o,l,u,s,d])}var ir=0,sr=()=>`__${String(++ir)}__`;function ur(){let{router:e}=Oe("useSubmit"),{basename:t}=i.useContext(b),r=kt(),n=e.fetch,a=e.navigate;return i.useCallback(async(o,l={})=>{let{action:u,method:s,encType:d,formData:f,body:c}=Wt(o,t);if(l.navigate===!1){let p=l.fetcherKey||sr();await n(p,r,l.action||u,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:f,body:c,formMethod:l.method||s,formEncType:l.encType||d,flushSync:l.flushSync})}else await a(l.action||u,{unstable_defaultShouldRevalidate:l.unstable_defaultShouldRevalidate,preventScrollReset:l.preventScrollReset,formData:f,body:c,formMethod:l.method||s,formEncType:l.encType||d,replace:l.replace,state:l.state,fromRouteId:r,flushSync:l.flushSync,viewTransition:l.viewTransition})},[n,a,t,r])}function cr(e,{relative:t}={}){let{basename:r}=i.useContext(b),n=i.useContext(L);E(n,"useFormAction must be used inside a RouteContext");let[a]=n.matches.slice(-1),o={...W(e||".",{relative:t})},l=$();if(e==null){o.search=l.search;let u=new URLSearchParams(o.search),s=u.getAll("index");if(s.some(f=>f==="")){u.delete("index"),s.filter(c=>c).forEach(c=>u.append("index",c));let f=u.toString();o.search=f?`?${f}`:""}}return(!e||e===".")&&a.route.index&&(o.search=o.search?o.search.replace(/^\?/,"?index&"):"?index"),r!=="/"&&(o.pathname=o.pathname==="/"?r:P([r,o.pathname])),U(o)}function dr(e,{relative:t}={}){let r=i.useContext(xe);E(r!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:n}=Oe("useViewTransitionState"),a=W(e,{relative:t});if(!r.isTransitioning)return!1;let o=k(r.currentLocation.pathname,n)||r.currentLocation.pathname,l=k(r.nextLocation.pathname,n)||r.nextLocation.pathname;return V(a.pathname,l)!=null||V(a.pathname,o)!=null}export{mr as B,nr as N,pr as R,Nt as a,hr as b,$ as u};
@@ -0,0 +1 @@
1
+ import{j as s}from"./react-vendor-C7Sl8SE7.js";import{J as t,i as n,S as a}from"./index-DXSohzrE.js";function o({primary:e,secondary:l,tertiary:i}){return s.jsxs("div",{className:"flex flex-col gap-2 pt-1 sm:flex-row sm:flex-wrap sm:items-center sm:justify-between",children:[s.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e&&s.jsxs(n,{tone:"primary",onClick:e.onClick,disabled:e.disabled,children:[e.loading&&s.jsx(a,{}),e.label]}),l&&s.jsx(n,{tone:"secondary",onClick:l.onClick,disabled:l.disabled,children:l.label})]}),i&&s.jsx("div",{className:"text-xs leading-relaxed text-fg-4",children:i})]})}function c({children:e,className:l}){return s.jsx(t,{padding:"md",elevation:"flat",className:l,children:e})}export{o as A,c as S};
@@ -0,0 +1,28 @@
1
+ <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="512" height="512" rx="112" fill="#05060a"/>
3
+ <defs>
4
+ <linearGradient id="ribbon" x1="96" y1="160" x2="416" y2="352" gradientUnits="userSpaceOnUse">
5
+ <stop offset="0" stop-color="#b6ffa8"/>
6
+ <stop offset="0.5" stop-color="#7cff67"/>
7
+ <stop offset="1" stop-color="#56ef4d"/>
8
+ </linearGradient>
9
+ </defs>
10
+ <g id="icon" fill="none" stroke-linecap="round" stroke-linejoin="round">
11
+ <!-- Continuous figure-8 ribbon: one endless band crossing at the center.
12
+ Right lobe + the UNDER half of the crossing render first in a deeper green for ribbon depth. -->
13
+ <path d="M256 256
14
+ C 296 200, 376 188, 412 240
15
+ C 442 288, 400 332, 340 326
16
+ C 296 322, 268 290, 256 256
17
+ C 244 222, 216 190, 172 186
18
+ C 112 180, 70 224, 100 272
19
+ C 136 324, 216 312, 256 256 Z"
20
+ stroke="#34d058" stroke-width="56"/>
21
+ <!-- OVER pass: the left lobe sweeps ON TOP at the crossing in bright accent, creating the woven Möbius twist. -->
22
+ <path d="M256 256
23
+ C 244 222, 216 190, 172 186
24
+ C 112 180, 70 224, 100 272
25
+ C 136 324, 216 312, 256 256"
26
+ stroke="url(#ribbon)" stroke-width="56"/>
27
+ </g>
28
+ </svg>
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg">
7
+ <title>Pikiloop</title>
8
+ <link href="https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet">
9
+ <script type="module" crossorigin src="/assets/index-DXSohzrE.js"></script>
10
+ <link rel="modulepreload" crossorigin href="/assets/react-vendor-C7Sl8SE7.js">
11
+ <link rel="modulepreload" crossorigin href="/assets/router-DHISdpPk.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-reSbuley.css">
13
+ </head>
14
+ <body>
15
+ <div id="root"></div>
16
+ </body>
17
+ </html>
@@ -0,0 +1,261 @@
1
+ /**
2
+ * Minimal Agent Client Protocol (ACP) client.
3
+ *
4
+ * ACP is a JSON-RPC 2.0 protocol over stdio that standardises how clients
5
+ * (editors, orchestrators) talk to AI coding agents. Reference impls:
6
+ * Hermes (`hermes acp`), Gemini CLI (`gemini --acp`), OpenCode, Claude Code
7
+ * via `@zed-industries/claude-code-acp` adapter.
8
+ *
9
+ * This is a deliberately small implementation — it parses line-delimited
10
+ * JSON-RPC messages, dispatches results/notifications, and lets callers
11
+ * `request()` and consume an async stream of `sessionUpdate` notifications.
12
+ *
13
+ * Spec: https://agentclientprotocol.com — methods we use:
14
+ * client → agent: initialize, session/new, session/load, session/prompt,
15
+ * session/set_model, session/set_session_mode, session/cancel
16
+ * agent → client: session/update (streaming notifications)
17
+ * session/request_permission (we deny by default)
18
+ * fs/read_text_file, fs/write_text_file (we say "no")
19
+ */
20
+ import { spawn } from 'node:child_process';
21
+ import { createInterface } from 'node:readline';
22
+ import { EventEmitter } from 'node:events';
23
+ import { agentLog, agentWarn } from './utils.js';
24
+ /**
25
+ * Translate a Claude-style MCP server map (keyed by name with
26
+ * `{type?, command|url, args?, env?, headers?}`) into ACP wire format:
27
+ * stdio: { name, command, args, env: [{name, value}, ...] }
28
+ * http: { type: "http", name, url, headers: [{name, value}, ...] }
29
+ * sse: { type: "sse", name, url, headers: [{name, value}, ...] }
30
+ *
31
+ * The ACP schema requires `name` plus a list-of-records `env` for stdio
32
+ * servers — sending an object map for env, or omitting name, results in
33
+ * a JSON-RPC -32602 (Invalid params) response.
34
+ */
35
+ export function toAcpMcpServers(servers) {
36
+ if (!servers)
37
+ return [];
38
+ const out = [];
39
+ for (const [name, cfg] of Object.entries(servers)) {
40
+ if (!cfg || typeof cfg !== 'object')
41
+ continue;
42
+ const type = String(cfg.type || '').toLowerCase();
43
+ if ((type === 'http' || type === 'sse') && cfg.url) {
44
+ const headers = Object.entries(cfg.headers || {}).map(([n, v]) => ({ name: n, value: String(v) }));
45
+ out.push({ type, name, url: String(cfg.url), headers });
46
+ continue;
47
+ }
48
+ if (cfg.command) {
49
+ const env = Object.entries(cfg.env || {}).map(([n, v]) => ({ name: n, value: String(v) }));
50
+ out.push({
51
+ name,
52
+ command: String(cfg.command),
53
+ args: Array.isArray(cfg.args) ? cfg.args.map(String) : [],
54
+ env,
55
+ });
56
+ }
57
+ }
58
+ return out;
59
+ }
60
+ /**
61
+ * AcpClient — encapsulates a single ACP child process.
62
+ *
63
+ * Events:
64
+ * - 'sessionUpdate' (params) → agent → client streaming events
65
+ * - 'request' ({method, id, params}) → agent → client requests we must answer
66
+ * - 'exit' (code) → process closed
67
+ */
68
+ export class AcpClient extends EventEmitter {
69
+ opts;
70
+ proc = null;
71
+ nextId = 1;
72
+ pending = new Map();
73
+ exited = false;
74
+ constructor(opts) {
75
+ super();
76
+ this.opts = opts;
77
+ }
78
+ start() {
79
+ if (this.proc)
80
+ return;
81
+ agentLog(`[acp] spawn: ${this.opts.command} ${this.opts.args.join(' ')}`);
82
+ this.proc = spawn(this.opts.command, this.opts.args, {
83
+ cwd: this.opts.cwd,
84
+ env: this.opts.env,
85
+ stdio: ['pipe', 'pipe', 'pipe'],
86
+ });
87
+ const rl = createInterface({ input: this.proc.stdout, crlfDelay: Infinity });
88
+ rl.on('line', line => this.handleLine(line));
89
+ this.proc.stderr.on('data', (chunk) => {
90
+ const text = chunk.toString();
91
+ // ACP stderr is reserved for human-readable diagnostics.
92
+ for (const ln of text.split('\n')) {
93
+ const t = ln.trim();
94
+ if (t)
95
+ agentLog(`[acp:stderr] ${t.slice(0, 240)}`);
96
+ }
97
+ });
98
+ this.proc.on('error', err => {
99
+ agentWarn(`[acp] spawn error: ${err.message}`);
100
+ this.failPending(err);
101
+ });
102
+ this.proc.on('close', code => {
103
+ agentLog(`[acp] exit code=${code}`);
104
+ this.exited = true;
105
+ this.emit('exit', code);
106
+ this.failPending(new Error(`ACP process exited with code ${code}`));
107
+ });
108
+ }
109
+ isAlive() {
110
+ return !!this.proc && !this.exited;
111
+ }
112
+ /** Send a JSON-RPC request and resolve when the agent responds. */
113
+ async request(method, params, timeoutMs = 60_000) {
114
+ if (!this.proc || this.exited)
115
+ throw new Error('ACP process not running');
116
+ const id = this.nextId++;
117
+ return new Promise((resolve, reject) => {
118
+ const timer = setTimeout(() => {
119
+ this.pending.delete(id);
120
+ reject(new Error(`ACP request timed out after ${timeoutMs}ms: ${method}`));
121
+ }, timeoutMs);
122
+ this.pending.set(id, {
123
+ method,
124
+ resolve: v => { clearTimeout(timer); resolve(v); },
125
+ reject: e => { clearTimeout(timer); reject(e); },
126
+ });
127
+ this.write({ jsonrpc: '2.0', id, method, params });
128
+ });
129
+ }
130
+ /**
131
+ * Best-effort request — resolves with `null` on any error or non-existent
132
+ * method, instead of throwing. Useful for optional methods like
133
+ * `session/set_session_mode` that may or may not be implemented by the
134
+ * agent. The error is logged but does not propagate.
135
+ */
136
+ async tryRequest(method, params, timeoutMs = 15_000) {
137
+ try {
138
+ return await this.request(method, params, timeoutMs);
139
+ }
140
+ catch (e) {
141
+ agentLog(`[acp] tryRequest(${method}) skipped: ${e?.message || e}`);
142
+ return null;
143
+ }
144
+ }
145
+ /** Send a notification (no response expected). */
146
+ notify(method, params) {
147
+ if (!this.proc || this.exited)
148
+ return;
149
+ this.write({ jsonrpc: '2.0', method, params });
150
+ }
151
+ /** Send a JSON-RPC response back to the agent (when it asks us something). */
152
+ respond(id, result) {
153
+ this.write({ jsonrpc: '2.0', id, result });
154
+ }
155
+ respondError(id, code, message) {
156
+ this.write({ jsonrpc: '2.0', id, error: { code, message } });
157
+ }
158
+ /**
159
+ * Wait for the session/update event stream to go quiet for `quietMs`
160
+ * milliseconds, or until `maxMs` elapses. Used to drain replay events
161
+ * after `session/load`. Returns the number of events observed.
162
+ */
163
+ async waitForQuiet(quietMs = 150, maxMs = 3_000) {
164
+ let events = 0;
165
+ let lastEventAt = Date.now();
166
+ const onUpdate = () => { events++; lastEventAt = Date.now(); };
167
+ this.on('sessionUpdate', onUpdate);
168
+ try {
169
+ const startedAt = Date.now();
170
+ while (Date.now() - startedAt < maxMs) {
171
+ const idle = Date.now() - lastEventAt;
172
+ if (idle >= quietMs)
173
+ break;
174
+ await new Promise(r => setTimeout(r, Math.min(50, quietMs - idle + 1)));
175
+ }
176
+ return events;
177
+ }
178
+ finally {
179
+ this.off('sessionUpdate', onUpdate);
180
+ }
181
+ }
182
+ /** Gracefully shut down. */
183
+ async close() {
184
+ if (!this.proc || this.exited)
185
+ return;
186
+ try {
187
+ this.proc.stdin.end();
188
+ }
189
+ catch { }
190
+ await new Promise(resolve => {
191
+ const timer = setTimeout(() => {
192
+ try {
193
+ this.proc?.kill('SIGTERM');
194
+ }
195
+ catch { }
196
+ resolve();
197
+ }, 1500);
198
+ this.proc?.on('close', () => { clearTimeout(timer); resolve(); });
199
+ });
200
+ }
201
+ // ------------------------------------------------------------------------
202
+ write(msg) {
203
+ if (!this.proc || this.exited)
204
+ return;
205
+ try {
206
+ this.proc.stdin.write(JSON.stringify(msg) + '\n');
207
+ }
208
+ catch (e) {
209
+ agentWarn(`[acp] write failed: ${e?.message || e}`);
210
+ }
211
+ }
212
+ handleLine(line) {
213
+ const trimmed = line.trim();
214
+ if (!trimmed)
215
+ return;
216
+ let msg;
217
+ try {
218
+ msg = JSON.parse(trimmed);
219
+ }
220
+ catch {
221
+ // ACP sometimes prefixes diagnostic logs to stdout; ignore non-JSON
222
+ agentLog(`[acp:stdout-noise] ${trimmed.slice(0, 200)}`);
223
+ return;
224
+ }
225
+ // Response (has id and result/error)
226
+ if ('id' in msg && (('result' in msg) || ('error' in msg))) {
227
+ const resp = msg;
228
+ const pending = this.pending.get(resp.id);
229
+ if (!pending)
230
+ return;
231
+ this.pending.delete(resp.id);
232
+ if (resp.error)
233
+ pending.reject(new Error(`ACP error ${resp.error.code} on ${pending.method}: ${resp.error.message}`));
234
+ else
235
+ pending.resolve(resp.result);
236
+ return;
237
+ }
238
+ // Notification (no id) — agent → client streaming event
239
+ if (!('id' in msg) && 'method' in msg) {
240
+ const n = msg;
241
+ if (n.method === 'session/update') {
242
+ this.emit('sessionUpdate', n.params);
243
+ }
244
+ else {
245
+ this.emit('notification', n);
246
+ }
247
+ return;
248
+ }
249
+ // Request (has id and method) — agent → client RPC
250
+ if ('id' in msg && 'method' in msg) {
251
+ const r = msg;
252
+ this.emit('request', { id: r.id, method: r.method, params: r.params });
253
+ return;
254
+ }
255
+ }
256
+ failPending(err) {
257
+ for (const p of this.pending.values())
258
+ p.reject(err);
259
+ this.pending.clear();
260
+ }
261
+ }