@x-otto/coding 0.0.1-alpha.2 → 0.0.1-alpha.4
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.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ GIT binary patch`)){r++;continue}for(let r of e.split(`
|
|
|
9
9
|
`))r.startsWith(`+`)&&!r.startsWith(`+++`)?t++:r.startsWith(`-`)&&!r.startsWith(`---`)&&n++}let a=r>0?`, ${r} binary file${r===1?``:`s`}`:``;return`+${t}/-${n}${a}`}const vo=/^[a-zA-Z0-9_-]+$/;function yo(e){return{save(t,n){if(!vo.test(t))throw Error(`Invalid jobId for applied diff store: ${t}`);D(e,{recursive:!0}),k(b(e,`${t}.patch`),n,`utf-8`)},load(t){let n=b(e,`${t}.patch`);if(E(n))return O(n,`utf-8`)},delete(t){let n=b(e,`${t}.patch`);E(n)&&Xr(n)},loadAll(){return E(e)?Ur(e).filter(e=>He(e)===`.patch`).map(t=>({jobId:t.slice(0,-6),diff:O(b(e,t),`utf-8`)})):[]}}}const bo=[`delegate_job`];function xo(e){return e.filter(e=>!bo.includes(e.name))}function So(){return`job_${di().replace(/-/g,``).slice(0,8)}`}function Co(e){let t=e.outputDir??b(Be(),`otto-jobs`);return e.registry.setWorktreeCleanupErrorHandler((t,n,r)=>e.logger.warn({jobId:t,op:n,err:r instanceof Error?r.message:String(r)},`Failed to clean up agent job worktree`)),new ho({repoRoot:e.repoRoot,registry:e.registry,notify:e.notify,onWorktreeCleanupError:(t,n)=>{e.logger.warn({op:t,err:n instanceof Error?n.message:String(n)},`Failed to clean up agent job worktree`)},appliedDiffStore:e.appliedDiffDir?yo(e.appliedDiffDir):void 0,spawnRun:({runId:t,prompt:n,outputPath:r,workspaceDir:i,onAwaitingInput:a})=>mo({runId:t,prompt:n,outputPath:r,model:e.getModel(),systemPrompt:e.systemPrompt,tools:[...xo(e.buildTools(i)),...e.mcpTools?.()??[]],maxToolTurns:e.maxToolTurns,stream:e.stream,logger:e.logger,hookRegistry:e.hookRegistry,onAwaitingInput:a}),buildOutputPath:e=>(D(t,{recursive:!0}),b(t,`agent-job-${e}.log`)),newJobId:e.newJobId??So})}function wo(e){return Co({repoRoot:e.workspaceDir,registry:Rt,notify:(t,n)=>e.agentJobNotify?.(t,n),buildTools:t=>e.buildToolsForWorkspace(t),mcpTools:()=>e.connectorTools(),getModel:()=>{let t=e.settings.get(`model`),n=(t?e.modelRegistry.find(t):void 0)??e.modelRegistry.getAll().find(e=>e.id!==`__otto_setup__`);if(!n)throw Error(`No model available — configure a model or run /model first.`);return n},stream:e.stream,logger:e.logger,hookRegistry:e.hookRegistry,appliedDiffDir:s()?void 0:b(n,`jobs`,`applied`)})}function To(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n?.role!==`assistant`)continue;let r=(n.content??[]).filter(e=>e.type===`text`&&typeof e.text==`string`).map(e=>e.text).join(`
|
|
10
10
|
`).trim();if(r.length>0)return r}return``}function Eo(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if(n?.role!==`assistant`)continue;let r=n.stopReason;return r===`refusal`||r===`max_tokens`?r:null}return null}function Do(e){let t=Error(e);return t.name=`AbortError`,t}function Oo(e){let t=new Map;return{runSession:async n=>{let r=Date.now(),i=new AbortController;n.taskId&&t.set(n.taskId,i);let a=n.signal,o=()=>i.abort();a&&(a.aborted?i.abort():a.addEventListener(`abort`,o,{once:!0}));let s;s=n.sessionMode===`sticky`&&n.sessionId?e.getSession(n.sessionId)||await e.createSession({id:n.sessionId,agentName:n.agentName,slot:n.slot,modelId:n.model,category:n.category,delegated:!0,promptContext:n.promptContext??(n.agentName?{taskDescription:n.prompt}:void 0),depth:n.depth,readOnly:n.readOnly}):await e.createSession({agentName:n.agentName,slot:n.slot,modelId:n.model,category:n.category,delegated:!0,promptContext:n.promptContext??(n.agentName?{taskDescription:n.prompt}:void 0),depth:n.depth,transient:!0,readOnly:n.readOnly});let c=s.id,l=Ct(s.coreAgent,{id:c,agentName:n.agentName??`agent`,title:n.agentName??n.prompt.replace(/\s+/g,` `).slice(0,48),prompt:n.prompt,model:n.model??s.model.id,modelDecidedBy:s.modelResolution?.decidedBy,origin:`main`,depth:n.depth??0,abort:()=>s.abort(),messages:()=>s.session.messages()});try{if(i.signal.aborted)throw Do(`Task cancelled before the session started`);let e=n.agentName?`<agent-guardrails>\n${gn}\n</agent-guardrails>\n\n<task>\n${n.prompt}\n</task>`:n.prompt,t=s.prompt(e);t.catch(()=>{}),await Promise.race([t,new Promise((e,t)=>{i.signal.addEventListener(`abort`,()=>{s.abort(),t(Do(`Task cancelled`))})})]);let a=s.session.messages(),o=To(a),c=Eo(a);return c&&(o=`${o}\n\n[⚠ subagent did not complete cleanly (stop reason: ${c}) — the output above may be partial or unreliable; verify before relying on it]`),{text:o,sessionId:s.id,durationMs:Date.now()-r}}finally{Bt.setMessages(c,s.session.messages()),l(),Bt.markEnded(c),a?.removeEventListener(`abort`,o),n.taskId&&t.delete(n.taskId),n.sessionMode===`ephemeral`&&await e.removeSession(s.id).catch(t=>{e.logger.warn(`Failed to remove ephemeral session %s: %s`,s.id,t)})}},abortTask:e=>{t.get(e)?.abort()}}}function ko(e){let t=new gi({focusTracking:process.env.OTTO_TUI_FOCUS===`1`}),n=new hi({getConfig:e.getConfig,getCwd:e.getCwd,onInteraction:()=>t.recordInteraction(),isFollowUpPending:e.isFollowUpPending,gate:new vi({getCondition:()=>e.getConfig()?.condition,getIdleThresholdMs:()=>e.getConfig()?.idle_threshold_ms,state:t})});return n.registerChannel(new _i({getConfig:e.getConfig})),n.registerChannel(new pi(`hook`,()=>!0,t=>e.emitHookNotification({sessionId:t.sessionId,message:t.message,title:t.title,notification_type:t.type}))),n.registerChannel(new mi({getConfig:e.getConfig,isTrusted:()=>Sr(e.getCwd())})),{dispatcher:n,presenceTracker:t}}function Ao(e,t){if(!t||t.length===0)return e;let n=t.map(e=>RegExp(`^`+e.replace(/[.+^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`.*`)+`$`,`i`));return e.filter(e=>!n.some(t=>t.test(e)))}var jo=class{catalog;derivedModelIds=new Map;constructor(e,t,n){this.modelRegistry=e,this.authStore=t,this.catalog=n??new d}async hydrate(){let e=new Set,t=await this.catalog.load();if(!t)return e;for(let n of Object.values(t.providers)){let t=oe(this.modelRegistry,n.mergeProvider,n.modelIds,{templateApi:n.modelApi});for(let n of t.availableIds)e.add(n);let r=this.derivedModelIds.get(n.mergeProvider)??new Set;for(let e of t.derivedIds)r.add(e);this.derivedModelIds.set(n.mergeProvider,r)}return e}refreshInFlight=null;async refresh(){return this.refreshInFlight||=this.doRefresh().finally(()=>{this.refreshInFlight=null}),this.refreshInFlight}async doRefresh(){let e=this.modelRegistry,t=this.authStore,n=t.listProviders(),r=await Promise.all(n.map(e=>t.getAuthSource(e).catch(()=>null))),i=[];for(let a=0;a<n.length;a++){let o=n[a];if(!r[a]){i.push({provider:o,status:`skipped`,reason:`not authenticated`});continue}let s=await t.resolveAuth(o).catch(()=>null);if(!s?.token){let e=r[a]===`oauth`&&!t.oauth.has(o)?`provider capability not granted — trust the plugin in /extension`:`credential expired or refresh failed — re-login`;i.push({provider:o,status:`skipped`,reason:e});continue}let c=ue(o,s.token,{mode:s.mode,beta:s.beta});if(!c){let t=e.getByProvider(o);if(t.length>0){let e=t.map(e=>e.id);await this.catalog.put(o,{fetchedAt:Date.now(),mergeProvider:o,modelIds:e}).catch(()=>{}),i.push({provider:o,status:`ok`,added:0,kept:e.length,total:e.length,availableIds:e})}else i.push({provider:o,status:`skipped`,reason:`no live models endpoint`});continue}try{let t=Ao(await v(c),c.modelIdExclude),n=oe(e,c.mergeProvider,t,{templateApi:c.modelApi}),r=new Set(n.availableIds),a=this.derivedModelIds.get(c.mergeProvider)??new Set;for(let t of a)r.has(t)||e.unregister(t);this.derivedModelIds.set(c.mergeProvider,new Set([...[...a].filter(e=>r.has(e)),...n.derivedIds])),await this.catalog.put(o,{fetchedAt:Date.now(),mergeProvider:c.mergeProvider,modelApi:c.modelApi,modelIds:t}).catch(()=>{}),i.push({provider:o,status:`ok`,added:n.added,kept:n.kept,total:n.total,availableIds:n.availableIds})}catch(e){i.push({provider:o,status:`failed`,reason:e instanceof Error?e.message:String(e)})}}return i}};function Mo(e){return e.modelRegistry.getAll()}function No(e,t){return e.modelRegistry.resolve(t)}function Po(e){return e.providerRegistry.list()}function Fo(e,t){e.hookRegistry.register(t)}function Io(e,t){return e.hookRegistry.unregister(t)}async function Lo(e){return e.modelCatalogManager.hydrate()}function Ro(e,t){return e.codingSessionPool.getSessionAvailableModels(t)}function zo(e,t,n){e.codingSessionPool.setSessionAvailableModels(t,n)}async function Bo(e){return e.modelCatalogManager.refresh()}async function Vo(e,t){let n=new Set(t?e.codingSessionPool.getSessionAvailableModels(t):[]),r=ne(e.authStore);return Promise.all(e.modelRegistry.getAll().filter(e=>e.id!==`__otto_setup__`).map(async e=>{let t=await r(e);return{id:e.id,provider:e.provider,strengths:e.strengths??[],available:n.has(e.id),usable:t.usable,...t.reason?{unusableReason:t.reason}:{}}}))}function Ho(e,t){e.notificationDispatcher.registerChannel(t)}function Uo(e,t){e.notificationDispatcher.registerChannel(new pi(`inapp`,()=>!0,e=>t(e.title??`otto`,e.message,e.type)))}function Wo(e){e.presenceTracker.recordInteraction()}function Go(e,t){e.presenceTracker.setFocus(t)}async function Ko(e,t,n){if(!t)return;if(n){e.permissionRegistry.addSessionAlwaysAllow(n,t),e.codingSessionPool.setSessionPermissionAllow(n,e.permissionRegistry.getSessionAlwaysAllow(n)),e.logger.info({tool:t,sessionId:n},`Tool added to session always-allow list`);return}let r=e.settings.get(`permission_always_allow`)??[];r.includes(t)||(e.permissionRegistry.addAlwaysAllow(t),await e.settings.persist({permission_always_allow:[...r,t]}),e.logger.info({tool:t},`Tool added to project always-allow list`))}function qo(e){return e.settings.get(`permission_mode`)??`auto`}async function Jo(e,t){let n=qo(e);await e.settings.update({permission_mode:t}),e.settings.persist({permission_mode:t}).catch(n=>e.logger.warn({err:n instanceof Error?n.message:String(n),mode:t},`Failed to persist permission mode`)),e.logger.info({from:n,to:t},`Permission mode set`)}function Yo(e,t){return e.permissionRegistry.getSessionAlwaysAllow(t)}async function Xo(e,t){if(!t)return!1;let n=e.settings.get(`permission_always_allow`)??[];if(!n.includes(t))return!1;let r=n.filter(e=>e!==t);return e.permissionRegistry.setAlwaysAllow(r),await e.settings.persist({permission_always_allow:r}),e.logger.info({tool:t},`Tool removed from project always-allow list`),!0}function Zo(e,t){t&&(e.permissionRegistry.clearSessionAlwaysAllow(t),e.codingSessionPool.setSessionPermissionAllow(t,[]),e.logger.info({sessionId:t},`Session always-allow list cleared`))}async function Qo(e,t={}){e.ensureNotDisposed(),await e.ensureSettingsLoaded();let n=await e.sessionConfigResolver.resolve(t),r=await e.agentRuntime.createSession(n);return e.notificationDispatcher.attach(r),e.toolsSyncCoordinator?.record(r.id,{agentName:t.agentName,promptPreset:t.promptPreset??(t.agentName?`subagent`:`main`),readOnly:t.readOnly,hasExplicitTools:t.tools!==void 0}),e.logger.info({sessionId:r.id},`Session created`),r}function $o(e,t){return e.codingSessionPool.getSession(t)}async function es(e,t,n){if(!e.storage.storageHost)throw Error(`shareSession requires a configured storage.host`);await e.storage.storageHost.host.updateMetadata(`sessions`,e.workspaceRef?.key,t,{visibility:n.visibility},void 0),e.logger.info({sessionId:t,visibility:n.visibility},`Session visibility changed`)}function ts(e){return e.codingSessionPool.active}function ns(e,t){return e.codingSessionPool.listSessions(t)}async function rs(e,t){let n=ns(e,t),r;try{r=t?.workspaceId===void 0?e.workspaceRef?.key:Ci(t.workspaceId)}catch{r=void 0}if(!r)return n;let i=await e.codingSessionPool.listAllPersistedSessions({workspaceKey:r}).catch(()=>[]),a=t?.workspaceId??e.workspaceRef?.id,o=new Set(n.map(e=>e.id)),s=i.filter(e=>!o.has(e.id)).map(e=>({...e,workspaceId:a})),c=[...n,...s];return c.sort((e,t)=>{let n=e.updatedAt?.getTime()??e.createdAt.getTime();return(t.updatedAt?.getTime()??t.createdAt.getTime())-n}),c}async function is(e,t){e.notificationDispatcher.detach(t);let n=await e.codingSessionPool.removeSession(t);return n&&(e.toolsSyncCoordinator?.forget(t),e.logger.info({sessionId:t},`Session removed`)),n}async function as(e,t){let n=await e.codingSessionPool.archiveSession(t);return n&&e.logger.info({sessionId:t},`Session archived`),n}async function os(e,t,n){let r=await e.codingSessionPool.forkSession(t,n);return r&&e.notificationDispatcher.attach(r),r}var ss=class{contexts=new Map;constructor(e){this.deps=e}record(e,t){t.hasExplicitTools||this.contexts.set(e,{agentName:t.agentName,promptPreset:t.promptPreset,readOnly:t.readOnly})}forget(e){this.contexts.delete(e)}resyncOne(e){let t=this.contexts.get(e);return t?this.resyncSession(e,t):!1}resync(){let e=new Set(this.deps.listSessionIds());for(let t of this.contexts.keys())e.has(t)||this.contexts.delete(t);let t=0;for(let[e,n]of this.contexts)this.resyncSession(e,n)&&t++;return t}resyncSession(e,t){let n=this.deps.getSession(e);if(!n)return!1;try{let e=this.deps.sessionConfigResolver.resolveToolsForResync(t.agentName,t.promptPreset,t.readOnly);return n.model.supportsTools===!1&&(e=[]),n.tools=e,!0}catch(t){return this.deps.logger.warn({sessionId:e,err:t instanceof Error?t.message:String(t)},`[session-tools-sync] resync failed for session, skipping (fail-soft)`),!1}}};const cs=S(`@x-otto/coding:plugin-panel-manager`);function ls(e){let t=e.plugins??Vn({cwd:e.workspaceDir,homedir:e.homedir,disabled:e.disabledPlugins}),n=[];for(let e of t){let t=e.manifest.contributes?.panels;if(!t||t.length===0)continue;let r=T(e);if(!r.gated){if(!e.manifest.capabilities?.includes(`tui.renderer`)){cs.warn({pluginId:e.id},`plugin declares contributes.panels but not capabilities:["tui.renderer"], skipped (fail-closed)`);continue}if(r.pendingCapabilities.includes(`tui.renderer`)){cs.warn({pluginId:e.id},`plugin capability "tui.renderer" declared but not yet granted, skipping panels (fail-closed)`);continue}for(let r of t){let t=b(e.dir,r.entry);if(!E(t)){cs.warn({pluginId:e.id,panelId:r.id,modulePath:t},`panel entry not found — postinstall build may not have run`);continue}n.push({id:`${e.id}:${r.id}`,pluginId:e.id,title:r.title,modulePath:t,exportName:r.export??`default`})}}}return n}function us(e){let t=[];for(let n of e){if(T(n).gated)continue;let e=n.manifest.contributes?.statusItems;if(!e?.length)continue;let r=Un(n.manifest.contributes?.contextKeys);for(let i of e){if((i.point??Mn.statuslineItem)!==Mn.statuslineItem||!Gn(i.when,r))continue;let e=r[i.dataSource.contextKey];e!=null&&t.push({item:{id:`${n.id}:${i.id}`,text:e},order:i.order??0})}}return t.sort((e,t)=>e.order-t.order).map(e=>e.item)}function ds(e){let t=[];for(let n of e){if(T(n).gated)continue;let e=n.manifest.contributes;if(!e?.menus?.length)continue;let r=Un(e.contextKeys);t.push(...nr(Mn.menuItem,e.menus,e.actions,r))}return t}const fs={capability:`tui.renderer`,axis:`renderers`,noun:`renderer`,pendingNote:`RFC-140 D3`,logger:S(`@x-otto/coding:plugin-renderer-loader`),entries:e=>e.manifest.contributes?.renderers,entryPath:e=>e.entry,exportName:e=>e.export,idLogFields:e=>({rendererId:e.id}),logTypeofOnNotFunction:!0,build:(e,t,n)=>({id:`${e.id}:${t.id}`,pluginId:e.id,matcher:t.matcher,render:n}),successLogFields:e=>({rendererId:e.id,matcher:e.matcher})};function ps(e){return Ga(e,fs)}const ms=S(`@x-otto/coding:plugin-a2ui-component-loader`),hs=new Set([`Text`,`Card`,`List`,`Progress`,`Chip`,`Button`]),gs={capability:`a2ui.component`,axis:`a2uiComponents`,noun:`a2ui component`,pendingNote:`RFC-140 D3 pattern`,logger:ms,entries:e=>e.manifest.contributes?.a2uiComponents,entryPath:e=>e.entry,exportName:e=>e.export,idLogFields:e=>({type:e.type}),logTypeofOnNotFunction:!1,preCheck:(e,t)=>hs.has(t.type)?(ms.warn({pluginId:e.id,type:t.type},`plugin a2ui component type collides with builtin reserved type, rejected (R4)`),!1):!0,build:(e,t,n)=>({type:t.type,pluginId:e.id,render:n})};function _s(e){return Ga(e,gs,{key:e=>e.type,onConflict:(e,t)=>{ms.warn({pluginId:e.pluginId,type:e.type,existingOwner:t},`a2ui component type already registered by another plugin, rejected (first-registered wins)`)}})}const vs={capability:`tui.renderer`,axis:`statusWidgets`,noun:`status widget`,pendingNote:`RFC-140 D3 pattern`,logger:S(`@x-otto/coding:plugin-status-widget-loader`),entries:e=>e.manifest.contributes?.statusWidgets,entryPath:e=>e.entry,exportName:e=>e.export,idLogFields:e=>({widgetId:e.id}),logTypeofOnNotFunction:!0,build:(e,t,n)=>({id:`${e.id}:${t.id}`,pluginId:e.id,render:n,tickMs:t.tickMs,order:t.order}),successLogFields:e=>({widgetId:e.id})};function ys(e){return Ga(e,vs)}const bs={capability:`tui.renderer`,axis:`fileViewers`,noun:`file viewer`,pendingNote:`RFC-140 D3 pattern`,logger:S(`@x-otto/coding:plugin-file-viewer-loader`),entries:e=>e.manifest.contributes?.fileViewers,entryPath:e=>e.entry,exportName:e=>e.export,idLogFields:e=>({viewerId:e.id}),logTypeofOnNotFunction:!0,build:(e,t,n)=>({id:`${e.id}:${t.id}`,pluginId:e.id,label:t.label,matcher:t.matcher,render:n,order:t.order}),successLogFields:e=>({viewerId:e.id,matcher:e.matcher})};function xs(e){return Ga(e,bs)}var Ss=class{constructor(e){this.deps=e}listFileCommands(){return[...hr(this.deps.getWorkspaceDir(),this.deps.getActivePlugins()),...this.deps.pluginModuleManager.commands]}computedPluginCommands(){return this.deps.pluginModuleManager.commands}async callMcpTool(e,t,n){let r=this.deps.mcpController.getMcpClient(e);if(!r)throw Error(`MCP server "${e}" not connected or not found`);let i=await r.callTool({name:t,arguments:n});return{content:i.content,isError:i.isError}}getPluginPanelRegistrations(){return ls({workspaceDir:this.deps.getWorkspaceDir(),homedir:ze(),disabledPlugins:this.deps.settings.get(`disabled_plugins`),plugins:this.deps.getActivePlugins()})}getPluginStatusItems(){return us(this.deps.getActivePlugins())}getGlobalMenuItems(){return ds(this.deps.getActivePlugins())}getPluginRenderers(){return ps(this.deps.getActivePlugins())}getPluginA2uiComponents(){return _s(this.deps.getActivePlugins())}getPluginStatusWidgets(){return ys(this.deps.getActivePlugins())}getPluginFileViewers(){return xs(this.deps.getActivePlugins())}getPluginRegistrations(){let e=new Map,t=t=>{let n=e.get(t);return n||(n={pluginId:t},e.set(t,n)),n};for(let e of this.getPluginRenderers()){let n=t(e.pluginId);(n.renderers??=[]).push(e)}for(let e of this.getPluginStatusItems()){let n=t(e.id.split(`:`)[0]??e.id);(n.statusItems??=[]).push(e)}for(let e of this.getPluginPanelRegistrations()){let n=t(e.pluginId);(n.panels??=[]).push(e)}for(let e of this.getPluginA2uiComponents()){let n=t(e.pluginId);(n.a2uiComponents??=[]).push(e)}for(let e of this.getPluginStatusWidgets()){let n=t(e.pluginId);(n.statusWidgets??=[]).push(e)}for(let e of this.getPluginFileViewers()){let n=t(e.pluginId);(n.fileViewers??=[]).push(e)}return[...e.values()]}};const A=S(`@x-otto/coding:plugin-hooks`),Cs=4096;function ws(e,t){let n=Ye();return n.OTTO_PLUGIN_DIR=e.pluginDir,n.OTTO_PLUGIN_ID=e.pluginId,e.workspaceDir&&(n.OTTO_WORKSPACE_DIR=e.workspaceDir),t&&Object.assign(n,t),n}function Ts(e){let t=Xe(e);return t.safe?null:{success:!1,hook:`pre-check`,command:e,error:`Dangerous command blocked: ${t.reason}`}}function Es(e,t){let n=!1,r,i;if(e?.length){let t=typeof e==`string`?e:e.toString(`utf-8`);r=t.slice(0,Cs),n=t.length>Cs}if(t?.length){let e=typeof t==`string`?t:t.toString(`utf-8`);i=e.slice(0,Cs),n||=e.length>Cs}return{stdout:r,stderr:i,truncated:n}}async function Ds(e,t){return Ts(t)||(A.info({pluginId:e.pluginId,command:t},`Executing postinstall hook`),new Promise(n=>{let r=Ti(t,{cwd:e.pluginDir,env:ws(e),shell:!0,stdio:`pipe`}),i=[],a=[];r.stdout?.on(`data`,e=>{i.push(e)}),r.stderr?.on(`data`,e=>{a.push(e)});let o=!1,s=setTimeout(()=>{o=!0,r.kill()},3e4);r.on(`close`,(r,c)=>{clearTimeout(s);let{stdout:l,stderr:u,truncated:d}=Es(Buffer.concat(i),Buffer.concat(a)),f={success:!o&&r===0&&c===null,hook:`postinstall`,command:t,exitCode:r,signal:c??void 0,stdout:l,stderr:u,truncated:d||void 0};o&&(f.timeout=!0,f.error=`postinstall hook timed out (30s)`),f.success||A.warn({pluginId:e.pluginId,result:f},`Postinstall hook failed`),n(f)}),r.on(`error`,e=>{clearTimeout(s),n({success:!1,hook:`postinstall`,command:t,error:e.message})})}))}function Os(e,t,n,r,i){let a=Ts(t);if(a){A.warn({pluginId:e.pluginId,command:t},`Setup hook blocked by safety check`),n?.(a);return}if(A.info({pluginId:e.pluginId,command:t},`Executing setup hook (async)`),r){let a=r.spawn({command:t,args:[],options:{shell:!0},owner:{type:`plugin-hook`,id:e.pluginId},category:`plugin`,label:`${e.pluginId}:setup`,lifecycle:`evictable`,killGraceMs:5e3,cwd:e.pluginDir,env:ws(e),signal:i}),o=setTimeout(()=>{A.warn({pluginId:e.pluginId},`Setup hook exceeded 60s — killing`),a.kill({reason:`setup timeout (60s)`})},6e4);o.unref?.();let s=``,c=``;a.onStdoutLine(e=>{s+=e+`
|
|
11
11
|
`}),a.onStderrLine(e=>{c+=e+`
|
|
12
|
-
`}),a.onExit(r=>{clearTimeout(o);let{stdout:i,stderr:a,truncated:l}=Es(s,c),u={success:r.code===0&&r.signal===null,hook:`setup`,command:t,exitCode:r.code,signal:r.signal??void 0,stdout:i,stderr:a,truncated:l||void 0};u.success?A.info({pluginId:e.pluginId},`Setup hook succeeded`):A.error({pluginId:e.pluginId,exitCode:r.code,signal:r.signal,stderr:a?.slice(0,512)},`Setup hook failed`),n?.(u)}),a.onError(r=>{A.error({pluginId:e.pluginId,err:r},`Setup hook spawn error`),n?.({success:!1,hook:`setup`,command:t,error:r.message})});return}let o=Ti(t,{cwd:e.pluginDir,env:ws(e),shell:!0,timeout:6e4,stdio:`pipe`}),s=``,c=``;o.stdout?.on(`data`,e=>{s+=e.toString(`utf-8`)}),o.stderr?.on(`data`,e=>{c+=e.toString(`utf-8`)}),o.on(`close`,(r,i)=>{let{stdout:a,stderr:o,truncated:l}=Es(s,c),u={success:r===0&&i===null,hook:`setup`,command:t,exitCode:r,signal:i,stdout:a,stderr:o,truncated:l||void 0};u.success?A.info({pluginId:e.pluginId},`Setup hook succeeded`):A.error({pluginId:e.pluginId,exitCode:r,signal:i,stderr:o?.slice(0,512)},`Setup hook failed`),n?.(u)}),o.on(`error`,r=>{A.error({pluginId:e.pluginId,err:r},`Setup hook spawn error`),n?.({success:!1,hook:`setup`,command:t,error:r.message})})}const ks=S(`@x-otto/coding:plugin-lifecycle`),As=`plugin_lifecycle`,js=new Set;async function Ms(e,t,n){let r=t.get(As)?.setupDone??[],i=new Map(r.map(e=>[e.id,e.version])),a=new Set(e.map(e=>e.id));for(let e of i.keys())a.has(e)||i.delete(e);let o=!1;for(let r of e){let e=i.get(r.id),a=r.manifest.version,s=r.manifest.scripts?.setup;if(!s){(e===void 0||e!==a)&&(i.set(r.id,a),o=!0);continue}if(!(e!==void 0&&e===a)){if(T(r).gated){ks.info({pluginId:r.id},`Setup hook deferred: plugin not yet trusted`);continue}js.has(r.id)||(js.add(r.id),Os({pluginDir:r.dir,pluginId:r.id,workspaceDir:n},s,e=>{js.delete(r.id),i.set(r.id,a),Ns(t,i)},Ht))}}o&&await Ns(t,i)}async function Ns(e,t){let n=[...t].map(([e,t])=>({id:e,version:t}));await e.persist({[As]:{setupDone:n}})}function Ps(e,t){let n;try{n=Gr(t)}catch{return!1}let r;try{r=Gr(e)}catch{r=e}return r===n||r.startsWith(n+Ge)}const j=S(`@x-otto/coding:plugin-i18n-loader`),Fs=/^([a-zA-Z0-9_-]+)\.json$/;function Is(e){return Buffer.byteLength(e,`utf8`)<=En?e:`${Buffer.from(e,`utf8`).subarray(0,En).toString(`utf8`)}…`}function Ls(e,t,n){let r=new Map,i=x(t,n);if(!Ps(i,t))return j.warn({pluginId:e,i18nDir:n},`i18nDir resolves outside plugin dir, skipped`),r;let a;try{a=Ur(i)}catch{return r}let o=a.filter(e=>Fs.test(e)).sort();o.length>Tn&&(j.warn({pluginId:e,i18nDir:n,declared:o.length,limit:Tn},`plugin i18nDir declares more locale files than the per-plugin limit, truncated`),o=o.slice(0,Tn));for(let n of o){let a=Fs.exec(n)?.[1];if(!a)continue;let o=x(i,n);if(!Ps(o,t)){j.warn({pluginId:e,filename:n},`i18nDir locale file resolves outside plugin dir, skipped`);continue}let s;try{s=O(o,`utf8`)}catch(t){j.warn({pluginId:e,filename:n,err:String(t)},`i18nDir locale file read failed, skipped`);continue}if(Buffer.byteLength(s,`utf8`)>wn){j.warn({pluginId:e,filename:n,limit:wn},`i18nDir locale file exceeds byte limit, skipped`);continue}let c;try{c=JSON.parse(s)}catch(t){j.warn({pluginId:e,filename:n,err:String(t)},`i18nDir locale file is not valid JSON, skipped`);continue}if(typeof c!=`object`||!c||Array.isArray(c)){j.warn({pluginId:e,filename:n},`i18nDir locale file is not a flat object, skipped`);continue}for(let[e,t]of Object.entries(c)){if(typeof t!=`string`)continue;let n=r.get(e)??{};n[a]=t,r.set(e,n)}}return r}function Rs(e){let t=[];for(let n of e){if(T(n).gated)continue;let e=n.manifest.contributes?.i18nDir,r=n.manifest.contributes?.i18n;if(!e&&!r?.length)continue;let i=e?Ls(n.id,n.dir,e):new Map;if(r?.length)for(let e of r){let t=i.get(e.id)??{};for(let[r,i]of Object.entries(e.translations))r in t&&j.debug({pluginId:n.id,id:e.id,locale:r},`i18n inline entry overrides locale dir value`),t[r]=i;i.set(e.id,t)}let a=[...i.keys()];a.length>Cn&&(j.warn({pluginId:n.id,declared:a.length,limit:Cn},`plugin declares more i18n entries than the per-plugin limit, truncated`),a=a.slice(0,Cn));for(let e of a){let r=i.get(e);if(!r)continue;let a={};for(let[e,t]of Object.entries(r))a[e]=Is(t);t.push({pluginId:n.id,id:e,translations:a})}}return t}const zs=S(`@x-otto/coding:declarative-agents`);function Bs(e){return{...e,defaultTools:e.defaultTools?.length?Tr(e.defaultTools):e.defaultTools,disallowedTools:e.disallowedTools?.length?Tr(e.disallowedTools):e.disallowedTools}}function Vs(e,t){let n=tt(e);if(!n)return zs.warn({sourcePath:t},`Agent definition missing frontmatter, skipped`),null;let{fields:r,body:i}=n,a=r.get(`name`),o=r.get(`description`);if(!a||!o||!i)return zs.warn({sourcePath:t},`Agent definition requires name/description/body, skipped`),null;let s=$e(r.get(`tools`)),c=Number.parseInt(r.get(`maxtoolturns`)??``,10),l=Number.parseInt(r.get(`maxtoolturnextensions`)??``,10),u=r.get(`prompt-mode`),d=$e(r.get(`disallowed-tools`)),f=r.get(`allow-subagents`)===`true`?!0:r.get(`allow-subagents`)===`false`?!1:void 0;return{name:a,description:o,taskTypes:$e(r.get(`tasktypes`))??[o],capabilities:$e(r.get(`capabilities`))??[],systemPromptTemplate:i,promptMode:u===`append`||u===`replace`?u:void 0,defaultTools:s,disallowedTools:d?.length?d:void 0,preferredModelTier:r.get(`slot`)??r.get(`tier`),defaultMaxToolTurns:Number.isInteger(c)?c:void 0,defaultMaxToolTurnExtensions:Number.isInteger(l)?l:void 0,allowSubagents:f}}async function Hs(e,t){let{homedir:n}=await import(`node:os`),{join:r}=await import(`node:path`),i=t?.globalDir??r(n(),`.otto`,`agents`),a=r(e,`.otto`,`agents`),s=(t?.plugins??Vn({cwd:e,homedir:n()})).filter(e=>e.manifest.contributes?.agents!==!1).filter(e=>!T(e).gated).map(e=>({dir:r(e.dir,`agents`),claude:!1})),c=o(),l=c&&!_r(e).gated,u=[...s,...c?[{dir:r(n(),`.claude`,`agents`),claude:!0}]:[],{dir:i,claude:!1},...l?[{dir:r(e,`.claude`,`agents`),claude:!0}]:[],{dir:a,claude:!1}],d=new Map;for(let{dir:e,claude:t}of u)for(let n of await Us(e))d.set(n.name,t?Bs(n):n);let f=[...d.values()];return f.length>0&&zs.info(`Loaded %d declarative agent(s): %s`,f.length,f.map(e=>e.name).join(`, `)),f}async function Us(e){let{readFile:t,readdir:n}=await import(`node:fs/promises`),{join:r}=await import(`node:path`),i;try{i=await n(e)}catch{return[]}let a=[];for(let n of i.filter(e=>e.endsWith(`.md`)).sort()){let i=r(e,n);try{let e=Vs(await t(i,`utf-8`),i);e&&a.push(e)}catch(e){zs.warn({sourcePath:i,err:e},`Failed to read agent definition, skipped`)}}return a}const Ws=S(`@x-otto/coding:declarative-teams`),Gs=new Set([`handoff`,`sequential`,`parallel`,`hierarchical`,`router`]);function Ks(e){if(!e)return;let t=[];for(let n of e.split(`|`)){let[e,r]=n.split(/→|->/);if(e===void 0||r===void 0)continue;let i=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e!==``),a=r.trim();i.length>0&&a!==``&&t.push({keywords:i,agentId:a})}return t.length>0?t:void 0}function qs(e,t){let n=tt(e);if(!n)return Ws.warn({sourcePath:t},`Team definition missing frontmatter, skipped`),null;let{fields:r}=n,i=r.get(`name`),a=r.get(`pattern`),o=$e(r.get(`agents`));if(!i||!a||!Gs.has(a)||!o||o.length===0)return Ws.warn({sourcePath:t},`Team definition requires name, valid pattern and non-empty agents, skipped`),null;let s=Number.parseInt(r.get(`maxhandoffdepth`)??``,10);return{name:i,pattern:a,agentNames:o,pipeline:$e(r.get(`pipeline`)),supervisorId:r.get(`supervisor`),entryAgentId:r.get(`entry`),routerStrategy:r.get(`router`),rules:Ks(r.get(`rules`)),maxHandoffDepth:Number.isInteger(s)?s:void 0}}async function Js(e,t){let{homedir:n}=await import(`node:os`),{join:r}=await import(`node:path`),i=t?.globalDir??r(n(),`.otto`,`teams`),a=r(e,`.otto`,`teams`),o=new Map;for(let e of[i,a])for(let t of await Ys(e))o.set(t.name,t);let s=[...o.values()];return s.length>0&&Ws.info(`Loaded %d declarative team(s): %s`,s.length,s.map(e=>e.name).join(`, `)),s}async function Ys(e){let{readFile:t,readdir:n}=await import(`node:fs/promises`),{join:r}=await import(`node:path`),i;try{i=await n(e)}catch{return[]}let a=[];for(let n of i.filter(e=>e.endsWith(`.md`)).sort()){let i=r(e,n);try{let e=qs(await t(i,`utf-8`),i);e&&a.push(e)}catch(e){Ws.warn({sourcePath:i,err:e},`Failed to read team definition, skipped`)}}return a}var Xs=class{constructor(e,t,n,r,i,a,o,s,c,l){this.settings=e,this.mcp=t,this.skills=n,this.pluginModules=r,this.pluginProviders=i,this.tools=a,this.modelCatalog=o,this.workspaceDir=s,this.activePlugins=c,this.i18n=l}async reload(){await this.settings.load(),Ms(this.activePlugins(),this.settings,this.workspaceDir),await this.mcp.reload(),this.skills&&(this.skills.updatePluginDirs(this.activePlugins().filter(e=>e.manifest.contributes?.skills!==!1).filter(e=>!T(e).gated).map(e=>({id:e.id,dir:b(e.dir,`skills`)}))),await this.skills.discover());let e=Rs(this.activePlugins());this.i18n.register(e);let t=(await this.modelCatalog.refresh().catch(()=>[])).reduce((e,t)=>e+(t.added??0),0),n=await Hs(this.workspaceDir,{plugins:this.activePlugins()}),r=await Js(this.workspaceDir),i=await this.pluginModules.reload(new Set(n.map(e=>e.name)));n.push(...i);let a=await this.pluginProviders.reload();return{mcpTools:this.tools.getAvailable(`full`).filter(e=>e.name.startsWith(`mcp__`)).length,models:t,agents:n.length,teamCount:r.length,agentProfiles:n,teamDeclarations:r,pendingProviderCapabilities:a.pendingCapabilityPluginIds,i18nEntries:e.length}}};const Zs=S(`@x-otto/coding:panel-backend-controller`);var Qs=class{stateListeners=new Map;statusListeners=new Map;inProcessHandlers=new Map;subscribedManager=null;constructor(e){this.deps=e}registerInProcessBackend(e,t){this.inProcessHandlers.set(e,t);let n=this.statusListeners.get(e);if(n)for(let e of n)e(`ready`)}unregisterInProcessBackend(e){this.inProcessHandlers.delete(e)}resolveServerForPlugin(e){if(this.inProcessHandlers.has(e))return{ok:!0};let t=this.deps.getActivePlugins().find(t=>t.id===e);if(!t)return{ok:!1,reason:`plugin "${e}" not found or not active`};if(!t.manifest.capabilities?.includes(`panel.backend`))return{ok:!1,reason:`plugin "${e}" does not declare capabilities:["panel.backend"]`};let n=T(t);if(n.pendingCapabilities.includes(`panel.backend`))return{ok:!1,reason:`plugin "${e}" capability "panel.backend" declared but not yet granted`};if(n.gated)return{ok:!1,reason:`plugin "${e}" is untrusted`};let r=this.deps.mcpController.listEffectiveServers(),i=Object.entries(r).filter(([,t])=>t.pluginId===e);return i.length===0?{ok:!1,reason:`plugin "${e}" has no associated MCP server`}:(i.length>1&&Zs.warn({pluginId:e,serverNames:i.map(([e])=>e)},`plugin contributes multiple MCP servers; panel backend uses the first match (multi-server routing not yet supported)`),{ok:!0,serverName:i[0][0]})}async call(e,t,n,r){let i=this.inProcessHandlers.get(e);if(i)return i(t,n);let a=this.resolveServerForPlugin(e);if(!a.ok||!a.serverName)throw Error(a.reason??`cannot resolve backend server for plugin "${e}"`);let o=this.deps.mcpController.getMcpClient(a.serverName);if(!o)throw Error(`MCP server "${a.serverName}" for plugin "${e}" is not connected`);let s=r?.operationId?{...n,__operationId:r.operationId}:n;return o.callRaw(t,s,r?.signal)}async cancel(e,t){if(this.inProcessHandlers.has(e))return;let n=this.resolveServerForPlugin(e);if(!n.ok||!n.serverName)return;let r=this.deps.mcpController.getMcpClient(n.serverName);r&&await r.callRaw(`backend/cancel`,{id:t}).catch(()=>void 0)}subscribeState(e,t){return this.ensureNotificationSubscription(),this.stateListeners.has(e)||this.stateListeners.set(e,new Set),this.stateListeners.get(e).add(t),()=>{this.stateListeners.get(e)?.delete(t)}}onStatusChange(e,t){return this.ensureNotificationSubscription(),this.statusListeners.has(e)||this.statusListeners.set(e,new Set),this.statusListeners.get(e).add(t),()=>{this.statusListeners.get(e)?.delete(t)}}getStatus(e){if(this.inProcessHandlers.has(e))return`ready`;let t=this.resolveServerForPlugin(e);if(!t.ok||!t.serverName||this.deps.mcpController.listEffectiveServers()[t.serverName]?.disabled)return`disabled`;let n=this.deps.mcpController.getMcpClient(t.serverName);if(!n)return`crashed`;let r=n.getStatus();return r===`ready`?`ready`:r===`connecting`||r===`reconnecting`?`connecting`:`crashed`}notifyReload(){this.ensureNotificationSubscription();for(let[e,t]of this.statusListeners){if(t.size===0)continue;let n=this.getStatus(e);for(let e of t)e(n)}}ensureNotificationSubscription(){let e=this.deps.mcpController.manager;if(this.subscribedManager===e||(this.subscribedManager=e,!e))return;e.on(`server.notification`,({name:e,method:t,params:n})=>{if(t!==`backend/state`)return;let r=this.pluginIdForServer(e);if(!r)return;let i=this.stateListeners.get(r);if(!(!i||i.size===0))for(let e of i)e(n??{})});let t=e=>{let t=this.pluginIdForServer(e);if(!t)return;let n=this.statusListeners.get(t);if(!n||n.size===0)return;let r=this.getStatus(t);for(let e of n)e(r)};e.on(`server.connected`,({name:e})=>t(e)),e.on(`server.disconnected`,({name:e})=>t(e))}pluginIdForServer(e){return this.deps.mcpController.listEffectiveServers()[e]?.pluginId}};const $s=S(`@x-otto/coding:plugin-log-writer`);function ec(){return x(n,`plugin-logs`)}function tc(e){return Sn.test(e)?b(ec(),`${e}.jsonl`):($s.warn({pluginId:e},`plugin id failed kebab-case validation, skipping log path resolution`),null)}function nc(e){let t;try{t=Jr(e).size}catch{return}if(!(t<=5242880))try{let t=O(e,`utf8`),n=Math.floor(t.length/2),r=t.indexOf(`
|
|
12
|
+
`}),a.onExit(r=>{clearTimeout(o);let{stdout:i,stderr:a,truncated:l}=Es(s,c),u={success:r.code===0&&r.signal===null,hook:`setup`,command:t,exitCode:r.code,signal:r.signal??void 0,stdout:i,stderr:a,truncated:l||void 0};u.success?A.info({pluginId:e.pluginId},`Setup hook succeeded`):A.error({pluginId:e.pluginId,exitCode:r.code,signal:r.signal,stderr:a?.slice(0,512)},`Setup hook failed`),n?.(u)}),a.onError(r=>{A.error({pluginId:e.pluginId,err:r},`Setup hook spawn error`),n?.({success:!1,hook:`setup`,command:t,error:r.message})});return}let o=Ti(t,{cwd:e.pluginDir,env:ws(e),shell:!0,timeout:6e4,stdio:`pipe`}),s=``,c=``;o.stdout?.on(`data`,e=>{s+=e.toString(`utf-8`)}),o.stderr?.on(`data`,e=>{c+=e.toString(`utf-8`)}),o.on(`close`,(r,i)=>{let{stdout:a,stderr:o,truncated:l}=Es(s,c),u={success:r===0&&i===null,hook:`setup`,command:t,exitCode:r,signal:i,stdout:a,stderr:o,truncated:l||void 0};u.success?A.info({pluginId:e.pluginId},`Setup hook succeeded`):A.error({pluginId:e.pluginId,exitCode:r,signal:i,stderr:o?.slice(0,512)},`Setup hook failed`),n?.(u)}),o.on(`error`,r=>{A.error({pluginId:e.pluginId,err:r},`Setup hook spawn error`),n?.({success:!1,hook:`setup`,command:t,error:r.message})})}const ks=S(`@x-otto/coding:plugin-lifecycle`),As=`plugin_lifecycle`,js=new Set;async function Ms(e,t,n){let r=t.get(As)?.setupDone??[],i=new Map(r.map(e=>[e.id,e.version])),a=new Set(e.map(e=>e.id));for(let e of i.keys())a.has(e)||i.delete(e);let o=!1;for(let r of e){let e=i.get(r.id),a=r.manifest.version,s=r.manifest.scripts?.setup;if(!s){(e===void 0||e!==a)&&(i.set(r.id,a),o=!0);continue}if(!(e!==void 0&&e===a)){if(T(r).gated){ks.info({pluginId:r.id},`Setup hook deferred: plugin not yet trusted`);continue}js.has(r.id)||(js.add(r.id),Os({pluginDir:r.dir,pluginId:r.id,workspaceDir:n},s,e=>{js.delete(r.id),i.set(r.id,a),Ns(t,i)},Ht))}}o&&await Ns(t,i)}async function Ns(e,t){let n=[...t].map(([e,t])=>({id:e,version:t}));await e.persist({[As]:{setupDone:n}})}function Ps(e,t){let n;try{n=Gr(t)}catch{return!1}let r;try{r=Gr(e)}catch{r=e}return r===n||r.startsWith(n+Ge)}const j=S(`@x-otto/coding:plugin-i18n-loader`),Fs=/^([a-zA-Z0-9_-]+)\.json$/;function Is(e){return Buffer.byteLength(e,`utf8`)<=En?e:`${Buffer.from(e,`utf8`).subarray(0,En).toString(`utf8`)}…`}function Ls(e,t,n){let r=new Map,i=x(t,n);if(!Ps(i,t))return j.warn({pluginId:e,i18nDir:n},`i18nDir resolves outside plugin dir, skipped`),r;let a;try{a=Ur(i)}catch{return r}let o=a.filter(e=>Fs.test(e)).sort();o.length>Tn&&(j.warn({pluginId:e,i18nDir:n,declared:o.length,limit:Tn},`plugin i18nDir declares more locale files than the per-plugin limit, truncated`),o=o.slice(0,Tn));for(let n of o){let a=Fs.exec(n)?.[1];if(!a)continue;let o=x(i,n);if(!Ps(o,t)){j.warn({pluginId:e,filename:n},`i18nDir locale file resolves outside plugin dir, skipped`);continue}let s;try{s=O(o,`utf8`)}catch(t){j.warn({pluginId:e,filename:n,err:String(t)},`i18nDir locale file read failed, skipped`);continue}if(Buffer.byteLength(s,`utf8`)>wn){j.warn({pluginId:e,filename:n,limit:wn},`i18nDir locale file exceeds byte limit, skipped`);continue}let c;try{c=JSON.parse(s)}catch(t){j.warn({pluginId:e,filename:n,err:String(t)},`i18nDir locale file is not valid JSON, skipped`);continue}if(typeof c!=`object`||!c||Array.isArray(c)){j.warn({pluginId:e,filename:n},`i18nDir locale file is not a flat object, skipped`);continue}for(let[e,t]of Object.entries(c)){if(typeof t!=`string`)continue;let n=r.get(e)??{};n[a]=t,r.set(e,n)}}return r}function Rs(e){let t=[];for(let n of e){if(T(n).gated)continue;let e=n.manifest.contributes?.i18nDir,r=n.manifest.contributes?.i18n;if(!e&&!r?.length)continue;let i=e?Ls(n.id,n.dir,e):new Map;if(r?.length)for(let e of r){let t=i.get(e.id)??{};for(let[r,i]of Object.entries(e.translations))r in t&&j.debug({pluginId:n.id,id:e.id,locale:r},`i18n inline entry overrides locale dir value`),t[r]=i;i.set(e.id,t)}let a=[...i.keys()];a.length>Cn&&(j.warn({pluginId:n.id,declared:a.length,limit:Cn},`plugin declares more i18n entries than the per-plugin limit, truncated`),a=a.slice(0,Cn));for(let e of a){let r=i.get(e);if(!r)continue;let a={};for(let[e,t]of Object.entries(r))a[e]=Is(t);t.push({pluginId:n.id,id:e,translations:a})}}return t}const zs=S(`@x-otto/coding:declarative-agents`);function Bs(e){return{...e,defaultTools:e.defaultTools?.length?Tr(e.defaultTools):e.defaultTools,disallowedTools:e.disallowedTools?.length?Tr(e.disallowedTools):e.disallowedTools}}function Vs(e,t){let n=tt(e);if(!n)return zs.warn({sourcePath:t},`Agent definition missing frontmatter, skipped`),null;let{fields:r,body:i}=n,a=r.get(`name`),o=r.get(`description`);if(!a||!o||!i)return zs.warn({sourcePath:t},`Agent definition requires name/description/body, skipped`),null;let s=$e(r.get(`tools`)),c=Number.parseInt(r.get(`maxtoolturns`)??``,10),l=Number.parseInt(r.get(`maxtoolturnextensions`)??``,10),u=r.get(`prompt-mode`),d=$e(r.get(`disallowed-tools`)),f=r.get(`allow-subagents`)===`true`?!0:r.get(`allow-subagents`)===`false`?!1:void 0;return{name:a,description:o,taskTypes:$e(r.get(`tasktypes`))??[o],capabilities:$e(r.get(`capabilities`))??[],systemPromptTemplate:i,promptMode:u===`append`||u===`replace`?u:void 0,defaultTools:s,disallowedTools:d?.length?d:void 0,preferredModelTier:r.get(`slot`)??r.get(`tier`),defaultMaxToolTurns:Number.isInteger(c)?c:void 0,defaultMaxToolTurnExtensions:Number.isInteger(l)?l:void 0,allowSubagents:f}}async function Hs(e,t){let{homedir:n}=await import(`node:os`),{join:r}=await import(`node:path`),i=t?.globalDir??r(n(),`.otto`,`agents`),a=r(e,`.otto`,`agents`),s=(t?.plugins??Vn({cwd:e,homedir:n()})).filter(e=>e.manifest.contributes?.agents!==!1).filter(e=>!T(e).gated).map(e=>({dir:r(e.dir,`agents`),claude:!1})),c=o(),l=c&&!_r(e).gated,u=[...s,...c?[{dir:r(n(),`.claude`,`agents`),claude:!0}]:[],{dir:i,claude:!1},...l?[{dir:r(e,`.claude`,`agents`),claude:!0}]:[],{dir:a,claude:!1}],d=new Map;for(let{dir:e,claude:t}of u)for(let n of await Us(e))d.set(n.name,t?Bs(n):n);let f=[...d.values()];return f.length>0&&zs.info(`Loaded %d declarative agent(s): %s`,f.length,f.map(e=>e.name).join(`, `)),f}async function Us(e){let{readFile:t,readdir:n}=await import(`node:fs/promises`),{join:r}=await import(`node:path`),i;try{i=await n(e)}catch{return[]}let a=[];for(let n of i.filter(e=>e.endsWith(`.md`)).sort()){let i=r(e,n);try{let e=Vs(await t(i,`utf-8`),i);e&&a.push(e)}catch(e){zs.warn({sourcePath:i,err:e},`Failed to read agent definition, skipped`)}}return a}const Ws=S(`@x-otto/coding:declarative-teams`),Gs=new Set([`handoff`,`sequential`,`parallel`,`hierarchical`,`router`]);function Ks(e){if(!e)return;let t=[];for(let n of e.split(`|`)){let[e,r]=n.split(/→|->/);if(e===void 0||r===void 0)continue;let i=e.split(`,`).map(e=>e.trim().toLowerCase()).filter(e=>e!==``),a=r.trim();i.length>0&&a!==``&&t.push({keywords:i,agentId:a})}return t.length>0?t:void 0}function qs(e,t){let n=tt(e);if(!n)return Ws.warn({sourcePath:t},`Team definition missing frontmatter, skipped`),null;let{fields:r}=n,i=r.get(`name`),a=r.get(`pattern`),o=$e(r.get(`agents`));if(!i||!a||!Gs.has(a)||!o||o.length===0)return Ws.warn({sourcePath:t},`Team definition requires name, valid pattern and non-empty agents, skipped`),null;let s=Number.parseInt(r.get(`maxhandoffdepth`)??``,10);return{name:i,pattern:a,agentNames:o,pipeline:$e(r.get(`pipeline`)),supervisorId:r.get(`supervisor`),entryAgentId:r.get(`entry`),routerStrategy:r.get(`router`),rules:Ks(r.get(`rules`)),maxHandoffDepth:Number.isInteger(s)?s:void 0}}async function Js(e,t){let{homedir:n}=await import(`node:os`),{join:r}=await import(`node:path`),i=t?.globalDir??r(n(),`.otto`,`teams`),a=r(e,`.otto`,`teams`),o=new Map;for(let e of[i,a])for(let t of await Ys(e))o.set(t.name,t);let s=[...o.values()];return s.length>0&&Ws.info(`Loaded %d declarative team(s): %s`,s.length,s.map(e=>e.name).join(`, `)),s}async function Ys(e){let{readFile:t,readdir:n}=await import(`node:fs/promises`),{join:r}=await import(`node:path`),i;try{i=await n(e)}catch{return[]}let a=[];for(let n of i.filter(e=>e.endsWith(`.md`)).sort()){let i=r(e,n);try{let e=qs(await t(i,`utf-8`),i);e&&a.push(e)}catch(e){Ws.warn({sourcePath:i,err:e},`Failed to read team definition, skipped`)}}return a}var Xs=class{reloadQueue=Promise.resolve();constructor(e,t,n,r,i,a,o,s,c,l){this.settings=e,this.mcp=t,this.skills=n,this.pluginModules=r,this.pluginProviders=i,this.tools=a,this.modelCatalog=o,this.workspaceDir=s,this.activePlugins=c,this.i18n=l}async reload(){let e=this.reloadQueue.then(()=>this.reloadSerial());return this.reloadQueue=e.catch(()=>void 0),e}async reloadSerial(){await this.settings.load(),Ms(this.activePlugins(),this.settings,this.workspaceDir),await this.mcp.reload(),this.skills&&(this.skills.updatePluginDirs(this.activePlugins().filter(e=>e.manifest.contributes?.skills!==!1).filter(e=>!T(e).gated).map(e=>({id:e.id,dir:b(e.dir,`skills`)}))),await this.skills.discover());let e=Rs(this.activePlugins());this.i18n.register(e);let t=(await this.modelCatalog.refresh().catch(()=>[])).reduce((e,t)=>e+(t.added??0),0),n=await Hs(this.workspaceDir,{plugins:this.activePlugins()}),r=await Js(this.workspaceDir),i=await this.pluginModules.reload(new Set(n.map(e=>e.name)));n.push(...i);let a=await this.pluginProviders.reload();return{mcpTools:this.tools.getAvailable(`full`).filter(e=>e.name.startsWith(`mcp__`)).length,models:t,agents:n.length,teamCount:r.length,agentProfiles:n,teamDeclarations:r,pendingProviderCapabilities:a.pendingCapabilityPluginIds,i18nEntries:e.length}}};const Zs=S(`@x-otto/coding:panel-backend-controller`);var Qs=class{stateListeners=new Map;statusListeners=new Map;inProcessHandlers=new Map;subscribedManager=null;constructor(e){this.deps=e}registerInProcessBackend(e,t){this.inProcessHandlers.set(e,t);let n=this.statusListeners.get(e);if(n)for(let e of n)e(`ready`)}unregisterInProcessBackend(e){this.inProcessHandlers.delete(e)}resolveServerForPlugin(e){if(this.inProcessHandlers.has(e))return{ok:!0};let t=this.deps.getActivePlugins().find(t=>t.id===e);if(!t)return{ok:!1,reason:`plugin "${e}" not found or not active`};if(!t.manifest.capabilities?.includes(`panel.backend`))return{ok:!1,reason:`plugin "${e}" does not declare capabilities:["panel.backend"]`};let n=T(t);if(n.pendingCapabilities.includes(`panel.backend`))return{ok:!1,reason:`plugin "${e}" capability "panel.backend" declared but not yet granted`};if(n.gated)return{ok:!1,reason:`plugin "${e}" is untrusted`};let r=this.deps.mcpController.listEffectiveServers(),i=Object.entries(r).filter(([,t])=>t.pluginId===e);return i.length===0?{ok:!1,reason:`plugin "${e}" has no associated MCP server`}:(i.length>1&&Zs.warn({pluginId:e,serverNames:i.map(([e])=>e)},`plugin contributes multiple MCP servers; panel backend uses the first match (multi-server routing not yet supported)`),{ok:!0,serverName:i[0][0]})}async call(e,t,n,r){let i=this.inProcessHandlers.get(e);if(i)return i(t,n);let a=this.resolveServerForPlugin(e);if(!a.ok||!a.serverName)throw Error(a.reason??`cannot resolve backend server for plugin "${e}"`);let o=this.deps.mcpController.getMcpClient(a.serverName);if(!o)throw Error(`MCP server "${a.serverName}" for plugin "${e}" is not connected`);let s=r?.operationId?{...n,__operationId:r.operationId}:n;return o.callRaw(t,s,r?.signal)}async cancel(e,t){if(this.inProcessHandlers.has(e))return;let n=this.resolveServerForPlugin(e);if(!n.ok||!n.serverName)return;let r=this.deps.mcpController.getMcpClient(n.serverName);r&&await r.callRaw(`backend/cancel`,{id:t}).catch(()=>void 0)}subscribeState(e,t){return this.ensureNotificationSubscription(),this.stateListeners.has(e)||this.stateListeners.set(e,new Set),this.stateListeners.get(e).add(t),()=>{this.stateListeners.get(e)?.delete(t)}}onStatusChange(e,t){return this.ensureNotificationSubscription(),this.statusListeners.has(e)||this.statusListeners.set(e,new Set),this.statusListeners.get(e).add(t),()=>{this.statusListeners.get(e)?.delete(t)}}getStatus(e){if(this.inProcessHandlers.has(e))return`ready`;let t=this.resolveServerForPlugin(e);if(!t.ok||!t.serverName||this.deps.mcpController.listEffectiveServers()[t.serverName]?.disabled)return`disabled`;let n=this.deps.mcpController.getMcpClient(t.serverName);if(!n)return`crashed`;let r=n.getStatus();return r===`ready`?`ready`:r===`connecting`||r===`reconnecting`?`connecting`:`crashed`}notifyReload(){this.ensureNotificationSubscription();for(let[e,t]of this.statusListeners){if(t.size===0)continue;let n=this.getStatus(e);for(let e of t)e(n)}}ensureNotificationSubscription(){let e=this.deps.mcpController.manager;if(this.subscribedManager===e||(this.subscribedManager=e,!e))return;e.on(`server.notification`,({name:e,method:t,params:n})=>{if(t!==`backend/state`)return;let r=this.pluginIdForServer(e);if(!r)return;let i=this.stateListeners.get(r);if(!(!i||i.size===0))for(let e of i)e(n??{})});let t=e=>{let t=this.pluginIdForServer(e);if(!t)return;let n=this.statusListeners.get(t);if(!n||n.size===0)return;let r=this.getStatus(t);for(let e of n)e(r)};e.on(`server.connected`,({name:e})=>t(e)),e.on(`server.disconnected`,({name:e})=>t(e))}pluginIdForServer(e){return this.deps.mcpController.listEffectiveServers()[e]?.pluginId}};const $s=S(`@x-otto/coding:plugin-log-writer`);function ec(){return x(n,`plugin-logs`)}function tc(e){return Sn.test(e)?b(ec(),`${e}.jsonl`):($s.warn({pluginId:e},`plugin id failed kebab-case validation, skipping log path resolution`),null)}function nc(e){let t;try{t=Jr(e).size}catch{return}if(!(t<=5242880))try{let t=O(e,`utf8`),n=Math.floor(t.length/2),r=t.indexOf(`
|
|
13
13
|
`,n);k(e,r>=0?t.slice(r+1):t.slice(n))}catch(t){$s.warn({path:e,err:String(t)},`plugin log truncation failed (fail-soft)`)}}function rc(e,t,n){if(!s())try{let r=tc(e);if(!r)return;let i=ec();E(i)||D(i,{recursive:!0}),nc(r),Lr(r,`${JSON.stringify({ts:Date.now(),level:t,pluginId:e,msg:n})}\n`)}catch(t){$s.warn({pluginId:e,err:String(t)},`plugin log append failed (fail-soft)`)}}const ic=S(`@x-otto/coding:plugin-tool-wiring`);function M(e,t){return`plugin:${e}:${t}`}function ac(e){let t=e.split(`:`);return t.length<3||t[0]!==`plugin`?null:t[1]||null}function oc(e){let t=e?.content;return typeof t==`string`?t:Array.isArray(t)?t.map(e=>e&&typeof e==`object`&&`text`in e?String(e.text):``).join(``):``}const N={preToolUse:`tool.execute.before`,postToolUse:`tool.execute.after`,userPromptSubmit:`chat.message.before`,sessionStart:`session.created`,stop:`stream.end`,sessionRestored:`session.restored`,sessionDeleted:`session.deleted`,sessionIdle:`session.idle`,sessionError:`session.error`,streamStart:`stream.start`,compactionPending:`compaction.before`,compactionOccurred:`compaction.after`,taskCreated:`task.created`,taskStarted:`task.started`,taskCompleted:`task.completed`,taskFailed:`task.failed`};function sc(e,t){let n=[];if(t.preToolUse){let r=t.preToolUse;n.push(y({name:M(e,`preToolUse`),timing:N.preToolUse,handle:async(t,n)=>{let i=await r({toolName:t.toolName,input:t.args});i&&(i.decision===`deny`?(n.decision=`deny`,n.cancelled=!0,n.cancelReason=i.reason??`denied by plugin ${e}`):i.decision===`ask`&&(n.decision=`ask`,n.decisionReason=i.reason??`requires approval (plugin ${e})`))}}))}if(t.postToolUse){let r=t.postToolUse;n.push(y({name:M(e,`postToolUse`),timing:N.postToolUse,handle:async e=>{await r({toolName:e.toolName,input:e.args,result:e.result})}}))}if(t.userPromptSubmit){let r=t.userPromptSubmit;n.push(y({name:M(e,`userPromptSubmit`),timing:N.userPromptSubmit,handle:async e=>{await r({prompt:oc(e.message)})}}))}if(t.sessionStart){let r=t.sessionStart;n.push(y({name:M(e,`sessionStart`),timing:N.sessionStart,handle:async()=>{await r()}}))}if(t.stop){let r=t.stop;n.push(y({name:M(e,`stop`),timing:N.stop,handle:async()=>{await r()}}))}if(t.sessionRestored){let r=t.sessionRestored;n.push(y({name:M(e,`sessionRestored`),timing:N.sessionRestored,handle:async e=>{await r({sessionId:e.sessionId})}}))}if(t.sessionDeleted){let r=t.sessionDeleted;n.push(y({name:M(e,`sessionDeleted`),timing:N.sessionDeleted,handle:async e=>{await r({sessionId:e.sessionId})}}))}if(t.sessionIdle){let r=t.sessionIdle;n.push(y({name:M(e,`sessionIdle`),timing:N.sessionIdle,handle:async e=>{await r({sessionId:e.sessionId})}}))}if(t.sessionError){let r=t.sessionError;n.push(y({name:M(e,`sessionError`),timing:N.sessionError,handle:async e=>{await r({sessionId:e.sessionId,error:e.error})}}))}if(t.streamStart){let r=t.streamStart;n.push(y({name:M(e,`streamStart`),timing:N.streamStart,handle:async e=>{await r({sessionId:e.sessionId,model:e.model})}}))}if(t.compactionPending){let r=t.compactionPending;n.push(y({name:M(e,`compactionPending`),timing:N.compactionPending,handle:async e=>{await r({sessionId:e.sessionId,messageCount:e.messageCount})}}))}if(t.compactionOccurred){let r=t.compactionOccurred;n.push(y({name:M(e,`compactionOccurred`),timing:N.compactionOccurred,handle:async e=>{await r({sessionId:e.sessionId,retainedCount:e.retainedCount})}}))}if(t.taskCreated){let r=t.taskCreated;n.push(y({name:M(e,`taskCreated`),timing:N.taskCreated,handle:async e=>{await r({taskId:e.task.id})}}))}if(t.taskStarted){let r=t.taskStarted;n.push(y({name:M(e,`taskStarted`),timing:N.taskStarted,handle:async e=>{await r({taskId:e.task.id,agent:e.agent})}}))}if(t.taskCompleted){let r=t.taskCompleted;n.push(y({name:M(e,`taskCompleted`),timing:N.taskCompleted,handle:async e=>{await r({taskId:e.task.id,status:e.task.status,durationMs:e.result.durationMs,tokenUsage:e.result.tokenUsage})}}))}if(t.taskFailed){let r=t.taskFailed;n.push(y({name:M(e,`taskFailed`),timing:N.taskFailed,handle:async e=>{await r({taskId:e.task.id,error:e.error.message})}}))}return n}function cc(e,t,n,r){return r.map(r=>({name:r.name,description:r.description,argumentHint:r.argumentHint,allowedTools:r.allowedTools,model:r.model,body:r.body,source:`plugin`,scope:t===`bundled`?`project`:t,pluginId:e,filePath:`${n}#computed:${r.name}`}))}function lc(e){return e.map(e=>({name:e.name,description:e.description,taskTypes:e.taskTypes??[],capabilities:e.capabilities??[],systemPromptTemplate:e.systemPromptTemplate,...e.promptMode?{promptMode:e.promptMode}:{},...e.defaultTools?{defaultTools:e.defaultTools}:{},...e.disallowedTools?{disallowedTools:e.disallowedTools}:{},...e.preferredModelTier?{preferredModelTier:e.preferredModelTier}:{},...e.allowSubagents===void 0?{}:{allowSubagents:e.allowSubagents}}))}function uc(e,t,n){return n.map(n=>({definition:{metadata:{name:n.name,description:n.description??``},body:n.body,directory:t,filePath:`${t}#computed:${n.name}`,supportingFiles:[]},source:{type:`plugin`,root:t,id:e}}))}function dc(e,t){return t instanceof Ke?t.pluginSource===void 0?new t.constructor(t.message,{code:t.code,cause:t.cause,status:t.status,headers:t.headers,errorType:t.errorType,pluginSource:e}):t:new qe(t instanceof Error?t.message:String(t),{code:`PROVIDER_PLUGIN_ERROR`,cause:t instanceof Error?t:void 0,pluginSource:e})}function fc(e,t){return()=>{let n=t();return{...n,async*converse(t,r,i,a){try{for await(let o of n.converse(t,r,i,a))o.type===`error`?yield{type:`error`,error:dc(e,o.error)}:yield o}catch(t){throw dc(e,t)}}}}}function pc(e,t){try{return t()}catch(t){let n=String(t);return ic.warn({pluginId:e,err:n},`plugin oauthProviderFactory threw, skipped`),rc(e,`warn`,`oauthProviderFactory threw, skipped: ${n}`),null}}function mc(e){return e&&typeof e==`object`&&Array.isArray(e.content)?e:{content:[{type:`text`,text:typeof e==`string`?e:JSON.stringify(e??null)}]}}function hc(e,t,n){let r=t;if(!r||typeof r!=`object`)return ic.warn({pluginId:e},`plugin tool entry is not an object, skipped`),null;if(typeof r.name!=`string`||!r.name)return ic.warn({pluginId:e},`plugin tool missing valid name, skipped`),null;if(typeof r.execute!=`function`)return ic.warn({pluginId:e,tool:r.name},`plugin tool missing execute function, skipped`),null;if(!r.parameters||typeof r.parameters.safeParse!=`function`)return ic.warn({pluginId:e,tool:r.name},`plugin tool missing valid parameters.safeParse, skipped`),null;let i=r.name,a=r.description??``,o=r.parameters,s=r.execute;return{name:i,description:a,parameters:o,async execute(t){try{let r={pluginId:e,workspaceDir:n?.workspaceDir??``,logger:n?.logger??{info:()=>{},warn:()=>{},error:()=>{}},host:n?.host,signal:t.signal,storage:n?.storage},i=mc(await s(t.params,r));return i.isError?{...i,pluginSource:e}:i}catch(t){throw t instanceof Error&&Object.assign(t,{pluginSource:e}),t}}}}function gc(e,t){let n=[],r=async(t,n)=>{try{await t.onEvent(n)}catch(n){ic.warn({pluginId:e,monitorId:t.id,err:String(n)},`plugin monitor onEvent threw, isolated`)}};for(let i of t)n.push(y({name:M(e,`monitor:${i.id}:stream.end`),timing:`stream.end`,handle:async e=>{e.tokenUsage&&await r(i,{type:`turn.completed`,sessionId:e.sessionId,tokens:{input:e.tokenUsage.input,output:e.tokenUsage.output}})}})),n.push(y({name:M(e,`monitor:${i.id}:compaction.after`),timing:`compaction.after`,handle:async e=>{await r(i,{type:`compaction.occurred`,sessionId:e.sessionId,tokensSaved:0})}})),n.push(y({name:M(e,`monitor:${i.id}:session.error`),timing:`session.error`,handle:async e=>{await r(i,{type:`error`,sessionId:e.sessionId,message:e.error})}}));return n}function _c(e){return{...e}}var vc=class{stats=new Map;clock;constructor(e=()=>Date.now()){this.clock=e}ensure(e){let t=this.stats.get(e);return t||(t={pluginId:e,hookTimeouts:0,toolTimeouts:0},this.stats.set(e,t)),t}recordHookTimeout(e,t){let n=this.ensure(e);n.hookTimeouts++,n.lastTimeoutHook=t}recordToolTimeout(e){let t=this.ensure(e);t.toolTimeouts++}recordError(e,t){let n=this.ensure(e);n.lastError={message:t,timestamp:this.clock()}}query(e){let t=this.stats.get(e);return t?_c(t):{pluginId:e,hookTimeouts:0,toolTimeouts:0}}all(){return[...this.stats.values()].map(_c)}clear(){this.stats.clear()}};function yc(e){return new vc(e)}const bc=3600*1e3;function xc(){return{authorizedSessionIds:new Set,readCountThisEpoch:0,llmCountThisEpoch:0,llmCallTimes:[],notifyTimes:[]}}var Sc=class{states=new Map;constructor(e=()=>Date.now()){this.now=e}stateOf(e){let t=this.states.get(e);return t||(t=xc(),this.states.set(e,t)),t}onNotifyDelivered(e,t){let n=this.stateOf(e);n.authorizedSessionIds.add(t),n.readCountThisEpoch=0,n.llmCountThisEpoch=0}isSessionAuthorized(e,t){return this.stateOf(e).authorizedSessionIds.has(t)}tryConsumeRead(e){let t=this.stateOf(e);return t.readCountThisEpoch>=1?!1:(t.readCountThisEpoch+=1,!0)}tryConsumeLlm(e){let t=this.stateOf(e);if(t.llmCountThisEpoch>=2)return{ok:!1,reason:`epoch`};let n=this.now()-bc;return t.llmCallTimes=t.llmCallTimes.filter(e=>e>n),t.llmCallTimes.length>=30?{ok:!1,reason:`hourly`}:(t.llmCountThisEpoch+=1,t.llmCallTimes.push(this.now()),{ok:!0})}tryConsumeNotify(e){let t=this.stateOf(e),n=this.now()-bc;return t.notifyTimes=t.notifyTimes.filter(e=>e>n),t.notifyTimes.length>=20?!1:(t.notifyTimes.push(this.now()),!0)}reset(e){this.states.delete(e)}};function Cc(e){return e.kind===`session`?0:1}var wc=class{queue=[];inFlightId=null;maxPending;maxPerPlugin;ttlMs;now;constructor(e={}){this.maxPending=e.maxPending??8,this.maxPerPlugin=e.maxPerPlugin??1,this.ttlMs=e.ttlMs??3e5,this.now=e.now??Date.now}enqueue(e){if(this.sweepExpired(),this.queue.length>=this.maxPending)return{accepted:!1,reason:`queue-full`};if(e.origin.kind===`plugin`){let t=e.origin.pluginId;if(this.queue.filter(e=>e.request.origin.kind===`plugin`&&e.request.origin.pluginId===t).length>=this.maxPerPlugin)return{accepted:!1,reason:`plugin-concurrency`}}let t,n=new Promise(e=>{t=e}),r={...e,enqueuedAt:this.now()};return this.queue.push({request:r,resolve:t,dispatched:!1}),this.queue.sort((e,t)=>Cc(e.request.origin)-Cc(t.request.origin)||e.request.enqueuedAt-t.request.enqueuedAt),{accepted:!0,answer:n}}async waitForTurn(e,t=25){for(;;){if(this.takeNext()?.id===e)return!0;if(!this.queue.some(t=>t.request.id===e))return!1;await new Promise(e=>setTimeout(e,t))}}takeNext(){if(this.sweepExpired(),this.inFlightId!==null)return;let e=this.queue.find(e=>!e.dispatched);if(e)return e.dispatched=!0,this.inFlightId=e.request.id,e.request}settle(e,t){let n=this.queue.findIndex(t=>t.request.id===e);if(n===-1)return!1;let[r]=this.queue.splice(n,1);return this.inFlightId===e&&(this.inFlightId=null),r.resolve(t),!0}release(e){let t=this.queue.findIndex(t=>t.request.id===e);return t===-1?!1:(this.queue.splice(t,1),this.inFlightId===e&&(this.inFlightId=null),!0)}get hasInFlight(){return this.inFlightId!==null}get size(){return this.queue.length}sweepExpired(){let e=this.now()-this.ttlMs;for(let t=this.queue.length-1;t>=0;t--){let n=this.queue[t];n.dispatched||n.request.enqueuedAt>e||(this.queue.splice(t,1),n.resolve(Tc(n.request.question)))}}shutdown(){let e=this.queue.splice(0,this.queue.length);this.inFlightId=null;for(let t of e)t.resolve(Tc(t.request.question))}};function Tc(e){return{answer:``,acceptedRecommendation:!1,resolvedBy:`human`}}const P={start:`service.start`,started:`service.started`,stop:`service.stop`,stopped:`service.stopped`,hostCall:`service.hostCall`,hostResult:`service.hostResult`,crashed:`service.crashed`,notify:`service.notify`};function Ec(){return`const { parentPort, workerData } = require('worker_threads')
|
|
14
14
|
const __send = (m) => parentPort.postMessage(m)
|
|
15
15
|
|
|
@@ -184,7 +184,7 @@ parentPort.on('message', async (msg) => {
|
|
|
184
184
|
}
|
|
185
185
|
})
|
|
186
186
|
`}const F=S(`@x-otto/coding:plugin-service-pool`),Dc=5e3;function Oc(e){return[`--experimental-permission`,`--allow-fs-read=*`,...e?[`--allow-fs-write=${e}`]:[]]}`${Be()}`;let kc=null,Ac=null;function jc(){return Ac||(kc||=Vr(b(Be(),`otto-plugin-service-`)),Ac=b(kc,`service-entry.cjs`),k(Ac,Ec()),Ac)}function Mc(e,t){return`${e}:${t}`}var Nc=class{services=new Map;get runningKeys(){return[...this.services.entries()].filter(([,e])=>e.status===`running`).map(([e])=>e)}statusOf(e,t){return this.services.get(Mc(e,t))?.status}restartsOf(e,t){return this.services.get(Mc(e,t))?.restarts??0}notify(e,t,n){let r=this.services.get(Mc(e,t));if(!r||r.status!==`running`)return!1;try{return r.worker.postMessage({type:P.notify,notification:n}),!0}catch{return!1}}runningServiceIds(e){let t=`${e}:`;return[...this.services.entries()].filter(([e,n])=>e.startsWith(t)&&n.status===`running`).map(([e])=>e.slice(t.length))}async start(e){let t=Mc(e.pluginId,e.serviceId);return await this.stop(e.pluginId,e.serviceId),this.spawnAndStart(t,e,0)}spawnAndStart(e,t,n){return new Promise(r=>{let i;try{i=new ji(jc(),{execArgv:[...Oc(t.storageDir)]})}catch(t){F.error({key:e,err:String(t)},`failed to create service worker`),r({error:String(t)});return}i.unref();let a={worker:i,input:t,status:`starting`,restarts:n,stopping:!1};this.services.set(e,a);let o=!1,s=e=>{o||(o=!0,r(e))};i.on(`message`,t=>{this.onWorkerMessage(e,a,t,s)}),i.on(`error`,t=>{F.warn({key:e,err:String(t)},`service worker error`),a.status=`failed`,s({error:String(t)}),this.scheduleRestart(e,a)}),i.on(`exit`,()=>{a.stopping||(a.status!==`failed`&&(a.status=`failed`),s({error:`service worker exited unexpectedly`}),this.scheduleRestart(e,a))}),i.postMessage({type:P.start,compiledPath:t.compiledPath,serviceId:t.serviceId,factoryCtx:t.factoryCtx,serviceCtx:{pluginId:t.pluginId,workspaceDir:t.workspaceDir,workspaceKey:t.workspaceKey,hostCapabilities:t.hostCapabilities,storageDir:t.storageDir,hasStorageCapability:t.hasStorageCapability}})})}async onWorkerMessage(e,t,n,r){if(n.type===P.started){n.error?(t.status=`failed`,F.warn({key:e,err:n.error},`plugin service failed to start`),r({error:n.error}),this.scheduleRestart(e,t)):(t.status=`running`,F.info({key:e},`plugin service started`),r({}));return}if(n.type===P.crashed){F.warn({key:e,err:n.error},`plugin service crashed at runtime`),t.status=`failed`,this.scheduleRestart(e,t);return}if(n.type===P.hostCall){await this.dispatchHostCall(e,t,n);return}}async dispatchHostCall(e,t,n){let{callId:r,method:i,params:a}=n;if(i===`log.info`||i===`log.warn`||i===`log.error`){let e=a?.msg??``;F[i.slice(4)]({pluginId:t.input.pluginId,serviceId:t.input.serviceId},e);return}if(!r)return;let o=(e,n)=>{try{t.worker.postMessage({type:P.hostResult,callId:r,result:e,error:n})}catch{}};if(i===`startJob`){let e=t.input.bridge.startJob;if(!e){o(void 0,`capability not granted: agent.dispatch`);return}let n=a;try{o(await e({title:String(n?.title??``),prompt:String(n?.prompt??``)}))}catch(e){o(void 0,e instanceof Error?e.message:String(e))}return}if(i===`readTranscript`){let e=t.input.bridge.readTranscript;if(!e){o(void 0,`capability not granted: session.read`);return}let n=a;try{let t=typeof n?.sinceIndex==`number`?n.sinceIndex:void 0;o(await e({sessionId:String(n?.sessionId??``),sinceIndex:t}))}catch(e){o(void 0,e instanceof Error?e.message:String(e))}return}if(i===`notify`){let e=t.input.bridge.notify;if(!e){o(void 0,`capability not granted: user.notify`);return}let n=a,r=String(n?.level??`info`),i=r===`warning`||r===`error`?r:`info`;try{await e({level:i,code:String(n?.code??``),message:String(n?.message??``)}),o(void 0)}catch(e){o(void 0,e instanceof Error?e.message:String(e))}return}if(i===`ask`){o(void 0,`capability not granted: user.ask`);return}if(i===`complete`){let e=t.input.bridge.complete;if(!e){o(void 0,`capability not granted: llm.complete`);return}let n=a;try{let t=typeof n?.maxTokens==`number`?n.maxTokens:void 0;o(await e({prompt:String(n?.prompt??``),maxTokens:t}))}catch(e){o(void 0,e instanceof Error?e.message:String(e))}return}F.warn({key:e,method:i},`plugin service requested unknown host method (rejected)`),o(void 0,`unknown host method: ${String(i)}`)}scheduleRestart(e,t){if(t.stopping||t.restartTimer)return;if(t.restarts>=5){F.error({key:e,restarts:t.restarts},`plugin service exceeded restart limit, giving up (no further restarts)`),t.status=`failed`;return}let n=t.restarts+1,r=Math.min(1e3*2**(n-1),3e4);F.warn({key:e,attempt:n,delayMs:r},`restarting plugin service after crash`);let i=setTimeout(()=>{t.restartTimer=void 0;let r=this.services.get(e);!r||r.stopping||this.spawnAndStart(e,t.input,n)},r);i.unref?.(),t.restartTimer=i}async stop(e,t){let n=Mc(e,t),r=this.services.get(n);if(!r)return;r.stopping=!0,r.restartTimer&&=(clearTimeout(r.restartTimer),void 0),this.services.delete(n);let i=new Promise(e=>{let t=n=>{n?.type===P.stopped&&(r.worker.off(`message`,t),e(!0))};r.worker.on(`message`,t);try{r.worker.postMessage({type:P.stop})}catch{e(!1)}}),a=new Promise(e=>{setTimeout(()=>e(!1),Dc).unref?.()});await Promise.race([i,a])||F.warn({key:n,timeoutMs:Dc},`plugin service did not stop gracefully, terminating (state may be lost)`),r.status=`stopped`;try{await r.worker.terminate()}catch{}}async stopPlugin(e){let t=`${e}:`,n=[...this.services.keys()].filter(e=>e.startsWith(t));for(let r of n){let n=r.slice(t.length);await this.stop(e,n)}}async dispose(){let e=[...this.services.keys()];for(let t of e){let e=t.indexOf(`:`);await this.stop(t.slice(0,e),t.slice(e+1))}if(kc){try{qr(kc,{recursive:!0,force:!0})}catch{}kc=null,Ac=null}}};let Pc=null;function Fc(){return Pc||=new Nc,Pc}async function Ic(){await Pc?.dispose(),Pc=null}const Lc=[/\bsk-[A-Za-z0-9_-]{16,}/g,/\bgh[pousr]_[A-Za-z0-9]{20,}/g,/\bAKIA[0-9A-Z]{16}\b/g,/\bxox[abposr]-[A-Za-z0-9-]{10,}/g,/\bBearer\s+[A-Za-z0-9._~+/-]{20,}=*/g,/\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/g];function Rc(e){let t=e;for(let e of Lc)t=t.replace(e,`***`);return t}function zc(e){if(typeof e==`string`)return e;if(!Array.isArray(e))return``;let t=[];for(let n of e){let e=n;e?.type===`text`&&typeof e.text==`string`&&t.push(e.text)}return t.join(`
|
|
187
|
-
`)}function Bc(e){if(e.role===`user`)return e.internal?null:{role:`user`,text:Rc(zc(e.content))};if(e.role===`assistant`){let t=e.content.filter(e=>e.type===`tool_call`)[0]?.name,n={role:`assistant`,text:Rc(zc(e.content))};return t&&(n.toolName=t),n}return e.role===`tool_result`?e.internal?null:{role:`tool_result`,text:Rc(zc(e.content)),toolName:e.toolName}:null}function Vc(e,t,n){let r=Math.max(0,Math.min(t,e.length)),i=e.slice(r),a=i.length>n?i.slice(i.length-n):i,o=[];for(let e of a){let t=Bc(e);t&&o.push(t)}return{messages:o,nextIndex:e.length}}const I=S(`@x-otto/coding:plugin-module-loader`),Hc=e(import.meta.url),Uc=[`plugin.ts`,`plugin.tsx`];function Wc(e){for(let t of Uc){let n=b(e,t);if(E(n))return n}return null}const Gc={name:`otto-plugin-sdk-shim`,setup(e){e.onResolve({filter:/^@otto\/(plugin|extension)$/},()=>({path:`otto-plugin-sdk`,namespace:`otto-sdk-shim`})),e.onLoad({filter:/.*/,namespace:`otto-sdk-shim`},()=>({contents:`export const definePlugin = (f) => f;`,loader:`js`}))}};function Kc(){let e={};try{let t=Ve(Mi(import.meta.resolve(`@x-otto/shared`))),n=Hc.resolve(`pino`,{paths:[t]});e.pino=n,e[`thread-stream`]=Hc.resolve(`thread-stream`,{paths:[Ve(n)]}),e[`jsonc-parser`]=Hc.resolve(`jsonc-parser`,{paths:[t]})}catch(e){I.warn({err:String(e)},`failed to pre-resolve pino/thread-stream/jsonc-parser absolute paths, falling back to bare-specifier external (pre-fix behavior)`)}return e}function qc(e){let t=Object.keys(e);return{name:`otto-plugin-absolute-external`,setup(n){if(t.length===0)return;let r=RegExp(`^(${t.map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)).join(`|`)})$`);n.onResolve({filter:r},t=>({path:e[t.path],external:!0}))}}}async function Jc(e){let t=Wc(e);if(!t)return null;let n=b(e,`plugin-dist`);D(n,{recursive:!0});let r=b(n,`plugin.cjs`),i=Kc(),a=[`react`,`ink`,`jsonc-parser`,`pino`,`thread-stream`].filter(e=>!(e in i)),{build:o}=Hc(`esbuild`);return await o({entryPoints:[t],outfile:r,bundle:!0,format:`cjs`,platform:`node`,external:a,jsx:`transform`,logLevel:`silent`,define:{"import.meta.url":`__otto_plugin_import_meta_url`},banner:{js:`const __otto_plugin_import_meta_url = require("url").pathToFileURL(__filename).href;`},plugins:[Gc,qc(i)]}),$c(n,e),r}const Yc=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`];function Xc(e){let t=[],n=r=>{let i;try{i=Ur(r,{withFileTypes:!0})}catch{return}for(let a of i){let i=a.name;if(i===`plugin-dist`||i===`panels-dist`||i===`node_modules`||i.startsWith(`.`))continue;let o=b(r,i);if(a.isDirectory())n(o);else if(a.isFile()){let n=i.lastIndexOf(`.`),r=n>=0?i.slice(n):``;Yc.includes(r)&&t.push(We(e,o))}}};return n(e),t.sort()}function Zc(e){let t=Xc(e),n=ui(`sha256`);for(let r of t){let t=r.split(Ge).join(`/`);n.update(t),n.update(`\0`);try{n.update(O(b(e,r)))}catch(e){n.update(`<unreadable:${e instanceof Error?e.message:String(e)}>`)}n.update(`\0`)}return n.digest(`hex`)}function Qc(e){return{apiVersion:On,compilerVersion:r,sourceHash:Zc(e)}}function $c(e,t){try{let n=b(e,`meta.json`),r=b(e,`.meta.json.tmp-${process.pid}`);k(r,JSON.stringify(Qc(t))),Kr(r,n)}catch(e){I.warn(`Failed to write plugin artifact meta: %s`,e instanceof Error?e.message:String(e))}}function el(e){try{let t=O(b(e,`plugin-dist`,`meta.json`),`utf8`),n=JSON.parse(t),r=Qc(e);return n.apiVersion===r.apiVersion&&n.compilerVersion===r.compilerVersion&&n.sourceHash===r.sourceHash}catch{return!1}}function tl(e){let t=b(e,`plugin-dist`,`plugin.cjs`);return E(t)?el(e)?t:(I.info(`Plugin artifact at %s is stale (meta mismatch/missing) — recompiling`,t),null):null}async function nl(e,t,n){if(!Wc(e.dir))return null;if((e.scope===`project`||e.scope===`repository`)&&!Xn(e.dir))return I.warn({pluginId:e.id},`project/repository plugin not trusted, skipping code module (fail-closed)`),null;let r=T(e);if(r.pendingCapabilities.length>0)return I.warn({pluginId:e.id,pendingCapabilities:r.pendingCapabilities},`plugin declares high-risk capabilities not yet granted, skipping code module entirely before factory execution (fail-closed, RFC-140 D3)`),null;let i=tl(e.dir);if(i)I.info({pluginId:e.id,outfile:i},`using prebuilt plugin module (RFC-150 D5, skip compile)`);else try{i=await Jc(e.dir)}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin.ts compile failed`),n?.(e.id,`compile failed: ${r}`),null}if(!i)return null;let a;try{delete Hc.cache[i];let e=Hc(i);a=e?.default??e}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin.ts load failed`),n?.(e.id,`load failed: ${r}`),null}if(typeof a!=`function`)return I.warn({pluginId:e.id},`plugin.ts default export is not a factory function`),n?.(e.id,`default export is not a factory function`),null;try{let n=await a(t);return{pluginId:e.id,module:n,compiledPath:i}}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin factory threw`),n?.(e.id,`factory threw: ${r}`),null}}const L={load:`worker.load`,loaded:`worker.loaded`,error:`worker.error`,toolExecute:`tool.execute`,toolResult:`tool.result`,toolCancel:`tool.cancel`,sigilResolve:`sigil.resolve`,sigilResult:`sigil.result`,onActivate:`worker.onActivate`,activated:`worker.activated`,onDeactivate:`worker.onDeactivate`,deactivated:`worker.deactivated`,stop:`worker.stop`,hostCall:`host.call`,hostResult:`host.result`};function rl(e){return`${e===`worker`?`const { parentPort } = require('worker_threads')
|
|
187
|
+
`)}function Bc(e){if(e.role===`user`)return e.internal?null:{role:`user`,text:Rc(zc(e.content))};if(e.role===`assistant`){let t=e.content.filter(e=>e.type===`tool_call`)[0]?.name,n={role:`assistant`,text:Rc(zc(e.content))};return t&&(n.toolName=t),n}return e.role===`tool_result`?e.internal?null:{role:`tool_result`,text:Rc(zc(e.content)),toolName:e.toolName}:null}function Vc(e,t,n){let r=Math.max(0,Math.min(t,e.length)),i=e.slice(r),a=i.length>n?i.slice(i.length-n):i,o=[];for(let e of a){let t=Bc(e);t&&o.push(t)}return{messages:o,nextIndex:e.length}}const I=S(`@x-otto/coding:plugin-module-loader`),Hc=e(import.meta.url),Uc=[`plugin.ts`,`plugin.tsx`];function Wc(e){for(let t of Uc){let n=b(e,t);if(E(n))return n}return null}const Gc={name:`otto-plugin-sdk-shim`,setup(e){e.onResolve({filter:/^@(?:x-)?otto\/(plugin|extension)$/},()=>({path:`otto-plugin-sdk`,namespace:`otto-sdk-shim`})),e.onLoad({filter:/.*/,namespace:`otto-sdk-shim`},()=>({contents:`export const definePlugin = (f) => f;`,loader:`js`}))}};function Kc(){let e={};try{let t=Ve(Mi(import.meta.resolve(`@x-otto/shared`))),n=Hc.resolve(`pino`,{paths:[t]});e.pino=n,e[`thread-stream`]=Hc.resolve(`thread-stream`,{paths:[Ve(n)]}),e[`jsonc-parser`]=Hc.resolve(`jsonc-parser`,{paths:[t]})}catch(e){I.warn({err:String(e)},`failed to pre-resolve pino/thread-stream/jsonc-parser absolute paths, falling back to bare-specifier external (pre-fix behavior)`)}return e}function qc(e){let t=Object.keys(e);return{name:`otto-plugin-absolute-external`,setup(n){if(t.length===0)return;let r=RegExp(`^(${t.map(e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)).join(`|`)})$`);n.onResolve({filter:r},t=>({path:e[t.path],external:!0}))}}}async function Jc(e){let t=Wc(e);if(!t)return null;let n=b(e,`plugin-dist`);D(n,{recursive:!0});let r=b(n,`plugin.cjs`),i=Kc(),a=[`react`,`ink`,`jsonc-parser`,`pino`,`thread-stream`].filter(e=>!(e in i)),{build:o}=Hc(`esbuild`);return await o({entryPoints:[t],outfile:r,bundle:!0,format:`cjs`,platform:`node`,external:a,jsx:`transform`,logLevel:`silent`,define:{"import.meta.url":`__otto_plugin_import_meta_url`},banner:{js:`const __otto_plugin_import_meta_url = require("url").pathToFileURL(__filename).href;`},plugins:[Gc,qc(i)]}),$c(n,e),r}const Yc=[`.ts`,`.tsx`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`];function Xc(e){let t=[],n=r=>{let i;try{i=Ur(r,{withFileTypes:!0})}catch{return}for(let a of i){let i=a.name;if(i===`plugin-dist`||i===`panels-dist`||i===`node_modules`||i.startsWith(`.`))continue;let o=b(r,i);if(a.isDirectory())n(o);else if(a.isFile()){let n=i.lastIndexOf(`.`),r=n>=0?i.slice(n):``;Yc.includes(r)&&t.push(We(e,o))}}};return n(e),t.sort()}function Zc(e){let t=Xc(e),n=ui(`sha256`);for(let r of t){let t=r.split(Ge).join(`/`);n.update(t),n.update(`\0`);try{n.update(O(b(e,r)))}catch(e){n.update(`<unreadable:${e instanceof Error?e.message:String(e)}>`)}n.update(`\0`)}return n.digest(`hex`)}function Qc(e){return{apiVersion:On,compilerVersion:r,sourceHash:Zc(e)}}function $c(e,t){try{let n=b(e,`meta.json`),r=b(e,`.meta.json.tmp-${process.pid}`);k(r,JSON.stringify(Qc(t))),Kr(r,n)}catch(e){I.warn(`Failed to write plugin artifact meta: %s`,e instanceof Error?e.message:String(e))}}function el(e){try{let t=O(b(e,`plugin-dist`,`meta.json`),`utf8`),n=JSON.parse(t),r=Qc(e);return n.apiVersion===r.apiVersion&&n.compilerVersion===r.compilerVersion&&n.sourceHash===r.sourceHash}catch{return!1}}function tl(e){let t=b(e,`plugin-dist`,`plugin.cjs`);return E(t)?el(e)?t:(I.info(`Plugin artifact at %s is stale (meta mismatch/missing) — recompiling`,t),null):null}async function nl(e,t,n){if(!Wc(e.dir))return null;if((e.scope===`project`||e.scope===`repository`)&&!Xn(e.dir))return I.warn({pluginId:e.id},`project/repository plugin not trusted, skipping code module (fail-closed)`),null;let r=T(e);if(r.pendingCapabilities.length>0)return I.warn({pluginId:e.id,pendingCapabilities:r.pendingCapabilities},`plugin declares high-risk capabilities not yet granted, skipping code module entirely before factory execution (fail-closed, RFC-140 D3)`),null;let i=tl(e.dir);if(i)I.info({pluginId:e.id,outfile:i},`using prebuilt plugin module (RFC-150 D5, skip compile)`);else try{i=await Jc(e.dir)}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin.ts compile failed`),n?.(e.id,`compile failed: ${r}`),null}if(!i)return null;let a;try{delete Hc.cache[i];let e=Hc(i);a=e?.default??e}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin.ts load failed`),n?.(e.id,`load failed: ${r}`),null}if(typeof a!=`function`)return I.warn({pluginId:e.id},`plugin.ts default export is not a factory function`),n?.(e.id,`default export is not a factory function`),null;try{let n=await a(t);return{pluginId:e.id,module:n,compiledPath:i}}catch(t){let r=String(t);return I.warn({pluginId:e.id,err:r},`plugin factory threw`),n?.(e.id,`factory threw: ${r}`),null}}const L={load:`worker.load`,loaded:`worker.loaded`,error:`worker.error`,toolExecute:`tool.execute`,toolResult:`tool.result`,toolCancel:`tool.cancel`,sigilResolve:`sigil.resolve`,sigilResult:`sigil.result`,onActivate:`worker.onActivate`,activated:`worker.activated`,onDeactivate:`worker.onDeactivate`,deactivated:`worker.deactivated`,stop:`worker.stop`,hostCall:`host.call`,hostResult:`host.result`};function rl(e){return`${e===`worker`?`const { parentPort } = require('worker_threads')
|
|
188
188
|
const __send = (m) => parentPort.postMessage(m)
|
|
189
189
|
const __onMessage = (fn) => parentPort.on('message', fn)`:`const __send = (m) => process.send(m)
|
|
190
190
|
const __onMessage = (fn) => process.on('message', fn)`}\n${`// RFC-303 M4:工具执行上下文——host/logger 经反向 RPC 代理回宿主
|
|
@@ -343,7 +343,7 @@ __onMessage(async (msg) => {
|
|
|
343
343
|
return
|
|
344
344
|
}
|
|
345
345
|
if (msg.type === '${L.stop}') { toolExecutors.clear(); pluginInstance = null; process.exit(0) }
|
|
346
|
-
})`}`}var il=class{pending=new Map;idCounter=0;boundPluginId=``;hostCallDispatcher=null;setHostCallDispatcher(e){this.hostCallDispatcher=e}constructor(e){this.adapter=e,this.adapter.onMessage(e=>{if(e.type===L.loaded){let t=this.settlePending(`__load__`);t&&t.resolve(e.module);return}if(e.type===L.error){let t=this.settlePending(`__load__`);t&&t.reject(Error(e.error??this.adapter.loadFailedMessage?.()??`plugin isolated transport load failed`));return}if(e.type===L.toolResult){let t=this.settlePending(e.id);t&&t.resolve({result:e.result,error:e.error});return}if(e.type===L.sigilResult){let t=this.settlePending(e.id);t&&t.resolve({result:e.result,error:e.error});return}if(e.type===L.activated||e.type===L.deactivated){let t=this.settlePending(e.id);t&&t.resolve({error:e.error});return}if(e.type===L.hostCall){let t=this.boundPluginId,n=this.hostCallDispatcher,r=t=>{try{this.adapter.send({type:L.hostResult,id:e.id,...t})}catch{}};if(!n){r({error:`host call dispatcher not installed (plugin host capabilities unavailable)`});return}n(t,e.method??``,e.args??[]).then(e=>r({result:e})).catch(e=>r({error:e instanceof Error?e.message:String(e)}));return}}),this.adapter.onError(e=>{this.adapter.onErrorLog?.(e),this.rejectAllPending(e)}),this.adapter.onExit(e=>{if(this.pending.size===0)return;this.adapter.onExitLog?.(e);let t=this.adapter.exitErrorMessage?.(e)??`plugin isolated transport exited unexpectedly (code ${e})`;this.rejectAllPending(Error(t))})}rejectAllPending(e){for(let[,t]of this.pending)t.type===`load`?t.reject(e):t.resolve({error:e.message});this.pending.clear(),this.adapter.unref()}syncRefState(){this.pending.size>0?this.adapter.ref():this.adapter.unref()}trackPending(e,t){this.pending.set(e,t),this.syncRefState()}settlePending(e){let t=this.pending.get(e);return t&&(this.pending.delete(e),this.syncRefState()),t}async load(e,t,n){if(this.pending.has(`__load__`))throw Error(this.adapter.alreadyLoadingMessage?.(e)??`plugin isolated transport already loading ${e}`);return this.boundPluginId=e,new Promise((r,i)=>{this.trackPending(`__load__`,{type:`load`,resolve:r,reject:i}),this.adapter.send({type:L.load,pluginId:e,compiledPath:t,ctx:n,...n.hostMethods?{hostMethods:n.hostMethods}:{}})})}async executeTool(e,t,n){let r=`tool-${++this.idCounter}`,i=n?.timeoutMs??6e4,a=n?.signal;return a?.aborted?{error:`plugin tool execution aborted`}:new Promise(n=>{let o,s,c=()=>{o!==void 0&&clearTimeout(o),s&&a&&a.removeEventListener(`abort`,s)};this.trackPending(r,{type:`tool`,resolve:e=>{c(),n(e)}});let l=e=>{let t=this.settlePending(r);if(t){try{this.adapter.send({type:L.toolCancel,id:r})}catch{}t.resolve({error:e})}};i>0&&(o=setTimeout(()=>{this.adapter.onToolTimeout?.(e,i),l(`plugin tool "${e}" timed out after ${i}ms`)},i),o.unref?.()),a&&(s=()=>l(`plugin tool execution aborted`),a.addEventListener(`abort`,s,{once:!0})),this.adapter.send({type:L.toolExecute,id:r,name:e,params:t})})}async resolveSigil(e,t,n,r){let i=`sigil-${++this.idCounter}`,a=r?.timeoutMs??6e4;return new Promise(r=>{let o;this.trackPending(i,{type:`sigil`,resolve:e=>{o!==void 0&&clearTimeout(o),r(e)}}),a>0&&(o=setTimeout(()=>{let t=this.settlePending(i);t&&t.resolve({error:`sigil resolver "${e}" timed out after ${a}ms`})},a),o.unref?.()),this.adapter.send({type:L.sigilResolve,id:i,name:e,param:t,ctx:n})})}async activate(){let e=`lifecycle-${++this.idCounter}`;return new Promise(t=>{this.trackPending(e,{type:`lifecycle`,resolve:t}),this.adapter.send({type:L.onActivate,id:e})})}async deactivate(){let e=`lifecycle-${++this.idCounter}`;return new Promise(t=>{this.trackPending(e,{type:`lifecycle`,resolve:t}),this.adapter.send({type:L.onDeactivate,id:e})})}clearPending(){this.pending.clear()}};const al=S(`@x-otto/coding:plugin-worker-pool`);let ol=null,sl=null;function cl(){return sl||(ol||=Vr(b(Be(),`otto-plugin-worker-`)),sl=b(ol,`worker-entry.cjs`),k(sl,rl(`worker`)),sl)}var ll=class extends il{worker;constructor(){let e=new ji(cl());e.unref(),super({send:t=>e.postMessage(t),onMessage:t=>e.on(`message`,e=>t(e)),onError:t=>e.on(`error`,e=>t(e)),onExit:t=>e.on(`exit`,t),ref:()=>e.ref(),unref:()=>e.unref(),onToolTimeout:(e,t)=>{al.warn({tool:e,timeoutMs:t},`plugin tool execution timed out`)},onErrorLog:e=>{al.warn({err:String(e)},`plugin worker error`)},onExitLog:e=>{al.warn({code:e},`plugin worker exited unexpectedly with pending requests`)},exitErrorMessage:e=>`plugin worker exited unexpectedly (code ${e})`,loadFailedMessage:()=>`plugin worker load failed`,alreadyLoadingMessage:e=>`plugin worker already loading ${e}`}),this.worker=e}async stop(){try{this.worker.postMessage({type:L.stop}),await this.worker.terminate()}catch{}this.clearPending(),this.worker.unref()}},ul=class{workers=new Map;maxConcurrent;hostCallDispatcher=null;constructor(e=8){this.maxConcurrent=e}setHostCallDispatcher(e){this.hostCallDispatcher=e}async load(e,t,n){if(this.workers.size>=this.maxConcurrent)return null;await this.unload(e);let r=new ll;this.hostCallDispatcher&&r.setHostCallDispatcher(this.hostCallDispatcher),this.workers.set(e,r);try{return await r.load(e,t,n)}catch(t){throw this.workers.delete(e),r.stop().catch(()=>{}),t}}async executeTool(e,t,n,r){let i=this.workers.get(e);if(!i)throw Error(`no worker for plugin ${e}`);return i.executeTool(t,n,r)}async resolveSigil(e,t,n,r,i){let a=this.workers.get(e);if(!a)throw Error(`no worker for plugin ${e}`);return a.resolveSigil(t,n,r,i)}async activate(e){let t=this.workers.get(e);if(!t)throw Error(`no worker for plugin ${e}`);return t.activate()}async deactivate(e){let t=this.workers.get(e);if(!t)throw Error(`no worker for plugin ${e}`);return t.deactivate()}async unload(e){let t=this.workers.get(e);t&&(this.workers.delete(e),await t.stop())}async dispose(){let e=[...this.workers.values()];if(this.workers.clear(),ol){try{qr(ol,{recursive:!0,force:!0})}catch{}ol=null,sl=null}await Promise.all(e.map(e=>e.stop().catch(()=>{})))}get size(){return this.workers.size}};const dl=S(`@x-otto/coding:plugin-process-pool`);let fl=null,pl=null;function ml(){return pl||(fl||=Vr(b(Be(),`otto-plugin-process-`)),pl=b(fl,`process-entry.cjs`),k(pl,rl(`process`)),pl)}var hl=class extends il{child;sandboxToDispose;constructor(e){let t=ml(),n=process.execPath,r=[t],i=n,a=r,o;if(Re()){let t=Fe({network:`deny`}),s=t.wrap({command:n,args:r,options:{timeout:0,cwd:e},projectRoot:e});i=s.command,a=s.args,o=t}else dl.warn(`No platform sandbox available for project/repository scope plugin isolation — falling back to plain child_process (still process-isolated, but without OS-level file/network constraints)`);let s=Ti(i,a,{cwd:e,stdio:[`ignore`,`ignore`,`pipe`,`ipc`]});s.unref(),super({send:e=>s.send(e),onMessage:e=>s.on(`message`,t=>e(t)),onError:e=>s.on(`error`,t=>e(t)),onExit:e=>s.on(`exit`,e),ref:()=>{s.channel?.ref(),s.stderr?.ref?.()},unref:()=>{s.channel?.unref(),s.stderr?.unref?.()},onToolTimeout:(e,t)=>{dl.warn({tool:e,timeoutMs:t},`plugin tool execution timed out (isolated process)`)},onErrorLog:e=>{dl.warn({err:String(e)},`plugin process error`)},onExitLog:e=>{dl.warn({code:e},`plugin process exited unexpectedly with pending requests`)},exitErrorMessage:e=>`plugin process exited unexpectedly (code ${e})`,loadFailedMessage:()=>`plugin process load failed`,alreadyLoadingMessage:e=>`plugin process already loading ${e}`}),this.child=s,this.sandboxToDispose=o,this.child.stderr?.on(`data`,e=>{dl.warn({stderr:e.toString().slice(0,500)},`plugin process stderr output`)}),this.child.on(`exit`,()=>{this.sandboxToDispose?.dispose().catch(()=>void 0),this.sandboxToDispose=void 0})}async stop(){try{this.child.send({type:L.stop})}catch{}try{this.child.kill()}catch{}this.clearPending()}},gl=class{processes=new Map;maxConcurrent;hostCallDispatcher=null;constructor(e=4){this.maxConcurrent=e}setHostCallDispatcher(e){this.hostCallDispatcher=e}async load(e,t,n){if(this.processes.size>=this.maxConcurrent)return null;await this.unload(e);let r=new hl(n.workspaceDir);this.hostCallDispatcher&&r.setHostCallDispatcher(this.hostCallDispatcher),this.processes.set(e,r);try{return await r.load(e,t,n)}catch(t){throw this.processes.delete(e),r.stop().catch(()=>{}),t}}async executeTool(e,t,n,r){let i=this.processes.get(e);if(!i)throw Error(`no process for plugin ${e}`);return i.executeTool(t,n,r)}async resolveSigil(e,t,n,r,i){let a=this.processes.get(e);if(!a)throw Error(`no process for plugin ${e}`);return a.resolveSigil(t,n,r,i)}async activate(e){let t=this.processes.get(e);if(!t)throw Error(`no process for plugin ${e}`);return t.activate()}async deactivate(e){let t=this.processes.get(e);if(!t)throw Error(`no process for plugin ${e}`);return t.deactivate()}async unload(e){let t=this.processes.get(e);t&&(this.processes.delete(e),await t.stop())}async dispose(){let e=[...this.processes.values()];if(this.processes.clear(),fl){try{qr(fl,{recursive:!0,force:!0})}catch{}fl=null,pl=null}await Promise.all(e.map(e=>e.stop().catch(()=>{})))}get size(){return this.processes.size}};const _l=S(`@x-otto/coding:plugin-module-loader-isolated`);let vl=null;function yl(){return vl||=new ul,vl}let bl=null;function xl(){return bl||=new gl,bl}async function Sl(){await Promise.all([vl?.dispose()??Promise.resolve(),bl?.dispose()??Promise.resolve()])}function Cl(e){return e===`project`||e===`repository`?xl():yl()}function wl(e){return!!e.manifest.capabilities?.includes(`tools`)}function Tl(e,t,n){let r={};if(t.contributions&&(r.contributions=t.contributions),t.tools.length>0&&(r.tools=t.tools.map(t=>({name:t.name,description:t.description||t.name,parameters:{safeParse(e){return t.hasParameters?{success:!0,data:e}:{success:!0,data:{}}},...t.parametersSchema===void 0?{}:{toJSONSchema:()=>t.parametersSchema}},async execute(r,i){let{result:a,error:o}=await n.executeTool(e,t.name,r,{signal:i?.signal});if(o)throw Error(o);return a&&typeof a==`object`&&Array.isArray(a.content)?a:{content:[{type:`text`,text:typeof a==`string`?a:JSON.stringify(a??null)}]}}}))),t.hasSigilProviders&&_l.warn({pluginId:e},`plugin declares sigilProviders but is loaded via the isolated path (tools capability) — dynamic @ search providers are not proxied over RPC and will be inactive; declare input.resolver without tools to use the in-process path, or use static sigilEntries`),t.sigilResolvers?.length>0){r.sigilResolvers={};for(let i of t.sigilResolvers)r.sigilResolvers[i.name]={resolve:(t,r)=>n.resolveSigil(e,i.name,t,r,{timeoutMs:i.timeoutMs}).then(e=>{if(e.error)throw Error(e.error);return e.result??``}),timeoutMs:i.timeoutMs,uiHostOnly:i.uiHostOnly}}return t.hasOnActivate&&(r.onActivate=async()=>{let{error:t}=await n.activate(e);if(t)throw Error(t)}),t.hasOnDeactivate&&(r.onDeactivate=async()=>{let{error:t}=await n.deactivate(e);if(t)throw Error(t)}),r}async function El(e,t,n,r){if((e.scope===`project`||e.scope===`repository`)&&!Xn(e.dir))return _l.warn({pluginId:e.id},`project/repository plugin not trusted, skipping isolated code module (fail-closed)`),null;let i=T(e);if(i.pendingCapabilities.length>0)return _l.warn({pluginId:e.id,pendingCapabilities:i.pendingCapabilities},`plugin declares high-risk capabilities not yet granted, skipping isolated code module before worker execution (fail-closed, RFC-140 D3)`),null;let a=n??Cl(e.scope),o;try{o=await Jc(e.dir)}catch(t){let n=String(t);return _l.warn({pluginId:e.id,err:n},`plugin.ts compile failed (isolated path)`),r?.(e.id,`compile failed: ${n}`),null}if(!o)return null;let s=[...Object.keys(t.host??{}),`listActivePlugins`];if(t.host&&Object.keys(t.host).length>0||t.listActivePlugins){let e=t.host;a.setHostCallDispatcher?.(async(n,r,i)=>{if(r===`listActivePlugins`)return t.listActivePlugins?t.listActivePlugins():[];if(!e||typeof e[r]!=`function`)throw Error(`host method '${r}' not available (not declared or not granted)`);if(!(r in e))throw Error(`host method '${r}' not in whitelist`);let a=e[r];return a(...i)})}try{let n=await a.load(e.id,o,{pluginId:t.pluginId,pluginDir:t.pluginDir,workspaceDir:t.workspaceDir,hostMethods:s,listActivePlugins:!0});if(n===null){if(e.scope===`project`||e.scope===`repository`){let t=`plugin process pool exhausted (project/repository scope requires isolated execution, refusing to downgrade to in-process)`;return _l.warn({pluginId:e.id},t),r?.(e.id,t),null}return _l.info({pluginId:e.id},`plugin worker pool exhausted, falling back to in-process load`),nl(e,t,r)}return{pluginId:e.id,module:Tl(e.id,n,a),compiledPath:o}}catch(t){let n=String(t);return _l.warn({pluginId:e.id,err:n},`plugin.ts worker load failed`),r?.(e.id,`worker load failed: ${n}`),null}}function Dl(e,t){return e.includes(`onStartup`)?!0:e.some(e=>t.has(e))}var Ol=class{axisName=`hooks`;hookNamesByPlugin=new Map;constructor(e){this.hookRegistry=e}register(e){let t=e.loaded.module.hooks;if(t){let n=sc(e.plugin.id,t);this.hookRegistry.registerAll(n);let r=this.hookNamesByPlugin.get(e.plugin.id)??[];r.push(...n.map(e=>e.name)),this.hookNamesByPlugin.set(e.plugin.id,r)}}unregister(e){let t=this.hookNamesByPlugin.get(e);if(t){for(let e of t)this.hookRegistry.unregister(e);this.hookNamesByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.hookNamesByPlugin.keys()])this.unregister(e)}},kl=class{axisName=`monitors`;hookNamesByPlugin=new Map;monitorsByPlugin=new Map;constructor(e,t){this.hookRegistry=e,this.logger=t}register(e){let t=e.loaded.module.monitors;if(!t?.length)return;if(!e.plugin.manifest.capabilities?.includes(`monitor`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares monitors but not capabilities:["monitor"], skipped (fail-closed)`);return}let n=gc(e.plugin.id,t);this.hookRegistry.registerAll(n);let r=this.hookNamesByPlugin.get(e.plugin.id)??[];r.push(...n.map(e=>e.name)),this.hookNamesByPlugin.set(e.plugin.id,r),this.monitorsByPlugin.set(e.plugin.id,t)}unregister(e){let t=this.hookNamesByPlugin.get(e);if(t){for(let e of t)this.hookRegistry.unregister(e);this.hookNamesByPlugin.delete(e)}this.monitorsByPlugin.delete(e)}unregisterAll(){for(let e of[...this.hookNamesByPlugin.keys()])this.unregister(e)}async dispatch(e){for(let[t,n]of this.monitorsByPlugin)for(let r of n)try{await r.onEvent(e)}catch(n){this.logger.warn({pluginId:t,monitorId:r.id,eventType:e.type,err:String(n)},`plugin monitor onEvent threw (host event), isolated`)}}get monitorPluginIds(){return[...this.monitorsByPlugin.keys()]}},Al=class{axisName=`feedback`;feedbackRegisteredSources=new Set;constructor(e,t){this.feedbackRegistry=e,this.logger=t}register(e){let t=e.loaded.module.feedbackProviders;if(!(!t||!this.feedbackRegistry)){if(!e.plugin.manifest.capabilities?.includes(`feedback`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares feedbackProviders but not capabilities:["feedback"], skipped (fail-closed)`);return}this.feedbackRegistry.register(t,e.plugin.id)?this.feedbackRegisteredSources.add(e.plugin.id):this.logger.warn({pluginId:e.plugin.id},`plugin feedbackProviders rejected (already registered by a different plugin)`)}}unregister(e){!this.feedbackRegistry||!this.feedbackRegisteredSources.has(e)||(this.feedbackRegistry.unregister(e),this.feedbackRegisteredSources.delete(e))}unregisterAll(){for(let e of[...this.feedbackRegisteredSources])this.unregister(e)}};const jl=S(`@x-otto/coding:plugin-sigil-loader`);function Ml(e){return e.startsWith(`!`)||e.startsWith(`#`)}function Nl(e){let t=[];for(let n of e){let e=n.manifest.contributes?.sigilEntries;if(e?.length){if(T(n).gated){jl.warn({pluginId:n.id},`plugin gated (untrusted), sigilEntries skipped`);continue}for(let r of e){if(Ml(r.value)){jl.warn({pluginId:n.id,label:r.label},`sigilEntries value starts with '!' or '#' (mode-prefix collision), skipped`);continue}t.push({label:r.label,value:r.value,kind:r.kind,description:r.description,source:n.id,resolverId:r.resolverId?`${n.id}:${r.resolverId}`:void 0})}}}return t}function Pl(e){for(let t of e)t.manifest.contributes?.inputEntries&&jl.warn({pluginId:t.id},`contributes.inputEntries is deprecated (RFC-210); migrate to contributes.sigilEntries (inline array) — the file-path form is no longer loaded`)}function Fl(e,t){let n=[];for(let[r,i]of Object.entries(t)){let t=`${e}:${r}`;typeof i==`function`?n.push({id:t,resolve:i}):i&&typeof i.resolve==`function`?n.push({id:t,resolve:i.resolve,timeoutMs:i.timeoutMs,uiHostOnly:i.uiHostOnly}):jl.warn({pluginId:e,name:r},`sigilResolvers entry is neither function nor {resolve}, skipped`)}return n}function Il(e,t){return t.map(t=>async(n,r)=>(await t(n,r)).filter(e=>!Ml(e.value)).map(t=>({...t,source:e})))}function Ll(e,t){for(let n of e)n.resolverId&&!t(n.resolverId)&&jl.warn({label:n.label,resolverId:n.resolverId,source:n.source},`sigilEntries.resolverId has no matching resolver (declared sigilResolvers missing or capability not granted) — entry will pass through unexpanded at submit`)}var Rl=class{axisName=`sigil`;sigilResolverSourcePluginIds=new Set;sigilProviderUnsubsByPlugin=new Map;constructor(e,t,n){this.sigilResolverRegistry=e,this.pluginInput=t,this.logger=n}register(e){let t=e.loaded.module.sigilResolvers,n=e.loaded.module.sigilProviders;if(t&&Object.keys(t).length>0||n?.length){if(!e.plugin.manifest.capabilities?.includes(`input.resolver`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares sigilResolvers/sigilProviders but not capabilities:["input.resolver"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`input.resolver`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "input.resolver" declared but not yet granted, skipping sigil axes (fail-closed)`);return}if(t&&this.sigilResolverRegistry){let n=Fl(e.plugin.id,t);n.length>0&&(this.sigilResolverRegistry.register(n,e.plugin.id),this.sigilResolverSourcePluginIds.add(e.plugin.id))}if(n?.length&&this.pluginInput){let t=this.sigilProviderUnsubsByPlugin.get(e.plugin.id)??[];for(let r of Il(e.plugin.id,n))t.push(this.pluginInput.registerProvider(`@`,r));this.sigilProviderUnsubsByPlugin.set(e.plugin.id,t)}if(this.sigilResolverRegistry){let t=this.sigilResolverRegistry;Ll(Nl([e.plugin]),e=>t.get(e)!==void 0)}}}unregister(e){this.sigilResolverRegistry&&this.sigilResolverSourcePluginIds.has(e)&&(this.sigilResolverRegistry.unregisterBySource(e),this.sigilResolverSourcePluginIds.delete(e));let t=this.sigilProviderUnsubsByPlugin.get(e);if(t){for(let e of t)try{e()}catch{}this.sigilProviderUnsubsByPlugin.delete(e)}}unregisterAll(){let e=new Set([...this.sigilResolverSourcePluginIds,...this.sigilProviderUnsubsByPlugin.keys()]);for(let t of e)this.unregister(t)}},zl=class{axisName=`computedCommands`;commandsByPlugin=new Map;register(e){let t=e.loaded.module.contributions?.commands;if(t?.length&&e.plugin.scope!==`builtin`){let n=this.commandsByPlugin.get(e.plugin.id)??[];n.push(...cc(e.plugin.id,e.plugin.scope,e.plugin.dir,t)),this.commandsByPlugin.set(e.plugin.id,n)}}unregister(e){this.commandsByPlugin.delete(e)}unregisterAll(){}resetForReload(){this.commandsByPlugin.clear()}getComputedCommands(){return[...this.commandsByPlugin.values()].flat()}},Bl=class{axisName=`computedAgents`;profilesByPlugin=new Map;existingAgentNames=new Set;register(e){let t=e.loaded.module.contributions?.agents;if(!t?.length)return;let n=this.profilesByPlugin.get(e.plugin.id)??[];n.push(...lc(t)),this.profilesByPlugin.set(e.plugin.id,n)}unregister(e){this.profilesByPlugin.delete(e)}unregisterAll(){}setExistingAgentNames(e){this.existingAgentNames=e}resetForReload(e){this.profilesByPlugin.clear(),this.existingAgentNames=e}getAppendedAgents(){let e=new Set(this.existingAgentNames),t=[];for(let n of this.profilesByPlugin.values())for(let r of n)e.has(r.name)||(e.add(r.name),t.push(r));return t}},Vl=class{axisName=`computedSkills`;skillNamesByPlugin=new Map;constructor(e){this.skillRegistry=e}register(e){let t=e.loaded.module.contributions?.skills;if(!t?.length||!this.skillRegistry)return;let n=this.skillNamesByPlugin.get(e.plugin.id)??[];for(let{definition:r,source:i}of uc(e.plugin.id,e.plugin.dir,t))this.skillRegistry.get(r.metadata.name)||(this.skillRegistry.register(r,i),n.push(r.metadata.name));n.length>0&&this.skillNamesByPlugin.set(e.plugin.id,n)}unregister(e){let t=this.skillNamesByPlugin.get(e);if(t){for(let e of t)this.skillRegistry?.unregister(e);this.skillNamesByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.skillNamesByPlugin.keys()])this.unregister(e)}};const R=S(`@x-otto/coding:plugin-provider-loader`);function Hl(e){let t=S(`wire-protocol:${e}`),n=e=>(t,...n)=>e(t,...n);return{debug:n(t.debug.bind(t)),info:n(t.info.bind(t)),warn:n(t.warn.bind(t)),error:n(t.error.bind(t))}}function z(e,t){return`${e}:${t}`}function Ul(e){return new Set([...(e.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0&&e.oauthRef).map(e=>e.oauthRef),...e.codeProviderIds??[]])}function Wl(e,t){let n=Ul(t);return new Set((t.contributes?.oauth??[]).map(t=>n.has(t.id)?t.id:z(e,t.id)))}function Gl(e,t){return new Set((t.contributes?.providers??[]).filter(e=>e.catalogOnly!==!0&&e.baseUrl&&e.wireApi).map(t=>t.preserveProviderId===!0?t.id:z(e,t.id)))}function Kl(e,t,n){return new Set([...n.codeProviderIds??[],...(n.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0).map(e=>e.id)]).has(t)?t:z(e,t)}function ql(e){return`code:${e}`}function Jl(e,t,n,r,i,a,o){let s=e.id.indexOf(`/`),c=s>=0?e.id.slice(s+1):e.id;return{id:e.id,name:c,api:n,provider:t,baseUrl:r,reasoning:e.reasoning??!1,input:[`text`],cost:e.cost,contextWindow:e.contextWindow,maxOutputTokens:e.maxOutput,imageConstraints:i,supportsTools:a,strengths:e.strengths,thinkingLevels:e.thinkingLevels,thinkingMode:e.thinkingMode,responseBodyPolicy:o}}function Yl(e,t,n,r,i){return(a,o)=>{let s=e.url.replace(`{baseUrl}`,r??``).replace(`{clientVersion}`,process.env.OTTO_CODEX_CLIENT_VERSION||`1.0.0`),c=e.authScheme??`bearer`,l=c===`x-api-key`||c===`auto`&&o.mode!==`oauth`?{"x-api-key":a}:{authorization:`Bearer ${a}`};return c===`auto`&&o.mode===`oauth`&&o.beta&&e.betaHeaderName&&(l[e.betaHeaderName]=o.beta),{url:s,headers:{...i,...e.headers,...l},mergeProvider:t,modelApi:n,modelIdExclude:e.modelIdExclude}}}function Xl(e,t,n,r,i,a){return()=>{let o=r.get(a);if(!o)throw new qe(`wire protocol '${a}' is not registered — is its provider plugin installed and trusted? (RFC-148)`,{code:`WIRE_PROTOCOL_NOT_REGISTERED`});return o.create({resolveAuth:()=>t.resolveAuth(n).then(e=>e??void 0),resolveBaseUrl:async()=>i,headers:e.headers,tokenDerivedHeaders:e.tokenDerivedHeaders,allowAuthHeaderOverride:e.allowAuthHeaderOverride,logger:Hl(a)})}}function Zl(e,t,n,r,i,a,o){let s=t.contributes?.oauth;if(s?.length&&n)if(t.capabilities?.includes(`provider`))for(let t of s){let s=r.has(t.id)?t.id:z(e,t.id);if(f.includes(t.id)||n.isReservedId(t.id)){a.rejected.push({id:t.id,reason:`oauth id collides with builtin reserved OAuth provider`}),R.warn({pluginId:e,oauthId:t.id},`plugin oauth id collides with builtin reserved, rejected (R3)`);continue}let c=t.name??i.get(t.id)??t.id,l=t.kind===`pkce`?Fi({...t,id:s,name:c,tokenExchangeEncoding:t.tokenExchangeEncoding??`form`,assumesLoopbackAlways:t.assumesLoopbackAlways??!1,subscriptionScoped:t.subscriptionScoped??!1}):Pi({...t,id:s,name:c,allowCustomDomain:t.allowCustomDomain??!1});if(o?.has(s))n.replace(l,e);else if(!n.register(l,e)){a.rejected.push({id:t.id,reason:`oauth registration rejected (id already claimed by another plugin or reserved)`});continue}}else{R.warn({pluginId:e},`plugin declares contributes.oauth but not capabilities:["provider"], skipped (fail-closed)`);for(let e of s)a.rejected.push({id:e.id,reason:`capability "provider" not declared`})}}function Ql(e,t,n,r,i,a){let o=t.contributes?.providers;if(!o?.length)return;if(!t.capabilities?.includes(`provider`)){R.warn({pluginId:e},`plugin declares contributes.providers but not capabilities:["provider"], skipped (fail-closed)`);for(let e of o)i.rejected.push({id:e.id,reason:`capability "provider" not declared`});return}let s=new Set;for(let t of o){if(i.registered.includes(t.id)){i.rejected.push({id:t.id,reason:`duplicate provider id in manifest`}),R.warn({pluginId:e,providerId:t.id},`duplicate provider id in manifest, second entry rejected (review F5)`);continue}if(ae(t.id)){i.rejected.push({id:t.id,reason:`reserved builtin provider id`}),R.warn({pluginId:e,providerId:t.id},`plugin provider id collides with builtin, rejected (R3)`);continue}let o=t.preserveProviderId===!0,c=o?t.id:z(e,t.id),l=o?t.id:z(e,t.id);if(t.catalogOnly===!0){let a=l;if(t.oauthRef){let n=o?t.oauthRef:z(e,t.oauthRef);if(!r?.get(n)){i.rejected.push({id:t.id,reason:`oauthRef '${t.oauthRef}' not found in current plugin's oauth table (R7)`}),R.warn({pluginId:e,providerId:t.id,oauthRef:t.oauthRef},`catalog provider oauthRef not found, rejected (R7)`);continue}a=n}if(t.envKey&&!n.authStore.registerEnvKey(l,t.envKey,e)){i.rejected.push({id:t.id,reason:`envKey registration rejected (reserved or claimed)`});continue}if(!le({id:l,name:t.name,env:t.oauthRef?void 0:t.envKey},e)){i.rejected.push({id:t.id,reason:`provider descriptor id already claimed`}),t.envKey&&n.authStore.unregisterEnvKey(l);continue}if(t.models?.length){let r=t.models.map(e=>Jl(e,a,c,t.baseUrl??``,void 0,t.supportsTools,t.responseBodyPolicy)),i=n.modelRegistry.registerWithSource(r,e);for(let t of i)R.warn({pluginId:e,modelId:t},`plugin model id collides, rejected`)}i.registered.push(t.id);continue}let u=l;if(t.oauthRef){let n=o?t.oauthRef:z(e,t.oauthRef);if(!r?.get(n)){i.rejected.push({id:t.id,reason:`oauthRef '${t.oauthRef}' not found in current plugin's oauth table (R7: cross-plugin/invalid ref rejected)`}),R.warn({pluginId:e,providerId:t.id,oauthRef:t.oauthRef},`provider oauthRef not found in current plugin oauth table, rejected (R7)`);continue}u=n,t.envKey&&R.warn({pluginId:e,providerId:t.id},`provider declares both oauthRef and envKey; ignoring envKey (R2, oauth takes priority)`)}if(t.envKey&&!t.oauthRef&&!n.authStore.registerEnvKey(l,t.envKey,e)){i.rejected.push({id:t.id,reason:`envKey registration rejected (reserved or claimed by another plugin)`});continue}let d=t.baseUrl,f=t.wireApi;if(!d||!f){i.rejected.push({id:t.id,reason:`baseUrl and wireApi required for non-catalog providers`});continue}let p=t.modelsEndpoint?Yl(t.modelsEndpoint,l,c,t.baseUrl,t.headers):void 0,m=()=>{t.oauthRef&&r&&!s.has(u)&&r.unregister(u)};if(!le({id:l,name:t.name,env:t.oauthRef?void 0:t.envKey,buildModelsRequest:p},e)){i.rejected.push({id:t.id,reason:`provider descriptor id already claimed by another plugin`}),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(l),m();continue}t.allowAuthHeaderOverride&&R.warn({pluginId:e,providerId:t.id},`provider declares allowAuthHeaderOverride: custom headers may replace auth headers (RFC-270 D3)`);let h=Xl(t,n.authStore,u,n.wireProtocolRegistry,d,f);if(!(a?.has(c)?n.providerRegistry.replacePluginProvider(c,h,e):n.providerRegistry.registerPluginProvider(c,h,e))){i.rejected.push({id:t.id,reason:`api already registered by another plugin or reserved`}),pe(l),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(l),m();continue}if(t.models?.length){let r=t.models.map(e=>Jl(e,u,c,d,t.imageConstraints,t.supportsTools,t.responseBodyPolicy)),i=n.modelRegistry.registerWithSource(r,e);for(let t of i)R.warn({pluginId:e,modelId:t},`plugin model id collides with an existing model, rejected (no silent override)`)}i.registered.push(t.id),t.oauthRef&&s.add(u)}}function $l(e,t,n,r,i){let a={registered:[],rejected:[]},o=n.authStore.oauth;return Zl(e,t,o,Ul(t),new Map((t.contributes?.providers??[]).filter(e=>e.oauthRef&&e.name).map(e=>[e.oauthRef,e.name])),a,r),Ql(e,t,n,o,a,i),a}async function eu(e,t,n,r,i){let a=n.authStore.oauth,o=Ul(t),s=t.contributes?.oauth;if(s?.length&&a)for(let t of s){let n=o.has(t.id)?t.id:z(e,t.id);r?.has(n)||a.unregister(n)}let c=t.contributes?.providers;if(c?.length){for(let t of c){let r=t.preserveProviderId===!0?t.id:z(e,t.id);pe(r),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(r)}await n.providerRegistry.unregisterBySource(e,i),n.modelRegistry.unregisterBySource(e)}}var tu=class{axisName=`oauthProviderFactories`;oauthIdsByPlugin=new Map;constructor(e,t){this.authStore=e,this.logger=t}register(e){let t=e.loaded.module.oauthProviderFactories;if(!t||!this.authStore)return;if(!e.plugin.manifest.capabilities?.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares oauthProviderFactories but not capabilities:["provider"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "provider" not yet granted, skipping oauthProviderFactories (fail-closed)`);return}let n=new Set((e.plugin.manifest.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0&&e.oauthRef).map(e=>e.oauthRef));for(let[r,i]of Object.entries(t)){let t=pc(e.plugin.id,i);if(!t)continue;let a=n.has(r)?r:z(e.plugin.id,r);if(t.id!==a){this.logger.warn({pluginId:e.plugin.id,name:r,expectedId:a,actualId:t.id},`plugin oauth provider id mismatch with manifest oauthRef/preserveProviderId, skipped`);continue}if(this.authStore.oauth.register(t,e.plugin.id)){let n=this.oauthIdsByPlugin.get(e.plugin.id)??new Set;n.add(t.id),this.oauthIdsByPlugin.set(e.plugin.id,n)}else this.logger.warn({pluginId:e.plugin.id,oauthId:t.id},`plugin oauthProviderFactory rejected (reserved or claimed)`)}}unregister(e){if(!this.authStore)return;let t=this.oauthIdsByPlugin.get(e);if(t){for(let e of t)this.authStore.oauth.unregister(e);this.oauthIdsByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.oauthIdsByPlugin.keys()])this.unregister(e)}},nu=class{axisName=`providerFactories`;providerSourcePluginIds=new Set;modelSourcePluginIds=new Set;descriptorIdsByPlugin=new Map;constructor(e,t,n){this.providerRegistry=e,this.modelRegistry=t,this.logger=n}register(e){let t=e.loaded.module.providerFactories;if(!t||!this.providerRegistry)return;if(!e.plugin.manifest.capabilities?.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares providerFactories but not capabilities:["provider"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "provider" declared but not yet granted, skipping providerFactories (fail-closed, RFC-124 C2)`);return}let n=e.plugin.manifest.codeProviderModelsEndpoints??{},r=e.plugin.manifest.codeProviderModels??{};for(let[i,a]of Object.entries(t)){let t=Kl(e.plugin.id,i,e.plugin.manifest);if(!this.providerRegistry.registerPluginProvider(t,fc(e.plugin.id,a),ql(e.plugin.id))){this.logger.warn({pluginId:e.plugin.id,api:t},`plugin providerFactory rejected (reserved builtin or claimed by another plugin)`);continue}this.providerSourcePluginIds.add(e.plugin.id);let o=n[i];if(o)if(le({id:t,buildModelsRequest:Yl(o,t,t)},ql(e.plugin.id))){let n=this.descriptorIdsByPlugin.get(e.plugin.id)??new Set;n.add(t),this.descriptorIdsByPlugin.set(e.plugin.id,n)}else this.logger.warn({pluginId:e.plugin.id,api:t},`plugin codeProviderModelsEndpoints descriptor rejected (reserved builtin or claimed by another plugin)`);let s=r[i];if(s?.models?.length&&this.modelRegistry){let n=s.models.map(e=>Jl(e,t,t,s.baseUrl,s.imageConstraints,s.supportsTools,s.responseBodyPolicy)),r=this.modelRegistry.registerWithSource(n,e.plugin.id);this.modelSourcePluginIds.add(e.plugin.id),r.length>0&&this.logger.warn({pluginId:e.plugin.id,rejectedModelIds:r},`plugin codeProviderModels contains model ids already claimed by another source, rejected`)}}}async unregister(e){this.providerRegistry&&this.providerSourcePluginIds.has(e)&&(await this.providerRegistry.unregisterBySource(ql(e)),this.providerSourcePluginIds.delete(e)),this.modelRegistry&&this.modelSourcePluginIds.has(e)&&(this.modelRegistry.unregisterBySource(e),this.modelSourcePluginIds.delete(e));let t=this.descriptorIdsByPlugin.get(e);if(t){for(let e of t)pe(e);this.descriptorIdsByPlugin.delete(e)}}async unregisterAll(){let e=new Set([...this.providerSourcePluginIds,...this.modelSourcePluginIds,...this.descriptorIdsByPlugin.keys()]);for(let t of e)await this.unregister(t)}},ru=class{axisName=`wireProtocols`;wireProtocolSourcePluginIds=new Set;cacheReportingApisByPlugin=new Map;constructor(e,t){this.wireProtocolRegistry=e,this.logger=t}register(e){let t=e.loaded.module.wireProtocols;if(!(!t||!this.wireProtocolRegistry)){if(!e.plugin.manifest.capabilities?.includes(`wire-protocol`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares wireProtocols but not capabilities:["wire-protocol"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`wire-protocol`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "wire-protocol" declared but not yet granted, skipping wireProtocols (fail-closed, RFC-124 C2 pattern)`);return}for(let[n,r]of Object.entries(t))if(this.wireProtocolRegistry.register(n,r,e.plugin.id)){if(this.wireProtocolSourcePluginIds.add(e.plugin.id),r.meta?.reportsCacheTokens){ce(n);let t=this.cacheReportingApisByPlugin.get(e.plugin.id)??new Set;t.add(n),this.cacheReportingApisByPlugin.set(e.plugin.id,t)}}else this.logger.warn({pluginId:e.plugin.id,wireApi:n},`plugin wireProtocol rejected (already registered by another plugin, first-win)`)}}unregister(e){this.wireProtocolRegistry&&this.wireProtocolSourcePluginIds.has(e)&&(this.wireProtocolRegistry.unregisterBySource(e),this.wireProtocolSourcePluginIds.delete(e));let t=this.cacheReportingApisByPlugin.get(e);if(t){for(let e of t)fe(e);this.cacheReportingApisByPlugin.delete(e)}}unregisterAll(){let e=new Set([...this.wireProtocolSourcePluginIds,...this.cacheReportingApisByPlugin.keys()]);for(let t of e)this.unregister(t)}},iu=class{axisName=`tools`;toolSourcePluginIds=new Set;constructor(e,t){this.toolRegistry=e,this.logger=t}register(e){let t=e.loaded.module.tools;if(!t?.length||!this.toolRegistry)return;if(!e.plugin.manifest.capabilities?.includes(`tools`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares tools but not capabilities:["tools"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`tools`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "tools" declared but not yet granted, skipping tools (fail-closed, RFC-124 C2)`);return}let n=this.toolRegistry,r={workspaceDir:e.workspaceDir,logger:{info:t=>this.logger.info({pluginId:e.plugin.id},t),warn:t=>this.logger.warn({pluginId:e.plugin.id},t),error:t=>this.logger.error({pluginId:e.plugin.id},t)},host:e.host,storage:e.storage},i=t.map(t=>hc(e.plugin.id,t,r)).filter(e=>e!==null).filter(t=>n.has(t.name)?(this.logger.warn({pluginId:e.plugin.id,tool:t.name},`plugin tool name collides with an existing tool, rejected (R3, no silent override)`),!1):!0);i.length>0&&(n.register(i,{preset:`full`,source:e.plugin.id}),this.toolSourcePluginIds.add(e.plugin.id))}unregister(e){!this.toolRegistry||!this.toolSourcePluginIds.has(e)||(this.toolRegistry.unregisterBySource(e),this.toolSourcePluginIds.delete(e))}unregisterAll(){for(let e of[...this.toolSourcePluginIds])this.unregister(e)}};const au=`[plugin]`;function ou(e,t,n){let r=n.name?.trim()||n.key;return`${au} ${e}:${t}:${n.key} — ${r}`}function su(e,t,n){let r=e.subscriber;return!r||r.kind!==`plugin-service`||r.pluginId!==t||r.serviceId!==n?!1:e.name.startsWith(au)}function cu(e,t,n){let r=`${au} ${t}:${n}:`;if(!e.name.startsWith(r))return;let i=e.name.slice(r.length),a=i.indexOf(` — `);if(!(a<=0))return i.slice(0,a)}function lu(e){let{port:t,logger:n,pluginId:r,serviceId:i}=e,a={added:0,updated:0,removed:0},o=new Map;for(let t of e.declared){let e=t?.key?.trim(),a=t?.cron?.trim();if(!e||!a){n.warn({pluginId:r,serviceId:i,key:t?.key},`plugin schedule subscription missing key or cron, skipped (RFC-327 D2)`);continue}if(o.has(e)){n.warn({pluginId:r,serviceId:i,key:e},`duplicate plugin schedule subscription key, later declaration ignored`);continue}o.set(e,{...t,key:e,cron:a})}let s=new Map;for(let e of t.list()){if(!su(e,r,i))continue;let t=cu(e,r,i);t!==void 0&&s.set(t,e)}for(let[e,c]of o){let o=ou(r,i,c),l=s.get(e);if(!l){try{t.add({name:o,prompt:`plugin service subscription (${r}:${i}:${e})`,cronExpression:c.cron,recurring:!0,origin:`user`,subscriber:{kind:`plugin-service`,pluginId:r,serviceId:i}}),a.added+=1}catch(t){n.warn({pluginId:r,serviceId:i,key:e,err:t instanceof Error?t.message:String(t)},`failed to register plugin schedule subscription`)}continue}(l.cronExpression!==c.cron||l.name!==o)&&t.update(l.id,{cronExpression:c.cron,name:o})&&(a.updated+=1)}for(let[e,n]of s)o.has(e)||t.remove(n.id)&&(a.removed+=1);return a}function uu(e){let{port:t,pluginId:n}=e,r=0;for(let e of t.list()){let i=e.subscriber;!i||i.kind!==`plugin-service`||i.pluginId!==n||e.name.startsWith(au)&&t.remove(e.id)&&(r+=1)}return r}var du=class{axisName=`services`;startedByPlugin=new Map;scheduleDeclarations=new Map;constructor(e){this.deps=e}async register(e){let t=e.loaded.module.services;if(!t?.length)return;if(!e.plugin.manifest.capabilities?.includes(`service`)){this.deps.logger.warn({pluginId:e.plugin.id},`plugin declares services but not capabilities:["service"], skipped (fail-closed, RFC-287 D-M3-1)`);return}if(e.verdict.pendingCapabilities.includes(`service`)){this.deps.logger.warn({pluginId:e.plugin.id},`plugin capability "service" declared but not yet granted, skipping services (fail-closed)`);return}let n=e.loaded.compiledPath;if(!n){this.deps.logger.warn({pluginId:e.plugin.id},`plugin declares services but has no compiled entry path; services need a compiled module to run in the service worker (skipped)`);return}let r=this.startedByPlugin.get(e.plugin.id)??[];for(let i of t){if(!i?.id)continue;let t=this.deps.getWorkspaceKey(),a=this.deps.hasStorageCapability(e.plugin.id),{error:o}=await this.deps.pool.start({pluginId:e.plugin.id,serviceId:i.id,compiledPath:n,workspaceDir:this.deps.workspaceDir,workspaceKey:t,factoryCtx:{pluginId:e.plugin.id,pluginDir:e.plugin.dir,workspaceDir:this.deps.workspaceDir},hostCapabilities:this.deps.hostCapabilitiesFor(e.plugin.id),storageDir:a?this.deps.storageDirFor(e.plugin.id,t):``,hasStorageCapability:a,bridge:this.deps.bridgeFor(e.plugin.id)});o&&this.deps.logger.warn({pluginId:e.plugin.id,serviceId:i.id,err:o},`plugin service failed to start`),r.push(i.id),this.scheduleDeclarations.set(`${e.plugin.id}:${i.id}`,i.schedules??[]);let s=this.deps.getSchedulePort?.();if(i.schedules?.length){if(!s)this.deps.logger.debug({pluginId:e.plugin.id,serviceId:i.id,count:i.schedules.length},`plugin declares schedule subscriptions but no scheduler in this process, skipped (RFC-327 D2 boundary)`);else if(!o){let t=lu({port:s,logger:this.deps.logger,pluginId:e.plugin.id,serviceId:i.id,declared:i.schedules});(t.added||t.updated||t.removed)&&this.deps.logger.info({pluginId:e.plugin.id,serviceId:i.id,...t},`plugin schedule subscriptions reconciled`)}}else s&&lu({port:s,logger:this.deps.logger,pluginId:e.plugin.id,serviceId:i.id,declared:[]})}r.length>0&&this.startedByPlugin.set(e.plugin.id,r)}async unregister(e){if(!this.startedByPlugin.has(e))return;this.startedByPlugin.delete(e);for(let t of[...this.scheduleDeclarations.keys()])t.startsWith(`${e}:`)&&this.scheduleDeclarations.delete(t);let t=this.deps.getSchedulePort?.();if(t){let n=uu({port:t,pluginId:e});n>0&&this.deps.logger.info({pluginId:e,removed:n},`plugin schedule subscriptions revoked`)}await this.deps.pool.stopPlugin(e)}async unregisterAll(){for(let e of[...this.startedByPlugin.keys()])await this.unregister(e)}reconcileAllSchedules(){let e=this.deps.getSchedulePort?.();if(e)for(let[t,n]of this.startedByPlugin)for(let r of n){let n=this.scheduleDeclarations.get(`${t}:${r}`);if(n===void 0)continue;let i=lu({port:e,logger:this.deps.logger,pluginId:t,serviceId:r,declared:n});(i.added||i.updated||i.removed)&&this.deps.logger.info({pluginId:t,serviceId:r,...i,source:`scheduler-ready reconcile`},`plugin schedule subscriptions reconciled (M3 scheduler-ready)`)}}};const fu=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,pu=b(n,`plugin-state`);function mu(e){let t=hu(e);try{return qr(t,{recursive:!0,force:!0}),{removed:!E(t),dir:t}}catch{return{removed:!1,dir:t}}}function hu(e){if(!fu.test(e))throw Error(`invalid pluginId for scoped storage: ${e} (must be kebab-case)`);return b(pu,e)}var gu=class{persistence;baseDir;pluginId;workspaceKey;constructor(e,t){if(this.pluginId=e,this.workspaceKey=t,!fu.test(e))throw Error(`invalid pluginId for scoped storage: ${e} (must be kebab-case)`);if(typeof t!=`string`||t.length===0||t.includes(`/`)||t.includes(`\\`)||t.includes(`..`))throw Error(`invalid workspaceKey for scoped storage: ${t}`);if(s()){this.baseDir=`:memory:/plugin-state/${e}/${t}`,this.persistence=cn({type:`memory`});return}let n=x(b(hu(e),t));D(n,{recursive:!0});let r=Gr(n),i=Gr(pu);if(r!==i&&!r.startsWith(i+`/`))throw Error(`scoped storage path escapes plugin-state root: ${r}`);this.baseDir=n,this.persistence=cn({type:`file`,baseDir:n})}async save(e,t){await this.persistence.save({id:e,data:t,version:1,metadata:{}})}async load(e){let t=await this.persistence.load(e);return t?t.data:null}delete(e){return this.persistence.delete(e)}list(){return this.persistence.list()}};function _u(e){let t=new Set([...e.manifest.codeProviderIds??[],...(e.manifest.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0).map(e=>e.id)]),n=`${e.id}:`;return e=>t.has(e)||e.startsWith(n)}function vu(e,t,n){let r=e.manifest.capabilities??[],i={},a=!1,o=n.startPluginJob;r.includes(`agent.dispatch`)&&!t.pendingCapabilities.includes(`agent.dispatch`)&&o?(i.startJob=async t=>{let r=n.getSessionId?.();if(!r)throw Error(`agent.dispatch unavailable: no active session to attach the job to`);return{jobId:o({pluginId:e.id,title:t.title,prompt:t.prompt,sessionId:r}).id}},a=!0):r.includes(`agent.dispatch`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`agent.dispatch`)},`plugin declares agent.dispatch but it is not available (not yet granted, or host provides no job dispatcher) — skipping (fail-closed, RFC-287 D2)`);let s=n.getSessionMessages,c=bu(n);r.includes(`session.read`)&&!t.pendingCapabilities.includes(`session.read`)&&s?(i.readTranscript=async t=>{if(!c.isSessionAuthorized(e.id,t.sessionId))throw Error(`session not authorized for this plugin`);let n=s(t.sessionId);if(!n)throw Error(`session not found`);if(!c.tryConsumeRead(e.id))throw Error(`readTranscript quota exceeded for this notification`);return Vc(n,t.sinceIndex??0,500)},a=!0):r.includes(`session.read`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`session.read`)},`plugin declares session.read but it is not available (not yet granted, or host provides no transcript source) — skipping (fail-closed, RFC-318 D2)`);let l=n.completeText;r.includes(`llm.complete`)&&!t.pendingCapabilities.includes(`llm.complete`)&&l?(i.complete=async t=>{if(t.prompt.length>32e3)throw Error(`prompt exceeds 32000 chars limit`);let n=c.tryConsumeLlm(e.id);if(!n.ok)throw Error(`llm.complete quota exceeded (${n.reason})`);let r=Math.min(t.maxTokens??2048,2048);return l(t.prompt,{maxTokens:r})},a=!0):r.includes(`llm.complete`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`llm.complete`)},`plugin declares llm.complete but it is not available (not yet granted, or host provides no model caller) — skipping (fail-closed, RFC-318 D2)`);let u=n.askUser;r.includes(`user.ask`)&&!t.pendingCapabilities.includes(`user.ask`)&&u?(i.ask=async t=>u(e.id,{header:String(t.header??``),question:String(t.question??``),background:String(t.background??``),recommendation:String(t.recommendation??``),...Array.isArray(t.options)?{options:t.options}:{},...t.allowFreeform===void 0?{}:{allowFreeform:!!t.allowFreeform},...t.multiSelect===void 0?{}:{multiSelect:!!t.multiSelect},...Array.isArray(t.evidence)?{evidence:t.evidence.map(String)}:{}}),a=!0):r.includes(`user.ask`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`user.ask`)},`plugin declares user.ask but it is not available (not yet granted, or host provides no UI sink) — skipping (fail-closed, RFC-344 M3)`);let d=n.notifyUser;return r.includes(`user.notify`)&&!t.pendingCapabilities.includes(`user.notify`)&&d?(i.notify=async t=>{if(!c.tryConsumeNotify(e.id)){n.logger.debug({pluginId:e.id,code:t.code},`plugin user.notify dropped: rate limit exceeded (silent by design, RFC-327 D3)`);return}let r=t.message.replace(/[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,` `).slice(0,500);d({pluginId:e.id,level:t.level,code:t.code.slice(0,120),message:r})},a=!0):r.includes(`user.notify`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`user.notify`)},`plugin declares user.notify but it is not available (not yet granted, or host provides no UI sink) — skipping (fail-closed, RFC-327 D3)`),a?i:void 0}const yu=new WeakMap;function bu(e){if(e.capabilityQuota)return e.capabilityQuota;let t=yu.get(e);return t||(t=new Sc,yu.set(e,t)),t}const xu=new Map([[`oauthProviderFactories`,`provider`],[`providerFactories`,`provider`],[`wireProtocols`,`wire-protocol`]]);function Su(e){let t=e.manifest.contributes;return!t||typeof t!=`object`?[]:Object.keys(t)}var Cu=class e{contributesSnapshot=new Map;static DEACTIVATE_TIMEOUT_MS=5e3;hooksAxis;monitorsAxis;feedbackAxis;sigilAxis;computedCommandsAxis;computedAgentsAxis;computedSkillsAxis;oauthProviderAxis;codeProviderAxis;wireProtocolAxis;toolsAxis;servicesAxis;axisHandlers;firedEvents=new Set;deferredIds=new Set;loadedModules=new Map;constructor(e){this.deps=e,this.hooksAxis=new Ol(e.hookRegistry),this.monitorsAxis=new kl(e.hookRegistry,e.logger),this.feedbackAxis=new Al(e.feedbackRegistry,e.logger),this.sigilAxis=new Rl(e.sigilResolverRegistry,e.pluginInput,e.logger),this.computedCommandsAxis=new zl,this.computedAgentsAxis=new Bl,this.computedSkillsAxis=new Vl(e.skillRegistry),this.oauthProviderAxis=new tu(e.authStore,e.logger),this.codeProviderAxis=new nu(e.providerRegistry,e.modelRegistry,e.logger),this.wireProtocolAxis=new ru(e.wireProtocolRegistry,e.logger),this.toolsAxis=new iu(e.toolRegistry,e.logger),this.servicesAxis=new du({pool:e.servicePool??Fc(),logger:e.logger,workspaceDir:e.workspaceDir,getWorkspaceKey:()=>e.getWorkspaceKey?.()??`default`,bridgeFor:t=>{let n=e.activePlugins().find(e=>e.id===t);if(!n)return{};let r=vu(n,T(n),e);if(!r)return{};let i={};return r.startJob&&(i.startJob=r.startJob),r.readTranscript&&(i.readTranscript=r.readTranscript),r.complete&&(i.complete=r.complete),r.notify&&(i.notify=r.notify),i},hostCapabilitiesFor:t=>{let n=e.activePlugins().find(e=>e.id===t);if(!n)return[];let r=vu(n,T(n),e);if(!r)return[];let i=[];return r.startJob&&i.push(`startJob`),r.readTranscript&&i.push(`readTranscript`),r.complete&&i.push(`complete`),r.notify&&i.push(`notify`),i},storageDirFor:(e,t)=>new gu(e,t).baseDir,hasStorageCapability:t=>!!e.activePlugins().find(e=>e.id===t)?.manifest.capabilities?.includes(`storage`),...e.getSchedulePort?{getSchedulePort:e.getSchedulePort}:{}}),this.axisHandlers=[this.hooksAxis,this.monitorsAxis,this.feedbackAxis,this.sigilAxis,this.computedCommandsAxis,this.computedAgentsAxis,this.computedSkillsAxis,this.oauthProviderAxis,this.codeProviderAxis,this.wireProtocolAxis,this.toolsAxis,this.servicesAxis]}get deferredPluginIds(){return this.deferredIds}emitMonitorEvent(e){return this.monitorsAxis.dispatch(e)}reconcileServiceSchedules(){this.servicesAxis.reconcileAllSchedules()}get monitorPluginIds(){return this.monitorsAxis.monitorPluginIds}async activateOn(e,t){return this.firedEvents.add(e),this.reload(t)}get commands(){return this.computedCommandsAxis.getComputedCommands()}async callOnDeactivate(t,n){let r;try{await Promise.race([n(),new Promise((n,i)=>{r=setTimeout(()=>{i(Error(`plugin "${t}" onDeactivate timed out after ${e.DEACTIVATE_TIMEOUT_MS}ms`))},e.DEACTIVATE_TIMEOUT_MS),r.unref?.()})])}catch(e){this.deps.logger.warn({pluginId:t,err:String(e)},`plugin onDeactivate failed or timed out`)}finally{r!==void 0&&clearTimeout(r)}}async unregisterAllAxes(){for(let e of this.axisHandlers)await e.unregisterAll()}async unregisterPluginAxes(e,t){let n=t?T(t):void 0;for(let r of this.axisHandlers){let i=xu.get(r.axisName);i!==void 0&&t!==void 0&&n!==void 0&&t.manifest.capabilities?.some(e=>e===i)&&!n.gated&&!n.pendingCapabilities.includes(i)||await r.unregister(e)}bu(this.deps).reset(e)}pluginSignature(e){let t=T(e),n=`${t.gated?`gated`:`ok`}:${[...t.pendingCapabilities].sort().join(`,`)}`,r=`nofile`;for(let t of[`plugin.ts`,`plugin.tsx`])try{let n=Jr(b(e.dir,t));r=`${t}:${n.mtimeMs}:${n.size}`;break}catch{}return`${JSON.stringify(e.manifest)}|${n}|${r}`}async reload(e){let t=this.deps.activePlugins(),n=new Map(t.map(e=>[e.id,e])),r=new Map(t.map(e=>[e.id,this.pluginSignature(e)])),i=[],a=new Set,o=new Set;for(let[e,t]of this.loadedModules)n.get(e)?r.get(e)!==t.signature&&(t.module.module.onDeactivate&&i.push({pluginId:e,onDeactivate:t.module.module.onDeactivate}),o.add(e)):(t.module.module.onDeactivate&&i.push({pluginId:e,onDeactivate:t.module.module.onDeactivate}),a.add(e));for(let{pluginId:e,onDeactivate:t}of i)await this.callOnDeactivate(e,t);for(let e of a)await this.unregisterPluginAxes(e,void 0),this.loadedModules.delete(e);for(let e of o)await this.unregisterPluginAxes(e,n.get(e));this.computedAgentsAxis.setExistingAgentNames(e);let s=new Set;for(let e of this.deps.activePlugins()){if(!Dl(rr(e.manifest),this.firedEvents)){s.add(e.id);continue}if(this.loadedModules.get(e.id)&&!o.has(e.id))continue;let t={pluginId:e.id,pluginDir:e.dir,workspaceDir:this.deps.workspaceDir,callMcpTool:(e,t,n)=>this.deps.callMcpTool(e,t,n),logger:{debug:t=>{this.deps.logger.debug({pluginId:e.id},t)},info:t=>{this.deps.logger.info({pluginId:e.id},t),rc(e.id,`info`,t)},warn:t=>{this.deps.logger.warn({pluginId:e.id},t),rc(e.id,`warn`,t)},error:t=>{this.deps.logger.error({pluginId:e.id},t),rc(e.id,`error`,t)}},getWireProtocol:e=>this.deps.wireProtocolRegistry?.get(e),resolveProviderCredential:(()=>{let t=_u(e);return e=>t(e)?this.deps.providerRegistry?.resolveAccessKey(e)??Promise.resolve(null):Promise.resolve(null)})(),resolveProviderAuth:(()=>{let t=_u(e);return e=>t(e)?this.deps.providerRegistry?.resolveAuth(e)??Promise.resolve(null):Promise.resolve(null)})(),host:vu(e,T(e),this.deps),listActivePlugins:()=>this.deps.activePlugins().map(e=>({id:e.id,version:e.manifest.version,capabilities:e.manifest.capabilities??[],contributes:this.contributesSnapshot.get(e.id)??Su(e)}))},n=this.deps.useIsolatedLoading!==!1&&wl(e)?await El(e,t,void 0,this.deps.onPluginLoadError):await nl(e,t,this.deps.onPluginLoadError);if(!n)continue;let i=T(e);if(i.gated){this.deps.logger.warn({pluginId:e.id},`project plugin not trusted, skipping code axes (fail-closed, RFC-124 C1)`);continue}let a;if(e.manifest.capabilities?.includes(`storage`))try{let t=this.deps.getWorkspaceKey?.()??yi;a=new gu(e.id,t)}catch(t){this.deps.logger.warn({pluginId:e.id,err:String(t)},`failed to construct scoped storage for plugin, storage capability unavailable`)}let c={plugin:e,verdict:i,loaded:n,host:vu(e,i,this.deps),workspaceDir:this.deps.workspaceDir,storage:a};for(let e of this.axisHandlers)await e.register(c);if(n.module.onActivate)try{await n.module.onActivate()}catch(t){this.deps.logger.warn({pluginId:e.id,err:String(t)},`plugin onActivate threw`)}this.contributesSnapshot.set(e.id,Su(e)),this.loadedModules.set(e.id,{module:n,manifest:e.manifest,signature:r.get(e.id)??this.pluginSignature(e)})}return this.deferredIds=s,this.computedAgentsAxis.getAppendedAgents()}async cleanup(){for(let[e,t]of this.loadedModules)t.module.module.onDeactivate&&await this.callOnDeactivate(e,t.module.module.onDeactivate);this.loadedModules.clear(),await this.unregisterAllAxes();let e=bu(this.deps);for(let t of this.deps.activePlugins())e.reset(t.id);this.firedEvents.clear()}};const wu=S(`@x-otto/coding:panel-compiler`),Tu=e(import.meta.url);function Eu(e){let t=b(e,`panels`);if(!E(t))return{compiled:[],errors:[],skipped:!0};let n;try{n=Ur(t).filter(e=>e.endsWith(`.tsx`))}catch{return{compiled:[],errors:[],skipped:!0}}if(n.length===0)return{compiled:[],errors:[],skipped:!0};let r=b(e,`panels-dist`);D(r,{recursive:!0});let i=Vr(b(Be(),`otto-panel-shims-`)),a=b(i,`react-shim.js`),o=b(i,`ink-shim.js`),s=b(i,`tui-shim.js`);k(a,`const R = globalThis.React
|
|
346
|
+
})`}`}var il=class{pending=new Map;idCounter=0;boundPluginId=``;hostCallDispatcher=null;setHostCallDispatcher(e){this.hostCallDispatcher=e}constructor(e){this.adapter=e,this.adapter.onMessage(e=>{if(e.type===L.loaded){let t=this.settlePending(`__load__`);t&&t.resolve(e.module);return}if(e.type===L.error){let t=this.settlePending(`__load__`);t&&t.reject(Error(e.error??this.adapter.loadFailedMessage?.()??`plugin isolated transport load failed`));return}if(e.type===L.toolResult){let t=this.settlePending(e.id);t&&t.resolve({result:e.result,error:e.error});return}if(e.type===L.sigilResult){let t=this.settlePending(e.id);t&&t.resolve({result:e.result,error:e.error});return}if(e.type===L.activated||e.type===L.deactivated){let t=this.settlePending(e.id);t&&t.resolve({error:e.error});return}if(e.type===L.hostCall){let t=this.boundPluginId,n=this.hostCallDispatcher,r=t=>{try{this.adapter.send({type:L.hostResult,id:e.id,...t})}catch{}};if(!n){r({error:`host call dispatcher not installed (plugin host capabilities unavailable)`});return}n(t,e.method??``,e.args??[]).then(e=>r({result:e})).catch(e=>r({error:e instanceof Error?e.message:String(e)}));return}}),this.adapter.onError(e=>{this.adapter.onErrorLog?.(e),this.rejectAllPending(e)}),this.adapter.onExit(e=>{if(this.pending.size===0)return;this.adapter.onExitLog?.(e);let t=this.adapter.exitErrorMessage?.(e)??`plugin isolated transport exited unexpectedly (code ${e})`;this.rejectAllPending(Error(t))})}rejectAllPending(e){for(let[,t]of this.pending)t.type===`load`?t.reject(e):t.resolve({error:e.message});this.pending.clear(),this.adapter.unref()}syncRefState(){this.pending.size>0?this.adapter.ref():this.adapter.unref()}trackPending(e,t){this.pending.set(e,t),this.syncRefState()}settlePending(e){let t=this.pending.get(e);return t&&(this.pending.delete(e),this.syncRefState()),t}async load(e,t,n){if(this.pending.has(`__load__`))throw Error(this.adapter.alreadyLoadingMessage?.(e)??`plugin isolated transport already loading ${e}`);return this.boundPluginId=e,new Promise((r,i)=>{this.trackPending(`__load__`,{type:`load`,resolve:r,reject:i}),this.adapter.send({type:L.load,pluginId:e,compiledPath:t,ctx:n,...n.hostMethods?{hostMethods:n.hostMethods}:{}})})}async executeTool(e,t,n){let r=`tool-${++this.idCounter}`,i=n?.timeoutMs??6e4,a=n?.signal;return a?.aborted?{error:`plugin tool execution aborted`}:new Promise(n=>{let o,s,c=()=>{o!==void 0&&clearTimeout(o),s&&a&&a.removeEventListener(`abort`,s)};this.trackPending(r,{type:`tool`,resolve:e=>{c(),n(e)}});let l=e=>{let t=this.settlePending(r);if(t){try{this.adapter.send({type:L.toolCancel,id:r})}catch{}t.resolve({error:e})}};i>0&&(o=setTimeout(()=>{this.adapter.onToolTimeout?.(e,i),l(`plugin tool "${e}" timed out after ${i}ms`)},i),o.unref?.()),a&&(s=()=>l(`plugin tool execution aborted`),a.addEventListener(`abort`,s,{once:!0})),this.adapter.send({type:L.toolExecute,id:r,name:e,params:t})})}async resolveSigil(e,t,n,r){let i=`sigil-${++this.idCounter}`,a=r?.timeoutMs??6e4;return new Promise(r=>{let o;this.trackPending(i,{type:`sigil`,resolve:e=>{o!==void 0&&clearTimeout(o),r(e)}}),a>0&&(o=setTimeout(()=>{let t=this.settlePending(i);t&&t.resolve({error:`sigil resolver "${e}" timed out after ${a}ms`})},a),o.unref?.()),this.adapter.send({type:L.sigilResolve,id:i,name:e,param:t,ctx:n})})}async activate(){let e=`lifecycle-${++this.idCounter}`;return new Promise(t=>{this.trackPending(e,{type:`lifecycle`,resolve:t}),this.adapter.send({type:L.onActivate,id:e})})}async deactivate(){let e=`lifecycle-${++this.idCounter}`;return new Promise(t=>{this.trackPending(e,{type:`lifecycle`,resolve:t}),this.adapter.send({type:L.onDeactivate,id:e})})}clearPending(){this.pending.clear()}};const al=S(`@x-otto/coding:plugin-worker-pool`);let ol=null,sl=null;function cl(){return sl||(ol||=Vr(b(Be(),`otto-plugin-worker-`)),sl=b(ol,`worker-entry.cjs`),k(sl,rl(`worker`)),sl)}var ll=class extends il{worker;constructor(){let e=new ji(cl());e.unref(),super({send:t=>e.postMessage(t),onMessage:t=>e.on(`message`,e=>t(e)),onError:t=>e.on(`error`,e=>t(e)),onExit:t=>e.on(`exit`,t),ref:()=>e.ref(),unref:()=>e.unref(),onToolTimeout:(e,t)=>{al.warn({tool:e,timeoutMs:t},`plugin tool execution timed out`)},onErrorLog:e=>{al.warn({err:String(e)},`plugin worker error`)},onExitLog:e=>{al.warn({code:e},`plugin worker exited unexpectedly with pending requests`)},exitErrorMessage:e=>`plugin worker exited unexpectedly (code ${e})`,loadFailedMessage:()=>`plugin worker load failed`,alreadyLoadingMessage:e=>`plugin worker already loading ${e}`}),this.worker=e}async stop(){try{this.worker.postMessage({type:L.stop}),await this.worker.terminate()}catch{}this.clearPending(),this.worker.unref()}},ul=class{workers=new Map;maxConcurrent;hostCallDispatcher=null;constructor(e=8){this.maxConcurrent=e}setHostCallDispatcher(e){this.hostCallDispatcher=e}async load(e,t,n){if(this.workers.size>=this.maxConcurrent)return null;await this.unload(e);let r=new ll;this.hostCallDispatcher&&r.setHostCallDispatcher(this.hostCallDispatcher),this.workers.set(e,r);try{return await r.load(e,t,n)}catch(t){throw this.workers.delete(e),r.stop().catch(()=>{}),t}}async executeTool(e,t,n,r){let i=this.workers.get(e);if(!i)throw Error(`no worker for plugin ${e}`);return i.executeTool(t,n,r)}async resolveSigil(e,t,n,r,i){let a=this.workers.get(e);if(!a)throw Error(`no worker for plugin ${e}`);return a.resolveSigil(t,n,r,i)}async activate(e){let t=this.workers.get(e);if(!t)throw Error(`no worker for plugin ${e}`);return t.activate()}async deactivate(e){let t=this.workers.get(e);if(!t)throw Error(`no worker for plugin ${e}`);return t.deactivate()}async unload(e){let t=this.workers.get(e);t&&(this.workers.delete(e),await t.stop())}async dispose(){let e=[...this.workers.values()];if(this.workers.clear(),ol){try{qr(ol,{recursive:!0,force:!0})}catch{}ol=null,sl=null}await Promise.all(e.map(e=>e.stop().catch(()=>{})))}get size(){return this.workers.size}};const dl=S(`@x-otto/coding:plugin-process-pool`);let fl=null,pl=null;function ml(){return pl||(fl||=Vr(b(Be(),`otto-plugin-process-`)),pl=b(fl,`process-entry.cjs`),k(pl,rl(`process`)),pl)}var hl=class extends il{child;sandboxToDispose;constructor(e){let t=ml(),n=process.execPath,r=[t],i=n,a=r,o;if(Re()){let t=Fe({network:`deny`}),s=t.wrap({command:n,args:r,options:{timeout:0,cwd:e},projectRoot:e});i=s.command,a=s.args,o=t}else dl.warn(`No platform sandbox available for project/repository scope plugin isolation — falling back to plain child_process (still process-isolated, but without OS-level file/network constraints)`);let s=Ti(i,a,{cwd:e,stdio:[`ignore`,`ignore`,`pipe`,`ipc`]});s.unref(),super({send:e=>s.send(e),onMessage:e=>s.on(`message`,t=>e(t)),onError:e=>s.on(`error`,t=>e(t)),onExit:e=>s.on(`exit`,e),ref:()=>{s.channel?.ref(),s.stderr?.ref?.()},unref:()=>{s.channel?.unref(),s.stderr?.unref?.()},onToolTimeout:(e,t)=>{dl.warn({tool:e,timeoutMs:t},`plugin tool execution timed out (isolated process)`)},onErrorLog:e=>{dl.warn({err:String(e)},`plugin process error`)},onExitLog:e=>{dl.warn({code:e},`plugin process exited unexpectedly with pending requests`)},exitErrorMessage:e=>`plugin process exited unexpectedly (code ${e})`,loadFailedMessage:()=>`plugin process load failed`,alreadyLoadingMessage:e=>`plugin process already loading ${e}`}),this.child=s,this.sandboxToDispose=o,this.child.stderr?.on(`data`,e=>{dl.warn({stderr:e.toString().slice(0,500)},`plugin process stderr output`)}),this.child.on(`exit`,()=>{this.sandboxToDispose?.dispose().catch(()=>void 0),this.sandboxToDispose=void 0})}async stop(){try{this.child.send({type:L.stop})}catch{}try{this.child.kill()}catch{}this.clearPending()}},gl=class{processes=new Map;maxConcurrent;hostCallDispatcher=null;constructor(e=4){this.maxConcurrent=e}setHostCallDispatcher(e){this.hostCallDispatcher=e}async load(e,t,n){if(this.processes.size>=this.maxConcurrent)return null;await this.unload(e);let r=new hl(n.workspaceDir);this.hostCallDispatcher&&r.setHostCallDispatcher(this.hostCallDispatcher),this.processes.set(e,r);try{return await r.load(e,t,n)}catch(t){throw this.processes.delete(e),r.stop().catch(()=>{}),t}}async executeTool(e,t,n,r){let i=this.processes.get(e);if(!i)throw Error(`no process for plugin ${e}`);return i.executeTool(t,n,r)}async resolveSigil(e,t,n,r,i){let a=this.processes.get(e);if(!a)throw Error(`no process for plugin ${e}`);return a.resolveSigil(t,n,r,i)}async activate(e){let t=this.processes.get(e);if(!t)throw Error(`no process for plugin ${e}`);return t.activate()}async deactivate(e){let t=this.processes.get(e);if(!t)throw Error(`no process for plugin ${e}`);return t.deactivate()}async unload(e){let t=this.processes.get(e);t&&(this.processes.delete(e),await t.stop())}async dispose(){let e=[...this.processes.values()];if(this.processes.clear(),fl){try{qr(fl,{recursive:!0,force:!0})}catch{}fl=null,pl=null}await Promise.all(e.map(e=>e.stop().catch(()=>{})))}get size(){return this.processes.size}};const _l=S(`@x-otto/coding:plugin-module-loader-isolated`);let vl=null;function yl(){return vl||=new ul,vl}let bl=null;function xl(){return bl||=new gl,bl}async function Sl(){await Promise.all([vl?.dispose()??Promise.resolve(),bl?.dispose()??Promise.resolve()])}function Cl(e){return e===`project`||e===`repository`?xl():yl()}function wl(e){return!!e.manifest.capabilities?.includes(`tools`)}function Tl(e,t,n){let r={};if(t.contributions&&(r.contributions=t.contributions),t.tools.length>0&&(r.tools=t.tools.map(t=>({name:t.name,description:t.description||t.name,parameters:{safeParse(e){return t.hasParameters?{success:!0,data:e}:{success:!0,data:{}}},...t.parametersSchema===void 0?{}:{toJSONSchema:()=>t.parametersSchema}},async execute(r,i){let{result:a,error:o}=await n.executeTool(e,t.name,r,{signal:i?.signal});if(o)throw Error(o);return a&&typeof a==`object`&&Array.isArray(a.content)?a:{content:[{type:`text`,text:typeof a==`string`?a:JSON.stringify(a??null)}]}}}))),t.hasSigilProviders&&_l.warn({pluginId:e},`plugin declares sigilProviders but is loaded via the isolated path (tools capability) — dynamic @ search providers are not proxied over RPC and will be inactive; declare input.resolver without tools to use the in-process path, or use static sigilEntries`),t.sigilResolvers?.length>0){r.sigilResolvers={};for(let i of t.sigilResolvers)r.sigilResolvers[i.name]={resolve:(t,r)=>n.resolveSigil(e,i.name,t,r,{timeoutMs:i.timeoutMs}).then(e=>{if(e.error)throw Error(e.error);return e.result??``}),timeoutMs:i.timeoutMs,uiHostOnly:i.uiHostOnly}}return t.hasOnActivate&&(r.onActivate=async()=>{let{error:t}=await n.activate(e);if(t)throw Error(t)}),t.hasOnDeactivate&&(r.onDeactivate=async()=>{let{error:t}=await n.deactivate(e);if(t)throw Error(t)}),r}async function El(e,t,n,r){if((e.scope===`project`||e.scope===`repository`)&&!Xn(e.dir))return _l.warn({pluginId:e.id},`project/repository plugin not trusted, skipping isolated code module (fail-closed)`),null;let i=T(e);if(i.pendingCapabilities.length>0)return _l.warn({pluginId:e.id,pendingCapabilities:i.pendingCapabilities},`plugin declares high-risk capabilities not yet granted, skipping isolated code module before worker execution (fail-closed, RFC-140 D3)`),null;let a=n??Cl(e.scope),o;try{o=await Jc(e.dir)}catch(t){let n=String(t);return _l.warn({pluginId:e.id,err:n},`plugin.ts compile failed (isolated path)`),r?.(e.id,`compile failed: ${n}`),null}if(!o)return null;let s=[...Object.keys(t.host??{}),`listActivePlugins`];if(t.host&&Object.keys(t.host).length>0||t.listActivePlugins){let e=t.host;a.setHostCallDispatcher?.(async(n,r,i)=>{if(r===`listActivePlugins`)return t.listActivePlugins?t.listActivePlugins():[];if(!e||typeof e[r]!=`function`)throw Error(`host method '${r}' not available (not declared or not granted)`);if(!(r in e))throw Error(`host method '${r}' not in whitelist`);let a=e[r];return a(...i)})}try{let n=await a.load(e.id,o,{pluginId:t.pluginId,pluginDir:t.pluginDir,workspaceDir:t.workspaceDir,hostMethods:s,listActivePlugins:!0});if(n===null){if(e.scope===`project`||e.scope===`repository`){let t=`plugin process pool exhausted (project/repository scope requires isolated execution, refusing to downgrade to in-process)`;return _l.warn({pluginId:e.id},t),r?.(e.id,t),null}return _l.info({pluginId:e.id},`plugin worker pool exhausted, falling back to in-process load`),nl(e,t,r)}return{pluginId:e.id,module:Tl(e.id,n,a),compiledPath:o}}catch(t){let n=String(t);return _l.warn({pluginId:e.id,err:n},`plugin.ts worker load failed`),r?.(e.id,`worker load failed: ${n}`),null}}function Dl(e,t){return e.includes(`onStartup`)?!0:e.some(e=>t.has(e))}var Ol=class{axisName=`hooks`;hookNamesByPlugin=new Map;constructor(e){this.hookRegistry=e}register(e){let t=e.loaded.module.hooks;if(t){let n=sc(e.plugin.id,t);this.hookRegistry.registerAll(n);let r=this.hookNamesByPlugin.get(e.plugin.id)??[];r.push(...n.map(e=>e.name)),this.hookNamesByPlugin.set(e.plugin.id,r)}}unregister(e){let t=this.hookNamesByPlugin.get(e);if(t){for(let e of t)this.hookRegistry.unregister(e);this.hookNamesByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.hookNamesByPlugin.keys()])this.unregister(e)}},kl=class{axisName=`monitors`;hookNamesByPlugin=new Map;monitorsByPlugin=new Map;constructor(e,t){this.hookRegistry=e,this.logger=t}register(e){let t=e.loaded.module.monitors;if(!t?.length)return;if(!e.plugin.manifest.capabilities?.includes(`monitor`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares monitors but not capabilities:["monitor"], skipped (fail-closed)`);return}let n=gc(e.plugin.id,t);this.hookRegistry.registerAll(n);let r=this.hookNamesByPlugin.get(e.plugin.id)??[];r.push(...n.map(e=>e.name)),this.hookNamesByPlugin.set(e.plugin.id,r),this.monitorsByPlugin.set(e.plugin.id,t)}unregister(e){let t=this.hookNamesByPlugin.get(e);if(t){for(let e of t)this.hookRegistry.unregister(e);this.hookNamesByPlugin.delete(e)}this.monitorsByPlugin.delete(e)}unregisterAll(){for(let e of[...this.hookNamesByPlugin.keys()])this.unregister(e)}async dispatch(e){for(let[t,n]of this.monitorsByPlugin)for(let r of n)try{await r.onEvent(e)}catch(n){this.logger.warn({pluginId:t,monitorId:r.id,eventType:e.type,err:String(n)},`plugin monitor onEvent threw (host event), isolated`)}}get monitorPluginIds(){return[...this.monitorsByPlugin.keys()]}},Al=class{axisName=`feedback`;feedbackRegisteredSources=new Set;constructor(e,t){this.feedbackRegistry=e,this.logger=t}register(e){let t=e.loaded.module.feedbackProviders;if(!(!t||!this.feedbackRegistry)){if(!e.plugin.manifest.capabilities?.includes(`feedback`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares feedbackProviders but not capabilities:["feedback"], skipped (fail-closed)`);return}this.feedbackRegistry.register(t,e.plugin.id)?this.feedbackRegisteredSources.add(e.plugin.id):this.logger.warn({pluginId:e.plugin.id},`plugin feedbackProviders rejected (already registered by a different plugin)`)}}unregister(e){!this.feedbackRegistry||!this.feedbackRegisteredSources.has(e)||(this.feedbackRegistry.unregister(e),this.feedbackRegisteredSources.delete(e))}unregisterAll(){for(let e of[...this.feedbackRegisteredSources])this.unregister(e)}};const jl=S(`@x-otto/coding:plugin-sigil-loader`);function Ml(e){return e.startsWith(`!`)||e.startsWith(`#`)}function Nl(e){let t=[];for(let n of e){let e=n.manifest.contributes?.sigilEntries;if(e?.length){if(T(n).gated){jl.warn({pluginId:n.id},`plugin gated (untrusted), sigilEntries skipped`);continue}for(let r of e){if(Ml(r.value)){jl.warn({pluginId:n.id,label:r.label},`sigilEntries value starts with '!' or '#' (mode-prefix collision), skipped`);continue}t.push({label:r.label,value:r.value,kind:r.kind,description:r.description,source:n.id,resolverId:r.resolverId?`${n.id}:${r.resolverId}`:void 0})}}}return t}function Pl(e){for(let t of e)t.manifest.contributes?.inputEntries&&jl.warn({pluginId:t.id},`contributes.inputEntries is deprecated (RFC-210); migrate to contributes.sigilEntries (inline array) — the file-path form is no longer loaded`)}function Fl(e,t){let n=[];for(let[r,i]of Object.entries(t)){let t=`${e}:${r}`;typeof i==`function`?n.push({id:t,resolve:i}):i&&typeof i.resolve==`function`?n.push({id:t,resolve:i.resolve,timeoutMs:i.timeoutMs,uiHostOnly:i.uiHostOnly}):jl.warn({pluginId:e,name:r},`sigilResolvers entry is neither function nor {resolve}, skipped`)}return n}function Il(e,t){return t.map(t=>async(n,r)=>(await t(n,r)).filter(e=>!Ml(e.value)).map(t=>({...t,source:e})))}function Ll(e,t){for(let n of e)n.resolverId&&!t(n.resolverId)&&jl.warn({label:n.label,resolverId:n.resolverId,source:n.source},`sigilEntries.resolverId has no matching resolver (declared sigilResolvers missing or capability not granted) — entry will pass through unexpanded at submit`)}var Rl=class{axisName=`sigil`;sigilResolverSourcePluginIds=new Set;sigilProviderUnsubsByPlugin=new Map;constructor(e,t,n){this.sigilResolverRegistry=e,this.pluginInput=t,this.logger=n}register(e){let t=e.loaded.module.sigilResolvers,n=e.loaded.module.sigilProviders;if(t&&Object.keys(t).length>0||n?.length){if(!e.plugin.manifest.capabilities?.includes(`input.resolver`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares sigilResolvers/sigilProviders but not capabilities:["input.resolver"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`input.resolver`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "input.resolver" declared but not yet granted, skipping sigil axes (fail-closed)`);return}if(t&&this.sigilResolverRegistry){let n=Fl(e.plugin.id,t);n.length>0&&(this.sigilResolverRegistry.register(n,e.plugin.id),this.sigilResolverSourcePluginIds.add(e.plugin.id))}if(n?.length&&this.pluginInput){let t=this.sigilProviderUnsubsByPlugin.get(e.plugin.id)??[];for(let r of Il(e.plugin.id,n))t.push(this.pluginInput.registerProvider(`@`,r));this.sigilProviderUnsubsByPlugin.set(e.plugin.id,t)}if(this.sigilResolverRegistry){let t=this.sigilResolverRegistry;Ll(Nl([e.plugin]),e=>t.get(e)!==void 0)}}}unregister(e){this.sigilResolverRegistry&&this.sigilResolverSourcePluginIds.has(e)&&(this.sigilResolverRegistry.unregisterBySource(e),this.sigilResolverSourcePluginIds.delete(e));let t=this.sigilProviderUnsubsByPlugin.get(e);if(t){for(let e of t)try{e()}catch{}this.sigilProviderUnsubsByPlugin.delete(e)}}unregisterAll(){let e=new Set([...this.sigilResolverSourcePluginIds,...this.sigilProviderUnsubsByPlugin.keys()]);for(let t of e)this.unregister(t)}},zl=class{axisName=`computedCommands`;commandsByPlugin=new Map;register(e){let t=e.loaded.module.contributions?.commands;if(t?.length&&e.plugin.scope!==`builtin`){let n=this.commandsByPlugin.get(e.plugin.id)??[];n.push(...cc(e.plugin.id,e.plugin.scope,e.plugin.dir,t)),this.commandsByPlugin.set(e.plugin.id,n)}}unregister(e){this.commandsByPlugin.delete(e)}unregisterAll(){}resetForReload(){this.commandsByPlugin.clear()}getComputedCommands(){return[...this.commandsByPlugin.values()].flat()}},Bl=class{axisName=`computedAgents`;profilesByPlugin=new Map;existingAgentNames=new Set;register(e){let t=e.loaded.module.contributions?.agents;if(!t?.length)return;let n=this.profilesByPlugin.get(e.plugin.id)??[];n.push(...lc(t)),this.profilesByPlugin.set(e.plugin.id,n)}unregister(e){this.profilesByPlugin.delete(e)}unregisterAll(){}setExistingAgentNames(e){this.existingAgentNames=e}resetForReload(e){this.profilesByPlugin.clear(),this.existingAgentNames=e}getAppendedAgents(){let e=new Set(this.existingAgentNames),t=[];for(let n of this.profilesByPlugin.values())for(let r of n)e.has(r.name)||(e.add(r.name),t.push(r));return t}},Vl=class{axisName=`computedSkills`;skillNamesByPlugin=new Map;constructor(e){this.skillRegistry=e}register(e){let t=e.loaded.module.contributions?.skills;if(!t?.length||!this.skillRegistry)return;let n=this.skillNamesByPlugin.get(e.plugin.id)??[];for(let{definition:r,source:i}of uc(e.plugin.id,e.plugin.dir,t))this.skillRegistry.get(r.metadata.name)||(this.skillRegistry.register(r,i),n.push(r.metadata.name));n.length>0&&this.skillNamesByPlugin.set(e.plugin.id,n)}unregister(e){let t=this.skillNamesByPlugin.get(e);if(t){for(let e of t)this.skillRegistry?.unregister(e);this.skillNamesByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.skillNamesByPlugin.keys()])this.unregister(e)}};const R=S(`@x-otto/coding:plugin-provider-loader`);function Hl(e){let t=S(`wire-protocol:${e}`),n=e=>(t,...n)=>e(t,...n);return{debug:n(t.debug.bind(t)),info:n(t.info.bind(t)),warn:n(t.warn.bind(t)),error:n(t.error.bind(t))}}function z(e,t){return`${e}:${t}`}function Ul(e){return new Set([...(e.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0&&e.oauthRef).map(e=>e.oauthRef),...e.codeProviderIds??[]])}function Wl(e,t){let n=Ul(t);return new Set((t.contributes?.oauth??[]).map(t=>n.has(t.id)?t.id:z(e,t.id)))}function Gl(e,t){return new Set((t.contributes?.providers??[]).filter(e=>e.catalogOnly!==!0&&e.baseUrl&&e.wireApi).map(t=>t.preserveProviderId===!0?t.id:z(e,t.id)))}function Kl(e,t,n){return new Set([...n.codeProviderIds??[],...(n.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0).map(e=>e.id)]).has(t)?t:z(e,t)}function ql(e){return`code:${e}`}function Jl(e,t,n,r,i,a,o){let s=e.id.indexOf(`/`),c=s>=0?e.id.slice(s+1):e.id;return{id:e.id,name:c,api:n,provider:t,baseUrl:r,reasoning:e.reasoning??!1,input:e.input??[`text`],cost:e.cost,contextWindow:e.contextWindow,maxOutputTokens:e.maxOutput,imageConstraints:i,supportsTools:a,strengths:e.strengths,thinkingLevels:e.thinkingLevels,thinkingMode:e.thinkingMode,responseBodyPolicy:o}}function Yl(e,t,n,r,i){return(a,o)=>{let s=e.url.replace(`{baseUrl}`,r??``).replace(`{clientVersion}`,process.env.OTTO_CODEX_CLIENT_VERSION||`1.0.0`),c=e.authScheme??`bearer`,l=c===`x-api-key`||c===`auto`&&o.mode!==`oauth`?{"x-api-key":a}:{authorization:`Bearer ${a}`};return c===`auto`&&o.mode===`oauth`&&o.beta&&e.betaHeaderName&&(l[e.betaHeaderName]=o.beta),{url:s,headers:{...i,...e.headers,...l},mergeProvider:t,modelApi:n,modelIdExclude:e.modelIdExclude}}}function Xl(e,t,n,r,i,a){return()=>{let o=r.get(a);if(!o)throw new qe(`wire protocol '${a}' is not registered — is its provider plugin installed and trusted? (RFC-148)`,{code:`WIRE_PROTOCOL_NOT_REGISTERED`});return o.create({resolveAuth:()=>t.resolveAuth(n).then(e=>e??void 0),resolveBaseUrl:async()=>i,headers:e.headers,tokenDerivedHeaders:e.tokenDerivedHeaders,allowAuthHeaderOverride:e.allowAuthHeaderOverride,logger:Hl(a)})}}function Zl(e,t,n,r,i,a,o){let s=t.contributes?.oauth;if(s?.length&&n)if(t.capabilities?.includes(`provider`))for(let t of s){let s=r.has(t.id)?t.id:z(e,t.id);if(f.includes(t.id)||n.isReservedId(t.id)){a.rejected.push({id:t.id,reason:`oauth id collides with builtin reserved OAuth provider`}),R.warn({pluginId:e,oauthId:t.id},`plugin oauth id collides with builtin reserved, rejected (R3)`);continue}let c=t.name??i.get(t.id)??t.id,l=t.kind===`pkce`?Fi({...t,id:s,name:c,tokenExchangeEncoding:t.tokenExchangeEncoding??`form`,assumesLoopbackAlways:t.assumesLoopbackAlways??!1,subscriptionScoped:t.subscriptionScoped??!1}):Pi({...t,id:s,name:c,allowCustomDomain:t.allowCustomDomain??!1});if(o?.has(s))n.replace(l,e);else if(!n.register(l,e)){a.rejected.push({id:t.id,reason:`oauth registration rejected (id already claimed by another plugin or reserved)`});continue}}else{R.warn({pluginId:e},`plugin declares contributes.oauth but not capabilities:["provider"], skipped (fail-closed)`);for(let e of s)a.rejected.push({id:e.id,reason:`capability "provider" not declared`})}}function Ql(e,t,n,r,i,a){let o=t.contributes?.providers;if(!o?.length)return;if(!t.capabilities?.includes(`provider`)){R.warn({pluginId:e},`plugin declares contributes.providers but not capabilities:["provider"], skipped (fail-closed)`);for(let e of o)i.rejected.push({id:e.id,reason:`capability "provider" not declared`});return}let s=new Set;for(let t of o){if(i.registered.includes(t.id)){i.rejected.push({id:t.id,reason:`duplicate provider id in manifest`}),R.warn({pluginId:e,providerId:t.id},`duplicate provider id in manifest, second entry rejected (review F5)`);continue}if(ae(t.id)){i.rejected.push({id:t.id,reason:`reserved builtin provider id`}),R.warn({pluginId:e,providerId:t.id},`plugin provider id collides with builtin, rejected (R3)`);continue}let o=t.preserveProviderId===!0,c=o?t.id:z(e,t.id),l=o?t.id:z(e,t.id);if(t.catalogOnly===!0){let a=l;if(t.oauthRef){let n=o?t.oauthRef:z(e,t.oauthRef);if(!r?.get(n)){i.rejected.push({id:t.id,reason:`oauthRef '${t.oauthRef}' not found in current plugin's oauth table (R7)`}),R.warn({pluginId:e,providerId:t.id,oauthRef:t.oauthRef},`catalog provider oauthRef not found, rejected (R7)`);continue}a=n}if(t.envKey&&!n.authStore.registerEnvKey(l,t.envKey,e)){i.rejected.push({id:t.id,reason:`envKey registration rejected (reserved or claimed)`});continue}if(!le({id:l,name:t.name,env:t.oauthRef?void 0:t.envKey},e)){i.rejected.push({id:t.id,reason:`provider descriptor id already claimed`}),t.envKey&&n.authStore.unregisterEnvKey(l);continue}if(t.models?.length){let r=t.models.map(e=>Jl(e,a,c,t.baseUrl??``,void 0,t.supportsTools,t.responseBodyPolicy)),i=n.modelRegistry.registerWithSource(r,e);for(let t of i)R.warn({pluginId:e,modelId:t},`plugin model id collides, rejected`)}i.registered.push(t.id);continue}let u=l;if(t.oauthRef){let n=o?t.oauthRef:z(e,t.oauthRef);if(!r?.get(n)){i.rejected.push({id:t.id,reason:`oauthRef '${t.oauthRef}' not found in current plugin's oauth table (R7: cross-plugin/invalid ref rejected)`}),R.warn({pluginId:e,providerId:t.id,oauthRef:t.oauthRef},`provider oauthRef not found in current plugin oauth table, rejected (R7)`);continue}u=n,t.envKey&&R.warn({pluginId:e,providerId:t.id},`provider declares both oauthRef and envKey; ignoring envKey (R2, oauth takes priority)`)}if(t.envKey&&!t.oauthRef&&!n.authStore.registerEnvKey(l,t.envKey,e)){i.rejected.push({id:t.id,reason:`envKey registration rejected (reserved or claimed by another plugin)`});continue}let d=t.baseUrl,f=t.wireApi;if(!d||!f){i.rejected.push({id:t.id,reason:`baseUrl and wireApi required for non-catalog providers`});continue}let p=t.modelsEndpoint?Yl(t.modelsEndpoint,l,c,t.baseUrl,t.headers):void 0,m=()=>{t.oauthRef&&r&&!s.has(u)&&r.unregister(u)};if(!le({id:l,name:t.name,env:t.oauthRef?void 0:t.envKey,buildModelsRequest:p},e)){i.rejected.push({id:t.id,reason:`provider descriptor id already claimed by another plugin`}),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(l),m();continue}t.allowAuthHeaderOverride&&R.warn({pluginId:e,providerId:t.id},`provider declares allowAuthHeaderOverride: custom headers may replace auth headers (RFC-270 D3)`);let h=Xl(t,n.authStore,u,n.wireProtocolRegistry,d,f);if(!(a?.has(c)?n.providerRegistry.replacePluginProvider(c,h,e):n.providerRegistry.registerPluginProvider(c,h,e))){i.rejected.push({id:t.id,reason:`api already registered by another plugin or reserved`}),pe(l),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(l),m();continue}if(t.models?.length){let r=t.models.map(e=>Jl(e,u,c,d,t.imageConstraints,t.supportsTools,t.responseBodyPolicy)),i=n.modelRegistry.registerWithSource(r,e);for(let t of i)R.warn({pluginId:e,modelId:t},`plugin model id collides with an existing model, rejected (no silent override)`)}i.registered.push(t.id),t.oauthRef&&s.add(u)}}function $l(e,t,n,r,i){let a={registered:[],rejected:[]},o=n.authStore.oauth;return Zl(e,t,o,Ul(t),new Map((t.contributes?.providers??[]).filter(e=>e.oauthRef&&e.name).map(e=>[e.oauthRef,e.name])),a,r),Ql(e,t,n,o,a,i),a}async function eu(e,t,n,r,i){let a=n.authStore.oauth,o=Ul(t),s=t.contributes?.oauth;if(s?.length&&a)for(let t of s){let n=o.has(t.id)?t.id:z(e,t.id);r?.has(n)||a.unregister(n)}let c=t.contributes?.providers;if(c?.length){for(let t of c){let r=t.preserveProviderId===!0?t.id:z(e,t.id);pe(r),t.envKey&&!t.oauthRef&&n.authStore.unregisterEnvKey(r)}await n.providerRegistry.unregisterBySource(e,i),n.modelRegistry.unregisterBySource(e)}}var tu=class{axisName=`oauthProviderFactories`;oauthIdsByPlugin=new Map;constructor(e,t){this.authStore=e,this.logger=t}register(e){let t=e.loaded.module.oauthProviderFactories;if(!t||!this.authStore)return;if(!e.plugin.manifest.capabilities?.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares oauthProviderFactories but not capabilities:["provider"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "provider" not yet granted, skipping oauthProviderFactories (fail-closed)`);return}let n=new Set((e.plugin.manifest.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0&&e.oauthRef).map(e=>e.oauthRef));for(let[r,i]of Object.entries(t)){let t=pc(e.plugin.id,i);if(!t)continue;let a=n.has(r)?r:z(e.plugin.id,r);if(t.id!==a){this.logger.warn({pluginId:e.plugin.id,name:r,expectedId:a,actualId:t.id},`plugin oauth provider id mismatch with manifest oauthRef/preserveProviderId, skipped`);continue}if(this.authStore.oauth.register(t,e.plugin.id)){let n=this.oauthIdsByPlugin.get(e.plugin.id)??new Set;n.add(t.id),this.oauthIdsByPlugin.set(e.plugin.id,n)}else this.logger.warn({pluginId:e.plugin.id,oauthId:t.id},`plugin oauthProviderFactory rejected (reserved or claimed)`)}}unregister(e){if(!this.authStore)return;let t=this.oauthIdsByPlugin.get(e);if(t){for(let e of t)this.authStore.oauth.unregister(e);this.oauthIdsByPlugin.delete(e)}}unregisterAll(){for(let e of[...this.oauthIdsByPlugin.keys()])this.unregister(e)}},nu=class{axisName=`providerFactories`;providerSourcePluginIds=new Set;modelSourcePluginIds=new Set;descriptorIdsByPlugin=new Map;constructor(e,t,n){this.providerRegistry=e,this.modelRegistry=t,this.logger=n}register(e){let t=e.loaded.module.providerFactories;if(!t||!this.providerRegistry)return;if(!e.plugin.manifest.capabilities?.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares providerFactories but not capabilities:["provider"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`provider`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "provider" declared but not yet granted, skipping providerFactories (fail-closed, RFC-124 C2)`);return}let n=e.plugin.manifest.codeProviderModelsEndpoints??{},r=e.plugin.manifest.codeProviderModels??{};for(let[i,a]of Object.entries(t)){let t=Kl(e.plugin.id,i,e.plugin.manifest);if(!this.providerRegistry.registerPluginProvider(t,fc(e.plugin.id,a),ql(e.plugin.id))){this.logger.warn({pluginId:e.plugin.id,api:t},`plugin providerFactory rejected (reserved builtin or claimed by another plugin)`);continue}this.providerSourcePluginIds.add(e.plugin.id);let o=n[i];if(o)if(le({id:t,buildModelsRequest:Yl(o,t,t)},ql(e.plugin.id))){let n=this.descriptorIdsByPlugin.get(e.plugin.id)??new Set;n.add(t),this.descriptorIdsByPlugin.set(e.plugin.id,n)}else this.logger.warn({pluginId:e.plugin.id,api:t},`plugin codeProviderModelsEndpoints descriptor rejected (reserved builtin or claimed by another plugin)`);let s=r[i];if(s?.models?.length&&this.modelRegistry){let n=s.models.map(e=>Jl(e,t,t,s.baseUrl,s.imageConstraints,s.supportsTools,s.responseBodyPolicy)),r=this.modelRegistry.registerWithSource(n,e.plugin.id);this.modelSourcePluginIds.add(e.plugin.id),r.length>0&&this.logger.warn({pluginId:e.plugin.id,rejectedModelIds:r},`plugin codeProviderModels contains model ids already claimed by another source, rejected`)}}}async unregister(e){this.providerRegistry&&this.providerSourcePluginIds.has(e)&&(await this.providerRegistry.unregisterBySource(ql(e)),this.providerSourcePluginIds.delete(e)),this.modelRegistry&&this.modelSourcePluginIds.has(e)&&(this.modelRegistry.unregisterBySource(e),this.modelSourcePluginIds.delete(e));let t=this.descriptorIdsByPlugin.get(e);if(t){for(let e of t)pe(e);this.descriptorIdsByPlugin.delete(e)}}async unregisterAll(){let e=new Set([...this.providerSourcePluginIds,...this.modelSourcePluginIds,...this.descriptorIdsByPlugin.keys()]);for(let t of e)await this.unregister(t)}},ru=class{axisName=`wireProtocols`;wireProtocolSourcePluginIds=new Set;cacheReportingApisByPlugin=new Map;constructor(e,t){this.wireProtocolRegistry=e,this.logger=t}register(e){let t=e.loaded.module.wireProtocols;if(!(!t||!this.wireProtocolRegistry)){if(!e.plugin.manifest.capabilities?.includes(`wire-protocol`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares wireProtocols but not capabilities:["wire-protocol"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`wire-protocol`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "wire-protocol" declared but not yet granted, skipping wireProtocols (fail-closed, RFC-124 C2 pattern)`);return}for(let[n,r]of Object.entries(t))if(this.wireProtocolRegistry.register(n,r,e.plugin.id)){if(this.wireProtocolSourcePluginIds.add(e.plugin.id),r.meta?.reportsCacheTokens){ce(n);let t=this.cacheReportingApisByPlugin.get(e.plugin.id)??new Set;t.add(n),this.cacheReportingApisByPlugin.set(e.plugin.id,t)}}else this.logger.warn({pluginId:e.plugin.id,wireApi:n},`plugin wireProtocol rejected (already registered by another plugin, first-win)`)}}unregister(e){this.wireProtocolRegistry&&this.wireProtocolSourcePluginIds.has(e)&&(this.wireProtocolRegistry.unregisterBySource(e),this.wireProtocolSourcePluginIds.delete(e));let t=this.cacheReportingApisByPlugin.get(e);if(t){for(let e of t)fe(e);this.cacheReportingApisByPlugin.delete(e)}}unregisterAll(){let e=new Set([...this.wireProtocolSourcePluginIds,...this.cacheReportingApisByPlugin.keys()]);for(let t of e)this.unregister(t)}},iu=class{axisName=`tools`;toolSourcePluginIds=new Set;constructor(e,t){this.toolRegistry=e,this.logger=t}register(e){let t=e.loaded.module.tools;if(!t?.length||!this.toolRegistry)return;if(!e.plugin.manifest.capabilities?.includes(`tools`)){this.logger.warn({pluginId:e.plugin.id},`plugin declares tools but not capabilities:["tools"], skipped (fail-closed)`);return}if(e.verdict.pendingCapabilities.includes(`tools`)){this.logger.warn({pluginId:e.plugin.id},`plugin capability "tools" declared but not yet granted, skipping tools (fail-closed, RFC-124 C2)`);return}let n=this.toolRegistry,r={workspaceDir:e.workspaceDir,logger:{info:t=>this.logger.info({pluginId:e.plugin.id},t),warn:t=>this.logger.warn({pluginId:e.plugin.id},t),error:t=>this.logger.error({pluginId:e.plugin.id},t)},host:e.host,storage:e.storage},i=t.map(t=>hc(e.plugin.id,t,r)).filter(e=>e!==null).filter(t=>n.has(t.name)?(this.logger.warn({pluginId:e.plugin.id,tool:t.name},`plugin tool name collides with an existing tool, rejected (R3, no silent override)`),!1):!0);i.length>0&&(n.register(i,{preset:`full`,source:e.plugin.id}),this.toolSourcePluginIds.add(e.plugin.id))}unregister(e){!this.toolRegistry||!this.toolSourcePluginIds.has(e)||(this.toolRegistry.unregisterBySource(e),this.toolSourcePluginIds.delete(e))}unregisterAll(){for(let e of[...this.toolSourcePluginIds])this.unregister(e)}};const au=`[plugin]`;function ou(e,t,n){let r=n.name?.trim()||n.key;return`${au} ${e}:${t}:${n.key} — ${r}`}function su(e,t,n){let r=e.subscriber;return!r||r.kind!==`plugin-service`||r.pluginId!==t||r.serviceId!==n?!1:e.name.startsWith(au)}function cu(e,t,n){let r=`${au} ${t}:${n}:`;if(!e.name.startsWith(r))return;let i=e.name.slice(r.length),a=i.indexOf(` — `);if(!(a<=0))return i.slice(0,a)}function lu(e){let{port:t,logger:n,pluginId:r,serviceId:i}=e,a={added:0,updated:0,removed:0},o=new Map;for(let t of e.declared){let e=t?.key?.trim(),a=t?.cron?.trim();if(!e||!a){n.warn({pluginId:r,serviceId:i,key:t?.key},`plugin schedule subscription missing key or cron, skipped (RFC-327 D2)`);continue}if(o.has(e)){n.warn({pluginId:r,serviceId:i,key:e},`duplicate plugin schedule subscription key, later declaration ignored`);continue}o.set(e,{...t,key:e,cron:a})}let s=new Map;for(let e of t.list()){if(!su(e,r,i))continue;let t=cu(e,r,i);t!==void 0&&s.set(t,e)}for(let[e,c]of o){let o=ou(r,i,c),l=s.get(e);if(!l){try{t.add({name:o,prompt:`plugin service subscription (${r}:${i}:${e})`,cronExpression:c.cron,recurring:!0,origin:`user`,subscriber:{kind:`plugin-service`,pluginId:r,serviceId:i}}),a.added+=1}catch(t){n.warn({pluginId:r,serviceId:i,key:e,err:t instanceof Error?t.message:String(t)},`failed to register plugin schedule subscription`)}continue}(l.cronExpression!==c.cron||l.name!==o)&&t.update(l.id,{cronExpression:c.cron,name:o})&&(a.updated+=1)}for(let[e,n]of s)o.has(e)||t.remove(n.id)&&(a.removed+=1);return a}function uu(e){let{port:t,pluginId:n}=e,r=0;for(let e of t.list()){let i=e.subscriber;!i||i.kind!==`plugin-service`||i.pluginId!==n||e.name.startsWith(au)&&t.remove(e.id)&&(r+=1)}return r}var du=class{axisName=`services`;startedByPlugin=new Map;scheduleDeclarations=new Map;constructor(e){this.deps=e}async register(e){let t=e.loaded.module.services;if(!t?.length)return;if(!e.plugin.manifest.capabilities?.includes(`service`)){this.deps.logger.warn({pluginId:e.plugin.id},`plugin declares services but not capabilities:["service"], skipped (fail-closed, RFC-287 D-M3-1)`);return}if(e.verdict.pendingCapabilities.includes(`service`)){this.deps.logger.warn({pluginId:e.plugin.id},`plugin capability "service" declared but not yet granted, skipping services (fail-closed)`);return}let n=e.loaded.compiledPath;if(!n){this.deps.logger.warn({pluginId:e.plugin.id},`plugin declares services but has no compiled entry path; services need a compiled module to run in the service worker (skipped)`);return}let r=this.startedByPlugin.get(e.plugin.id)??[];for(let i of t){if(!i?.id)continue;let t=this.deps.getWorkspaceKey(),a=this.deps.hasStorageCapability(e.plugin.id),{error:o}=await this.deps.pool.start({pluginId:e.plugin.id,serviceId:i.id,compiledPath:n,workspaceDir:this.deps.workspaceDir,workspaceKey:t,factoryCtx:{pluginId:e.plugin.id,pluginDir:e.plugin.dir,workspaceDir:this.deps.workspaceDir},hostCapabilities:this.deps.hostCapabilitiesFor(e.plugin.id),storageDir:a?this.deps.storageDirFor(e.plugin.id,t):``,hasStorageCapability:a,bridge:this.deps.bridgeFor(e.plugin.id)});o&&this.deps.logger.warn({pluginId:e.plugin.id,serviceId:i.id,err:o},`plugin service failed to start`),r.push(i.id),this.scheduleDeclarations.set(`${e.plugin.id}:${i.id}`,i.schedules??[]);let s=this.deps.getSchedulePort?.();if(i.schedules?.length){if(!s)this.deps.logger.debug({pluginId:e.plugin.id,serviceId:i.id,count:i.schedules.length},`plugin declares schedule subscriptions but no scheduler in this process, skipped (RFC-327 D2 boundary)`);else if(!o){let t=lu({port:s,logger:this.deps.logger,pluginId:e.plugin.id,serviceId:i.id,declared:i.schedules});(t.added||t.updated||t.removed)&&this.deps.logger.info({pluginId:e.plugin.id,serviceId:i.id,...t},`plugin schedule subscriptions reconciled`)}}else s&&lu({port:s,logger:this.deps.logger,pluginId:e.plugin.id,serviceId:i.id,declared:[]})}r.length>0&&this.startedByPlugin.set(e.plugin.id,r)}async unregister(e){if(!this.startedByPlugin.has(e))return;this.startedByPlugin.delete(e);for(let t of[...this.scheduleDeclarations.keys()])t.startsWith(`${e}:`)&&this.scheduleDeclarations.delete(t);let t=this.deps.getSchedulePort?.();if(t){let n=uu({port:t,pluginId:e});n>0&&this.deps.logger.info({pluginId:e,removed:n},`plugin schedule subscriptions revoked`)}await this.deps.pool.stopPlugin(e)}async unregisterAll(){for(let e of[...this.startedByPlugin.keys()])await this.unregister(e)}reconcileAllSchedules(){let e=this.deps.getSchedulePort?.();if(e)for(let[t,n]of this.startedByPlugin)for(let r of n){let n=this.scheduleDeclarations.get(`${t}:${r}`);if(n===void 0)continue;let i=lu({port:e,logger:this.deps.logger,pluginId:t,serviceId:r,declared:n});(i.added||i.updated||i.removed)&&this.deps.logger.info({pluginId:t,serviceId:r,...i,source:`scheduler-ready reconcile`},`plugin schedule subscriptions reconciled (M3 scheduler-ready)`)}}};const fu=/^[a-z0-9]+(?:-[a-z0-9]+)*$/,pu=b(n,`plugin-state`);function mu(e){let t=hu(e);try{return qr(t,{recursive:!0,force:!0}),{removed:!E(t),dir:t}}catch{return{removed:!1,dir:t}}}function hu(e){if(!fu.test(e))throw Error(`invalid pluginId for scoped storage: ${e} (must be kebab-case)`);return b(pu,e)}var gu=class{persistence;baseDir;pluginId;workspaceKey;constructor(e,t){if(this.pluginId=e,this.workspaceKey=t,!fu.test(e))throw Error(`invalid pluginId for scoped storage: ${e} (must be kebab-case)`);if(typeof t!=`string`||t.length===0||t.includes(`/`)||t.includes(`\\`)||t.includes(`..`))throw Error(`invalid workspaceKey for scoped storage: ${t}`);if(s()){this.baseDir=`:memory:/plugin-state/${e}/${t}`,this.persistence=cn({type:`memory`});return}let n=x(b(hu(e),t));D(n,{recursive:!0});let r=Gr(n),i=Gr(pu);if(r!==i&&!r.startsWith(i+`/`))throw Error(`scoped storage path escapes plugin-state root: ${r}`);this.baseDir=n,this.persistence=cn({type:`file`,baseDir:n})}async save(e,t){await this.persistence.save({id:e,data:t,version:1,metadata:{}})}async load(e){let t=await this.persistence.load(e);return t?t.data:null}delete(e){return this.persistence.delete(e)}list(){return this.persistence.list()}};function _u(e){let t=new Set([...e.manifest.codeProviderIds??[],...(e.manifest.contributes?.providers??[]).filter(e=>e.preserveProviderId===!0).map(e=>e.id)]),n=`${e.id}:`;return e=>t.has(e)||e.startsWith(n)}function vu(e,t,n){let r=e.manifest.capabilities??[],i={},a=!1,o=n.startPluginJob;r.includes(`agent.dispatch`)&&!t.pendingCapabilities.includes(`agent.dispatch`)&&o?(i.startJob=async t=>{let r=n.getSessionId?.();if(!r)throw Error(`agent.dispatch unavailable: no active session to attach the job to`);return{jobId:o({pluginId:e.id,title:t.title,prompt:t.prompt,sessionId:r}).id}},a=!0):r.includes(`agent.dispatch`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`agent.dispatch`)},`plugin declares agent.dispatch but it is not available (not yet granted, or host provides no job dispatcher) — skipping (fail-closed, RFC-287 D2)`);let s=n.getSessionMessages,c=bu(n);r.includes(`session.read`)&&!t.pendingCapabilities.includes(`session.read`)&&s?(i.readTranscript=async t=>{if(!c.isSessionAuthorized(e.id,t.sessionId))throw Error(`session not authorized for this plugin`);let n=s(t.sessionId);if(!n)throw Error(`session not found`);if(!c.tryConsumeRead(e.id))throw Error(`readTranscript quota exceeded for this notification`);return Vc(n,t.sinceIndex??0,500)},a=!0):r.includes(`session.read`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`session.read`)},`plugin declares session.read but it is not available (not yet granted, or host provides no transcript source) — skipping (fail-closed, RFC-318 D2)`);let l=n.completeText;r.includes(`llm.complete`)&&!t.pendingCapabilities.includes(`llm.complete`)&&l?(i.complete=async t=>{if(t.prompt.length>32e3)throw Error(`prompt exceeds 32000 chars limit`);let n=c.tryConsumeLlm(e.id);if(!n.ok)throw Error(`llm.complete quota exceeded (${n.reason})`);let r=Math.min(t.maxTokens??2048,2048);return l(t.prompt,{maxTokens:r})},a=!0):r.includes(`llm.complete`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`llm.complete`)},`plugin declares llm.complete but it is not available (not yet granted, or host provides no model caller) — skipping (fail-closed, RFC-318 D2)`);let u=n.askUser;r.includes(`user.ask`)&&!t.pendingCapabilities.includes(`user.ask`)&&u?(i.ask=async t=>u(e.id,{header:String(t.header??``),question:String(t.question??``),background:String(t.background??``),recommendation:String(t.recommendation??``),...Array.isArray(t.options)?{options:t.options}:{},...t.allowFreeform===void 0?{}:{allowFreeform:!!t.allowFreeform},...t.multiSelect===void 0?{}:{multiSelect:!!t.multiSelect},...Array.isArray(t.evidence)?{evidence:t.evidence.map(String)}:{}}),a=!0):r.includes(`user.ask`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`user.ask`)},`plugin declares user.ask but it is not available (not yet granted, or host provides no UI sink) — skipping (fail-closed, RFC-344 M3)`);let d=n.notifyUser;return r.includes(`user.notify`)&&!t.pendingCapabilities.includes(`user.notify`)&&d?(i.notify=async t=>{if(!c.tryConsumeNotify(e.id)){n.logger.debug({pluginId:e.id,code:t.code},`plugin user.notify dropped: rate limit exceeded (silent by design, RFC-327 D3)`);return}let r=t.message.replace(/[\u0000-\u001f\u007f-\u009f\u200e\u200f\u202a-\u202e\u2066-\u2069]/g,` `).slice(0,500);d({pluginId:e.id,level:t.level,code:t.code.slice(0,120),message:r})},a=!0):r.includes(`user.notify`)&&n.logger.warn({pluginId:e.id,pending:t.pendingCapabilities.includes(`user.notify`)},`plugin declares user.notify but it is not available (not yet granted, or host provides no UI sink) — skipping (fail-closed, RFC-327 D3)`),a?i:void 0}const yu=new WeakMap;function bu(e){if(e.capabilityQuota)return e.capabilityQuota;let t=yu.get(e);return t||(t=new Sc,yu.set(e,t)),t}const xu=new Map([[`oauthProviderFactories`,`provider`],[`providerFactories`,`provider`],[`wireProtocols`,`wire-protocol`]]);function Su(e){let t=e.manifest.contributes;return!t||typeof t!=`object`?[]:Object.keys(t)}var Cu=class e{contributesSnapshot=new Map;static DEACTIVATE_TIMEOUT_MS=5e3;hooksAxis;monitorsAxis;feedbackAxis;sigilAxis;computedCommandsAxis;computedAgentsAxis;computedSkillsAxis;oauthProviderAxis;codeProviderAxis;wireProtocolAxis;toolsAxis;servicesAxis;axisHandlers;firedEvents=new Set;deferredIds=new Set;loadedModules=new Map;constructor(e){this.deps=e,this.hooksAxis=new Ol(e.hookRegistry),this.monitorsAxis=new kl(e.hookRegistry,e.logger),this.feedbackAxis=new Al(e.feedbackRegistry,e.logger),this.sigilAxis=new Rl(e.sigilResolverRegistry,e.pluginInput,e.logger),this.computedCommandsAxis=new zl,this.computedAgentsAxis=new Bl,this.computedSkillsAxis=new Vl(e.skillRegistry),this.oauthProviderAxis=new tu(e.authStore,e.logger),this.codeProviderAxis=new nu(e.providerRegistry,e.modelRegistry,e.logger),this.wireProtocolAxis=new ru(e.wireProtocolRegistry,e.logger),this.toolsAxis=new iu(e.toolRegistry,e.logger),this.servicesAxis=new du({pool:e.servicePool??Fc(),logger:e.logger,workspaceDir:e.workspaceDir,getWorkspaceKey:()=>e.getWorkspaceKey?.()??`default`,bridgeFor:t=>{let n=e.activePlugins().find(e=>e.id===t);if(!n)return{};let r=vu(n,T(n),e);if(!r)return{};let i={};return r.startJob&&(i.startJob=r.startJob),r.readTranscript&&(i.readTranscript=r.readTranscript),r.complete&&(i.complete=r.complete),r.notify&&(i.notify=r.notify),i},hostCapabilitiesFor:t=>{let n=e.activePlugins().find(e=>e.id===t);if(!n)return[];let r=vu(n,T(n),e);if(!r)return[];let i=[];return r.startJob&&i.push(`startJob`),r.readTranscript&&i.push(`readTranscript`),r.complete&&i.push(`complete`),r.notify&&i.push(`notify`),i},storageDirFor:(e,t)=>new gu(e,t).baseDir,hasStorageCapability:t=>!!e.activePlugins().find(e=>e.id===t)?.manifest.capabilities?.includes(`storage`),...e.getSchedulePort?{getSchedulePort:e.getSchedulePort}:{}}),this.axisHandlers=[this.hooksAxis,this.monitorsAxis,this.feedbackAxis,this.sigilAxis,this.computedCommandsAxis,this.computedAgentsAxis,this.computedSkillsAxis,this.oauthProviderAxis,this.codeProviderAxis,this.wireProtocolAxis,this.toolsAxis,this.servicesAxis]}get deferredPluginIds(){return this.deferredIds}emitMonitorEvent(e){return this.monitorsAxis.dispatch(e)}reconcileServiceSchedules(){this.servicesAxis.reconcileAllSchedules()}get monitorPluginIds(){return this.monitorsAxis.monitorPluginIds}async activateOn(e,t){return this.firedEvents.add(e),this.reload(t)}get commands(){return this.computedCommandsAxis.getComputedCommands()}async callOnDeactivate(t,n){let r;try{await Promise.race([n(),new Promise((n,i)=>{r=setTimeout(()=>{i(Error(`plugin "${t}" onDeactivate timed out after ${e.DEACTIVATE_TIMEOUT_MS}ms`))},e.DEACTIVATE_TIMEOUT_MS),r.unref?.()})])}catch(e){this.deps.logger.warn({pluginId:t,err:String(e)},`plugin onDeactivate failed or timed out`)}finally{r!==void 0&&clearTimeout(r)}}async unregisterAllAxes(){for(let e of this.axisHandlers)await e.unregisterAll()}async unregisterPluginAxes(e,t){let n=t?T(t):void 0;for(let r of this.axisHandlers){let i=xu.get(r.axisName);i!==void 0&&t!==void 0&&n!==void 0&&t.manifest.capabilities?.some(e=>e===i)&&!n.gated&&!n.pendingCapabilities.includes(i)||await r.unregister(e)}bu(this.deps).reset(e)}pluginSignature(e){let t=T(e),n=`${t.gated?`gated`:`ok`}:${[...t.pendingCapabilities].sort().join(`,`)}`,r=`nofile`;for(let t of[`plugin.ts`,`plugin.tsx`])try{let n=Jr(b(e.dir,t));r=`${t}:${n.mtimeMs}:${n.size}`;break}catch{}return`${JSON.stringify(e.manifest)}|${n}|${r}`}async reload(e){let t=this.deps.activePlugins(),n=new Map(t.map(e=>[e.id,e])),r=new Map(t.map(e=>[e.id,this.pluginSignature(e)])),i=[],a=new Set,o=new Set;for(let[e,t]of this.loadedModules)n.get(e)?r.get(e)!==t.signature&&(t.module.module.onDeactivate&&i.push({pluginId:e,onDeactivate:t.module.module.onDeactivate}),o.add(e)):(t.module.module.onDeactivate&&i.push({pluginId:e,onDeactivate:t.module.module.onDeactivate}),a.add(e));for(let{pluginId:e,onDeactivate:t}of i)await this.callOnDeactivate(e,t);for(let e of a)await this.unregisterPluginAxes(e,void 0),this.loadedModules.delete(e);for(let e of o)await this.unregisterPluginAxes(e,n.get(e));this.computedAgentsAxis.setExistingAgentNames(e);let s=new Set;for(let e of this.deps.activePlugins()){if(!Dl(rr(e.manifest),this.firedEvents)){s.add(e.id);continue}if(this.loadedModules.get(e.id)&&!o.has(e.id))continue;let t={pluginId:e.id,pluginDir:e.dir,workspaceDir:this.deps.workspaceDir,callMcpTool:(e,t,n)=>this.deps.callMcpTool(e,t,n),logger:{debug:t=>{this.deps.logger.debug({pluginId:e.id},t)},info:t=>{this.deps.logger.info({pluginId:e.id},t),rc(e.id,`info`,t)},warn:t=>{this.deps.logger.warn({pluginId:e.id},t),rc(e.id,`warn`,t)},error:t=>{this.deps.logger.error({pluginId:e.id},t),rc(e.id,`error`,t)}},getWireProtocol:e=>this.deps.wireProtocolRegistry?.get(e),resolveProviderCredential:(()=>{let t=_u(e);return e=>t(e)?this.deps.providerRegistry?.resolveAccessKey(e)??Promise.resolve(null):Promise.resolve(null)})(),resolveProviderAuth:(()=>{let t=_u(e);return e=>t(e)?this.deps.providerRegistry?.resolveAuth(e)??Promise.resolve(null):Promise.resolve(null)})(),host:vu(e,T(e),this.deps),listActivePlugins:()=>this.deps.activePlugins().map(e=>({id:e.id,version:e.manifest.version,capabilities:e.manifest.capabilities??[],contributes:this.contributesSnapshot.get(e.id)??Su(e)}))},n=this.deps.useIsolatedLoading!==!1&&wl(e)?await El(e,t,void 0,this.deps.onPluginLoadError):await nl(e,t,this.deps.onPluginLoadError);if(!n)continue;let i=T(e);if(i.gated){this.deps.logger.warn({pluginId:e.id},`project plugin not trusted, skipping code axes (fail-closed, RFC-124 C1)`);continue}let a;if(e.manifest.capabilities?.includes(`storage`))try{let t=this.deps.getWorkspaceKey?.()??yi;a=new gu(e.id,t)}catch(t){this.deps.logger.warn({pluginId:e.id,err:String(t)},`failed to construct scoped storage for plugin, storage capability unavailable`)}let c={plugin:e,verdict:i,loaded:n,host:vu(e,i,this.deps),workspaceDir:this.deps.workspaceDir,storage:a};for(let e of this.axisHandlers)await e.register(c);if(n.module.onActivate)try{await n.module.onActivate()}catch(t){this.deps.logger.warn({pluginId:e.id,err:String(t)},`plugin onActivate threw`)}this.contributesSnapshot.set(e.id,Su(e)),this.loadedModules.set(e.id,{module:n,manifest:e.manifest,signature:r.get(e.id)??this.pluginSignature(e)})}return this.deferredIds=s,this.computedAgentsAxis.getAppendedAgents()}async cleanup(){for(let[e,t]of this.loadedModules)t.module.module.onDeactivate&&await this.callOnDeactivate(e,t.module.module.onDeactivate);this.loadedModules.clear(),await this.unregisterAllAxes();let e=bu(this.deps);for(let t of this.deps.activePlugins())e.reset(t.id);this.firedEvents.clear()}};const wu=S(`@x-otto/coding:panel-compiler`),Tu=e(import.meta.url);function Eu(e){let t=b(e,`panels`);if(!E(t))return{compiled:[],errors:[],skipped:!0};let n;try{n=Ur(t).filter(e=>e.endsWith(`.tsx`))}catch{return{compiled:[],errors:[],skipped:!0}}if(n.length===0)return{compiled:[],errors:[],skipped:!0};let r=b(e,`panels-dist`);D(r,{recursive:!0});let i=Vr(b(Be(),`otto-panel-shims-`)),a=b(i,`react-shim.js`),o=b(i,`ink-shim.js`),s=b(i,`tui-shim.js`);k(a,`const R = globalThis.React
|
|
347
347
|
if (!R) throw new Error('otto panel: globalThis.React 未注入(TUI 须在加载面板前 import panel-globals)')
|
|
348
348
|
export default R
|
|
349
349
|
export const useState = R.useState, useEffect = R.useEffect, useCallback = R.useCallback,
|