@x-otto/install 0.0.1-alpha.4 → 0.0.1-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -70,8 +70,8 @@ await manager.install('./dir', { as: 'plugin' })
|
|
|
70
70
|
|
|
71
71
|
## Dependencies
|
|
72
72
|
|
|
73
|
-
- **Internal**: `@x-otto/mcp`, `@x-otto/plugin`, `@x-otto/skill`, `@x-otto/shared`
|
|
74
|
-
- **External**: `zod`, Node.js built-ins (fs, path, os, child_process)
|
|
73
|
+
- **Internal**: `@x-otto/env`, `@x-otto/mcp`, `@x-otto/plugin`, `@x-otto/skill`, `@x-otto/shared`
|
|
74
|
+
- **External**: `semver`, `zod`, Node.js built-ins (fs, path, os, child_process)
|
|
75
75
|
|
|
76
76
|
## Related
|
|
77
77
|
|
package/dist/index.d.ts
CHANGED
|
@@ -233,7 +233,7 @@ declare function listInstalledItems(options: ListInstalledOptions, mcpServers?:
|
|
|
233
233
|
* @param name 扩展名称
|
|
234
234
|
* @param type 扩展类型(由 detectUninstallTarget 提供)
|
|
235
235
|
* @param options 卸载选项
|
|
236
|
-
* @param
|
|
236
|
+
* @param getMcpServers 读取当前 mcp_servers 配置(仅 mcp 类型需要)
|
|
237
237
|
* @param persistSettings 持久化 settings(仅 mcp 类型需要)
|
|
238
238
|
*/
|
|
239
239
|
declare function uninstall(name: string, type: UninstallTarget, options: UninstallOptions, getMcpServers?: () => Record<string, unknown> | undefined, persistSettings?: (servers: Record<string, unknown>) => Promise<void>): Promise<UninstallResult>;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import{cpSync as e,createWriteStream as t,existsSync as n,mkdirSync as r,mkdtempSync as i,readFileSync as a,readdirSync as o,realpathSync as s,renameSync as c,rmSync as l,statSync as u,unlinkSync as d,writeFileSync as f}from"node:fs";import{homedir as p,tmpdir as m}from"node:os";import{basename as h,dirname as ee,join as g,relative as _,resolve as v}from"node:path";import{spawn as y,spawnSync as b}from"node:child_process";import{createLogger as te,isIntranetReachable as ne}from"@x-otto/shared";import{isShadowModeEnabled as re,normalizeEnv as x,resolveInternalRegistryUrl as ie,resolveNpmSniffRegistries as ae}from"@x-otto/env";import{parseSkillContent as oe}from"@x-otto/skill";import{HIGH_RISK_CAPABILITIES as se,PLUGIN_MANIFEST_FILENAME as ce,isPluginTrusted as le,parsePluginManifest as ue,trustPlugin as de,untrustPlugin as fe}from"@x-otto/plugin";import{compare as pe}from"semver";const me=[`.zip`,`.tar.gz`,`.tgz`,`.tar`],he=6e4;async function ge(e,t,n){return new Promise(r=>{let i=y(e,t,{stdio:`pipe`,...n}),a=``,o=``;i.stdout?.on(`data`,e=>{a+=e.toString(`utf-8`)}),i.stderr?.on(`data`,e=>{o+=e.toString(`utf-8`)});let s=!1,c=!1,l=n.timeout?setTimeout(()=>{c=!0,i.kill()},n.timeout):void 0;i.on(`close`,(e,t)=>{l&&clearTimeout(l),s||(s=!0,r({stdout:a,stderr:o,status:e,signal:t,timedOut:c}))}),i.on(`error`,()=>{l&&clearTimeout(l),s||(s=!0,r({stdout:a,stderr:o,status:null,signal:null,timedOut:!1}))})})}async function _e(e,t){let n=async(e,t)=>{let{stderr:n,status:r,signal:i,timedOut:a}=await ge(e,t,{timeout:he});if(a)throw Error(`解压超时(${he/1e3}s)`);if(r!==0){let e=n.trim()||`exit code ${r}${i?` (${i})`:``}`;throw Error(`解压失败:${e}`)}},r=e.toLowerCase();if(r.endsWith(`.tar.gz`)||r.endsWith(`.tgz`)){await n(`tar`,[`xzf`,e,`-C`,t]);return}if(r.endsWith(`.tar`)){await n(`tar`,[`xf`,e,`-C`,t]);return}if(r.endsWith(`.zip`)){await n(`unzip`,[`-o`,`-q`,e,`-d`,t]);return}throw Error(`不支持的归档格式:${e}`)}async function ve(e,t){let{stderr:n,status:r,signal:i,timedOut:a}=await ge(`tar`,[`czf`,t,`-C`,e,`.`],{timeout:he});if(a)throw Error(`打包超时(${he/1e3}s)`);if(r!==0){let e=n.trim()||`exit code ${r}${i?` (${i})`:``}`;throw Error(`打包失败:${e}`)}}function S(e){let t=v(e),n;try{n=s(e)}catch{n=t}let r=0,i=0,a=c=>{let l;try{l=o(c,{withFileTypes:!0})}catch{return}for(let o of l){let l=g(c,o.name);if(o.isSymbolicLink()){let t;try{t=s(l)}catch{throw Error(`安全拒绝:归档包含断链 "${_(e,l)}"`)}if(!t.startsWith(n+`/`)&&t!==n)throw Error(`安全拒绝:归档包含越界链接 "${_(e,l)}" → "${t}"`);try{u(l).isDirectory()&&a(l)}catch{}continue}if(!v(l).startsWith(t+`/`)&&v(l)!==t)throw Error(`安全拒绝:归档包含越界路径 "${_(e,l)}"`);if(o.isDirectory()){a(l);continue}if(o.isFile()){if(r++,r>1e4)throw Error(`安全拒绝:归档包含超过 10000 个文件`);try{i+=u(l).size}catch{}if(i>104857600)throw Error(`安全拒绝:归档总大小超过 100MB`)}}};return a(e),{totalBytes:i}}function ye(e,t){let n;try{n=u(e).size}catch{return}if(n===0)throw Error(`安全拒绝:归档文件为空`);let r=t/n;if(r>100)throw Error(`安全拒绝:压缩比异常(${Math.round(r)}:1,上限 100:1)`)}function be(){return i(g(m(),`otto-install-`))}function C(e){try{n(e)&&l(e,{recursive:!0,force:!0})}catch{}}function w(e){return e.replace(/\/\/[^@]+@/,`//`)}function xe(t){let n=be();try{e(t,n,{recursive:!0,verbatimSymlinks:!0,filter:e=>!e.includes(`/node_modules/`)&&!e.endsWith(`/node_modules`)});let{totalBytes:r}=S(n);return{tempDir:n,sourceUrl:w(h(t)),sourceType:`file`}}catch(e){throw C(n),e}}async function Se(e){if(!n(e))throw Error(`文件不存在:${e}`);if(u(e).isDirectory())return xe(e);let t=h(e);if(!me.some(e=>t.endsWith(e)))throw Error(`不支持的归档格式:${t}。支持 .zip、.tar.gz、.tgz、.tar(或直接传目录路径)`);let r=be();try{await _e(e,r);let{totalBytes:n}=S(r);return ye(e,n),{tempDir:r,sourceUrl:w(t),sourceType:`file`}}catch(e){throw C(r),e}}const Ce=te(`@x-otto/coding:install:url-resolver`),we=x(process.env.OTTO_DOWNLOAD_TIMEOUT_MS,3e4),Te=x(process.env.OTTO_DOWNLOAD_MAX_REDIRECTS,3),Ee=100*1024*1024;async function De(e,t){let r=h(new URL(e).pathname)||`download`,i=r.toLowerCase();if(!me.some(e=>i.endsWith(e)))throw Error(`URL 文件类型不支持:${r}。请提供 .zip、.tar.gz、.tgz 或 .tar 归档。`);let a=g(m(),`otto-download-${Date.now()}-${r}`),o=be();try{await Oe(e,a,t)}catch(e){C(o);try{n(a)&&d(a)}catch{}throw e}try{await _e(a,o);let{totalBytes:e}=S(o);ye(a,e)}catch(e){throw C(o),e}finally{try{n(a)&&d(a)}catch{}}return{tempDir:o,sourceUrl:w(e),sourceType:`url`}}async function Oe(e,n,r){let i=e;for(let a=0;a<=Te;a++){let o=await fetch(i,{signal:AbortSignal.timeout(we),redirect:`manual`});if(o.status>=300&&o.status<400&&o.headers.get(`location`)){i=o.headers.get(`location`),Ce.info(`Redirecting (%d/%d): %s → %s`,a+1,Te,e,i);continue}if(!o.ok){let e=o.status===404?`(URL 指向的文件不存在——核对下载地址)`:o.status===403||o.status===401?`(无访问权限——该资源可能需要登录或已过期)`:``;throw Error(`下载失败:HTTP ${o.status} ${o.statusText}${e}`)}let s=o.headers.get(`content-length`);if(s){let e=Number(s);if(Number.isFinite(e)&&e>Ee)throw Error(`文件过大:${Math.round(e/1024/1024)}MB,上限 ${Math.round(Ee/1024/1024)}MB`)}if(!o.body)throw Error(`下载失败:响应体为空`);let c=t(n),l=o.body.getReader(),u=0,d=0,f=s&&Number.isFinite(Number(s))?Number(s):void 0,p=f===void 0?262144:Math.max(f*.03,65536);try{for(;;){let{done:e,value:t}=await l.read();if(e)break;if(u+=t.byteLength,u>Ee)throw Error(`下载文件过大(超过 ${Math.round(Ee/1024/1024)}MB)`);r&&u-d>=p&&(d=u,r(u,f)),c.write(t)||await new Promise(e=>c.once(`drain`,e))}r&&u!==d&&r(u,f)}finally{l.releaseLock(),c.end(),await new Promise((e,t)=>{c.on(`finish`,e),c.on(`error`,t)})}return}throw Error(`下载失败:重定向次数超过上限 (${Te})`)}const ke=x(process.env.OTTO_GIT_CLONE_TIMEOUT_MS,3e4);async function T(e,t){return new Promise(n=>{let r=y(`git`,e,{stdio:`pipe`,...t}),i=``,a=``;r.stdout?.on(`data`,e=>{i+=e.toString(`utf-8`)}),r.stderr?.on(`data`,e=>{a+=e.toString(`utf-8`)});let o=!1,s=!1,c=t.timeout?setTimeout(()=>{s=!0,r.kill()},t.timeout):void 0;r.on(`close`,e=>{c&&clearTimeout(c),o||(o=!0,n({stdout:i,stderr:a,status:e,timedOut:s}))}),r.on(`error`,()=>{c&&clearTimeout(c),o||(o=!0,n({stdout:i,stderr:a,status:null,timedOut:!1}))})})}async function Ae(e,t){let n=be();return t===void 0?je(e,n):Me(e,n,t)}async function je(e,t){let n=await T([`clone`,`--depth`,`1`,`--quiet`,`--`,e,t],{timeout:ke});if(n.timedOut)throw C(t),Error(`git clone 超时(${ke/1e3}s)`);if(n.status!==0)throw C(t),Error(`git clone 失败:${Pe(n.stderr)}`);let r=await Ne(t);return{tempDir:t,sourceUrl:w(e),sourceType:`git`,commit:r}}async function Me(e,t,n){let r=await T([`init`,`--quiet`,t],{timeout:5e3});if(r.status!==0)throw C(t),Error(`git init 失败:${r.stderr.trim()||`unknown error`}`);let i=await T([`fetch`,`--depth`,`1`,`--quiet`,`--`,e,n],{cwd:t,timeout:ke});if(i.timedOut)throw C(t),Error(`git fetch 超时(${ke/1e3}s)`);if(i.status!==0){C(t);let e=i.stderr.trim()||`unknown error`,r=/couldn't find remote ref|fatal: remote error|unable to negotiate|no such ref/i.test(e)?`(ref '${n}' 不存在,或不是合法的 tag/branch 名——commit hash 精确 pin 暂不支持,因主流 git 托管方默认拒绝按任意 commit fetch)`:``;throw Error(`git fetch ref '${n}' 失败:${Pe(e)}${r}`)}let a=await T([`checkout`,`--quiet`,`FETCH_HEAD`],{cwd:t,timeout:1e4});if(a.status!==0)throw C(t),Error(`git checkout FETCH_HEAD 失败:${a.stderr.trim()||`unknown error`}`);let o=await Ne(t);return{tempDir:t,sourceUrl:w(e),sourceType:`git`,commit:o}}async function Ne(e){try{let t=await T([`rev-parse`,`HEAD`],{cwd:e,timeout:5e3});return t.status===0?t.stdout.trim():void 0}catch{return}}function Pe(e){let t=e.trim()||`unknown error`;return`${t}${/not found|repository.*does not exist/i.test(t)?`(仓库地址可能有误或为私有仓库——核对 URL;私有仓库需先配置 git 凭据)`:/permission denied|authentication failed|could not read/i.test(t)?`(无访问权限——私有仓库需配置 SSH key 或 git 凭据)`:/could not resolve host|unable to access/i.test(t)?`(网络不可达——检查网络连接后重试)`:``}`}function Fe(){return[...ae(),`https://registry.npmjs.org`]}async function Ie(e,t=5e3){for(let n of Fe()){let r=`${n}/${encodeURIComponent(e)}`,i=new AbortController,a=setTimeout(()=>i.abort(),t);try{let e=await fetch(r,{signal:i.signal});if(e.ok){let t=await e.json(),r=t[`dist-tags`];if(r){let e=r.latest??r.alpha??Le(r);if(e)return{version:e,registry:n}}if(t?.version)return{version:t.version,registry:n}}}catch{}finally{clearTimeout(a)}}return null}function Le(e){let t;for(let n of Object.values(e))(!t||Re(n,t)>0)&&(t=n);return t}function Re(e,t){let n=/(\d+)\.(\d+)\.(\d+)/.exec(e),r=/(\d+)\.(\d+)\.(\d+)/.exec(t);if(n&&r)for(let e=1;e<=3;e++){let t=Number(n[e])-Number(r[e]);if(t!==0)return t}return e<t?-1:e>t?1:0}const ze=x(process.env.OTTO_NPM_PACK_TIMEOUT_MS,6e4);function Be(e){let t=e.indexOf(`@`,e.startsWith(`@`)?1:0);return t>0?e.slice(0,t):e}function Ve(e){return e.indexOf(`@`,e.startsWith(`@`)?1:0)>0}async function He(e){let t=i(g(m(),`otto-npm-`)),r=i(g(m(),`otto-npm-extract-`)),a=await Ie(Be(e)).catch(()=>null),o=a?.registry,s=Ve(e)?e:a?`${e}@${a.version}`:e;try{let{stderr:i,status:a,timedOut:c}=await Ue(s,t,o);if(c)throw Error(`npm pack 超时(${ze/1e3}s)`);if(a!==0){let e=i.trim()||`exit code ${a}`,t=/404|E404/.test(e)?`(包名可能拼写有误——用 /search <关键词> 在 registry 中查找,或核对 npmjs.com)`:/ENOTFOUND|ETIMEDOUT|ECONNREFUSED|network/i.test(e)?`(网络不可达——检查网络连接或 npm registry 配置后重试)`:``;throw Error(`npm pack 失败:${e}${t}`)}let l=We(t);if(!l)throw Error(`npm pack 未生成 .tgz 文件:${e}`);await _e(l,r);let{totalBytes:u}=S(r);ye(l,u);try{Ge(t)}catch{}let d=g(r,`package`);return n(d)?{tempDir:d,sourceUrl:`npm:${e}`,sourceType:`npm`}:{tempDir:r,sourceUrl:`npm:${e}`,sourceType:`npm`}}catch(e){throw Ge(t),Ge(r),e}}async function Ue(e,t,n){return new Promise(r=>{let i=[`pack`,e,`--pack-destination`,t,`--quiet`];n&&i.push(`--registry`,n);let a=y(`npm`,i,{stdio:`pipe`}),o=``,s=``;a.stdout?.on(`data`,e=>{o+=e.toString(`utf-8`)}),a.stderr?.on(`data`,e=>{s+=e.toString(`utf-8`)});let c=!1,l=!1,u=setTimeout(()=>{l=!0,a.kill()},ze);a.on(`close`,e=>{clearTimeout(u),c||(c=!0,r({stdout:o,stderr:s,status:e,timedOut:l}))}),a.on(`error`,()=>{clearTimeout(u),c||(c=!0,r({stdout:o,stderr:s,status:null,timedOut:!1}))})})}function We(e){try{let t=o(e);for(let n of t)if(n.endsWith(`.tgz`)||n.endsWith(`.tar.gz`))return g(e,n)}catch{}return null}function Ge(e){try{n(e)&&l(e,{recursive:!0,force:!0})}catch{}}function Ke(e){let t=g(e,`SKILL.md`);if(n(t))return[t];let r=[];try{let t=o(e);for(let i of t){let t=g(e,i);try{if(!u(t).isDirectory())continue}catch{continue}let a=g(t,`SKILL.md`);n(a)&&r.push(a)}}catch{}return r}function qe(e){let t=Ke(e);return t.length>0?t[0]:null}function Je(e){let t=qe(e);if(!t)throw Error(`未找到 SKILL.md。skill 包必须包含一个 SKILL.md 文件(位于根目录或一层子目录下)。`);let n=a(t,`utf-8`),r=g(t,`..`);try{return oe(n,t,r)}catch(e){throw Error(`SKILL.md 解析失败:${e instanceof Error?e.message:String(e)}`)}}function Ye(e,t){let r=n(g(e,ce)),i=qe(e)!==null,a=n(g(e,`.mcp.json`));if(t)return Xe(e,t);let o=[];if(r&&o.push(`plugin`),i&&o.push(`skill`),a&&o.push(`mcp`),o.length===0)throw Error(`未检测到可安装内容。需要 otto-plugin.json(plugin)、SKILL.md(skill)或 .mcp.json(mcp)。如确定类型,请使用 --as 指定。`);if(o.length>1)throw Error(`检测到多种内容类型:${o.join(` + `)}。无法自动判定,请使用 --as ${o.join(` 或 --as `)} 指定。`);return Xe(e,o[0])}function Xe(e,t){switch(t){case`skill`:return Ze(e);case`plugin`:return Qe(e);case`mcp`:return $e(e)}}function Ze(e){let t=Ke(e);if(t.length===0)throw Error(`未找到 SKILL.md。skill 包必须包含一个 SKILL.md 文件。`);let n=[];for(let e of t)try{let t=a(e,`utf-8`),r=g(e,`..`);n.push(oe(t,e,r))}catch(t){throw Error(`${e}: ${t instanceof Error?t.message:String(t)}`)}if(new Set(n.map(e=>e.metadata.name)).size!==n.length){let e=n.filter((e,t,n)=>n.findIndex(t=>t.metadata.name===e.metadata.name)!==t).map(e=>`"${e.metadata.name}" (${e.filePath})`).join(`, `);throw Error(`检测到同名 skill:${e}。请修改 SKILL.md 中的 name 字段使其唯一。`)}return{type:`skill`,skillDef:n.length===1?n[0]:void 0,skillDefs:n}}function Qe(e){let t=g(e,ce);if(!n(t))throw Error(`未找到 ${ce}。`);let r=ue(a(t,`utf-8`),t);if(!r)throw Error(`${ce} 格式无效(缺少 id 字段或 JSON 解析失败)。`);return{type:`plugin`,pluginManifest:r}}function $e(e){let t=g(e,`.mcp.json`),r;if(n(t)){let e=a(t,`utf-8`);try{r=JSON.parse(e)}catch{throw Error(`.mcp.json 格式无效(JSON 解析失败)。`)}}else r={};return{type:`mcp`,mcpConfig:r}}const et=/^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/;function tt(t,a,o){let s;if(o)s=o;else try{s=Je(t)}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}let u=s.metadata.name;if(!et.test(u))return{success:!1,error:`skill 名称 "${u}" 不符合命名规范。仅允许小写字母、数字和连字符(kebab-case),例如 "my-skill"。`};let d=a.global?g(p(),`.otto`,`skills`):a.workspaceDir?g(a.workspaceDir,`.otto`,`skills`):g(process.cwd(),`.otto`,`skills`),m=g(d,u),h=n(m);if(a.dryRun){let e=nt(s.directory);return{success:!0,name:u,targetPath:m,definition:s,plan:[`来源:${s.directory}`,`目标:${m}`,`模式:${a.global?`全局`:`项目`}级`,h?`操作:覆盖(--force)`:`操作:新建`,`文件(${e.length}):`,...e.map(e=>` ${e}`)]}}if(h&&!a.force)return{success:!1,name:u,error:`skill "${u}" 已存在于 ${m}。`,failureKind:`conflict`};r(d,{recursive:!0});let v=i(g(d,`.otto-staging-${u}-`)),y=[];try{if(e(s.directory,v,{recursive:!0}),a.sourceMetadata)try{let e={sourceType:a.sourceMetadata.sourceType,sourceUrl:a.sourceMetadata.sourceUrl,commit:a.sourceMetadata.commit,subPath:_(t,s.directory)||void 0,installedAt:new Date().toISOString(),installedBy:`user`,installerVersion:process.env.OTTO_VERSION??`unknown`};f(g(v,`.otto-install.json`),JSON.stringify(e,null,2)+`
|
|
2
2
|
`)}catch(e){y.push(`无法写入安装元数据:${e instanceof Error?e.message:String(e)}`)}if(h){let e=g(ee(m),`.${u}.bak`);try{l(e,{recursive:!0,force:!0})}catch{}try{c(m,e)}catch(e){return l(v,{recursive:!0,force:!0}),{success:!1,name:u,error:`无法替换已有 skill 目录:${e instanceof Error?e.message:String(e)}`}}try{c(v,m)}catch(t){try{c(e,m)}catch{}return l(v,{recursive:!0,force:!0}),{success:!1,name:u,error:`安装失败:${t instanceof Error?t.message:String(t)}`}}try{l(e,{recursive:!0,force:!0})}catch{}}else try{c(v,m)}catch(e){return l(v,{recursive:!0,force:!0}),{success:!1,name:u,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}}catch(e){try{l(v,{recursive:!0,force:!0})}catch{}return{success:!1,name:u,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}return{success:!0,name:u,targetPath:m,definition:s,...y.length>0?{warnings:y}:{}}}function nt(e){let t=[],n=[{dir:e,prefix:``}];for(;;){let e=n.pop();if(!e)break;let r=o(e.dir,{withFileTypes:!0});for(let i of r){let r=e.prefix?`${e.prefix}/${i.name}`:i.name;i.isDirectory()?n.push({dir:g(e.dir,i.name),prefix:r}):t.push(r)}}return t.sort()}function rt(e){return(e.capabilities??[]).filter(e=>se.includes(e))}const it={provider:`provider —— 注册 LLM provider,将处理你的凭据与请求流量`,tools:`tools —— 注册可被 agent 调用的工具`,"tui.renderer":`tui.renderer —— 在 TUI 进程内运行自定义渲染代码`,network:`network —— 发起任意网络请求`};async function at(t,a,o){let s=a.id,u=o.global?g(p(),`.otto`,`plugins`):o.workspaceDir?g(o.workspaceDir,`.otto`,`plugins`):g(process.cwd(),`.otto`,`plugins`),d=g(u,s),m=n(d);if(o.dryRun){let e=rt(a);return{success:!0,name:s,targetPath:d,manifest:a,pendingCapabilities:e.length>0?e:void 0,plan:[`类型:plugin`,`名称:${a.name??s}`,`来源:${t}`,`目标:${d}`,`模式:${o.global?`全局`:`项目`}级`,m?`操作:覆盖(--force)`:`操作:新建`,`信任策略:${o.global?`自动信任(用户级)`:`安装后自动信任`}`,...a.scripts?.postinstall?[`⚠ postinstall(安装后立即执行 shell):${a.scripts.postinstall}`]:[],...a.scripts?.setup?[`⚠ setup(首次加载执行 shell):${a.scripts.setup}`]:[],...e.length>0?[`⚠ 高危能力(安装后需另行 /trust plugin ${s} 显式授予,默认不生效):`,...e.map(e=>` • ${it[e]??e}`)]:[]]}}if(m&&!o.force)return{success:!1,name:s,error:`plugin "${s}" 已存在于 ${d}。`,failureKind:`conflict`};r(u,{recursive:!0});let h=i(g(u,`.otto-staging-plugin-${s}-`)),_=[];try{if(e(t,h,{recursive:!0}),o.sourceMetadata)try{let e={sourceType:o.sourceMetadata.sourceType,sourceUrl:o.sourceMetadata.sourceUrl,commit:o.sourceMetadata.commit,subPath:o.sourceMetadata.subPath,installedAt:new Date().toISOString(),installedBy:`user`,installerVersion:process.env.OTTO_VERSION??`unknown`};f(g(h,`.otto-install.json`),JSON.stringify(e,null,2)+`
|
|
3
|
-
`)}catch(e){_.push(`无法写入安装元数据:${e instanceof Error?e.message:String(e)}`)}if(m){let e=g(ee(d),`.${s}.bak`);try{l(e,{recursive:!0,force:!0})}catch{}try{c(d,e)}catch(e){return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`无法替换已有 plugin 目录:${e instanceof Error?e.message:String(e)}`}}try{c(h,d)}catch(t){try{c(e,d)}catch{}return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`安装失败:${t instanceof Error?t.message:String(t)}(已恢复旧版本)`}}try{l(e,{recursive:!0,force:!0})}catch{}}else try{c(h,d)}catch(e){return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}}catch(e){try{l(h,{recursive:!0,force:!0})}catch{}return{success:!1,name:s,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}let v=!1;if(!o.global)try{de(d),v=!0}catch{}let y=[..._],b;if(a.scripts?.postinstall&&o.postInstallExecutor)if(o.global||le(d)){if(b=await o.postInstallExecutor({pluginDir:d,pluginId:s,workspaceDir:o.workspaceDir},a.scripts.postinstall),!b.success){let e=b.timeout?`postinstall 超时 (30s): ${a.scripts.postinstall}`:b.error?`postinstall 错误: ${b.error}`:`postinstall 返回非零 (exit=${b.exitCode}): ${a.scripts.postinstall}`;y.push(e)}}else{let e=o.global?void 0:`postinstall 跳过:插件信任持久化失败,使用 isPluginTrusted 验证未通过`;e&&y.push(e)}else a.scripts?.postinstall&&!o.postInstallExecutor?y.push(`postinstall 跳过:当前环境中未配置钩子执行器`):!o.global&&!v&&y.push(`插件信任持久化失败,可执行面(.mcp.json/commands/scripts)下次加载时将被门控`);let te=rt(a);return te.length>0&&y.push(`插件声明高危能力(${te.join(`, `)})尚未授予——运行 /trust plugin ${s} 完成确认后方可生效`),{success:!0,name:s,targetPath:d,manifest:a,pendingCapabilities:te.length>0?te:void 0,...b?{postinstall:b}:{},...y.length>0?{warnings:y}:{}}}async function ot(e,t,n,r,i){let a=n.global?`全局`:`项目`;if(n.dryRun){let n=t.type??(t.command?`stdio`:`http`);return{success:!0,name:e,mcpConfig:t,plan:[`类型:mcp`,`名称:${e}`,`传输:${n}`,`${t.command?`命令:${t.command} ${(t.args??[]).join(` `)}`:``}`,`${t.url?`URL:${t.url}`:``}`,`模式:${a}级`,`操作:写入 settings.mcp_servers.${e}`].filter(e=>!!e)}}let o=r()??{};if(e in o&&!n.force)return{success:!1,name:e,error:`MCP server "${e}" 已存在。`,failureKind:`conflict`};let s={...o,[e]:t};try{await i(s)}catch(t){return{success:!1,name:e,error:`写入 MCP 配置失败:${t instanceof Error?t.message:String(t)}`}}return{success:!0,name:e,mcpConfig:t}}const st=/^https?:\/\//,ct=/^(git@|git:\/\/|ssh:\/\/)|\.git$|(?<!https?:\/\/)\b(github\.com|gitlab\.com|bitbucket\.org)\b/;var lt=class{async install(e,t,n,r){let i,a;try{let o=t.type??ut(e);E(t,{phase:`resolving`,message:`Resolving ${o} source...`});let s=t.onProgress&&!t.dryRun?(e,n)=>{E(t,{phase:`resolving`,message:`Resolving ${o} source...`,bytesDownloaded:e,bytesTotal:n})}:void 0;a=await ht(e,o,t.ref,s),i=a.tempDir;let c=i;if(t.subPath){let{resolve:e,sep:n}=await import(`node:path`),r=e(i,t.subPath);if(r!==i&&!r.startsWith(i+n))throw Error(`subPath 越出来源根目录:${t.subPath}`);let{existsSync:a}=await import(`node:fs`);if(!a(r))throw Error(`subPath 不存在于来源中:${t.subPath}`);c=r}E(t,{phase:`detecting`,message:`Detecting installed content...`});let l=Ye(c,t.as),u=l.type;switch(u){case`skill`:{let e=l.skillDefs??(l.skillDef?[l.skillDef]:[]);if(e.length===0)throw Error(`skill 检测失败:无法解析 SKILL.md`);let n={...t,sourceMetadata:{sourceType:o,sourceUrl:a.sourceUrl,commit:a.commit}};if(e.length===1)return E(t,{phase:`installing`,message:`Installing ${e[0].metadata.name}`,current:1,total:1}),tt(c,n,e[0]);let r=c,i=[];for(let a=0;a<e.length;a++)E(t,{phase:`installing`,message:`Installing ${e[a].metadata.name}`,current:a+1,total:e.length}),i.push(tt(r,n,e[a]));let s=i.every(e=>e.success);return{success:s,name:`${e.length} skills`,error:s?void 0:pt(i),failureKind:s?void 0:mt(i),plan:t.dryRun?i.map((t,n)=>{let r=(e[n].supportingFiles?.length??0)+1;return`${t.name??`?`} → ${t.targetPath??`?`} (${r} 文件)`}):void 0,results:i,warnings:i.flatMap(e=>e.warnings??[]),targetPath:i[0]?.targetPath}}case`plugin`:{if(!l.pluginManifest)throw Error(`plugin 检测失败:无法解析 otto-plugin.json`);E(t,{phase:`installing`,message:`Installing ${l.pluginManifest.id}`,current:1,total:1});let e={...t,sourceMetadata:{sourceType:o,sourceUrl:a.sourceUrl,commit:a.commit}};return await at(c,l.pluginManifest,e)}case`mcp`:{if(!n||!r)return{success:!1,error:`MCP 安装需要 settings 访问权限。请在 CLI 环境中执行。`};let e=l.mcpConfig?.url?new URL(l.mcpConfig.url).hostname.replace(/\./g,`-`):l.mcpConfig?.command?l.mcpConfig.command.replace(/[^a-z0-9-]/g,`-`).slice(0,40):`mcp-server`,i={...l.mcpConfig,...t.env?{env:{...l.mcpConfig?.env??{},...t.env}}:{}};return E(t,{phase:`installing`,message:`Installing MCP ${e}`,current:1,total:1}),ot(e,i,t,n,r)}default:return{success:!1,error:`不支持的内容类型:${u}`}}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}finally{i&&C(i)}}async installSkill(e,t){return this.install(e,{...t,as:`skill`})}};function ut(e){return ct.test(e)?`git`:st.test(e)?`url`:dt(e)?`file`:`npm`}function dt(e){return/^@[^/]+\/[^/]+$/.test(e)?!1:!!(/\.(zip|tar\.gz|tgz|tar)$/i.test(e)||e.includes(`/`)||e.includes(`\\`))}function ft(e){return e.replace(/[。.]\s*$/,``)}function pt(e){let t=e.filter(e=>!e.success),n=t.map(e=>`${e.name??`?`} —— ${ft(e.error??`unknown error`)}`).join(`;`);return`${t.length}/${e.length} 个 skill 安装失败:${n}`}function mt(e){let t=e.filter(e=>!e.success);if(t.length!==0)return t.every(e=>e.failureKind===`conflict`)?`conflict`:void 0}function E(e,t){if(e.onProgress&&!(e.dryRun&&t.phase!==`resolving`&&t.phase!==`detecting`))try{e.onProgress(t)}catch{}}async function ht(e,t,n,r){switch(t){case`file`:return Se(e);case`url`:return De(e,r);case`git`:return Ae(e,n);case`npm`:return He(e)}}function gt(e,t,r){let i=t.global?g(p(),`.otto`):t.workspaceRoot?g(t.workspaceRoot,`.otto`):t.workspaceDir?g(t.workspaceDir,`.otto`):g(process.cwd(),`.otto`);return n(g(i,`skills`,e))?`skill`:n(g(i,`plugins`,e))?`plugin`:r&&e in r?`mcp`:null}function D(e){try{return o(e,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function _t(e,t){let n=[],r=e.workspaceDir??process.cwd(),i=!e.scope||e.scope===`global`,a=!e.scope||e.scope===`project`,o=!e.scope||e.scope===`repository`;if(i){let e=g(p(),`.otto`);D(g(e,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`global`})),D(g(e,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`global`}))}if(a){let e=g(r,`.otto`);D(g(e,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`project`})),D(g(e,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`project`})),t&&Object.entries(t).forEach(([e,t])=>{let r=t.command??t.url;n.push({name:e,type:`mcp`,scope:`project`,detail:r})})}if(o&&e.workspaceRoot){let t=g(e.workspaceRoot,`.otto`);D(g(t,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`repository`})),D(g(t,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`repository`}))}let s=new Map;for(let e of n){let t=`${e.type}:${e.name}`;(!s.has(t)||e.scope===`global`)&&s.set(t,e)}return[...s.values()]}async function vt(e,t,r,i,a){if(e.includes(`/`)||e.includes(`\\`)||e.includes(`..`))return{success:!1,name:e,type:t,error:`非法名称(含路径分隔符或 ..):${e}`};let o=r.global?g(p(),`.otto`):r.workspaceRoot?g(r.workspaceRoot,`.otto`):r.workspaceDir?g(r.workspaceDir,`.otto`):g(process.cwd(),`.otto`),s=r.global?`全局`:r.workspaceRoot?`仓库`:`项目`;switch(t){case`skill`:{let i=g(o,`skills`,e);if(r.dryRun)return{success:!0,name:e,type:t,plan:[`类型:skill`,`名称:${e}`,`路径:${i}`,`模式:${s}级`,`操作:删除目录`]};if(!n(i))return{success:!1,name:e,type:t,error:`skill "${e}" 不存在于 ${i}`};try{l(i,{recursive:!0,force:!0})}catch(n){return{success:!1,name:e,type:t,error:`删除失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}case`plugin`:{let i=g(o,`plugins`,e);if(r.dryRun)return{success:!0,name:e,type:t,plan:[`类型:plugin`,`名称:${e}`,`路径:${i}`,`模式:${s}级`,`操作:删除目录 + 撤销信任记录`]};if(!n(i))return{success:!1,name:e,type:t,error:`plugin "${e}" 不存在于 ${i}`};try{try{fe(i)}catch{}l(i,{recursive:!0,force:!0})}catch(n){return{success:!1,name:e,type:t,error:`删除失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}case`mcp`:{if(!i||!a)return{success:!1,name:e,type:t,error:`MCP 卸载需要 settings 访问权限`};let n={...i()??{}};if(!(e in n))return{success:!1,name:e,type:t,error:`MCP server "${e}" 不存在`};if(r.dryRun){let r=n[e];return{success:!0,name:e,type:t,plan:[`类型:mcp server`,`名称:${e}`,`命令:${r?.command??`(URL)`}`,`模式:${s}级`,`操作:从 settings.mcp_servers 删除配置`]}}delete n[e];try{await a(n)}catch(n){return{success:!1,name:e,type:t,error:`删除 MCP 配置失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}}}function yt(e){let t=[];if(e.scope===void 0||e.scope===`all`||e.scope===`project`){let n=e.workspaceDir?g(e.workspaceDir,`.otto`):g(process.cwd(),`.otto`);O(g(n,`skills`),`skill`,t),O(g(n,`plugins`),`plugin`,t)}if((e.scope===void 0||e.scope===`all`||e.scope===`repository`)&&e.workspaceRoot){let n=g(e.workspaceRoot,`.otto`);O(g(n,`skills`),`skill`,t),O(g(n,`plugins`),`plugin`,t)}if(e.scope===void 0||e.scope===`all`||e.scope===`global`){let e=g(p(),`.otto`);O(g(e,`skills`),`skill`,t),O(g(e,`plugins`),`plugin`,t)}return t}function O(e,t,r){if(!n(e))return;let i;try{i=o(e)}catch{return}for(let o of i){let i=g(e,o);try{if(!u(i).isDirectory())continue}catch{continue}if(t===`skill`){let e=g(i,`SKILL.md`);if(!n(e))continue;try{let n=oe(a(e,`utf-8`),e,i);n.metadata.version&&r.push({name:n.metadata.name,type:t,installed:n.metadata.version,path:i})}catch{}}else{let e=g(i,`otto-plugin.json`);if(!n(e))continue;try{let n=ue(a(e,`utf-8`),e);n?.version&&r.push({name:n.id,type:t,installed:n.version,path:i})}catch{}}}}async function bt(e){let t=[];for(let n of e){let e=xt(n.path);if(e===`git`){let e=await Et(n.path,n.name,n.type);if(e){t.push(e);continue}t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(.otto-install.json 声明 git 来源但缺 commit/sourceUrl)`});continue}if(e===`file`||e===`url`){t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(${e} 来源不支持版本比对)`});continue}if(e===void 0&&!St(n.name)){let e=await Et(n.path,n.name,n.type);if(e){t.push(e);continue}t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(非 npm 来源且无 .otto-install.json)`});continue}try{let e=await Ct(n.name);if(!e){t.push({name:n.name,type:n.type,installed:n.installed,error:`无法获取最新版本`});continue}let r=pe(e,n.installed)>0;t.push({name:n.name,type:n.type,installed:n.installed,latest:e,newer:r})}catch{t.push({name:n.name,type:n.type,installed:n.installed,error:`版本检查失败`})}}return t}function xt(e){let t=g(e,`.otto-install.json`);if(n(t))try{return JSON.parse(a(t,`utf-8`)).sourceType}catch{return}}function St(e){return!e.includes(`://`)&&!e.endsWith(`.git`)&&!e.endsWith(`.zip`)}async function Ct(e){return(await Ie(e))?.version??null}function wt(e,t){let r=[];if(!n(e))return r;let i;try{i=o(e)}catch{return r}for(let o of i){let i=g(e,o);try{if(!u(i).isDirectory())continue}catch{continue}let s=g(i,`.otto-install.json`);if(!n(s))continue;let c;try{c=JSON.parse(a(s,`utf-8`))}catch{continue}if(!(c.sourceType!==`git`||!c.commit||!c.sourceUrl))try{let e=Tt(c.sourceUrl);if(!e){r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,error:`远程无默认分支`});continue}r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,remoteCommit:e,newer:e!==c.commit})}catch{r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,error:`git ls-remote 执行异常`})}}return r}function Tt(e){let t=b(`git`,[`ls-remote`,`--symref`,e,`HEAD`],{stdio:`pipe`,timeout:1e4});if(t.status===0){let e=t.stdout.toString().trim().split(`
|
|
3
|
+
`)}catch(e){_.push(`无法写入安装元数据:${e instanceof Error?e.message:String(e)}`)}if(m){let e=g(ee(d),`.${s}.bak`);try{l(e,{recursive:!0,force:!0})}catch{}try{c(d,e)}catch(e){return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`无法替换已有 plugin 目录:${e instanceof Error?e.message:String(e)}`}}try{c(h,d)}catch(t){try{c(e,d)}catch{}return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`安装失败:${t instanceof Error?t.message:String(t)}(已恢复旧版本)`}}try{l(e,{recursive:!0,force:!0})}catch{}}else try{c(h,d)}catch(e){return l(h,{recursive:!0,force:!0}),{success:!1,name:s,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}}catch(e){try{l(h,{recursive:!0,force:!0})}catch{}return{success:!1,name:s,error:`安装失败:${e instanceof Error?e.message:String(e)}`}}let v=!1;if(!o.global)try{de(d),v=!0}catch{}let y=[..._],b;if(a.scripts?.postinstall&&o.postInstallExecutor)if(o.global||le(d)){if(b=await o.postInstallExecutor({pluginDir:d,pluginId:s,workspaceDir:o.workspaceDir},a.scripts.postinstall),!b.success){let e=b.timeout?`postinstall 超时 (30s): ${a.scripts.postinstall}`:b.error?`postinstall 错误: ${b.error}`:`postinstall 返回非零 (exit=${b.exitCode}): ${a.scripts.postinstall}`;y.push(e)}}else{let e=o.global?void 0:`postinstall 跳过:插件信任持久化失败,使用 isPluginTrusted 验证未通过`;e&&y.push(e)}else a.scripts?.postinstall&&!o.postInstallExecutor?y.push(`postinstall 跳过:当前环境中未配置钩子执行器`):!o.global&&!v&&y.push(`插件信任持久化失败,可执行面(.mcp.json/commands/scripts)下次加载时将被门控`);let te=rt(a);return te.length>0&&y.push(`插件声明高危能力(${te.join(`, `)})尚未授予——运行 /trust plugin ${s} 完成确认后方可生效`),{success:!0,name:s,targetPath:d,manifest:a,pendingCapabilities:te.length>0?te:void 0,...b?{postinstall:b}:{},...y.length>0?{warnings:y}:{}}}async function ot(e,t,n,r,i){let a=n.global?`全局`:`项目`;if(n.dryRun){let n=t.type??(t.command?`stdio`:`http`);return{success:!0,name:e,mcpConfig:t,plan:[`类型:mcp`,`名称:${e}`,`传输:${n}`,`${t.command?`命令:${t.command} ${(t.args??[]).join(` `)}`:``}`,`${t.url?`URL:${t.url}`:``}`,`模式:${a}级`,`操作:写入 settings.mcp_servers.${e}`].filter(e=>!!e)}}let o=r()??{};if(e in o&&!n.force)return{success:!1,name:e,error:`MCP server "${e}" 已存在。`,failureKind:`conflict`};let s={...o,[e]:t};try{await i(s)}catch(t){return{success:!1,name:e,error:`写入 MCP 配置失败:${t instanceof Error?t.message:String(t)}`}}return{success:!0,name:e,mcpConfig:t}}const st=/^https?:\/\//,ct=/^(git@|git:\/\/|ssh:\/\/)|\.git$|(?<!https?:\/\/)\b(github\.com|gitlab\.com|bitbucket\.org)\b/;var lt=class{async install(e,t,n,r){let i,a;try{let o=t.type??ut(e);E(t,{phase:`resolving`,message:`Resolving ${o} source...`});let s=t.onProgress&&!t.dryRun?(e,n)=>{E(t,{phase:`resolving`,message:`Resolving ${o} source...`,bytesDownloaded:e,bytesTotal:n})}:void 0;a=await ht(e,o,t.ref,s),i=a.tempDir;let c=i;if(t.subPath){let{resolve:e,sep:n}=await import(`node:path`),r=e(i,t.subPath);if(r!==i&&!r.startsWith(i+n))throw Error(`subPath 越出来源根目录:${t.subPath}`);let{existsSync:a}=await import(`node:fs`);if(!a(r))throw Error(`subPath 不存在于来源中:${t.subPath}`);c=r}E(t,{phase:`detecting`,message:`Detecting installed content...`});let l=Ye(c,t.as),u=l.type;switch(u){case`skill`:{let e=l.skillDefs??(l.skillDef?[l.skillDef]:[]);if(e.length===0)throw Error(`skill 检测失败:无法解析 SKILL.md`);let n={...t,sourceMetadata:{sourceType:o,sourceUrl:a.sourceUrl,commit:a.commit}};if(e.length===1)return E(t,{phase:`installing`,message:`Installing ${e[0].metadata.name}`,current:1,total:1}),tt(c,n,e[0]);let r=c,i=[];for(let a=0;a<e.length;a++)E(t,{phase:`installing`,message:`Installing ${e[a].metadata.name}`,current:a+1,total:e.length}),i.push(tt(r,n,e[a]));let s=i.every(e=>e.success);return{success:s,name:`${e.length} skills`,error:s?void 0:pt(i),failureKind:s?void 0:mt(i),plan:t.dryRun?i.map((t,n)=>{let r=(e[n].supportingFiles?.length??0)+1;return`${t.name??`?`} → ${t.targetPath??`?`} (${r} 文件)`}):void 0,results:i,warnings:i.flatMap(e=>e.warnings??[]),targetPath:i[0]?.targetPath}}case`plugin`:{if(!l.pluginManifest)throw Error(`plugin 检测失败:无法解析 otto-plugin.json`);E(t,{phase:`installing`,message:`Installing ${l.pluginManifest.id}`,current:1,total:1});let e={...t,sourceMetadata:{sourceType:o,sourceUrl:a.sourceUrl,commit:a.commit}};return await at(c,l.pluginManifest,e)}case`mcp`:{if(!n||!r)return{success:!1,error:`MCP 安装需要 settings 访问权限。请在 CLI 环境中执行。`};let e=l.mcpConfig?.url?new URL(l.mcpConfig.url).hostname.replace(/\./g,`-`):l.mcpConfig?.command?l.mcpConfig.command.replace(/[^a-z0-9-]/g,`-`).slice(0,40):`mcp-server`,i={...l.mcpConfig,...t.env?{env:{...l.mcpConfig?.env,...t.env}}:{}};return E(t,{phase:`installing`,message:`Installing MCP ${e}`,current:1,total:1}),ot(e,i,t,n,r)}default:return{success:!1,error:`不支持的内容类型:${u}`}}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}finally{i&&C(i)}}async installSkill(e,t){return this.install(e,{...t,as:`skill`})}};function ut(e){return ct.test(e)?`git`:st.test(e)?`url`:dt(e)?`file`:`npm`}function dt(e){return/^@[^/]+\/[^/]+$/.test(e)?!1:!!(/\.(zip|tar\.gz|tgz|tar)$/i.test(e)||e.includes(`/`)||e.includes(`\\`))}function ft(e){return e.replace(/[。.]\s*$/,``)}function pt(e){let t=e.filter(e=>!e.success),n=t.map(e=>`${e.name??`?`} —— ${ft(e.error??`unknown error`)}`).join(`;`);return`${t.length}/${e.length} 个 skill 安装失败:${n}`}function mt(e){let t=e.filter(e=>!e.success);if(t.length!==0)return t.every(e=>e.failureKind===`conflict`)?`conflict`:void 0}function E(e,t){if(e.onProgress&&!(e.dryRun&&t.phase!==`resolving`&&t.phase!==`detecting`))try{e.onProgress(t)}catch{}}async function ht(e,t,n,r){switch(t){case`file`:return Se(e);case`url`:return De(e,r);case`git`:return Ae(e,n);case`npm`:return He(e)}}function gt(e,t,r){let i=t.global?g(p(),`.otto`):t.workspaceRoot?g(t.workspaceRoot,`.otto`):t.workspaceDir?g(t.workspaceDir,`.otto`):g(process.cwd(),`.otto`);return n(g(i,`skills`,e))?`skill`:n(g(i,`plugins`,e))?`plugin`:r&&e in r?`mcp`:null}function D(e){try{return o(e,{withFileTypes:!0}).filter(e=>e.isDirectory()).map(e=>e.name)}catch{return[]}}function _t(e,t){let n=[],r=e.workspaceDir??process.cwd(),i=!e.scope||e.scope===`global`,a=!e.scope||e.scope===`project`,o=!e.scope||e.scope===`repository`;if(i){let e=g(p(),`.otto`);D(g(e,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`global`})),D(g(e,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`global`}))}if(a){let e=g(r,`.otto`);D(g(e,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`project`})),D(g(e,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`project`})),t&&Object.entries(t).forEach(([e,t])=>{let r=t.command??t.url;n.push({name:e,type:`mcp`,scope:`project`,detail:r})})}if(o&&e.workspaceRoot){let t=g(e.workspaceRoot,`.otto`);D(g(t,`skills`)).forEach(e=>n.push({name:e,type:`skill`,scope:`repository`})),D(g(t,`plugins`)).forEach(e=>n.push({name:e,type:`plugin`,scope:`repository`}))}let s=new Map;for(let e of n){let t=`${e.type}:${e.name}`;(!s.has(t)||e.scope===`global`)&&s.set(t,e)}return[...s.values()]}async function vt(e,t,r,i,a){if(e.includes(`/`)||e.includes(`\\`)||e.includes(`..`))return{success:!1,name:e,type:t,error:`非法名称(含路径分隔符或 ..):${e}`};let o=r.global?g(p(),`.otto`):r.workspaceRoot?g(r.workspaceRoot,`.otto`):r.workspaceDir?g(r.workspaceDir,`.otto`):g(process.cwd(),`.otto`),s=r.global?`全局`:r.workspaceRoot?`仓库`:`项目`;switch(t){case`skill`:{let i=g(o,`skills`,e);if(r.dryRun)return{success:!0,name:e,type:t,plan:[`类型:skill`,`名称:${e}`,`路径:${i}`,`模式:${s}级`,`操作:删除目录`]};if(!n(i))return{success:!1,name:e,type:t,error:`skill "${e}" 不存在于 ${i}`};try{l(i,{recursive:!0,force:!0})}catch(n){return{success:!1,name:e,type:t,error:`删除失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}case`plugin`:{let i=g(o,`plugins`,e);if(r.dryRun)return{success:!0,name:e,type:t,plan:[`类型:plugin`,`名称:${e}`,`路径:${i}`,`模式:${s}级`,`操作:删除目录 + 撤销信任记录`]};if(!n(i))return{success:!1,name:e,type:t,error:`plugin "${e}" 不存在于 ${i}`};try{try{fe(i)}catch{}l(i,{recursive:!0,force:!0})}catch(n){return{success:!1,name:e,type:t,error:`删除失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}case`mcp`:{if(!i||!a)return{success:!1,name:e,type:t,error:`MCP 卸载需要 settings 访问权限`};let n={...i()};if(!(e in n))return{success:!1,name:e,type:t,error:`MCP server "${e}" 不存在`};if(r.dryRun){let r=n[e];return{success:!0,name:e,type:t,plan:[`类型:mcp server`,`名称:${e}`,`命令:${r?.command??`(URL)`}`,`模式:${s}级`,`操作:从 settings.mcp_servers 删除配置`]}}delete n[e];try{await a(n)}catch(n){return{success:!1,name:e,type:t,error:`删除 MCP 配置失败:${n instanceof Error?n.message:String(n)}`}}return{success:!0,name:e,type:t}}}}function yt(e){let t=[];if(e.scope===void 0||e.scope===`all`||e.scope===`project`){let n=e.workspaceDir?g(e.workspaceDir,`.otto`):g(process.cwd(),`.otto`);O(g(n,`skills`),`skill`,t),O(g(n,`plugins`),`plugin`,t)}if((e.scope===void 0||e.scope===`all`||e.scope===`repository`)&&e.workspaceRoot){let n=g(e.workspaceRoot,`.otto`);O(g(n,`skills`),`skill`,t),O(g(n,`plugins`),`plugin`,t)}if(e.scope===void 0||e.scope===`all`||e.scope===`global`){let e=g(p(),`.otto`);O(g(e,`skills`),`skill`,t),O(g(e,`plugins`),`plugin`,t)}return t}function O(e,t,r){if(!n(e))return;let i;try{i=o(e)}catch{return}for(let o of i){let i=g(e,o);try{if(!u(i).isDirectory())continue}catch{continue}if(t===`skill`){let e=g(i,`SKILL.md`);if(!n(e))continue;try{let n=oe(a(e,`utf-8`),e,i);n.metadata.version&&r.push({name:n.metadata.name,type:t,installed:n.metadata.version,path:i})}catch{}}else{let e=g(i,`otto-plugin.json`);if(!n(e))continue;try{let n=ue(a(e,`utf-8`),e);n?.version&&r.push({name:n.id,type:t,installed:n.version,path:i})}catch{}}}}async function bt(e){let t=[];for(let n of e){let e=xt(n.path);if(e===`git`){let e=await Et(n.path,n.name,n.type);if(e){t.push(e);continue}t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(.otto-install.json 声明 git 来源但缺 commit/sourceUrl)`});continue}if(e===`file`||e===`url`){t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(${e} 来源不支持版本比对)`});continue}if(e===void 0&&!St(n.name)){let e=await Et(n.path,n.name,n.type);if(e){t.push(e);continue}t.push({name:n.name,type:n.type,installed:n.installed,error:`无法检查升级(非 npm 来源且无 .otto-install.json)`});continue}try{let e=await Ct(n.name);if(!e){t.push({name:n.name,type:n.type,installed:n.installed,error:`无法获取最新版本`});continue}let r=pe(e,n.installed)>0;t.push({name:n.name,type:n.type,installed:n.installed,latest:e,newer:r})}catch{t.push({name:n.name,type:n.type,installed:n.installed,error:`版本检查失败`})}}return t}function xt(e){let t=g(e,`.otto-install.json`);if(n(t))try{return JSON.parse(a(t,`utf-8`)).sourceType}catch{return}}function St(e){return!e.includes(`://`)&&!e.endsWith(`.git`)&&!e.endsWith(`.zip`)}async function Ct(e){return(await Ie(e))?.version??null}function wt(e,t){let r=[];if(!n(e))return r;let i;try{i=o(e)}catch{return r}for(let o of i){let i=g(e,o);try{if(!u(i).isDirectory())continue}catch{continue}let s=g(i,`.otto-install.json`);if(!n(s))continue;let c;try{c=JSON.parse(a(s,`utf-8`))}catch{continue}if(!(c.sourceType!==`git`||!c.commit||!c.sourceUrl))try{let e=Tt(c.sourceUrl);if(!e){r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,error:`远程无默认分支`});continue}r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,remoteCommit:e,newer:e!==c.commit})}catch{r.push({name:o,type:t,sourceUrl:c.sourceUrl,installedCommit:c.commit,error:`git ls-remote 执行异常`})}}return r}function Tt(e){let t=b(`git`,[`ls-remote`,`--symref`,e,`HEAD`],{stdio:`pipe`,timeout:1e4});if(t.status===0){let e=t.stdout.toString().trim().split(`
|
|
4
4
|
`);for(let t=e.length-1;t>=0;t--){let n=e[t];if(!n.startsWith(`ref:`))return n.split(` `)[0]}}for(let t of[`refs/heads/main`,`refs/heads/master`]){let n=b(`git`,[`ls-remote`,e,t],{stdio:`pipe`,timeout:1e4});if(n.status===0){let e=n.stdout.toString().trim().split(` `)[0];if(e)return e}}}async function Et(e,t,r){let i=g(e,`.otto-install.json`);if(!n(i))return null;let o;try{o=JSON.parse(a(i,`utf-8`))}catch{return null}if(o.sourceType!==`git`||!o.commit||!o.sourceUrl)return null;let s;try{s=Tt(o.sourceUrl)}catch{return{name:t,type:r,installed:o.commit,error:`git ls-remote 执行异常`}}return s?{name:t,type:r,installed:o.commit,latest:s.slice(0,8),newer:s!==o.commit}:{name:t,type:r,installed:o.commit,error:`远程无默认分支`}}Object.freeze({status:`aborted`});function k(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}var A=class extends Error{constructor(){super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`)}},Dt=class extends Error{constructor(e){super(`Encountered unidirectional transform during encode: ${e}`),this.name=`ZodEncodeError`}};const Ot={};function j(e){return e&&Object.assign(Ot,e),Ot}function kt(e){let t=Object.values(e).filter(e=>typeof e==`number`);return Object.entries(e).filter(([e,n])=>t.indexOf(+e)===-1).map(([e,t])=>t)}function At(e,t){return typeof t==`bigint`?t.toString():t}function jt(e){return{get value(){{let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}function Mt(e){return e==null}function Nt(e){let t=e.startsWith(`^`)?1:0,n=e.endsWith(`$`)?e.length-1:e.length;return e.slice(t,n)}const Pt=Symbol(`evaluating`);function M(e,t,n){let r;Object.defineProperty(e,t,{get(){if(r!==Pt)return r===void 0&&(r=Pt,r=n()),r},set(n){Object.defineProperty(e,t,{value:n})},configurable:!0})}function N(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function P(...e){let t={};for(let n of e)Object.assign(t,Object.getOwnPropertyDescriptors(n));return Object.defineProperties({},t)}function Ft(e){return JSON.stringify(e)}function It(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,``).replace(/[\s_-]+/g,`-`).replace(/^-+|-+$/g,``)}const Lt=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{};function Rt(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}const zt=jt(()=>{if(typeof navigator<`u`&&navigator?.userAgent?.includes(`Cloudflare`))return!1;try{return Function(``),!0}catch{return!1}});function F(e){if(Rt(e)===!1)return!1;let t=e.constructor;if(t===void 0||typeof t!=`function`)return!0;let n=t.prototype;return!(Rt(n)===!1||Object.prototype.hasOwnProperty.call(n,`isPrototypeOf`)===!1)}function Bt(e){return F(e)?{...e}:Array.isArray(e)?[...e]:e}const Vt=new Set([`string`,`number`,`symbol`]);function I(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function L(e,t,n){let r=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(r._zod.parent=e),r}function R(e){let t=e;if(!t)return{};if(typeof t==`string`)return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,typeof t.error==`string`?{...t,error:()=>t.error}:t}function Ht(e){return Object.keys(e).filter(t=>e[t]._zod.optin===`optional`&&e[t]._zod.optout===`optional`)}-Number.MAX_VALUE,Number.MAX_VALUE;function Ut(e,t){let n=e._zod.def,r=n.checks;if(r&&r.length>0)throw Error(`.pick() cannot be used on object schemas containing refinements`);return L(e,P(e._zod.def,{get shape(){let e={};for(let r in t){if(!(r in n.shape))throw Error(`Unrecognized key: "${r}"`);t[r]&&(e[r]=n.shape[r])}return N(this,`shape`,e),e},checks:[]}))}function Wt(e,t){let n=e._zod.def,r=n.checks;if(r&&r.length>0)throw Error(`.omit() cannot be used on object schemas containing refinements`);return L(e,P(e._zod.def,{get shape(){let r={...e._zod.def.shape};for(let e in t){if(!(e in n.shape))throw Error(`Unrecognized key: "${e}"`);t[e]&&delete r[e]}return N(this,`shape`,r),r},checks:[]}))}function Gt(e,t){if(!F(t))throw Error(`Invalid input to extend: expected a plain object`);let n=e._zod.def.checks;if(n&&n.length>0){let n=e._zod.def.shape;for(let e in t)if(Object.getOwnPropertyDescriptor(n,e)!==void 0)throw Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}return L(e,P(e._zod.def,{get shape(){let n={...e._zod.def.shape,...t};return N(this,`shape`,n),n}}))}function Kt(e,t){if(!F(t))throw Error(`Invalid input to safeExtend: expected a plain object`);return L(e,P(e._zod.def,{get shape(){let n={...e._zod.def.shape,...t};return N(this,`shape`,n),n}}))}function qt(e,t){return L(e,P(e._zod.def,{get shape(){let n={...e._zod.def.shape,...t._zod.def.shape};return N(this,`shape`,n),n},get catchall(){return t._zod.def.catchall},checks:[]}))}function Jt(e,t,n){let r=t._zod.def.checks;if(r&&r.length>0)throw Error(`.partial() cannot be used on object schemas containing refinements`);return L(t,P(t._zod.def,{get shape(){let r=t._zod.def.shape,i={...r};if(n)for(let t in n){if(!(t in r))throw Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=e?new e({type:`optional`,innerType:r[t]}):r[t])}else for(let t in r)i[t]=e?new e({type:`optional`,innerType:r[t]}):r[t];return N(this,`shape`,i),i},checks:[]}))}function Yt(e,t,n){return L(t,P(t._zod.def,{get shape(){let r=t._zod.def.shape,i={...r};if(n)for(let t in n){if(!(t in i))throw Error(`Unrecognized key: "${t}"`);n[t]&&(i[t]=new e({type:`nonoptional`,innerType:r[t]}))}else for(let t in r)i[t]=new e({type:`nonoptional`,innerType:r[t]});return N(this,`shape`,i),i}}))}function z(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function Xt(e,t){return t.map(t=>{var n;return(n=t).path??(n.path=[]),t.path.unshift(e),t})}function Zt(e){return typeof e==`string`?e:e?.message}function B(e,t,n){let r={...e,path:e.path??[]};return e.message||(r.message=Zt(e.inst?._zod.def?.error?.(e))??Zt(t?.error?.(e))??Zt(n.customError?.(e))??Zt(n.localeError?.(e))??`Invalid input`),delete r.inst,delete r.continue,t?.reportInput||delete r.input,r}function Qt(e){return Array.isArray(e)?`array`:typeof e==`string`?`string`:`unknown`}function V(...e){let[t,n,r]=e;return typeof t==`string`?{message:t,code:`custom`,input:n,inst:r}:{...t}}const $t=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,At,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},en=k(`$ZodError`,$t),tn=k(`$ZodError`,$t,{Parent:Error});function nn(e,t=e=>e.message){let n={},r=[];for(let i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}function rn(e,t=e=>e.message){let n={_errors:[]},r=e=>{for(let i of e.issues)if(i.code===`invalid_union`&&i.errors.length)i.errors.map(e=>r({issues:e}));else if(i.code===`invalid_key`)r({issues:i.issues});else if(i.code===`invalid_element`)r({issues:i.issues});else if(i.path.length===0)n._errors.push(t(i));else{let e=n,r=0;for(;r<i.path.length;){let n=i.path[r];r===i.path.length-1?(e[n]=e[n]||{_errors:[]},e[n]._errors.push(t(i))):e[n]=e[n]||{_errors:[]},e=e[n],r++}}};return r(e),n}const an=e=>(t,n,r,i)=>{let a=r?Object.assign(r,{async:!1}):{async:!1},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise)throw new A;if(o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>B(e,a,j())));throw Lt(t,i?.callee),t}return o.value},on=e=>async(t,n,r,i)=>{let a=r?Object.assign(r,{async:!0}):{async:!0},o=t._zod.run({value:n,issues:[]},a);if(o instanceof Promise&&(o=await o),o.issues.length){let t=new(i?.Err??e)(o.issues.map(e=>B(e,a,j())));throw Lt(t,i?.callee),t}return o.value},sn=e=>(t,n,r)=>{let i=r?{...r,async:!1}:{async:!1},a=t._zod.run({value:n,issues:[]},i);if(a instanceof Promise)throw new A;return a.issues.length?{success:!1,error:new(e??en)(a.issues.map(e=>B(e,i,j())))}:{success:!0,data:a.value}},cn=sn(tn),ln=e=>async(t,n,r)=>{let i=r?Object.assign(r,{async:!0}):{async:!0},a=t._zod.run({value:n,issues:[]},i);return a instanceof Promise&&(a=await a),a.issues.length?{success:!1,error:new e(a.issues.map(e=>B(e,i,j())))}:{success:!0,data:a.value}},un=ln(tn),dn=e=>(t,n,r)=>{let i=r?Object.assign(r,{direction:`backward`}):{direction:`backward`};return an(e)(t,n,i)},fn=e=>(t,n,r)=>an(e)(t,n,r),pn=e=>async(t,n,r)=>{let i=r?Object.assign(r,{direction:`backward`}):{direction:`backward`};return on(e)(t,n,i)},mn=e=>async(t,n,r)=>on(e)(t,n,r),hn=e=>(t,n,r)=>{let i=r?Object.assign(r,{direction:`backward`}):{direction:`backward`};return sn(e)(t,n,i)},gn=e=>(t,n,r)=>sn(e)(t,n,r),_n=e=>async(t,n,r)=>{let i=r?Object.assign(r,{direction:`backward`}):{direction:`backward`};return ln(e)(t,n,i)},vn=e=>async(t,n,r)=>ln(e)(t,n,r),yn=/^[cC][^\s-]{8,}$/,bn=/^[0-9a-z]+$/,xn=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Sn=/^[0-9a-vA-V]{20}$/,Cn=/^[A-Za-z0-9]{27}$/,wn=/^[a-zA-Z0-9_-]{21}$/,Tn=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,En=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Dn=e=>e?RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,On=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/;function kn(){return RegExp(`^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`,`u`)}const An=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,jn=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,Mn=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,Nn=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Pn=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,Fn=/^[A-Za-z0-9_-]*$/,In=/^\+[1-9]\d{6,14}$/,Ln=`(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`,Rn=RegExp(`^${Ln}$`);function zn(e){let t=`(?:[01]\\d|2[0-3]):[0-5]\\d`;return typeof e.precision==`number`?e.precision===-1?`${t}`:e.precision===0?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}function Bn(e){return RegExp(`^${zn(e)}$`)}function Vn(e){let t=zn({precision:e.precision}),n=[`Z`];e.local&&n.push(``),e.offset&&n.push(`([+-](?:[01]\\d|2[0-3]):[0-5]\\d)`);let r=`${t}(?:${n.join(`|`)})`;return RegExp(`^${Ln}T(?:${r})$`)}const Hn=e=>{let t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??``}}`:`[\\s\\S]*`;return RegExp(`^${t}$`)},Un=/^(?:true|false)$/i,Wn=/^[^A-Z]*$/,Gn=/^[^a-z]*$/,H=k(`$ZodCheck`,(e,t)=>{var n;e._zod??={},e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),Kn=k(`$ZodCheckMaxLength`,(e,t)=>{var n;H.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!Mt(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.maximum??1/0;t.maximum<n&&(e._zod.bag.maximum=t.maximum)}),e._zod.check=n=>{let r=n.value;if(r.length<=t.maximum)return;let i=Qt(r);n.issues.push({origin:i,code:`too_big`,maximum:t.maximum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),qn=k(`$ZodCheckMinLength`,(e,t)=>{var n;H.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!Mt(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag.minimum??-1/0;t.minimum>n&&(e._zod.bag.minimum=t.minimum)}),e._zod.check=n=>{let r=n.value;if(r.length>=t.minimum)return;let i=Qt(r);n.issues.push({origin:i,code:`too_small`,minimum:t.minimum,inclusive:!0,input:r,inst:e,continue:!t.abort})}}),Jn=k(`$ZodCheckLengthEquals`,(e,t)=>{var n;H.init(e,t),(n=e._zod.def).when??(n.when=e=>{let t=e.value;return!Mt(t)&&t.length!==void 0}),e._zod.onattach.push(e=>{let n=e._zod.bag;n.minimum=t.length,n.maximum=t.length,n.length=t.length}),e._zod.check=n=>{let r=n.value,i=r.length;if(i===t.length)return;let a=Qt(r),o=i>t.length;n.issues.push({origin:a,...o?{code:`too_big`,maximum:t.length}:{code:`too_small`,minimum:t.length},inclusive:!0,exact:!0,input:n.value,inst:e,continue:!t.abort})}}),Yn=k(`$ZodCheckStringFormat`,(e,t)=>{var n,r;H.init(e,t),e._zod.onattach.push(e=>{let n=e._zod.bag;n.format=t.format,t.pattern&&(n.patterns??=new Set,n.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:t.format,input:n.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(r=e._zod).check??(r.check=()=>{})}),Xn=k(`$ZodCheckRegex`,(e,t)=>{Yn.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:`string`,code:`invalid_format`,format:`regex`,input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),Zn=k(`$ZodCheckLowerCase`,(e,t)=>{t.pattern??=Wn,Yn.init(e,t)}),Qn=k(`$ZodCheckUpperCase`,(e,t)=>{t.pattern??=Gn,Yn.init(e,t)}),$n=k(`$ZodCheckIncludes`,(e,t)=>{H.init(e,t);let n=I(t.includes),r=new RegExp(typeof t.position==`number`?`^.{${t.position}}${n}`:n);t.pattern=r,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(r)}),e._zod.check=n=>{n.value.includes(t.includes,t.position)||n.issues.push({origin:`string`,code:`invalid_format`,format:`includes`,includes:t.includes,input:n.value,inst:e,continue:!t.abort})}}),er=k(`$ZodCheckStartsWith`,(e,t)=>{H.init(e,t);let n=RegExp(`^${I(t.prefix)}.*`);t.pattern??=n,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(n)}),e._zod.check=n=>{n.value.startsWith(t.prefix)||n.issues.push({origin:`string`,code:`invalid_format`,format:`starts_with`,prefix:t.prefix,input:n.value,inst:e,continue:!t.abort})}}),tr=k(`$ZodCheckEndsWith`,(e,t)=>{H.init(e,t);let n=RegExp(`.*${I(t.suffix)}$`);t.pattern??=n,e._zod.onattach.push(e=>{let t=e._zod.bag;t.patterns??=new Set,t.patterns.add(n)}),e._zod.check=n=>{n.value.endsWith(t.suffix)||n.issues.push({origin:`string`,code:`invalid_format`,format:`ends_with`,suffix:t.suffix,input:n.value,inst:e,continue:!t.abort})}}),nr=k(`$ZodCheckOverwrite`,(e,t)=>{H.init(e,t),e._zod.check=e=>{e.value=t.tx(e.value)}});var rr=class{constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}indented(e){this.indent+=1,e(this),--this.indent}write(e){if(typeof e==`function`){e(this,{execution:`sync`}),e(this,{execution:`async`});return}let t=e.split(`
|
|
5
5
|
`).filter(e=>e),n=Math.min(...t.map(e=>e.length-e.trimStart().length)),r=t.map(e=>e.slice(n)).map(e=>` `.repeat(this.indent*2)+e);for(let e of r)this.content.push(e)}compile(){let e=Function,t=this?.args,n=[...(this?.content??[``]).map(e=>` ${e}`)];return new e(...t,n.join(`
|
|
6
6
|
`))}};const ir={major:4,minor:3,patch:6},U=k(`$ZodType`,(e,t)=>{var n;e??={},e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=ir;let r=[...e._zod.def.checks??[]];e._zod.traits.has(`$ZodCheck`)&&r.unshift(e);for(let t of r)for(let n of t._zod.onattach)n(e);if(r.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{let t=(e,t,n)=>{let r=z(e),i;for(let a of t){if(a._zod.def.when){if(!a._zod.def.when(e))continue}else if(r)continue;let t=e.issues.length,o=a._zod.check(e);if(o instanceof Promise&&n?.async===!1)throw new A;if(i||o instanceof Promise)i=(i??Promise.resolve()).then(async()=>{await o,e.issues.length!==t&&(r||=z(e,t))});else{if(e.issues.length===t)continue;r||=z(e,t)}}return i?i.then(()=>e):e},n=(n,i,a)=>{if(z(n))return n.aborted=!0,n;let o=t(i,r,a);if(o instanceof Promise){if(a.async===!1)throw new A;return o.then(t=>e._zod.parse(t,a))}return e._zod.parse(o,a)};e._zod.run=(i,a)=>{if(a.skipChecks)return e._zod.parse(i,a);if(a.direction===`backward`){let t=e._zod.parse({value:i.value,issues:[]},{...a,skipChecks:!0});return t instanceof Promise?t.then(e=>n(e,i,a)):n(t,i,a)}let o=e._zod.parse(i,a);if(o instanceof Promise){if(a.async===!1)throw new A;return o.then(e=>t(e,r,a))}return t(o,r,a)}}M(e,`~standard`,()=>({validate:t=>{try{let n=cn(e,t);return n.success?{value:n.data}:{issues:n.error?.issues}}catch{return un(e,t).then(e=>e.success?{value:e.data}:{issues:e.error?.issues})}},vendor:`zod`,version:1}))}),ar=k(`$ZodString`,(e,t)=>{U.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??Hn(e._zod.bag),e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value==`string`||n.issues.push({expected:`string`,code:`invalid_type`,input:n.value,inst:e}),n}}),W=k(`$ZodStringFormat`,(e,t)=>{Yn.init(e,t),ar.init(e,t)}),or=k(`$ZodGUID`,(e,t)=>{t.pattern??=En,W.init(e,t)}),sr=k(`$ZodUUID`,(e,t)=>{if(t.version){let e={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(e===void 0)throw Error(`Invalid UUID version: "${t.version}"`);t.pattern??=Dn(e)}else t.pattern??=Dn();W.init(e,t)}),cr=k(`$ZodEmail`,(e,t)=>{t.pattern??=On,W.init(e,t)}),lr=k(`$ZodURL`,(e,t)=>{W.init(e,t),e._zod.check=n=>{try{let r=n.value.trim(),i=new URL(r);t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(i.hostname)||n.issues.push({code:`invalid_format`,format:`url`,note:`Invalid hostname`,pattern:t.hostname.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(i.protocol.endsWith(`:`)?i.protocol.slice(0,-1):i.protocol)||n.issues.push({code:`invalid_format`,format:`url`,note:`Invalid protocol`,pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),t.normalize?n.value=i.href:n.value=r;return}catch{n.issues.push({code:`invalid_format`,format:`url`,input:n.value,inst:e,continue:!t.abort})}}}),ur=k(`$ZodEmoji`,(e,t)=>{t.pattern??=kn(),W.init(e,t)}),dr=k(`$ZodNanoID`,(e,t)=>{t.pattern??=wn,W.init(e,t)}),fr=k(`$ZodCUID`,(e,t)=>{t.pattern??=yn,W.init(e,t)}),pr=k(`$ZodCUID2`,(e,t)=>{t.pattern??=bn,W.init(e,t)}),mr=k(`$ZodULID`,(e,t)=>{t.pattern??=xn,W.init(e,t)}),hr=k(`$ZodXID`,(e,t)=>{t.pattern??=Sn,W.init(e,t)}),gr=k(`$ZodKSUID`,(e,t)=>{t.pattern??=Cn,W.init(e,t)}),_r=k(`$ZodISODateTime`,(e,t)=>{t.pattern??=Vn(t),W.init(e,t)}),vr=k(`$ZodISODate`,(e,t)=>{t.pattern??=Rn,W.init(e,t)}),yr=k(`$ZodISOTime`,(e,t)=>{t.pattern??=Bn(t),W.init(e,t)}),br=k(`$ZodISODuration`,(e,t)=>{t.pattern??=Tn,W.init(e,t)}),xr=k(`$ZodIPv4`,(e,t)=>{t.pattern??=An,W.init(e,t),e._zod.bag.format=`ipv4`}),Sr=k(`$ZodIPv6`,(e,t)=>{t.pattern??=jn,W.init(e,t),e._zod.bag.format=`ipv6`,e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:`invalid_format`,format:`ipv6`,input:n.value,inst:e,continue:!t.abort})}}}),Cr=k(`$ZodCIDRv4`,(e,t)=>{t.pattern??=Mn,W.init(e,t)}),wr=k(`$ZodCIDRv6`,(e,t)=>{t.pattern??=Nn,W.init(e,t),e._zod.check=n=>{let r=n.value.split(`/`);try{if(r.length!==2)throw Error();let[e,t]=r;if(!t)throw Error();let n=Number(t);if(`${n}`!==t||n<0||n>128)throw Error();new URL(`http://[${e}]`)}catch{n.issues.push({code:`invalid_format`,format:`cidrv6`,input:n.value,inst:e,continue:!t.abort})}}});function Tr(e){if(e===``)return!0;if(e.length%4!=0)return!1;try{return atob(e),!0}catch{return!1}}const Er=k(`$ZodBase64`,(e,t)=>{t.pattern??=Pn,W.init(e,t),e._zod.bag.contentEncoding=`base64`,e._zod.check=n=>{Tr(n.value)||n.issues.push({code:`invalid_format`,format:`base64`,input:n.value,inst:e,continue:!t.abort})}});function Dr(e){if(!Fn.test(e))return!1;let t=e.replace(/[-_]/g,e=>e===`-`?`+`:`/`);return Tr(t.padEnd(Math.ceil(t.length/4)*4,`=`))}const Or=k(`$ZodBase64URL`,(e,t)=>{t.pattern??=Fn,W.init(e,t),e._zod.bag.contentEncoding=`base64url`,e._zod.check=n=>{Dr(n.value)||n.issues.push({code:`invalid_format`,format:`base64url`,input:n.value,inst:e,continue:!t.abort})}}),kr=k(`$ZodE164`,(e,t)=>{t.pattern??=In,W.init(e,t)});function Ar(e,t=null){try{let n=e.split(`.`);if(n.length!==3)return!1;let[r]=n;if(!r)return!1;let i=JSON.parse(atob(r));return!(`typ`in i&&i?.typ!==`JWT`||!i.alg||t&&(!(`alg`in i)||i.alg!==t))}catch{return!1}}const jr=k(`$ZodJWT`,(e,t)=>{W.init(e,t),e._zod.check=n=>{Ar(n.value,t.alg)||n.issues.push({code:`invalid_format`,format:`jwt`,input:n.value,inst:e,continue:!t.abort})}}),Mr=k(`$ZodBoolean`,(e,t)=>{U.init(e,t),e._zod.pattern=Un,e._zod.parse=(n,r)=>{if(t.coerce)try{n.value=!!n.value}catch{}let i=n.value;return typeof i==`boolean`||n.issues.push({expected:`boolean`,code:`invalid_type`,input:i,inst:e}),n}}),Nr=k(`$ZodUnknown`,(e,t)=>{U.init(e,t),e._zod.parse=e=>e}),Pr=k(`$ZodNever`,(e,t)=>{U.init(e,t),e._zod.parse=(t,n)=>(t.issues.push({expected:`never`,code:`invalid_type`,input:t.value,inst:e}),t)});function Fr(e,t,n){e.issues.length&&t.issues.push(...Xt(n,e.issues)),t.value[n]=e.value}const Ir=k(`$ZodArray`,(e,t)=>{U.init(e,t),e._zod.parse=(n,r)=>{let i=n.value;if(!Array.isArray(i))return n.issues.push({expected:`array`,code:`invalid_type`,input:i,inst:e}),n;n.value=Array(i.length);let a=[];for(let e=0;e<i.length;e++){let o=i[e],s=t.element._zod.run({value:o,issues:[]},r);s instanceof Promise?a.push(s.then(t=>Fr(t,n,e))):Fr(s,n,e)}return a.length?Promise.all(a).then(()=>n):n}});function Lr(e,t,n,r,i){if(e.issues.length){if(i&&!(n in r))return;t.issues.push(...Xt(n,e.issues))}e.value===void 0?n in r&&(t.value[n]=void 0):t.value[n]=e.value}function Rr(e){let t=Object.keys(e.shape);for(let n of t)if(!e.shape?.[n]?._zod?.traits?.has(`$ZodType`))throw Error(`Invalid element at key "${n}": expected a Zod schema`);let n=Ht(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function zr(e,t,n,r,i,a){let o=[],s=i.keySet,c=i.catchall._zod,l=c.def.type,u=c.optout===`optional`;for(let i in t){if(s.has(i))continue;if(l===`never`){o.push(i);continue}let a=c.run({value:t[i],issues:[]},r);a instanceof Promise?e.push(a.then(e=>Lr(e,n,i,t,u))):Lr(a,n,i,t,u)}return o.length&&n.issues.push({code:`unrecognized_keys`,keys:o,input:t,inst:a}),e.length?Promise.all(e).then(()=>n):n}const Br=k(`$ZodObject`,(e,t)=>{if(U.init(e,t),!Object.getOwnPropertyDescriptor(t,`shape`)?.get){let e=t.shape;Object.defineProperty(t,`shape`,{get:()=>{let n={...e};return Object.defineProperty(t,`shape`,{value:n}),n}})}let n=jt(()=>Rr(t));M(e._zod,`propValues`,()=>{let e=t.shape,n={};for(let t in e){let r=e[t]._zod;if(r.values){n[t]??(n[t]=new Set);for(let e of r.values)n[t].add(e)}}return n});let r=Rt,i=t.catchall,a;e._zod.parse=(t,o)=>{a??=n.value;let s=t.value;if(!r(s))return t.issues.push({expected:`object`,code:`invalid_type`,input:s,inst:e}),t;t.value={};let c=[],l=a.shape;for(let e of a.keys){let n=l[e],r=n._zod.optout===`optional`,i=n._zod.run({value:s[e],issues:[]},o);i instanceof Promise?c.push(i.then(n=>Lr(n,t,e,s,r))):Lr(i,t,e,s,r)}return i?zr(c,s,t,o,n.value,e):c.length?Promise.all(c).then(()=>t):t}}),Vr=k(`$ZodObjectJIT`,(e,t)=>{Br.init(e,t);let n=e._zod.parse,r=jt(()=>Rr(t)),i=e=>{let t=new rr([`shape`,`payload`,`ctx`]),n=r.value,i=e=>{let t=Ft(e);return`shape[${t}]._zod.run({ value: input[${t}], issues: [] }, ctx)`};t.write(`const input = payload.value;`);let a=Object.create(null),o=0;for(let e of n.keys)a[e]=`key_${o++}`;t.write(`const newResult = {};`);for(let r of n.keys){let n=a[r],o=Ft(r),s=e[r]?._zod?.optout===`optional`;t.write(`const ${n} = ${i(r)};`),s?t.write(`
|