@x-otto/plugin 0.1.0-alpha.1 → 0.1.0-alpha.11

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/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- import{z as e}from"zod";import{TypedEventEmitter as t,acquireFileLockSync as n,createLogger as r,releaseFileLockSync as i,waitForFileLockReleaseSync as a}from"@x-otto/shared";import{closeSync as o,existsSync as s,fsyncSync as c,mkdirSync as l,openSync as u,readFileSync as d,readSync as f,readdirSync as p,renameSync as ee,statSync as te,unlinkSync as ne,writeFileSync as re}from"node:fs";import{basename as m,dirname as ie,join as h,relative as ae,resolve as g}from"node:path";import{OTTO_HOME as _,findWorkspaceRoot as oe,isShadowModeEnabled as se,resolveConfigLayers as ce}from"@x-otto/env";import{satisfies as le,validRange as ue}from"semver";import{homedir as v}from"node:os";import{sigilOf as y}from"@x-otto/interchange";import{readdir as de}from"node:fs/promises";import{randomUUID as fe}from"node:crypto";const pe=[`provider`,`tools`,`hooks`,`tui.renderer`,`network`,`context`,`monitor`,`wire-protocol`,`a2ui.component`,`panel.backend`,`mcp.server`,`feedback`,`input.resolver`,`a2ui.renderer`,`theme`,`agent.dispatch`,`service`,`storage`,`session.read`,`llm.complete`,`user.notify`,`user.ask`],b={provider:!0,tools:!0,hooks:!1,"tui.renderer":!0,network:!0,context:!1,monitor:!1,"wire-protocol":!0,"a2ui.component":!0,"panel.backend":!0,"mcp.server":!0,feedback:!1,"input.resolver":!0,"a2ui.renderer":!0,theme:!1,"agent.dispatch":!0,service:!0,storage:!1,"session.read":!0,"llm.complete":!0,"user.notify":!1,"user.ask":!0},x=Object.freeze(Object.keys(b).filter(e=>b[e])),S=r(`@x-otto/coding:plugin-manifest`),C=`otto-plugin.json`,w=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,T=e=>e.optional().catch(void 0),E=e.string().refine(e=>e.trim().length>0,`must be non-empty`),me=e.object({id:E,title:E,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E)}),he=e.object({role:T(E),toolName:T(E),contentType:T(E)}).refine(e=>e.role!=null||e.toolName!=null||e.contentType!=null,{message:`matcher must declare at least one of role/toolName/contentType`}),ge=e.object({id:E,matcher:he,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E)}),_e=e.object({id:E,matcher:he,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E)}),ve=e.object({extensions:T(e.array(E)),filenames:T(e.array(E)),glob:T(e.array(E))}).refine(e=>(e.extensions?.length??0)+(e.filenames?.length??0)+(e.glob?.length??0)>0,{message:`matcher must declare at least one of extensions/filenames/glob`}),ye=D(e.object({id:E,label:E,matcher:ve,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E),order:T(e.number())}),`fileViewers`),be=D(e.object({type:E,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E)}),`a2uiComponents`),xe=D(e.object({id:E,entry:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:T(E),order:T(e.number()),tickMs:T(e.number())}),`statusWidgets`),Se=D(ge,`renderers`),Ce=D(me,`panels`),we=e.discriminatedUnion(`type`,[e.object({type:e.literal(`builtin`),id:E}),e.object({type:e.literal(`mcp`),server:E,tool:E,params:T(e.record(e.string(),e.unknown()))}),e.object({type:e.literal(`open`),target:E}),e.object({type:e.literal(`command`),name:E,args:T(E)}),e.object({type:e.literal(`script`),name:E})]),Te=e.object({id:E,title:E,command:we,color:T(e.enum([`accent`,`amber`,`red`,`green`,`gray`]))}),Ee=e.object({action:E,point:E,when:T(E),order:T(e.number())}),De=e.object({key:E,groups:e.array(e.array(E)),map:e.object({none:E,partial:E,all:E})});function D(t,n){return e.array(e.unknown()).transform(e=>{let r=e.map(e=>t.safeParse(e)),i=r.filter(e=>e.success).map(e=>e.data),a=r.length-i.length;if(a>0&&n){let e=r.filter(e=>!e.success).map(e=>e.success?``:e.error.issues.map(e=>e.message).join(`; `));S.warn({label:n,dropped:a,total:r.length,issues:e},`contributes.${n}: ${a}/${r.length} 条 entry 校验失败,已静默丢弃(fail-soft)`)}return i.length>0?i:void 0})}const Oe=e.object({input:e.number().min(0),output:e.number().min(0),cacheRead:e.number().min(0),cacheWrite:e.number().min(0)}),ke=e.object({maxImagesPerRequest:e.number().int().positive(),maxDimensionPxIfOverLimit:T(e.number().int().positive())}),Ae=e.enum([`planning`,`knowledge`,`coding`,`reasoning`,`vision`,`speed`,`long-context`]),je=e.enum([`low`,`medium`,`high`,`xhigh`,`max`]),Me=e.enum([`enabled`,`adaptive`]),Ne=e.object({id:E,contextWindow:e.number().int().positive(),maxOutput:e.number().int().positive(),cost:T(Oe),strengths:T(e.array(Ae).min(1)),reasoning:T(e.boolean()),thinkingLevels:T(e.array(je).min(1)),thinkingMode:T(Me)}),Pe=e.enum([`openai-completions`,`openai-responses`,`anthropic-messages`]),Fe=e.object({label:E,value:E.refine(e=>!e.startsWith(`!`)&&!e.startsWith(`#`),`value must not start with '!' or '#' (mode-prefix collision)`),kind:e.enum([`resource`,`hashtag`]),description:T(E),resolverId:T(E)}),Ie=e.object({id:E,dataSource:e.object({contextKey:E}),point:T(E),when:T(E),order:T(e.number())}),Le=e.union([E,e.object({file:E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`)})]),Re=e.object({id:E,priority:T(e.number()),content:Le}),ze=e.object({id:E,translations:e.record(e.string(),e.string())}),Be=/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/,O=e=>!Be.test(e),Ve=/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,k=t=>e.string().max(16).refine(e=>Ve.test(e),`${t} must be a #RRGGBB or #RGB hex color`),He=e.object({brand:k(`brand`),brandShimmer:k(`brandShimmer`),accent:k(`accent`),accentDim:k(`accentDim`),accentBright:k(`accentBright`),text:T(k(`text`)),inactive:k(`inactive`),secondary:k(`secondary`),subtle:k(`subtle`),replyPrefix:k(`replyPrefix`),success:k(`success`),error:k(`error`),warning:k(`warning`),special:k(`special`),suggestion:k(`suggestion`),permission:k(`permission`),codeText:k(`codeText`),diffAdd:k(`diffAdd`),diffRemove:k(`diffRemove`),diffAddBg:k(`diffAddBg`),diffRemoveBg:k(`diffRemoveBg`),panelBorder:k(`panelBorder`),overlayBg:k(`overlayBg`),tagBg:k(`tagBg`),toolText:k(`toolText`),focusBorder:k(`focusBorder`),selection:k(`selection`)}),A=e.enum(`brand.brandShimmer.accent.accentDim.accentBright.text.inactive.secondary.subtle.replyPrefix.success.error.warning.special.suggestion.permission.codeText.diffAdd.diffRemove.diffAddBg.diffRemoveBg.panelBorder.overlayBg.tagBg.toolText.focusBorder.selection`.split(`.`)),Ue=e.strictObject({heading1:T(A),heading2:T(A),headingWeak:T(A),listMarker:T(A),listMarkerMuted:T(A),quoteBar:T(A),quoteText:T(A),link:T(A),inlineCode:T(A),codeFence:T(A),tableHeader:T(A),tableDivider:T(A),listIndent:T(e.union([e.literal(2),e.literal(3)])),listMarkers:T(e.tuple([e.string().min(1).max(4),e.string().min(1).max(4),e.string().min(1).max(4),e.string().min(1).max(4)])),codeBlockDivider:T(e.enum([`hr`,`none`]))}),We=e.object({localId:E.max(64).refine(e=>w.test(e),`localId must be kebab-case`),label:E.max(64).refine(O,`label must not contain control characters`),appearance:e.enum([`dark`,`light`]),colors:He,markdown:T(Ue),meta:T(e.object({author:T(E.max(128).refine(O,`author must not contain control characters`)),description:T(E.max(256).refine(O,`description must not contain control characters`)),version:T(E.max(32).refine(O,`version must not contain control characters`))}))}),Ge=10,Ke=500,qe=2*1024,Je=20,Ye=64*1024,Xe=e.object({id:E,label:E,toolRef:E}),Ze=e.object({header:E.refine(e=>/^[a-zA-Z0-9][a-zA-Z0-9\-_]*$/.test(e),`header name must be alphanumeric with hyphens/underscores only`),source:e.object({kind:e.literal(`jwt-claim`),claim:E,namespace:T(E),tokenSources:T(e.array(e.enum([`id_token`,`access_token`])))})}),Qe=e.object({imageConstraints:T(ke),supportsTools:T(e.boolean())}),j=e.object({url:E,responseFormat:e.literal(`openai-list`),authScheme:T(e.enum([`bearer`,`x-api-key`,`auto`])),betaHeaderName:T(E),modelIdExclude:T(D(e.string(),`modelIdExclude`))}),M=e.object({store:T(e.boolean()),sendMaxOutputTokens:T(e.boolean())}),$e=e.object({id:E,name:T(E),catalogOnly:T(e.boolean()),baseUrl:T(E),wireApi:T(Pe),envKey:T(E),oauthRef:T(E),headers:T(e.record(e.string(),e.string())),models:T(D(Ne,`models`)),tokenDerivedHeaders:T(D(Ze,`tokenDerivedHeaders`)),modelsEndpoint:T(j),responseBodyPolicy:T(M),allowAuthHeaderOverride:T(e.boolean()),preserveProviderId:T(e.boolean())}).extend(Qe.shape).superRefine((t,n)=>{if(t.catalogOnly===!0){t.wireApi&&n.addIssue({code:e.ZodIssueCode.custom,message:`catalogOnly entries must not declare wireApi; use providerFactories for custom protocols`,path:[`wireApi`]}),t.baseUrl&&n.addIssue({code:e.ZodIssueCode.custom,message:`catalogOnly entries must not declare baseUrl; use providerFactories for custom protocols`,path:[`baseUrl`]});return}t.baseUrl||n.addIssue({code:e.ZodIssueCode.custom,message:`baseUrl is required unless catalogOnly is true`,path:[`baseUrl`]}),t.wireApi||n.addIssue({code:e.ZodIssueCode.custom,message:`wireApi is required unless catalogOnly is true`,path:[`wireApi`]})}),et=e.object({name:E.refine(e=>/^[a-z][a-z0-9-]*$/.test(e),`must be lowercase kebab-case`),bin:T(E)}),tt=e.discriminatedUnion(`kind`,[e.object({kind:e.literal(`pkce`),id:E,name:T(E),clientId:E,authorizeUrl:E,tokenUrl:E,redirectUri:E,scope:E,loopbackPorts:T(e.array(e.number().int().positive())),assumesLoopbackAlways:T(e.boolean()),extraAuthParams:T(e.record(e.string(),e.string())),tokenExchangeEncoding:T(e.enum([`json`,`form`])),subscriptionScoped:T(e.boolean()),oauthBeta:T(E)}),e.object({kind:e.literal(`device-flow`),id:E,name:T(E),clientId:E,deviceCodeUrlTemplate:E,tokenUrlTemplate:E,refreshUrlTemplate:T(E),scope:E,allowCustomDomain:T(e.boolean()),userAgent:T(E)})]),nt=e.object({skills:T(e.boolean()),agents:T(e.boolean()),commands:T(e.boolean()),mcp:T(e.boolean()),cli:T(et),panels:T(Ce),actions:T(D(Te,`actions`)),menus:T(D(Ee,`menus`)),contextKeys:T(D(De,`contextKeys`)),providers:T(D($e,`providers`)),oauth:T(D(tt,`oauth`)),statusItems:T(D(Ie,`statusItems`)),perfMetrics:T(D(Xe,`perfMetrics`)),renderers:T(Se),fileViewers:T(ye),statusWidgets:T(xe),a2uiComponents:T(be),contextSources:T(D(Re,`contextSources`)),i18n:T(D(ze,`i18n`)),themePresets:T(D(We,`themePresets`)),i18nDir:T(E.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`)),inputEntries:T(E),sigilEntries:T(D(Fe,`sigilEntries`)),a2uiRenderers:T(D(_e,`a2uiRenderers`))}),rt=e.enum(pe),it=e.array(e.unknown()).transform(e=>{let t=e.map(e=>rt.safeParse(e)).filter(e=>e.success).map(e=>e.data);return t.length>0?[...new Set(t)]:void 0}),at=/^(onStartup|onCommand:[^\s]+|onView:[^\s]+|onProvider:[^\s]+)$/,ot=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&at.test(e));return t.length>0?[...new Set(t)]:void 0}),st=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&w.test(e));return t.length>0?[...new Set(t)]:void 0}),ct=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&e.trim().length>0);return t.length>0?[...new Set(t)]:void 0}),lt=j.extend({headers:T(e.record(e.string(),e.string()))}),ut=e.record(e.string(),e.unknown()).transform(e=>{let t={};for(let[n,r]of Object.entries(e)){let e=lt.safeParse(r);e.success&&(t[n]=e.data)}return Object.keys(t).length>0?t:void 0}),dt=e.object({baseUrl:E,models:D(Ne,`codeProviderModels`),responseBodyPolicy:T(M)}).extend(Qe.shape),ft=e.record(e.string(),e.unknown()).transform(e=>{let t={};for(let[n,r]of Object.entries(e)){let e=dt.safeParse(r);e.success&&e.data.models&&e.data.models.length>0&&(t[n]=e.data)}return Object.keys(t).length>0?t:void 0}),pt=e.object({postinstall:T(E),setup:T(E)}).catchall(E),mt=e.object({otto:T(E)}),ht=e.object({id:e.string().regex(w),name:T(e.string()),version:T(e.string()),description:T(e.string()),engines:T(mt),contributes:T(nt),scripts:T(pt),capabilities:T(it),activationEvents:T(ot),dependsOn:T(st),codeProviderIds:T(ct),codeProviderModelsEndpoints:T(ut),codeProviderModels:T(ft)});function gt(e){return e.activationEvents?.length?e.activationEvents:[`onStartup`]}function N(e,t){let n;try{n=JSON.parse(e)}catch(e){return S.warn({sourcePath:t,err:String(e)},`plugin manifest invalid JSON, skipped`),null}let r=ht.safeParse(n);return r.success?r.data:(S.warn({sourcePath:t,issues:r.error.issues.map(e=>e.path.join(`.`)||`<root>`)},`plugin manifest missing/invalid "id" (kebab-case required) or not an object, skipped`),null)}const P=r(`@x-otto/coding:plugin-discovery`);function F(e){try{return te(e).isDirectory()}catch{return!1}}const _t=[{id:`otto-plugin-manager`,dir:`<builtin:otto-plugin-manager>`,scope:`builtin`,manifest:{id:`otto-plugin-manager`,name:`Plugin Manager`,description:`otto 插件生命周期管理(create/build/dev/install)—— 随 otto 内置分发,恒定信任、恒定启用。`,version:void 0,contributes:void 0,scripts:void 0,capabilities:void 0,activationEvents:void 0,dependsOn:void 0}},{id:`otto-tui`,dir:`<builtin:otto-tui>`,scope:`builtin`,manifest:{id:`otto-tui`,name:`TUI`,description:`otto 终端交互界面本体(渲染/输入/面板/状态栏)—— 随 otto 内置分发,恒定信任、恒定启用。`,version:void 0,contributes:void 0,scripts:void 0,capabilities:void 0,activationEvents:void 0,dependsOn:void 0}}];function vt(e){let{cwd:t,homedir:n}=e,r=e.disabled?new Set(e.disabled):null,i=ce({cwd:t,homedir:n,claudeCompat:!1,workspaceRoot:oe(t)}).filter(e=>e.kind===`otto`).map(e=>({dir:h(e.dir,`plugins`),scope:e.scope}));for(let t of e.bundledDirs??[])s(t)&&i.unshift({dir:t,scope:`bundled`});let a=new Map;for(let e of _t)a.set(e.id,e);for(let{dir:e,scope:t}of i){if(!s(e)||!F(e))continue;let n;try{n=p(e).sort()}catch(t){P.warn({root:e,err:String(t)},`failed to read plugins root, skipped`);continue}for(let i of n){let n=h(e,i);if(!F(n))continue;let o=h(n,C);if(!s(o))continue;let c;try{c=d(o,`utf-8`)}catch(e){P.warn({manifestPath:o,err:String(e)},`failed to read plugin manifest, skipped`);continue}let l=N(c,o);l&&(r?.has(l.id)||a.has(l.id)||a.set(l.id,{id:l.id,dir:n,manifest:l,scope:t}))}}return[...a.values()].sort((e,t)=>e.id.localeCompare(t.id))}function I(e){return e.manifest.dependsOn??[]}function yt(e){let t=new Map,n=new Map,r=e.filter(e=>e.scope===`builtin`),i=e.filter(e=>e.scope!==`builtin`),a=new Set(r.map(e=>e.id)),o=new Map;for(let e of i)o.set(e.id,e);let s=e=>o.has(e)||a.has(e),c=!0;for(;c;){c=!1;for(let e of o.values()){let t=I(e).filter(e=>!s(e));t.length>0&&(n.set(e.id,[...new Set(t)]),o.delete(e.id),c=!0)}}let l=new Map,u=new Map;for(let e of o.values()){let t=I(e).filter(e=>o.has(e));l.set(e.id,t.length);for(let n of t){let t=u.get(n);t?t.push(e.id):u.set(n,[e.id])}}let d=[...o.values()].filter(e=>l.get(e.id)===0).map(e=>e.id).sort((e,t)=>e.localeCompare(t)),f=[];for(;d.length>0;){let e=d.shift();f.push(e);let t=[];for(let n of u.get(e)??[]){let e=(l.get(n)??0)-1;l.set(n,e),e===0&&t.push(n)}t.length>0&&(d.push(...t),d.sort((e,t)=>e.localeCompare(t)))}let p=new Set(f);for(let e of o.values())p.has(e.id)||t.set(e.id,bt(e.id,o));return{ordered:[...r,...f.map(e=>o.get(e))],cyclic:t,missingDeps:n}}function bt(e,t){let n=[],r=new Set,i=e;for(;i&&!r.has(i);){n.push(i),r.add(i);let e=t.get(i);if(!e)break;i=I(e).filter(e=>t.has(e)).sort((e,t)=>e.localeCompare(t))[0]}return i===e&&n.push(e),n}const xt=1;function St(){return`1.0.0`}function L(e){if(e.scope===`builtin`)return!0;let t=e.manifest.engines?.otto;return t?ue(t)?le(St(),t):!1:!0}function Ct(e){let t=[],n=new Map;for(let r of e)L(r)?t.push(r):n.set(r.id,r.manifest.engines?.otto??`(invalid range)`);return{compatible:t,incompatible:n}}function wt(e,t,n){if(!e?.length)return t?[...t]:void 0;if(!t?.length)return[...e];if(!n)return[...e,...t];let r=new Map(t.map(e=>[n(e),e])),i=new Set,a=[];for(let t of e){let e=n(t);i.add(e),a.push(r.has(e)?r.get(e):t)}for(let e of t)i.has(n(e))||a.push(e);return a}const R={commands:e=>e.name,agents:e=>e.name,skills:e=>e.name,mcp:e=>e.name,panels:e=>e.id,actions:e=>e.id,menus:null,contextKeys:e=>e.key,statusItems:e=>e.id,renderers:e=>e.id,contextSources:e=>e.id,a2uiComponents:e=>e.type,statusWidgets:e=>e.id,fileViewers:e=>e.id};function Tt(...e){let t=e.filter(e=>e!=null);return t.length===0?{}:t.reduce((e,t)=>{let n={};for(let r of Object.keys(R)){let i=R[r],a=wt(e[r],t[r],i);a&&(n[r]=a)}return n},{})}const z={extensionDetailActions:`extension/detail/actions`},B={statuslineItem:`shell/statusline/item`,menuItem:`shell/menu/item`},Et={...z,...B};function V(e,t){if(!e)return!0;let n=e.indexOf(`:`);if(n===-1){let n=t[e];return n===!0||typeof n==`string`&&n.length>0}let r=e.slice(0,n),i=e.slice(n+1),a=t[r];return a!=null&&String(a)===i}function Dt(e,t,n,r){let i=new Map((n??[]).map(e=>[e.id,e]));return(t??[]).filter(t=>t.point===e&&V(t.when,r)).map(e=>({menu:e,action:i.get(e.action)})).filter(e=>e.action!=null).sort((e,t)=>(e.menu.order??0)-(t.menu.order??0)).map(({action:e})=>({id:e.id,title:e.title,color:e.color,command:e.command}))}function H(e){let t=e.replace(/\$\{OTTO_HOME\}/g,_);return t===`~`?v():t.startsWith(`~/`)?v()+t.slice(1):t}function U(e,t=s){let n=e.groups.length;if(n===0)return e.map.none;let r=e.groups.filter(e=>e.some(e=>t(H(e)))).length;return r===0?e.map.none:r===n?e.map.all:e.map.partial}function Ot(e,t){let n={};for(let r of e??[])n[r.key]=U(r,t);return n}var W=class extends Error{constructor(e){super(`dispatch: 缺少 capability「${e}」——宿主未注入`),this.name=`MissingCapabilityError`}};async function kt(e,t){switch(e.type){case`builtin`:if(!t.builtin)throw new W(`builtin`);await t.builtin(e.id);return;case`mcp`:if(!t.callMcp)throw new W(`mcp`);await t.callMcp(e.server,e.tool,e.params);return;case`open`:if(!t.open)throw new W(`open`);await t.open(e.target);return;case`command`:if(!t.runCommand)throw new W(`command`);await t.runCommand(e.name,e.args);return;case`script`:if(!t.runScript)throw new W(`script`);await t.runScript(e.name);return;default:throw new W(e.type)}}function At(e){return e}function G(e){return`${e.kind}\u0000${e.label}`}function jt(e,t){if(t===``)return 0;let n=e.label.toLowerCase();return n.startsWith(t)?2:e.description&&e.description.toLowerCase().includes(t)?1:n.includes(t)?0:-1}function Mt(e){return e.startsWith(`!`)||e.startsWith(`#`)}function Nt(){let e=new Map,t=new Map;function n(t){for(let n of t){if(Mt(n.value))throw Error(`[plugin-input] sigil value 不得以 '!' 或 '#' 开头(会被误判为 bash/memory 模式):${JSON.stringify(n.value)}`);let t=G(n);e.delete(t),e.set(t,n)}}function r(t){let n=[...e.values()];return t?n.filter(e=>y(e.kind)===t):n}function i(t,n,r=50){let i=t.toLowerCase(),a=[],o=0;for(let t of e.values()){let e=o++;if(n&&y(t.kind)!==n)continue;let r=jt(t,i);r<0||a.push({entry:t,score:r,order:e})}return a.sort((e,t)=>t.score-e.score||e.order-t.order),a.length<=r?a.map(e=>e.entry):a.slice(0,r).map(e=>e.entry)}function a(e,n){let r=t.get(e);return r||(r=new Set,t.set(e,r)),r.add(n),()=>{r?.delete(n)}}async function o(e,n,r=50){let a=i(e,n,r),o=n?t.get(n):void 0;if(!o||o.size===0)return a;let s=[],c=await Promise.allSettled([...o].map(t=>Promise.resolve().then(()=>t(e,n))));for(let e of c)e.status===`fulfilled`&&s.push(...e.value.filter(e=>!Mt(e.value)));let l=new Set(a.map(e=>G(e))),u=[...a];for(let e of s){let t=G(e);l.has(t)||(l.add(t),u.push(e))}return u.length<=r?u:u.slice(0,r)}function s(t){for(let n of e.values())if(n.label===t)return n}function c(t){let n=!1;for(let[r,i]of e)i.label===t&&(e.delete(r),n=!0);return n}function l(t){for(let[n,r]of e)r.source===t&&e.delete(n)}return{register:n,registerProvider:a,search:i,searchAsync:o,getAll:r,findByLabel:s,unregister:c,unregisterBySource:l}}function Pt(){return[{label:`Code Review`,description:`请求代码审查`,value:`Please review the following code for correctness, style, security, and performance. Provide specific, actionable feedback.`,kind:`hashtag`,source:`builtin`},{label:`Write Tests`,description:`为代码编写单元测试`,value:`Please write comprehensive unit tests for the following code. Cover normal cases, edge cases, error cases, and ensure high coverage.`,kind:`hashtag`,source:`builtin`},{label:`Explain Code`,description:`解释代码逻辑`,value:`Please explain the following code in detail. Cover the overall architecture, key algorithms, data flow, and any notable design decisions.`,kind:`hashtag`,source:`builtin`}]}const Ft=r(`@x-otto/plugin:file-provider`),It=new Set([`node_modules`,`.git`,`dist`,`build`,`out`,`coverage`,`.next`,`.nuxt`,`.turbo`,`.nx`,`.cache`,`.otto`,`.venv`,`__pycache__`]);async function Lt(e,t,n){let r=[];async function i(a,o){if(r.length>=t)return;let s;try{s=await de(a,{withFileTypes:!0})}catch(e){o&&n?.(e);return}for(let n of s){if(r.length>=t)return;if(n.isDirectory()){if(It.has(n.name)||n.name.startsWith(`.`))continue;await i(h(a,n.name),!1)}else n.isFile()&&r.push(ae(e,h(a,n.name)))}}return await i(e,!0),r}function Rt(e,t){if(t===``)return 0;let n=e.toLowerCase();return m(n).startsWith(t)?3:n.startsWith(t)?2:n.includes(t)?1:-1}function zt(e,t,n,r){let i;try{i=u(h(e,t),`r`);let a=Buffer.allocUnsafe(8192),o=f(i,a,0,a.length,0),s=a.toString(`utf-8`,0,o).split(`
1
+ import{z as e}from"zod";import{TypedEventEmitter as t,acquireFileLockSync as n,createLogger as r,releaseFileLockSync as i,waitForFileLockReleaseSync as a}from"@x-otto/shared";import{closeSync as o,existsSync as s,fsyncSync as c,mkdirSync as l,openSync as u,readFileSync as d,readSync as f,readdirSync as p,renameSync as ee,statSync as te,unlinkSync as ne,writeFileSync as re}from"node:fs";import{basename as m,dirname as ie,join as h,relative as ae,resolve as g}from"node:path";import{OTTO_HOME as oe,findWorkspaceRoot as se,isShadowModeEnabled as ce,resolveConfigLayers as le}from"@x-otto/env";import{satisfies as ue,validRange as de}from"semver";import{homedir as fe}from"node:os";import{sigilOf as pe,sigilOf as _}from"@x-otto/interchange";import{readdir as me}from"node:fs/promises";import{randomUUID as he}from"node:crypto";const v=`provider,tools,hooks,tui.renderer,network,context,monitor,wire-protocol,a2ui.component,panel.backend,mcp.server,feedback,input.resolver,a2ui.renderer,theme,agent.dispatch,service,storage,session.read,llm.complete,user.notify,user.ask,config,credentials,cli.command,tui.command,events,settings.read,schedule`.split(`,`),ge={provider:!0,tools:!0,hooks:!1,"tui.renderer":!0,network:!0,context:!1,monitor:!1,"wire-protocol":!0,"a2ui.component":!0,"panel.backend":!0,"mcp.server":!0,feedback:!1,"input.resolver":!0,"a2ui.renderer":!0,theme:!1,"agent.dispatch":!0,service:!0,storage:!1,"session.read":!0,"llm.complete":!0,"user.notify":!1,"user.ask":!0,config:!1,credentials:!0,"cli.command":!0,"tui.command":!0,events:!1,"settings.read":!1,schedule:!0},y=Object.freeze(Object.keys(ge).filter(e=>ge[e])),b=r(`@x-otto/coding:plugin-manifest`),x=`otto-plugin.json`,S=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,C=e=>e.optional().catch(void 0),w=e.string().refine(e=>e.trim().length>0,`must be non-empty`),_e=e.object({id:w,title:w,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w)}),ve=e.object({role:C(w),toolName:C(w),contentType:C(w)}).refine(e=>e.role!=null||e.toolName!=null||e.contentType!=null,{message:`matcher must declare at least one of role/toolName/contentType`}),ye=e.object({id:w,matcher:ve,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w)}),be=e.object({id:w,matcher:ve,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w)}),xe=e.object({extensions:C(e.array(w)),filenames:C(e.array(w)),glob:C(e.array(w))}).refine(e=>(e.extensions?.length??0)+(e.filenames?.length??0)+(e.glob?.length??0)>0,{message:`matcher must declare at least one of extensions/filenames/glob`}),Se=T(e.object({id:w,label:w,matcher:xe,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w),order:C(e.number())}),`fileViewers`),Ce=T(e.object({type:w,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w)}),`a2uiComponents`),we=T(e.object({id:w,entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),export:C(w),order:C(e.number()),tickMs:C(e.number())}),`statusWidgets`),Te=T(ye,`renderers`),Ee=T(_e,`panels`),De=e.discriminatedUnion(`type`,[e.object({type:e.literal(`builtin`),id:w}),e.object({type:e.literal(`mcp`),server:w,tool:w,params:C(e.record(e.string(),e.unknown()))}),e.object({type:e.literal(`open`),target:w}),e.object({type:e.literal(`command`),name:w,args:C(w)}),e.object({type:e.literal(`script`),name:w})]),Oe=e.object({id:w,title:w,command:De,color:C(e.enum([`accent`,`amber`,`red`,`green`,`gray`]))}),ke=e.object({action:w,point:w,when:C(w),order:C(e.number())}),Ae=e.object({key:w,groups:e.array(e.array(w)),map:e.object({none:w,partial:w,all:w})});function T(t,n){return e.array(e.unknown()).transform(e=>{let r=e.map(e=>t.safeParse(e)),i=r.filter(e=>e.success).map(e=>e.data),a=r.length-i.length;if(a>0&&n){let e=r.filter(e=>!e.success).map(e=>e.success?``:e.error.issues.map(e=>e.message).join(`; `));b.warn({label:n,dropped:a,total:r.length,issues:e},`contributes.${n}: ${a}/${r.length} 条 entry 校验失败,已静默丢弃(fail-soft)`)}return i.length>0?i:void 0})}const je=e.object({input:e.number().min(0),output:e.number().min(0),cacheRead:e.number().min(0),cacheWrite:e.number().min(0)}),Me=e.object({maxImagesPerRequest:e.number().int().positive(),maxDimensionPxIfOverLimit:C(e.number().int().positive())}),Ne=e.enum([`planning`,`knowledge`,`coding`,`reasoning`,`vision`,`speed`,`long-context`]),Pe=e.enum([`low`,`medium`,`high`,`xhigh`,`max`]),Fe=e.enum([`enabled`,`adaptive`]),Ie=e.object({id:w,contextWindow:e.number().int().positive(),maxOutput:e.number().int().positive(),cost:C(je),strengths:C(e.array(Ne).min(1)),reasoning:C(e.boolean()),input:C(e.array(e.enum([`text`,`image`])).min(1)),thinkingLevels:C(e.array(Pe).min(1)),thinkingMode:C(Fe)}),Le=e.enum([`openai-completions`,`openai-responses`,`anthropic-messages`]),Re=e.object({label:w,value:w.refine(e=>!e.startsWith(`!`)&&!e.startsWith(`#`),`value must not start with '!' or '#' (mode-prefix collision)`),kind:e.enum([`resource`,`hashtag`]),description:C(w),resolverId:C(w)}),ze=e.object({id:w,dataSource:e.object({contextKey:w}),point:C(w),when:C(w),order:C(e.number())}),Be=e.union([w,e.object({file:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`)})]),Ve=e.object({id:w,priority:C(e.number()),content:Be}),He=e.object({id:w,translations:e.record(e.string(),e.string())}),Ue=/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/,E=e=>!Ue.test(e),We=/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/,D=t=>e.string().max(16).refine(e=>We.test(e),`${t} must be a #RRGGBB or #RGB hex color`),Ge=e.object({brand:D(`brand`),brandShimmer:D(`brandShimmer`),accent:D(`accent`),accentDim:D(`accentDim`),accentBright:D(`accentBright`),text:C(D(`text`)),inactive:D(`inactive`),secondary:D(`secondary`),subtle:D(`subtle`),replyPrefix:D(`replyPrefix`),success:D(`success`),error:D(`error`),warning:D(`warning`),special:D(`special`),suggestion:D(`suggestion`),permission:D(`permission`),codeText:D(`codeText`),diffAdd:D(`diffAdd`),diffRemove:D(`diffRemove`),diffAddBg:D(`diffAddBg`),diffRemoveBg:D(`diffRemoveBg`),panelBorder:D(`panelBorder`),overlayBg:D(`overlayBg`),tagBg:D(`tagBg`),toolText:D(`toolText`),focusBorder:D(`focusBorder`),selection:D(`selection`)}),O=e.enum(`brand.brandShimmer.accent.accentDim.accentBright.text.inactive.secondary.subtle.replyPrefix.success.error.warning.special.suggestion.permission.codeText.diffAdd.diffRemove.diffAddBg.diffRemoveBg.panelBorder.overlayBg.tagBg.toolText.focusBorder.selection`.split(`.`)),Ke=e.strictObject({heading1:C(O),heading2:C(O),headingWeak:C(O),listMarker:C(O),listMarkerMuted:C(O),quoteBar:C(O),quoteText:C(O),link:C(O),inlineCode:C(O),codeFence:C(O),tableHeader:C(O),tableDivider:C(O),listIndent:C(e.union([e.literal(2),e.literal(3)])),listMarkers:C(e.tuple([e.string().min(1).max(4),e.string().min(1).max(4),e.string().min(1).max(4),e.string().min(1).max(4)])),codeBlockDivider:C(e.enum([`hr`,`none`]))}),qe=e.object({localId:w.max(64).refine(e=>S.test(e),`localId must be kebab-case`),label:w.max(64).refine(E,`label must not contain control characters`),appearance:e.enum([`dark`,`light`]),colors:Ge,markdown:C(Ke),meta:C(e.object({author:C(w.max(128).refine(E,`author must not contain control characters`)),description:C(w.max(256).refine(E,`description must not contain control characters`)),version:C(w.max(32).refine(E,`version must not contain control characters`))}))}),Je=10,Ye=500,Xe=2*1024,Ze=20,Qe=64*1024,$e=32,et=4,tt=8*1024,nt=256,rt=e.object({id:w,label:w,toolRef:w}),it=e.object({header:w.refine(e=>/^[a-zA-Z0-9][a-zA-Z0-9\-_]*$/.test(e),`header name must be alphanumeric with hyphens/underscores only`),source:e.object({kind:e.literal(`jwt-claim`),claim:w,namespace:C(w),tokenSources:C(e.array(e.enum([`id_token`,`access_token`])))})}),k=e.object({imageConstraints:C(Me),supportsTools:C(e.boolean())}),A=e.object({url:w,responseFormat:e.literal(`openai-list`),authScheme:C(e.enum([`bearer`,`x-api-key`,`auto`])),betaHeaderName:C(w),modelIdExclude:C(T(e.string(),`modelIdExclude`))}),j=e.object({store:C(e.boolean()),sendMaxOutputTokens:C(e.boolean())}),at=e.object({id:w,name:C(w),catalogOnly:C(e.boolean()),baseUrl:C(w),wireApi:C(Le),envKey:C(w),oauthRef:C(w),headers:C(e.record(e.string(),e.string())),models:C(T(Ie,`models`)),tokenDerivedHeaders:C(T(it,`tokenDerivedHeaders`)),modelsEndpoint:C(A),responseBodyPolicy:C(j),allowAuthHeaderOverride:C(e.boolean()),preserveProviderId:C(e.boolean()),requiresIntranet:C(e.boolean())}).extend(k.shape).superRefine((t,n)=>{if(t.catalogOnly===!0){t.wireApi&&n.addIssue({code:e.ZodIssueCode.custom,message:`catalogOnly entries must not declare wireApi; use providerFactories for custom protocols`,path:[`wireApi`]}),t.baseUrl&&n.addIssue({code:e.ZodIssueCode.custom,message:`catalogOnly entries must not declare baseUrl; use providerFactories for custom protocols`,path:[`baseUrl`]});return}t.baseUrl||n.addIssue({code:e.ZodIssueCode.custom,message:`baseUrl is required unless catalogOnly is true`,path:[`baseUrl`]}),t.wireApi||n.addIssue({code:e.ZodIssueCode.custom,message:`wireApi is required unless catalogOnly is true`,path:[`wireApi`]})}),ot=e.object({name:w.refine(e=>/^[a-z][a-z0-9-]*$/.test(e),`must be lowercase kebab-case`),bin:C(w)}),st=e.object({name:w.refine(e=>/^[a-z][a-z0-9-]*$/.test(e),`must be lowercase kebab-case`),summary:w.max(200).refine(E,`must not contain control characters`),i18nKey:C(w)}),ct=e.object({name:w.refine(e=>/^[a-z][a-z0-9-]*$/.test(e),`must be lowercase kebab-case`),description:w.max(200).refine(E,`must not contain control characters`),group:C(w),i18nKey:C(w)}),lt=e.discriminatedUnion(`kind`,[e.object({kind:e.literal(`pkce`),id:w,name:C(w),clientId:w,authorizeUrl:w,tokenUrl:w,redirectUri:w,scope:w,loopbackPorts:C(e.array(e.number().int().positive())),assumesLoopbackAlways:C(e.boolean()),extraAuthParams:C(e.record(e.string(),e.string())),tokenExchangeEncoding:C(e.enum([`json`,`form`])),subscriptionScoped:C(e.boolean()),oauthBeta:C(w)}),e.object({kind:e.literal(`device-flow`),id:w,name:C(w),clientId:w,deviceCodeUrlTemplate:w,tokenUrlTemplate:w,refreshUrlTemplate:C(w),scope:w,allowCustomDomain:C(e.boolean()),userAgent:C(w)})]),ut=e.object({type:e.enum([`string`,`number`,`integer`,`boolean`,`array`,`object`]),title:C(w),description:C(w),default:e.unknown().optional(),enum:C(e.array(e.unknown())),minimum:C(e.number()),maximum:C(e.number()),pattern:C(w),items:e.unknown().optional(),properties:C(e.record(e.string(),e.unknown()))});function M(e,t){if(t>4||typeof e!=`object`||!e)return!1;let n=e;if(typeof n.description==`string`&&n.description.length>256)return!1;if(n.properties&&typeof n.properties==`object`){let e=n.properties;if(Object.keys(e).length>32)return!1;for(let n of Object.values(e))if(!M(n,t+1))return!1}return!(n.items&&typeof n.items==`object`&&!M(n.items,t+1))}const dt=e.unknown().transform(e=>{if(typeof e!=`object`||!e)return;let t=JSON.stringify(e).length;if(t>8192){b.warn({bytes:t,limit:tt},`config schema exceeds byte limit, dropped`);return}if(!M(e,0)){b.warn(`config schema exceeds depth/field/description limit, dropped`);return}let n=ut.safeParse(e);if(!n.success){b.warn({err:n.error.issues},`config schema invalid, dropped`);return}return n.data}),ft=e.object({id:w,label:C(w),entry:w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`),capabilities:C(e.object({atomic:C(e.boolean()),permSecure:C(e.boolean()),crossProcessLock:C(e.boolean()),watchable:C(e.boolean())}))}),pt=e.object({type:w.refine(e=>{let t=e.split(`.`);return t.length>=2&&t.every(e=>e.length>0)},`event type must be <pluginId>.<event> namespaced format`),description:C(w),payloadSchema:C(e.record(e.string(),e.unknown()))}),mt=e.object({skills:C(e.boolean()),agents:C(e.boolean()),commands:C(e.boolean()),mcp:C(e.boolean()),cli:C(ot),cliCommands:C(T(st,`cliCommands`)),slashCommands:C(T(ct,`slashCommands`)),panels:C(Ee),actions:C(T(Oe,`actions`)),menus:C(T(ke,`menus`)),contextKeys:C(T(Ae,`contextKeys`)),providers:C(T(at,`providers`)),oauth:C(T(lt,`oauth`)),statusItems:C(T(ze,`statusItems`)),perfMetrics:C(T(rt,`perfMetrics`)),renderers:C(Te),fileViewers:C(Se),statusWidgets:C(we),a2uiComponents:C(Ce),contextSources:C(T(Ve,`contextSources`)),i18n:C(T(He,`i18n`)),themePresets:C(T(qe,`themePresets`)),i18nDir:C(w.refine(e=>!e.startsWith(`/`)&&!e.split(/[\\/]/).includes(`..`),`unsafe path (absolute or traversal)`)),inputEntries:C(w),sigilEntries:C(T(Re,`sigilEntries`)),a2uiRenderers:C(T(be,`a2uiRenderers`)),config:C(dt),credentialBackends:C(T(ft,`credentialBackends`)),events:C(T(pt,`events`))}),ht=e.enum(v),gt=e.array(e.unknown()).transform(e=>{let t=e.map(e=>ht.safeParse(e)).filter(e=>e.success).map(e=>e.data);return t.length>0?[...new Set(t)]:void 0}),_t=/^(onStartup|onCommand:[^\s]+|onView:[^\s]+|onProvider:[^\s]+)$/,vt=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&_t.test(e));return t.length>0?[...new Set(t)]:void 0}),yt=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&S.test(e));return t.length>0?[...new Set(t)]:void 0}),bt=e.array(e.unknown()).transform(e=>{let t=e.filter(e=>typeof e==`string`&&e.trim().length>0);return t.length>0?[...new Set(t)]:void 0}),xt=A.extend({headers:C(e.record(e.string(),e.string()))}),St=e.record(e.string(),e.unknown()).transform(e=>{let t={};for(let[n,r]of Object.entries(e)){let e=xt.safeParse(r);e.success&&(t[n]=e.data)}return Object.keys(t).length>0?t:void 0}),Ct=e.object({baseUrl:w,models:T(Ie,`codeProviderModels`),responseBodyPolicy:C(j)}).extend(k.shape),wt=e.record(e.string(),e.unknown()).transform(e=>{let t={};for(let[n,r]of Object.entries(e)){let e=Ct.safeParse(r);e.success&&e.data.models&&e.data.models.length>0&&(t[n]=e.data)}return Object.keys(t).length>0?t:void 0}),Tt=e.object({postinstall:C(w),setup:C(w)}).catchall(w),Et=e.object({otto:C(w)}),Dt=e.object({plane:C(e.enum([`host`,`preset`])),id:e.string().regex(S),name:C(e.string()),version:C(e.string()),description:C(e.string()),engines:C(Et),contributes:C(mt),scripts:C(Tt),capabilities:C(gt),activationEvents:C(vt),dependsOn:C(yt),codeProviderIds:C(bt),codeProviderModelsEndpoints:C(St),codeProviderModels:C(wt)});function Ot(e){return e.plane??`preset`}function kt(e){return e.activationEvents?.length?e.activationEvents:[`onStartup`]}function N(e,t){let n;try{n=JSON.parse(e)}catch(e){return b.warn({sourcePath:t,err:String(e)},`plugin manifest invalid JSON, skipped`),null}let r=Dt.safeParse(n);return r.success?r.data:(b.warn({sourcePath:t,issues:r.error.issues.map(e=>e.path.join(`.`)||`<root>`)},`plugin manifest missing/invalid "id" (kebab-case required) or not an object, skipped`),null)}const P=r(`@x-otto/coding:plugin-discovery`);function F(e){try{return te(e).isDirectory()}catch{return!1}}const At=[{id:`otto-plugin-manager`,dir:`<builtin:otto-plugin-manager>`,scope:`builtin`,manifest:{id:`otto-plugin-manager`,name:`Plugin Manager`,description:`otto 插件生命周期管理(create/build/dev/install)—— 随 otto 内置分发,恒定信任、恒定启用。`,version:void 0,contributes:void 0,scripts:void 0,capabilities:void 0,activationEvents:void 0,dependsOn:void 0}},{id:`otto-tui`,dir:`<builtin:otto-tui>`,scope:`builtin`,manifest:{id:`otto-tui`,name:`TUI`,description:`otto 终端交互界面本体(渲染/输入/面板/状态栏)—— 随 otto 内置分发,恒定信任、恒定启用。`,version:void 0,contributes:void 0,scripts:void 0,capabilities:void 0,activationEvents:void 0,dependsOn:void 0}}];function jt(e){let{cwd:t,homedir:n}=e,r=e.disabled?new Set(e.disabled):null,i=le({cwd:t,homedir:n,claudeCompat:!1,workspaceRoot:se(t)}).filter(e=>e.kind===`otto`).map(e=>({dir:h(e.dir,`plugins`),scope:e.scope}));for(let t of e.bundledDirs??[])s(t)&&i.unshift({dir:t,scope:`bundled`});let a=new Map;for(let e of At)a.set(e.id,e);for(let{dir:e,scope:t}of i){if(!s(e)||!F(e))continue;let n;try{n=p(e).sort()}catch(t){P.warn({root:e,err:String(t)},`failed to read plugins root, skipped`);continue}for(let i of n){let n=h(e,i);if(!F(n))continue;let o=h(n,x);if(!s(o))continue;let c;try{c=d(o,`utf-8`)}catch(e){P.warn({manifestPath:o,err:String(e)},`failed to read plugin manifest, skipped`);continue}let l=N(c,o);l&&(r?.has(l.id)||a.has(l.id)||a.set(l.id,{id:l.id,dir:n,manifest:l,scope:t}))}}return[...a.values()].sort((e,t)=>e.id.localeCompare(t.id))}function I(e){return e.manifest.dependsOn??[]}function Mt(e){let t=new Map,n=new Map,r=e.filter(e=>e.scope===`builtin`),i=e.filter(e=>e.scope!==`builtin`),a=new Set(r.map(e=>e.id)),o=new Map;for(let e of i)o.set(e.id,e);let s=e=>o.has(e)||a.has(e),c=!0;for(;c;){c=!1;for(let e of o.values()){let t=I(e).filter(e=>!s(e));t.length>0&&(n.set(e.id,[...new Set(t)]),o.delete(e.id),c=!0)}}let l=new Map,u=new Map;for(let e of o.values()){let t=I(e).filter(e=>o.has(e));l.set(e.id,t.length);for(let n of t){let t=u.get(n);t?t.push(e.id):u.set(n,[e.id])}}let d=[...o.values()].filter(e=>l.get(e.id)===0).map(e=>e.id).sort((e,t)=>e.localeCompare(t)),f=[];for(;d.length>0;){let e=d.shift();f.push(e);let t=[];for(let n of u.get(e)??[]){let e=(l.get(n)??0)-1;l.set(n,e),e===0&&t.push(n)}t.length>0&&(d.push(...t),d.sort((e,t)=>e.localeCompare(t)))}let p=new Set(f);for(let e of o.values())p.has(e.id)||t.set(e.id,Nt(e.id,o));return{ordered:[...r,...f.map(e=>o.get(e))],cyclic:t,missingDeps:n}}function Nt(e,t){let n=[],r=new Set,i=e;for(;i&&!r.has(i);){n.push(i),r.add(i);let e=t.get(i);if(!e)break;i=I(e).filter(e=>t.has(e)).sort((e,t)=>e.localeCompare(t))[0]}return i===e&&n.push(e),n}const Pt=1;function Ft(){return`1.0.0`}function L(e){if(e.scope===`builtin`)return!0;let t=e.manifest.engines?.otto;return t?de(t)?ue(Ft(),t):!1:!0}function It(e){let t=[],n=new Map;for(let r of e)L(r)?t.push(r):n.set(r.id,r.manifest.engines?.otto??`(invalid range)`);return{compatible:t,incompatible:n}}function Lt(e,t,n){if(!e?.length)return t?[...t]:void 0;if(!t?.length)return[...e];if(!n)return[...e,...t];let r=new Map(t.map(e=>[n(e),e])),i=new Set,a=[];for(let t of e){let e=n(t);i.add(e),a.push(r.has(e)?r.get(e):t)}for(let e of t)i.has(n(e))||a.push(e);return a}const R={commands:e=>e.name,agents:e=>e.name,skills:e=>e.name,mcp:e=>e.name,panels:e=>e.id,actions:e=>e.id,menus:null,contextKeys:e=>e.key,statusItems:e=>e.id,renderers:e=>e.id,contextSources:e=>e.id,a2uiComponents:e=>e.type,statusWidgets:e=>e.id,fileViewers:e=>e.id,events:e=>e.type};function Rt(...e){let t=e.filter(e=>e!=null);return t.length===0?{}:t.reduce((e,t)=>{let n={};for(let r of Object.keys(R)){let i=R[r],a=Lt(e[r],t[r],i);a&&(n[r]=a)}return n},{})}const z={extensionDetailActions:`extension/detail/actions`},B={statuslineItem:`shell/statusline/item`,menuItem:`shell/menu/item`},zt={...z,...B};function V(e,t){if(!e)return!0;let n=e.indexOf(`:`);if(n===-1){let n=t[e];return n===!0||typeof n==`string`&&n.length>0}let r=e.slice(0,n),i=e.slice(n+1),a=t[r];return a!=null&&String(a)===i}function Bt(e,t,n,r){let i=new Map((n??[]).map(e=>[e.id,e]));return(t??[]).filter(t=>t.point===e&&V(t.when,r)).map(e=>({menu:e,action:i.get(e.action)})).filter(e=>e.action!=null).sort((e,t)=>(e.menu.order??0)-(t.menu.order??0)).map(({action:e})=>({id:e.id,title:e.title,color:e.color,command:e.command}))}function H(e){let t=e.replace(/\$\{OTTO_HOME\}/g,oe);return t===`~`?fe():t.startsWith(`~/`)?fe()+t.slice(1):t}function U(e,t=s){let n=e.groups.length;if(n===0)return e.map.none;let r=e.groups.filter(e=>e.some(e=>t(H(e)))).length;return r===0?e.map.none:r===n?e.map.all:e.map.partial}function Vt(e,t){let n={};for(let r of e??[])n[r.key]=U(r,t);return n}var W=class extends Error{constructor(e){super(`dispatch: 缺少 capability「${e}」——宿主未注入`),this.name=`MissingCapabilityError`}};async function Ht(e,t){switch(e.type){case`builtin`:if(!t.builtin)throw new W(`builtin`);await t.builtin(e.id);return;case`mcp`:if(!t.callMcp)throw new W(`mcp`);await t.callMcp(e.server,e.tool,e.params);return;case`open`:if(!t.open)throw new W(`open`);await t.open(e.target);return;case`command`:if(!t.runCommand)throw new W(`command`);await t.runCommand(e.name,e.args);return;case`script`:if(!t.runScript)throw new W(`script`);await t.runScript(e.name);return;default:throw new W(e.type)}}function Ut(e){return e}function G(e){return`${e.kind}\u0000${e.label}`}function Wt(e,t){if(t===``)return 0;let n=e.label.toLowerCase();return n.startsWith(t)?3:e.description&&e.description.toLowerCase().includes(t)?2:n.includes(t)?1:e.kind.toLowerCase()===t?0:-1}function Gt(e){return e.startsWith(`!`)||e.startsWith(`#`)}function Kt(){let e=new Map,t=new Map;function n(t){for(let n of t){if(Gt(n.value))throw Error(`[plugin-input] sigil value 不得以 '!' 或 '#' 开头(会被误判为 bash/memory 模式):${JSON.stringify(n.value)}`);let t=G(n);e.delete(t),e.set(t,n)}}function r(t){let n=[...e.values()];return t?n.filter(e=>_(e.kind)===t):n}function i(t,n,r=50){let i=t.toLowerCase(),a=[],o=0;for(let t of e.values()){let e=o++;if(n&&_(t.kind)!==n)continue;let r=Wt(t,i);r<0||a.push({entry:t,score:r,order:e})}return a.sort((e,t)=>t.score-e.score||e.order-t.order),a.length<=r?a.map(e=>e.entry):a.slice(0,r).map(e=>e.entry)}function a(e,n){let r=t.get(e);return r||(r=new Set,t.set(e,r)),r.add(n),()=>{r?.delete(n)}}async function o(e,n,r=50){let a=i(e,n,r),o=n?t.get(n):void 0;if(!o||o.size===0)return a;let s=[],c=await Promise.allSettled([...o].map(t=>Promise.resolve().then(()=>t(e,n))));for(let e of c)e.status===`fulfilled`&&s.push(...e.value.filter(e=>!Gt(e.value)));let l=new Set(a.map(e=>G(e))),u=[...a];for(let e of s){let t=G(e);l.has(t)||(l.add(t),u.push(e))}return u.length<=r?u:u.slice(0,r)}function s(t){for(let n of e.values())if(n.label===t)return n}function c(t){let n=!1;for(let[r,i]of e)i.label===t&&(e.delete(r),n=!0);return n}function l(t){for(let[n,r]of e)r.source===t&&e.delete(n)}return{register:n,registerProvider:a,search:i,searchAsync:o,getAll:r,findByLabel:s,unregister:c,unregisterBySource:l}}function qt(){return[{label:`Code Review`,description:`请求代码审查`,value:`Please review the following code for correctness, style, security, and performance. Provide specific, actionable feedback.`,kind:`hashtag`,source:`builtin`},{label:`Write Tests`,description:`为代码编写单元测试`,value:`Please write comprehensive unit tests for the following code. Cover normal cases, edge cases, error cases, and ensure high coverage.`,kind:`hashtag`,source:`builtin`},{label:`Explain Code`,description:`解释代码逻辑`,value:`Please explain the following code in detail. Cover the overall architecture, key algorithms, data flow, and any notable design decisions.`,kind:`hashtag`,source:`builtin`}]}const Jt=r(`@x-otto/plugin:file-provider`),Yt=new Set([`node_modules`,`.git`,`dist`,`build`,`out`,`coverage`,`.next`,`.nuxt`,`.turbo`,`.nx`,`.cache`,`.otto`,`.venv`,`__pycache__`]);async function Xt(e,t,n){let r=[];async function i(a,o){if(r.length>=t)return;let s;try{s=await me(a,{withFileTypes:!0})}catch(e){o&&n?.(e);return}for(let n of s){if(r.length>=t)return;if(n.isDirectory()){if(Yt.has(n.name)||n.name.startsWith(`.`))continue;await i(h(a,n.name),!1)}else n.isFile()&&r.push(ae(e,h(a,n.name)))}}return await i(e,!0),r}function Zt(e,t){if(t===``)return 0;let n=e.toLowerCase();return m(n).startsWith(t)?3:n.startsWith(t)?2:n.includes(t)?1:-1}function Qt(e,t,n,r){let i;try{i=u(h(e,t),`r`);let a=Buffer.allocUnsafe(8192),o=f(i,a,0,a.length,0),s=a.toString(`utf-8`,0,o).split(`
2
2
  `).slice(0,n).join(`
3
- `);return s.length>r?`${s.slice(0,r-1)}…`:s}catch{return``}finally{if(i!==void 0)try{o(i)}catch{}}}function Bt(e){let{cwd:t,max:n=20,walkMax:r=5e3,ttlMs:i=1e4,now:a=Date.now}=e,o=null,s=0,c=null,l=new Map;async function u(){return o&&a()-s<i?o:c||(c=Lt(t,r,e=>{Ft.warn({cwd:t,err:String(e)},`@file provider workspace walk failed at root — @ panel will show no files`)}).then(e=>(o=e,s=a(),c=null,l=new Map,e)),c)}function d(e){let n=l.get(e);if(n!==void 0)return n;let r=zt(t,e,20,500);return l.set(e,r),r}return async e=>{let t=await u(),r=e.toLowerCase(),i=[];for(let e of t){let t=Rt(e,r);if(!(t<0)&&(i.push({path:e,score:t}),r===``&&i.length>=n))break}return i.sort((e,t)=>t.score-e.score||e.path.length-t.path.length),i.slice(0,n).map(({path:e})=>({label:e,value:`[@file:${e.replace(/]/g,`\\]`)}]`,kind:`file`,source:`file`,preview:d(e)}))}}const Vt=r(`@x-otto/coding:trust-store`),Ht={"ui.renderer":`tui.renderer`};function Ut(e){return[...new Set(e.map(e=>Ht[e]??e))]}const K=2e3;function q(e,t){let r=ie(e),o=m(e),s=n(r,o,{timeoutMs:K});s||a(r,o,{timeoutMs:K})&&(s=n(r,o,{timeoutMs:K}));try{return t()}finally{s&&i(r,o)}}function J(e){try{let t=JSON.parse(d(e,`utf-8`)),n=t?.trusted,r=t?.capabilities,i={};if(r&&typeof r==`object`)for(let[e,t]of Object.entries(r))Array.isArray(t)&&(i[e]=Ut(t.filter(e=>typeof e==`string`)));return{trusted:Array.isArray(n)?n.filter(e=>typeof e==`string`):[],capabilities:i}}catch{return{trusted:[],capabilities:{}}}}function Wt(e,t){let n=`${e}.${fe()}.tmp`,r;try{r=u(n,`w`),re(r,t),c(r),o(r),r=void 0,ee(n,e)}catch(e){if(r!==void 0)try{o(r)}catch{}try{ne(n)}catch{}throw e}}function Y(e,t,n){if(!se())try{l(ie(e),{recursive:!0});let n={trusted:[...new Set(t.trusted)]};t.capabilities&&Object.keys(t.capabilities).length>0&&(n.capabilities=t.capabilities),Wt(e,JSON.stringify(n,null,2))}catch(t){Vt.warn({storePath:e,err:t},`Failed to persist ${n} store`)}}function Gt(e,t){return J(e).trusted.includes(g(t))}function Kt(e,t,n){return q(e,()=>{let r=g(t),i=J(e);return i.trusted.includes(r)?!1:(i.trusted.push(r),Y(e,i,n),!0)})}function qt(e,t,n){return q(e,()=>{let r=g(t),i=J(e),a=i.trusted.filter(e=>e!==r),o={...i.capabilities},s=r in o;return delete o[r],a.length===i.trusted.length&&!s?!1:(Y(e,{trusted:a,capabilities:o},n),!0)})}function Jt(e,t){return J(e).capabilities?.[g(t)]??[]}function Yt(e,t,n,r){return q(e,()=>{let i=g(t),a=J(e),o=new Set(a.capabilities?.[i]??[]),s=o.size;for(let e of n)o.add(e);return o.size===s?!1:(Y(e,{trusted:a.trusted,capabilities:{...a.capabilities,[i]:[...o]}},r),!0)})}const X=r(`@x-otto/plugin:trust`);function Z(){return process.env.OTTO_PLUGIN_TRUST_PATH||h(_,`plugin-trust.json`)}function Xt(e,t=Z()){return Gt(t,e)}function Zt(e,t=Z()){Kt(t,e,`plugin-trust`)&&X.info({dir:g(e)},`Plugin trusted`)}function Qt(e,t=Z()){qt(t,e,`plugin-trust`)&&X.info({dir:g(e)},`Plugin trust revoked`)}function $t(e,t=Z()){return Jt(t,e)}function en(e){try{let t=h(e,C);if(!s(t))return[];let n=N(d(t,`utf8`),t);return n?.capabilities?n.capabilities.filter(e=>x.includes(e)):[]}catch{return[]}}function tn(e,t,n=Z()){Yt(n,e,t,`plugin-trust`)&&X.info({dir:g(e),caps:t},`Plugin capabilities granted`)}function Q(e){try{return p(e).length>0}catch{return!1}}function nn(e,t){let n=g(e),r=s(h(n,`.mcp.json`)),i=Q(h(n,`commands`)),a=!!(t?.scripts?.postinstall||t?.scripts?.setup),o=!!(t?.contributes?.panels&&t.contributes.panels.length>0),c=Q(h(n,`skills`)),l=Q(h(n,`agents`)),u=!!t?.contributes?.cli,d=!!t?.capabilities?.some(e=>x.includes(e));return{mcpJson:r,commands:i,scripts:a,panels:o,skills:c,agents:l,cli:u,highRiskCapabilities:d,any:r||i||a||o||c||l||u||d}}function rn(e,t=Z()){let n=nn(e.dir,e.manifest),r=Xt(e.dir,t),i=(e.scope===`project`||e.scope===`repository`)&&n.any&&!r,a=new Set(e.manifest?.capabilities??[]),o=e.scope===`bundled`||e.scope===`builtin`?a:new Set(Jt(t,e.dir));return{surface:n,trusted:r,gated:i,pendingCapabilities:x.filter(e=>a.has(e)&&!o.has(e)),grantedCapabilities:x.filter(e=>a.has(e)&&o.has(e))}}function $(e){return e.split(/[-_]/)[0]??e}var an=class extends t{entries=new Map;currentLocale=`zh`;register(e){this.entries.clear();for(let t of e)this.entries.set(`${t.pluginId}:${t.id}`,t.translations)}get size(){return this.entries.size}getLocale(){return this.currentLocale}setLocale(e){e!==this.currentLocale&&(this.currentLocale=e,this.emit(`change`,e))}t(e,t=this.currentLocale){let n=this.entries.get(e);if(!n)return e;let r=n[t];if(r!==void 0)return r;let i=$(t);for(let[e,t]of Object.entries(n))if($(e)===i)return t;return n.en===void 0?Object.values(n)[0]??e:n.en}};export{z as EXTENSION_POINTS,x as HIGH_RISK_CAPABILITIES,w as ID_RE,Ke as MAX_I18N_ENTRIES_PER_PLUGIN,Ye as MAX_I18N_FILE_BYTES,Je as MAX_I18N_LOCALE_FILES_PER_PLUGIN,qe as MAX_I18N_TRANSLATION_BYTES,Ge as MAX_THEME_PRESETS_PER_PLUGIN,xt as PLUGIN_API_VERSION,pe as PLUGIN_CAPABILITIES,C as PLUGIN_MANIFEST_FILENAME,Et as POINT,an as PluginI18nRegistry,B as SHELL_POINTS,Pt as createBuiltinHashtags,Bt as createFileProvider,Nt as createPluginInputRegistry,At as definePlugin,nn as detectPluginExecutableSurface,vt as discoverPlugins,kt as dispatch,U as evaluateContextKey,Ot as evaluateContextKeys,rn as evaluatePluginTrust,V as evaluateWhen,H as expandPath,Ct as filterEngineCompatible,tn as grantPluginCapabilities,$t as grantedPluginCapabilities,L as isEngineCompatible,Gt as isPathTrusted,Xt as isPluginTrusted,Tt as mergeContributions,N as parsePluginManifest,Z as pluginTrustStorePath,en as readHighRiskCapabilities,Dt as resolveActions,gt as resolveActivationEvents,y as sigilOf,yt as topoSortPlugins,Kt as trustPath,Zt as trustPlugin,qt as untrustPath,Qt as untrustPlugin};
3
+ `);return s.length>r?`${s.slice(0,r-1)}…`:s}catch{return``}finally{if(i!==void 0)try{o(i)}catch{}}}function $t(e){let{cwd:t,max:n=20,walkMax:r=5e3,ttlMs:i=1e4,now:a=Date.now}=e,o=null,s=0,c=null,l=new Map;async function u(){return o&&a()-s<i?o:c||(c=Xt(t,r,e=>{Jt.warn({cwd:t,err:String(e)},`@file provider workspace walk failed at root — @ panel will show no files`)}).then(e=>(o=e,s=a(),c=null,l=new Map,e)),c)}function d(e){let n=l.get(e);if(n!==void 0)return n;let r=Qt(t,e,20,500);return l.set(e,r),r}return async e=>{let t=await u(),r=e.toLowerCase(),i=[];for(let e of t){let t=Zt(e,r);if(!(t<0)&&(i.push({path:e,score:t}),r===``&&i.length>=n))break}return i.sort((e,t)=>t.score-e.score||e.path.length-t.path.length),i.slice(0,n).map(({path:e})=>({label:e,value:`[@file:${e.replace(/]/g,`\\]`)}]`,kind:`file`,source:`file`,preview:d(e)}))}}const en=r(`@x-otto/plugin:trust-store`),tn={"ui.renderer":`tui.renderer`};function nn(e){return[...new Set(e.map(e=>tn[e]??e))]}const K=2e3;function q(e,t,r){let o=ie(e),s=m(e),c=n(o,s,{timeoutMs:K});if(c||a(o,s,{timeoutMs:K})&&(c=n(o,s,{timeoutMs:K})),!c&&r?.requireLock)throw Error(`Failed to acquire trust store lock within ${K}ms; revocation aborted to avoid silently losing it to a concurrent writer`);try{return t()}finally{c&&i(o,s)}}function J(e){try{let t=JSON.parse(d(e,`utf-8`)),n=t?.trusted,r={},i=t?.capabilities;if(i&&typeof i==`object`)for(let[e,t]of Object.entries(i))Array.isArray(t)&&(r[e]=nn(t.filter(e=>typeof e==`string`)));let a={},o=t?.versions;if(o&&typeof o==`object`)for(let[e,t]of Object.entries(o))typeof t==`string`&&(a[g(e)]=t);return{trusted:Array.isArray(n)?n.filter(e=>typeof e==`string`):[],capabilities:r,versions:a}}catch{return{trusted:[],capabilities:{},versions:{}}}}function rn(e,t){let n=`${e}.${he()}.tmp`,r;try{r=u(n,`w`),re(r,t),c(r),o(r),r=void 0,ee(n,e)}catch(e){if(r!==void 0)try{o(r)}catch{}try{ne(n)}catch{}throw e}}function Y(e,t,n){if(!ce())try{l(ie(e),{recursive:!0});let n={trusted:[...new Set(t.trusted)]};t.capabilities&&Object.keys(t.capabilities).length>0&&(n.capabilities=t.capabilities),t.versions&&Object.keys(t.versions).length>0&&(n.versions=t.versions),rn(e,JSON.stringify(n,null,2))}catch(t){throw en.warn({storePath:e,err:t},`Failed to persist ${n} store`),t}}function an(e,t){return J(e).trusted.includes(g(t))}function on(e,t,n){return q(e,()=>{let r=g(t),i=J(e);return i.trusted.includes(r)?!1:(i.trusted.push(r),Y(e,i,n),!0)})}function X(e,t,n){return q(e,()=>{let r=g(t),i=J(e),a=i.trusted.filter(e=>e!==r),o={...i.capabilities},s=r in o;delete o[r];let c={...i.versions},l=r in c;return delete c[r],a.length===i.trusted.length&&!s&&!l?!1:(Y(e,{trusted:a,capabilities:o,versions:c},n),!0)},{requireLock:!0})}function sn(e,t){return J(e).capabilities?.[g(t)]??[]}function cn(e,t,n,r){return q(e,()=>{let i=g(t),a=J(e),o=new Set(a.capabilities?.[i]??[]),s=o.size;for(let e of n)o.add(e);return o.size===s?!1:(Y(e,{trusted:a.trusted,capabilities:{...a.capabilities,[i]:[...o]}},r),!0)})}function ln(e,t,n,r,i){return q(e,()=>{let a=g(t),o=J(e),s=new Set(o.capabilities?.[a]??[]),c=s.size;for(let e of n)s.add(e);let l=o.versions?.[a]!==r;return s.size===c&&!l?!1:(Y(e,{trusted:o.trusted,capabilities:{...o.capabilities,[a]:[...s]},versions:{...o.versions,[a]:r}},i),!0)})}function un(e,t,n){let r=g(t),i=J(e);return i.versions?.[r]===n?i.capabilities?.[r]??[]:[]}const Z=r(`@x-otto/plugin:trust`);function Q(){return process.env.OTTO_PLUGIN_TRUST_PATH||h(oe,`plugin-trust.json`)}function dn(e,t=Q()){return an(t,e)}function fn(e,t=Q()){on(t,e,`plugin-trust`)&&Z.info({dir:g(e)},`Plugin trusted`)}function pn(e,t=Q()){X(t,e,`plugin-trust`)&&Z.info({dir:g(e)},`Plugin trust revoked`)}function mn(e,t=Q()){return sn(t,e)}function hn(e){try{let t=h(e,x);if(!s(t))return[];let n=N(d(t,`utf8`),t);return n?.capabilities?n.capabilities.filter(e=>y.includes(e)):[]}catch{return[]}}function gn(e,t,n=Q()){cn(n,e,t,`plugin-trust`)&&Z.info({dir:g(e),caps:t},`Plugin capabilities granted`)}function _n(e,t,n,r=Q()){ln(r,e,t,n,`plugin-trust`)&&Z.info({dir:g(e),caps:t,version:n},`Plugin capabilities granted (version-bound)`)}function vn(e,t,n=Q()){return un(n,e,t)}function $(e){try{return p(e).length>0}catch{return!1}}function yn(e,t){let n=g(e),r=s(h(n,`.mcp.json`)),i=$(h(n,`commands`)),a=!!(t?.scripts?.postinstall||t?.scripts?.setup),o=!!(t?.contributes?.panels&&t.contributes.panels.length>0),c=[`plugin.ts`,`plugin.tsx`].some(e=>s(h(n,e))),l=$(h(n,`skills`)),u=$(h(n,`agents`)),d=!!t?.contributes?.cli,f=!!t?.capabilities?.some(e=>y.includes(e));return{mcpJson:r,commands:i,scripts:a,panels:o,pluginEntry:c,skills:l,agents:u,cli:d,highRiskCapabilities:f,any:r||i||a||o||c||l||u||d||f}}function bn(e,t=Q()){let n=yn(e.dir,e.manifest),r=dn(e.dir,t),i=(e.scope===`project`||e.scope===`repository`)&&n.any&&!r,a=new Set(e.manifest?.capabilities??[]),o=e.scope===`bundled`||e.scope===`builtin`?a:new Set(sn(t,e.dir));return{surface:n,trusted:r,gated:i,pendingCapabilities:y.filter(e=>a.has(e)&&!o.has(e)),grantedCapabilities:y.filter(e=>a.has(e)&&o.has(e))}}const xn=[`apikey`,`secret`,`token`,`password`,`credential`,`privatekey`,`accesskey`];function Sn(e){let t=e.toLowerCase();return xn.some(e=>t.includes(e))}function Cn(e){let t={};for(let[n,r]of Object.entries(e))Sn(n)?t[n]=`[REDACTED]`:r&&typeof r==`object`&&!Array.isArray(r)?t[n]=Cn(r):t[n]=r;return t}function wn(e,t){let n={...t},r=e?.properties;if(r&&typeof r==`object`)for(let[e,t]of Object.entries(r))!(e in n)&&t&&typeof t==`object`&&`default`in t&&(n[e]=t.default);return n}function Tn(e){return e.split(/[-_]/)[0]??e}var En=class extends t{entries=new Map;currentLocale=`zh`;register(e){this.entries.clear();for(let t of e)this.entries.set(`${t.pluginId}:${t.id}`,t.translations)}get size(){return this.entries.size}getLocale(){return this.currentLocale}setLocale(e){e!==this.currentLocale&&(this.currentLocale=e,this.emit(`change`,e))}t(e,t=this.currentLocale){let n=this.entries.get(e);if(!n)return e;let r=n[t];if(r!==void 0)return r;let i=Tn(t);for(let[e,t]of Object.entries(n))if(Tn(e)===i)return t;return n.en===void 0?Object.values(n)[0]??e:n.en}};export{z as EXTENSION_POINTS,y as HIGH_RISK_CAPABILITIES,S as ID_RE,$e as MAX_CONFIG_FIELDS_PER_PLUGIN,nt as MAX_CONFIG_FIELD_DESCRIPTION_CHARS,tt as MAX_CONFIG_SCHEMA_BYTES,et as MAX_CONFIG_SCHEMA_DEPTH,Ye as MAX_I18N_ENTRIES_PER_PLUGIN,Qe as MAX_I18N_FILE_BYTES,Ze as MAX_I18N_LOCALE_FILES_PER_PLUGIN,Xe as MAX_I18N_TRANSLATION_BYTES,Je as MAX_THEME_PRESETS_PER_PLUGIN,Pt as PLUGIN_API_VERSION,v as PLUGIN_CAPABILITIES,x as PLUGIN_MANIFEST_FILENAME,zt as POINT,En as PluginI18nRegistry,B as SHELL_POINTS,qt as createBuiltinHashtags,$t as createFileProvider,Kt as createPluginInputRegistry,Ut as definePlugin,yn as detectPluginExecutableSurface,jt as discoverPlugins,Ht as dispatch,U as evaluateContextKey,Vt as evaluateContextKeys,bn as evaluatePluginTrust,V as evaluateWhen,H as expandPath,It as filterEngineCompatible,ln as grantCapabilitiesWithVersion,gn as grantPluginCapabilities,_n as grantPluginCapabilitiesWithVersion,un as grantedCapabilitiesForVersion,mn as grantedPluginCapabilities,vn as grantedPluginCapabilitiesForVersion,L as isEngineCompatible,an as isPathTrusted,dn as isPluginTrusted,Sn as isSensitiveField,wn as mergeConfigWithDefaults,Rt as mergeContributions,N as parsePluginManifest,Q as pluginTrustStorePath,hn as readHighRiskCapabilities,Cn as redactSensitiveFields,Bt as resolveActions,kt as resolveActivationEvents,Ot as resolveManifestPlane,pe as sigilOf,Mt as topoSortPlugins,on as trustPath,fn as trustPlugin,X as untrustPath,pn as untrustPlugin};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-otto/plugin",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.11",
4
4
  "files": [
5
5
  "dist",
6
6
  "README.md"
@@ -20,12 +20,13 @@
20
20
  "tag": "alpha"
21
21
  },
22
22
  "dependencies": {
23
- "@x-otto/env": "0.1.0-alpha.1",
24
- "@x-otto/interchange": "0.1.0-alpha.1",
25
- "@x-otto/provider": "0.1.0-alpha.1",
26
- "@x-otto/shared": "0.1.0-alpha.1",
27
23
  "semver": "7.7.4",
28
- "zod": "4.3.6"
24
+ "zod": "4.3.6",
25
+ "@x-otto/env": "0.1.0-alpha.11",
26
+ "@x-otto/hook-contracts": "0.1.0-alpha.11",
27
+ "@x-otto/interchange": "0.1.0-alpha.11",
28
+ "@x-otto/provider": "0.1.0-alpha.11",
29
+ "@x-otto/shared": "0.1.0-alpha.11"
29
30
  },
30
31
  "devDependencies": {
31
32
  "@types/semver": "7.7.1"