@agenthippo-ai/agenthippo 1.110.37 → 1.110.39

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/out/cli/index.js CHANGED
@@ -417,7 +417,7 @@ else {
417
417
  ${Ge}`,ut.message=ge)}return ut}onMaintenance(e){let n=Date.now();for(let[r,s]of this.activeSessions.entries())n-s.lastUsedAt>AN&&(this.activeSessions.delete(r),e.info(`[AgentIDE] Closed idle custom engine session (key=${r}, idleMs=${n-s.lastUsedAt})`));for(let{engine:r,manifest:s}of this.instances.values())try{r.onMaintenance?.(e)}catch(i){e.warn(`[AgentIDE] Custom engine "${s.id}" onMaintenance error: ${i}`)}this.workerPool.onMaintenance()}dispose(){this.clearInstances(),this.workerPool.disposeAll(),this.activeSessions.clear(),this.mtimeCache.clear()}};An.CustomEngine=bd});var Ai=S(fe=>{"use strict";var RN=fe&&fe.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),CN=fe&&fe.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),kN=fe&&fe.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&RN(n,e,r[s]);return CN(n,e),n}})();Object.defineProperty(fe,"__esModule",{value:!0});fe.resolveModelAlias=fe.getSessionDir=fe.createSessionDir=fe.computeSkillsSignature=fe.syncPackToWorkspace=fe.initSessionStoreWithStore=fe.CLIPermissionHandler=fe.AutoApprovePermissionHandler=fe.DirectorySessionStore=fe.FileSessionStore=fe.MemorySessionStore=fe.StaticConfigProvider=fe.NoOpEditTracker=fe.NoOpLogger=fe.ConsoleLogger=void 0;fe.createHeadlessRunner=Od;fe.createEvalRunner=VN;fe.createCLIRunner=WN;var cE=kN(require("path")),$N=jm(),DN=Vm(),LN=pi(),Ht=qa();Object.defineProperty(fe,"ConsoleLogger",{enumerable:!0,get:function(){return Ht.ConsoleLogger}});Object.defineProperty(fe,"NoOpLogger",{enumerable:!0,get:function(){return Ht.NoOpLogger}});Object.defineProperty(fe,"NoOpEditTracker",{enumerable:!0,get:function(){return Ht.NoOpEditTracker}});Object.defineProperty(fe,"StaticConfigProvider",{enumerable:!0,get:function(){return Ht.StaticConfigProvider}});Object.defineProperty(fe,"MemorySessionStore",{enumerable:!0,get:function(){return Ht.MemorySessionStore}});Object.defineProperty(fe,"FileSessionStore",{enumerable:!0,get:function(){return Ht.FileSessionStore}});Object.defineProperty(fe,"DirectorySessionStore",{enumerable:!0,get:function(){return Ht.DirectorySessionStore}});Object.defineProperty(fe,"AutoApprovePermissionHandler",{enumerable:!0,get:function(){return Ht.AutoApprovePermissionHandler}});Object.defineProperty(fe,"CLIPermissionHandler",{enumerable:!0,get:function(){return Ht.CLIPermissionHandler}});var lE=fi(),MN=hd(),uE=no(),GN=br(),UN=ps(),HN=ui(),jN="AGENTHIPPO_TURN_NONCE";function xN(t,e){let n=t?.trim();if(n)return n;let r=e?.trim();if(r)return r;let s=process.env.AGENTHIPPO_ANALYTICS_USER_ID?.trim()||process.env.AGENTIDE_ANALYTICS_USER_ID?.trim();if(s)return s;let i=process.env.LOGNAME?.trim()||process.env.USER?.trim()||process.env.LNAME?.trim()||process.env.USERNAME?.trim();return i||"anonymous"}function Od(t){if(t.freshState){let E=new Ht.MemorySessionStore;(0,lE.initSessionStoreWithStore)(E)}else(0,lE.initSessionStoreWithStore)(new Ht.DirectorySessionStore(cE.join(t.storagePath,"provider-sessions")));let e=!!(t.litellmApiKey||t.openaiApiKey||t.anthropicApiKey),n={storagePath:t.storagePath,codexHome:void 0,claudeConfigDir:void 0,litellmApiKey:t.litellmApiKey??(e?void 0:t.apiKey),litellmBaseUrl:t.baseUrl,openaiApiKey:t.openaiApiKey,anthropicApiKey:t.anthropicApiKey,claudeCodeExecutablePath:t.claudeCodeExecutablePath,codexExecutablePath:t.codexExecutablePath},r=t.logger??new Ht.ConsoleLogger("[AgentIDE]"),s=t.editTracker??new Ht.NoOpEditTracker,i=new Ht.StaticConfigProvider({},t.customProviders??{},t.engineSettings??{}),o=t.permissionHandler??new Ht.AutoApprovePermissionHandler,a={logger:r,editTracker:s,configProvider:i,permissionHandler:o,cliEnvPatch:t.cliEnvPatch},c=t.packId??"default",l=E=>(0,MN.computeSkillsSignature)(E,c),d=()=>t.bundledPromptsDir,u,f,p,g=()=>(u||(u=new DN.ClaudeEngine(n,async(E,w)=>l(E)??`headless-${c}`,d)),u),m=()=>(f||(f=new $N.CodexEngine(n,l,d)),f),h=async()=>{if(!p){let{CustomEngine:E}=await Promise.resolve().then(()=>In(vd()));p=new E(n,d)}return p},y=new uE.SessionEventWriter(t.analyticsSessionsDir??cE.join((0,HN.getAgentideHome)(),"analytics","sessions"));return{async run(E){let w={success:!1,text:"",thinking:"",toolCalls:[]},O={async thinking(T){if(E.emitter)return E.emitter.thinking(T);w.thinking+=T},async text(T){if(E.emitter)return E.emitter.text(T);w.text+=T},async toolStart(T,K,B,ne){if(E.emitter)return E.emitter.toolStart(T,K,B,ne);w.toolCalls.push({name:T,input:K})},async toolEnd(T,K,B,ne,J){if(E.emitter)return E.emitter.toolEnd(T,K,B,ne,J);let oe=w.toolCalls.find(ge=>ge.name===T&&!ge.result);oe&&(oe.result=B,oe.isError=ne)},async progress(T){if(E.emitter)return E.emitter.progress(T);r.debug(`[Progress] ${T}`)},async question(T){return E.emitter?E.emitter.question(T):(r.debug(`[Question] ${T.prompt}`),{selected:[],freeText:null,declined:!0})},async error(T){w.error=T,w.success=!1,await E.emitter?.error(T)},async done(){w.error||(w.success=!0),await E.emitter?.done()}},b=(0,LN.generateRequestId)(),v=E.sessionId??`headless-${Date.now()}`,A=t.provenance?.(),N=(0,uE.wrapEmitterWithObservability)(O,y,v,b,(0,UN.currentCredential)()?.userId,A&&{policy_version:A.policyVersion,pack_digest:A.packDigest,engine_version:A.engineVersion,tier:A.tier,instance_id:A.instanceId}),I={modelId:E.modelId,engineId:E.engineId,workspaceRoot:E.workspaceRoot,additionalDirectories:E.additionalDirectories,sessionId:v,analyticsUserId:xN(E.analyticsUserId,t.analyticsUserId),apiKey:E.modelToken??(e?void 0:t.apiKey),baseUrl:t.baseUrl,useLiteLLM:t.useLiteLLM,agentPackId:c,agentPackVersion:t.packVersion,policyVersion:A?.policyVersion,packDigest:A?.packDigest,engineVersion:A?.engineVersion,tier:A?.tier,instanceId:A?.instanceId,permissions:E.permissions,engineHomeUserKey:E.engineHomeUserKey,requestId:b};await N.emitTurnStart();let k=null;if(t.dataPlane&&!E.turnEnv?.[jN])try{k=await t.dataPlane.beginTurn({sessionKey:v})}catch(T){return w.error=`data-plane turn registration failed: ${T instanceof Error?T.message:String(T)}`,await N.error(w.error),await N.emitTurnEnd(!1),w}let P={...a,cliEnvPatch:{...a.cliEnvPatch??{},...(0,GN.buildSessionEnvPatch)({workspaceRoot:E.workspaceRoot,chatSessionId:v,gatewaySessionKey:E.gatewaySessionKey}),...E.turnEnv??{},...k?.env??{}}};try{let T=E.engineId.trim().toLowerCase();T==="claude"?await g().stream(E.message,I,N,P,E.signal):T==="codex"?await m().stream(E.message,I,N,P,E.signal):await(await h()).stream(E.message,I,N,P,E.signal)}catch(T){w.error=T instanceof Error?T.message:String(T),w.success=!1,await N.error(w.error)}finally{try{await k?.release()}catch{}}return await N.emitTurnEnd(w.success),w},dispose(){u?.dispose(),f?.dispose(),p?.dispose()}}}var BN=fi();Object.defineProperty(fe,"initSessionStoreWithStore",{enumerable:!0,get:function(){return BN.initSessionStoreWithStore}});var Hc=hd();Object.defineProperty(fe,"syncPackToWorkspace",{enumerable:!0,get:function(){return Hc.syncPackToWorkspace}});Object.defineProperty(fe,"computeSkillsSignature",{enumerable:!0,get:function(){return Hc.computeSkillsSignature}});Object.defineProperty(fe,"createSessionDir",{enumerable:!0,get:function(){return Hc.createSessionDir}});Object.defineProperty(fe,"getSessionDir",{enumerable:!0,get:function(){return Hc.getSessionDir}});var FN=Ja();Object.defineProperty(fe,"resolveModelAlias",{enumerable:!0,get:function(){return FN.resolveModelAlias}});function VN(t,e,n){return Od({storagePath:t,apiKey:e,baseUrl:n,freshState:!0,logger:new Ht.NoOpLogger})}function WN(t,e,n){return Od({storagePath:t,apiKey:e,baseUrl:n,logger:new Ht.ConsoleLogger("[Agent]")})}});var bi=S(Jt=>{"use strict";var KN=Jt&&Jt.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),qN=Jt&&Jt.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),jc=Jt&&Jt.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&KN(n,e,r[s]);return qN(n,e),n}})();Object.defineProperty(Jt,"__esModule",{value:!0});Jt.resolvePackPath=fE;Jt.listAvailablePacks=zN;Jt.loadAgentPack=QN;Jt.getDefaultConfig=tR;Jt.getEnvDefaultModel=nR;Jt.getApiConfig=pE;Jt.hasCredentialForEngine=rR;Jt.getFileAccess=sR;var cn=jc(require("fs")),pt=jc(require("path")),YN=jc(require("os")),JN=jc(require("js-yaml")),xc=Ze();function Zo(t,e){return process.env[t]??(e?process.env[e]:void 0)}var XN=process.env.AGENTHIPPO_HOME||pt.join(YN.homedir(),xc.AGENTIDE_DIR_NAME),Id=pt.join(XN,"agents"),Pd="agents";function io(t){if(!cn.existsSync(t))return;let e=pt.join(t,"current.txt");if(cn.existsSync(e)){let r=cn.readFileSync(e,"utf-8").trim(),s=pt.join(t,r);if(cn.existsSync(s))return s}let n=pt.join(t,"agent.yaml");if(cn.existsSync(n))return t;try{let s=cn.readdirSync(t,{withFileTypes:!0}).filter(i=>i.isDirectory()&&/^\d+\.\d+\.\d+/.test(i.name)).map(i=>i.name).sort((i,o)=>{let[a,c,l]=i.split(".").map(p=>parseInt(p,10)||0),[d,u,f]=o.split(".").map(p=>parseInt(p,10)||0);return d!==a?d-a:u!==c?u-c:f-l});for(let i of s){let o=pt.join(t,i),a=pt.join(o,"agent.yaml");if(cn.existsSync(a))return o}}catch{}}function fE(t,e){if(pt.isAbsolute(t)||t.startsWith("./")||t.startsWith("../")){let c=pt.isAbsolute(t)?t:pt.resolve(process.cwd(),t);if(cn.existsSync(c)){try{if(cn.statSync(c).isDirectory())return io(c)??c}catch{}return c}return}let n=pt.join(process.cwd(),t),r=io(n);if(r)return r;let s=pt.join(process.cwd(),Pd,t),i=io(s);if(i)return i;if(e){let c=pt.join(e,xc.AGENTIDE_DIR_NAME,Pd,t),l=io(c);if(l)return l}let o=pt.join(Id,t),a=io(o);if(a)return a}function dE(t,e){let n=[];if(!cn.existsSync(t))return n;let r=cn.readdirSync(t,{withFileTypes:!0});for(let s of r){if(!s.isDirectory()||s.name.startsWith("."))continue;let i=pt.join(t,s.name),o=io(i);if(!o)continue;let a;o!==i&&(a=pt.basename(o)),n.push({name:s.name,path:o,version:a,source:e})}return n}function zN(t){let e=[],n=new Set;if(t){let s=pt.join(t,xc.AGENTIDE_DIR_NAME,Pd),i=dE(s,"workspace");for(let o of i)e.push(o),n.add(o.name)}let r=dE(Id,"user-library");for(let s of r)n.has(s.name)||e.push(s);return e}async function QN(t,e){let n=fE(t,e);if(!n){let u=pt.isAbsolute(t)||t.startsWith("./")||t.startsWith("../")?[pt.resolve(process.cwd(),t)]:[`${process.cwd()}/${t}`,`${process.cwd()}/agents/${t}`,e?`${e}/${xc.AGENTIDE_DIR_NAME}/agents/${t}`:null,`${Id}/${t}`].filter(Boolean);throw new Error(`Agent pack not found: ${t}
418
418
  Searched: ${u.join(", ")}`)}let r=pt.join(n,"agent.yaml");if(!cn.existsSync(r))throw new Error(`Missing agent.yaml in pack: ${n}`);let s=cn.readFileSync(r,"utf-8"),i=JN.load(s);eR(i,r);let o=ZN(i),a="",c=pt.join(n,"AGENTS.md");return cn.existsSync(c)&&(a=cn.readFileSync(c,"utf-8")),{manifest:o,packPath:n,systemPrompt:a,rules:[]}}function ZN(t){let e=t.spec.engine?.trim()??"",n=e.toLowerCase();return e!==n?{...t,spec:{...t.spec,engine:n}}:t}function eR(t,e){let n=[];if(t.metadata?.name||n.push("Missing metadata.name"),t.metadata?.version||n.push("Missing metadata.version"),t.spec?.engine?.trim()||n.push("Missing spec.engine"),t.spec?.engine?.trim().toLowerCase()==="custom"&&n.push('Invalid spec.engine: use the concrete custom engine id (for example, openclaw), not "custom"'),t.spec?.cheapModel!==void 0&&typeof t.spec.cheapModel!="string"&&n.push("Invalid spec.cheapModel: must be a string when provided"),t.spec?.dataPlane!==void 0&&((typeof t.spec.dataPlane!="object"||!t.spec.dataPlane.connector?.trim())&&n.push("Invalid spec.dataPlane: requires a `connector` path (stdio MCP module run broker-side)"),t.spec.dataPlane?.provider!==void 0&&typeof t.spec.dataPlane.provider!="string"&&n.push("Invalid spec.dataPlane.provider: must be a string when provided")),n.length>0)throw new Error(`Invalid agent manifest at ${e}:
419
419
  - ${n.join(`
420
- - `)}`)}function tR(){return{engine:(Zo("AGENTHIPPO_DEFAULT_ENGINE","AGENTIDE_DEFAULT_ENGINE")||"claude").trim().toLowerCase(),model:Zo("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")||"claude-sonnet-4-5-20250929"}}function nR(){return Zo("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")?.trim()||void 0}function pE(){let t=Zo("AGENTHIPPO_LITELLM_API_KEY","AGENTIDE_LITELLM_API_KEY"),e=Zo("AGENTHIPPO_LITELLM_BASE_URL","AGENTIDE_LITELLM_BASE_URL"),n=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY,r=process.env.OPENAI_API_KEY;return{apiKey:t||n||r,baseUrl:e,useLiteLLM:!!e,litellmApiKey:t,openaiApiKey:r,anthropicApiKey:n}}function rR(t,e=pE()){if(e.useLiteLLM)return!0;let n=t.trim().toLowerCase();return n==="claude"?!!e.anthropicApiKey:n==="codex"?!!e.openaiApiKey:!0}function sR(t){return t?.manifest.spec.permissions?.fileAccess??"workspace-write"}});var Bc=S((d1,iR)=>{iR.exports={name:"agenthippo",displayName:"Agent Hippo",description:"Agent Hippo - The easiest way to build and test your AI agents",version:"1.110.37",agenthippo:{litellmImageTag:"0.2.22",hippoclawNpm:"@agenthippo-ai/hippoclaw@2026.7.28"},publisher:"agenthippo",private:!0,engines:{vscode:"^1.93.0"},enabledApiProposals:["chatParticipantAdditions","chatParticipantPrivate","languageModelThinkingPart"],activationEvents:["onStartupFinished","onCommand:agentide.customEngine.list","onCommand:agentide.engine.install","onCommand:agentide.engine.uninstall","onChatParticipant:agentide.claude","onChatParticipant:agentide.codex"],main:"./out/extension.js",contributes:{authentication:[{id:"agenthippo",label:"AgentHippo"}],chatParticipants:[{id:"agentide.claude",name:"claude",fullName:"Claude Agent",description:"AI coding agent powered by Anthropic's Claude Agent SDK",isSticky:!1},{id:"agentide.codex",name:"codex",fullName:"Codex Agent",description:"AI coding agent powered by OpenAI's Codex SDK",isSticky:!1}],mcpServerDefinitionProviders:[{id:"bundled-mcp-servers",label:"Agent Hippo Bundled MCP Servers"}],commands:[{command:"agentide.skills.syncRemote",title:"Sync Remote Skills",category:"Agent Hippo"},{command:"agentide.clearManagedResources",title:"Clear Managed Resources",category:"Agent Hippo"},{command:"agentide.showManagedResources",title:"Show Managed Resources",category:"Agent Hippo"},{command:"agentide.cleanupSessionLogs",title:"Cleanup Old Session Logs",category:"Agent Hippo"},{command:"agentide.pack.install",title:"Install Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.list",title:"List Installed Packs",category:"Agent Hippo"},{command:"agentide.customEngine.list",title:"List Custom Engines",category:"Agent Hippo"},{command:"agentide.pack.uninstall",title:"Uninstall Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.getActive",title:"Get Active Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.create",title:"Create Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.share",title:"Share Agent to User Library",category:"Agent Hippo"},{command:"agentide.pack.publish",title:"Publish Agent to Store",category:"Agent Hippo"},{command:"agentide.skill.share",title:"Save Skill to User Library",category:"Agent Hippo"},{command:"agentide.skill.publish",title:"Publish Skill to Store",category:"Agent Hippo"},{command:"agentide.mcp.share",title:"Save MCP Server to User Library",category:"Agent Hippo"},{command:"agentide.mcp.publish",title:"Publish MCP Server to Store",category:"Agent Hippo"},{command:"agenthippo.signIn",title:"Sign In to AgentHippo",category:"Agent Hippo"},{command:"agenthippo.signOut",title:"Sign Out of AgentHippo",category:"Agent Hippo"},{command:"agentide.store.find",title:"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",category:"Agent Hippo"},{command:"agentide.engine.install",title:"Install Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.uninstall",title:"Uninstall Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.publish",title:"Publish Engine to Store",category:"Agent Hippo"},{command:"agentide.spotlight.publish",title:"Publish Spotlight View to Store (Full Bundle)",category:"Agent Hippo"},{command:"agentide.view.install",title:"Install Spotlight View",category:"Agent Hippo"},{command:"agentide.store.sync",title:"Sync Store Index",category:"Agent Hippo"},{command:"agentide.store.setup",title:"Setup Store Index Automation",category:"Agent Hippo"},{command:"agentide.pack.browseLibrary",title:"Browse User Library",category:"Agent Hippo"},{command:"agentide.pack.update",title:"Update Agent from User Library",category:"Agent Hippo"},{command:"agentide.pack.duplicate",title:"Duplicate Agent",category:"Agent Hippo"},{command:"agentide.pack.refresh",title:"Refresh Agent Packs",category:"Agent Hippo"},{command:"agentide.pack.resetDefault",title:"Reset Default Agent",category:"Agent Hippo"},{command:"agentide.gateway.connect",title:"Connect to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.disconnect",title:"Disconnect from Gateway",category:"Agent Hippo"},{command:"agentide.gateway.toggle",title:"Toggle Gateway Connection",category:"Agent Hippo"},{command:"agentide.gateway.status",title:"Show Gateway Status",category:"Agent Hippo"},{command:"agentide.gateway.connectSession",title:"Connect Chat to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.listSessions",title:"Show Connected Gateway Sessions",category:"Agent Hippo"},{command:"agentide.gateway.resetMappings",title:"Reset Agent Mappings (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.toggle",title:"Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.install",title:"Install Agent Anywhere (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.uninstall",title:"Uninstall Agent Anywhere (OpenClaw CLI)",category:"Agent Hippo"},{command:"agentide.anywhere.start",title:"Start Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.stop",title:"Stop Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.status",title:"Agent Anywhere Status",category:"Agent Hippo"},{command:"agentide.anywhere.connect",title:"Connect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.disconnect",title:"Disconnect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.openConfig",title:"Open Agent Anywhere Config",category:"Agent Hippo"},{command:"agentide.anywhere.openWebUI",title:"Open Agent Anywhere Web UI",category:"Agent Hippo"},{command:"agentide.anywhere.detect",title:"Detect Agent Anywhere Gateway",category:"Agent Hippo"},{command:"agentide.anywhere.meetAgent",title:"Meet Agent Anywhere...",category:"Agent Hippo"},{command:"agentide.setupCli",title:"Setup AgentHippo CLI",category:"Agent Hippo"},{command:"agentide.cli.status",title:"AgentHippo CLI Status",category:"Agent Hippo"},{command:"agentide.installBundledTools",title:"Install Bundled Tools (rg, sg, tree-sitter)",category:"Agent Hippo"},{command:"agentide.setupAnalytics",title:"Install Spotlight (OTEL + DuckDB)",category:"Agent Hippo"},{command:"agentide.analytics.toggle",title:"Manage Spotlight",category:"Agent Hippo"},{command:"agentide.analytics.start",title:"Start Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.stop",title:"Stop Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.status",title:"Show Spotlight Status",category:"Agent Hippo"},{command:"agentide.analytics.query",title:"Query Spotlight (Cost, Sessions)",category:"Agent Hippo"},{command:"agentide.analytics.openDashboard",title:"Open Spotlight Dashboard",category:"Agent Hippo"},{command:"agentide.fleet.open",title:"Open Agent Team",category:"Agent Hippo"},{command:"agentide.analytics.clearArtifacts",title:"Clear Spotlight Artifacts",category:"Agent Hippo"},{command:"agentide.analytics.regenerateDefaults",title:"Regenerate Default Charts",category:"Agent Hippo"}],menus:{ChatModePicker:[{command:"agentide.anywhere.meetAgent",group:"navigation@30",when:"agentide.anywhere.enabled && !agentide.anywhere.hidden",icon:"$(broadcast)"}]},viewsContainers:{activitybar:[{id:"agentide-analytics",title:"Agent Hippo",icon:"$(graph)"},{id:"agentide-team",title:"Agent Team",icon:"$(organization)"}]},views:{"agentide-analytics":[{type:"webview",id:"agentide.analyticsView",name:"Spotlight"}],"agentide-team":[{type:"webview",id:"agentide.teamView",name:"Agent Team"}]},configuration:{title:"Agent Hippo",properties:{"agentide.permissions.fileAccess":{type:"string",scope:"application",enum:["read-only","workspace-write","full"],default:"full",markdownDescription:"Filesystem access scope (applies to all engines).\n- `read-only`: Read/search only (no file writes)\n- `workspace-write`: Read/write within workspace folders only\n- `full`: Full filesystem access (yolo, default)\n\n**Security**: Agent manifest permissions take precedence - user cannot override stricter pack permissions."},"agentide.claude.maxThinkingTokens":{type:"number",default:1024,description:"Claude extended thinking budget (tokens). Set to 0 to disable. Requires a compatible model; Anthropic requires >=1024 for extended thinking."},"agentide.claude.cheapModel":{type:"string",default:"",description:"Optional cheap Claude model for subagents/background routing (for example, claude-haiku-4-5-20251001). Main model selection still comes from the model picker."},"agentide.sessions.retentionDays":{type:"number",default:7,minimum:1,maximum:365,description:"Number of days to retain session logs before cleanup. Cleanup runs on startup (best-effort) and via the 'Agent Hippo: Cleanup Old Session Logs' command."},"agentide.fallbackDirectory":{type:"string",scope:"machine",default:".agent-hippo",description:"Directory name (relative to home) used as workspace when no folder is open. Default: ~/.agent-hippo"},"agentide.additionalEngineDir":{type:"string",scope:"machine",default:"",description:"Additional directories to scan for custom engines. Machine-scoped: engines discovered here are executed, so a workspace must not be able to point this at attacker-controlled code."},"agentide.auth.baseUrl":{type:"string",scope:"application",default:"https://auth.agenthippo.ai",markdownDescription:"AgentHippo auth broker base URL for team sign-in and bootstrap (`agenthippo.signIn`).\n\n**Application-scoped on purpose**: this endpoint receives your PKCE authorization code and your AgentHippo access token, and its `/api/ide/bootstrap` response is written into your model-routing settings. A workspace must never be able to redirect it. Must be `https://` (plain `http://` is accepted only for loopback dev hosts)."},"agentide.cli.path":{type:"string",scope:"machine",default:"",description:"Optional absolute path to the AgentHippo CLI binary. If unset, Agent Hippo auto-detects a bundled binary or falls back to PATH. Machine-scoped: this path is executed."},"agentide.cli.installSource":{type:"string",scope:"machine",default:"",description:"Optional setup source for AgentHippo CLI. Supports HTTPS URL to a prebuilt binary, or local file path. If empty, setup builds from the local repository. Machine-scoped: this source is downloaded and executed."},"agentide.storeRepo":{type:"string",scope:"application",default:"agenthippoai/agenthippo-store",markdownDescription:"GitHub repository for pack store (owner/repo format).\n\nDefault: `agenthippoai/agenthippo-store` ([github.com/agenthippoai/agenthippo-store](https://github.com/agenthippoai/agenthippo-store))\n\nSet to your own repo (e.g., `mycompany/our-packs`) to use a private or custom store."},"agentide.store.indexUrl":{type:"string",scope:"application",default:"https://agenthippoai.github.io/agenthippo-store",markdownDescription:`Base URL for the store index (Orama + metadata are loaded from paths under this URL).
420
+ - `)}`)}function tR(){return{engine:(Zo("AGENTHIPPO_DEFAULT_ENGINE","AGENTIDE_DEFAULT_ENGINE")||"claude").trim().toLowerCase(),model:Zo("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")||"claude-sonnet-4-5-20250929"}}function nR(){return Zo("AGENTHIPPO_DEFAULT_MODEL","AGENTIDE_DEFAULT_MODEL")?.trim()||void 0}function pE(){let t=Zo("AGENTHIPPO_LITELLM_API_KEY","AGENTIDE_LITELLM_API_KEY"),e=Zo("AGENTHIPPO_LITELLM_BASE_URL","AGENTIDE_LITELLM_BASE_URL"),n=process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_API_KEY,r=process.env.OPENAI_API_KEY;return{apiKey:t||n||r,baseUrl:e,useLiteLLM:!!e,litellmApiKey:t,openaiApiKey:r,anthropicApiKey:n}}function rR(t,e=pE()){if(e.useLiteLLM)return!0;let n=t.trim().toLowerCase();return n==="claude"?!!e.anthropicApiKey:n==="codex"?!!e.openaiApiKey:!0}function sR(t){return t?.manifest.spec.permissions?.fileAccess??"workspace-write"}});var Bc=S((d1,iR)=>{iR.exports={name:"agenthippo",displayName:"Agent Hippo",description:"Agent Hippo - The easiest way to build and test your AI agents",version:"1.110.39",agenthippo:{litellmImageTag:"0.2.23",hippoclawNpm:"@agenthippo-ai/hippoclaw@2026.7.28"},publisher:"agenthippo",private:!0,engines:{vscode:"^1.93.0"},enabledApiProposals:["chatParticipantAdditions","chatParticipantPrivate","languageModelThinkingPart"],activationEvents:["onStartupFinished","onCommand:agentide.customEngine.list","onCommand:agentide.engine.install","onCommand:agentide.engine.uninstall","onChatParticipant:agentide.claude","onChatParticipant:agentide.codex"],main:"./out/extension.js",contributes:{authentication:[{id:"agenthippo",label:"AgentHippo"}],chatParticipants:[{id:"agentide.claude",name:"claude",fullName:"Claude Agent",description:"AI coding agent powered by Anthropic's Claude Agent SDK",isSticky:!1},{id:"agentide.codex",name:"codex",fullName:"Codex Agent",description:"AI coding agent powered by OpenAI's Codex SDK",isSticky:!1}],mcpServerDefinitionProviders:[{id:"bundled-mcp-servers",label:"Agent Hippo Bundled MCP Servers"}],commands:[{command:"agentide.skills.syncRemote",title:"Sync Remote Skills",category:"Agent Hippo"},{command:"agentide.clearManagedResources",title:"Clear Managed Resources",category:"Agent Hippo"},{command:"agentide.showManagedResources",title:"Show Managed Resources",category:"Agent Hippo"},{command:"agentide.cleanupSessionLogs",title:"Cleanup Old Session Logs",category:"Agent Hippo"},{command:"agentide.pack.install",title:"Install Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.list",title:"List Installed Packs",category:"Agent Hippo"},{command:"agentide.customEngine.list",title:"List Custom Engines",category:"Agent Hippo"},{command:"agentide.pack.uninstall",title:"Uninstall Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.getActive",title:"Get Active Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.create",title:"Create Agent Pack",category:"Agent Hippo"},{command:"agentide.pack.share",title:"Share Agent to User Library",category:"Agent Hippo"},{command:"agentide.pack.publish",title:"Publish Agent to Store",category:"Agent Hippo"},{command:"agentide.skill.share",title:"Save Skill to User Library",category:"Agent Hippo"},{command:"agentide.skill.publish",title:"Publish Skill to Store",category:"Agent Hippo"},{command:"agentide.mcp.share",title:"Save MCP Server to User Library",category:"Agent Hippo"},{command:"agentide.mcp.publish",title:"Publish MCP Server to Store",category:"Agent Hippo"},{command:"agenthippo.signIn",title:"Sign In to AgentHippo",category:"Agent Hippo"},{command:"agenthippo.signOut",title:"Sign Out of AgentHippo",category:"Agent Hippo"},{command:"agentide.store.find",title:"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",category:"Agent Hippo"},{command:"agentide.engine.install",title:"Install Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.uninstall",title:"Uninstall Custom Engine",category:"Agent Hippo"},{command:"agentide.engine.publish",title:"Publish Engine to Store",category:"Agent Hippo"},{command:"agentide.spotlight.publish",title:"Publish Spotlight View to Store (Full Bundle)",category:"Agent Hippo"},{command:"agentide.view.install",title:"Install Spotlight View",category:"Agent Hippo"},{command:"agentide.store.sync",title:"Sync Store Index",category:"Agent Hippo"},{command:"agentide.store.setup",title:"Setup Store Index Automation",category:"Agent Hippo"},{command:"agentide.pack.browseLibrary",title:"Browse User Library",category:"Agent Hippo"},{command:"agentide.pack.update",title:"Update Agent from User Library",category:"Agent Hippo"},{command:"agentide.pack.duplicate",title:"Duplicate Agent",category:"Agent Hippo"},{command:"agentide.pack.refresh",title:"Refresh Agent Packs",category:"Agent Hippo"},{command:"agentide.pack.resetDefault",title:"Reset Default Agent",category:"Agent Hippo"},{command:"agentide.gateway.connect",title:"Connect to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.disconnect",title:"Disconnect from Gateway",category:"Agent Hippo"},{command:"agentide.gateway.toggle",title:"Toggle Gateway Connection",category:"Agent Hippo"},{command:"agentide.gateway.status",title:"Show Gateway Status",category:"Agent Hippo"},{command:"agentide.gateway.connectSession",title:"Connect Chat to Gateway",category:"Agent Hippo"},{command:"agentide.gateway.listSessions",title:"Show Connected Gateway Sessions",category:"Agent Hippo"},{command:"agentide.gateway.resetMappings",title:"Reset Agent Mappings (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.toggle",title:"Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.install",title:"Install Agent Anywhere (Gateway)",category:"Agent Hippo"},{command:"agentide.anywhere.uninstall",title:"Uninstall Agent Anywhere (OpenClaw CLI)",category:"Agent Hippo"},{command:"agentide.anywhere.start",title:"Start Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.stop",title:"Stop Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.status",title:"Agent Anywhere Status",category:"Agent Hippo"},{command:"agentide.anywhere.connect",title:"Connect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.disconnect",title:"Disconnect Agent Anywhere",category:"Agent Hippo"},{command:"agentide.anywhere.openConfig",title:"Open Agent Anywhere Config",category:"Agent Hippo"},{command:"agentide.anywhere.openWebUI",title:"Open Agent Anywhere Web UI",category:"Agent Hippo"},{command:"agentide.anywhere.detect",title:"Detect Agent Anywhere Gateway",category:"Agent Hippo"},{command:"agentide.anywhere.meetAgent",title:"Meet Agent Anywhere...",category:"Agent Hippo"},{command:"agentide.setupCli",title:"Setup AgentHippo CLI",category:"Agent Hippo"},{command:"agentide.cli.status",title:"AgentHippo CLI Status",category:"Agent Hippo"},{command:"agentide.installBundledTools",title:"Install Bundled Tools (rg, sg, tree-sitter)",category:"Agent Hippo"},{command:"agentide.setupAnalytics",title:"Install Spotlight (OTEL + DuckDB)",category:"Agent Hippo"},{command:"agentide.analytics.toggle",title:"Manage Spotlight",category:"Agent Hippo"},{command:"agentide.analytics.start",title:"Start Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.stop",title:"Stop Spotlight (OTEL + LiteLLM)",category:"Agent Hippo"},{command:"agentide.analytics.status",title:"Show Spotlight Status",category:"Agent Hippo"},{command:"agentide.analytics.query",title:"Query Spotlight (Cost, Sessions)",category:"Agent Hippo"},{command:"agentide.analytics.openDashboard",title:"Open Spotlight Dashboard",category:"Agent Hippo"},{command:"agentide.fleet.open",title:"Open Agent Team",category:"Agent Hippo"},{command:"agentide.analytics.clearArtifacts",title:"Clear Spotlight Artifacts",category:"Agent Hippo"},{command:"agentide.analytics.regenerateDefaults",title:"Regenerate Default Charts",category:"Agent Hippo"}],menus:{ChatModePicker:[{command:"agentide.anywhere.meetAgent",group:"navigation@30",when:"agentide.anywhere.enabled && !agentide.anywhere.hidden",icon:"$(broadcast)"}]},viewsContainers:{activitybar:[{id:"agentide-analytics",title:"Agent Hippo",icon:"$(graph)"},{id:"agentide-team",title:"Agent Team",icon:"$(organization)"}]},views:{"agentide-analytics":[{type:"webview",id:"agentide.analyticsView",name:"Spotlight"}],"agentide-team":[{type:"webview",id:"agentide.teamView",name:"Agent Team"}]},configuration:{title:"Agent Hippo",properties:{"agentide.permissions.fileAccess":{type:"string",scope:"application",enum:["read-only","workspace-write","full"],default:"full",markdownDescription:"Filesystem access scope (applies to all engines).\n- `read-only`: Read/search only (no file writes)\n- `workspace-write`: Read/write within workspace folders only\n- `full`: Full filesystem access (yolo, default)\n\n**Security**: Agent manifest permissions take precedence - user cannot override stricter pack permissions."},"agentide.claude.maxThinkingTokens":{type:"number",default:1024,description:"Claude extended thinking budget (tokens). Set to 0 to disable. Requires a compatible model; Anthropic requires >=1024 for extended thinking."},"agentide.claude.cheapModel":{type:"string",default:"",description:"Optional cheap Claude model for subagents/background routing (for example, claude-haiku-4-5-20251001). Main model selection still comes from the model picker."},"agentide.sessions.retentionDays":{type:"number",default:7,minimum:1,maximum:365,description:"Number of days to retain session logs before cleanup. Cleanup runs on startup (best-effort) and via the 'Agent Hippo: Cleanup Old Session Logs' command."},"agentide.fallbackDirectory":{type:"string",scope:"machine",default:".agent-hippo",description:"Directory name (relative to home) used as workspace when no folder is open. Default: ~/.agent-hippo"},"agentide.additionalEngineDir":{type:"string",scope:"machine",default:"",description:"Additional directories to scan for custom engines. Machine-scoped: engines discovered here are executed, so a workspace must not be able to point this at attacker-controlled code."},"agentide.auth.baseUrl":{type:"string",scope:"application",default:"https://auth.agenthippo.ai",markdownDescription:"AgentHippo auth broker base URL for team sign-in and bootstrap (`agenthippo.signIn`).\n\n**Application-scoped on purpose**: this endpoint receives your PKCE authorization code and your AgentHippo access token, and its `/api/ide/bootstrap` response is written into your model-routing settings. A workspace must never be able to redirect it. Must be `https://` (plain `http://` is accepted only for loopback dev hosts)."},"agentide.cli.path":{type:"string",scope:"machine",default:"",description:"Optional absolute path to the AgentHippo CLI binary. If unset, Agent Hippo auto-detects a bundled binary or falls back to PATH. Machine-scoped: this path is executed."},"agentide.cli.installSource":{type:"string",scope:"machine",default:"",description:"Optional setup source for AgentHippo CLI. Supports HTTPS URL to a prebuilt binary, or local file path. If empty, setup builds from the local repository. Machine-scoped: this source is downloaded and executed."},"agentide.storeRepo":{type:"string",scope:"application",default:"agenthippoai/agenthippo-store",markdownDescription:"GitHub repository for pack store (owner/repo format).\n\nDefault: `agenthippoai/agenthippo-store` ([github.com/agenthippoai/agenthippo-store](https://github.com/agenthippoai/agenthippo-store))\n\nSet to your own repo (e.g., `mycompany/our-packs`) to use a private or custom store."},"agentide.store.indexUrl":{type:"string",scope:"application",default:"https://agenthippoai.github.io/agenthippo-store",markdownDescription:`Base URL for the store index (Orama + metadata are loaded from paths under this URL).
421
421
 
422
422
  Default: \`https://agenthippoai.github.io/agenthippo-store\`
423
423
 
@@ -482,7 +482,7 @@ Plaid.create({
482
482
  </script>`)}function GC(t){return async(e,n)=>{let r=new URL(e.url??"/","http://connect.invalid");if(!r.pathname.startsWith("/connect/"))return!1;let s=`${e.method} ${r.pathname}`;try{if(s==="GET /connect/start"){let i=await t.provider.startConnect(r.searchParams.get("ticket")??void 0,t.browserUser(e));if(i.kind==="redirect")n.writeHead(302,{...el,Location:i.location}),n.end();else{let o=(0,$C.randomBytes)(16).toString("base64");qd(n,200,MC(i.flow,i.linkToken,o),LC(o))}return!0}if(s==="GET /connect/google/callback"){let i=await t.provider.finishGoogle({state:r.searchParams.get("state")??void 0,code:r.searchParams.get("code")??void 0,error:r.searchParams.get("error")??void 0},t.browserUser(e));return t.audit?.("connect","grant_connected",{service:"google",userId:i.userId}),qd(n,200,Yd("Google connected",`<p>Connected <b>${tl(i.email??"your Google account")}</b>. You can close this tab and go back to your agent.</p>`),FE),!0}if(s==="POST /connect/bank/exchange"){let i;try{i=JSON.parse(await(0,DC.readBodyWithCap)(e))??{}}catch{throw new Zc.ConnectError(400,"Bad request.")}let o=await t.provider.finishBank(i,t.browserUser(e));return t.audit?.("connect","grant_connected",{service:"bank",userId:o.userId,institution:o.institution??null}),n.writeHead(200,{...el,"Content-Type":"text/plain; charset=utf-8"}),n.end("ok"),!0}throw new Zc.ConnectError(404,"Not found.")}catch(i){let o=i instanceof Zc.ConnectError?i.status:500,a=i instanceof Zc.ConnectError?i.message:"Something went wrong. Ask your agent for a new link and try again.";return t.audit?.("connect","grant_connect_failed",{route:s,status:o,error:i instanceof Error?i.message:String(i)}),s==="POST /connect/bank/exchange"?(n.writeHead(o,{...el,"Content-Type":"text/plain; charset=utf-8"}),n.end(a)):qd(n,o,Yd("Could not connect",`<p>${tl(a)}</p>`),FE),!0}}}});var WE=S(Pr=>{"use strict";var UC=Pr&&Pr.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),HC=Pr&&Pr.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),jC=Pr&&Pr.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&UC(n,e,r[s]);return HC(n,e),n}})();Object.defineProperty(Pr,"__esModule",{value:!0});Pr.backupTimestamp=BC;Pr.backupPathFor=VE;Pr.renameToBackup=FC;var xC=require("fs"),zd=jC(require("path"));function BC(t=new Date){return t.toISOString().replace(/[-:]/g,"").replace(/\.\d+Z$/,"Z")}function VE(t,e){let n=zd.dirname(t),r=zd.basename(t).replace(/\.json$/i,"");return zd.join(n,`${r}.${e}.bk`)}async function FC(t,e){let n=VE(t,e);try{return await xC.promises.rename(t,n),n}catch(r){if((r&&typeof r=="object"&&"code"in r?String(r.code):"")==="ENOENT")return;throw r}}});var il=S($t=>{"use strict";var VC=$t&&$t.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),WC=$t&&$t.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),KC=$t&&$t.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&VC(n,e,r[s]);return WC(n,e),n}})();Object.defineProperty($t,"__esModule",{value:!0});$t._resetOutboundHandleStoreLockForTest=YC;$t._setOutboundHandleStorePathForTest=JC;$t.buildGatewayOutboundHandleKey=JE;$t.upsertGatewayOutboundHandle=tk;$t.getLastGatewayOutboundHandle=nk;$t.listGatewayOutboundTargets=rk;$t.mergeGatewayOutboundHandles=sk;$t.resolveGatewayOutboundHandle=ik;$t.backupAndClearOutboundHandlesForAgent=ok;$t.getGatewayOutboundStoreSnapshot=ak;var nl=require("fs"),qC=KC(require("path")),KE=WE(),Zd=1,YE={value:void 0},po=new Map,Qd=new Map;function ef(t,e){let r=(Qd.get(t)??Promise.resolve()).then(()=>e());return Qd.set(t,r.catch(()=>{})),r}function YC(){Qd.clear(),po.clear()}function JC(t){YE.value=t,po.clear()}function ra(t){return YE.value??t}function JE(t,e){let n=e?.trim();return n?`${t}::thread:${n}`:`${t}::`}function XC(){return{version:Zd,lastByAgent:{},targetsByAgent:{}}}async function Ks(t){let e=ra(t),n=po.get(e);if(n)return n;try{let s=await nl.promises.readFile(e,"utf-8"),i=JSON.parse(s);if(i.targetsByAgent&&typeof i.targetsByAgent=="object"){let o={version:i.version??Zd,lastByAgent:i.lastByAgent??{},targetsByAgent:i.targetsByAgent};return po.set(e,o),o}}catch{}let r=XC();return po.set(e,r),r}async function tf(t,e){let n=ra(t);await nl.promises.mkdir(qC.dirname(n),{recursive:!0});let r={version:Zd,lastByAgent:e.lastByAgent,targetsByAgent:e.targetsByAgent},s=`${n}.tmp`;await nl.promises.writeFile(s,JSON.stringify(r,null,2),"utf-8"),await nl.promises.rename(s,n),po.set(n,e)}function Ws(t,e){if(e?.toLowerCase()!=="slack")return t;let n=t.match(/^(user|channel|group):(.+)$/i);return n?`${n[1].toLowerCase()}:${n[2].toUpperCase()}`:t}function qE(t,e,n){let r=Ws(t,n),s=Ws(e,n);return r.toLowerCase()===s.toLowerCase()}function zC(t,e,n){if(n)return t.find(i=>qE(i.target,e,i.channel)&&i.threadId?.trim()===n);let r=t.filter(i=>qE(i.target,e,i.channel));return r.length===0?void 0:r.find(i=>!i.threadId?.trim())??rl(r)[0]}function QC(t,e){let n=t.match(/:thread:([^:]+)$/),r=n?t.slice(0,-n[0].length):t,s=r.match(/:direct:([^:]+)$/);if(s)return Ws(`user:${s[1]}`,e);let i=r.match(/:dm:([^:]+)$/);if(i)return Ws(`user:${i[1]}`,e);let o=r.match(/:channel:([^:]+)$/);if(o)return Ws(`channel:${o[1]}`,e);let a=r.match(/:group:([^:]+)$/);if(a)return Ws(`channel:${a[1]}`,e)}function ZC(t){let e=t.target?.trim();if(e)return Ws(e,t.channel);let n=t.sessionKey?.trim().toLowerCase();if(n){let s=QC(n,t.channel);if(s)return s}let r=t.senderId?.trim();if(r&&t.channel)return Ws(`user:${r}`,t.channel)}function ek(t){return t.senderName?.trim()?t.senderName.trim():t.senderUsername?.trim()?t.senderUsername.trim():t.target?.trim()||t.senderId?.trim()}function rl(t){return[...t].sort((e,n)=>n.lastSeenAt-e.lastSeenAt)}function sl(t,e){let n=e.trim();if(!n||t.lastByAgent[n]||t.targetsByAgent[n])return n;if(n.toLowerCase()==="default"){for(let r of["default","Default"])if(t.lastByAgent[r]||t.targetsByAgent[r])return r}return n}async function tk(t,e,n,r,s){let i=e.trim();if(!i)return;let o=s?.gatewayAgentId?.trim()||void 0,a=n.channel?.trim(),c=n.sessionKey?.trim().toLowerCase();if(!a&&c){let d=c.match(/^agent:[^:]+:([a-z0-9_-]+):/);d&&(a=d[1])}let l=ZC(n);if(!(!a||!l))return ef(ra(t),async()=>{let d=Date.now(),u=await Ks(t);u.targetsByAgent[i]||(u.targetsByAgent[i]={});let f=JE(l,n.threadId?.trim()),p=u.targetsByAgent[i][f],g={agentId:i,...o?{gatewayAgentId:o}:{},channel:a,accountId:n.accountId?.trim()||void 0,target:l,threadId:n.threadId?.trim()||void 0,sessionKey:n.sessionKey?.trim()||void 0,sessionId:n.sessionId?.trim()||void 0,senderId:n.senderId?.trim()||void 0,senderName:n.senderName?.trim()||void 0,senderUsername:n.senderUsername?.trim()||void 0,label:ek(n),firstSeenAt:p?.firstSeenAt??d,lastSeenAt:d,lastInboundRunId:r,inboundCount:(p?.inboundCount??0)+1};return u.targetsByAgent[i][f]=g,u.lastByAgent[i]=g,await tf(t,u),g})}async function nk(t,e){let n=await Ks(t),r=sl(n,e);return n.lastByAgent[r]}async function rk(t,e){let n=await Ks(t);if(e?.trim()){let s=sl(n,e.trim());return rl(Object.values(n.targetsByAgent[s]??{}))}let r=[];for(let s of Object.values(n.targetsByAgent))r.push(...Object.values(s));return rl(r)}async function sk(t,e,n){let r=await Ks(t),s=n?.trim()?[n.trim()]:[...new Set([...Object.keys(r.targetsByAgent),...Object.keys(r.lastByAgent)])];return s.length===0?0:ef(ra(e),async()=>{let i=await Ks(e),o=0,a=!1;for(let c of s){let l=r.targetsByAgent[c]??{},d=Object.entries(l);d.length>0&&!i.targetsByAgent[c]&&(i.targetsByAgent[c]={});for(let[f,p]of d){let g=i.targetsByAgent[c]?.[f];(!g||p.lastSeenAt>=g.lastSeenAt)&&(i.targetsByAgent[c][f]=p,o++,a=!0)}let u=r.lastByAgent[c];if(u){let f=i.lastByAgent[c];(!f||u.lastSeenAt>=f.lastSeenAt)&&(i.lastByAgent[c]=u,a=!0)}}return a&&await tf(e,i),o})}async function ik(t,e,n){let r=await Ks(t),s=sl(r,e),i=n?.target?.trim();if(i){let o=Object.values(r.targetsByAgent[s]??{});return zC(o,i,n?.threadId?.trim())}return r.lastByAgent[s]}async function ok(t,e,n=(0,KE.backupTimestamp)()){let r=ra(t);return ef(r,async()=>{let s=await Ks(t),i=sl(s,e),o=s.targetsByAgent[i],a=Object.prototype.hasOwnProperty.call(s.lastByAgent,i),c=o?Object.keys(o).length:0;if(c===0&&!a)return{removed:0};let l=await(0,KE.renameToBackup)(r,n);return delete s.targetsByAgent[i],delete s.lastByAgent[i],await tf(t,s),{removed:c,backupPath:l}})}async function ak(t){let e=await Ks(t),n={};for(let[r,s]of Object.entries(e.targetsByAgent))n[r]=rl(Object.values(s));return{lastByAgent:e.lastByAgent,targetsByAgent:n}}});var zE=S(Ir=>{"use strict";var ck=Ir&&Ir.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),lk=Ir&&Ir.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),uk=Ir&&Ir.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&ck(n,e,r[s]);return lk(n,e),n}})();Object.defineProperty(Ir,"__esModule",{value:!0});Ir.EGRESS_URL_ENV=void 0;Ir.startEgressBroker=_k;var dk=uk(require("http")),fk=Or(),pk=co(),gk=il(),XE=yc();Ir.EGRESS_URL_ENV="AGENTHIPPO_EGRESS_URL";function hk(t){return t?.match(/^Bearer\s+(\S+)$/i)?.[1]}function mk(t){return t?(0,pk.hashNonce)(t).slice(0,12):"none"}function Ek(t,e){return(0,XE.getGatewayOutboundFilePath)(t,(0,XE.safeGatewaySessionDirId)(e))}async function _k(t){let e=dk.createServer(async(s,i)=>{let o=(a,c,l,d)=>{l&&t.audit?.("unauthorized",l,d??{}),i.writeHead(a,{"Content-Type":"application/json"}),i.end(JSON.stringify({ok:!1,error:c}))};try{if((s.url?.split("?")[0]??"")!=="/egress/send"){o(404,"not found");return}if(s.method!=="POST"){i.writeHead(405,{"Content-Type":"application/json",Allow:"POST"}),i.end(JSON.stringify({ok:!1,error:"method not allowed"}));return}let c=hk(s.headers.authorization),l=c?t.registry.resolve(c):void 0;if(!l){o(401,"Unauthorized: missing, unknown, or expired turn nonce","egress_nonce_reject",{reason:c?"unknown_or_expired":"missing",nonce_sha256_prefix:mk(c)});return}let d=l.egressStoreKey?.trim();if(!d){o(403,"no outbound route for this turn (not a channel-originated session)","egress_deny",{userId:l.userId,reason:"no_store_key"});return}let u;try{u=JSON.parse(await(0,fk.readBodyWithCap)(s))}catch{o(400,"invalid JSON body");return}let f=typeof u.message=="string"?u.message:"";if(!f.trim()){o(400,"message is required");return}let p=typeof u.to=="string"?u.to.trim():void 0,g=typeof u.media=="string"&&u.media.trim()||void 0,m=Ek(t.workspaceRoot,d),h;try{h=await(0,gk.resolveGatewayOutboundHandle)(m,t.agentId,p?{target:p}:void 0)}catch(E){t.logger?.warn(`[Egress] store read failed: ${E instanceof Error?E.message:String(E)}`)}if(!h){o(404,p?`no bound handle matches "${p}" for this session (cannot address a new destination)`:"no reply destination bound for this session yet","egress_deny",{userId:l.userId,reason:"no_matching_handle",to:p??"(reply-to-sender)"});return}t.audit?.(l.sessionKey,"egress_authorize",{userId:l.userId,channel:h.channel,target:h.target});let y=await t.send(h,f,g);i.writeHead(y.ok?200:502,{"Content-Type":"application/json"}),i.end(JSON.stringify(y))}catch(a){t.logger?.warn(`[Egress] broker error: ${a instanceof Error?a.message:String(a)}`),i.headersSent||i.writeHead(500,{"Content-Type":"application/json"}),i.end(JSON.stringify({ok:!1,error:"Internal error"}))}});await new Promise((s,i)=>{e.once("error",i),e.listen(0,"127.0.0.1",()=>s())});let n=e.address();if(!n||typeof n=="string")throw new Error("Egress broker failed to bind a loopback port");let r=`http://127.0.0.1:${n.port}/egress/send`;return t.logger?.info(`[Egress] broker listening at ${r}`),{url:r,close:()=>new Promise(s=>e.close(()=>s()))}}});var n_=S(Gn=>{"use strict";var yk=Gn&&Gn.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),wk=Gn&&Gn.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Sk=Gn&&Gn.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&yk(n,e,r[s]);return wk(n,e),n}})();Object.defineProperty(Gn,"__esModule",{value:!0});Gn.ASSERTION_HEADER=void 0;Gn.startDataPlaneSidecar=Nk;var QE=Sk(require("http")),t_=require("crypto"),Ak=Pi(),bk=co(),ZE=Or(),e_=ta(),Tk=Xd(),vk=fo();Gn.ASSERTION_HEADER="x-agent-user-assertion";function Ok(t,e){let n=t.headers[e];return(Array.isArray(n)?n[0]:n)?.trim()||void 0}function ol(t){return(0,t_.createHash)("sha256").update(t).digest("hex").slice(0,12)}function Pk(t){return t?.match(/^Bearer\s+(\S+)$/i)?.[1]}function Ik(t,e){let n=Buffer.from(t),r=Buffer.from(e);return n.length===r.length&&(0,t_.timingSafeEqual)(n,r)}async function Nk(t){let e=t.bindHost??"0.0.0.0",n=await Ak.DataPlane.start(t.config,{logger:t.logger,audit:t.audit,gateway:{host:e,port:t.gatewayPort,advertiseHost:e==="0.0.0.0"?void 0:e}}),r=new Map,s=QE.createServer(async(d,u)=>{let f=(p,g)=>{u.writeHead(p,{"Content-Type":"application/json"}),u.end(JSON.stringify({error:g}))};try{let p=d.url?.split("?")[0]??"";if(d.method==="GET"&&p==="/health")return u.writeHead(200,{"Content-Type":"application/json"}),u.end(JSON.stringify({ok:!0}));let g=Pk(d.headers.authorization);if(!g||!Ik(g,t.registerToken))return t.audit?.("unauthorized","sidecar_register_reject",{reason:g?"bad_token":"missing_token"}),f(401,"unauthorized");if((d.method==="GET"||d.method==="POST")&&p==="/edge/turn"){let m=(Array.isArray(d.headers["x-agent-user"])?d.headers["x-agent-user"][0]:d.headers["x-agent-user"])?.trim();if(!m)return t.audit?.("unauthorized","sidecar_edge_reject",{reason:"missing_user"}),f(400,"X-Agent-User required");let h=Ok(d,Gn.ASSERTION_HEADER)?.replace(/^Bearer\s+/i,"").trim()||void 0,{nonce:y}=n.registerTurnRaw({userId:m,sessionKey:m,inboundToken:h});return t.audit?.(m,"sidecar_edge_register",{userId:m,assertion:h?`sha256:${ol(h)}`:"none",nonce_sha256_prefix:ol(y)}),u.writeHead(200,{"Content-Type":"application/json",[vk.TURN_NONCE_HEADER]:y}),u.end(JSON.stringify({ok:!0}))}if(d.method==="POST"&&p==="/turns"){let m;try{m=JSON.parse(await(0,ZE.readBodyWithCap)(d))}catch{return f(400,"bad json")}let h=(m.userId??"").trim();if(!h)return f(400,"userId required");let y=m.renewNonce?.trim()||void 0;if(y!==void 0&&!(0,bk.isNonceShaped)(y))return f(400,"renewNonce must be a previously minted turn nonce");let E=m.agent?.pack?.trim(),w=!!(E&&t.agent?.pack&&E!==t.agent.pack);w&&console.warn(`Warning: turn registration claims agent "${E}" but this connector loaded "${t.agent?.pack}". One connector is meant to serve one agent \u2014 both now share this connector's base credential, so neither is bounded by the job it was deployed for.`);let{nonce:O,release:b}=n.registerTurnRaw({userId:h,sessionKey:(m.sessionKey??"").trim()||h,inboundToken:m.inboundToken,egressStoreKey:m.egressStoreKey},{renewNonce:y});return r.set(O,b),t.audit?.((m.sessionKey??"").trim()||h,"sidecar_register",{userId:h,claimedAgent:E??"none",binding:"asserted",nonce_sha256_prefix:ol(O),...y?{renewed:!0}:{},...w?{agentMismatch:!0,loadedAgent:t.agent?.pack}:{}}),u.writeHead(200,{"Content-Type":"application/json"}),u.end(JSON.stringify({nonce:O}))}if(d.method==="DELETE"&&p.startsWith("/turns/")){let m=decodeURIComponent(p.slice(7)),h=r.has(m);return r.get(m)?.(),r.delete(m),t.audit?.("control","sidecar_release",{released:h,nonce_sha256_prefix:ol(m)}),u.writeHead(204),u.end()}f(404,"not found")}catch(p){t.logger?.warn(`[Sidecar] control error: ${p instanceof Error?p.message:String(p)}`),u.headersSent||u.writeHead(500,{"Content-Type":"application/json"}),u.end(JSON.stringify({error:"internal"}))}});await new Promise((d,u)=>{s.once("error",u),s.listen(t.controlPort,e,()=>d())});let i=s.address(),o=i&&typeof i!="string"?i.port:t.controlPort;t.logger?.info(`[Sidecar] gateway ${n.url} | control :${o} (bound ${e})`),(t.config.provider??"passthrough").trim().toLowerCase()==="passthrough"&&console.warn(`Warning: provider=passthrough needs a per-user token on every turn. Edge-registered turns supply it via the ${Gn.ASSERTION_HEADER} header \u2014 if your edge does not forward it, every tool call will fail closed.`);let a,c,l=n.broker.provider;if(t.connectPort!==void 0&&l instanceof e_.StoredGrantProvider){let d=(0,Tk.createConnectHandler)({provider:l,browserUser:p=>(0,ZE.resolveUserId)(p.headers,void 0),audit:t.audit}),u=QE.createServer(async(p,g)=>{try{await d(p,g)||(g.writeHead(404,{"Content-Type":"application/json"}),g.end(JSON.stringify({error:"not found"})))}catch(m){t.logger?.warn(`[Sidecar] connect error: ${m instanceof Error?m.message:String(m)}`),g.headersSent||g.writeHead(500),g.end()}});await new Promise((p,g)=>{u.once("error",g),u.listen(t.connectPort,e,()=>p())});let f=u.address();c=f&&typeof f!="string"?f.port:t.connectPort,a=u,t.logger?.info(`[Sidecar] connect pages :${c} (bound ${e})`)}return{gatewayUrl:n.url,controlPort:o,connectPort:c,...l instanceof e_.StoredGrantProvider?{grants:l}:{},close:async()=>{await new Promise(d=>s.close(()=>d())),a&&await new Promise(d=>a.close(()=>d())),await n.close()}}}});var sf=S(qs=>{"use strict";Object.defineProperty(qs,"__esModule",{value:!0});qs.RemoteDataPlane=qs.EdgeDataPlane=void 0;qs.resolveEdgeDataPlane=Rk;qs.resolveRemoteDataPlane=Ck;var al=fo();function Rk(t=process.env){let e=t.AGENTHIPPO_DATA_PLANE_EDGE?.trim(),n=t.AGENTHIPPO_DATA_MCP_URL?.trim();return!e||e==="0"||e.toLowerCase()==="false"||!n?null:{gatewayUrl:n}}var nf=class{cfg;constructor(e){this.cfg=e}get url(){return this.cfg.gatewayUrl}adoptTurn(e){return{nonce:e,env:{[al.TURN_NONCE_ENV]:e,[al.DATA_MCP_URL_ENV]:this.cfg.gatewayUrl},release:async()=>{try{await fetch(new URL("/turn",this.cfg.gatewayUrl),{method:"DELETE",headers:{Authorization:`Bearer ${e}`}})}catch{}}}}};qs.EdgeDataPlane=nf;function Ck(t=process.env){let e=t.AGENTHIPPO_DATA_PLANE_CONTROL_URL?.trim(),n=t.AGENTHIPPO_DATA_PLANE_TOKEN?.trim(),r=t.AGENTHIPPO_DATA_MCP_URL?.trim();return!e||!n||!r?null:{controlUrl:e,registerToken:n,gatewayUrl:r}}var rf=class{cfg;constructor(e){this.cfg=e}get url(){return this.cfg.gatewayUrl}async registerTurn(e){let n=await fetch(`${this.cfg.controlUrl.replace(/\/$/,"")}/turns`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.cfg.registerToken}`},body:JSON.stringify(e)});if(!n.ok)throw new Error(`data-plane sidecar register failed: HTTP ${n.status}`);let{nonce:r}=await n.json();return{nonce:r,env:{[al.TURN_NONCE_ENV]:r,[al.DATA_MCP_URL_ENV]:this.cfg.gatewayUrl},release:async()=>{try{await fetch(`${this.cfg.controlUrl.replace(/\/$/,"")}/turns/${encodeURIComponent(r)}`,{method:"DELETE",headers:{Authorization:`Bearer ${this.cfg.registerToken}`}})}catch{}}}}};qs.RemoteDataPlane=rf});var Pi=S(W=>{"use strict";var kk=W&&W.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),$k=W&&W.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Dk=W&&W.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&kk(n,e,r[s]);return $k(n,e),n}})();Object.defineProperty(W,"__esModule",{value:!0});W.DataPlane=W.resolveEdgeDataPlane=W.EdgeDataPlane=W.resolveRemoteDataPlane=W.RemoteDataPlane=W.ASSERTION_HEADER=W.startDataPlaneSidecar=W.EGRESS_URL_ENV=W.startEgressBroker=W.TURN_NONCE_HEADER=W.TURN_NONCE_ENV=W.DATA_MCP_URL_ENV=W.startDataGateway=W.TURN_META_KEY=W.ConnectorHost=W.createConnectHandler=W.parseGrantKey=W.GrantStore=W.ConnectError=W.readStoredGrantConfig=W.StoredGrantProvider=W.identityProvider=W.passthroughProvider=W.resolveProvider=W.CredentialBroker=W.DEFAULT_TURN_DEADLINE_MS=W.isNonceShaped=W.hashNonce=W.TurnRegistry=void 0;W.resolveDataPlaneConfig=Hk;var sa=Dk(require("path")),Lk=co(),r_=jd(),Mk=Bd(),of=fo(),Gk=Xt(),cl=co();Object.defineProperty(W,"TurnRegistry",{enumerable:!0,get:function(){return cl.TurnRegistry}});Object.defineProperty(W,"hashNonce",{enumerable:!0,get:function(){return cl.hashNonce}});Object.defineProperty(W,"isNonceShaped",{enumerable:!0,get:function(){return cl.isNonceShaped}});Object.defineProperty(W,"DEFAULT_TURN_DEADLINE_MS",{enumerable:!0,get:function(){return cl.DEFAULT_TURN_DEADLINE_MS}});var ll=jd();Object.defineProperty(W,"CredentialBroker",{enumerable:!0,get:function(){return ll.CredentialBroker}});Object.defineProperty(W,"resolveProvider",{enumerable:!0,get:function(){return ll.resolveProvider}});Object.defineProperty(W,"passthroughProvider",{enumerable:!0,get:function(){return ll.passthroughProvider}});Object.defineProperty(W,"identityProvider",{enumerable:!0,get:function(){return ll.identityProvider}});var cf=ta();Object.defineProperty(W,"StoredGrantProvider",{enumerable:!0,get:function(){return cf.StoredGrantProvider}});Object.defineProperty(W,"readStoredGrantConfig",{enumerable:!0,get:function(){return cf.readStoredGrantConfig}});Object.defineProperty(W,"ConnectError",{enumerable:!0,get:function(){return cf.ConnectError}});var i_=Md();Object.defineProperty(W,"GrantStore",{enumerable:!0,get:function(){return i_.GrantStore}});Object.defineProperty(W,"parseGrantKey",{enumerable:!0,get:function(){return i_.parseGrantKey}});var Uk=Xd();Object.defineProperty(W,"createConnectHandler",{enumerable:!0,get:function(){return Uk.createConnectHandler}});var o_=Bd();Object.defineProperty(W,"ConnectorHost",{enumerable:!0,get:function(){return o_.ConnectorHost}});Object.defineProperty(W,"TURN_META_KEY",{enumerable:!0,get:function(){return o_.TURN_META_KEY}});var ul=fo();Object.defineProperty(W,"startDataGateway",{enumerable:!0,get:function(){return ul.startDataGateway}});Object.defineProperty(W,"DATA_MCP_URL_ENV",{enumerable:!0,get:function(){return ul.DATA_MCP_URL_ENV}});Object.defineProperty(W,"TURN_NONCE_ENV",{enumerable:!0,get:function(){return ul.TURN_NONCE_ENV}});Object.defineProperty(W,"TURN_NONCE_HEADER",{enumerable:!0,get:function(){return ul.TURN_NONCE_HEADER}});var a_=zE();Object.defineProperty(W,"startEgressBroker",{enumerable:!0,get:function(){return a_.startEgressBroker}});Object.defineProperty(W,"EGRESS_URL_ENV",{enumerable:!0,get:function(){return a_.EGRESS_URL_ENV}});var c_=n_();Object.defineProperty(W,"startDataPlaneSidecar",{enumerable:!0,get:function(){return c_.startDataPlaneSidecar}});Object.defineProperty(W,"ASSERTION_HEADER",{enumerable:!0,get:function(){return c_.ASSERTION_HEADER}});var dl=sf();Object.defineProperty(W,"RemoteDataPlane",{enumerable:!0,get:function(){return dl.RemoteDataPlane}});Object.defineProperty(W,"resolveRemoteDataPlane",{enumerable:!0,get:function(){return dl.resolveRemoteDataPlane}});Object.defineProperty(W,"EdgeDataPlane",{enumerable:!0,get:function(){return dl.EdgeDataPlane}});Object.defineProperty(W,"resolveEdgeDataPlane",{enumerable:!0,get:function(){return dl.resolveEdgeDataPlane}});var s_={"personal-connectors":sa.join("skills","personal-connectors","scripts","server.mjs")};function Hk(t,e,n=(0,Gk.findBundledBasePromptsDir)()){let r=t?.dataPlane,s=r?.connector?.trim();if(!s)return;let i=r?.provider?.trim()||void 0;if(s.startsWith("builtin:")){let o=s.slice(8),a=s_[o];if(!a)throw new Error(`Unknown builtin connector "${o}" (known: ${Object.keys(s_).join(", ")})`);if(!n)throw new Error(`connector ${s}: this AgentHippo build ships no base-prompts. Copy the connector into the pack (${sa.dirname(a)}/server.mjs and lib.mjs) and point spec.dataPlane.connector at the copy.`);return{connectorPath:sa.join(n,a),provider:i}}return{connectorPath:sa.isAbsolute(s)?s:sa.join(e,s),provider:i}}var af=class t{url;registry;broker;connector;gateway;constructor(e,n,r,s,i){this.url=e,this.registry=n,this.broker=r,this.connector=s,this.gateway=i}static async start(e,n){let r=n?.registry??new Lk.TurnRegistry,s=new r_.CredentialBroker(n?.provider??(0,r_.resolveProvider)(e.provider)),i=await Mk.ConnectorHost.spawn({connectorPath:e.connectorPath,logger:n?.logger});try{let o=await(0,of.startDataGateway)({registry:r,broker:s,connector:i,logger:n?.logger,audit:n?.audit,host:n?.gateway?.host,port:n?.gateway?.port,advertiseHost:n?.gateway?.advertiseHost});return new t(o.url,r,s,i,o)}catch(o){throw await i.close(),o}}registerTurnRaw(e,n){return this.registry.register(e,n)}registerTurn(e,n){let{nonce:r,release:s}=this.registry.register(e,n);return{nonce:r,env:{[of.TURN_NONCE_ENV]:r,[of.DATA_MCP_URL_ENV]:this.url},release:s}}async close(){await this.gateway.close(),await this.connector.close()}};W.DataPlane=af});var f_=S(gl=>{"use strict";Object.defineProperty(gl,"__esModule",{value:!0});gl.resolveLocalTurnUserId=d_;gl.resolveLocalTurnScope=xk;var l_=Pi(),u_=sf(),fl=fo(),jk=ps();function d_(t=process.env){return t.AGENTHIPPO_DATA_USER?.trim()||(0,jk.currentCredential)()?.userId?.trim()||t.LOGNAME?.trim()||t.USER?.trim()||t.LNAME?.trim()||t.USERNAME?.trim()||void 0}var lf=new WeakMap,pl=class{mode;userId;gatewayUrl;registrar;closePlane;sessionNonce;activeTurns=0;latestRelease;constructor(e,n,r,s,i){this.mode=e,this.userId=n,this.gatewayUrl=r,this.registrar=s,this.closePlane=i}async beginTurn(e){let n=await this.registrar.registerTurn({userId:this.userId,sessionKey:e.sessionKey,renewNonce:this.sessionNonce});this.sessionNonce=n.nonce,this.latestRelease=n.release,this.activeTurns++;let r=!1;return{env:n.env,release:async()=>{if(!r&&(r=!0,this.activeTurns--,this.activeTurns<=0)){let s=this.latestRelease;this.latestRelease=void 0,await s?.()}}}}async close(){await this.closePlane()}};async function xk(t){let e=t.env??process.env,n=i=>{let o=d_(e);if(!o)throw new Error(`${i} is configured but no acting user resolves \u2014 set AGENTHIPPO_DATA_USER (fail-closed: turns register a real identity; there is no anonymous data access)`);return o},r=lf.has(e)?lf.get(e):(0,u_.resolveRemoteDataPlane)(e);if(r){lf.set(e,r);let i=n("The data-plane sidecar"),o=new u_.RemoteDataPlane(r);return delete e.AGENTHIPPO_DATA_PLANE_TOKEN,e[fl.DATA_MCP_URL_ENV]=o.url,new pl("sidecar",i,o.url,{registerTurn:a=>o.registerTurn({...a,agent:t.agent})},async()=>{})}if(e[fl.TURN_NONCE_ENV]?.trim()&&e[fl.DATA_MCP_URL_ENV]?.trim())return console.warn("Warning: using a pre-minted session nonce from the environment (not rotated per turn, expires on the registry deadline). Set AGENTHIPPO_DATA_PLANE_CONTROL_URL + AGENTHIPPO_DATA_PLANE_TOKEN to register real per-turn identities instead."),null;let s=t.packPath?(0,l_.resolveDataPlaneConfig)(t.spec,t.packPath):void 0;if(s){let i=n("The pack's data plane (spec.dataPlane)"),o=await l_.DataPlane.start(s,{logger:t.logger,audit:t.audit});return e[fl.DATA_MCP_URL_ENV]=o.url,new pl("in-process",i,o.url,{registerTurn:async a=>o.registerTurn(a,{renewNonce:a.renewNonce})},()=>o.close())}return null}});var Ii=S(Le=>{"use strict";var Bk=Le&&Le.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),Fk=Le&&Le.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Vk=Le&&Le.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&Bk(n,e,r[s]);return Fk(n,e),n}})();Object.defineProperty(Le,"__esModule",{value:!0});Le.WARRANT_TTL_ENV=Le.DEFAULT_WARRANT_TTL_SECONDS=Le.MAX_TTL_SECONDS=void 0;Le.b64urlEncode=uf;Le.signCompactJws=p_;Le.verifyCompactJws=g_;Le.timingSafeEqualString=Wk;Le.generateWarrantKeypair=Kk;Le.warrantTtlFromEnv=qk;Le.mintWarrant=Yk;Le.verifyWarrant=Jk;Le.jwks=Xk;var ws=Vk(require("node:crypto"));function uf(t){return Buffer.from(t,"utf8").toString("base64url")}function p_(t,e,n){let r={alg:"ES256",typ:t.typ??"JWT",kid:t.kid},s=`${uf(JSON.stringify(r))}.${uf(JSON.stringify(e))}`,i=ws.sign("sha256",Buffer.from(s),{key:ws.createPrivateKey(n),dsaEncoding:"ieee-p1363"});return`${s}.${i.toString("base64url")}`}function g_(t,e,n={}){let r=t.split(".");if(r.length!==3)return{ok:!1,reason:"malformed"};let[s,i,o]=r,a,c;try{a=JSON.parse(Buffer.from(s,"base64url").toString("utf8")),c=JSON.parse(Buffer.from(i,"base64url").toString("utf8"))}catch{return{ok:!1,reason:"unparseable"}}if(a.alg!=="ES256")return{ok:!1,reason:`unsupported alg ${a.alg}`};if(n.typ!==void 0&&a.typ!==void 0&&a.typ!==n.typ)return{ok:!1,reason:`unexpected token type ${a.typ}`};let l=a.kid?e[a.kid]:void 0;if(!l)return{ok:!1,reason:"unknown kid"};let d=!1;try{d=ws.verify("sha256",Buffer.from(`${s}.${i}`),{key:ws.createPublicKey(l),dsaEncoding:"ieee-p1363"},Buffer.from(o,"base64url"))}catch{return{ok:!1,reason:"bad signature"}}return d?{ok:!0,header:a,payload:c,signingInput:`${s}.${i}`}:{ok:!1,reason:"bad signature"}}function Wk(t,e){let n=Buffer.from(t,"utf8"),r=Buffer.from(e,"utf8");return n.length!==r.length?!1:ws.timingSafeEqual(n,r)}function Kk(t){let{privateKey:e,publicKey:n}=ws.generateKeyPairSync("ec",{namedCurve:"P-256"}),r=n.export({type:"spki",format:"pem"}).toString();return{privateKeyPem:e.export({type:"pkcs8",format:"pem"}).toString(),publicKeyPem:r,kid:t??ws.createHash("sha256").update(r).digest("hex").slice(0,16)}}Le.MAX_TTL_SECONDS=86400;Le.DEFAULT_WARRANT_TTL_SECONDS=3600;Le.WARRANT_TTL_ENV="AGENTHIPPO_WARRANT_TTL_SECONDS";function qk(t=process.env){let e=t[Le.WARRANT_TTL_ENV]?.trim();if(e===void 0||e==="")return Le.DEFAULT_WARRANT_TTL_SECONDS;let n=Number(e);return!Number.isFinite(n)||n<=0?Le.DEFAULT_WARRANT_TTL_SECONDS:Math.min(Math.floor(n),Le.MAX_TTL_SECONDS)}function Yk(t,e){let n=t.nowSeconds??Math.floor(Date.now()/1e3),r=Math.min(t.ttlSeconds??120,Le.MAX_TTL_SECONDS),s={user:t.user,pack:t.pack,packVersion:t.packVersion,sandboxId:t.sandboxId,tier:t.tier,aud:t.aud,iat:n,exp:n+r,jti:ws.randomUUID(),...t.billing==="user"?{billing:"user"}:{},...t.budgetKey?{budgetKey:t.budgetKey}:{},...t.budgetWindowSeconds!==void 0&&t.budgetWindowSeconds>0?{budgetWindowSeconds:t.budgetWindowSeconds}:{}};return p_({typ:"JWT",kid:e.kid},s,e.privateKeyPem)}function Jk(t,e,n){let r=g_(t,e);if(!r.ok)return{ok:!1,reason:r.reason};let s=r.payload,i=n.nowSeconds??Math.floor(Date.now()/1e3);return typeof s.exp!="number"||s.exp<=i?{ok:!1,reason:"expired"}:s.aud!==n.audience?{ok:!1,reason:`wrong audience ${s.aud}`}:n.channelSandboxId!==void 0&&s.sandboxId!==n.channelSandboxId?{ok:!1,reason:"warrant not bound to this channel"}:s.user?{ok:!0,claims:s}:{ok:!1,reason:"no principal"}}function Xk(t){return{keys:t.map(e=>({...ws.createPublicKey(e.publicKeyPem).export({format:"jwk"}),kid:e.kid,alg:"ES256",use:"sig"}))}}});var oa=S(le=>{"use strict";Object.defineProperty(le,"__esModule",{value:!0});le.DENY_SCOPE_ALIASES=le.DENY_MODE_ALIASES=le.STRICTEST_DENY_MODE=le.DENY_MODES=le.DENY_SCOPES=le.STRICTEST_ON_BREACH=le.ON_BREACH_ALIASES=le.ON_BREACH_ACTIONS=le.DEPRECATED_CAP_SPELLINGS=le.LEASE_CAP_ALIASES=le.LEASE_CAP_FIELDS=void 0;le.parseCapPolicy=h_;le.parseLease=Zk;le.LEASE_CAP_FIELDS={maxTurnsPerSession:{kind:"positive-int"},maxSessionSeconds:{kind:"positive-int"},maxConcurrentSandboxes:{kind:"positive-int"}};le.LEASE_CAP_ALIASES={maxConcurrentCells:"maxConcurrentSandboxes"};le.DEPRECATED_CAP_SPELLINGS={maxConcurrentCells:"maxConcurrentSandboxes",AGENTHIPPO_MAX_CONCURRENT_CELLS:"AGENTHIPPO_MAX_CONCURRENT_SANDBOXES","destroy-cell":"destroy-sandbox","--max-concurrent-cells":"--max-concurrent-sandboxes"};le.ON_BREACH_ACTIONS={"revoke-inference":{strictness:1},"destroy-sandbox":{strictness:2}};le.ON_BREACH_ALIASES={"destroy-cell":"destroy-sandbox"};le.STRICTEST_ON_BREACH=Object.keys(le.ON_BREACH_ACTIONS).reduce((t,e)=>le.ON_BREACH_ACTIONS[t].strictness>=le.ON_BREACH_ACTIONS[e].strictness?t:e);le.DENY_SCOPES=["session","user","pack"];le.DENY_MODES={drain:{strictness:1},kill:{strictness:2}};le.STRICTEST_DENY_MODE="kill";le.DENY_MODE_ALIASES={};le.DENY_SCOPE_ALIASES={};var ia=t=>typeof t=="object"&&t!==null&&!Array.isArray(t);function zk(t,e){return typeof e!="number"?{ok:!1,reason:`${t} must be a number, got ${typeof e} (${JSON.stringify(e)})`}:Number.isFinite(e)?e<=0?{ok:!1,reason:`${t} must be greater than 0, got ${e} (omit the field for "unbounded")`}:Number.isInteger(e)?{ok:!0,value:e}:{ok:!1,reason:`${t} must be a whole number, got ${e}`}:{ok:!1,reason:`${t} must be finite, got ${e}`}}function h_(t,e="caps"){if(t==null)return{ok:!0,caps:{},warnings:[]};if(!ia(t))return{ok:!1,reason:`${e} must be an object`};let n=[],r={};for(let[i,o]of Object.entries(t)){if(o==null||i==="onBreach")continue;let a=i in le.LEASE_CAP_FIELDS?i:le.LEASE_CAP_ALIASES[i];if(!a){n.push(`${e}.${i} is not a cap this build understands and is NOT being enforced`);continue}let c=zk(`${e}.${i}`,o);if(!c.ok)return{ok:!1,reason:c.reason};r[a]=c.value}let s=t.onBreach;if(s!=null){if(typeof s!="string")return{ok:!1,reason:`${e}.onBreach must be a string, got ${typeof s}`};let i=s in le.ON_BREACH_ACTIONS?s:le.ON_BREACH_ALIASES[s];i?r.onBreach=i:(r.onBreach=le.STRICTEST_ON_BREACH,n.push(`${e}.onBreach="${s}" is not an action this build understands. Failing CLOSED to "${le.STRICTEST_ON_BREACH}" (the strictest known action). Known actions: ${Object.keys(le.ON_BREACH_ACTIONS).join(", ")}.`))}return{ok:!0,caps:r,warnings:n}}function Qk(t,e){if(!ia(t))return{ok:!1,reason:`deny[${e}] must be an object`};let n=[],r=t.scope;if(typeof r!="string")return{ok:!1,reason:`deny[${e}].scope must be a string`};let s=le.DENY_SCOPES.includes(r)?r:le.DENY_SCOPE_ALIASES[r];if(!s)return{ok:!1,reason:`deny[${e}].scope "${r}" is not a scope this build understands (known: ${le.DENY_SCOPES.join(", ")})`};if(typeof t.match!="string"||t.match.length===0)return{ok:!1,reason:`deny[${e}].match must be a non-empty string`};let i=t.mode;if(typeof i!="string")return{ok:!1,reason:`deny[${e}].mode must be a string`};let o=i in le.DENY_MODES?i:le.DENY_MODE_ALIASES[i];o||(o=le.STRICTEST_DENY_MODE,n.push(`deny[${e}].mode="${i}" is not a mode this build understands. Failing CLOSED to "${le.STRICTEST_DENY_MODE}". Known modes: ${Object.keys(le.DENY_MODES).join(", ")}.`));let a={scope:s,match:t.match,mode:o};if(t.reason!==void 0){if(typeof t.reason!="string")return{ok:!1,reason:`deny[${e}].reason must be a string`};a.reason=t.reason}if(t.until!==void 0&&t.until!==null){if(typeof t.until!="number"||!Number.isFinite(t.until))return{ok:!1,reason:`deny[${e}].until must be a finite epoch-seconds number`};a.until=t.until}if(t.user!==void 0&&t.user!==null){if(typeof t.user!="string")return{ok:!1,reason:`deny[${e}].user must be a string`};a.user=t.user}if(t.followUser!==void 0&&t.followUser!==null){if(typeof t.followUser!="boolean")return{ok:!1,reason:`deny[${e}].followUser must be a boolean`};a.followUser=t.followUser}return{ok:!0,rule:a,warnings:n}}function Zk(t){if(!ia(t))return{ok:!1,reason:"lease must be a JSON object"};let e=[];if(typeof t.pack!="string"||t.pack.length===0)return{ok:!1,reason:"lease.pack must be a non-empty string"};if(typeof t.enabled!="boolean")return{ok:!1,reason:`lease.enabled must be a boolean, got ${typeof t.enabled}`};if(typeof t.expiresAt!="number"||!Number.isFinite(t.expiresAt))return{ok:!1,reason:`lease.expiresAt must be a finite epoch-seconds number, got ${JSON.stringify(t.expiresAt)}`};let n={pack:t.pack,enabled:t.enabled,expiresAt:t.expiresAt};for(let r of["version","imageDigest","reason"]){let s=t[r];if(s!=null){if(typeof s!="string")return{ok:!1,reason:`lease.${r} must be a string, got ${typeof s}`};n[r]=s}}for(let r of["requireSignedPack","requireSignedLease","allowServiceTurns","billUsers"]){let s=t[r];if(s!=null){if(typeof s!="boolean")return{ok:!1,reason:`lease.${r} must be a boolean, got ${typeof s}`};n[r]=s}}if(t.budget!==void 0&&t.budget!==null){let r=t.budget;if(typeof r!="object"||Array.isArray(r))return{ok:!1,reason:"lease.budget must be an object"};let s=r.scope;if(s!=="session"&&s!=="user")return{ok:!1,reason:`lease.budget.scope must be 'session' or 'user', got ${JSON.stringify(s)}`};let i=r.windowSeconds;if(i!=null&&(typeof i!="number"||!Number.isFinite(i)||i<0))return{ok:!1,reason:"lease.budget.windowSeconds must be a non-negative number"};n.budget={scope:s,...typeof i=="number"&&i>0?{windowSeconds:i}:{}}}if(t.caps!==void 0&&t.caps!==null){let r=h_(t.caps,"lease.caps");if(!r.ok)return{ok:!1,reason:r.reason};n.caps=r.caps,e.push(...r.warnings)}if(t.deny!==void 0&&t.deny!==null){if(!Array.isArray(t.deny))return{ok:!1,reason:"lease.deny must be an array"};let r=[];for(let s=0;s<t.deny.length;s++){let i=Qk(t.deny[s],s);if(!i.ok)return{ok:!1,reason:i.reason};r.push(i.rule),e.push(...i.warnings)}n.deny=r}if(t.grants!==void 0&&t.grants!==null){let r=ia(t.grants)?t.grants.revoke:void 0;if(!Array.isArray(r))e.push("lease.grants.revoke is not an array \u2014 ignored");else{let s=[];for(let[i,o]of r.entries()){if(!ia(o)||typeof o.user!="string"||!/^[0-9a-f]{64}$/.test(o.user)||typeof o.requestedAt!="number"||!Number.isFinite(o.requestedAt)||o.service!==void 0&&o.service!=="google"&&o.service!=="bank"){e.push(`lease.grants.revoke[${i}] is malformed \u2014 ignored`);continue}s.push({user:o.user,requestedAt:o.requestedAt,...o.service?{service:o.service}:{}})}n.grants={revoke:s}}}return t.issuedAt!==void 0&&t.issuedAt!==null&&(typeof t.issuedAt=="number"&&Number.isFinite(t.issuedAt)?n.issuedAt=t.issuedAt:e.push("lease.issuedAt is not a finite number \u2014 ignored")),t.deployment!==void 0&&t.deployment!==null&&(typeof t.deployment=="string"&&t.deployment.length>0?n.deployment=t.deployment:e.push("lease.deployment is not a non-empty string \u2014 ignored")),{ok:!0,lease:n,warnings:e}}});var ho=S(j=>{"use strict";var e$=j&&j.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),t$=j&&j.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),ff=j&&j.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&e$(n,e,r[s]);return t$(n,e),n}})();Object.defineProperty(j,"__esModule",{value:!0});j.PACK_FULL_REVERIFY_INTERVAL_MS=j.PACK_PROBE_INTERVAL_MS=j.LEASE_JWKS_PINS_ENV=j.LEASE_JWKS_URL_ENV=j.LEASE_SIGNING_KEYS_ENV=j.ALLOW_INSECURE_TRUST_ROOT_ENV=j.PACK_JWKS_PINS_ENV=j.PACK_JWKS_URL_ENV_LEGACY=j.PACK_JWKS_URL_ENV=j.ALLOW_UNSIGNED_PACK_ENV=j.DIGEST_EXCLUDED_SEGMENTS=j.PACK_SIGNATURE_FILE=void 0;j.isDigestExcluded=ml;j.computePackDigestFromFiles=E_;j.computePackDigest=pf;j.packTreeProbe=df;j.signPack=n$;j.readPackSignature=__;j.verifyPack=y_;j.verifyPackFromFiles=r$;j.requireSignedPack=S_;j.resolveRequireSignedPack=i$;j.allowUnsignedPackFromEnv=o$;j.describePackRefusal=a$;j.publicKeyThumbprints=A_;j.parseJwksPins=b_;j.assertSecureTrustUrl=T_;j.loadPackTrustRoot=O_;j.loadLeaseTrustRoot=d$;j.selectLeaseSigningKeys=f$;j.checkTrustRootSeparation=p$;j.loadPackSigningKeys=h$;j.createPackVerifier=m$;var go=ff(require("node:crypto")),Ys=ff(require("node:fs")),hl=ff(require("node:path")),aa=Ii();j.PACK_SIGNATURE_FILE="pack.sig";j.DIGEST_EXCLUDED_SEGMENTS=new Set([".git","node_modules"]);function ml(t){return t===j.PACK_SIGNATURE_FILE?!0:t.split("/").some(e=>j.DIGEST_EXCLUDED_SEGMENTS.has(e))}function m_(t){let e=go.createHash("sha256"),n=[...t].sort((r,s)=>r.rel<s.rel?-1:r.rel>s.rel?1:0);for(let r of n){r.link&&e.update("L:");let s=Buffer.from(r.rel);e.update(`${s.length}:`),e.update(s),e.update(`${r.body.length}:`),e.update(r.body)}return e.digest("hex")}function E_(t){let e=[];for(let n of t){let r=n.path.replace(/\\/g,"/");ml(r)||e.push({rel:r,body:n.content,link:n.link})}return m_(e)}function pf(t){let e=[],n=(r,s)=>{for(let i of Ys.readdirSync(r)){let o=s?`${s}/${i}`:i;if(ml(o))continue;let a=hl.join(r,i),c=Ys.lstatSync(a);c.isSymbolicLink()?e.push({rel:o,body:Buffer.from(Ys.readlinkSync(a)),link:!0}):c.isDirectory()?n(a,o):c.isFile()&&e.push({rel:o,body:Ys.readFileSync(a)})}};return n(t,""),m_(e)}function df(t){let e=[],n=(r,s)=>{let i;try{i=Ys.readdirSync(r).sort()}catch{e.push(`${s}/?unreadable`);return}for(let o of i){let a=s?`${s}/${o}`:o;if(ml(a))continue;let c=hl.join(r,o),l;try{l=Ys.lstatSync(c)}catch{e.push(`${a}|gone`);continue}if(l.isDirectory()){n(c,a);continue}e.push(`${a}|${l.size}|${l.mtimeMs}|${l.ino}|${l.mode}`)}};try{n(t,"")}catch{return"unwalkable"}return go.createHash("sha256").update(e.join(`
483
483
  `)).digest("hex")}function n$(t){let e=pf(t.packDir),n={pack:t.pack,packVersion:t.packVersion,digest:e,iat:t.nowSeconds??Math.floor(Date.now()/1e3)},r=(0,aa.signCompactJws)({typ:"JWT",kid:t.kid},n,t.privateKeyPem);return Ys.writeFileSync(hl.join(t.packDir,j.PACK_SIGNATURE_FILE),`${r}
484
484
  `),{signature:r,digest:e}}function __(t){try{return Ys.readFileSync(hl.join(t,j.PACK_SIGNATURE_FILE),"utf8").trim()||void 0}catch{return}}function y_(t,e,n){return w_(t,e,n.pack,n.packVersion,()=>pf(n.packDir))}function r$(t,e,n,r,s){return w_(t,e,n,r,()=>E_(s))}function w_(t,e,n,r,s){if(Object.keys(e).length===0)return{ok:!1,kind:"no-trust-root",reason:"no trusted pack-signing keys are configured on this instance"};let i=(0,aa.verifyCompactJws)(t,e);if(!i.ok)return i.reason==="unknown kid"?{ok:!1,kind:"unknown-key",reason:`unknown signing key ${s$(t)??"(none named)"}`}:i.reason==="bad signature"?{ok:!1,kind:"bad-signature",reason:"signature does not verify"}:i.reason==="malformed"?{ok:!1,kind:"malformed",reason:"malformed signature"}:i.reason==="unparseable"?{ok:!1,kind:"malformed",reason:"unreadable signature"}:{ok:!1,kind:"malformed",reason:i.reason};let o=i.payload;return o.pack!==n?{ok:!1,kind:"identity-mismatch",reason:`signature is for pack ${o.pack}, not ${n}`}:o.packVersion!==r?{ok:!1,kind:"identity-mismatch",reason:`signature is for ${o.pack}@${o.packVersion}, not @${r}`}:typeof o.digest!="string"||!o.digest?{ok:!1,kind:"malformed",reason:"signature carries no digest"}:(0,aa.timingSafeEqualString)(s(),o.digest)?{ok:!0,claims:o}:{ok:!1,kind:"digest-mismatch",reason:"pack contents changed after signing"}}function s$(t){try{return JSON.parse(Buffer.from(t.split(".")[0],"base64url").toString("utf8")).kid}catch{return}}function S_(t,e){return!!t||!!e}j.ALLOW_UNSIGNED_PACK_ENV="AGENTHIPPO_ALLOW_UNSIGNED_PACK";function i$(t){return S_(t.lease,t.localRequire)?!0:!t.localAllowUnsigned}function o$(t=process.env){let e=t[j.ALLOW_UNSIGNED_PACK_ENV]?.trim().toLowerCase();return e==="1"||e==="true"||e==="yes"}function a$(t){let n=[`refusing to run ${t.packVersion?`${t.pack}@${t.packVersion}`:t.pack}: ${t.detail}`];switch(t.kind){case"unsigned":n.push(` The pack directory has no ${j.PACK_SIGNATURE_FILE}${t.packDir?` at ${t.packDir}`:""}.`,` Sign it: agenthippo pack sign ${t.pack} --key <private-key.pem> --kid <key-id>`," (generate a key with: agenthippo pack keygen -o key.pem, then publish its public half to JWKS)");break;case"no-trust-root":n.push(" This is NOT a problem with the pack \u2014 this instance has no keys to check it against."," Configure ONE of:",' AGENTHIPPO_PACK_SIGNING_KEYS inline JSON {"<kid>":"<public PEM>"} (air-gapped installs)',` ${j.PACK_JWKS_URL_ENV} https URL of the JWKS document publishing your signing keys`,` ${j.PACK_JWKS_PINS_ENV} optional, comma-separated sha256 thumbprints to pin those keys to`);break;case"trust-root-unavailable":n.push(" A trust root IS configured but could not be loaded, so no signature can be checked.",` ${t.trustRootHint??""}`.trimEnd(),' This is deliberately an error and not an empty keyring: "cannot reach the trust root" and',' "no trust root configured" have different causes and different fixes.');break;case"unknown-key":n.push(" The pack IS signed, but by a key this fleet does not trust."," Either publish that key to your JWKS / AGENTHIPPO_PACK_SIGNING_KEYS, or re-sign the pack"," with a key that is already trusted. A key is never trusted just because it arrived with the pack.");break;case"digest-mismatch":n.push(" The signature is valid but the pack tree no longer matches it \u2014 something changed after signing."," Note that .claude/, .codex/ and .agent-hippo/ are now INSIDE the digest (they carry hooks and"," other executable content), so edits there invalidate a signature that used to survive them.",` Re-sign after reviewing the diff: agenthippo pack sign ${t.pack} --key <private-key.pem> --kid <key-id>`);break;case"identity-mismatch":n.push(" The signature is valid but names a different pack or version \u2014 a replayed signature, not this artifact.");break;case"malformed":case"bad-signature":n.push(` ${j.PACK_SIGNATURE_FILE} is present but unusable. Re-sign the pack; do not hand-edit it.`);break;case"no-pack":break}return n.push(` To run unsigned packs anyway (LOCAL DEVELOPMENT ONLY), set ${j.ALLOW_UNSIGNED_PACK_ENV}=1.`," A lease that sets requireSignedPack overrides that escape hatch \u2014 the control plane's demand cannot be waived locally."),n.join(`
485
- `)}j.PACK_JWKS_URL_ENV="AGENTHIPPO_PACK_JWKS_URL";j.PACK_JWKS_URL_ENV_LEGACY="AGENTHIPPO_PACK_SIGNING_JWKS_URL";j.PACK_JWKS_PINS_ENV="AGENTHIPPO_PACK_JWKS_PINS";j.ALLOW_INSECURE_TRUST_ROOT_ENV="AGENTHIPPO_ALLOW_INSECURE_TRUST_ROOT";j.LEASE_SIGNING_KEYS_ENV="AGENTHIPPO_LEASE_SIGNING_KEYS";j.LEASE_JWKS_URL_ENV="AGENTHIPPO_LEASE_JWKS_URL";j.LEASE_JWKS_PINS_ENV="AGENTHIPPO_LEASE_JWKS_PINS";function A_(t){let e=go.createPublicKey(t),n=e.export({format:"jwk"}),r=n.kty==="EC"?{crv:n.crv,kty:n.kty,x:n.x,y:n.y}:n.kty==="RSA"?{e:n.e,kty:n.kty,n:n.n}:{kty:n.kty};return{jwk:go.createHash("sha256").update(JSON.stringify(r)).digest("base64url"),spki:go.createHash("sha256").update(e.export({type:"spki",format:"der"})).digest("hex")}}var c$=t=>t.trim().replace(/^sha256:/i,"").toLowerCase();function b_(t){return(t??"").split(",").map(c$).filter(e=>e.length>0)}function T_(t,e,n=process.env){let r;try{r=new URL(t)}catch{return{ok:!1,reason:`${e} is not a valid URL: ${t}`}}if(r.protocol==="https:")return{ok:!0,warnings:[]};let s=(n[j.ALLOW_INSECURE_TRUST_ROOT_ENV]??"").trim().toLowerCase();return s==="1"||s==="true"||s==="yes"?{ok:!0,warnings:[`INSECURE: ${e} is ${r.protocol}//${r.host} (not https) and ${j.ALLOW_INSECURE_TRUST_ROOT_ENV} is set. Anyone on the path between this instance and that host can choose which packs it will run and whether the kill switch is honoured. This must never be set outside local development.`]}:{ok:!1,reason:`${e} must be https (got ${r.protocol}//${r.host}). Set ${j.ALLOW_INSECURE_TRUST_ROOT_ENV}=1 to allow plaintext for LOCAL DEVELOPMENT ONLY.`}}var l$={label:"pack",purpose:"pack-signing",inlineEnv:"AGENTHIPPO_PACK_SIGNING_KEYS",urlEnvs:[j.PACK_JWKS_URL_ENV,j.PACK_JWKS_URL_ENV_LEGACY],pinsEnv:j.PACK_JWKS_PINS_ENV,derivedRisk:"chooses which packs this instance will run"},u$={label:"lease",purpose:"lease-signing",inlineEnv:j.LEASE_SIGNING_KEYS_ENV,urlEnvs:[j.LEASE_JWKS_URL_ENV],pinsEnv:j.LEASE_JWKS_PINS_ENV,derivedRisk:"chooses whether this instance's kill switch is ever honoured"};async function v_(t,e){let n=e.env??process.env,r=[],s=b_(n[t.pinsEnv]),i=n[t.inlineEnv]?.trim(),o=t.urlEnvs.map(f=>n[f]).find(f=>f!==void 0&&f.trim()!=="")?.trim(),a=!!i||!!o,c=(f,p,g)=>{if(s.length===0)return Object.keys(f).length===0?{status:"unavailable",keys:{},source:p,url:g,warnings:r,explicitlyConfigured:a,reason:"the trust root published no usable ES256 keys"}:{status:"configured",keys:f,source:p,url:g,warnings:r,explicitlyConfigured:a};let m={};for(let[h,y]of Object.entries(f)){let E;try{E=A_(y)}catch{r.push(`${t.label} trust root: key ${h} is unreadable and was dropped`);continue}s.some(O=>(0,aa.timingSafeEqualString)(O,E.jwk.toLowerCase())||(0,aa.timingSafeEqualString)(O,E.spki))?m[h]=y:r.push(`${t.label} trust root: key ${h} does not match any pin in ${t.pinsEnv} and was REFUSED (its thumbprints are jwk=${E.jwk} spki=${E.spki})`)}return Object.keys(m).length===0?{status:"unavailable",keys:{},source:p,url:g,warnings:r,explicitlyConfigured:a,reason:`every key offered by the trust root failed the ${t.pinsEnv} pin check`}:{status:"configured",keys:m,source:p,url:g,warnings:r,explicitlyConfigured:a}};if(i){let f;try{f=JSON.parse(i)}catch(p){return{status:"unavailable",keys:{},source:"inline",warnings:r,explicitlyConfigured:a,reason:`${t.inlineEnv} is set but is not valid JSON: ${p instanceof Error?p.message:String(p)}`}}return c(f,"inline")}let l=o,d=!1;if(!l&&e.leaseUrl){try{l=new URL(`/.well-known/jwks.json?purpose=${t.purpose}`,e.leaseUrl).toString()}catch{return{status:"unavailable",keys:{},warnings:r,explicitlyConfigured:a,reason:`AGENTHIPPO_LEASE_URL is not a valid URL: ${e.leaseUrl}`}}d=!0}if(!l)return{status:"unconfigured",keys:{},warnings:r,explicitlyConfigured:a};let u=T_(l,`the ${t.purpose} JWKS URL`,n);if(!u.ok)return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:u.reason,derivedFromLease:d,explicitlyConfigured:a};r.push(...u.warnings),d&&s.length===0&&r.push(`${t.label} trust root is derived from AGENTHIPPO_LEASE_URL (${l}) and is not pinned. Whoever can answer that origin ${t.derivedRisk}. Pin it with ${t.urlEnvs[0]} and ${t.pinsEnv}.`);try{let f=await(e.fetchImpl??fetch)(l);if(!f.ok)return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:`JWKS fetch returned HTTP ${f.status}`,derivedFromLease:d,explicitlyConfigured:a};let p=await f.json(),g=g$(p);return g.ok?{...c(g.pems,"jwks",l),derivedFromLease:d}:{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:g.reason,derivedFromLease:d,explicitlyConfigured:a}}catch(f){return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,derivedFromLease:d,explicitlyConfigured:a,reason:`JWKS fetch failed: ${f instanceof Error?f.message:String(f)}`}}}async function O_(t){return v_(l$,t)}async function d$(t){return v_(u$,t)}function f$(t,e){return t.explicitlyConfigured?{keys:t.keys,packFallback:!1}:{keys:{...e.keys,...t.keys},packFallback:!0}}function p$(t,e){let n=[];if(!t.explicitlyConfigured)return{warnings:n};if(t.url){let s=null;try{s=new URL(t.url).searchParams.get("purpose")}catch{}if(s!==null&&s!=="lease-signing")return{warnings:n,fatal:`${j.LEASE_JWKS_URL_ENV} points at a '${s}' document (${t.url}). A plane that separates keys by purpose never serves a lease-signing key there, so signed-lease verification breaks at the next lease-key rotation \u2014 and requireSignedLease is sticky with no plane-side undo. Point it at ?purpose=lease-signing (with its own ${j.LEASE_JWKS_PINS_ENV}) instead.`};s===null&&e.url===t.url&&n.push(`the lease trust root and the pack trust root are the SAME document (${t.url}). An older plane that returns every key it holds supports this; a plane that separates keys by purpose does not, and the break lands at the next lease-key rotation, after requireSignedLease has latched. Give the lease root its own URL: ?purpose=lease-signing.`)}let r=Object.keys(t.keys).filter(s=>e.keys[s]!==void 0&&e.keys[s].trim()===t.keys[s].trim());return r.length>0&&n.push(`kid(s) ${r.map(s=>`'${s}'`).join(", ")} carry the same public key in BOTH the lease and the pack trust root \u2014 one key under two purposes. The control plane refuses to register such a key, so whichever purpose rotates first strands the other; give each purpose its own keypair.`),{warnings:n}}function g$(t){if(t.pemsByKid&&typeof t.pemsByKid=="object")return{ok:!0,pems:t.pemsByKid};if(!Array.isArray(t.keys))return{ok:!1,reason:"JWKS document has neither `pemsByKid` nor a `keys` array"};let e={};for(let n of t.keys)if(!(!n||typeof n!="object")&&!(n.kty!=="EC"||n.crv!=="P-256")&&!(n.alg!==void 0&&n.alg!=="ES256")&&!(typeof n.kid!="string"||!n.kid))try{e[n.kid]=go.createPublicKey({key:n,format:"jwk"}).export({type:"spki",format:"pem"}).toString()}catch{}return Object.keys(e).length===0?{ok:!1,reason:"JWKS document published no usable ES256 (P-256) keys"}:{ok:!0,pems:e}}async function h$(t){return(await O_(t)).keys}j.PACK_PROBE_INTERVAL_MS=1e3;j.PACK_FULL_REVERIFY_INTERVAL_MS=3e4;function m$(t={}){let e=t.probeIntervalMs??j.PACK_PROBE_INTERVAL_MS,n=t.fullReverifyIntervalMs??j.PACK_FULL_REVERIFY_INTERVAL_MS,r,s="",i="",o=0,a=0,c=0,l=u=>`${u.packDir}\0${u.pack}\0${u.packVersion}\0${Object.keys(u.keys).sort().join(",")}`,d=(u,f)=>{c+=1,s=l(u),i=df(u.packDir),o=f,a=f;let p=__(u.packDir);return r=p?y_(p,u.keys,{packDir:u.packDir,pack:u.pack,packVersion:u.packVersion}):{ok:!1,kind:"unsigned",reason:`${u.pack} is not signed (no ${j.PACK_SIGNATURE_FILE} at the pack root)`},r};return{fullVerifications:()=>c,refresh(u,f=Date.now()){return d(u,f)},verify(u,f=Date.now()){return!r||s!==l(u)||f-a>=n?d(u,f):f-o<e||(o=f,df(u.packDir)===i)?r:d(u,f)}}}});var mo=S(se=>{"use strict";Object.defineProperty(se,"__esModule",{value:!0});se.MAX_LEASE_ENVELOPE_TTL_SECONDS=se.LEASE_JWS_TYP=se.LeaseDeniedError=se.LEASE_MAX_STALENESS_ENV=se.DEFAULT_LEASE_MAX_STALENESS_SECONDS=se.MIN_LEASE_POLL_SECONDS=se.DEFAULT_LEASE_POLL_SECONDS=void 0;se.resolveLeasePollSeconds=gf;se.leaseCacheSecondsFor=hf;se.effectiveKillLatencySeconds=y$;se.leaseMaxStalenessFromEnv=R_;se.resolveAllowServiceTurns=w$;se.describeServiceTurnGate=S$;se.denyVerdict=C_;se.resolveFollowedUsers=b$;se.leaseIsDead=T$;se.policyVersion=v$;se.assertAdmitted=O$;se.signLease=P$;se.verifySignedLease=$_;se.requireSignedLease=D_;se.leaseUrlDeployment=L_;se.createLeaseSource=N$;var E$=require("crypto"),I_=Ii(),N_=oa(),_$=ho();se.DEFAULT_LEASE_POLL_SECONDS=30;se.MIN_LEASE_POLL_SECONDS=5;function gf(t){let e=typeof t=="number"&&Number.isFinite(t)?t:se.DEFAULT_LEASE_POLL_SECONDS;return Math.max(se.MIN_LEASE_POLL_SECONDS,Math.floor(e))}function hf(t){return gf(t)}function y$(t){let e=gf(t);return e+hf(e)}se.DEFAULT_LEASE_MAX_STALENESS_SECONDS=1440*60;se.LEASE_MAX_STALENESS_ENV="AGENTHIPPO_LEASE_MAX_STALENESS_SECONDS";function R_(t=process.env){let e=t[se.LEASE_MAX_STALENESS_ENV]?.trim();if(e===void 0||e==="")return se.DEFAULT_LEASE_MAX_STALENESS_SECONDS;let n=Number(e);return!Number.isFinite(n)||n<0?se.DEFAULT_LEASE_MAX_STALENESS_SECONDS:Math.floor(n)}function w$(t){return t.managed?t.lease===!0?{allowed:!0,gate:"lease_allows"}:{allowed:!1,gate:t.lease===!1?"lease_denies":"lease_absent_field"}:{allowed:!0,gate:"unmanaged_no_lease"}}function S$(t){switch(t){case"lease_allows":return"permitted by the control plane (lease.allowServiceTurns)";case"unmanaged_no_lease":return"permitted: no control plane configured, so AGENTHIPPO_SERVICE_USER is the only gate";case"lease_denies":return"refused: the control plane set lease.allowServiceTurns=false";case"lease_absent_field":return"refused: this is a managed deployment and the lease does not set allowServiceTurns (absent means deny \u2014 enable it in the console)"}}function C_(t,e,n){if(!t?.deny?.length)return{denied:!1};let r=n??Math.floor(Date.now()/1e3),s=e.sessionKey.indexOf("--"),i=s>=0?e.sessionKey.slice(s+2):e.sessionKey,o={denied:!1};for(let a of t.deny){if(a.until!==void 0&&a.until<=r)continue;let c=!1;if(a.scope==="pack"?c=a.match===e.pack:a.scope==="session"?(c=a.match===e.sessionKey||a.match===i,c&&a.user!==void 0&&e.userId!==void 0&&a.user!==e.userId&&(c=!1),!c&&a.followUser!==!1&&e.userId!==void 0&&A$(a,e.userId,e.followedUsers)&&(c=!0)):a.scope==="user"&&(c=e.userId!==void 0&&a.match===e.userId||e.userHash!==void 0&&e.sessionKey.startsWith(`u${e.userHash(a.match)}--`)),!c)continue;let l=`${a.mode==="kill"?"stopped":"draining"} by the control plane${a.reason?`: ${a.reason}`:""}`;if(a.mode==="kill")return{denied:!0,mode:"kill",reason:l};o.denied||(o={denied:!0,mode:"drain",reason:l})}return o}var k_=t=>`${t.scope}:${t.match}`;function A$(t,e,n){return n?.get(k_(t))?.has(e)??!1}function b$(t,e,n){let r=new Map;if(!t?.deny?.length)return r;let s=n??Math.floor(Date.now()/1e3);for(let i of t.deny){if(i.scope!=="session"||i.followUser===!1||i.until!==void 0&&i.until<=s)continue;let o=new Set;for(let[a,c]of e){let l=a.indexOf("--"),d=l>=0?a.slice(l+2):a;i.match!==a&&i.match!==d||i.user!==void 0&&i.user!==c||o.add(c)}o.size>0&&r.set(k_(i),o)}return r}function T$(t,e){if(!t)return{dead:!1};let n=e??Math.floor(Date.now()/1e3);return t.enabled?t.expiresAt<=n?{dead:!0,reason:`lease expired at ${new Date(t.expiresAt*1e3).toISOString()}`}:{dead:!1}:{dead:!0,reason:`kill switch active${t.reason?`: ${t.reason}`:""}`}}function v$(t){if(!t)return;let{expiresAt:e,...n}=t,r=s=>Array.isArray(s)?s.map(r):s&&typeof s=="object"?Object.fromEntries(Object.keys(s).sort().map(i=>[i,r(s[i])])):s;return(0,E$.createHash)("sha256").update(JSON.stringify(r(n))).digest("hex")}var Ss=class extends Error{constructor(e){super(e),this.name="LeaseDeniedError"}};se.LeaseDeniedError=Ss;function O$(t,e){if(!t)return;let n=e.nowSeconds??Math.floor(Date.now()/1e3);if(!t.enabled)throw new Ss(`kill switch active for pack ${e.pack}${t.reason?`: ${t.reason}`:""}`);if(t.pack!==e.pack)throw new Ss(`lease is for pack ${t.pack}, not ${e.pack}`);if(t.expiresAt<=n)throw new Ss(`lease for ${e.pack} expired at ${new Date(t.expiresAt*1e3).toISOString()}`);if(t.version&&t.version!==e.version)throw new Ss(`pack ${e.pack} is pinned to ${t.version}; refusing to start ${e.version} (rollback in force)`);if(t.imageDigest&&e.image&&!e.image.includes(t.imageDigest))throw new Ss(`image for ${e.pack} does not match the leased digest ${t.imageDigest}`);if(e.sessionKey){let r=C_(t,{sessionKey:e.sessionKey,pack:e.pack,userHash:e.userHash,userId:e.userId,followedUsers:e.followedUsers},n);if(r.denied)throw new Ss(r.reason??"stopped by the control plane")}}se.LEASE_JWS_TYP="agenthippo-lease+jws";se.MAX_LEASE_ENVELOPE_TTL_SECONDS=3600;function P$(t,e,n){let r=n.nowSeconds??Math.floor(Date.now()/1e3),s=Math.min(n.ttlSeconds??300,se.MAX_LEASE_ENVELOPE_TTL_SECONDS),i={lease:t,aud:n.instanceId??"*",sub:t.pack,iat:r,exp:r+s,...n.iss?{iss:n.iss}:{}};return(0,I_.signCompactJws)({typ:se.LEASE_JWS_TYP,kid:e.kid},i,e.privateKeyPem)}function $_(t,e,n={}){if(Object.keys(e).length===0)return{ok:!1,reason:"no trusted lease-signing keys are configured on this instance"};let r=(0,I_.verifyCompactJws)(t,e,{typ:se.LEASE_JWS_TYP});if(!r.ok)return{ok:!1,reason:`lease signature: ${r.reason}`};let s=r.payload,i=n.nowSeconds??Math.floor(Date.now()/1e3),o=n.clockSkewSeconds??60;if(typeof s.iat!="number"||!Number.isFinite(s.iat))return{ok:!1,reason:"lease envelope has no issued-at"};if(typeof s.exp!="number"||!Number.isFinite(s.exp))return{ok:!1,reason:"lease envelope has no expiry"};if(s.exp-s.iat>se.MAX_LEASE_ENVELOPE_TTL_SECONDS)return{ok:!1,reason:`lease envelope lifetime ${s.exp-s.iat}s exceeds the ${se.MAX_LEASE_ENVELOPE_TTL_SECONDS}s cap`};if(s.exp+o<=i)return{ok:!1,reason:`lease envelope expired at ${new Date(s.exp*1e3).toISOString()}`};if(s.iat-o>i)return{ok:!1,reason:"lease envelope is issued in the future"};if(n.minIat!==void 0&&s.iat<n.minIat)return{ok:!1,reason:`lease envelope is older than one already accepted (replay/rollback: iat ${s.iat} < ${n.minIat})`};if(n.instanceId!==void 0&&s.aud!=="*"&&s.aud!==n.instanceId)return{ok:!1,reason:`lease envelope is for instance ${s.aud}, not ${n.instanceId}`};let a=(0,N_.parseLease)(s.lease);return a.ok?s.sub!==a.lease.pack?{ok:!1,reason:`lease envelope subject ${s.sub} does not match lease.pack ${a.lease.pack}`}:{ok:!0,lease:a.lease,claims:s}:{ok:!1,reason:`signed lease is malformed: ${a.reason}`}}function D_(t,e){return!!t||!!e}var P_=t=>/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t),I$=2e4;function L_(t){if(t)try{let e=/\/lease\/([^/]+)\.json$/.exec(new URL(t).pathname);return e?decodeURIComponent(e[1]):void 0}catch{return}}function N$(t){let e=t.staticLease,n=0,r,s,i=!1,o=!1,a,c=L_(t.url),l=!1,d,u=!1,f=!1,p=!1,g=!1,m=t.cacheSeconds??hf(se.DEFAULT_LEASE_POLL_SECONDS),h=t.maxStalenessSeconds??R_(t.env),y=t.fetchImpl??fetch,E=()=>D_(l,t.requireSignedLease),w=I=>({...e??{pack:"",expiresAt:0},enabled:!1,reason:`the control plane has not been reachable for ${I}s, past the ${h}s staleness ceiling (${se.LEASE_MAX_STALENESS_ENV}). Refusing work rather than running on a lease that can no longer be revoked. Set ${se.LEASE_MAX_STALENESS_ENV}=0 to accept unbounded staleness.`}),O=()=>({pack:"",expiresAt:0,enabled:!1,reason:`this instance is managed (${t.url}) but has never successfully fetched its lease`+(s?` (${s})`:"")+". Refusing work until the control plane is reachable rather than booting ungoverned. For an air-gapped deployment, provide the lease with --static-lease."}),b=!1,v=I=>{if(b=!0,!t.persistence)return;let k;try{k=t.persistence.load()}catch(T){t.logger?.warn(`[Lease] persisted lease unreadable: ${T instanceof Error?T.message:String(T)}`);return}if(!k||typeof k.body!="string")return;typeof k.lastGoodAt=="number"&&Number.isFinite(k.lastGoodAt)&&(r=Math.min(k.lastGoodAt,I));let P=N(k.body,I);if(!P.ok){t.logger?.warn(`[Lease] persisted lease not reinstalled: ${P.reason}`);return}P.signed&&(i=!0,P.lease.requireSignedLease&&(l=!0)),e=P.lease,o=P.signed,a=void 0},A=I=>I.deployment!==void 0&&c!==void 0&&I.deployment!==c?`lease is for deployment ${I.deployment}, not ${c} (${t.url})`:void 0,N=(I,k)=>{let P=I.trim(),T,K;if(P_(P))T=P;else{try{K=JSON.parse(P)}catch(J){return{ok:!1,reason:`lease body is not JSON: ${J instanceof Error?J.message:String(J)}`}}typeof K=="string"&&P_(K.trim())?T=K.trim():K&&typeof K=="object"&&typeof K.lease=="string"&&(T=K.lease.trim())}if(T){let J=$_(T,t.signingKeys?.()??{},{instanceId:t.instanceId,minIat:d,nowSeconds:k});if(!J.ok)return{ok:!1,reason:J.reason};let oe=A(J.lease);return oe?{ok:!1,reason:oe}:(d=J.claims.iat,{ok:!0,lease:J.lease,signed:!0})}if(E())return{ok:!1,reason:'a signed lease is required but the control plane returned an unsigned one (expected a compact JWS body or {"lease":"<jws>"})'};let B=(0,N_.parseLease)(K);if(!B.ok)return{ok:!1,reason:B.reason};for(let J of B.warnings)t.logger?.warn(`[Lease] ${J}`);let ne=A(B.lease);return ne?{ok:!1,reason:ne}:{ok:!0,lease:B.lease,signed:!1}};return{status(I){let k=I??Math.floor(Date.now()/1e3),P=r===void 0?void 0:k-r,T=!!t.url&&e===void 0&&s!==void 0;return{signed:i,currentSigned:o,clockOffsetSeconds:a,requireSignedLease:E(),lastGoodAt:r,stalenessSeconds:P,maxStalenessSeconds:h,failClosed:T||h>0&&P!==void 0&&P>h,lastError:s}},async get(I){let k=I??Math.floor(Date.now()/1e3);if(!t.url)return e;if(!g){g=!0;let P=(0,_$.assertSecureTrustUrl)(t.url,"AGENTHIPPO_LEASE_URL",t.env??process.env);if(P.ok)for(let T of P.warnings)t.logger?.warn(`[Lease] ${T}`);else E()?t.logger?.warn(`[Lease] INSECURE LEASE CHANNEL \u2014 ${P.reason} Signed leases are required here, so the policy itself is still verified \u2014 but the channel is not: anyone on the path can read this instance's identity, pack and version, and can delay a kill switch by up to ${se.MAX_LEASE_ENVELOPE_TTL_SECONDS}s by replaying the last envelope. requireSignedLease is not a substitute for https; serve the lease over https.`):t.logger?.warn(`[Lease] INSECURE LEASE CHANNEL \u2014 ${P.reason} Anyone on the path can lift this instance's kill switch, widen its caps or change its version pin. Continuing to poll (refusing would disable the kill switch entirely), but this deployment is not governable until the lease is signed: set requireSignedLease and have the control plane sign leases.`)}if(e===void 0&&!b&&v(k),e&&k-n<m)return e;try{let P={accept:"application/json, text/plain"};for(let[ne,J]of Object.entries(t.identity?.()??{}))J!==void 0&&J!==""&&(P[`x-agenthippo-${ne}`]=String(J));let T=await y(t.url,{headers:P,signal:AbortSignal.timeout(I$)});if(!T.ok)throw new Error(T.status===404?`lease fetch 404 \u2014 the control plane has no deployment at ${t.url}; check AGENTHIPPO_LEASE_URL`:`lease fetch ${T.status}`);let K=typeof T.text=="function"?await T.text():JSON.stringify(await T.json()),B=N(K,k);if(!B.ok)throw new Error(B.reason);B.signed?(i=!0,B.lease.requireSignedLease&&(l=!0)):p||(p=!0,t.logger?.warn(`[Lease] running on an UNSIGNED lease. Anyone who can answer or intercept ${t.url} can lift this instance's kill switch, widen its caps and change its version pin. Have the control plane sign leases (ES256 compact JWS) and set requireSignedLease.`)),e=B.lease,o=B.signed,a=B.signed&&B.lease.issuedAt!==void 0?B.lease.issuedAt-(I??Math.ceil(Date.now()/1e3)):void 0,n=k,r=k,s=void 0,u=!1,f=!1;try{t.persistence?.save({body:K,lastGoodAt:k})}catch(ne){t.logger?.warn(`[Lease] could not persist lease: ${ne instanceof Error?ne.message:String(ne)}`)}return e}catch(P){if(s=P instanceof Error?P.message:String(P),e===void 0)return f||(f=!0,t.logger?.warn(`[Lease] NO LEASE HAS EVER BEEN INSTALLED \u2014 fetch failed (${s}) and there is no persisted or static lease to fall back on. Failing closed: turns are refused until the control plane is reachable. For air-gapped use, provide --static-lease.`)),O();t.logger?.warn(`[Lease] fetch failed, using cached lease: ${s}`),r===void 0&&(r=k);let T=k-r;return h>0&&T>h?(u||(u=!0,t.logger?.warn(`[Lease] STALENESS CEILING PASSED \u2014 no successful lease refresh for ${T}s (ceiling ${h}s). Failing closed: turns are refused until the control plane is reachable.`)),w(T)):e}}}}});var U_=S(As=>{"use strict";var R$=As&&As.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),C$=As&&As.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),k$=As&&As.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&R$(n,e,r[s]);return C$(n,e),n}})();Object.defineProperty(As,"__esModule",{value:!0});As.startGrantGovernance=M$;var $$=k$(require("os")),M_=mo(),G_=ho(),D$=5*6e4,L$=6*36e5;async function M$(t){let e=Math.max(15,t.pollSeconds??60),n=t.env??process.env,r=await(0,G_.loadLeaseTrustRoot)({env:n,leaseUrl:t.leaseUrl,fetchImpl:t.fetchImpl}),s,i=`connector-${$$.hostname()}`,o=new Map,a=(0,M_.createLeaseSource)({url:t.leaseUrl,fetchImpl:t.fetchImpl,env:n,instanceId:i,cacheSeconds:e-1,signingKeys:()=>r.keys,identity:()=>({instance:i,role:"connector",...s?{grants:JSON.stringify(s)}:{},...t.enrollToken?{"enroll-token":t.enrollToken}:{}}),logger:t.logger}),c=(0,M_.leaseUrlDeployment)(t.leaseUrl),l=async()=>{let f;try{f=await t.provider.listGrants(),s=await t.provider.summary(f)}catch(b){t.logger?.warn(`[grants] could not count grants: ${b instanceof Error?b.message:b}`)}r.status!=="configured"&&(r=await(0,G_.loadLeaseTrustRoot)({env:n,leaseUrl:t.leaseUrl,fetchImpl:t.fetchImpl}));let p=await a.get(),g=p?.grants?.revoke??[],m=new Set(g.map(b=>b.user));for(let b of o.keys())m.has(b)||o.delete(b);if(!g.length)return;if(!a.status().currentSigned){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s) on an UNSIGNED lease \u2014 only a signed lease may revoke a user's grants`);return}if(!c||p?.deployment!==c){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s): the lease does not name deployment ${c??`(none in ${t.leaseUrl})`}`);return}let h=a.status().clockOffsetSeconds;if(h===void 0){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s) until a live lease poll measures the plane's clock`);return}let y=Date.now(),E=g.filter(b=>(o.get(b.user)?.at??0)<=y),w=new Set,O=E.map(b=>({...b,requestedAt:b.requestedAt-h}));await t.provider.applyRevocations(O,f,b=>{let v=b.result.ok?"grant_revoked_by_plane":"grant_revoke_failed";t.audit?.("control",v,{user_sha256:b.user,service:b.service,failed:b.result.failed}),t.logger?.info(`[grants] ${v}: ${b.service} for user sha256:${b.user.slice(0,12)}\u2026`),b.result.ok||w.add(b.user)});for(let b of E)if(w.has(b.user)){let v=Math.min((o.get(b.user)?.delayMs??D$/2)*2,L$);o.set(b.user,{at:y+v,delayMs:v})}else o.delete(b.user)};await l().catch(f=>t.logger?.warn(`[grants] first poll failed: ${f instanceof Error?f.message:f}`));let d,u=setInterval(()=>{d||(d=l().catch(f=>t.logger?.warn(`[grants] poll failed: ${f instanceof Error?f.message:f}`)).finally(()=>{d=void 0}))},e*1e3);return u.unref(),{tick:l,stop:()=>clearInterval(u)}}});var mf=S(El=>{"use strict";Object.defineProperty(El,"__esModule",{value:!0});El.createDataPlaneAuditSink=V_;El.dataPlaneSidecarCommand=x$;var H_=require("fs"),G$=bi(),j_=Pi(),U$=U_(),x_=Or(),F_=no(),H$=Qi(),j$=pi(),B_=Ai(),Js=Xt();async function V_(t,e){let{dir:n,ephemeral:r}=(0,x_.resolveStateDir)(t),s=(0,x_.resolveAnalyticsSessionsDir)(n,r),i=!0,o;try{await H_.promises.mkdir(s,{recursive:!0}),await H_.promises.access(s)}catch(l){i=!1,o=l instanceof Error?l.message:String(l)}let a=new F_.SessionEventWriter(s);return{audit:(l,d,u)=>{let f=typeof u.userId=="string"?u.userId:void 0,p=(0,H$.hashIdentity)(f),g=p?{...u,userId:p}:u,m=p&&l===f?p:l;a.append(m,(0,j$.generateRequestId)(),d,e?{...g,agent:{...e,digest:null}}:g)},auditDir:s,ephemeral:r,ok:i,error:o}}async function x$(t){let e=process.env.AGENTHIPPO_DATA_PLANE_TOKEN?.trim();e||(console.error("Error: AGENTHIPPO_DATA_PLANE_TOKEN is required (shared secret the trusted EDGE \u2014 or, legacy, the agent's serve \u2014 presents to register turns)."),process.exit(1));let n;try{n=await(0,G$.loadAgentPack)(t.agent,t.workspace)}catch(g){console.error(`Error: ${g instanceof Error?g.message:g}`),process.exit(1);return}let r=(0,j_.resolveDataPlaneConfig)(n.manifest.spec,n.packPath);if(!r){console.error("Error: pack declares no spec.dataPlane \u2014 nothing for the sidecar to run."),process.exit(1);return}let s=t.verbose?new B_.ConsoleLogger("[Sidecar]"):new B_.NoOpLogger,{audit:i,auditDir:o,ephemeral:a,ok:c,error:l}=await V_(t.stateDir,{pack:n.manifest.metadata.name,version:n.manifest.metadata.version??"0.0.0"});if(!c){let g=`${o}: ${l}`;if((0,F_.evidenceRequired)()){console.error(`${Js.COLORS.red}Error: data-plane audit directory is not writable${Js.COLORS.reset} \u2014 ${g}`),console.error("AGENTHIPPO_EVIDENCE_REQUIRED is set, so refusing to run an unauditable data plane. Unset it to downgrade this to a warning."),process.exit(1);return}console.warn(`${Js.COLORS.yellow}Warning:${Js.COLORS.reset} data-plane audit directory is not writable \u2014 ${g}`),console.warn(" Tool authorizations and denials will NOT be recorded. Set --state-dir or AGENTHIPPO_HOME to a writable path.")}let d;try{d=await(0,j_.startDataPlaneSidecar)({config:r,registerToken:e,gatewayPort:t.gatewayPort,controlPort:t.controlPort,connectPort:t.connectPort,bindHost:t.host??"0.0.0.0",logger:s,audit:i,agent:{pack:n.manifest.metadata.name,version:n.manifest.metadata.version??"0.0.0"}})}catch(g){console.error(`${Js.COLORS.red}Error: failed to start the data-plane sidecar:${Js.COLORS.reset} ${g instanceof Error?g.message:g}`),process.exit(1);return}console.log(`OK: Data-plane sidecar (provider=${r.provider??"passthrough"}) \u2014 connector: ${r.connectorPath}`),console.log(` gateway (engine dials, nonce-auth): ${d.gatewayUrl}`),console.log(` control (edge/serve registers, bearer): :${d.controlPort}`),d.connectPort!==void 0&&console.log(` connect (users link accounts, via edge): :${d.connectPort}`),console.log(` audit (tool_authorize / tool_deny / register events): ${o}${a?" (EPHEMERAL \u2014 lost on restart; set AGENTHIPPO_HOME or --state-dir)":""}`),console.log(" Base credentials live here only \u2014 never in the agent container."),console.log(" Edge mode (P1): give the register token to the IdP edge only; serve runs with AGENTHIPPO_DATA_PLANE_EDGE=1 and no token.");let u,f=()=>{u?.stop(),d.close().finally(()=>process.exit(0))};process.on("SIGINT",f),process.on("SIGTERM",f);let p=process.env.AGENTHIPPO_LEASE_URL?.trim();u=d.grants&&p?await(0,U$.startGrantGovernance)({provider:d.grants,leaseUrl:p,enrollToken:process.env.AGENTHIPPO_ENROLL_TOKEN?.trim()||void 0,logger:{info:g=>console.log(g),warn:g=>console.warn(`${Js.COLORS.yellow}Warning:${Js.COLORS.reset} ${g}`)},audit:i}):void 0,u&&console.log(` grants governance: counts reported and revocations applied on the lease poll (${p})`),await new Promise(()=>{})}});var _f=S(Ef=>{"use strict";Object.defineProperty(Ef,"__esModule",{value:!0});Ef.resolveCliTurnScope=W$;var B$=f_(),F$=mf(),W_=Pi(),V$=no(),K_=qa(),Xs=Xt();async function W$(t){let e=t.pack?.manifest.spec,n=t.pack?.packPath,r=!!((0,W_.resolveRemoteDataPlane)()||e&&n&&(0,W_.resolveDataPlaneConfig)(e,n)),s;if(r){let o=t.pack?{pack:t.pack.manifest.metadata.name,version:t.pack.manifest.metadata.version??"0.0.0"}:void 0,a=await(0,F$.createDataPlaneAuditSink)(void 0,o);if(s=a.audit,!a.ok){let c=`${a.auditDir}: ${a.error}`;(0,V$.evidenceRequired)()&&(console.error(`${Xs.COLORS.red}Error: data-plane audit directory is not writable${Xs.COLORS.reset} \u2014 ${c}`),console.error("AGENTHIPPO_EVIDENCE_REQUIRED is set, so refusing to run an unauditable data plane. Unset it to downgrade this to a warning."),process.exit(1)),console.warn(`${Xs.COLORS.yellow}Warning:${Xs.COLORS.reset} data-plane audit directory is not writable \u2014 ${c}`),console.warn(" Tool authorizations and denials will NOT be recorded. Set AGENTHIPPO_HOME to a writable path.")}}let i;try{i=await(0,B$.resolveLocalTurnScope)({spec:e,packPath:n,agent:t.pack?{pack:t.pack.manifest.metadata.name,version:t.pack.manifest.metadata.version}:void 0,logger:t.verbose?new K_.ConsoleLogger("[DataPlane]"):new K_.NoOpLogger,audit:s})}catch(o){console.error(`${Xs.COLORS.red}Error: failed to start the data plane:${Xs.COLORS.reset} ${o instanceof Error?o.message:o}`),process.exit(1)}return i&&!t.quiet&&console.log(`${Xs.COLORS.green}OK:${Xs.COLORS.reset} Data plane ${i.mode==="sidecar"?"SIDECAR":"(in-process)"} \u2014 gateway ${i.gatewayUrl}; acting as ${i.userId} (locally asserted; per-turn registration, session-stable nonce bytes)`),i}});var J_=S(bs=>{"use strict";var K$=bs&&bs.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),q$=bs&&bs.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),wf=bs&&bs.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&K$(n,e,r[s]);return q$(n,e),n}})();Object.defineProperty(bs,"__esModule",{value:!0});bs.chatCommand=eD;var Y$=wf(require("readline")),J$=wf(require("path")),X$=wf(require("os")),Nr=Ai(),Ni=bi(),he=Xt(),z$=Ti(),q_=Ze(),Q$=br(),Y_=Bs(),Z$=_f(),yf="-".repeat(62);async function eD(t){let e=(0,Ni.getApiConfig)(),n,r="default",s,i,o,a=t.verbose?new Nr.ConsoleLogger("[Sync]"):new Nr.NoOpLogger;if(t.agent)try{n=await(0,Ni.loadAgentPack)(t.agent,t.workspace),r=n.manifest.metadata.name,s=t.engine||n.manifest.spec.engine;let A=["claude","codex"].includes(s)?void 0:(0,Y_.tryResolveCustomEngineManifest)(t.workspace,s)?.model?.defaultModel,N=t.model||n.manifest.spec.model||A||(0,Ni.getEnvDefaultModel)()||(0,Ni.getDefaultConfig)().model;i=(0,Nr.resolveModelAlias)(N);let I=n.manifest.spec.cheapModel?.trim();o=I?(0,Nr.resolveModelAlias)(I):void 0,await(0,Nr.syncPackToWorkspace)(t.workspace,n.packPath,r,s,a,(0,he.findBundledBasePromptsDir)()),console.log(`${he.COLORS.green}OK:${he.COLORS.reset} Loaded agent: ${n.manifest.metadata.name} v${n.manifest.metadata.version}`),N!==i&&console.log(`${he.COLORS.dim} Model: ${N} -> ${i}${he.COLORS.reset}`),I&&I!==o&&console.log(`${he.COLORS.dim} Cheap model: ${I} -> ${o}${he.COLORS.reset}`)}catch(v){console.error(`${he.COLORS.red}Error: ${v instanceof Error?v.message:v}${he.COLORS.reset}`),process.exit(1)}else{let v=(0,Ni.getDefaultConfig)();s=t.engine||v.engine;let A=["claude","codex"].includes(s)?void 0:(0,Y_.tryResolveCustomEngineManifest)(t.workspace,s)?.model?.defaultModel,N=t.model||A||(0,Ni.getEnvDefaultModel)()||v.model;i=(0,Nr.resolveModelAlias)(N),N!==i&&console.log(`${he.COLORS.dim}Model: ${N} -> ${i}${he.COLORS.reset}`)}if(!e.apiKey&&(s==="claude"||s==="codex")){let v=(0,he.getLiteLLMQuickstartHintLines)();console.log(["To start a chat, set an API key and re-run the command. Example:",` ${v[1]}`,"","Other options:"," AGENTHIPPO_LITELLM_API_KEY=your_key AGENTHIPPO_LITELLM_BASE_URL=https://... dist/agenthippo chat"," LITELLM_API_KEY=your_key LITELLM_BASE_URL=https://... dist/agenthippo chat"," ANTHROPIC_API_KEY=your_key dist/agenthippo chat"," OPENAI_API_KEY=your_key dist/agenthippo chat"].join(`
485
+ `)}j.PACK_JWKS_URL_ENV="AGENTHIPPO_PACK_JWKS_URL";j.PACK_JWKS_URL_ENV_LEGACY="AGENTHIPPO_PACK_SIGNING_JWKS_URL";j.PACK_JWKS_PINS_ENV="AGENTHIPPO_PACK_JWKS_PINS";j.ALLOW_INSECURE_TRUST_ROOT_ENV="AGENTHIPPO_ALLOW_INSECURE_TRUST_ROOT";j.LEASE_SIGNING_KEYS_ENV="AGENTHIPPO_LEASE_SIGNING_KEYS";j.LEASE_JWKS_URL_ENV="AGENTHIPPO_LEASE_JWKS_URL";j.LEASE_JWKS_PINS_ENV="AGENTHIPPO_LEASE_JWKS_PINS";function A_(t){let e=go.createPublicKey(t),n=e.export({format:"jwk"}),r=n.kty==="EC"?{crv:n.crv,kty:n.kty,x:n.x,y:n.y}:n.kty==="RSA"?{e:n.e,kty:n.kty,n:n.n}:{kty:n.kty};return{jwk:go.createHash("sha256").update(JSON.stringify(r)).digest("base64url"),spki:go.createHash("sha256").update(e.export({type:"spki",format:"der"})).digest("hex")}}var c$=t=>t.trim().replace(/^sha256:/i,"").toLowerCase();function b_(t){return(t??"").split(",").map(c$).filter(e=>e.length>0)}function T_(t,e,n=process.env){let r;try{r=new URL(t)}catch{return{ok:!1,reason:`${e} is not a valid URL: ${t}`}}if(r.protocol==="https:")return{ok:!0,warnings:[]};let s=(n[j.ALLOW_INSECURE_TRUST_ROOT_ENV]??"").trim().toLowerCase();return s==="1"||s==="true"||s==="yes"?{ok:!0,warnings:[`INSECURE: ${e} is ${r.protocol}//${r.host} (not https) and ${j.ALLOW_INSECURE_TRUST_ROOT_ENV} is set. Anyone on the path between this instance and that host can choose which packs it will run and whether the kill switch is honoured. This must never be set outside local development.`]}:{ok:!1,reason:`${e} must be https (got ${r.protocol}//${r.host}). Set ${j.ALLOW_INSECURE_TRUST_ROOT_ENV}=1 to allow plaintext for LOCAL DEVELOPMENT ONLY.`}}var l$={label:"pack",purpose:"pack-signing",inlineEnv:"AGENTHIPPO_PACK_SIGNING_KEYS",urlEnvs:[j.PACK_JWKS_URL_ENV,j.PACK_JWKS_URL_ENV_LEGACY],pinsEnv:j.PACK_JWKS_PINS_ENV,derivedRisk:"chooses which packs this instance will run"},u$={label:"lease",purpose:"lease-signing",inlineEnv:j.LEASE_SIGNING_KEYS_ENV,urlEnvs:[j.LEASE_JWKS_URL_ENV],pinsEnv:j.LEASE_JWKS_PINS_ENV,derivedRisk:"chooses whether this instance's kill switch is ever honoured"};async function v_(t,e){let n=e.env??process.env,r=[],s=b_(n[t.pinsEnv]),i=n[t.inlineEnv]?.trim(),o=t.urlEnvs.map(f=>n[f]).find(f=>f!==void 0&&f.trim()!=="")?.trim(),a=!!i||!!o,c=(f,p,g)=>{if(s.length===0)return Object.keys(f).length===0?{status:"unavailable",keys:{},source:p,url:g,warnings:r,explicitlyConfigured:a,reason:"the trust root published no usable ES256 keys"}:{status:"configured",keys:f,source:p,url:g,warnings:r,explicitlyConfigured:a};let m={};for(let[h,y]of Object.entries(f)){let E;try{E=A_(y)}catch{r.push(`${t.label} trust root: key ${h} is unreadable and was dropped`);continue}s.some(O=>(0,aa.timingSafeEqualString)(O,E.jwk.toLowerCase())||(0,aa.timingSafeEqualString)(O,E.spki))?m[h]=y:r.push(`${t.label} trust root: key ${h} does not match any pin in ${t.pinsEnv} and was REFUSED (its thumbprints are jwk=${E.jwk} spki=${E.spki})`)}return Object.keys(m).length===0?{status:"unavailable",keys:{},source:p,url:g,warnings:r,explicitlyConfigured:a,reason:`every key offered by the trust root failed the ${t.pinsEnv} pin check`}:{status:"configured",keys:m,source:p,url:g,warnings:r,explicitlyConfigured:a}};if(i){let f;try{f=JSON.parse(i)}catch(p){return{status:"unavailable",keys:{},source:"inline",warnings:r,explicitlyConfigured:a,reason:`${t.inlineEnv} is set but is not valid JSON: ${p instanceof Error?p.message:String(p)}`}}return c(f,"inline")}let l=o,d=!1;if(!l&&e.leaseUrl){try{l=new URL(`/.well-known/jwks.json?purpose=${t.purpose}`,e.leaseUrl).toString()}catch{return{status:"unavailable",keys:{},warnings:r,explicitlyConfigured:a,reason:`AGENTHIPPO_LEASE_URL is not a valid URL: ${e.leaseUrl}`}}d=!0}if(!l)return{status:"unconfigured",keys:{},warnings:r,explicitlyConfigured:a};let u=T_(l,`the ${t.purpose} JWKS URL`,n);if(!u.ok)return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:u.reason,derivedFromLease:d,explicitlyConfigured:a};r.push(...u.warnings),d&&s.length===0&&r.push(`${t.label} trust root is derived from AGENTHIPPO_LEASE_URL (${l}) and is not pinned. Whoever can answer that origin ${t.derivedRisk}. Pin it with ${t.urlEnvs[0]} and ${t.pinsEnv}.`);try{let f=await(e.fetchImpl??fetch)(l);if(!f.ok)return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:`JWKS fetch returned HTTP ${f.status}`,derivedFromLease:d,explicitlyConfigured:a};let p=await f.json(),g=g$(p);return g.ok?{...c(g.pems,"jwks",l),derivedFromLease:d}:{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,reason:g.reason,derivedFromLease:d,explicitlyConfigured:a}}catch(f){return{status:"unavailable",keys:{},source:"jwks",url:l,warnings:r,derivedFromLease:d,explicitlyConfigured:a,reason:`JWKS fetch failed: ${f instanceof Error?f.message:String(f)}`}}}async function O_(t){return v_(l$,t)}async function d$(t){return v_(u$,t)}function f$(t,e){return t.explicitlyConfigured?{keys:t.keys,packFallback:!1}:{keys:{...e.keys,...t.keys},packFallback:!0}}function p$(t,e){let n=[];if(!t.explicitlyConfigured)return{warnings:n};if(t.url){let s=null;try{s=new URL(t.url).searchParams.get("purpose")}catch{}if(s!==null&&s!=="lease-signing")return{warnings:n,fatal:`${j.LEASE_JWKS_URL_ENV} points at a '${s}' document (${t.url}). A plane that separates keys by purpose never serves a lease-signing key there, so signed-lease verification breaks at the next lease-key rotation \u2014 and requireSignedLease is sticky with no plane-side undo. Point it at ?purpose=lease-signing (with its own ${j.LEASE_JWKS_PINS_ENV}) instead.`};s===null&&e.url===t.url&&n.push(`the lease trust root and the pack trust root are the SAME document (${t.url}). An older plane that returns every key it holds supports this; a plane that separates keys by purpose does not, and the break lands at the next lease-key rotation, after requireSignedLease has latched. Give the lease root its own URL: ?purpose=lease-signing.`)}let r=Object.keys(t.keys).filter(s=>e.keys[s]!==void 0&&e.keys[s].trim()===t.keys[s].trim());return r.length>0&&n.push(`kid(s) ${r.map(s=>`'${s}'`).join(", ")} carry the same public key in BOTH the lease and the pack trust root \u2014 one key under two purposes. The control plane refuses to register such a key, so whichever purpose rotates first strands the other; give each purpose its own keypair.`),{warnings:n}}function g$(t){if(t.pemsByKid&&typeof t.pemsByKid=="object")return{ok:!0,pems:t.pemsByKid};if(!Array.isArray(t.keys))return{ok:!1,reason:"JWKS document has neither `pemsByKid` nor a `keys` array"};let e={};for(let n of t.keys)if(!(!n||typeof n!="object")&&!(n.kty!=="EC"||n.crv!=="P-256")&&!(n.alg!==void 0&&n.alg!=="ES256")&&!(typeof n.kid!="string"||!n.kid))try{e[n.kid]=go.createPublicKey({key:n,format:"jwk"}).export({type:"spki",format:"pem"}).toString()}catch{}return Object.keys(e).length===0?{ok:!1,reason:"JWKS document published no usable ES256 (P-256) keys"}:{ok:!0,pems:e}}async function h$(t){return(await O_(t)).keys}j.PACK_PROBE_INTERVAL_MS=1e3;j.PACK_FULL_REVERIFY_INTERVAL_MS=3e4;function m$(t={}){let e=t.probeIntervalMs??j.PACK_PROBE_INTERVAL_MS,n=t.fullReverifyIntervalMs??j.PACK_FULL_REVERIFY_INTERVAL_MS,r,s="",i="",o=0,a=0,c=0,l=u=>`${u.packDir}\0${u.pack}\0${u.packVersion}\0${Object.keys(u.keys).sort().join(",")}`,d=(u,f)=>{c+=1,s=l(u),i=df(u.packDir),o=f,a=f;let p=__(u.packDir);return r=p?y_(p,u.keys,{packDir:u.packDir,pack:u.pack,packVersion:u.packVersion}):{ok:!1,kind:"unsigned",reason:`${u.pack} is not signed (no ${j.PACK_SIGNATURE_FILE} at the pack root)`},r};return{fullVerifications:()=>c,refresh(u,f=Date.now()){return d(u,f)},verify(u,f=Date.now()){return!r||s!==l(u)||f-a>=n?d(u,f):f-o<e||(o=f,df(u.packDir)===i)?r:d(u,f)}}}});var mo=S(se=>{"use strict";Object.defineProperty(se,"__esModule",{value:!0});se.MAX_LEASE_ENVELOPE_TTL_SECONDS=se.LEASE_JWS_TYP=se.LeaseDeniedError=se.LEASE_MAX_STALENESS_ENV=se.DEFAULT_LEASE_MAX_STALENESS_SECONDS=se.MIN_LEASE_POLL_SECONDS=se.DEFAULT_LEASE_POLL_SECONDS=void 0;se.resolveLeasePollSeconds=gf;se.leaseCacheSecondsFor=hf;se.effectiveKillLatencySeconds=y$;se.leaseMaxStalenessFromEnv=R_;se.resolveAllowServiceTurns=w$;se.describeServiceTurnGate=S$;se.denyVerdict=C_;se.resolveFollowedUsers=b$;se.leaseIsDead=T$;se.policyVersion=v$;se.assertAdmitted=O$;se.signLease=P$;se.verifySignedLease=$_;se.requireSignedLease=D_;se.leaseUrlDeployment=L_;se.createLeaseSource=N$;var E$=require("crypto"),I_=Ii(),N_=oa(),_$=ho();se.DEFAULT_LEASE_POLL_SECONDS=30;se.MIN_LEASE_POLL_SECONDS=5;function gf(t){let e=typeof t=="number"&&Number.isFinite(t)?t:se.DEFAULT_LEASE_POLL_SECONDS;return Math.max(se.MIN_LEASE_POLL_SECONDS,Math.floor(e))}function hf(t){return gf(t)}function y$(t){let e=gf(t);return e+hf(e)}se.DEFAULT_LEASE_MAX_STALENESS_SECONDS=1440*60;se.LEASE_MAX_STALENESS_ENV="AGENTHIPPO_LEASE_MAX_STALENESS_SECONDS";function R_(t=process.env){let e=t[se.LEASE_MAX_STALENESS_ENV]?.trim();if(e===void 0||e==="")return se.DEFAULT_LEASE_MAX_STALENESS_SECONDS;let n=Number(e);return!Number.isFinite(n)||n<0?se.DEFAULT_LEASE_MAX_STALENESS_SECONDS:Math.floor(n)}function w$(t){return t.managed?t.lease===!0?{allowed:!0,gate:"lease_allows"}:{allowed:!1,gate:t.lease===!1?"lease_denies":"lease_absent_field"}:{allowed:!0,gate:"unmanaged_no_lease"}}function S$(t){switch(t){case"lease_allows":return"permitted by the control plane (lease.allowServiceTurns)";case"unmanaged_no_lease":return"permitted: no control plane configured, so AGENTHIPPO_SERVICE_USER is the only gate";case"lease_denies":return"refused: the control plane set lease.allowServiceTurns=false";case"lease_absent_field":return"refused: this is a managed deployment and the lease does not set allowServiceTurns (absent means deny \u2014 enable it in the console)"}}function C_(t,e,n){if(!t?.deny?.length)return{denied:!1};let r=n??Math.floor(Date.now()/1e3),s=e.sessionKey.indexOf("--"),i=s>=0?e.sessionKey.slice(s+2):e.sessionKey,o={denied:!1};for(let a of t.deny){if(a.until!==void 0&&a.until<=r)continue;let c=!1;if(a.scope==="pack"?c=a.match===e.pack:a.scope==="session"?(c=a.match===e.sessionKey||a.match===i,c&&a.user!==void 0&&e.userId!==void 0&&a.user!==e.userId&&(c=!1),!c&&a.followUser!==!1&&e.userId!==void 0&&A$(a,e.userId,e.followedUsers)&&(c=!0)):a.scope==="user"&&(c=e.userId!==void 0&&a.match===e.userId||e.userHash!==void 0&&e.sessionKey.startsWith(`u${e.userHash(a.match)}--`)),!c)continue;let l=`${a.mode==="kill"?"stopped":"draining"} by the control plane${a.reason?`: ${a.reason}`:""}`;if(a.mode==="kill")return{denied:!0,mode:"kill",reason:l};o.denied||(o={denied:!0,mode:"drain",reason:l})}return o}var k_=t=>`${t.scope}:${t.match}`;function A$(t,e,n){return n?.get(k_(t))?.has(e)??!1}function b$(t,e,n){let r=new Map;if(!t?.deny?.length)return r;let s=n??Math.floor(Date.now()/1e3);for(let i of t.deny){if(i.scope!=="session"||i.followUser===!1||i.until!==void 0&&i.until<=s)continue;let o=new Set;for(let[a,c]of e){let l=a.indexOf("--"),d=l>=0?a.slice(l+2):a;i.match!==a&&i.match!==d||i.user!==void 0&&i.user!==c||o.add(c)}o.size>0&&r.set(k_(i),o)}return r}function T$(t,e){if(!t)return{dead:!1};let n=e??Math.floor(Date.now()/1e3);return t.enabled?t.expiresAt<=n?{dead:!0,reason:`lease expired at ${new Date(t.expiresAt*1e3).toISOString()}`}:{dead:!1}:{dead:!0,reason:`kill switch active${t.reason?`: ${t.reason}`:""}`}}function v$(t){if(!t)return;let{expiresAt:e,issuedAt:n,...r}=t,s=i=>Array.isArray(i)?i.map(s):i&&typeof i=="object"?Object.fromEntries(Object.keys(i).sort().map(o=>[o,s(i[o])])):i;return(0,E$.createHash)("sha256").update(JSON.stringify(s(r))).digest("hex")}var Ss=class extends Error{constructor(e){super(e),this.name="LeaseDeniedError"}};se.LeaseDeniedError=Ss;function O$(t,e){if(!t)return;let n=e.nowSeconds??Math.floor(Date.now()/1e3);if(!t.enabled)throw new Ss(`kill switch active for pack ${e.pack}${t.reason?`: ${t.reason}`:""}`);if(t.pack!==e.pack)throw new Ss(`lease is for pack ${t.pack}, not ${e.pack}`);if(t.expiresAt<=n)throw new Ss(`lease for ${e.pack} expired at ${new Date(t.expiresAt*1e3).toISOString()}`);if(t.version&&t.version!==e.version)throw new Ss(`pack ${e.pack} is pinned to ${t.version}; refusing to start ${e.version} (rollback in force)`);if(t.imageDigest&&e.image&&!e.image.includes(t.imageDigest))throw new Ss(`image for ${e.pack} does not match the leased digest ${t.imageDigest}`);if(e.sessionKey){let r=C_(t,{sessionKey:e.sessionKey,pack:e.pack,userHash:e.userHash,userId:e.userId,followedUsers:e.followedUsers},n);if(r.denied)throw new Ss(r.reason??"stopped by the control plane")}}se.LEASE_JWS_TYP="agenthippo-lease+jws";se.MAX_LEASE_ENVELOPE_TTL_SECONDS=3600;function P$(t,e,n){let r=n.nowSeconds??Math.floor(Date.now()/1e3),s=Math.min(n.ttlSeconds??300,se.MAX_LEASE_ENVELOPE_TTL_SECONDS),i={lease:t,aud:n.instanceId??"*",sub:t.pack,iat:r,exp:r+s,...n.iss?{iss:n.iss}:{}};return(0,I_.signCompactJws)({typ:se.LEASE_JWS_TYP,kid:e.kid},i,e.privateKeyPem)}function $_(t,e,n={}){if(Object.keys(e).length===0)return{ok:!1,reason:"no trusted lease-signing keys are configured on this instance"};let r=(0,I_.verifyCompactJws)(t,e,{typ:se.LEASE_JWS_TYP});if(!r.ok)return{ok:!1,reason:`lease signature: ${r.reason}`};let s=r.payload,i=n.nowSeconds??Math.floor(Date.now()/1e3),o=n.clockSkewSeconds??60;if(typeof s.iat!="number"||!Number.isFinite(s.iat))return{ok:!1,reason:"lease envelope has no issued-at"};if(typeof s.exp!="number"||!Number.isFinite(s.exp))return{ok:!1,reason:"lease envelope has no expiry"};if(s.exp-s.iat>se.MAX_LEASE_ENVELOPE_TTL_SECONDS)return{ok:!1,reason:`lease envelope lifetime ${s.exp-s.iat}s exceeds the ${se.MAX_LEASE_ENVELOPE_TTL_SECONDS}s cap`};if(s.exp+o<=i)return{ok:!1,reason:`lease envelope expired at ${new Date(s.exp*1e3).toISOString()}`};if(s.iat-o>i)return{ok:!1,reason:"lease envelope is issued in the future"};if(n.minIat!==void 0&&s.iat<n.minIat)return{ok:!1,reason:`lease envelope is older than one already accepted (replay/rollback: iat ${s.iat} < ${n.minIat})`};if(n.instanceId!==void 0&&s.aud!=="*"&&s.aud!==n.instanceId)return{ok:!1,reason:`lease envelope is for instance ${s.aud}, not ${n.instanceId}`};let a=(0,N_.parseLease)(s.lease);return a.ok?s.sub!==a.lease.pack?{ok:!1,reason:`lease envelope subject ${s.sub} does not match lease.pack ${a.lease.pack}`}:{ok:!0,lease:a.lease,claims:s}:{ok:!1,reason:`signed lease is malformed: ${a.reason}`}}function D_(t,e){return!!t||!!e}var P_=t=>/^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(t),I$=2e4;function L_(t){if(t)try{let e=/\/lease\/([^/]+)\.json$/.exec(new URL(t).pathname);return e?decodeURIComponent(e[1]):void 0}catch{return}}function N$(t){let e=t.staticLease,n=0,r,s,i=!1,o=!1,a,c=L_(t.url),l=!1,d,u=!1,f=!1,p=!1,g=!1,m=t.cacheSeconds??hf(se.DEFAULT_LEASE_POLL_SECONDS),h=t.maxStalenessSeconds??R_(t.env),y=t.fetchImpl??fetch,E=()=>D_(l,t.requireSignedLease),w=I=>({...e??{pack:"",expiresAt:0},enabled:!1,reason:`the control plane has not been reachable for ${I}s, past the ${h}s staleness ceiling (${se.LEASE_MAX_STALENESS_ENV}). Refusing work rather than running on a lease that can no longer be revoked. Set ${se.LEASE_MAX_STALENESS_ENV}=0 to accept unbounded staleness.`}),O=()=>({pack:"",expiresAt:0,enabled:!1,reason:`this instance is managed (${t.url}) but has never successfully fetched its lease`+(s?` (${s})`:"")+". Refusing work until the control plane is reachable rather than booting ungoverned. For an air-gapped deployment, provide the lease with --static-lease."}),b=!1,v=I=>{if(b=!0,!t.persistence)return;let k;try{k=t.persistence.load()}catch(T){t.logger?.warn(`[Lease] persisted lease unreadable: ${T instanceof Error?T.message:String(T)}`);return}if(!k||typeof k.body!="string")return;typeof k.lastGoodAt=="number"&&Number.isFinite(k.lastGoodAt)&&(r=Math.min(k.lastGoodAt,I));let P=N(k.body,I);if(!P.ok){t.logger?.warn(`[Lease] persisted lease not reinstalled: ${P.reason}`);return}P.signed&&(i=!0,P.lease.requireSignedLease&&(l=!0)),e=P.lease,o=P.signed,a=void 0},A=I=>I.deployment!==void 0&&c!==void 0&&I.deployment!==c?`lease is for deployment ${I.deployment}, not ${c} (${t.url})`:void 0,N=(I,k)=>{let P=I.trim(),T,K;if(P_(P))T=P;else{try{K=JSON.parse(P)}catch(J){return{ok:!1,reason:`lease body is not JSON: ${J instanceof Error?J.message:String(J)}`}}typeof K=="string"&&P_(K.trim())?T=K.trim():K&&typeof K=="object"&&typeof K.lease=="string"&&(T=K.lease.trim())}if(T){let J=$_(T,t.signingKeys?.()??{},{instanceId:t.instanceId,minIat:d,nowSeconds:k});if(!J.ok)return{ok:!1,reason:J.reason};let oe=A(J.lease);return oe?{ok:!1,reason:oe}:(d=J.claims.iat,{ok:!0,lease:J.lease,signed:!0})}if(E())return{ok:!1,reason:'a signed lease is required but the control plane returned an unsigned one (expected a compact JWS body or {"lease":"<jws>"})'};let B=(0,N_.parseLease)(K);if(!B.ok)return{ok:!1,reason:B.reason};for(let J of B.warnings)t.logger?.warn(`[Lease] ${J}`);let ne=A(B.lease);return ne?{ok:!1,reason:ne}:{ok:!0,lease:B.lease,signed:!1}};return{status(I){let k=I??Math.floor(Date.now()/1e3),P=r===void 0?void 0:k-r,T=!!t.url&&e===void 0&&s!==void 0;return{signed:i,currentSigned:o,clockOffsetSeconds:a,requireSignedLease:E(),lastGoodAt:r,stalenessSeconds:P,maxStalenessSeconds:h,failClosed:T||h>0&&P!==void 0&&P>h,lastError:s}},async get(I){let k=I??Math.floor(Date.now()/1e3);if(!t.url)return e;if(!g){g=!0;let P=(0,_$.assertSecureTrustUrl)(t.url,"AGENTHIPPO_LEASE_URL",t.env??process.env);if(P.ok)for(let T of P.warnings)t.logger?.warn(`[Lease] ${T}`);else E()?t.logger?.warn(`[Lease] INSECURE LEASE CHANNEL \u2014 ${P.reason} Signed leases are required here, so the policy itself is still verified \u2014 but the channel is not: anyone on the path can read this instance's identity, pack and version, and can delay a kill switch by up to ${se.MAX_LEASE_ENVELOPE_TTL_SECONDS}s by replaying the last envelope. requireSignedLease is not a substitute for https; serve the lease over https.`):t.logger?.warn(`[Lease] INSECURE LEASE CHANNEL \u2014 ${P.reason} Anyone on the path can lift this instance's kill switch, widen its caps or change its version pin. Continuing to poll (refusing would disable the kill switch entirely), but this deployment is not governable until the lease is signed: set requireSignedLease and have the control plane sign leases.`)}if(e===void 0&&!b&&v(k),e&&k-n<m)return e;try{let P={accept:"application/json, text/plain"};for(let[ne,J]of Object.entries(t.identity?.()??{}))J!==void 0&&J!==""&&(P[`x-agenthippo-${ne}`]=String(J));let T=await y(t.url,{headers:P,signal:AbortSignal.timeout(I$)});if(!T.ok)throw new Error(T.status===404?`lease fetch 404 \u2014 the control plane has no deployment at ${t.url}; check AGENTHIPPO_LEASE_URL`:`lease fetch ${T.status}`);let K=typeof T.text=="function"?await T.text():JSON.stringify(await T.json()),B=N(K,k);if(!B.ok)throw new Error(B.reason);B.signed?(i=!0,B.lease.requireSignedLease&&(l=!0)):p||(p=!0,t.logger?.warn(`[Lease] running on an UNSIGNED lease. Anyone who can answer or intercept ${t.url} can lift this instance's kill switch, widen its caps and change its version pin. Have the control plane sign leases (ES256 compact JWS) and set requireSignedLease.`)),e=B.lease,o=B.signed,a=B.signed&&B.lease.issuedAt!==void 0?B.lease.issuedAt-(I??Math.ceil(Date.now()/1e3)):void 0,n=k,r=k,s=void 0,u=!1,f=!1;try{t.persistence?.save({body:K,lastGoodAt:k})}catch(ne){t.logger?.warn(`[Lease] could not persist lease: ${ne instanceof Error?ne.message:String(ne)}`)}return e}catch(P){if(s=P instanceof Error?P.message:String(P),e===void 0)return f||(f=!0,t.logger?.warn(`[Lease] NO LEASE HAS EVER BEEN INSTALLED \u2014 fetch failed (${s}) and there is no persisted or static lease to fall back on. Failing closed: turns are refused until the control plane is reachable. For air-gapped use, provide --static-lease.`)),O();t.logger?.warn(`[Lease] fetch failed, using cached lease: ${s}`),r===void 0&&(r=k);let T=k-r;return h>0&&T>h?(u||(u=!0,t.logger?.warn(`[Lease] STALENESS CEILING PASSED \u2014 no successful lease refresh for ${T}s (ceiling ${h}s). Failing closed: turns are refused until the control plane is reachable.`)),w(T)):e}}}}});var U_=S(As=>{"use strict";var R$=As&&As.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),C$=As&&As.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),k$=As&&As.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&R$(n,e,r[s]);return C$(n,e),n}})();Object.defineProperty(As,"__esModule",{value:!0});As.startGrantGovernance=M$;var $$=k$(require("os")),M_=mo(),G_=ho(),D$=5*6e4,L$=6*36e5;async function M$(t){let e=Math.max(15,t.pollSeconds??60),n=t.env??process.env,r=await(0,G_.loadLeaseTrustRoot)({env:n,leaseUrl:t.leaseUrl,fetchImpl:t.fetchImpl}),s,i=`connector-${$$.hostname()}`,o=new Map,a=(0,M_.createLeaseSource)({url:t.leaseUrl,fetchImpl:t.fetchImpl,env:n,instanceId:i,cacheSeconds:e-1,signingKeys:()=>r.keys,identity:()=>({instance:i,role:"connector",...s?{grants:JSON.stringify(s)}:{},...t.enrollToken?{"enroll-token":t.enrollToken}:{}}),logger:t.logger}),c=(0,M_.leaseUrlDeployment)(t.leaseUrl),l=async()=>{let f;try{f=await t.provider.listGrants(),s=await t.provider.summary(f)}catch(b){t.logger?.warn(`[grants] could not count grants: ${b instanceof Error?b.message:b}`)}r.status!=="configured"&&(r=await(0,G_.loadLeaseTrustRoot)({env:n,leaseUrl:t.leaseUrl,fetchImpl:t.fetchImpl}));let p=await a.get(),g=p?.grants?.revoke??[],m=new Set(g.map(b=>b.user));for(let b of o.keys())m.has(b)||o.delete(b);if(!g.length)return;if(!a.status().currentSigned){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s) on an UNSIGNED lease \u2014 only a signed lease may revoke a user's grants`);return}if(!c||p?.deployment!==c){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s): the lease does not name deployment ${c??`(none in ${t.leaseUrl})`}`);return}let h=a.status().clockOffsetSeconds;if(h===void 0){t.logger?.warn(`[grants] ignoring ${g.length} revocation(s) until a live lease poll measures the plane's clock`);return}let y=Date.now(),E=g.filter(b=>(o.get(b.user)?.at??0)<=y),w=new Set,O=E.map(b=>({...b,requestedAt:b.requestedAt-h}));await t.provider.applyRevocations(O,f,b=>{let v=b.result.ok?"grant_revoked_by_plane":"grant_revoke_failed";t.audit?.("control",v,{user_sha256:b.user,service:b.service,failed:b.result.failed}),t.logger?.info(`[grants] ${v}: ${b.service} for user sha256:${b.user.slice(0,12)}\u2026`),b.result.ok||w.add(b.user)});for(let b of E)if(w.has(b.user)){let v=Math.min((o.get(b.user)?.delayMs??D$/2)*2,L$);o.set(b.user,{at:y+v,delayMs:v})}else o.delete(b.user)};await l().catch(f=>t.logger?.warn(`[grants] first poll failed: ${f instanceof Error?f.message:f}`));let d,u=setInterval(()=>{d||(d=l().catch(f=>t.logger?.warn(`[grants] poll failed: ${f instanceof Error?f.message:f}`)).finally(()=>{d=void 0}))},e*1e3);return u.unref(),{tick:l,stop:()=>clearInterval(u)}}});var mf=S(El=>{"use strict";Object.defineProperty(El,"__esModule",{value:!0});El.createDataPlaneAuditSink=V_;El.dataPlaneSidecarCommand=x$;var H_=require("fs"),G$=bi(),j_=Pi(),U$=U_(),x_=Or(),F_=no(),H$=Qi(),j$=pi(),B_=Ai(),Js=Xt();async function V_(t,e){let{dir:n,ephemeral:r}=(0,x_.resolveStateDir)(t),s=(0,x_.resolveAnalyticsSessionsDir)(n,r),i=!0,o;try{await H_.promises.mkdir(s,{recursive:!0}),await H_.promises.access(s)}catch(l){i=!1,o=l instanceof Error?l.message:String(l)}let a=new F_.SessionEventWriter(s);return{audit:(l,d,u)=>{let f=typeof u.userId=="string"?u.userId:void 0,p=(0,H$.hashIdentity)(f),g=p?{...u,userId:p}:u,m=p&&l===f?p:l;a.append(m,(0,j$.generateRequestId)(),d,e?{...g,agent:{...e,digest:null}}:g)},auditDir:s,ephemeral:r,ok:i,error:o}}async function x$(t){let e=process.env.AGENTHIPPO_DATA_PLANE_TOKEN?.trim();e||(console.error("Error: AGENTHIPPO_DATA_PLANE_TOKEN is required (shared secret the trusted EDGE \u2014 or, legacy, the agent's serve \u2014 presents to register turns)."),process.exit(1));let n;try{n=await(0,G$.loadAgentPack)(t.agent,t.workspace)}catch(g){console.error(`Error: ${g instanceof Error?g.message:g}`),process.exit(1);return}let r=(0,j_.resolveDataPlaneConfig)(n.manifest.spec,n.packPath);if(!r){console.error("Error: pack declares no spec.dataPlane \u2014 nothing for the sidecar to run."),process.exit(1);return}let s=t.verbose?new B_.ConsoleLogger("[Sidecar]"):new B_.NoOpLogger,{audit:i,auditDir:o,ephemeral:a,ok:c,error:l}=await V_(t.stateDir,{pack:n.manifest.metadata.name,version:n.manifest.metadata.version??"0.0.0"});if(!c){let g=`${o}: ${l}`;if((0,F_.evidenceRequired)()){console.error(`${Js.COLORS.red}Error: data-plane audit directory is not writable${Js.COLORS.reset} \u2014 ${g}`),console.error("AGENTHIPPO_EVIDENCE_REQUIRED is set, so refusing to run an unauditable data plane. Unset it to downgrade this to a warning."),process.exit(1);return}console.warn(`${Js.COLORS.yellow}Warning:${Js.COLORS.reset} data-plane audit directory is not writable \u2014 ${g}`),console.warn(" Tool authorizations and denials will NOT be recorded. Set --state-dir or AGENTHIPPO_HOME to a writable path.")}let d;try{d=await(0,j_.startDataPlaneSidecar)({config:r,registerToken:e,gatewayPort:t.gatewayPort,controlPort:t.controlPort,connectPort:t.connectPort,bindHost:t.host??"0.0.0.0",logger:s,audit:i,agent:{pack:n.manifest.metadata.name,version:n.manifest.metadata.version??"0.0.0"}})}catch(g){console.error(`${Js.COLORS.red}Error: failed to start the data-plane sidecar:${Js.COLORS.reset} ${g instanceof Error?g.message:g}`),process.exit(1);return}console.log(`OK: Data-plane sidecar (provider=${r.provider??"passthrough"}) \u2014 connector: ${r.connectorPath}`),console.log(` gateway (engine dials, nonce-auth): ${d.gatewayUrl}`),console.log(` control (edge/serve registers, bearer): :${d.controlPort}`),d.connectPort!==void 0&&console.log(` connect (users link accounts, via edge): :${d.connectPort}`),console.log(` audit (tool_authorize / tool_deny / register events): ${o}${a?" (EPHEMERAL \u2014 lost on restart; set AGENTHIPPO_HOME or --state-dir)":""}`),console.log(" Base credentials live here only \u2014 never in the agent container."),console.log(" Edge mode (P1): give the register token to the IdP edge only; serve runs with AGENTHIPPO_DATA_PLANE_EDGE=1 and no token.");let u,f=()=>{u?.stop(),d.close().finally(()=>process.exit(0))};process.on("SIGINT",f),process.on("SIGTERM",f);let p=process.env.AGENTHIPPO_LEASE_URL?.trim();u=d.grants&&p?await(0,U$.startGrantGovernance)({provider:d.grants,leaseUrl:p,enrollToken:process.env.AGENTHIPPO_ENROLL_TOKEN?.trim()||void 0,logger:{info:g=>console.log(g),warn:g=>console.warn(`${Js.COLORS.yellow}Warning:${Js.COLORS.reset} ${g}`)},audit:i}):void 0,u&&console.log(` grants governance: counts reported and revocations applied on the lease poll (${p})`),await new Promise(()=>{})}});var _f=S(Ef=>{"use strict";Object.defineProperty(Ef,"__esModule",{value:!0});Ef.resolveCliTurnScope=W$;var B$=f_(),F$=mf(),W_=Pi(),V$=no(),K_=qa(),Xs=Xt();async function W$(t){let e=t.pack?.manifest.spec,n=t.pack?.packPath,r=!!((0,W_.resolveRemoteDataPlane)()||e&&n&&(0,W_.resolveDataPlaneConfig)(e,n)),s;if(r){let o=t.pack?{pack:t.pack.manifest.metadata.name,version:t.pack.manifest.metadata.version??"0.0.0"}:void 0,a=await(0,F$.createDataPlaneAuditSink)(void 0,o);if(s=a.audit,!a.ok){let c=`${a.auditDir}: ${a.error}`;(0,V$.evidenceRequired)()&&(console.error(`${Xs.COLORS.red}Error: data-plane audit directory is not writable${Xs.COLORS.reset} \u2014 ${c}`),console.error("AGENTHIPPO_EVIDENCE_REQUIRED is set, so refusing to run an unauditable data plane. Unset it to downgrade this to a warning."),process.exit(1)),console.warn(`${Xs.COLORS.yellow}Warning:${Xs.COLORS.reset} data-plane audit directory is not writable \u2014 ${c}`),console.warn(" Tool authorizations and denials will NOT be recorded. Set AGENTHIPPO_HOME to a writable path.")}}let i;try{i=await(0,B$.resolveLocalTurnScope)({spec:e,packPath:n,agent:t.pack?{pack:t.pack.manifest.metadata.name,version:t.pack.manifest.metadata.version}:void 0,logger:t.verbose?new K_.ConsoleLogger("[DataPlane]"):new K_.NoOpLogger,audit:s})}catch(o){console.error(`${Xs.COLORS.red}Error: failed to start the data plane:${Xs.COLORS.reset} ${o instanceof Error?o.message:o}`),process.exit(1)}return i&&!t.quiet&&console.log(`${Xs.COLORS.green}OK:${Xs.COLORS.reset} Data plane ${i.mode==="sidecar"?"SIDECAR":"(in-process)"} \u2014 gateway ${i.gatewayUrl}; acting as ${i.userId} (locally asserted; per-turn registration, session-stable nonce bytes)`),i}});var J_=S(bs=>{"use strict";var K$=bs&&bs.__createBinding||(Object.create?(function(t,e,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(e,n);(!s||("get"in s?!e.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return e[n]}}),Object.defineProperty(t,r,s)}):(function(t,e,n,r){r===void 0&&(r=n),t[r]=e[n]})),q$=bs&&bs.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),wf=bs&&bs.__importStar||(function(){var t=function(e){return t=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},t(e)};return function(e){if(e&&e.__esModule)return e;var n={};if(e!=null)for(var r=t(e),s=0;s<r.length;s++)r[s]!=="default"&&K$(n,e,r[s]);return q$(n,e),n}})();Object.defineProperty(bs,"__esModule",{value:!0});bs.chatCommand=eD;var Y$=wf(require("readline")),J$=wf(require("path")),X$=wf(require("os")),Nr=Ai(),Ni=bi(),he=Xt(),z$=Ti(),q_=Ze(),Q$=br(),Y_=Bs(),Z$=_f(),yf="-".repeat(62);async function eD(t){let e=(0,Ni.getApiConfig)(),n,r="default",s,i,o,a=t.verbose?new Nr.ConsoleLogger("[Sync]"):new Nr.NoOpLogger;if(t.agent)try{n=await(0,Ni.loadAgentPack)(t.agent,t.workspace),r=n.manifest.metadata.name,s=t.engine||n.manifest.spec.engine;let A=["claude","codex"].includes(s)?void 0:(0,Y_.tryResolveCustomEngineManifest)(t.workspace,s)?.model?.defaultModel,N=t.model||n.manifest.spec.model||A||(0,Ni.getEnvDefaultModel)()||(0,Ni.getDefaultConfig)().model;i=(0,Nr.resolveModelAlias)(N);let I=n.manifest.spec.cheapModel?.trim();o=I?(0,Nr.resolveModelAlias)(I):void 0,await(0,Nr.syncPackToWorkspace)(t.workspace,n.packPath,r,s,a,(0,he.findBundledBasePromptsDir)()),console.log(`${he.COLORS.green}OK:${he.COLORS.reset} Loaded agent: ${n.manifest.metadata.name} v${n.manifest.metadata.version}`),N!==i&&console.log(`${he.COLORS.dim} Model: ${N} -> ${i}${he.COLORS.reset}`),I&&I!==o&&console.log(`${he.COLORS.dim} Cheap model: ${I} -> ${o}${he.COLORS.reset}`)}catch(v){console.error(`${he.COLORS.red}Error: ${v instanceof Error?v.message:v}${he.COLORS.reset}`),process.exit(1)}else{let v=(0,Ni.getDefaultConfig)();s=t.engine||v.engine;let A=["claude","codex"].includes(s)?void 0:(0,Y_.tryResolveCustomEngineManifest)(t.workspace,s)?.model?.defaultModel,N=t.model||A||(0,Ni.getEnvDefaultModel)()||v.model;i=(0,Nr.resolveModelAlias)(N),N!==i&&console.log(`${he.COLORS.dim}Model: ${N} -> ${i}${he.COLORS.reset}`)}if(!e.apiKey&&(s==="claude"||s==="codex")){let v=(0,he.getLiteLLMQuickstartHintLines)();console.log(["To start a chat, set an API key and re-run the command. Example:",` ${v[1]}`,"","Other options:"," AGENTHIPPO_LITELLM_API_KEY=your_key AGENTHIPPO_LITELLM_BASE_URL=https://... dist/agenthippo chat"," LITELLM_API_KEY=your_key LITELLM_BASE_URL=https://... dist/agenthippo chat"," ANTHROPIC_API_KEY=your_key dist/agenthippo chat"," OPENAI_API_KEY=your_key dist/agenthippo chat"].join(`
486
486
  `)),process.exit(1)}let c=J$.join(X$.tmpdir(),`${q_.AGENTIDE_CLI_NAME}-cli`),l=t.verbose?new Nr.ConsoleLogger("[Agent]"):new Nr.NoOpLogger,d=(0,he.findClaudeCodePath)(),u=(0,he.findCodexPath)(),f=(0,he.findBundledBasePromptsDir)();if(s==="claude"&&!d){console.error(`${he.COLORS.red}Error: Claude Code CLI not found.${he.COLORS.reset}`);let v=(0,z$.getUnsupportedClaudePlatformHint)();v&&console.error(` ${v}`),console.error(" Install it: npm install -g @anthropic-ai/claude-code"),console.error(" Or set CLAUDE_CODE_PATH environment variable"),console.error(" Or use --engine codex instead"),process.exit(1)}s==="codex"&&!u&&(console.error(`${he.COLORS.red}Error: Codex CLI not found.${he.COLORS.reset}`),console.error(" Install it: npm install -g @openai/codex"),console.error(" Or set CODEX_PATH environment variable"),console.error(" Or use --engine claude instead"),process.exit(1));let p=new Nr.AutoApprovePermissionHandler,g={fileAccess:(0,Ni.getFileAccess)(n)},m=`cli-${Date.now()}`,h=await(0,Z$.resolveCliTurnScope)({pack:n,verbose:t.verbose}),y=()=>(0,Nr.createHeadlessRunner)({storagePath:c,packId:r,packVersion:n?.manifest.metadata.version,bundledPromptsDir:f,apiKey:e.apiKey,baseUrl:e.baseUrl,useLiteLLM:e.useLiteLLM,litellmApiKey:e.litellmApiKey,openaiApiKey:e.openaiApiKey,anthropicApiKey:e.anthropicApiKey,logger:l,freshState:!1,claudeCodeExecutablePath:d,codexExecutablePath:u,permissionHandler:p,cliEnvPatch:(0,Q$.buildCliEnvPatch)({cliPath:process.execPath,workspaceRoot:t.workspace,agentId:r,chatSessionId:m,baseEnv:process.env}),dataPlane:h??void 0,...o?{engineSettings:{claudeCheapModel:o}}:{}}),E={runner:y(),sessionId:m,engine:s,model:i},w=()=>({async thinking(v){process.stdout.write(`${he.COLORS.gray}${v}${he.COLORS.reset}`)},async text(v){process.stdout.write(v)},async toolStart(v,A){console.log(`
487
487
  ${he.COLORS.blue}Tool: ${v}${he.COLORS.reset}`),A&&A.length<200&&t.verbose&&console.log(` ${he.COLORS.gray}${A}${he.COLORS.reset}`)},async toolEnd(v,A,N,I){console.log(I?` ${he.COLORS.red}Error: ${N?.slice(0,100)}${he.COLORS.reset}`:` ${he.COLORS.green}OK${he.COLORS.reset}`)},async progress(v){t.verbose&&console.log(`${he.COLORS.yellow}Progress: ${v}${he.COLORS.reset}`)},async error(v){console.error(`${he.COLORS.red}Error: ${v}${he.COLORS.reset}`)},async question(v){return{selected:[],freeText:null,declined:!0}},async done(){console.log(`
488
488
  `)}});console.log(""),console.log(yf),console.log(`${q_.AGENTIDE_BRAND_NAME} Chat`),console.log(yf),console.log(`Engine: ${E.engine}`),console.log(`Model: ${E.model}`),o&&console.log(`Cheap: ${o}`),console.log(`Workspace: ${t.workspace}`),n&&console.log(`Agent: ${n.manifest.metadata.name}`),console.log(yf),console.log("Type a message to chat. Commands: /help"),console.log("");let O=Y$.createInterface({input:process.stdin,output:process.stdout}),b=()=>{O.question(`${he.COLORS.cyan}> ${he.COLORS.reset}`,async v=>{let A=v.trim();if(!A){b();return}if(A.startsWith("/")){if(!await tD(A,E,O,{createRunner:y,claudeCodePath:d,codexPath:u,turnScope:h}))return;b();return}try{let N=await E.runner.run({engineId:E.engine,modelId:E.model,message:A,workspaceRoot:t.workspace,sessionId:E.sessionId,emitter:w(),permissions:g});!N.success&&N.error&&console.error(`
package/out/extension.js CHANGED
@@ -1,11 +1,11 @@
1
1
  /*! Copyright (c) 2026 AgentHippo.ai. All rights reserved. Proprietary; see LICENSE. */
2
- "use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(t,a,e,m){m===void 0&&(m=e);var E=Object.getOwnPropertyDescriptor(a,e);(!E||("get"in E?!a.__esModule:E.writable||E.configurable))&&(E={enumerable:!0,get:function(){return a[e]}}),Object.defineProperty(t,m,E)}):(function(t,a,e,m){m===void 0&&(m=e),t[m]=a[e]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(t,a){Object.defineProperty(t,"default",{enumerable:!0,value:a})}):function(t,a){t.default=a}),__importStar=this&&this.__importStar||(function(){var t=function(a){return t=Object.getOwnPropertyNames||function(e){var m=[];for(var E in e)Object.prototype.hasOwnProperty.call(e,E)&&(m[m.length]=E);return m},t(a)};return function(a){if(a&&a.__esModule)return a;var e={};if(a!=null)for(var m=t(a),E=0;E<m.length;E++)m[E]!=="default"&&__createBinding(e,a,m[E]);return __setModuleDefault(e,a),e}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.activate=activate,exports.deactivate=deactivate;const vscode=__importStar(require("vscode")),fs_1=require("fs"),path=__importStar(require("path")),os=__importStar(require("os")),types_1=require("./engines/types"),factory_1=require("./engines/factory"),sync_1=require("./sync"),session_1=require("./session"),utils_1=require("./utils"),agentEnvFile_1=require("./utils/agentEnvFile"),index_1=require("./utils/index"),runtime_1=require("./cli/runtime"),mcp_1=require("./mcp"),terminalLogger_1=require("./terminalLogger"),workspaceFolders_1=require("./workspaceFolders"),branding_1=require("./branding"),binary_1=require("./utils/binary"),paths_1=require("./agentpack/paths"),permissions_1=require("./permissions"),vscode_edit_tracker_1=require("./runtime/vscode/vscode-edit-tracker"),vscode_logger_1=require("./runtime/vscode/vscode-logger"),vscode_config_provider_1=require("./runtime/vscode/vscode-config-provider"),permission_handler_1=require("./runtime/interfaces/permission-handler"),customRegistry_1=require("./engines/customRegistry"),handleRemoteChat_js_1=require("./remote/handleRemoteChat.js"),serveClient_js_1=require("./remote/serveClient.js"),remotePackStatusBar_js_1=require("./remote/remotePackStatusBar.js"),provider_js_1=require("./auth/provider.js"),signInFlow_js_1=require("./auth/signInFlow.js"),onboardingPrompt_js_1=require("./auth/onboardingPrompt.js"),githubStoreGate_js_1=require("./auth/githubStoreGate.js"),sessionEvents_1=require("./analytics/sessionEvents"),base_1=require("./engines/base"),turn_scope_1=require("./cli/data-plane/turn-scope"),BUNDLED_TOOLS_DIR_KEY="agentide.bundledToolsDir",AGENTIDE_SESSIONS_DIR_NAME=`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/${paths_1.AGENT_CONSTANTS.SESSIONS_DIR}`,TERMINAL_LOG_FILE_NAME="terminal.md",MAX_TERMINAL_LOG_BYTES=2*1024*1024,ATTACHMENTS_DIR_NAME="attachments";let _state,_extensionContext;const _activeRunsByStreamId=new Map,_ideTurnScopes=new Map;function getIdeTurnScope(t,a,e,m,E){const h=`${t}::${a}`;let C=_ideTurnScopes.get(h);return C||(C=(0,turn_scope_1.resolveLocalTurnScope)({spec:m?.spec,packPath:e,agent:m?{pack:m.metadata.name,version:m.metadata.version}:void 0,logger:new vscode_logger_1.VSCodeLogger(E,"[DataPlane]"),audit:(y,T,n)=>_sessionEventWriter.append(y,(0,base_1.generateRequestId)(),T,n)}).then(y=>(y&&log(E,`[AgentIDE] Data plane ${y.mode} \u2014 gateway ${y.gatewayUrl}; acting as ${y.userId} (locally asserted; per-turn registration)`),y)).catch(y=>{throw _ideTurnScopes.delete(h),y}),_ideTurnScopes.set(h,C)),C}const _pendingQuestionsById=new Map,STREAM_QUESTION_TIMEOUT_MS=1e3*60*10;function resolvePendingQuestion(t,a){const e=_pendingQuestionsById.get(t);return e?(clearTimeout(e.timeout),_pendingQuestionsById.delete(t),e.resolver(a),!0):!1}function rejectPendingQuestionsForStream(t,a){for(const[e,m]of _pendingQuestionsById)m.streamId===t&&(clearTimeout(m.timeout),_pendingQuestionsById.delete(e),m.rejecter(new Error(a)))}async function askQuestionFromChatUI(t,a){return await new Promise((e,m)=>{const E=setTimeout(()=>{_pendingQuestionsById.delete(a.questionId),m(new Error("Question timed out waiting for user response"))},STREAM_QUESTION_TIMEOUT_MS);_pendingQuestionsById.set(a.questionId,{streamId:t,question:a,resolver:e,rejecter:m,timeout:E}),Promise.resolve(vscode.commands.executeCommand("agentide.streamCallback",{streamId:t,type:"question",metadata:a})).catch(h=>{clearTimeout(E),_pendingQuestionsById.delete(a.questionId),m(h instanceof Error?h:new Error(String(h)))})})}function normalizeQuestionAnswer(t){const a=t&&typeof t=="object"?t:{},e=Array.isArray(a.selected)?a.selected.filter(E=>typeof E=="string"&&E.trim().length>0):[],m=typeof a.freeText=="string"?a.freeText:(a.freeText===null,null);return{selected:e,freeText:m,declined:a.declined===!0,timedOut:a.timedOut===!0,cancelled:a.cancelled===!0}}function questionPromptToHeader(t){const a=t.split(/\r?\n/,1)[0]?.trim()||"Question";return a.length<=50?a:`${a.slice(0,47)}...`}function streamPayloadToAskQuestionsInput(t){const e={header:questionPromptToHeader(t.prompt),question:t.prompt,multiSelect:t.multiSelect,allowFreeformInput:t.allowFreeText};return t.options?.length&&(e.options=t.options.map(m=>({label:m.label,description:m.description,recommended:m.recommended}))),{questions:[e]}}async function askQuestionViaWorkbenchTool(t,a,e,m){const E=new vscode.CancellationTokenSource;m.addEventListener("abort",()=>E.cancel(),{once:!0});try{const h=streamPayloadToAskQuestionsInput(e),T=(await vscode.lm.invokeTool("vscode_askQuestions",{input:h,toolInvocationToken:{sessionResource:vscode.Uri.parse(t)}},E.token))?.content?.find(c=>typeof c.value=="string")?.value;if(!T)return{selected:[],freeText:null,declined:!0};const s=JSON.parse(T)?.answers??{},l=Object.keys(s)[0],i=l?s[l]:void 0;return i?{selected:i.selected??[],freeText:i.freeText??null,declined:i.skipped===!0}:{selected:[],freeText:null,declined:!0}}catch(h){const C=h instanceof Error&&(h.name==="Canceled"||h.message?.includes("cancel"));return{selected:[],freeText:null,declined:!0,cancelled:C}}finally{E.dispose()}}const SESSION_CLEANUP_INTERVAL_MS=1e3*60*5;function log(t,a){t.appendLine((0,branding_1.brandify)(a))}function logConsole(t){console.log((0,branding_1.brandify)(t))}function showInfo(t){return vscode.window.showInformationMessage((0,branding_1.brandify)(t))}function showWarning(t){return vscode.window.showWarningMessage((0,branding_1.brandify)(t))}function showError(t){return vscode.window.showErrorMessage((0,branding_1.brandify)(t))}async function activate(t){const a=vscode.window.createOutputChannel(branding_1.AGENTIDE_EXTENSION_NAME);log(a,`${branding_1.AGENTIDE_BRAND_NAME} extension activating...`),logConsole(`${branding_1.AGENTIDE_BRAND_NAME} extension activating...`);try{const g=await(0,agentEnvFile_1.mergeAgentHomeEnvIntoProcessEnv)();g.applied.length>0&&log(a,`[AgentIDE] Loaded ${g.applied.length} env var(s) from ${g.envFilePath} (shell env wins on conflict)`)}catch(g){const D=g instanceof Error?g.message:String(g);log(a,`[AgentIDE] Warning: failed to load ~/.agent-hippo/.env: ${D}`)}_extensionContext=t;const e=(0,utils_1.getAnalyticsScriptsDir)(t.extensionPath);process.env.AGENTIDE_ANALYTICS_SCRIPTS_DIR=e,log(a,`[AgentIDE] Analytics scripts dir: ${e}`),(0,session_1.initSessionStore)(t);const m=new vscode_logger_1.VSCodeLogger(a,"[Maintenance]"),E=setInterval(()=>{if((0,session_1.runSessionMaintenance)(),_state)for(const g of Object.values(_state.engines))g.onMaintenance(m)},SESSION_CLEANUP_INTERVAL_MS);t.subscriptions.push(new vscode.Disposable(()=>clearInterval(E)));const h=t.storageUri??t.globalStorageUri,C=t.storageUri?"per-workspace":"global",y={storagePath:h.fsPath},T=process.env.AGENTHIPPO_LITELLM_API_KEY?.trim()||process.env.LITELLM_MASTER_KEY?.trim();T&&(y.litellmApiKey=T,log(a,"[AgentIDE] Using local LiteLLM key from ~/.agent-hippo/.env"));for(const g of Object.values(types_1.AGENT_ENGINES)){const D=path.join(h.fsPath,g.id);try{await fs_1.promises.mkdir(D,{recursive:!0}),log(a,`[AgentIDE] ${g.displayName} dir: ${D} (${C})`),g.configEnvVar==="CODEX_HOME"?y.codexHome=D:g.configEnvVar==="CLAUDE_CONFIG_DIR"&&(y.claudeConfigDir=D)}catch(M){log(a,`[AgentIDE] Warning: failed to create ${g.id} dir: ${M instanceof Error?M.message:String(M)}`)}}const n=new sync_1.SyncService(()=>getBundledBasePromptsDir()),s=(0,factory_1.createEngines)({config:y,syncService:n,getBundledBasePromptsDir:()=>getBundledBasePromptsDir()});_state={outputChannel:a,engines:s,syncService:n,config:y};try{const g=vscode.workspace.getConfiguration("chat"),D=g.inspect("useAgentSkills");D&&!D.globalValue&&!D.workspaceValue&&!D.workspaceFolderValue&&(await g.update("useAgentSkills",!0,vscode.ConfigurationTarget.Global),log(a,"[AgentIDE] Enabled Agent Skills by default"))}catch(g){log(a,`[AgentIDE] Warning: failed to enable Agent Skills setting: ${g instanceof Error?g.message:String(g)}`)}await registerBundledMcpServers(t,a),(0,provider_js_1.registerAgentHippoAuth)(t),(0,provider_js_1.refreshBootstrapIfSignedIn)(t),t.subscriptions.push((0,provider_js_1.startAgentHippoTokenRefreshTimer)(t)),(0,onboardingPrompt_js_1.scheduleSignInOnboardingPrompt)(t),registerCommands(t,_state);const l=new remotePackStatusBar_js_1.RemotePackStatusBar(n,()=>getWorkspaceRoot(a).workspaceRoot,a);_state.remotePackStatusBar=l,t.subscriptions.push(l),l.refresh();const{GatewayLifecycleManager:i}=await import("./gateway/lifecycle.js");_state.gatewayLifecycle=new i(a,t),t.subscriptions.push({dispose:()=>_state?.gatewayLifecycle?.dispose()});const{GatewayService:c}=await import("./gateway/service.js");_state.gatewayService=new c(t,a),t.subscriptions.push({dispose:()=>_state?.gatewayService?.dispose()}),_state.gatewayLifecycle.setBridgeRef(_state.gatewayService),_state.gatewayLifecycle.onStatusChange(async g=>{g==="running"&&vscode.workspace.getConfiguration("agentide.anywhere").get("autoConnect",!1)&&_state?.gatewayLifecycle&&_state.gatewayLifecycle.connectBridge()});const{AnalyticsService:u}=await import("./analytics/service.js");_state.analyticsService=new u(t,a),t.subscriptions.push({dispose:()=>_state?.analyticsService?.dispose()});const{AnalyticsDashboardProvider:d,ArtifactManagerImpl:o,QueryRunnerImpl:r,ensureBundledFleetAdapters:p}=await import("./analytics/dashboard/index.js"),S=new o(a),k=new o(a),A=new r(a);p(A);const $=_state.analyticsService;_state.analyticsDashboard=new d(t,A,S,a,()=>$?.getIndexingService());const f=new d(t,A,k,a,()=>$?.getIndexingService(),"team");_state.analyticsTeamDashboard=f,t.subscriptions.push(vscode.window.registerWebviewViewProvider(d.viewType,_state.analyticsDashboard,{webviewOptions:{retainContextWhenHidden:!0}}),vscode.window.registerWebviewViewProvider("agentide.teamView",f,{webviewOptions:{retainContextWhenHidden:!0}}),_state.analyticsDashboard,f,{dispose:()=>S.dispose()},{dispose:()=>k.dispose()},{dispose:()=>A.dispose()}),t.subscriptions.push(vscode.commands.registerCommand("agentide.analytics.openDashboard",()=>{vscode.commands.executeCommand("agentide.analyticsView.focus")}),vscode.commands.registerCommand("agentide.fleet.open",async()=>{const g=_state?.analyticsTeamDashboard;g&&await g.openWithView("fleet"),await vscode.commands.executeCommand("agentide.teamView.focus")}),vscode.commands.registerCommand("agentide.analytics.clearArtifacts",async()=>{const g=await S.cleanup(0);await t.workspaceState.update("analytics.generatedDefaultDashboard",!1),vscode.window.showInformationMessage(`Cleared ${g.deletedCount} Spotlight artifacts (${(g.freedBytes/1024).toFixed(1)} KB)`)}),vscode.commands.registerCommand("agentide.analytics.regenerateDefaults",async()=>{_state?.analyticsDashboard&&(A.invalidateCache(),await _state.analyticsDashboard.runDefaultChartScript())}),vscode.commands.registerCommand("agentide.persistChatVote",async g=>{!g?.sessionId||!g?.requestId||await _sessionEventWriter.append(g.sessionId,g.requestId,"vote",{direction:g.direction,reason:g.reason,agentId:g.agentId,command:g.command})})),(0,terminalLogger_1.activateTerminalLogger)(t);const w=setTimeout(()=>{(0,terminalLogger_1.cleanupOldSessionLogs)(a)},5e3);t.subscriptions.push(new vscode.Disposable(()=>clearTimeout(w)));const I=setTimeout(async()=>{try{const{initializeStoreIndex:g}=await import("./store/oramaIndex.js");await g(a)}catch(g){log(a,`[AgentIDE] Store index init: ${g instanceof Error?g.message:String(g)}`)}},3e3);t.subscriptions.push(new vscode.Disposable(()=>clearTimeout(I))),vscode.workspace.workspaceFolders?.length&&refreshAgentideProject(_state).then(async()=>{n.ensureAgentideWatchers(a);try{const{workspaceRoot:g}=getWorkspaceRoot(a),{AgentPackManager:D}=await import("./agentpack/index.js"),M=new D(n,()=>g,()=>y.storagePath,a),{registered:b}=await M.repairUnregisteredAgents();b.length>0&&log(a,`[AgentIDE] Auto-repaired ${b.length} unregistered pack(s): ${b.join(", ")}`)}catch(g){log(a,`[AgentIDE] Pack repair check failed: ${g instanceof Error?g.message:String(g)}`)}_state?.remotePackStatusBar?.refresh()}),t.subscriptions.push(vscode.workspace.onDidChangeWorkspaceFolders(()=>{n.ensureAgentideWatchers(a),_state&&(refreshAgentideProject(_state),_state.remotePackStatusBar?.refresh())})),t.subscriptions.push(new vscode.Disposable(()=>{n.disposeAllWatchers()})),log(a,"[AgentIDE] Extension activation complete")}function deactivate(){if(_state)for(const t of Object.values(_state.engines))try{t.dispose()}catch{}for(const t of _ideTurnScopes.values())t.then(a=>a?.close()).catch(()=>{});_ideTurnScopes.clear(),_state=void 0}function escapeRegExp(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function quoteEnvValue(t){return/^[A-Za-z0-9_./:@-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function upsertEnvVar(t,a,e){const m=t.split(/\r?\n/),E=new RegExp(`^\\s*(?:export\\s+)?${escapeRegExp(a)}\\s*=`);let h=!1;for(let C=0;C<m.length;C++){const y=m[C],T=y.trim();!T||T.startsWith("#")||E.test(y)&&(m[C]=`${a}=${quoteEnvValue(e)}`,h=!0)}return h||(m.length>0&&m[m.length-1].trim()!==""&&m.push(""),m.push(`${a}=${quoteEnvValue(e)}`)),m.join(`
2
+ "use strict";var __createBinding=this&&this.__createBinding||(Object.create?(function(t,r,e,m){m===void 0&&(m=e);var E=Object.getOwnPropertyDescriptor(r,e);(!E||("get"in E?!r.__esModule:E.writable||E.configurable))&&(E={enumerable:!0,get:function(){return r[e]}}),Object.defineProperty(t,m,E)}):(function(t,r,e,m){m===void 0&&(m=e),t[m]=r[e]})),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?(function(t,r){Object.defineProperty(t,"default",{enumerable:!0,value:r})}):function(t,r){t.default=r}),__importStar=this&&this.__importStar||(function(){var t=function(r){return t=Object.getOwnPropertyNames||function(e){var m=[];for(var E in e)Object.prototype.hasOwnProperty.call(e,E)&&(m[m.length]=E);return m},t(r)};return function(r){if(r&&r.__esModule)return r;var e={};if(r!=null)for(var m=t(r),E=0;E<m.length;E++)m[E]!=="default"&&__createBinding(e,r,m[E]);return __setModuleDefault(e,r),e}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.activate=activate,exports.deactivate=deactivate;const vscode=__importStar(require("vscode")),fs_1=require("fs"),path=__importStar(require("path")),os=__importStar(require("os")),types_1=require("./engines/types"),factory_1=require("./engines/factory"),sync_1=require("./sync"),session_1=require("./session"),utils_1=require("./utils"),agentEnvFile_1=require("./utils/agentEnvFile"),index_1=require("./utils/index"),runtime_1=require("./cli/runtime"),mcp_1=require("./mcp"),terminalLogger_1=require("./terminalLogger"),workspaceFolders_1=require("./workspaceFolders"),branding_1=require("./branding"),binary_1=require("./utils/binary"),paths_1=require("./agentpack/paths"),permissions_1=require("./permissions"),vscode_edit_tracker_1=require("./runtime/vscode/vscode-edit-tracker"),vscode_logger_1=require("./runtime/vscode/vscode-logger"),vscode_config_provider_1=require("./runtime/vscode/vscode-config-provider"),permission_handler_1=require("./runtime/interfaces/permission-handler"),customRegistry_1=require("./engines/customRegistry"),handleRemoteChat_js_1=require("./remote/handleRemoteChat.js"),serveClient_js_1=require("./remote/serveClient.js"),remotePackStatusBar_js_1=require("./remote/remotePackStatusBar.js"),provider_js_1=require("./auth/provider.js"),signInFlow_js_1=require("./auth/signInFlow.js"),onboardingPrompt_js_1=require("./auth/onboardingPrompt.js"),githubStoreGate_js_1=require("./auth/githubStoreGate.js"),sessionEvents_1=require("./analytics/sessionEvents"),base_1=require("./engines/base"),turn_scope_1=require("./cli/data-plane/turn-scope"),BUNDLED_TOOLS_DIR_KEY="agentide.bundledToolsDir",AGENTIDE_SESSIONS_DIR_NAME=`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/${paths_1.AGENT_CONSTANTS.SESSIONS_DIR}`,TERMINAL_LOG_FILE_NAME="terminal.md",MAX_TERMINAL_LOG_BYTES=2*1024*1024,ATTACHMENTS_DIR_NAME="attachments";let _state,_extensionContext;const _activeRunsByStreamId=new Map,_ideTurnScopes=new Map;function getIdeTurnScope(t,r,e,m,E){const h=`${t}::${r}`;let C=_ideTurnScopes.get(h);return C||(C=(0,turn_scope_1.resolveLocalTurnScope)({spec:m?.spec,packPath:e,agent:m?{pack:m.metadata.name,version:m.metadata.version}:void 0,logger:new vscode_logger_1.VSCodeLogger(E,"[DataPlane]"),audit:(A,T,n)=>_sessionEventWriter.append(A,(0,base_1.generateRequestId)(),T,n)}).then(A=>(A&&log(E,`[AgentIDE] Data plane ${A.mode} \u2014 gateway ${A.gatewayUrl}; acting as ${A.userId} (locally asserted; per-turn registration)`),A)).catch(A=>{throw _ideTurnScopes.delete(h),A}),_ideTurnScopes.set(h,C)),C}const _pendingQuestionsById=new Map,STREAM_QUESTION_TIMEOUT_MS=1e3*60*10;function resolvePendingQuestion(t,r){const e=_pendingQuestionsById.get(t);return e?(clearTimeout(e.timeout),_pendingQuestionsById.delete(t),e.resolver(r),!0):!1}function rejectPendingQuestionsForStream(t,r){for(const[e,m]of _pendingQuestionsById)m.streamId===t&&(clearTimeout(m.timeout),_pendingQuestionsById.delete(e),m.rejecter(new Error(r)))}async function askQuestionFromChatUI(t,r){return await new Promise((e,m)=>{const E=setTimeout(()=>{_pendingQuestionsById.delete(r.questionId),m(new Error("Question timed out waiting for user response"))},STREAM_QUESTION_TIMEOUT_MS);_pendingQuestionsById.set(r.questionId,{streamId:t,question:r,resolver:e,rejecter:m,timeout:E}),Promise.resolve(vscode.commands.executeCommand("agentide.streamCallback",{streamId:t,type:"question",metadata:r})).catch(h=>{clearTimeout(E),_pendingQuestionsById.delete(r.questionId),m(h instanceof Error?h:new Error(String(h)))})})}function normalizeQuestionAnswer(t){const r=t&&typeof t=="object"?t:{},e=Array.isArray(r.selected)?r.selected.filter(E=>typeof E=="string"&&E.trim().length>0):[],m=typeof r.freeText=="string"?r.freeText:(r.freeText===null,null);return{selected:e,freeText:m,declined:r.declined===!0,timedOut:r.timedOut===!0,cancelled:r.cancelled===!0}}function questionPromptToHeader(t){const r=t.split(/\r?\n/,1)[0]?.trim()||"Question";return r.length<=50?r:`${r.slice(0,47)}...`}function streamPayloadToAskQuestionsInput(t){const e={header:questionPromptToHeader(t.prompt),question:t.prompt,multiSelect:t.multiSelect,allowFreeformInput:t.allowFreeText};return t.options?.length&&(e.options=t.options.map(m=>({label:m.label,description:m.description,recommended:m.recommended}))),{questions:[e]}}async function askQuestionViaWorkbenchTool(t,r,e,m){const E=new vscode.CancellationTokenSource;m.addEventListener("abort",()=>E.cancel(),{once:!0});try{const h=streamPayloadToAskQuestionsInput(e),T=(await vscode.lm.invokeTool("vscode_askQuestions",{input:h,toolInvocationToken:{sessionResource:vscode.Uri.parse(t)}},E.token))?.content?.find(l=>typeof l.value=="string")?.value;if(!T)return{selected:[],freeText:null,declined:!0};const s=JSON.parse(T)?.answers??{},c=Object.keys(s)[0],i=c?s[c]:void 0;return i?{selected:i.selected??[],freeText:i.freeText??null,declined:i.skipped===!0}:{selected:[],freeText:null,declined:!0}}catch(h){const C=h instanceof Error&&(h.name==="Canceled"||h.message?.includes("cancel"));return{selected:[],freeText:null,declined:!0,cancelled:C}}finally{E.dispose()}}const SESSION_CLEANUP_INTERVAL_MS=1e3*60*5;function log(t,r){t.appendLine((0,branding_1.brandify)(r))}function logConsole(t){console.log((0,branding_1.brandify)(t))}function showInfo(t){return vscode.window.showInformationMessage((0,branding_1.brandify)(t))}function showWarning(t){return vscode.window.showWarningMessage((0,branding_1.brandify)(t))}function showError(t){return vscode.window.showErrorMessage((0,branding_1.brandify)(t))}async function activate(t){const r=vscode.window.createOutputChannel(branding_1.AGENTIDE_EXTENSION_NAME);log(r,`${branding_1.AGENTIDE_BRAND_NAME} extension activating...`),logConsole(`${branding_1.AGENTIDE_BRAND_NAME} extension activating...`);try{const g=await(0,agentEnvFile_1.mergeAgentHomeEnvIntoProcessEnv)();g.applied.length>0&&log(r,`[AgentIDE] Loaded ${g.applied.length} env var(s) from ${g.envFilePath} (shell env wins on conflict)`)}catch(g){const D=g instanceof Error?g.message:String(g);log(r,`[AgentIDE] Warning: failed to load ~/.agent-hippo/.env: ${D}`)}_extensionContext=t;const e=(0,utils_1.getAnalyticsScriptsDir)(t.extensionPath);process.env.AGENTIDE_ANALYTICS_SCRIPTS_DIR=e,log(r,`[AgentIDE] Analytics scripts dir: ${e}`),(0,session_1.initSessionStore)(t);const m=new vscode_logger_1.VSCodeLogger(r,"[Maintenance]"),E=setInterval(()=>{if((0,session_1.runSessionMaintenance)(),_state)for(const g of Object.values(_state.engines))g.onMaintenance(m)},SESSION_CLEANUP_INTERVAL_MS);t.subscriptions.push(new vscode.Disposable(()=>clearInterval(E)));const h=t.storageUri??t.globalStorageUri,C=t.storageUri?"per-workspace":"global",A={storagePath:h.fsPath},T=process.env.AGENTHIPPO_LITELLM_API_KEY?.trim()||process.env.LITELLM_MASTER_KEY?.trim();T&&(A.litellmApiKey=T,log(r,"[AgentIDE] Using local LiteLLM key from ~/.agent-hippo/.env"));for(const g of Object.values(types_1.AGENT_ENGINES)){const D=path.join(h.fsPath,g.id);try{await fs_1.promises.mkdir(D,{recursive:!0}),log(r,`[AgentIDE] ${g.displayName} dir: ${D} (${C})`),g.configEnvVar==="CODEX_HOME"?A.codexHome=D:g.configEnvVar==="CLAUDE_CONFIG_DIR"&&(A.claudeConfigDir=D)}catch(M){log(r,`[AgentIDE] Warning: failed to create ${g.id} dir: ${M instanceof Error?M.message:String(M)}`)}}const n=new sync_1.SyncService(()=>getBundledBasePromptsDir()),s=(0,factory_1.createEngines)({config:A,syncService:n,getBundledBasePromptsDir:()=>getBundledBasePromptsDir()});_state={outputChannel:r,engines:s,syncService:n,config:A};try{const g=vscode.workspace.getConfiguration("chat"),D=g.inspect("useAgentSkills");D&&!D.globalValue&&!D.workspaceValue&&!D.workspaceFolderValue&&(await g.update("useAgentSkills",!0,vscode.ConfigurationTarget.Global),log(r,"[AgentIDE] Enabled Agent Skills by default"))}catch(g){log(r,`[AgentIDE] Warning: failed to enable Agent Skills setting: ${g instanceof Error?g.message:String(g)}`)}await registerBundledMcpServers(t,r),(0,provider_js_1.registerAgentHippoAuth)(t),(0,provider_js_1.refreshBootstrapIfSignedIn)(t),t.subscriptions.push((0,provider_js_1.startAgentHippoTokenRefreshTimer)(t)),(0,onboardingPrompt_js_1.scheduleSignInOnboardingPrompt)(t),registerCommands(t,_state);const c=new remotePackStatusBar_js_1.RemotePackStatusBar(n,()=>getWorkspaceRoot(r).workspaceRoot,r);_state.remotePackStatusBar=c,t.subscriptions.push(c),c.refresh();const{GatewayLifecycleManager:i}=await import("./gateway/lifecycle.js");_state.gatewayLifecycle=new i(r,t),t.subscriptions.push({dispose:()=>_state?.gatewayLifecycle?.dispose()});const{GatewayService:l}=await import("./gateway/service.js");_state.gatewayService=new l(t,r),t.subscriptions.push({dispose:()=>_state?.gatewayService?.dispose()}),_state.gatewayLifecycle.setBridgeRef(_state.gatewayService),_state.gatewayLifecycle.onStatusChange(async g=>{g==="running"&&vscode.workspace.getConfiguration("agentide.anywhere").get("autoConnect",!1)&&_state?.gatewayLifecycle&&_state.gatewayLifecycle.connectBridge()});const{AnalyticsService:u}=await import("./analytics/service.js");_state.analyticsService=new u(t,r),t.subscriptions.push({dispose:()=>_state?.analyticsService?.dispose()});const{AnalyticsDashboardProvider:d,ArtifactManagerImpl:o,QueryRunnerImpl:a,ensureBundledFleetAdapters:p}=await import("./analytics/dashboard/index.js"),S=new o(r),k=new o(r),y=new a(r);p(y);const $=_state.analyticsService;_state.analyticsDashboard=new d(t,y,S,r,()=>$?.getIndexingService());const f=new d(t,y,k,r,()=>$?.getIndexingService(),"team");_state.analyticsTeamDashboard=f,t.subscriptions.push(vscode.window.registerWebviewViewProvider(d.viewType,_state.analyticsDashboard,{webviewOptions:{retainContextWhenHidden:!0}}),vscode.window.registerWebviewViewProvider("agentide.teamView",f,{webviewOptions:{retainContextWhenHidden:!0}}),_state.analyticsDashboard,f,{dispose:()=>S.dispose()},{dispose:()=>k.dispose()},{dispose:()=>y.dispose()}),t.subscriptions.push(vscode.commands.registerCommand("agentide.analytics.openDashboard",()=>{vscode.commands.executeCommand("agentide.analyticsView.focus")}),vscode.commands.registerCommand("agentide.fleet.open",async()=>{const g=_state?.analyticsTeamDashboard;g&&await g.openWithView("fleet"),await vscode.commands.executeCommand("agentide.teamView.focus")}),vscode.commands.registerCommand("agentide.analytics.clearArtifacts",async()=>{const g=await S.cleanup(0);await t.workspaceState.update("analytics.generatedDefaultDashboard",!1),vscode.window.showInformationMessage(`Cleared ${g.deletedCount} Spotlight artifacts (${(g.freedBytes/1024).toFixed(1)} KB)`)}),vscode.commands.registerCommand("agentide.analytics.regenerateDefaults",async()=>{_state?.analyticsDashboard&&(y.invalidateCache(),await _state.analyticsDashboard.runDefaultChartScript())}),vscode.commands.registerCommand("agentide.persistChatVote",async g=>{!g?.sessionId||!g?.requestId||await _sessionEventWriter.append(g.sessionId,g.requestId,"vote",{direction:g.direction,reason:g.reason,agentId:g.agentId,command:g.command})})),(0,terminalLogger_1.activateTerminalLogger)(t);const w=setTimeout(()=>{(0,terminalLogger_1.cleanupOldSessionLogs)(r)},5e3);t.subscriptions.push(new vscode.Disposable(()=>clearTimeout(w)));const I=setTimeout(async()=>{try{const{initializeStoreIndex:g}=await import("./store/oramaIndex.js");await g(r)}catch(g){log(r,`[AgentIDE] Store index init: ${g instanceof Error?g.message:String(g)}`)}},3e3);t.subscriptions.push(new vscode.Disposable(()=>clearTimeout(I))),vscode.workspace.workspaceFolders?.length&&refreshAgentideProject(_state).then(async()=>{n.ensureAgentideWatchers(r);try{const{workspaceRoot:g}=getWorkspaceRoot(r),{AgentPackManager:D}=await import("./agentpack/index.js"),M=new D(n,()=>g,()=>A.storagePath,r),{registered:b}=await M.repairUnregisteredAgents();b.length>0&&log(r,`[AgentIDE] Auto-repaired ${b.length} unregistered pack(s): ${b.join(", ")}`)}catch(g){log(r,`[AgentIDE] Pack repair check failed: ${g instanceof Error?g.message:String(g)}`)}_state?.remotePackStatusBar?.refresh()}),t.subscriptions.push(vscode.workspace.onDidChangeWorkspaceFolders(()=>{n.ensureAgentideWatchers(r),_state&&(refreshAgentideProject(_state),_state.remotePackStatusBar?.refresh())})),t.subscriptions.push(new vscode.Disposable(()=>{n.disposeAllWatchers()})),log(r,"[AgentIDE] Extension activation complete")}function deactivate(){if(_state)for(const t of Object.values(_state.engines))try{t.dispose()}catch{}for(const t of _ideTurnScopes.values())t.then(r=>r?.close()).catch(()=>{});_ideTurnScopes.clear(),_state=void 0}function escapeRegExp(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function quoteEnvValue(t){return/^[A-Za-z0-9_./:@-]+$/.test(t)?t:`'${t.replace(/'/g,"'\\''")}'`}function upsertEnvVar(t,r,e){const m=t.split(/\r?\n/),E=new RegExp(`^\\s*(?:export\\s+)?${escapeRegExp(r)}\\s*=`);let h=!1;for(let C=0;C<m.length;C++){const A=m[C],T=A.trim();!T||T.startsWith("#")||E.test(A)&&(m[C]=`${r}=${quoteEnvValue(e)}`,h=!0)}return h||(m.length>0&&m[m.length-1].trim()!==""&&m.push(""),m.push(`${r}=${quoteEnvValue(e)}`)),m.join(`
3
3
  `).replace(/\s*$/,`
4
- `)}function hasEnvVar(t,a){const e=new RegExp(`^\\s*(?:export\\s+)?${escapeRegExp(a)}\\s*=`);return t.split(/\r?\n/).some(m=>{const E=m.trim();return!E||E.startsWith("#")?!1:e.test(m)})}function registerCommands(t,a){const{outputChannel:e,syncService:m,config:E}=a;t.subscriptions.push(vscode.commands.registerCommand("agentide.setParticipantApiKey",n=>{log(e,`[AgentIDE] Setting API key for ${n.provider}${n.baseUrl?` with baseUrl: ${n.baseUrl}`:""}`),n.provider==="litellm"&&(E.litellmApiKey=n.apiKey,E.litellmBaseUrl=n.baseUrl)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.binary.findOnPath",async n=>{const s=n?.name?.trim();if(!s)throw new Error("Binary name is required");return(0,binary_1.findBinaryCached)(s,(0,binary_1.getCommonBinaryPaths)(s))}));const h=async n=>{log(e,"[AgentIDE] Starting native OpenAI Codex OAuth login");const{loginOpenAICodex:s}=await import("@mariozechner/pi-ai"),l={onAuth:async({url:o})=>{n(o),log(e,`[AgentIDE] OpenAI Codex OAuth URL: ${o}`);try{await vscode.env.openExternal(vscode.Uri.parse(o)),showInfo("Complete ChatGPT sign-in in your browser. Return here if prompted for a redirect URL.")}catch(r){log(e,`[AgentIDE] Failed to auto-open OAuth URL: ${String(r)}`),showWarning(`Open this URL in your browser: ${o}`)}},onPrompt:async()=>{const o=await vscode.window.showInputBox({title:"ChatGPT Sign-In",prompt:"If your browser finished signing in, copy the full address from its address bar and paste it here.",placeHolder:"http://localhost:1455/auth/callback?code=\u2026",ignoreFocusOut:!0,validateInput:r=>r.trim().length>0?void 0:"Required"});if(!o||o.trim().length===0)throw new Error("OpenAI Codex OAuth cancelled");return o.trim()},onProgress:o=>{log(e,`[AgentIDE] OpenAI Codex OAuth: ${o}`)}};let i;for(let o=1;;o++)try{i=await s(l);break}catch(r){if(!(r instanceof Error&&r.message.includes("only available in Node.js environments"))||o>=20)throw r;await new Promise(S=>setTimeout(S,50))}const c=i?.access?.trim();if(!c)throw new Error("OpenAI Codex OAuth completed without an access token");const u={type:"oauth",...i},d={apiKey:c,oauthCredential:u,expiresAt:typeof i.expires=="number"?i.expires:void 0};return log(e,"[AgentIDE] OpenAI Codex OAuth login complete"),d};let C;t.subscriptions.push(vscode.commands.registerCommand("agentide.openaiCodex.loginOAuth",async()=>{if(C)return log(e,"[AgentIDE] OpenAI Codex OAuth login already in progress; joining it"),C.url&&vscode.env.openExternal(vscode.Uri.parse(C.url)),showInfo("A ChatGPT sign-in is already in progress. Finish it in your browser."),C.result;const n={result:h(s=>{n.url=s})};C=n;try{return await n.result}finally{C===n&&(C=void 0)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.openaiCodex.getValidApiKey",async n=>{const s=n?.oauthCredential;if(!s||typeof s!="object")throw new Error("Missing openai-codex OAuth credential payload.");const{getOAuthApiKey:l}=await import("@mariozechner/pi-ai"),c={"openai-codex":s.type==="oauth"?s:{type:"oauth",...s}},u=await l("openai-codex",c);if(!u?.apiKey)throw new Error("OpenAI Codex OAuth credential is invalid or expired. Please sign in again.");return{apiKey:String(u.apiKey),oauthCredential:{type:"oauth",...u.newCredentials},expiresAt:typeof u.newCredentials?.expires=="number"?u.newCredentials.expires:void 0}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.litellm.setUpstreamApiKey",async n=>{const s=n?.envVar?.trim()??"",l=n?.apiKey?.trim()??"";if(!s||!/^[A-Z][A-Z0-9_]*$/.test(s))throw new Error(`Invalid env var name: ${s}`);if(!l)throw new Error(`API key value cannot be empty for ${s}`);const i=(0,index_1.getAgentideHome)(),c=path.join(i,".env");await fs_1.promises.mkdir(i,{recursive:!0,mode:448});let u="";try{u=await fs_1.promises.readFile(c,"utf8")}catch{}const d=upsertEnvVar(u,s,l);await fs_1.promises.writeFile(c,d,"utf8");try{await fs_1.promises.chmod(c,384)}catch{}return log(e,`[AgentIDE] Updated LiteLLM upstream key in ${c} (${s})`),{envFilePath:c,envVar:s}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.litellm.getUpstreamApiKeyStatus",async n=>{const s=n?.envVar?.trim()??"";if(!s||!/^[A-Z][A-Z0-9_]*$/.test(s))throw new Error(`Invalid env var name: ${s}`);const l=(0,index_1.getAgentideHome)(),i=path.join(l,".env");let c="";try{c=await fs_1.promises.readFile(i,"utf8")}catch{}return{envFilePath:i,envVar:s,exists:hasEnvVar(c,s)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.clearManagedResources",async()=>{if(await vscode.window.showWarningMessage((0,branding_1.brandify)("Clear all AgentIDE managed resources?"),{modal:!0,detail:`This will remove derived folders and generated files. User-managed files in \`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/\` will NOT be deleted.`},"Clear Resources","Cancel")!=="Clear Resources")return;const{workspaceRoot:s,additionalDirectories:l,isHomeFallback:i}=getWorkspaceRoot(e);i&&await ensureFallbackDirectoryExists(e);const{cleared:c,skipped:u,errors:d}=await m.clearManagedResources(E.codexHome,E.claudeConfigDir,s,l,e),o=[`Cleared: ${c.length} resources`,u.length>0?`Skipped: ${u.length} (user files)`:"",d.length>0?`Errors: ${d.length}`:""].filter(Boolean).join(" | ");d.length>0?(showError(`AgentIDE: ${o}`),log(e,`[AgentIDE] Errors: ${d.join(", ")}`)):showInfo(`AgentIDE: ${o}`),log(e,`[AgentIDE] Clear complete: ${o}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skills.syncRemote",async()=>{const{workspaceRoot:n,additionalDirectories:s,isHomeFallback:l}=getWorkspaceRoot(e);l&&await ensureFallbackDirectoryExists(e),await m.ensureAgentideProjectPrepared(n,s,e),await m.syncRemoteSkillsIfEnabled(n,e,{force:!0}),await m.flushAgentideRootUpdate(n,e,{allowDuringActiveTurn:!0,force:!1}),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Remote skills sync complete (see ${branding_1.AGENTIDE_BRAND_NAME} output for details).`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.showManagedResources",async()=>{const{workspaceRoot:n,additionalDirectories:s,isHomeFallback:l}=getWorkspaceRoot(e);l&&await ensureFallbackDirectoryExists(e),await m.writeManagedPathsManifest(E.codexHome,E.claudeConfigDir,n,s,e);const i=path.join((0,paths_1.getAgentideDir)(n),"paths.md");if(await(0,utils_1.pathExists)(i)){const c=await vscode.workspace.openTextDocument(i);await vscode.window.showTextDocument(c)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cleanupSessionLogs",async()=>{const n=await(0,terminalLogger_1.cleanupOldSessionLogs)(e);n.cleaned>0?showInfo(`AgentIDE: Cleaned up ${n.cleaned} old session(s)`):n.errors.length>0?showWarning(`AgentIDE: Cleanup completed with ${n.errors.length} error(s)`):showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No old sessions to clean up`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.deleteSessionLogs",async n=>{const s=n?.sessionId;if(!s)return{deleted:!1,error:"sessionId is required"};const l=await(0,terminalLogger_1.deleteSessionLogs)(s);return l.deleted?(log(e,`[AgentIDE] Deleted session logs: ${s}`),(0,terminalLogger_1.cleanupOldSessionLogs)(e)):l.error&&log(e,`[AgentIDE] Failed to delete session logs: ${l.error}`),l})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cli.status",async()=>{const n=vscode.workspace.getConfiguration("agentide").get("cli.path",""),s=await(0,runtime_1.getCliHealth)({configuredPath:n,extensionPath:t.extensionPath}),i=(0,runtime_1.getBundledToolsHealth)({extensionPath:t.extensionPath,binaryDirHint:s.path?path.dirname(s.path):void 0}).tools.filter(c=>c.available).map(c=>c.name);if(s.installed){const c=s.source==="setting"?"configured path":s.source==="bundled"?"bundled binary":"system PATH",u=i.length>0?`; tools: ${i.join(", ")}`:"; tools: none";showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI available (${c})${s.version?` ${s.version}`:""}${u}`)}else showWarning(`${branding_1.AGENTIDE_BRAND_NAME}: CLI not found. Run '${branding_1.AGENTIDE_BRAND_NAME}: Setup AgentHippo CLI'.`);return s})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cli.isInstalled",async()=>{const n=vscode.workspace.getConfiguration("agentide").get("cli.path","");return(await(0,runtime_1.getCliHealth)({configuredPath:n,extensionPath:t.extensionPath})).installed})),t.subscriptions.push(vscode.commands.registerCommand("agentide.installBundledTools",async()=>{const n=(0,runtime_1.getBundledToolsHealth)({extensionPath:t.extensionPath});if(!n.platformKey){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Unsupported platform ${process.platform}-${process.arch}. Cannot install bundled tools.`);return}const s=t.globalStorageUri;if(!s){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No global storage path. Cannot install bundled tools.`);return}const l=path.join(s.fsPath,"tools"),c=[path.join(t.extensionPath,"out","scripts","vendor-tools.mjs"),path.join(t.extensionPath,"scripts","vendor-tools.mjs")].find(u=>{try{return require("fs").statSync(u).isFile()}catch{return!1}});if(!c){showError(`${branding_1.AGENTIDE_BRAND_NAME}: vendor-tools script not found. Run from extension source or rebuild.`);return}log(e,`[AgentIDE] Installing bundled tools (rg, sg, tree-sitter) into ${l} ...`);try{const{spawn:u}=await import("child_process");await new Promise((o,r)=>{const p=u(process.execPath,[c,"--out-dir",l,"--clean"],{stdio:["ignore","pipe","pipe"],env:{...process.env}});let S="";p.stdout?.on("data",k=>log(e,k.toString())),p.stderr?.on("data",k=>{S+=k.toString(),log(e,k.toString())}),p.on("error",r),p.on("close",k=>k===0?o():r(new Error(`Exit ${k}: ${S}`)))});const d=path.join(l,n.platformKey);await t.globalState.update(BUNDLED_TOOLS_DIR_KEY,d),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Bundled tools installed to ${d}. They will be used by the agent.`)}catch(u){const d=u instanceof Error?u.message:String(u);log(e,`[AgentIDE] Install bundled tools failed: ${d}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: Failed to install bundled tools. Check Output > Agent Hippo. ${d}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.setupCli",async()=>{log(e,"[AgentIDE] Starting CLI setup...");const n=vscode.workspace.getConfiguration("agentide.cli"),s=n.get("path",""),l=n.get("installSource","").trim();if(l&&/[;`|$&\n\r"']/.test(l))return showError(`${branding_1.AGENTIDE_BRAND_NAME}: Invalid CLI install source. Remove shell control characters from '${(0,branding_1.describeSettingKey)("agentide.cli.installSource")}'.`),{success:!1,error:"Invalid install source"};const i=await(0,runtime_1.getCliHealth)({configuredPath:s,extensionPath:t.extensionPath,forceRefresh:!0});if(i.installed&&i.path)return await vscode.workspace.getConfiguration("agentide").update("cli.path",i.path,vscode.ConfigurationTarget.Global),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI is ready at ${i.path}`),{success:!0,path:i.path};const u=process.platform==="win32"?"setup-cli.ps1":"setup-cli.sh",o=[path.join(t.extensionPath,"out","scripts",u),path.join(t.extensionPath,"scripts",u)].find(S=>{try{return require("fs").accessSync(S),!0}catch{return!1}});if(!o)return showError(`${branding_1.AGENTIDE_BRAND_NAME}: CLI setup script not found. Build CLI via extensions/agentide/scripts/build-cli.sh and set ${(0,branding_1.describeSettingKey)("agentide.cli.path")}.`),{success:!1,error:"Script not found"};const r=await y(o,e,l);if(!r.success)return r;const p=await(0,runtime_1.getCliHealth)({configuredPath:s,extensionPath:t.extensionPath,forceRefresh:!0});return p.installed&&p.path?(await vscode.workspace.getConfiguration("agentide").update("cli.path",p.path,vscode.ConfigurationTarget.Global),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI configured at ${p.path}`),{success:!0,path:p.path}):(showWarning(`${branding_1.AGENTIDE_BRAND_NAME}: Setup launched. Re-run '${branding_1.AGENTIDE_BRAND_NAME}: CLI Status' after terminal setup completes.`),{success:!0,pending:!0})}));async function y(n,s,l){const i=process.platform==="win32",c=/^https?:\/\//i.test(l),u=l?i?`-Source "${l}"`:`--source "${l}"`:"",d=i?vscode.window.createTerminal({name:"AgentHippo CLI Setup",cwd:path.dirname(n),shellPath:"powershell.exe",shellArgs:["-NoProfile","-NoExit","-ExecutionPolicy","Bypass","-Command",`& "${n}" ${u} -Yes; Write-Host ""; Write-Host "You can close this window."`]}):vscode.window.createTerminal({name:"AgentHippo CLI Setup",cwd:path.dirname(n),shellPath:"/bin/bash",shellArgs:["-c",`"${n}" ${u} --yes; echo ''; echo 'Press any key to close...'; read -n 1`]});return l&&log(s,`[AgentIDE] CLI install source configured (${c?"url":"package/path"}): ${l}`),d.show(),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI setup started. Check the terminal for progress.`),log(s,"[AgentIDE] CLI setup terminal opened"),{success:!0}}t.subscriptions.push(vscode.commands.registerCommand("agentide.setupAnalytics",async n=>{const s=n?.reinstall===!0;log(e,`[AgentIDE] Starting Spotlight ${s?"reinstall":"install/repair"}...`);const l=process.platform==="win32",i=l?"setup-analytics.ps1":"setup-analytics.sh",c=t.extensionPath,d=[path.join(c,"out","scripts","analytics",i),path.join(c,"scripts","analytics",i)].find(o=>{try{return require("fs").accessSync(o),!0}catch{return!1}});return d?l&&_state?.analyticsService?_state.analyticsService.setupWindowsSpotlight({reinstall:s}):T(d,e,{reinstall:s}):(showError(`Spotlight install script not found. Please run 'scripts/analytics/${i}' manually from the AgentIDE repository.`),{success:!1,error:"Script not found"})}));async function T(n,s,l={}){const i=process.platform==="win32",c=path.join(os.homedir(),branding_1.AGENTIDE_DIR_NAME),u=l.reinstall?"--yes --restart-litellm":"--yes";return(i?vscode.window.createTerminal({name:"Spotlight Install",cwd:path.dirname(n),env:{AGENT_HOME_DIR:c},shellPath:"powershell.exe",shellArgs:["-NoProfile","-NoExit","-ExecutionPolicy","Bypass","-Command",`& "${n}" -Yes; Write-Host ""; Write-Host "You can close this window."`]}):vscode.window.createTerminal({name:"Spotlight Install",cwd:path.dirname(n),env:{AGENT_HOME_DIR:c},shellPath:"/bin/bash",shellArgs:["-c",`"${n}" ${u}; echo ''; echo 'Press any key to close...'; read -n 1`]})).show(),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install started. Check the terminal for progress.`),log(s,"[AgentIDE] Spotlight install terminal opened"),{success:!0}}t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.install",async()=>{const{workspaceRoot:n,isHomeFallback:s}=getWorkspaceRoot(e);s&&await ensureFallbackDirectoryExists(e);const l=await vscode.window.showOpenDialog({canSelectFolders:!0,canSelectFiles:!1,canSelectMany:!1,openLabel:"Select Agent Pack Folder",title:"Install Agent Pack"});if(!l||l.length===0)return;const i=l[0].fsPath,{AgentPackManager:c}=await import("./agentpack/index.js"),u=new c(m,()=>n,()=>E.storagePath,e);try{const d=await u.installFromLocal(i);showInfo(`AgentIDE: Installed pack "${d.id}" v${d.version}`)}catch(d){const o=d instanceof Error?d.message:String(d);log(e,`[AgentIDE] Pack install error: ${o}`),showError(`AgentIDE: Failed to install pack - ${o}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.list",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),i=await new s(m,()=>n,()=>E.storagePath,e).listInstalled();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agent packs installed`);return}const c=i.map(d=>({label:d.id,description:`v${d.version} (${d.preferredEngine})`,detail:`Status: ${d.status} | Installed: ${new Date(d.installedAt).toLocaleDateString()}`})),u=await vscode.window.showQuickPick(c,{placeHolder:"Select a pack to view details",title:"Installed Agent Packs"});u&&(log(e,`[AgentIDE] Pack selected: ${u.label}`),e.show())})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getInstalled",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e);try{return await l.listInstalled()}catch(i){const c=i instanceof Error?i.message:String(i);return log(e,`[AgentIDE] Pack list error: ${c}`),[]}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.customEngine.list",n=>{const s=getConfiguredAdditionalEngineDir(),l=n?.workspaceRoot?.trim(),i=(vscode.workspace.workspaceFolders??[]).map(o=>o.uri.fsPath).filter(o=>!!o?.trim()),c=process.cwd?.(),u=Array.from(new Set([l,...i,c].map(o=>o?.trim()).filter(o=>!!o))),d=new Map;for(const o of u)try{const r=(0,customRegistry_1.discoverCustomEngineManifests)(o,s);for(const p of r)d.has(p.id)||d.set(p.id,{id:p.id,displayName:p.displayName||p.id,description:p.description,defaultModel:p.model?.defaultModel})}catch(r){const p=r instanceof Error?r.message:String(r);log(e,`[AgentIDE] Custom engine list warning for root ${o}: ${p}`)}if(d.size===0)try{const o=(0,customRegistry_1.discoverCustomEngineManifests)(void 0,s);for(const r of o)d.set(r.id,{id:r.id,displayName:r.displayName||r.id,description:r.description,defaultModel:r.model?.defaultModel})}catch(o){const r=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Custom engine list error: ${r}`)}return log(e,`[AgentIDE] Custom engine list: ${d.size} discovered (${Array.from(d.keys()).join(", ")||"none"}) from roots: ${u.join("; ")||"(home only)"}`),Array.from(d.values())})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.uninstall",async n=>{const{listInstalledCustomEngines:s,uninstallCustomEngine:l}=await import("./engines/install.js");let i=n?.id?.trim(),c=i;if(!i){const o=await s();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No custom engines are installed`);return}const r=await vscode.window.showQuickPick(o.map(p=>({label:p.displayName,description:p.id,detail:p.installDir,engine:p})),{placeHolder:"Select a custom engine to uninstall",title:"Uninstall Custom Engine"});if(!r)return;i=r.engine.id,c=r.engine.displayName}if(!i||n?.skipConfirmation!==!0&&await vscode.window.showWarningMessage(`Uninstall custom engine "${c||i}"?`,{modal:!0},"Uninstall","Cancel")!=="Uninstall")return;const u=await l(i,{logger:e});if(!u.removed){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Custom engine "${u.id}" is not installed`);return}clearCustomEngineRuntimeCache(a,u.id);const{invalidateLocalIndex:d}=await import("./store/oramaIndex.js");d(),await refreshCustomEnginePicker(e),showInfo(`Uninstalled engine "${u.displayName||u.id}"`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{collectEngineFiles:s,discoverPublishableEngines:l,isValidPublishVersion:i,validateEngineForPublish:c}=await import("./engines/publish.js"),{publishToStore:u,STORE_CONFIG:d,canPublishDirectlyToStore:o}=await import("./store/index.js"),r=await l(n);if(r.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No custom engines found. Add engine.manifest.json under .agent-hippo/engines/<id>/`);return}const p=await vscode.window.showQuickPick(r.map(S=>({label:S.displayName,description:S.id,detail:`${S.sourceLabel}: ${S.sourceDir}`,engine:S})),{placeHolder:"Select a custom engine to publish",title:`Publish to ${d.owner}/${d.repo}`});if(p)try{const S=await c(p.engine.sourceDir,p.engine.id);if(!S.valid){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Cannot publish - ${S.errors.join(", ")}`);return}if(S.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${S.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const k=await vscode.window.showInputBox({prompt:"Publish version (semver)",value:S.metadata?.suggestedVersion||"1.0.0",placeHolder:"e.g., 1.0.0",validateInput:M=>M&&i(M.replace(/^v/,""))?null:"Use semver format (e.g., 1.0.0)"});if(!k)return;const A=k.replace(/^v/,""),$=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Initial release, bug fixes..."}),f=await s(p.engine.sourceDir),w=await o();if(await vscode.window.showWarningMessage(w?`Publish "${p.engine.id}" v${A} to ${d.owner}/${d.repo}?
4
+ `)}function hasEnvVar(t,r){const e=new RegExp(`^\\s*(?:export\\s+)?${escapeRegExp(r)}\\s*=`);return t.split(/\r?\n/).some(m=>{const E=m.trim();return!E||E.startsWith("#")?!1:e.test(m)})}function registerCommands(t,r){const{outputChannel:e,syncService:m,config:E}=r;t.subscriptions.push(vscode.commands.registerCommand("agentide.setParticipantApiKey",n=>{log(e,`[AgentIDE] Setting API key for ${n.provider}${n.baseUrl?` with baseUrl: ${n.baseUrl}`:""}`),n.provider==="litellm"&&(E.litellmApiKey=n.apiKey,E.litellmBaseUrl=n.baseUrl)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.binary.findOnPath",async n=>{const s=n?.name?.trim();if(!s)throw new Error("Binary name is required");return(0,binary_1.findBinaryCached)(s,(0,binary_1.getCommonBinaryPaths)(s))}));const h=async n=>{log(e,"[AgentIDE] Starting native OpenAI Codex OAuth login");const{loginOpenAICodex:s}=await import("@mariozechner/pi-ai"),c={onAuth:async({url:o})=>{n(o),log(e,`[AgentIDE] OpenAI Codex OAuth URL: ${o}`);try{await vscode.env.openExternal(vscode.Uri.parse(o)),showInfo("Complete ChatGPT sign-in in your browser. Return here if prompted for a redirect URL.")}catch(a){log(e,`[AgentIDE] Failed to auto-open OAuth URL: ${String(a)}`),showWarning(`Open this URL in your browser: ${o}`)}},onPrompt:async()=>{const o=await vscode.window.showInputBox({title:"ChatGPT Sign-In",prompt:"If your browser finished signing in, copy the full address from its address bar and paste it here.",placeHolder:"http://localhost:1455/auth/callback?code=\u2026",ignoreFocusOut:!0,validateInput:a=>a.trim().length>0?void 0:"Required"});if(!o||o.trim().length===0)throw new Error("OpenAI Codex OAuth cancelled");return o.trim()},onProgress:o=>{log(e,`[AgentIDE] OpenAI Codex OAuth: ${o}`)}};let i;for(let o=1;;o++)try{i=await s(c);break}catch(a){if(!(a instanceof Error&&a.message.includes("only available in Node.js environments"))||o>=20)throw a;await new Promise(S=>setTimeout(S,50))}const l=i?.access?.trim();if(!l)throw new Error("OpenAI Codex OAuth completed without an access token");const u={type:"oauth",...i},d={apiKey:l,oauthCredential:u,expiresAt:typeof i.expires=="number"?i.expires:void 0};return log(e,"[AgentIDE] OpenAI Codex OAuth login complete"),d};let C;t.subscriptions.push(vscode.commands.registerCommand("agentide.openaiCodex.loginOAuth",async()=>{if(C)return log(e,"[AgentIDE] OpenAI Codex OAuth login already in progress; joining it"),C.url&&vscode.env.openExternal(vscode.Uri.parse(C.url)),showInfo("A ChatGPT sign-in is already in progress. Finish it in your browser."),C.result;const n={result:h(s=>{n.url=s})};C=n;try{return await n.result}finally{C===n&&(C=void 0)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.openaiCodex.getValidApiKey",async n=>{const s=n?.oauthCredential;if(!s||typeof s!="object")throw new Error("Missing openai-codex OAuth credential payload.");const{getOAuthApiKey:c}=await import("@mariozechner/pi-ai"),l={"openai-codex":s.type==="oauth"?s:{type:"oauth",...s}},u=await c("openai-codex",l);if(!u?.apiKey)throw new Error("OpenAI Codex OAuth credential is invalid or expired. Please sign in again.");return{apiKey:String(u.apiKey),oauthCredential:{type:"oauth",...u.newCredentials},expiresAt:typeof u.newCredentials?.expires=="number"?u.newCredentials.expires:void 0}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.litellm.setUpstreamApiKey",async n=>{const s=n?.envVar?.trim()??"",c=n?.apiKey?.trim()??"";if(!s||!/^[A-Z][A-Z0-9_]*$/.test(s))throw new Error(`Invalid env var name: ${s}`);if(!c)throw new Error(`API key value cannot be empty for ${s}`);const i=(0,index_1.getAgentideHome)(),l=path.join(i,".env");await fs_1.promises.mkdir(i,{recursive:!0,mode:448});let u="";try{u=await fs_1.promises.readFile(l,"utf8")}catch{}const d=upsertEnvVar(u,s,c);await fs_1.promises.writeFile(l,d,"utf8");try{await fs_1.promises.chmod(l,384)}catch{}return log(e,`[AgentIDE] Updated LiteLLM upstream key in ${l} (${s})`),{envFilePath:l,envVar:s}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.litellm.setChatGPTAuth",async n=>{const s=path.join((0,index_1.getAgentideHome)(),"chatgpt"),c=path.join(s,"auth.json"),i=n?.record;if(!i)return await fs_1.promises.rm(c,{force:!0}),{authFile:c,written:!1};if(typeof i.access_token!="string"||typeof i.expires_at!="number")throw new Error("ChatGPT auth record needs access_token and expires_at.");await fs_1.promises.mkdir(s,{recursive:!0,mode:448});const l=`${c}.${process.pid}.tmp`;return await fs_1.promises.writeFile(l,JSON.stringify(i),{encoding:"utf8",mode:384}),await fs_1.promises.rename(l,c),{authFile:c,written:!0}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.litellm.getUpstreamApiKeyStatus",async n=>{const s=n?.envVar?.trim()??"";if(!s||!/^[A-Z][A-Z0-9_]*$/.test(s))throw new Error(`Invalid env var name: ${s}`);const c=(0,index_1.getAgentideHome)(),i=path.join(c,".env");let l="";try{l=await fs_1.promises.readFile(i,"utf8")}catch{}return{envFilePath:i,envVar:s,exists:hasEnvVar(l,s)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.clearManagedResources",async()=>{if(await vscode.window.showWarningMessage((0,branding_1.brandify)("Clear all AgentIDE managed resources?"),{modal:!0,detail:`This will remove derived folders and generated files. User-managed files in \`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/\` will NOT be deleted.`},"Clear Resources","Cancel")!=="Clear Resources")return;const{workspaceRoot:s,additionalDirectories:c,isHomeFallback:i}=getWorkspaceRoot(e);i&&await ensureFallbackDirectoryExists(e);const{cleared:l,skipped:u,errors:d}=await m.clearManagedResources(E.codexHome,E.claudeConfigDir,s,c,e),o=[`Cleared: ${l.length} resources`,u.length>0?`Skipped: ${u.length} (user files)`:"",d.length>0?`Errors: ${d.length}`:""].filter(Boolean).join(" | ");d.length>0?(showError(`AgentIDE: ${o}`),log(e,`[AgentIDE] Errors: ${d.join(", ")}`)):showInfo(`AgentIDE: ${o}`),log(e,`[AgentIDE] Clear complete: ${o}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skills.syncRemote",async()=>{const{workspaceRoot:n,additionalDirectories:s,isHomeFallback:c}=getWorkspaceRoot(e);c&&await ensureFallbackDirectoryExists(e),await m.ensureAgentideProjectPrepared(n,s,e),await m.syncRemoteSkillsIfEnabled(n,e,{force:!0}),await m.flushAgentideRootUpdate(n,e,{allowDuringActiveTurn:!0,force:!1}),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Remote skills sync complete (see ${branding_1.AGENTIDE_BRAND_NAME} output for details).`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.showManagedResources",async()=>{const{workspaceRoot:n,additionalDirectories:s,isHomeFallback:c}=getWorkspaceRoot(e);c&&await ensureFallbackDirectoryExists(e),await m.writeManagedPathsManifest(E.codexHome,E.claudeConfigDir,n,s,e);const i=path.join((0,paths_1.getAgentideDir)(n),"paths.md");if(await(0,utils_1.pathExists)(i)){const l=await vscode.workspace.openTextDocument(i);await vscode.window.showTextDocument(l)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cleanupSessionLogs",async()=>{const n=await(0,terminalLogger_1.cleanupOldSessionLogs)(e);n.cleaned>0?showInfo(`AgentIDE: Cleaned up ${n.cleaned} old session(s)`):n.errors.length>0?showWarning(`AgentIDE: Cleanup completed with ${n.errors.length} error(s)`):showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No old sessions to clean up`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.deleteSessionLogs",async n=>{const s=n?.sessionId;if(!s)return{deleted:!1,error:"sessionId is required"};const c=await(0,terminalLogger_1.deleteSessionLogs)(s);return c.deleted?(log(e,`[AgentIDE] Deleted session logs: ${s}`),(0,terminalLogger_1.cleanupOldSessionLogs)(e)):c.error&&log(e,`[AgentIDE] Failed to delete session logs: ${c.error}`),c})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cli.status",async()=>{const n=vscode.workspace.getConfiguration("agentide").get("cli.path",""),s=await(0,runtime_1.getCliHealth)({configuredPath:n,extensionPath:t.extensionPath}),i=(0,runtime_1.getBundledToolsHealth)({extensionPath:t.extensionPath,binaryDirHint:s.path?path.dirname(s.path):void 0}).tools.filter(l=>l.available).map(l=>l.name);if(s.installed){const l=s.source==="setting"?"configured path":s.source==="bundled"?"bundled binary":"system PATH",u=i.length>0?`; tools: ${i.join(", ")}`:"; tools: none";showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI available (${l})${s.version?` ${s.version}`:""}${u}`)}else showWarning(`${branding_1.AGENTIDE_BRAND_NAME}: CLI not found. Run '${branding_1.AGENTIDE_BRAND_NAME}: Setup AgentHippo CLI'.`);return s})),t.subscriptions.push(vscode.commands.registerCommand("agentide.cli.isInstalled",async()=>{const n=vscode.workspace.getConfiguration("agentide").get("cli.path","");return(await(0,runtime_1.getCliHealth)({configuredPath:n,extensionPath:t.extensionPath})).installed})),t.subscriptions.push(vscode.commands.registerCommand("agentide.installBundledTools",async()=>{const n=(0,runtime_1.getBundledToolsHealth)({extensionPath:t.extensionPath});if(!n.platformKey){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Unsupported platform ${process.platform}-${process.arch}. Cannot install bundled tools.`);return}const s=t.globalStorageUri;if(!s){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No global storage path. Cannot install bundled tools.`);return}const c=path.join(s.fsPath,"tools"),l=[path.join(t.extensionPath,"out","scripts","vendor-tools.mjs"),path.join(t.extensionPath,"scripts","vendor-tools.mjs")].find(u=>{try{return require("fs").statSync(u).isFile()}catch{return!1}});if(!l){showError(`${branding_1.AGENTIDE_BRAND_NAME}: vendor-tools script not found. Run from extension source or rebuild.`);return}log(e,`[AgentIDE] Installing bundled tools (rg, sg, tree-sitter) into ${c} ...`);try{const{spawn:u}=await import("child_process");await new Promise((o,a)=>{const p=u(process.execPath,[l,"--out-dir",c,"--clean"],{stdio:["ignore","pipe","pipe"],env:{...process.env}});let S="";p.stdout?.on("data",k=>log(e,k.toString())),p.stderr?.on("data",k=>{S+=k.toString(),log(e,k.toString())}),p.on("error",a),p.on("close",k=>k===0?o():a(new Error(`Exit ${k}: ${S}`)))});const d=path.join(c,n.platformKey);await t.globalState.update(BUNDLED_TOOLS_DIR_KEY,d),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Bundled tools installed to ${d}. They will be used by the agent.`)}catch(u){const d=u instanceof Error?u.message:String(u);log(e,`[AgentIDE] Install bundled tools failed: ${d}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: Failed to install bundled tools. Check Output > Agent Hippo. ${d}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.setupCli",async()=>{log(e,"[AgentIDE] Starting CLI setup...");const n=vscode.workspace.getConfiguration("agentide.cli"),s=n.get("path",""),c=n.get("installSource","").trim();if(c&&/[;`|$&\n\r"']/.test(c))return showError(`${branding_1.AGENTIDE_BRAND_NAME}: Invalid CLI install source. Remove shell control characters from '${(0,branding_1.describeSettingKey)("agentide.cli.installSource")}'.`),{success:!1,error:"Invalid install source"};const i=await(0,runtime_1.getCliHealth)({configuredPath:s,extensionPath:t.extensionPath,forceRefresh:!0});if(i.installed&&i.path)return await vscode.workspace.getConfiguration("agentide").update("cli.path",i.path,vscode.ConfigurationTarget.Global),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI is ready at ${i.path}`),{success:!0,path:i.path};const u=process.platform==="win32"?"setup-cli.ps1":"setup-cli.sh",o=[path.join(t.extensionPath,"out","scripts",u),path.join(t.extensionPath,"scripts",u)].find(S=>{try{return require("fs").accessSync(S),!0}catch{return!1}});if(!o)return showError(`${branding_1.AGENTIDE_BRAND_NAME}: CLI setup script not found. Build CLI via extensions/agentide/scripts/build-cli.sh and set ${(0,branding_1.describeSettingKey)("agentide.cli.path")}.`),{success:!1,error:"Script not found"};const a=await A(o,e,c);if(!a.success)return a;const p=await(0,runtime_1.getCliHealth)({configuredPath:s,extensionPath:t.extensionPath,forceRefresh:!0});return p.installed&&p.path?(await vscode.workspace.getConfiguration("agentide").update("cli.path",p.path,vscode.ConfigurationTarget.Global),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI configured at ${p.path}`),{success:!0,path:p.path}):(showWarning(`${branding_1.AGENTIDE_BRAND_NAME}: Setup launched. Re-run '${branding_1.AGENTIDE_BRAND_NAME}: CLI Status' after terminal setup completes.`),{success:!0,pending:!0})}));async function A(n,s,c){const i=process.platform==="win32",l=/^https?:\/\//i.test(c),u=c?i?`-Source "${c}"`:`--source "${c}"`:"",d=i?vscode.window.createTerminal({name:"AgentHippo CLI Setup",cwd:path.dirname(n),shellPath:"powershell.exe",shellArgs:["-NoProfile","-NoExit","-ExecutionPolicy","Bypass","-Command",`& "${n}" ${u} -Yes; Write-Host ""; Write-Host "You can close this window."`]}):vscode.window.createTerminal({name:"AgentHippo CLI Setup",cwd:path.dirname(n),shellPath:"/bin/bash",shellArgs:["-c",`"${n}" ${u} --yes; echo ''; echo 'Press any key to close...'; read -n 1`]});return c&&log(s,`[AgentIDE] CLI install source configured (${l?"url":"package/path"}): ${c}`),d.show(),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: CLI setup started. Check the terminal for progress.`),log(s,"[AgentIDE] CLI setup terminal opened"),{success:!0}}t.subscriptions.push(vscode.commands.registerCommand("agentide.setupAnalytics",async n=>{const s=n?.reinstall===!0;log(e,`[AgentIDE] Starting Spotlight ${s?"reinstall":"install/repair"}...`);const c=process.platform==="win32",i=c?"setup-analytics.ps1":"setup-analytics.sh",l=t.extensionPath,d=[path.join(l,"out","scripts","analytics",i),path.join(l,"scripts","analytics",i)].find(o=>{try{return require("fs").accessSync(o),!0}catch{return!1}});return d?c&&_state?.analyticsService?_state.analyticsService.setupWindowsSpotlight({reinstall:s}):T(d,e,{reinstall:s}):(showError(`Spotlight install script not found. Please run 'scripts/analytics/${i}' manually from the AgentIDE repository.`),{success:!1,error:"Script not found"})}));async function T(n,s,c={}){const i=process.platform==="win32",l=path.join(os.homedir(),branding_1.AGENTIDE_DIR_NAME),u=c.reinstall?"--yes --restart-litellm":"--yes";return(i?vscode.window.createTerminal({name:"Spotlight Install",cwd:path.dirname(n),env:{AGENT_HOME_DIR:l},shellPath:"powershell.exe",shellArgs:["-NoProfile","-NoExit","-ExecutionPolicy","Bypass","-Command",`& "${n}" -Yes; Write-Host ""; Write-Host "You can close this window."`]}):vscode.window.createTerminal({name:"Spotlight Install",cwd:path.dirname(n),env:{AGENT_HOME_DIR:l},shellPath:"/bin/bash",shellArgs:["-c",`"${n}" ${u}; echo ''; echo 'Press any key to close...'; read -n 1`]})).show(),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Spotlight install started. Check the terminal for progress.`),log(s,"[AgentIDE] Spotlight install terminal opened"),{success:!0}}t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.install",async()=>{const{workspaceRoot:n,isHomeFallback:s}=getWorkspaceRoot(e);s&&await ensureFallbackDirectoryExists(e);const c=await vscode.window.showOpenDialog({canSelectFolders:!0,canSelectFiles:!1,canSelectMany:!1,openLabel:"Select Agent Pack Folder",title:"Install Agent Pack"});if(!c||c.length===0)return;const i=c[0].fsPath,{AgentPackManager:l}=await import("./agentpack/index.js"),u=new l(m,()=>n,()=>E.storagePath,e);try{const d=await u.installFromLocal(i);showInfo(`AgentIDE: Installed pack "${d.id}" v${d.version}`)}catch(d){const o=d instanceof Error?d.message:String(d);log(e,`[AgentIDE] Pack install error: ${o}`),showError(`AgentIDE: Failed to install pack - ${o}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.list",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),i=await new s(m,()=>n,()=>E.storagePath,e).listInstalled();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agent packs installed`);return}const l=i.map(d=>({label:d.id,description:`v${d.version} (${d.preferredEngine})`,detail:`Status: ${d.status} | Installed: ${new Date(d.installedAt).toLocaleDateString()}`})),u=await vscode.window.showQuickPick(l,{placeHolder:"Select a pack to view details",title:"Installed Agent Packs"});u&&(log(e,`[AgentIDE] Pack selected: ${u.label}`),e.show())})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getInstalled",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e);try{return await c.listInstalled()}catch(i){const l=i instanceof Error?i.message:String(i);return log(e,`[AgentIDE] Pack list error: ${l}`),[]}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.customEngine.list",n=>{const s=getConfiguredAdditionalEngineDir(),c=n?.workspaceRoot?.trim(),i=(vscode.workspace.workspaceFolders??[]).map(o=>o.uri.fsPath).filter(o=>!!o?.trim()),l=process.cwd?.(),u=Array.from(new Set([c,...i,l].map(o=>o?.trim()).filter(o=>!!o))),d=new Map;for(const o of u)try{const a=(0,customRegistry_1.discoverCustomEngineManifests)(o,s);for(const p of a)d.has(p.id)||d.set(p.id,{id:p.id,displayName:p.displayName||p.id,description:p.description,defaultModel:p.model?.defaultModel})}catch(a){const p=a instanceof Error?a.message:String(a);log(e,`[AgentIDE] Custom engine list warning for root ${o}: ${p}`)}if(d.size===0)try{const o=(0,customRegistry_1.discoverCustomEngineManifests)(void 0,s);for(const a of o)d.set(a.id,{id:a.id,displayName:a.displayName||a.id,description:a.description,defaultModel:a.model?.defaultModel})}catch(o){const a=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Custom engine list error: ${a}`)}return log(e,`[AgentIDE] Custom engine list: ${d.size} discovered (${Array.from(d.keys()).join(", ")||"none"}) from roots: ${u.join("; ")||"(home only)"}`),Array.from(d.values())})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.uninstall",async n=>{const{listInstalledCustomEngines:s,uninstallCustomEngine:c}=await import("./engines/install.js");let i=n?.id?.trim(),l=i;if(!i){const o=await s();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No custom engines are installed`);return}const a=await vscode.window.showQuickPick(o.map(p=>({label:p.displayName,description:p.id,detail:p.installDir,engine:p})),{placeHolder:"Select a custom engine to uninstall",title:"Uninstall Custom Engine"});if(!a)return;i=a.engine.id,l=a.engine.displayName}if(!i||n?.skipConfirmation!==!0&&await vscode.window.showWarningMessage(`Uninstall custom engine "${l||i}"?`,{modal:!0},"Uninstall","Cancel")!=="Uninstall")return;const u=await c(i,{logger:e});if(!u.removed){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Custom engine "${u.id}" is not installed`);return}clearCustomEngineRuntimeCache(r,u.id);const{invalidateLocalIndex:d}=await import("./store/oramaIndex.js");d(),await refreshCustomEnginePicker(e),showInfo(`Uninstalled engine "${u.displayName||u.id}"`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{collectEngineFiles:s,discoverPublishableEngines:c,isValidPublishVersion:i,validateEngineForPublish:l}=await import("./engines/publish.js"),{publishToStore:u,STORE_CONFIG:d,canPublishDirectlyToStore:o}=await import("./store/index.js"),a=await c(n);if(a.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No custom engines found. Add engine.manifest.json under .agent-hippo/engines/<id>/`);return}const p=await vscode.window.showQuickPick(a.map(S=>({label:S.displayName,description:S.id,detail:`${S.sourceLabel}: ${S.sourceDir}`,engine:S})),{placeHolder:"Select a custom engine to publish",title:`Publish to ${d.owner}/${d.repo}`});if(p)try{const S=await l(p.engine.sourceDir,p.engine.id);if(!S.valid){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Cannot publish - ${S.errors.join(", ")}`);return}if(S.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${S.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const k=await vscode.window.showInputBox({prompt:"Publish version (semver)",value:S.metadata?.suggestedVersion||"1.0.0",placeHolder:"e.g., 1.0.0",validateInput:M=>M&&i(M.replace(/^v/,""))?null:"Use semver format (e.g., 1.0.0)"});if(!k)return;const y=k.replace(/^v/,""),$=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Initial release, bug fixes..."}),f=await s(p.engine.sourceDir),w=await o();if(await vscode.window.showWarningMessage(w?`Publish "${p.engine.id}" v${y} to ${d.owner}/${d.repo}?
5
5
 
6
- This will open a pull request on the store repository.`:`Submit "${p.engine.id}" v${A} to ${d.owner}/${d.repo}?
6
+ This will open a pull request on the store repository.`:`Submit "${p.engine.id}" v${y} to ${d.owner}/${d.repo}?
7
7
 
8
- This will create a pull request from your fork.`,{modal:!0},"Submit PR")!=="Submit PR")return;const g=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing engine ${p.engine.id} v${A}`,cancellable:!1},async M=>{M.report({message:w?`Publishing to ${d.owner}/${d.repo}...`:"Preparing fork..."});const b=await u({type:"engine",slug:p.engine.id,version:A,files:f,changelog:$},e);return M.report({message:"Creating PR..."}),b});await vscode.window.showInformationMessage(`Published engine "${p.engine.id}" v${A}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(g.prUrl))}catch(S){const k=S instanceof Error?S.message:String(S);log(e,`[AgentIDE] Engine publish error: ${k}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: ${k}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.uninstall",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s,isDefaultAgent:l}=await import("./agentpack/index.js"),i=new s(m,()=>n,()=>E.storagePath,e),u=(await i.listInstalled()).filter(k=>!l(k.id));if(u.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agent packs available to uninstall`);return}const d=u.map(k=>({label:k.id,description:`v${k.version}${a.activePackId===k.id?" (active)":""}`})),o=await vscode.window.showQuickPick(d,{placeHolder:"Select a pack to uninstall",title:"Uninstall Agent Pack"});if(!o)return;const r=o.label,p=a.activePackId===r;if(await vscode.window.showWarningMessage(`Uninstall agent pack "${r}"?${p?" This will switch to the default agent.":""}`,{modal:!0},"Uninstall","Cancel")==="Uninstall")try{if(await i.uninstall(r),p){const k=await m.switchToPack(n,void 0,e,{importDerivedSkills:!0});a.activePackId=k,m.setActivePackId(n,k),log(e,"[AgentIDE] Switched to default agent after uninstalling active pack");try{await vscode.commands.executeCommand("agentide.applyPackPreferences",{packId:"default",silent:!0})}catch{}}showInfo(`AgentIDE: Uninstalled pack "${r}"${p?" - switched to default agent":""}`)}catch(k){const A=k instanceof Error?k.message:String(k);log(e,`[AgentIDE] Pack uninstall error: ${A}`),showError(`AgentIDE: Failed to uninstall pack - ${A}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.setActive",async n=>{if(!n?.packId)throw new Error("packId is required. Use workbench.action.chat.openAgentPackPicker for interactive selection.");const{workspaceRoot:s}=getWorkspaceRoot(e),l=n.packId==="default"?void 0:n.packId,i=await m.switchToPack(s,l,e,{importDerivedSkills:!0});return a.activePackId=i,m.setActivePackId(s,i),log(e,`[AgentIDE] Active pack switched to: ${i??"default"}`),await a.remotePackStatusBar?.refresh({notifyOnActivate:!0}),{activePackId:a.activePackId??"default"}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getActive",()=>({activePackId:a.activePackId??"default"}))),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getRemoteServeUrl",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),l=n?.packId?.trim()||m.getActivePackId(s)||a.activePackId;if(!l||l==="default")return;const i=await m.getActiveAgentManifest(s,e,l),c=(0,serveClient_js_1.getRemoteServeUrl)(i);if(c)return{packId:l,remoteUrl:c,preferredEngine:i?.spec?.engine}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.create",async()=>{const{workspaceRoot:n,isHomeFallback:s}=getWorkspaceRoot(e);s&&await ensureFallbackDirectoryExists(e);let l;try{const r=await vscode.commands.executeCommand("agentide.getChatState");l=r?.modelId,log(e,`[AgentIDE] Current chat state: mode=${r?.mode}, modelId=${l}, modelName=${r?.modelName}`)}catch{}const i=await vscode.window.showInputBox({prompt:"Enter the agent pack name",placeHolder:"e.g., code-reviewer, security-auditor, My Code Reviewer",validateInput:async r=>{const p=(0,paths_1.normalizePackName)(r),S=(0,paths_1.getPackNameError)(p);if(S)return S;const k=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,p);if(await(0,utils_1.pathExists)(k))return`A pack named "${p}" already exists. Choose a different name.`}});if(!i)return;const c=(0,paths_1.normalizePackName)(i);log(e,`[AgentIDE] Pack name normalized: "${i}" -> "${c}"`);const u=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,c),d=await vscode.window.showInputBox({prompt:"Enter a short description for the pack",placeHolder:"e.g., Advanced code review agent with security analysis"}),o=await vscode.window.showQuickPick([{label:"Claude",description:"Anthropic Claude Agent SDK",engine:"claude"},{label:"Codex",description:"OpenAI Codex SDK",engine:"codex"}],{placeHolder:"Select the preferred engine for this pack",title:"Preferred Engine"});if(o)try{await fs_1.promises.mkdir(path.join(u,"rules"),{recursive:!0}),await fs_1.promises.mkdir(path.join(u,"skills"),{recursive:!0}),await fs_1.promises.mkdir(path.join(u,"mcp"),{recursive:!0});const r=(0,paths_1.generateAgentYaml)(c,{description:d||void 0,engine:o.engine,model:l});await fs_1.promises.writeFile(path.join(u,"agent.yaml"),r);const p=(0,paths_1.generateAgentsMd)(c,{description:d||void 0});await fs_1.promises.writeFile(path.join(u,"AGENTS.md"),p);const{AgentPackManager:S}=await import("./agentpack/index.js");await new S(m,()=>n,()=>E.storagePath,e).installFromLocal(u),log(e,`[AgentIDE] Created agent pack scaffold: ${c}`),showInfo(`AgentIDE: Created agent pack "${c}" at ${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/${paths_1.AGENT_CONSTANTS.AGENTS_DIR}/${c}/`);const A=vscode.Uri.file(path.join(u,"AGENTS.md"));if(await vscode.window.showTextDocument(A),await vscode.window.showInformationMessage(`Agent pack "${c}" created. Would you like help generating a specialized configuration?`,"Yes, help me configure it","No, I'll edit manually")==="Yes, help me configure it"){const f=[`I just created a new agent pack called "${c}"`,d?` that should: ${d}.`:".",`
8
+ This will create a pull request from your fork.`,{modal:!0},"Submit PR")!=="Submit PR")return;const g=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing engine ${p.engine.id} v${y}`,cancellable:!1},async M=>{M.report({message:w?`Publishing to ${d.owner}/${d.repo}...`:"Preparing fork..."});const b=await u({type:"engine",slug:p.engine.id,version:y,files:f,changelog:$},e);return M.report({message:"Creating PR..."}),b});await vscode.window.showInformationMessage(`Published engine "${p.engine.id}" v${y}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(g.prUrl))}catch(S){const k=S instanceof Error?S.message:String(S);log(e,`[AgentIDE] Engine publish error: ${k}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: ${k}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.uninstall",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s,isDefaultAgent:c}=await import("./agentpack/index.js"),i=new s(m,()=>n,()=>E.storagePath,e),u=(await i.listInstalled()).filter(k=>!c(k.id));if(u.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agent packs available to uninstall`);return}const d=u.map(k=>({label:k.id,description:`v${k.version}${r.activePackId===k.id?" (active)":""}`})),o=await vscode.window.showQuickPick(d,{placeHolder:"Select a pack to uninstall",title:"Uninstall Agent Pack"});if(!o)return;const a=o.label,p=r.activePackId===a;if(await vscode.window.showWarningMessage(`Uninstall agent pack "${a}"?${p?" This will switch to the default agent.":""}`,{modal:!0},"Uninstall","Cancel")==="Uninstall")try{if(await i.uninstall(a),p){const k=await m.switchToPack(n,void 0,e,{importDerivedSkills:!0});r.activePackId=k,m.setActivePackId(n,k),log(e,"[AgentIDE] Switched to default agent after uninstalling active pack");try{await vscode.commands.executeCommand("agentide.applyPackPreferences",{packId:"default",silent:!0})}catch{}}showInfo(`AgentIDE: Uninstalled pack "${a}"${p?" - switched to default agent":""}`)}catch(k){const y=k instanceof Error?k.message:String(k);log(e,`[AgentIDE] Pack uninstall error: ${y}`),showError(`AgentIDE: Failed to uninstall pack - ${y}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.setActive",async n=>{if(!n?.packId)throw new Error("packId is required. Use workbench.action.chat.openAgentPackPicker for interactive selection.");const{workspaceRoot:s}=getWorkspaceRoot(e),c=n.packId==="default"?void 0:n.packId,i=await m.switchToPack(s,c,e,{importDerivedSkills:!0});return r.activePackId=i,m.setActivePackId(s,i),log(e,`[AgentIDE] Active pack switched to: ${i??"default"}`),await r.remotePackStatusBar?.refresh({notifyOnActivate:!0}),{activePackId:r.activePackId??"default"}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getActive",()=>({activePackId:r.activePackId??"default"}))),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.getRemoteServeUrl",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),c=n?.packId?.trim()||m.getActivePackId(s)||r.activePackId;if(!c||c==="default")return;const i=await m.getActiveAgentManifest(s,e,c),l=(0,serveClient_js_1.getRemoteServeUrl)(i);if(l)return{packId:c,remoteUrl:l,preferredEngine:i?.spec?.engine}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.create",async()=>{const{workspaceRoot:n,isHomeFallback:s}=getWorkspaceRoot(e);s&&await ensureFallbackDirectoryExists(e);let c;try{const a=await vscode.commands.executeCommand("agentide.getChatState");c=a?.modelId,log(e,`[AgentIDE] Current chat state: mode=${a?.mode}, modelId=${c}, modelName=${a?.modelName}`)}catch{}const i=await vscode.window.showInputBox({prompt:"Enter the agent pack name",placeHolder:"e.g., code-reviewer, security-auditor, My Code Reviewer",validateInput:async a=>{const p=(0,paths_1.normalizePackName)(a),S=(0,paths_1.getPackNameError)(p);if(S)return S;const k=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,p);if(await(0,utils_1.pathExists)(k))return`A pack named "${p}" already exists. Choose a different name.`}});if(!i)return;const l=(0,paths_1.normalizePackName)(i);log(e,`[AgentIDE] Pack name normalized: "${i}" -> "${l}"`);const u=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,l),d=await vscode.window.showInputBox({prompt:"Enter a short description for the pack",placeHolder:"e.g., Advanced code review agent with security analysis"}),o=await vscode.window.showQuickPick([{label:"Claude",description:"Anthropic Claude Agent SDK",engine:"claude"},{label:"Codex",description:"OpenAI Codex SDK",engine:"codex"}],{placeHolder:"Select the preferred engine for this pack",title:"Preferred Engine"});if(o)try{await fs_1.promises.mkdir(path.join(u,"rules"),{recursive:!0}),await fs_1.promises.mkdir(path.join(u,"skills"),{recursive:!0}),await fs_1.promises.mkdir(path.join(u,"mcp"),{recursive:!0});const a=(0,paths_1.generateAgentYaml)(l,{description:d||void 0,engine:o.engine,model:c});await fs_1.promises.writeFile(path.join(u,"agent.yaml"),a);const p=(0,paths_1.generateAgentsMd)(l,{description:d||void 0});await fs_1.promises.writeFile(path.join(u,"AGENTS.md"),p);const{AgentPackManager:S}=await import("./agentpack/index.js");await new S(m,()=>n,()=>E.storagePath,e).installFromLocal(u),log(e,`[AgentIDE] Created agent pack scaffold: ${l}`),showInfo(`AgentIDE: Created agent pack "${l}" at ${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/${paths_1.AGENT_CONSTANTS.AGENTS_DIR}/${l}/`);const y=vscode.Uri.file(path.join(u,"AGENTS.md"));if(await vscode.window.showTextDocument(y),await vscode.window.showInformationMessage(`Agent pack "${l}" created. Would you like help generating a specialized configuration?`,"Yes, help me configure it","No, I'll edit manually")==="Yes, help me configure it"){const f=[`I just created a new agent pack called "${l}"`,d?` that should: ${d}.`:".",`
9
9
 
10
10
  Please help me write a proper AGENTS.md file for this agent. `,`Ask me clarifying questions about:
11
11
  `,`1. What specific tasks this agent should excel at
@@ -13,24 +13,24 @@ Please help me write a proper AGENTS.md file for this agent. `,`Ask me clarifyin
13
13
  `,`3. What constraints or limitations it should follow
14
14
  `,`4. How it should format its outputs
15
15
 
16
- `,`The AGENTS.md file is at: ${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/agents/${c}/AGENTS.md`].join("");await vscode.commands.executeCommand("workbench.action.chat.open",{query:f,isPartialQuery:!1,mode:"agent",attachFiles:[A]})}}catch(r){const p=r instanceof Error?r.message:String(r);log(e,`[AgentIDE] Pack create error: ${p}`),showError(`AgentIDE: Failed to create pack - ${p}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e),c=(await l.listInstalledWithCleanup()).filter(o=>o.id!=="default");if(c.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to share (create an agent first)`);return}const u=c.map(o=>({label:o.id,description:`v${o.version}`})),d=await vscode.window.showQuickPick(u,{placeHolder:"Select an agent to share to User Library",title:"Share Agent to User Library"});if(d)try{const o=await l.shareToUserLibrary(d.label);showInfo(`AgentIDE: Shared "${d.label}" v${o} to User Library`)}catch(o){const r=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Share error: ${r}`),showError(`AgentIDE: ${r}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),{getAgentSkillsDir:l,getUserSkillDir:i}=await import("./agentpack/paths.js"),{copyDirRecursive:c,pathExists:u}=await import("./utils.js"),o=await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found`);return}const r=await vscode.window.showQuickPick(o.map(I=>({label:I.id,description:`v${I.version}`})),{placeHolder:"Select agent containing the skill",title:"Save Skill to User Library"});if(!r)return;const p=l(n,r.label);if(!await u(p)){showInfo(`AgentIDE: No skills found in ${r.label}`);return}const A=(await fs_1.promises.readdir(p,{withFileTypes:!0})).filter(I=>I.isDirectory()&&!I.name.startsWith(".")).map(I=>I.name);if(A.length===0){showInfo(`AgentIDE: No skills found in ${r.label}`);return}const $=await vscode.window.showQuickPick(A.map(I=>({label:I})),{placeHolder:"Select skill to save to User Library",title:"Save Skill to User Library"});if(!$)return;const f=path.join(p,$.label),w=i($.label);if(await u(w)){if(await vscode.window.showWarningMessage(`Skill "${$.label}" already exists in User Library. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(w,{recursive:!0,force:!0})}try{await c(f,w);const{getRegistry:I}=await import("./registry/index.js");await I(e).registerSkill({slug:$.label,displayName:$.label,latestVersion:"local",tags:[],stats:{installs:1}});const{invalidateLocalIndex:D}=await import("./store/oramaIndex.js");D(),showInfo(`AgentIDE: Saved skill "${$.label}" to User Library`)}catch(I){const g=I instanceof Error?I.message:String(I);log(e,`[AgentIDE] Share skill error: ${g}`),showError(`AgentIDE: ${g}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),{getAgentMcpDir:l,getUserMcpServerDir:i}=await import("./agentpack/paths.js"),{copyDirRecursive:c,pathExists:u}=await import("./utils.js"),o=await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found`);return}const r=await vscode.window.showQuickPick(o.map(w=>({label:w.id,description:`v${w.version}`})),{placeHolder:"Select agent containing the MCP server",title:"Save MCP Server to User Library"});if(!r)return;const p=l(n,r.label),S=path.join(p,".mcp.json");let k={mcpServers:{}};try{const w=await fs_1.promises.readFile(S,"utf-8");k=JSON.parse(w)}catch{showInfo(`AgentIDE: No MCP servers configured in ${r.label}`);return}if(!k.mcpServers||Object.keys(k.mcpServers).length===0){showInfo(`AgentIDE: No MCP servers configured in ${r.label}`);return}const A=Object.keys(k.mcpServers),$=await vscode.window.showQuickPick(A.map(w=>({label:w})),{placeHolder:"Select MCP server to save to User Library",title:"Save MCP Server to User Library"});if(!$)return;const f=i($.label);if(await u(f)){if(await vscode.window.showWarningMessage(`MCP "${$.label}" already exists in User Library. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(f,{recursive:!0,force:!0})}try{await fs_1.promises.mkdir(f,{recursive:!0});const w=k.mcpServers[$.label];await fs_1.promises.writeFile(path.join(f,"mcp.json"),JSON.stringify({name:$.label,...w},null,2));const I=path.join(p,$.label);await u(I)&&await c(I,f);const{getRegistry:g}=await import("./registry/index.js");await g(e).registerMcp({slug:$.label,displayName:$.label,transport:w.transport||"stdio",latestVersion:"local",tags:[],stats:{installs:1}});const{invalidateLocalIndex:M}=await import("./store/oramaIndex.js");M(),showInfo(`AgentIDE: Saved MCP "${$.label}" to User Library`)}catch(w){const I=w instanceof Error?w.message:String(w);log(e,`[AgentIDE] Share MCP error: ${I}`),showError(`AgentIDE: ${I}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.publish",async()=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s,validateForPublish:l}=await import("./agentpack/index.js"),{publishToStore:i,STORE_CONFIG:c}=await import("./store/index.js"),o=(await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup()).filter(g=>g.id!=="default");if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to publish (create an agent first)`);return}const r=await vscode.window.showQuickPick(o.map(g=>({label:g.id,description:`v${g.version}`})),{placeHolder:"Select an agent pack to publish",title:`Publish to ${c.owner}/${c.repo}`});if(!r)return;const p=await l(n,r.label);if(!p.valid){showError(`AgentIDE: Cannot publish - ${p.errors.join(", ")}`);return}if(p.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${p.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const S=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Added new features, fixed bugs..."}),{getAgentRoot:k}=await import("./agentpack/paths.js"),A=k(n,r.label),$=[];async function f(g,D){const M=await fs_1.promises.readdir(g);for(const b of M){if(b.startsWith("."))continue;const v=path.join(g,b),N=D?`${D}/${b}`:b;if((await fs_1.promises.stat(v)).isDirectory())await f(v,N);else{const P=await fs_1.promises.readFile(v,"utf-8");$.push({path:N,content:P})}}}await f(A,"");const w=o.find(g=>g.id===r.label);if(await vscode.window.showWarningMessage(`Submit "${w.id}" v${w.version} to ${c.owner}/${c.repo}?
16
+ `,`The AGENTS.md file is at: ${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/agents/${l}/AGENTS.md`].join("");await vscode.commands.executeCommand("workbench.action.chat.open",{query:f,isPartialQuery:!1,mode:"agent",attachFiles:[y]})}}catch(a){const p=a instanceof Error?a.message:String(a);log(e,`[AgentIDE] Pack create error: ${p}`),showError(`AgentIDE: Failed to create pack - ${p}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e),l=(await c.listInstalledWithCleanup()).filter(o=>o.id!=="default");if(l.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to share (create an agent first)`);return}const u=l.map(o=>({label:o.id,description:`v${o.version}`})),d=await vscode.window.showQuickPick(u,{placeHolder:"Select an agent to share to User Library",title:"Share Agent to User Library"});if(d)try{const o=await c.shareToUserLibrary(d.label);showInfo(`AgentIDE: Shared "${d.label}" v${o} to User Library`)}catch(o){const a=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Share error: ${a}`),showError(`AgentIDE: ${a}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),{getAgentSkillsDir:c,getUserSkillDir:i}=await import("./agentpack/paths.js"),{copyDirRecursive:l,pathExists:u}=await import("./utils.js"),o=await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found`);return}const a=await vscode.window.showQuickPick(o.map(I=>({label:I.id,description:`v${I.version}`})),{placeHolder:"Select agent containing the skill",title:"Save Skill to User Library"});if(!a)return;const p=c(n,a.label);if(!await u(p)){showInfo(`AgentIDE: No skills found in ${a.label}`);return}const y=(await fs_1.promises.readdir(p,{withFileTypes:!0})).filter(I=>I.isDirectory()&&!I.name.startsWith(".")).map(I=>I.name);if(y.length===0){showInfo(`AgentIDE: No skills found in ${a.label}`);return}const $=await vscode.window.showQuickPick(y.map(I=>({label:I})),{placeHolder:"Select skill to save to User Library",title:"Save Skill to User Library"});if(!$)return;const f=path.join(p,$.label),w=i($.label);if(await u(w)){if(await vscode.window.showWarningMessage(`Skill "${$.label}" already exists in User Library. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(w,{recursive:!0,force:!0})}try{await l(f,w);const{getRegistry:I}=await import("./registry/index.js");await I(e).registerSkill({slug:$.label,displayName:$.label,latestVersion:"local",tags:[],stats:{installs:1}});const{invalidateLocalIndex:D}=await import("./store/oramaIndex.js");D(),showInfo(`AgentIDE: Saved skill "${$.label}" to User Library`)}catch(I){const g=I instanceof Error?I.message:String(I);log(e,`[AgentIDE] Share skill error: ${g}`),showError(`AgentIDE: ${g}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.share",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),{getAgentMcpDir:c,getUserMcpServerDir:i}=await import("./agentpack/paths.js"),{copyDirRecursive:l,pathExists:u}=await import("./utils.js"),o=await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup();if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found`);return}const a=await vscode.window.showQuickPick(o.map(w=>({label:w.id,description:`v${w.version}`})),{placeHolder:"Select agent containing the MCP server",title:"Save MCP Server to User Library"});if(!a)return;const p=c(n,a.label),S=path.join(p,".mcp.json");let k={mcpServers:{}};try{const w=await fs_1.promises.readFile(S,"utf-8");k=JSON.parse(w)}catch{showInfo(`AgentIDE: No MCP servers configured in ${a.label}`);return}if(!k.mcpServers||Object.keys(k.mcpServers).length===0){showInfo(`AgentIDE: No MCP servers configured in ${a.label}`);return}const y=Object.keys(k.mcpServers),$=await vscode.window.showQuickPick(y.map(w=>({label:w})),{placeHolder:"Select MCP server to save to User Library",title:"Save MCP Server to User Library"});if(!$)return;const f=i($.label);if(await u(f)){if(await vscode.window.showWarningMessage(`MCP "${$.label}" already exists in User Library. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(f,{recursive:!0,force:!0})}try{await fs_1.promises.mkdir(f,{recursive:!0});const w=k.mcpServers[$.label];await fs_1.promises.writeFile(path.join(f,"mcp.json"),JSON.stringify({name:$.label,...w},null,2));const I=path.join(p,$.label);await u(I)&&await l(I,f);const{getRegistry:g}=await import("./registry/index.js");await g(e).registerMcp({slug:$.label,displayName:$.label,transport:w.transport||"stdio",latestVersion:"local",tags:[],stats:{installs:1}});const{invalidateLocalIndex:M}=await import("./store/oramaIndex.js");M(),showInfo(`AgentIDE: Saved MCP "${$.label}" to User Library`)}catch(w){const I=w instanceof Error?w.message:String(w);log(e,`[AgentIDE] Share MCP error: ${I}`),showError(`AgentIDE: ${I}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.publish",async()=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s,validateForPublish:c}=await import("./agentpack/index.js"),{publishToStore:i,STORE_CONFIG:l}=await import("./store/index.js"),o=(await new s(m,()=>n,()=>E.storagePath,e).listInstalledWithCleanup()).filter(g=>g.id!=="default");if(o.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to publish (create an agent first)`);return}const a=await vscode.window.showQuickPick(o.map(g=>({label:g.id,description:`v${g.version}`})),{placeHolder:"Select an agent pack to publish",title:`Publish to ${l.owner}/${l.repo}`});if(!a)return;const p=await c(n,a.label);if(!p.valid){showError(`AgentIDE: Cannot publish - ${p.errors.join(", ")}`);return}if(p.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${p.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const S=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Added new features, fixed bugs..."}),{getAgentRoot:k}=await import("./agentpack/paths.js"),y=k(n,a.label),$=[];async function f(g,D){const M=await fs_1.promises.readdir(g);for(const b of M){if(b.startsWith("."))continue;const v=path.join(g,b),N=D?`${D}/${b}`:b;if((await fs_1.promises.stat(v)).isDirectory())await f(v,N);else{const P=await fs_1.promises.readFile(v,"utf-8");$.push({path:N,content:P})}}}await f(y,"");const w=o.find(g=>g.id===a.label);if(await vscode.window.showWarningMessage(`Submit "${w.id}" v${w.version} to ${l.owner}/${l.repo}?
17
17
 
18
- This will create a pull request.`,{modal:!0},"Submit PR")==="Submit PR")try{const g=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing ${w.id} v${w.version}`,cancellable:!1},async M=>{M.report({message:"Preparing fork..."});const b=await i({type:"pack",slug:w.id,version:w.version,files:$,changelog:S},e);return M.report({message:"Creating PR..."}),b});await vscode.window.showInformationMessage(`Created PR #${g.prNumber} for ${w.id} v${w.version}`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(g.prUrl))}catch(g){const D=g instanceof Error?g.message:String(g);log(e,`[AgentIDE] Publish error: ${D}`),showError(`AgentIDE: ${D}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.installFromGitHub",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{installFromGitHub:l}=await import("./agentpack/index.js");let i=n;if(i||(i=await vscode.window.showInputBox({prompt:"Enter GitHub repository URL or owner/repo",placeHolder:"e.g., user/my-agent-pack or github://user/pack@v1.0.0",validateInput:c=>c.trim()?c.includes("/")?null:"Expected format: owner/repo or github://owner/repo@version":"Please enter a repository"})),!!i)try{const c=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:"Installing from GitHub",cancellable:!1},async d=>(d.report({message:"Downloading..."}),await l(s,{source:i,force:!1},e)));await vscode.commands.executeCommand("agentide.packsChanged"),await m.seedAgentDataIfNeeded(s,c.agentId,e),await vscode.window.showInformationMessage(`Installed ${c.agentId} ${c.version}!`,"Activate")==="Activate"&&await vscode.commands.executeCommand("agentide.pack.switch",c.agentId)}catch(c){const u=c instanceof Error?c.message:String(c);if(u.includes("already exists")){if(await vscode.window.showWarningMessage(u,"Overwrite","Cancel")==="Overwrite")try{const o=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:"Installing from GitHub",cancellable:!1},async r=>(r.report({message:"Downloading..."}),await l(s,{source:i,force:!0},e)));await vscode.commands.executeCommand("agentide.packsChanged"),await m.seedAgentDataIfNeeded(s,o.agentId,e),showInfo(`AgentIDE: Installed ${o.agentId} ${o.version}`)}catch(o){const r=o instanceof Error?o.message:String(o);showError(`AgentIDE: ${r}`)}}else log(e,`[AgentIDE] Install error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.browseLibrary",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e),i=await l.listUserLibrary();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: User Library is empty. Share agents with "${branding_1.AGENTIDE_BRAND_NAME}: Share Agent to User Library"`);return}const c=i.map(o=>({label:o.id,description:o.currentVersion?`v${o.currentVersion}`:`${o.versions.length} version(s)`,detail:o.description||`Preferred engine: ${o.preferredEngine||"unknown"}`,agentId:o.id,currentVersion:o.currentVersion})),u=await vscode.window.showQuickPick(c,{placeHolder:"Select an agent to install",title:"User Agent Library"});if(!(!u||(await vscode.window.showQuickPick([{label:"Install to Workspace",action:"install"},{label:"Cancel",action:"cancel"}],{placeHolder:`What would you like to do with "${u.agentId}"?`}))?.action!=="install"))try{const o=await l.installAgentToWorkspace(u.agentId);if(o.installed){const r=o.hydrated?`Installed "${u.agentId}" v${o.version} to workspace from User Library`:`"${u.agentId}" is already installed in this workspace`;showInfo(`AgentIDE: ${r}`)}else showError(`AgentIDE: Failed to install "${u.agentId}"`)}catch(o){const r=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Install error: ${r}`),showError(`AgentIDE: ${r}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),s=path.join(n,".agent-hippo","agents"),l=[];if(await(0,utils_1.pathExists)(s)){const c=await fs_1.promises.readdir(s);for(const u of c){const d=path.join(s,u,"skills");if(await(0,utils_1.pathExists)(d)){const o=await fs_1.promises.readdir(d);for(const r of o){const p=path.join(d,r),S=path.join(p,"SKILL.md");await(0,utils_1.pathExists)(S)&&l.push({name:r,path:p})}}}}if(l.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No skills found. Create a skill with SKILL.md in your agent's skills/ folder.`);return}const i=await vscode.window.showQuickPick(l.map(c=>({label:c.name,path:c.path})),{placeHolder:"Select a skill to publish"});if(i)try{const{validateSkillForPublish:c,collectSkillFiles:u}=await import("./skills/publish.js"),{publishToStore:d}=await import("./store/index.js"),o=await c(i.path);if(!o.valid){showError(`AgentIDE: ${o.errors.join(", ")}`);return}const r=o.metadata?.version||await vscode.window.showInputBox({prompt:"Version (semver)",placeHolder:"e.g., 1.0.0",validateInput:w=>/^\d+\.\d+\.\d+/.test(w)?null:"Use semver format (e.g., 1.0.0)"});if(!r)return;const p=await u(i.path),S=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing skill "${i.label}"`,cancellable:!1},async w=>{w.report({message:"Preparing fork..."});const I=await d({type:"skill",slug:i.label,version:r,files:p},e);return w.report({message:"Creating PR..."}),I}),{getRegistry:k}=await import("./registry/index.js"),{STORE_CONFIG:A}=await import("./store/index.js");await k(e).registerSkill({slug:i.label,displayName:o.metadata?.name||i.label,description:o.metadata?.description,github:{owner:A.owner,repo:A.repo},latestVersion:r,tags:o.metadata?.tags||[],stats:{installs:0}}),await vscode.window.showInformationMessage(`Published skill "${i.label}" v${r}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(S.prUrl))}catch(c){const u=c instanceof Error?c.message:String(c);log(e,`[AgentIDE] Skill publish error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),s=path.join(n,".agentide","agents"),l=[];if(await(0,utils_1.pathExists)(s)){const c=await fs_1.promises.readdir(s);for(const u of c){const d=path.join(s,u,"mcp"),o=path.join(d,".mcp.json");if(await(0,utils_1.pathExists)(o))try{const r=await fs_1.promises.readFile(o,"utf-8"),p=JSON.parse(r);if(p.mcpServers)for(const S of Object.keys(p.mcpServers))l.push({name:S,agentId:u,configPath:o,mcpDir:d})}catch{}}}if(l.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No MCP servers found. Add MCP servers to your agent's mcp/.mcp.json file.`);return}const i=await vscode.window.showQuickPick(l.map(c=>({label:c.name,description:`from ${c.agentId}`,detail:c.configPath,config:c})),{placeHolder:"Select an MCP server to publish"});if(i)try{const{publishToStore:c,STORE_CONFIG:u}=await import("./store/index.js"),{collectMcpFiles:d,validateMcpConfig:o}=await import("./mcp/publish.js"),{getRegistry:r}=await import("./registry/index.js"),p=await fs_1.promises.readFile(i.config.configPath,"utf-8"),k=JSON.parse(p).mcpServers[i.config.name],A=o({name:i.config.name,version:k.version||"1.0.0",description:k.description,transport:k.transport||"stdio",command:k.command,args:k.args,env:k.env,url:k.url,npmPackage:k.npmPackage});if(!A.valid){showError(`AgentIDE: ${A.errors.join(", ")}`);return}const $=k.version||await vscode.window.showInputBox({prompt:"Version (semver)",placeHolder:"e.g., 1.0.0",value:"1.0.0",validateInput:v=>/^\d+\.\d+\.\d+/.test(v)?null:"Use semver format (e.g., 1.0.0)"});if(!$)return;let f=k.description;if(!f&&(f=await vscode.window.showInputBox({prompt:"Description (required)",placeHolder:"What does this MCP server do?"}),!f)){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Description is required`);return}const w=await d(i.config.mcpDir),I={name:i.config.name,version:$,description:f,transport:k.transport||"stdio",command:k.command,args:k.args,env:k.env,url:k.url,npmPackage:k.npmPackage},g=JSON.parse(JSON.stringify(I));w.push({path:"mcp.json",content:JSON.stringify(g,null,2)});const D=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing MCP "${i.config.name}"`,cancellable:!1},async v=>{v.report({message:"Preparing fork..."});const N=await c({type:"mcp",slug:i.config.name,version:$,files:w},e);return v.report({message:"Creating PR..."}),N});await r(e).registerMcp({slug:i.config.name,displayName:i.config.name,description:f,transport:k.transport||"stdio",github:{owner:u.owner,repo:u.repo},latestVersion:$,tags:[],stats:{installs:0}}),await vscode.window.showInformationMessage(`Published MCP "${i.config.name}" v${$}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(D.prUrl))}catch(c){const u=c instanceof Error?c.message:String(c);log(e,`[AgentIDE] MCP publish error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.spotlight.publish",async(n,s)=>{const l=s?.bundle==="scripts-only"?"scripts-only":"full",{workspaceRoot:i}=getWorkspaceRoot(e),{collectViewFiles:c,discoverPublishableViews:u,validateViewForPublish:d}=await import("./spotlight/publish.js"),{publishToStore:o,STORE_CONFIG:r,canPublishDirectlyToStore:p}=await import("./store/index.js"),{isValidPublishVersion:S}=await import("./engines/publish.js"),k=await u(i);if(k.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No publishable Spotlight views found. Create a view under .agent-hippo/analytics and register it in panel/views.yaml.`);return}const A=typeof n=="string"?n.trim():"";let $=A?k.find(f=>f.id===A):void 0;if(A&&!$){showError(`${branding_1.AGENTIDE_BRAND_NAME}: View "${A}" is not publishable. Add widget scripts under .agent-hippo/analytics/views/${A}/scripts and register the view in panel/views.yaml.`);return}if(!$){const f=await vscode.window.showQuickPick(k.map(w=>({label:w.name,description:w.id,detail:`${w.sourceLabel} \u2022 ${w.scope} \u2022 ${w.scripts.length} script(s)`,view:w})),{placeHolder:"Select a Spotlight view to publish",title:`Publish to ${r.owner}/${r.repo}`});if(!f)return;$=f.view}try{const f=await d($,{expectedId:$.id,mode:l});if(!f.valid){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Cannot publish - ${f.errors.join(", ")}`);return}if(f.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${f.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const w=await vscode.window.showInputBox({prompt:"Publish version (semver)",value:f.metadata?.publishVersion||"1.0.0",placeHolder:"e.g., 1.0.0",validateInput:P=>P&&S(P.replace(/^v/,""))?null:"Use semver format (e.g., 1.0.0)"});if(!w||!f.metadata)return;const I=w.replace(/^v/,""),g=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Initial release, new widgets..."}),D=await c($,I,f.metadata,l),M=l==="full"?"full bundle (scripts + assets + charts/exports)":"scripts only",b=await p();if(await vscode.window.showWarningMessage(b?`Publish Spotlight view "${$.id}" v${I} (${M}) to ${r.owner}/${r.repo}?
18
+ This will create a pull request.`,{modal:!0},"Submit PR")==="Submit PR")try{const g=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing ${w.id} v${w.version}`,cancellable:!1},async M=>{M.report({message:"Preparing fork..."});const b=await i({type:"pack",slug:w.id,version:w.version,files:$,changelog:S},e);return M.report({message:"Creating PR..."}),b});await vscode.window.showInformationMessage(`Created PR #${g.prNumber} for ${w.id} v${w.version}`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(g.prUrl))}catch(g){const D=g instanceof Error?g.message:String(g);log(e,`[AgentIDE] Publish error: ${D}`),showError(`AgentIDE: ${D}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.installFromGitHub",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{installFromGitHub:c}=await import("./agentpack/index.js");let i=n;if(i||(i=await vscode.window.showInputBox({prompt:"Enter GitHub repository URL or owner/repo",placeHolder:"e.g., user/my-agent-pack or github://user/pack@v1.0.0",validateInput:l=>l.trim()?l.includes("/")?null:"Expected format: owner/repo or github://owner/repo@version":"Please enter a repository"})),!!i)try{const l=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:"Installing from GitHub",cancellable:!1},async d=>(d.report({message:"Downloading..."}),await c(s,{source:i,force:!1},e)));await vscode.commands.executeCommand("agentide.packsChanged"),await m.seedAgentDataIfNeeded(s,l.agentId,e),await vscode.window.showInformationMessage(`Installed ${l.agentId} ${l.version}!`,"Activate")==="Activate"&&await vscode.commands.executeCommand("agentide.pack.switch",l.agentId)}catch(l){const u=l instanceof Error?l.message:String(l);if(u.includes("already exists")){if(await vscode.window.showWarningMessage(u,"Overwrite","Cancel")==="Overwrite")try{const o=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:"Installing from GitHub",cancellable:!1},async a=>(a.report({message:"Downloading..."}),await c(s,{source:i,force:!0},e)));await vscode.commands.executeCommand("agentide.packsChanged"),await m.seedAgentDataIfNeeded(s,o.agentId,e),showInfo(`AgentIDE: Installed ${o.agentId} ${o.version}`)}catch(o){const a=o instanceof Error?o.message:String(o);showError(`AgentIDE: ${a}`)}}else log(e,`[AgentIDE] Install error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.browseLibrary",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e),i=await c.listUserLibrary();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: User Library is empty. Share agents with "${branding_1.AGENTIDE_BRAND_NAME}: Share Agent to User Library"`);return}const l=i.map(o=>({label:o.id,description:o.currentVersion?`v${o.currentVersion}`:`${o.versions.length} version(s)`,detail:o.description||`Preferred engine: ${o.preferredEngine||"unknown"}`,agentId:o.id,currentVersion:o.currentVersion})),u=await vscode.window.showQuickPick(l,{placeHolder:"Select an agent to install",title:"User Agent Library"});if(!(!u||(await vscode.window.showQuickPick([{label:"Install to Workspace",action:"install"},{label:"Cancel",action:"cancel"}],{placeHolder:`What would you like to do with "${u.agentId}"?`}))?.action!=="install"))try{const o=await c.installAgentToWorkspace(u.agentId);if(o.installed){const a=o.hydrated?`Installed "${u.agentId}" v${o.version} to workspace from User Library`:`"${u.agentId}" is already installed in this workspace`;showInfo(`AgentIDE: ${a}`)}else showError(`AgentIDE: Failed to install "${u.agentId}"`)}catch(o){const a=o instanceof Error?o.message:String(o);log(e,`[AgentIDE] Install error: ${a}`),showError(`AgentIDE: ${a}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),s=path.join(n,".agent-hippo","agents"),c=[];if(await(0,utils_1.pathExists)(s)){const l=await fs_1.promises.readdir(s);for(const u of l){const d=path.join(s,u,"skills");if(await(0,utils_1.pathExists)(d)){const o=await fs_1.promises.readdir(d);for(const a of o){const p=path.join(d,a),S=path.join(p,"SKILL.md");await(0,utils_1.pathExists)(S)&&c.push({name:a,path:p})}}}}if(c.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No skills found. Create a skill with SKILL.md in your agent's skills/ folder.`);return}const i=await vscode.window.showQuickPick(c.map(l=>({label:l.name,path:l.path})),{placeHolder:"Select a skill to publish"});if(i)try{const{validateSkillForPublish:l,collectSkillFiles:u}=await import("./skills/publish.js"),{publishToStore:d}=await import("./store/index.js"),o=await l(i.path);if(!o.valid){showError(`AgentIDE: ${o.errors.join(", ")}`);return}const a=o.metadata?.version||await vscode.window.showInputBox({prompt:"Version (semver)",placeHolder:"e.g., 1.0.0",validateInput:w=>/^\d+\.\d+\.\d+/.test(w)?null:"Use semver format (e.g., 1.0.0)"});if(!a)return;const p=await u(i.path),S=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing skill "${i.label}"`,cancellable:!1},async w=>{w.report({message:"Preparing fork..."});const I=await d({type:"skill",slug:i.label,version:a,files:p},e);return w.report({message:"Creating PR..."}),I}),{getRegistry:k}=await import("./registry/index.js"),{STORE_CONFIG:y}=await import("./store/index.js");await k(e).registerSkill({slug:i.label,displayName:o.metadata?.name||i.label,description:o.metadata?.description,github:{owner:y.owner,repo:y.repo},latestVersion:a,tags:o.metadata?.tags||[],stats:{installs:0}}),await vscode.window.showInformationMessage(`Published skill "${i.label}" v${a}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(S.prUrl))}catch(l){const u=l instanceof Error?l.message:String(l);log(e,`[AgentIDE] Skill publish error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.publish",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),s=path.join(n,".agentide","agents"),c=[];if(await(0,utils_1.pathExists)(s)){const l=await fs_1.promises.readdir(s);for(const u of l){const d=path.join(s,u,"mcp"),o=path.join(d,".mcp.json");if(await(0,utils_1.pathExists)(o))try{const a=await fs_1.promises.readFile(o,"utf-8"),p=JSON.parse(a);if(p.mcpServers)for(const S of Object.keys(p.mcpServers))c.push({name:S,agentId:u,configPath:o,mcpDir:d})}catch{}}}if(c.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No MCP servers found. Add MCP servers to your agent's mcp/.mcp.json file.`);return}const i=await vscode.window.showQuickPick(c.map(l=>({label:l.name,description:`from ${l.agentId}`,detail:l.configPath,config:l})),{placeHolder:"Select an MCP server to publish"});if(i)try{const{publishToStore:l,STORE_CONFIG:u}=await import("./store/index.js"),{collectMcpFiles:d,validateMcpConfig:o}=await import("./mcp/publish.js"),{getRegistry:a}=await import("./registry/index.js"),p=await fs_1.promises.readFile(i.config.configPath,"utf-8"),k=JSON.parse(p).mcpServers[i.config.name],y=o({name:i.config.name,version:k.version||"1.0.0",description:k.description,transport:k.transport||"stdio",command:k.command,args:k.args,env:k.env,url:k.url,npmPackage:k.npmPackage});if(!y.valid){showError(`AgentIDE: ${y.errors.join(", ")}`);return}const $=k.version||await vscode.window.showInputBox({prompt:"Version (semver)",placeHolder:"e.g., 1.0.0",value:"1.0.0",validateInput:v=>/^\d+\.\d+\.\d+/.test(v)?null:"Use semver format (e.g., 1.0.0)"});if(!$)return;let f=k.description;if(!f&&(f=await vscode.window.showInputBox({prompt:"Description (required)",placeHolder:"What does this MCP server do?"}),!f)){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Description is required`);return}const w=await d(i.config.mcpDir),I={name:i.config.name,version:$,description:f,transport:k.transport||"stdio",command:k.command,args:k.args,env:k.env,url:k.url,npmPackage:k.npmPackage},g=JSON.parse(JSON.stringify(I));w.push({path:"mcp.json",content:JSON.stringify(g,null,2)});const D=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing MCP "${i.config.name}"`,cancellable:!1},async v=>{v.report({message:"Preparing fork..."});const N=await l({type:"mcp",slug:i.config.name,version:$,files:w},e);return v.report({message:"Creating PR..."}),N});await a(e).registerMcp({slug:i.config.name,displayName:i.config.name,description:f,transport:k.transport||"stdio",github:{owner:u.owner,repo:u.repo},latestVersion:$,tags:[],stats:{installs:0}}),await vscode.window.showInformationMessage(`Published MCP "${i.config.name}" v${$}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(D.prUrl))}catch(l){const u=l instanceof Error?l.message:String(l);log(e,`[AgentIDE] MCP publish error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.spotlight.publish",async(n,s)=>{const c=s?.bundle==="scripts-only"?"scripts-only":"full",{workspaceRoot:i}=getWorkspaceRoot(e),{collectViewFiles:l,discoverPublishableViews:u,validateViewForPublish:d}=await import("./spotlight/publish.js"),{publishToStore:o,STORE_CONFIG:a,canPublishDirectlyToStore:p}=await import("./store/index.js"),{isValidPublishVersion:S}=await import("./engines/publish.js"),k=await u(i);if(k.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No publishable Spotlight views found. Create a view under .agent-hippo/analytics and register it in panel/views.yaml.`);return}const y=typeof n=="string"?n.trim():"";let $=y?k.find(f=>f.id===y):void 0;if(y&&!$){showError(`${branding_1.AGENTIDE_BRAND_NAME}: View "${y}" is not publishable. Add widget scripts under .agent-hippo/analytics/views/${y}/scripts and register the view in panel/views.yaml.`);return}if(!$){const f=await vscode.window.showQuickPick(k.map(w=>({label:w.name,description:w.id,detail:`${w.sourceLabel} \u2022 ${w.scope} \u2022 ${w.scripts.length} script(s)`,view:w})),{placeHolder:"Select a Spotlight view to publish",title:`Publish to ${a.owner}/${a.repo}`});if(!f)return;$=f.view}try{const f=await d($,{expectedId:$.id,mode:c});if(!f.valid){showError(`${branding_1.AGENTIDE_BRAND_NAME}: Cannot publish - ${f.errors.join(", ")}`);return}if(f.warnings.length>0&&await vscode.window.showWarningMessage(`Warnings: ${f.warnings.join(", ")}`,"Publish Anyway","Cancel")!=="Publish Anyway")return;const w=await vscode.window.showInputBox({prompt:"Publish version (semver)",value:f.metadata?.publishVersion||"1.0.0",placeHolder:"e.g., 1.0.0",validateInput:P=>P&&S(P.replace(/^v/,""))?null:"Use semver format (e.g., 1.0.0)"});if(!w||!f.metadata)return;const I=w.replace(/^v/,""),g=await vscode.window.showInputBox({prompt:"What changed in this version? (optional)",placeHolder:"Initial release, new widgets..."}),D=await l($,I,f.metadata,c),M=c==="full"?"full bundle (scripts + assets + charts/exports)":"scripts only",b=await p();if(await vscode.window.showWarningMessage(b?`Publish Spotlight view "${$.id}" v${I} (${M}) to ${a.owner}/${a.repo}?
19
19
 
20
- This will open a pull request on the store repository.`:`Submit Spotlight view "${$.id}" v${I} (${M}) to ${r.owner}/${r.repo}?
20
+ This will open a pull request on the store repository.`:`Submit Spotlight view "${$.id}" v${I} (${M}) to ${a.owner}/${a.repo}?
21
21
 
22
- This will create a pull request from your fork.`,{modal:!0},"Submit PR")!=="Submit PR")return;const N=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing Spotlight view ${$.id} v${I}`,cancellable:!1},async P=>(P.report({message:b?`Publishing to ${r.owner}/${r.repo}...`:"Preparing fork..."}),await o({type:"view",slug:$.id,version:I,files:D,changelog:g},e)));await vscode.window.showInformationMessage(`Published Spotlight view "${$.name}" v${I}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(N.prUrl))}catch(f){const w=f instanceof Error?f.message:String(f);log(e,`[AgentIDE] Spotlight publish error: ${w}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: ${w}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.install",async n=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{parseStoreUrl:s}=await import("./store/index.js");let l=n;if(l||(l=await vscode.window.showInputBox({prompt:"Enter store URL or GitHub link",placeHolder:"e.g., engine/gemini or https://github.com/.../engines/gemini",validateInput:i=>i.trim()?i.includes("/")?null:"Expected: type/slug, or GitHub URL":"Please enter a URL"})),!!l)try{const i=s(l);switch(i.type){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",i);break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",i);break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",i);break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",i);break;case"view":await vscode.commands.executeCommand("agentide.view.install",i);break}}catch(i){const c=i instanceof Error?i.message:String(i);log(e,`[AgentIDE] Store install error: ${c}`),showError(`AgentIDE: ${c}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.find",async n=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{isStoreUrl:s,parseStoreUrl:l,parseGitHubUrl:i,detectArtifactType:c}=await import("./store/index.js"),{searchMerged:u,listMergedArtifacts:d}=await import("./store/oramaIndex.js");let o,r="all";if(typeof n=="string"?o=n:n&&typeof n=="object"&&n.typeFilter&&(r=n.typeFilter),o)try{let b,v,N;if(s(o)){const R=l(o);b=R.type,v=R.slug,N=R.version}else{const R=i(o);b=await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:"Detecting artifact type...",cancellable:!1},async()=>await c(R.owner,R.repo,R.ref,R.path,e));const P=(R.path||R.repo).split("/");v=P[P.length-1]||R.repo,N=R.ref}switch(b){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",{type:"pack",slug:v,version:N,sourceUrl:o});break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",{type:"skill",slug:v,version:N,sourceUrl:o});break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",{type:"mcp",slug:v,version:N,sourceUrl:o});break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",{type:"engine",slug:v,version:N,sourceUrl:o});break;case"view":await vscode.commands.executeCommand("agentide.view.install",{type:"view",slug:v,version:N,sourceUrl:o});break}return}catch(b){const v=b instanceof Error?b.message:String(b);log(e,`[AgentIDE] Install error: ${v}`),showError(`AgentIDE: ${v}`);return}const{STORE_ICONS:p}=await import("./store/shared.js"),S={pack:p.pack,skill:p.skill,mcp:p.mcp,engine:p.engine,view:p.view},k=["all","pack","skill","mcp","engine","view"],A=vscode.window.createQuickPick();A.title=r==="view"?"Install Spotlight View":"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",A.placeholder="Search or paste a GitHub URL to install...",A.matchOnDescription=!0,A.matchOnDetail=!0,A.busy=!0;let $=[],f=r,w;const I={local:p.local,remote:p.remote},g=b=>{const v=b??$,N=f==="all"?v:v.filter(_=>_.type===f),R=k.map(_=>({label:_==="all"?"$(list-flat) All":`${S[_]} ${_.charAt(0).toUpperCase()+_.slice(1)}s`,description:_===f?"$(check)":"",alwaysShow:!0,itemType:"filter",filter:_})),P=N.map(_=>{const L=_.source==="local"?I.local:I.remote,x=_.installed?"$(check)":"",U=[_.source==="local"?"Local":"Remote",_.type];x&&U.push(x);let O=_.description||_.path;return _.installedTo&&_.installedTo.length>0&&(O+=` \u2022 Installed to: ${_.installedTo.join(", ")}`),{label:`${L} ${S[_.type]} ${_.slug}`,description:U.join(" \u2022 "),detail:O,itemType:"artifact",artifact:_}});A.items=[...R,{label:"",kind:vscode.QuickPickItemKind.Separator,itemType:"filter"},...P]},D=async b=>{w&&clearTimeout(w);const v=b.trim();if(!v||v.startsWith("http")||v.startsWith("store://")||v.startsWith("github.com")){g($);return}w=setTimeout(async()=>{try{const P=(await u(v,{type:f==="all"?void 0:f,limit:50},e)).map(_=>({type:_.type,slug:_.slug,path:`${_.type}s/${_.slug}`,description:_.description,installed:_.installed,installedVersion:_.installedVersion,source:_.source,installedTo:_.installedTo}));g(P)}catch(N){log(e,`[AgentIDE] Search error: ${N instanceof Error?N.message:String(N)}`),g($)}},150)};A.onDidChangeValue(D);try{$=(await d(void 0,e)).map(v=>({type:v.type,slug:v.slug,path:`${v.type}s/${v.slug}`,description:v.description,installed:v.installed,installedVersion:v.installedVersion,source:v.source,installedTo:v.installedTo})),A.busy=!1,g(),$.length===0&&(A.placeholder="Store is empty or index not synced yet. Try again later!")}catch(b){const v=b instanceof Error?b.message:String(b);log(e,`[AgentIDE] Store browse error: ${v}`),A.hide(),showError(`AgentIDE: ${v}`);return}const M=b=>{const v=b.trim();return v.startsWith("https://")||v.startsWith("http://")||v.startsWith("github.com/")||v.startsWith("store://")};A.onDidAccept(async()=>{const b=A.selectedItems[0],v=A.value.trim();if(v&&M(v)){A.hide(),log(e,`[AgentIDE] Browse Store: detected URL input: ${v}`),await vscode.commands.executeCommand("agentide.store.find",v);return}if(b){if(b.itemType==="filter"&&b.filter){f=b.filter,g();return}if(b.itemType==="artifact"&&b.artifact){A.hide();const{artifact:N}=b;switch(N.type){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",{type:"pack",slug:N.slug});break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",{type:"skill",slug:N.slug});break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",{type:"mcp",slug:N.slug});break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",{type:"engine",slug:N.slug});break;case"view":await vscode.commands.executeCommand("agentide.view.install",{type:"view",slug:N.slug});break}}}}),A.onDidHide(()=>A.dispose()),A.show()})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.search",async(n,s)=>{const{searchMerged:l}=await import("./store/oramaIndex.js");return l(n,s,e)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.sync",async()=>{const{forceRefresh:n,getIndexMeta:s}=await import("./store/oramaIndex.js");await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:"Syncing store index...",cancellable:!1},async()=>{await n(e)});const l=await s();l&&showInfo(`Store index synced: ${l.artifactCount} artifacts (updated ${new Date(l.generatedAt).toLocaleDateString()})`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.setup",async()=>{const{setupStoreAutomation:n}=await import("./store/github/setup.js"),s=await vscode.window.showInputBox({prompt:"Enter GitHub repository URL for your store",placeHolder:"https://github.com/owner/repo or owner/repo",validateInput:o=>o?o.match(/(?:github\.com\/)?([^/]+)\/([^/]+)/)?null:"Invalid format. Use: owner/repo or https://github.com/owner/repo":"Repository URL is required"});if(!s)return;const l=s.match(/(?:github\.com\/)?([^/]+)\/([^/]+)/);if(!l){showError("Invalid repository URL");return}const[,i,c]=l,u=c.replace(/\.git$/,""),d=await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:`Setting up store automation for ${i}/${u}...`,cancellable:!1},async()=>await n(i,u,e));if(d.success&&d.pullRequestUrl){const o=vscode.workspace.getConfiguration("agentide"),r=`${i}/${u}`,p=o.get("storeRepo",""),S=o.get("store.indexUrl",""),k=`https://${i}.github.io/${u}`;let A="";if(p){const f=p.match(/^(?:https?:\/\/github\.com\/)?([^/]+)\/([^/]+?)(?:\.git)?$/);f&&(A=`https://${f[1]}.github.io/${f[2]}`)}await o.update("storeRepo",r,vscode.ConfigurationTarget.Global),(!S||A&&S===A)&&await o.update("store.indexUrl",k,vscode.ConfigurationTarget.Global);const $=await vscode.window.showInformationMessage(`\u{1F99B} ${d.message}`,"Open Pull Request","Copy URL");$==="Open Pull Request"?await vscode.env.openExternal(vscode.Uri.parse(d.pullRequestUrl)):$==="Copy URL"&&(await vscode.env.clipboard.writeText(d.pullRequestUrl),showInfo("Pull request URL copied to clipboard"))}else d.success||showError(`Setup failed: ${d.message}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.storeInstall",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:l,listStoreVersions:i}=await import("./store/index.js"),{getAgentRoot:c}=await import("./agentpack/paths.js"),u=n||{type:"pack",slug:"",version:void 0};if(!u.version){const A=await i("pack",u.slug);if(A.length===0)u.version="main";else{const $=await vscode.window.showQuickPick(A.map(f=>({label:f.version,description:f.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!$)return;u.version=$.label}}const d=c(s,u.slug);if(await fs_1.promises.access(d).then(()=>!0).catch(()=>!1)){if(await vscode.window.showWarningMessage(`Pack "${u.slug}" already exists. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(d,{recursive:!0,force:!0})}await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing pack "${u.slug}"`,cancellable:!1},async A=>{A.report({message:"Downloading from store..."});const $=await l({type:"pack",slug:u.slug,version:u.version},e);A.report({message:"Extracting files..."}),await fs_1.promises.mkdir(d,{recursive:!0});for(const f of $){const w=path.join(d,f.path);await fs_1.promises.mkdir(path.dirname(w),{recursive:!0}),await fs_1.promises.writeFile(w,f.content)}}),await vscode.commands.executeCommand("agentide.packsChanged");const{getRegistry:r}=await import("./registry/index.js");await r(e).registerPack({slug:u.slug,displayName:u.slug,latestVersion:u.version||"main",tags:[],stats:{installs:1,stars:0}});const{invalidateLocalIndex:S}=await import("./store/oramaIndex.js");S(),await vscode.window.showInformationMessage(`Installed pack "${u.slug}" v${u.version}`,"Activate")==="Activate"&&await vscode.commands.executeCommand("agentide.pack.switch",u.slug)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:l,downloadFromExternalGitHub:i,listStoreVersions:c,isStoreUrl:u,parseGitHubUrl:d}=await import("./store/index.js"),{AgentPackManager:o}=await import("./agentpack/index.js"),r=new o(m,()=>s,()=>E.storagePath,e);let p=n;if(!p){const b=await vscode.window.showInputBox({prompt:"Enter skill store URL or GitHub URL",placeHolder:"e.g., skills/typescript-testing@v1.0.0 or https://github.com/user/repo"});if(!b)return;const{parseStoreUrl:v}=await import("./store/index.js");p=v(b)}const S=p.sourceUrl&&!u(p.sourceUrl);if(!p.version&&!S){const b=await c("skill",p.slug);if(b.length===0)p.version="main";else{const v=await vscode.window.showQuickPick(b.map(N=>({label:N.version,description:N.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!v)return;p.version=v.label}}const k=await r.listInstalledWithCleanup();if(k.length===0){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found. Create an agent first.`);return}const A=await vscode.window.showQuickPick(k.map(b=>({label:b.id,description:`v${b.version}`})),{placeHolder:"Select agent to install skill to"});if(!A)return;const{getAgentRoot:$}=await import("./agentpack/paths.js"),f=$(s,A.label),w=path.join(f,"skills",p.slug);if(await fs_1.promises.access(w).then(()=>!0).catch(()=>!1)){if(await vscode.window.showWarningMessage(`Skill "${p.slug}" already exists in ${A.label}. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(w,{recursive:!0,force:!0})}await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing skill "${p.slug}"`,cancellable:!1},async b=>{let v;if(S&&p.sourceUrl){b.report({message:"Downloading from GitHub..."});const N=d(p.sourceUrl);v=await i({owner:N.owner,repo:N.repo,ref:N.ref||"main",path:N.path},e)}else b.report({message:"Downloading from store..."}),v=await l({type:"skill",slug:p.slug,version:p.version},e);b.report({message:"Extracting files..."}),await fs_1.promises.mkdir(w,{recursive:!0});for(const N of v){const R=path.join(w,N.path);await fs_1.promises.mkdir(path.dirname(R),{recursive:!0}),await fs_1.promises.writeFile(R,N.content)}});const{getRegistry:g}=await import("./registry/index.js");await g(e).registerSkill({slug:p.slug,displayName:p.slug,latestVersion:p.version||"main",tags:[],stats:{installs:1},agentPackId:A.label});const{invalidateLocalIndex:M}=await import("./store/oramaIndex.js");M(),showInfo(`Installed skill "${p.slug}" to ${A.label}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:l,listStoreVersions:i}=await import("./store/index.js"),{AgentPackManager:c}=await import("./agentpack/index.js"),u=new c(m,()=>s,()=>E.storagePath,e);let d=n;if(!d){const A=await vscode.window.showInputBox({prompt:"Enter MCP store URL",placeHolder:"e.g., mcp/github@v1.0.0"});if(!A)return;const{parseStoreUrl:$}=await import("./store/index.js");d=$(A)}if(!d.version){const A=await i("mcp",d.slug);if(A.length===0)d.version="main";else{const $=await vscode.window.showQuickPick(A.map(f=>({label:f.version,description:f.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!$)return;d.version=$.label}}const o=await u.listInstalledWithCleanup();if(o.length===0){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found. Create an agent first.`);return}const r=await vscode.window.showQuickPick(o.map(A=>({label:A.id,description:`v${A.version}`})),{placeHolder:"Select agent to add MCP server to"});if(!r)return;await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing MCP "${d.slug}"`,cancellable:!1},async A=>{A.report({message:"Downloading from store..."});const $=await l({type:"mcp",slug:d.slug,version:d.version},e);A.report({message:"Merging MCP config..."});const f=$.find(v=>v.path==="mcp.json"||v.path.endsWith("/mcp.json"));if(!f)throw new Error("Downloaded MCP package missing mcp.json");const w=JSON.parse(f.content.toString()),{getAgentRoot:I}=await import("./agentpack/paths.js"),g=I(s,r.label),D=path.join(g,"mcp"),M=path.join(D,".mcp.json");await fs_1.promises.mkdir(D,{recursive:!0});let b={mcpServers:{}};try{const v=await fs_1.promises.readFile(M,"utf-8");b=JSON.parse(v),b.mcpServers||(b.mcpServers={})}catch{}b.mcpServers[d.slug]={transport:w.transport||"stdio",command:w.command,args:w.args,env:w.env,url:w.url,npmPackage:w.npmPackage,_version:d.version,_description:w.description},await fs_1.promises.writeFile(M,JSON.stringify(b,null,2));for(const v of $)if(v.path!=="mcp.json"&&!v.path.endsWith("/mcp.json")){const N=path.join(D,d.slug,v.path);await fs_1.promises.mkdir(path.dirname(N),{recursive:!0}),await fs_1.promises.writeFile(N,v.content)}});const{getRegistry:p}=await import("./registry/index.js");await p(e).registerMcp({slug:d.slug,displayName:d.slug,transport:"stdio",latestVersion:d.version||"main",tags:[],stats:{installs:1},agentPackId:r.label});const{invalidateLocalIndex:k}=await import("./store/oramaIndex.js");k(),showInfo(`Installed MCP "${d.slug}" v${d.version} to ${r.label}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.install",async n=>{const{downloadFromStore:s,downloadFromExternalGitHub:l,listStoreVersions:i,isStoreUrl:c,parseGitHubUrl:u,parseStoreUrl:d}=await import("./store/index.js"),{installCustomEngineFromFiles:o}=await import("./engines/install.js");let r=n;if(!r){const f=await vscode.window.showInputBox({prompt:"Enter custom engine store URL or GitHub URL",placeHolder:"e.g., engine/gemini or https://github.com/user/repo/tree/main/gemini"});if(!f)return;if(c(f))r=d(f);else{const w=u(f),I=(w.path||w.repo).split("/");r={type:"engine",slug:I[I.length-1]||w.repo,version:w.ref,sourceUrl:f}}}const p=r.sourceUrl&&!c(r.sourceUrl);if(!r.version&&!p){const f=await i("engine",r.slug);if(f.length===0)r.version="main";else{const w=await vscode.window.showQuickPick(f.map(I=>({label:I.version,description:I.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!w)return;r.version=w.label}}const S=async f=>await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing engine "${r.slug}"`,cancellable:!1},async w=>{let I;if(p&&r.sourceUrl){w.report({message:"Downloading from GitHub..."});const g=u(r.sourceUrl);I=await l({owner:g.owner,repo:g.repo,ref:g.ref||"main",path:g.path},e)}else w.report({message:"Downloading from store..."}),I=await s({type:"engine",slug:r.slug,version:r.version},e);return w.report({message:"Validating and installing..."}),await o(I,{slug:r.slug,version:r.version,sourceUrl:r.sourceUrl,overwrite:f,logger:e})});let k;try{k=await S(!1)}catch(f){const w=f instanceof Error?f.message:String(f);if(!w.includes("already exists")){log(e,`[AgentIDE] Engine install error: ${w}`),showError(`AgentIDE: ${w}`);return}if(await vscode.window.showWarningMessage(w,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;try{k=await S(!0)}catch(g){const D=g instanceof Error?g.message:String(g);log(e,`[AgentIDE] Engine install error: ${D}`),showError(`AgentIDE: ${D}`);return}}const{invalidateLocalIndex:A}=await import("./store/oramaIndex.js");if(A(),!k)return;clearCustomEngineRuntimeCache(a,k.id),await refreshCustomEnginePicker(e),await vscode.window.showInformationMessage(`Installed engine "${k.displayName}"`,"List Engines")==="List Engines"&&await vscode.commands.executeCommand("agentide.customEngine.list")})),t.subscriptions.push(vscode.commands.registerCommand("agentide.view.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:l,downloadFromExternalGitHub:i,listStoreVersions:c,isStoreUrl:u,parseGitHubUrl:d,parseStoreUrl:o}=await import("./store/index.js"),{installSpotlightViewFromFiles:r}=await import("./spotlight/install.js");let p=n;if(!p){const I=await vscode.window.showInputBox({prompt:"Enter Spotlight view store URL or GitHub URL",placeHolder:"e.g., view/cost-ops or https://github.com/user/repo/tree/main/spotlight/cost-ops"});if(!I)return;if(u(I))p=o(I);else{const g=d(I),D=(g.path||g.repo).split("/");p={type:"view",slug:D[D.length-1]||g.repo,version:g.ref,sourceUrl:I}}}const S=p.sourceUrl&&!u(p.sourceUrl);if(!p.version&&!S){const I=await c("view",p.slug);if(I.length===0)p.version="main";else{const g=await vscode.window.showQuickPick(I.map(D=>({label:D.version,description:D.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!g)return;p.version=g.label}}const k=async(I,g)=>await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing Spotlight view "${p.slug}"`,cancellable:!1},async D=>{let M;if(S&&p.sourceUrl){D.report({message:"Downloading from GitHub..."});const b=d(p.sourceUrl);M=(await i({owner:b.owner,repo:b.repo,ref:b.ref||"main",path:b.path},e)).map(N=>({path:N.path,content:N.content}))}else D.report({message:"Downloading from store..."}),M=await l({type:"view",slug:p.slug,version:p.version},e);return D.report({message:"Installing view..."}),await r(M,{slug:p.slug,version:p.version,overwrite:I,activate:g,workspaceRoot:s,logger:e})});let A;try{A=await k(!1,!1)}catch(I){const g=I instanceof Error?I.message:String(I);if(!g.includes("already exists")){log(e,`[AgentIDE] Spotlight view install error: ${g}`),showError(`AgentIDE: ${g}`);return}if(await vscode.window.showWarningMessage(g,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;try{A=await k(!0,!1)}catch(M){const b=M instanceof Error?M.message:String(M);log(e,`[AgentIDE] Spotlight view install error: ${b}`),showError(`AgentIDE: ${b}`);return}}const{invalidateLocalIndex:$}=await import("./store/oramaIndex.js");if($(),!A)return;const f=_state?.analyticsDashboard;f&&await f.refreshViewsFromDisk();const w=await vscode.window.showInformationMessage(`Installed Spotlight view "${A.id}" v${A.version||p.version||"main"}`,"Open Spotlight","Activate View");if(w==="Open Spotlight")await vscode.commands.executeCommand("agentide.analytics.openDashboard");else if(w==="Activate View"){const{setActiveSpotlightView:I}=await import("./spotlight/install.js");await I(A.viewsConfigPath,A.id);const g=_state?.analyticsDashboard;g&&await g.refreshViewsFromDisk(),await vscode.commands.executeCommand("agentide.analytics.openDashboard")}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.update",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e),i=await l.listInstalledWithCleanup(),c=[];for(const r of i){if(r.id==="default")continue;const p=await l.checkAgentUpdate(r.id);p&&c.push({id:r.id,version:r.version,newVersion:p})}if(c.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: All agents are up to date`);return}const u=c.map(r=>({label:r.id,description:`v${r.version} \u2192 v${r.newVersion}`})),d=await vscode.window.showQuickPick(u,{placeHolder:"Select an agent to update",title:"Update Agent from User Library"});if(!(!d||await vscode.window.showWarningMessage(`Update "${d.label}" from User Library? Current version will be backed up.`,{modal:!0},"Update","Cancel")!=="Update"))try{const r=await l.updateFromLibrary(d.label);showInfo(`AgentIDE: Updated "${d.label}" to v${r}`)}catch(r){const p=r instanceof Error?r.message:String(r);log(e,`[AgentIDE] Update error: ${p}`),showError(`AgentIDE: ${p}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.duplicate",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e),i=await l.listInstalledWithCleanup();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to duplicate`);return}const c=i.map(d=>({label:d.id,description:`v${d.version}`})),u=await vscode.window.showQuickPick(c,{placeHolder:"Select an agent to duplicate",title:"Duplicate Agent"});if(u)try{const d=await l.duplicate(u.label);showInfo(`AgentIDE: Created "${d}" as copy of "${u.label}"`);const o=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,d,paths_1.AGENT_CONSTANTS.AGENTS_MD);if(await(0,utils_1.pathExists)(o)){const r=await vscode.workspace.openTextDocument(o);await vscode.window.showTextDocument(r)}}catch(d){const o=d instanceof Error?d.message:String(d);log(e,`[AgentIDE] Duplicate error: ${o}`),showError(`AgentIDE: ${o}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.refresh",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),l=new s(m,()=>n,()=>E.storagePath,e);try{const{registered:i}=await l.repairUnregisteredAgents();return i.length>0?showInfo(`AgentIDE: Discovered ${i.length} new pack(s): ${i.join(", ")}`):showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No new packs found`),{registered:i}}catch(i){const c=i instanceof Error?i.message:String(i);return log(e,`[AgentIDE] Pack refresh error: ${c}`),showError(`AgentIDE: ${c}`),{registered:[]}}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.resetDefault",async()=>{if(await vscode.window.showWarningMessage("Reset the default agent? This will restore it from bundled templates. Current default agent will be backed up.",{modal:!0},"Reset","Cancel")!=="Reset")return;const{workspaceRoot:s}=getWorkspaceRoot(e),{AgentPackManager:l}=await import("./agentpack/index.js"),i=new l(m,()=>s,()=>E.storagePath,e);try{await i.resetDefault(getBundledBasePromptsDir()),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Default agent reset from bundled templates`),await m.flushAgentideRootUpdate(s,e,{force:!0,allowDuringActiveTurn:!0})}catch(c){const u=c instanceof Error?c.message:String(c);log(e,`[AgentIDE] Reset error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat",async n=>handleChatCommand(a,n))),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat.cancel",async n=>{const s=n?.streamId;if(!s)return{cancelled:!1,error:"streamId is required"};const l=_activeRunsByStreamId.get(s);if(!l)return log(e,`[AgentIDE] Cancel ignored: no active run for streamId=${s}`),rejectPendingQuestionsForStream(s,"Run cancelled"),{cancelled:!1};log(e,`[AgentIDE] Cancel requested: streamId=${s}, engine=${l.engine}, ageMs=${Date.now()-l.startedAt}`);try{l.abortController.abort()}catch{}return rejectPendingQuestionsForStream(s,"Run cancelled"),{cancelled:!0}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat.answerQuestion",async n=>{const s=n?.streamId,l=n?.questionId;if(!s||!l)return{ok:!1,error:"streamId and questionId are required"};const i=_pendingQuestionsById.get(l);if(!i||i.streamId!==s)return{ok:!1,error:"Question not found or already resolved"};const c=normalizeQuestionAnswer(n?.answer);return resolvePendingQuestion(l,c),{ok:!0}}))}function getUserPermissions(){return{fileAccess:vscode.workspace.getConfiguration("agentide").get("permissions.fileAccess","full")}}function getConfiguredAdditionalEngineDir(){return vscode.workspace.getConfiguration("agentide").get("additionalEngineDir")}function clearCustomEngineRuntimeCache(t,a){const e=t.engines.custom;try{e?.clearInstances?.(a)}catch(m){log(t.outputChannel,`[AgentIDE] Custom engine cache clear warning: ${m instanceof Error?m.message:String(m)}`)}}async function refreshCustomEnginePicker(t){try{await vscode.commands.executeCommand("agentide.engine.refresh")}catch(a){log(t,`[AgentIDE] Custom engine picker refresh warning: ${a instanceof Error?a.message:String(a)}`)}}const _sessionEventWriter=new sessionEvents_1.SessionEventWriter;async function handleChatCommand(t,a){const{outputChannel:e,engines:m,syncService:E,config:h}=t,{engine:C,streamId:y}=a;let{message:T}=a;const n=a.options??{};let s;const l=T.match(/^\[gw:(gw-[^\]]+)\]/);if(l){const P=l[1];T=T.slice(l[0].length),log(e,`[AgentIDE] Gateway request detected, token=${P.slice(0,20)}...`);const{GatewayService:_}=await import("./gateway/service.js");s=_.getGatewayEmitter(P),s?log(e,"[AgentIDE] Gateway emitter found, will stream to both Chat UI and Gateway"):log(e,`[AgentIDE] Gateway emitter NOT found for token ${P.slice(0,20)}...`)}const{workspaceRoot:i,additionalDirectories:c,isHomeFallback:u}=getWorkspaceRoot(e,n.workspaceRoot,n.additionalDirectories);y&&u&&await warnHomeFallbackOnce(e,y);const d=await E.getActiveAgentManifest(i,e,E.getActivePackId(i)??t.activePackId),o=d?.spec?.remote?.url?.trim();if(o)return(0,handleRemoteChat_js_1.handleRemoteServeChat)({outputChannel:e,syncService:E,sessionEventWriter:_sessionEventWriter,activeRunsByStreamId:_activeRunsByStreamId,rejectPendingQuestionsForStream,askQuestionViaWorkbenchTool,askQuestionFromChatUI,getServeAuth:async()=>{if(!_extensionContext)return;const P=await(0,provider_js_1.getAgentHippoAccessToken)(_extensionContext);if(P)return{accessToken:P.accessToken,userEmail:P.email}},ensureSignedIn:async()=>{if(!_extensionContext)return;const P=await(0,signInFlow_js_1.ensureAgentHippoSignedIn)(_extensionContext);if(P)return{accessToken:P.accessToken,userEmail:P.email}},log},{engine:C,message:T,options:a.options,streamId:y,sessionResource:a.sessionResource,requestId:a.requestId,remoteUrl:o,remoteManifest:d,workspaceRoot:i,incomingOptions:n,gatewayEmitter:s});let r={...n,workspaceRoot:i,additionalDirectories:c,agentPackId:t.activePackId};if(!y)return{error:"streamId is required - non-streaming mode is no longer supported"};let p=C,S=m[p];if(!S&&p!=="codex"&&p!=="claude"&&m.custom&&(r={...r,engineId:r.engineId??p},p="custom",S=m.custom,log(e,`[AgentIDE] Routing requested engine "${C}" through custom runtime loader`)),!S){const P=`Unknown engine: ${C}`;return log(e,`[AgentIDE] Error: ${P}`),{error:P}}log(e,`[AgentIDE] Chat request for engine=${C} (runtime=${p}), streamId: ${y}, useLiteLLM: ${r.useLiteLLM||!1}`);const k=new AbortController;_activeRunsByStreamId.set(y,{streamId:y,engine:p,startedAt:Date.now(),abortController:k});const A=(0,utils_1.createIPCStreamEmitter)(y),$=a.sessionResource,f=a.requestId,w={...A,async question(P){return $?await askQuestionViaWorkbenchTool($,f,P,k.signal):await askQuestionFromChatUI(y,P)}},I=s?{...w,async thinking(P){await A.thinking(P),await s.thinking(`<thinking>${P}</thinking>`)},async text(P){await A.text(P),await s.text(P)},async toolStart(P,_,L,x){await A.toolStart(P,_,L,x),await s.toolStart(P,_,L,x)},async toolEnd(P,_,L,x,U){await A.toolEnd(P,_,L,x,U),await s.toolEnd(P,_,L,x,U)},async progress(P){await A.progress(P),await s.progress(P)},async question(P){const _=await w.question(P);return await s.progress(`Question answered: ${questionPromptToHeader(P.prompt)}`),_},async error(P){await A.error(P),await s.error(P)},async done(){await A.done(),await s.done()}}:w,g=getTerminalLogInfo(r);await appendTerminalAttachmentsToLog(a.context,y,e,g?.uri),await persistImageAttachments(a.context,r,e),await persistFileAndDirectoryAttachments(a.context,r,e);const D=formatSdkContextSuffix(a.context,g?.relativePath),M=D?`${T}
22
+ This will create a pull request from your fork.`,{modal:!0},"Submit PR")!=="Submit PR")return;const N=await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Publishing Spotlight view ${$.id} v${I}`,cancellable:!1},async P=>(P.report({message:b?`Publishing to ${a.owner}/${a.repo}...`:"Preparing fork..."}),await o({type:"view",slug:$.id,version:I,files:D,changelog:g},e)));await vscode.window.showInformationMessage(`Published Spotlight view "${$.name}" v${I}! PR created.`,"View PR")==="View PR"&&vscode.env.openExternal(vscode.Uri.parse(N.prUrl))}catch(f){const w=f instanceof Error?f.message:String(f);log(e,`[AgentIDE] Spotlight publish error: ${w}`),showError(`${branding_1.AGENTIDE_BRAND_NAME}: ${w}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.install",async n=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{parseStoreUrl:s}=await import("./store/index.js");let c=n;if(c||(c=await vscode.window.showInputBox({prompt:"Enter store URL or GitHub link",placeHolder:"e.g., engine/gemini or https://github.com/.../engines/gemini",validateInput:i=>i.trim()?i.includes("/")?null:"Expected: type/slug, or GitHub URL":"Please enter a URL"})),!!c)try{const i=s(c);switch(i.type){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",i);break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",i);break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",i);break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",i);break;case"view":await vscode.commands.executeCommand("agentide.view.install",i);break}}catch(i){const l=i instanceof Error?i.message:String(i);log(e,`[AgentIDE] Store install error: ${l}`),showError(`AgentIDE: ${l}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.find",async n=>{await(0,githubStoreGate_js_1.ensureGitHubStoreAccess)(t);const{isStoreUrl:s,parseStoreUrl:c,parseGitHubUrl:i,detectArtifactType:l}=await import("./store/index.js"),{searchMerged:u,listMergedArtifacts:d}=await import("./store/oramaIndex.js");let o,a="all";if(typeof n=="string"?o=n:n&&typeof n=="object"&&n.typeFilter&&(a=n.typeFilter),o)try{let b,v,N;if(s(o)){const R=c(o);b=R.type,v=R.slug,N=R.version}else{const R=i(o);b=await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:"Detecting artifact type...",cancellable:!1},async()=>await l(R.owner,R.repo,R.ref,R.path,e));const P=(R.path||R.repo).split("/");v=P[P.length-1]||R.repo,N=R.ref}switch(b){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",{type:"pack",slug:v,version:N,sourceUrl:o});break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",{type:"skill",slug:v,version:N,sourceUrl:o});break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",{type:"mcp",slug:v,version:N,sourceUrl:o});break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",{type:"engine",slug:v,version:N,sourceUrl:o});break;case"view":await vscode.commands.executeCommand("agentide.view.install",{type:"view",slug:v,version:N,sourceUrl:o});break}return}catch(b){const v=b instanceof Error?b.message:String(b);log(e,`[AgentIDE] Install error: ${v}`),showError(`AgentIDE: ${v}`);return}const{STORE_ICONS:p}=await import("./store/shared.js"),S={pack:p.pack,skill:p.skill,mcp:p.mcp,engine:p.engine,view:p.view},k=["all","pack","skill","mcp","engine","view"],y=vscode.window.createQuickPick();y.title=a==="view"?"Install Spotlight View":"Install Packs, Skills, MCP Tools, Engines, Spotlight Views",y.placeholder="Search or paste a GitHub URL to install...",y.matchOnDescription=!0,y.matchOnDetail=!0,y.busy=!0;let $=[],f=a,w;const I={local:p.local,remote:p.remote},g=b=>{const v=b??$,N=f==="all"?v:v.filter(_=>_.type===f),R=k.map(_=>({label:_==="all"?"$(list-flat) All":`${S[_]} ${_.charAt(0).toUpperCase()+_.slice(1)}s`,description:_===f?"$(check)":"",alwaysShow:!0,itemType:"filter",filter:_})),P=N.map(_=>{const L=_.source==="local"?I.local:I.remote,x=_.installed?"$(check)":"",U=[_.source==="local"?"Local":"Remote",_.type];x&&U.push(x);let O=_.description||_.path;return _.installedTo&&_.installedTo.length>0&&(O+=` \u2022 Installed to: ${_.installedTo.join(", ")}`),{label:`${L} ${S[_.type]} ${_.slug}`,description:U.join(" \u2022 "),detail:O,itemType:"artifact",artifact:_}});y.items=[...R,{label:"",kind:vscode.QuickPickItemKind.Separator,itemType:"filter"},...P]},D=async b=>{w&&clearTimeout(w);const v=b.trim();if(!v||v.startsWith("http")||v.startsWith("store://")||v.startsWith("github.com")){g($);return}w=setTimeout(async()=>{try{const P=(await u(v,{type:f==="all"?void 0:f,limit:50},e)).map(_=>({type:_.type,slug:_.slug,path:`${_.type}s/${_.slug}`,description:_.description,installed:_.installed,installedVersion:_.installedVersion,source:_.source,installedTo:_.installedTo}));g(P)}catch(N){log(e,`[AgentIDE] Search error: ${N instanceof Error?N.message:String(N)}`),g($)}},150)};y.onDidChangeValue(D);try{$=(await d(void 0,e)).map(v=>({type:v.type,slug:v.slug,path:`${v.type}s/${v.slug}`,description:v.description,installed:v.installed,installedVersion:v.installedVersion,source:v.source,installedTo:v.installedTo})),y.busy=!1,g(),$.length===0&&(y.placeholder="Store is empty or index not synced yet. Try again later!")}catch(b){const v=b instanceof Error?b.message:String(b);log(e,`[AgentIDE] Store browse error: ${v}`),y.hide(),showError(`AgentIDE: ${v}`);return}const M=b=>{const v=b.trim();return v.startsWith("https://")||v.startsWith("http://")||v.startsWith("github.com/")||v.startsWith("store://")};y.onDidAccept(async()=>{const b=y.selectedItems[0],v=y.value.trim();if(v&&M(v)){y.hide(),log(e,`[AgentIDE] Browse Store: detected URL input: ${v}`),await vscode.commands.executeCommand("agentide.store.find",v);return}if(b){if(b.itemType==="filter"&&b.filter){f=b.filter,g();return}if(b.itemType==="artifact"&&b.artifact){y.hide();const{artifact:N}=b;switch(N.type){case"pack":await vscode.commands.executeCommand("agentide.pack.storeInstall",{type:"pack",slug:N.slug});break;case"skill":await vscode.commands.executeCommand("agentide.skill.install",{type:"skill",slug:N.slug});break;case"mcp":await vscode.commands.executeCommand("agentide.mcp.install",{type:"mcp",slug:N.slug});break;case"engine":await vscode.commands.executeCommand("agentide.engine.install",{type:"engine",slug:N.slug});break;case"view":await vscode.commands.executeCommand("agentide.view.install",{type:"view",slug:N.slug});break}}}}),y.onDidHide(()=>y.dispose()),y.show()})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.search",async(n,s)=>{const{searchMerged:c}=await import("./store/oramaIndex.js");return c(n,s,e)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.sync",async()=>{const{forceRefresh:n,getIndexMeta:s}=await import("./store/oramaIndex.js");await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:"Syncing store index...",cancellable:!1},async()=>{await n(e)});const c=await s();c&&showInfo(`Store index synced: ${c.artifactCount} artifacts (updated ${new Date(c.generatedAt).toLocaleDateString()})`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.store.setup",async()=>{const{setupStoreAutomation:n}=await import("./store/github/setup.js"),s=await vscode.window.showInputBox({prompt:"Enter GitHub repository URL for your store",placeHolder:"https://github.com/owner/repo or owner/repo",validateInput:o=>o?o.match(/(?:github\.com\/)?([^/]+)\/([^/]+)/)?null:"Invalid format. Use: owner/repo or https://github.com/owner/repo":"Repository URL is required"});if(!s)return;const c=s.match(/(?:github\.com\/)?([^/]+)\/([^/]+)/);if(!c){showError("Invalid repository URL");return}const[,i,l]=c,u=l.replace(/\.git$/,""),d=await vscode.window.withProgress({location:vscode.ProgressLocation.Notification,title:`Setting up store automation for ${i}/${u}...`,cancellable:!1},async()=>await n(i,u,e));if(d.success&&d.pullRequestUrl){const o=vscode.workspace.getConfiguration("agentide"),a=`${i}/${u}`,p=o.get("storeRepo",""),S=o.get("store.indexUrl",""),k=`https://${i}.github.io/${u}`;let y="";if(p){const f=p.match(/^(?:https?:\/\/github\.com\/)?([^/]+)\/([^/]+?)(?:\.git)?$/);f&&(y=`https://${f[1]}.github.io/${f[2]}`)}await o.update("storeRepo",a,vscode.ConfigurationTarget.Global),(!S||y&&S===y)&&await o.update("store.indexUrl",k,vscode.ConfigurationTarget.Global);const $=await vscode.window.showInformationMessage(`\u{1F99B} ${d.message}`,"Open Pull Request","Copy URL");$==="Open Pull Request"?await vscode.env.openExternal(vscode.Uri.parse(d.pullRequestUrl)):$==="Copy URL"&&(await vscode.env.clipboard.writeText(d.pullRequestUrl),showInfo("Pull request URL copied to clipboard"))}else d.success||showError(`Setup failed: ${d.message}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.storeInstall",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:c,listStoreVersions:i}=await import("./store/index.js"),{getAgentRoot:l}=await import("./agentpack/paths.js"),u=n||{type:"pack",slug:"",version:void 0};if(!u.version){const y=await i("pack",u.slug);if(y.length===0)u.version="main";else{const $=await vscode.window.showQuickPick(y.map(f=>({label:f.version,description:f.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!$)return;u.version=$.label}}const d=l(s,u.slug);if(await fs_1.promises.access(d).then(()=>!0).catch(()=>!1)){if(await vscode.window.showWarningMessage(`Pack "${u.slug}" already exists. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(d,{recursive:!0,force:!0})}await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing pack "${u.slug}"`,cancellable:!1},async y=>{y.report({message:"Downloading from store..."});const $=await c({type:"pack",slug:u.slug,version:u.version},e);y.report({message:"Extracting files..."}),await fs_1.promises.mkdir(d,{recursive:!0});for(const f of $){const w=path.join(d,f.path);await fs_1.promises.mkdir(path.dirname(w),{recursive:!0}),await fs_1.promises.writeFile(w,f.content)}}),await vscode.commands.executeCommand("agentide.packsChanged");const{getRegistry:a}=await import("./registry/index.js");await a(e).registerPack({slug:u.slug,displayName:u.slug,latestVersion:u.version||"main",tags:[],stats:{installs:1,stars:0}});const{invalidateLocalIndex:S}=await import("./store/oramaIndex.js");S(),await vscode.window.showInformationMessage(`Installed pack "${u.slug}" v${u.version}`,"Activate")==="Activate"&&await vscode.commands.executeCommand("agentide.pack.switch",u.slug)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.skill.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:c,downloadFromExternalGitHub:i,listStoreVersions:l,isStoreUrl:u,parseGitHubUrl:d}=await import("./store/index.js"),{AgentPackManager:o}=await import("./agentpack/index.js"),a=new o(m,()=>s,()=>E.storagePath,e);let p=n;if(!p){const b=await vscode.window.showInputBox({prompt:"Enter skill store URL or GitHub URL",placeHolder:"e.g., skills/typescript-testing@v1.0.0 or https://github.com/user/repo"});if(!b)return;const{parseStoreUrl:v}=await import("./store/index.js");p=v(b)}const S=p.sourceUrl&&!u(p.sourceUrl);if(!p.version&&!S){const b=await l("skill",p.slug);if(b.length===0)p.version="main";else{const v=await vscode.window.showQuickPick(b.map(N=>({label:N.version,description:N.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!v)return;p.version=v.label}}const k=await a.listInstalledWithCleanup();if(k.length===0){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found. Create an agent first.`);return}const y=await vscode.window.showQuickPick(k.map(b=>({label:b.id,description:`v${b.version}`})),{placeHolder:"Select agent to install skill to"});if(!y)return;const{getAgentRoot:$}=await import("./agentpack/paths.js"),f=$(s,y.label),w=path.join(f,"skills",p.slug);if(await fs_1.promises.access(w).then(()=>!0).catch(()=>!1)){if(await vscode.window.showWarningMessage(`Skill "${p.slug}" already exists in ${y.label}. Overwrite?`,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;await fs_1.promises.rm(w,{recursive:!0,force:!0})}await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing skill "${p.slug}"`,cancellable:!1},async b=>{let v;if(S&&p.sourceUrl){b.report({message:"Downloading from GitHub..."});const N=d(p.sourceUrl);v=await i({owner:N.owner,repo:N.repo,ref:N.ref||"main",path:N.path},e)}else b.report({message:"Downloading from store..."}),v=await c({type:"skill",slug:p.slug,version:p.version},e);b.report({message:"Extracting files..."}),await fs_1.promises.mkdir(w,{recursive:!0});for(const N of v){const R=path.join(w,N.path);await fs_1.promises.mkdir(path.dirname(R),{recursive:!0}),await fs_1.promises.writeFile(R,N.content)}});const{getRegistry:g}=await import("./registry/index.js");await g(e).registerSkill({slug:p.slug,displayName:p.slug,latestVersion:p.version||"main",tags:[],stats:{installs:1},agentPackId:y.label});const{invalidateLocalIndex:M}=await import("./store/oramaIndex.js");M(),showInfo(`Installed skill "${p.slug}" to ${y.label}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.mcp.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:c,listStoreVersions:i}=await import("./store/index.js"),{AgentPackManager:l}=await import("./agentpack/index.js"),u=new l(m,()=>s,()=>E.storagePath,e);let d=n;if(!d){const y=await vscode.window.showInputBox({prompt:"Enter MCP store URL",placeHolder:"e.g., mcp/github@v1.0.0"});if(!y)return;const{parseStoreUrl:$}=await import("./store/index.js");d=$(y)}if(!d.version){const y=await i("mcp",d.slug);if(y.length===0)d.version="main";else{const $=await vscode.window.showQuickPick(y.map(f=>({label:f.version,description:f.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!$)return;d.version=$.label}}const o=await u.listInstalledWithCleanup();if(o.length===0){showError(`${branding_1.AGENTIDE_BRAND_NAME}: No agents found. Create an agent first.`);return}const a=await vscode.window.showQuickPick(o.map(y=>({label:y.id,description:`v${y.version}`})),{placeHolder:"Select agent to add MCP server to"});if(!a)return;await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing MCP "${d.slug}"`,cancellable:!1},async y=>{y.report({message:"Downloading from store..."});const $=await c({type:"mcp",slug:d.slug,version:d.version},e);y.report({message:"Merging MCP config..."});const f=$.find(v=>v.path==="mcp.json"||v.path.endsWith("/mcp.json"));if(!f)throw new Error("Downloaded MCP package missing mcp.json");const w=JSON.parse(f.content.toString()),{getAgentRoot:I}=await import("./agentpack/paths.js"),g=I(s,a.label),D=path.join(g,"mcp"),M=path.join(D,".mcp.json");await fs_1.promises.mkdir(D,{recursive:!0});let b={mcpServers:{}};try{const v=await fs_1.promises.readFile(M,"utf-8");b=JSON.parse(v),b.mcpServers||(b.mcpServers={})}catch{}b.mcpServers[d.slug]={transport:w.transport||"stdio",command:w.command,args:w.args,env:w.env,url:w.url,npmPackage:w.npmPackage,_version:d.version,_description:w.description},await fs_1.promises.writeFile(M,JSON.stringify(b,null,2));for(const v of $)if(v.path!=="mcp.json"&&!v.path.endsWith("/mcp.json")){const N=path.join(D,d.slug,v.path);await fs_1.promises.mkdir(path.dirname(N),{recursive:!0}),await fs_1.promises.writeFile(N,v.content)}});const{getRegistry:p}=await import("./registry/index.js");await p(e).registerMcp({slug:d.slug,displayName:d.slug,transport:"stdio",latestVersion:d.version||"main",tags:[],stats:{installs:1},agentPackId:a.label});const{invalidateLocalIndex:k}=await import("./store/oramaIndex.js");k(),showInfo(`Installed MCP "${d.slug}" v${d.version} to ${a.label}`)})),t.subscriptions.push(vscode.commands.registerCommand("agentide.engine.install",async n=>{const{downloadFromStore:s,downloadFromExternalGitHub:c,listStoreVersions:i,isStoreUrl:l,parseGitHubUrl:u,parseStoreUrl:d}=await import("./store/index.js"),{installCustomEngineFromFiles:o}=await import("./engines/install.js");let a=n;if(!a){const f=await vscode.window.showInputBox({prompt:"Enter custom engine store URL or GitHub URL",placeHolder:"e.g., engine/gemini or https://github.com/user/repo/tree/main/gemini"});if(!f)return;if(l(f))a=d(f);else{const w=u(f),I=(w.path||w.repo).split("/");a={type:"engine",slug:I[I.length-1]||w.repo,version:w.ref,sourceUrl:f}}}const p=a.sourceUrl&&!l(a.sourceUrl);if(!a.version&&!p){const f=await i("engine",a.slug);if(f.length===0)a.version="main";else{const w=await vscode.window.showQuickPick(f.map(I=>({label:I.version,description:I.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!w)return;a.version=w.label}}const S=async f=>await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing engine "${a.slug}"`,cancellable:!1},async w=>{let I;if(p&&a.sourceUrl){w.report({message:"Downloading from GitHub..."});const g=u(a.sourceUrl);I=await c({owner:g.owner,repo:g.repo,ref:g.ref||"main",path:g.path},e)}else w.report({message:"Downloading from store..."}),I=await s({type:"engine",slug:a.slug,version:a.version},e);return w.report({message:"Validating and installing..."}),await o(I,{slug:a.slug,version:a.version,sourceUrl:a.sourceUrl,overwrite:f,logger:e})});let k;try{k=await S(!1)}catch(f){const w=f instanceof Error?f.message:String(f);if(!w.includes("already exists")){log(e,`[AgentIDE] Engine install error: ${w}`),showError(`AgentIDE: ${w}`);return}if(await vscode.window.showWarningMessage(w,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;try{k=await S(!0)}catch(g){const D=g instanceof Error?g.message:String(g);log(e,`[AgentIDE] Engine install error: ${D}`),showError(`AgentIDE: ${D}`);return}}const{invalidateLocalIndex:y}=await import("./store/oramaIndex.js");if(y(),!k)return;clearCustomEngineRuntimeCache(r,k.id),await refreshCustomEnginePicker(e),await vscode.window.showInformationMessage(`Installed engine "${k.displayName}"`,"List Engines")==="List Engines"&&await vscode.commands.executeCommand("agentide.customEngine.list")})),t.subscriptions.push(vscode.commands.registerCommand("agentide.view.install",async n=>{const{workspaceRoot:s}=getWorkspaceRoot(e),{downloadFromStore:c,downloadFromExternalGitHub:i,listStoreVersions:l,isStoreUrl:u,parseGitHubUrl:d,parseStoreUrl:o}=await import("./store/index.js"),{installSpotlightViewFromFiles:a}=await import("./spotlight/install.js");let p=n;if(!p){const I=await vscode.window.showInputBox({prompt:"Enter Spotlight view store URL or GitHub URL",placeHolder:"e.g., view/cost-ops or https://github.com/user/repo/tree/main/spotlight/cost-ops"});if(!I)return;if(u(I))p=o(I);else{const g=d(I),D=(g.path||g.repo).split("/");p={type:"view",slug:D[D.length-1]||g.repo,version:g.ref,sourceUrl:I}}}const S=p.sourceUrl&&!u(p.sourceUrl);if(!p.version&&!S){const I=await l("view",p.slug);if(I.length===0)p.version="main";else{const g=await vscode.window.showQuickPick(I.map(D=>({label:D.version,description:D.isPrerelease?"(pre-release)":""})),{placeHolder:"Select version to install"});if(!g)return;p.version=g.label}}const k=async(I,g)=>await vscode.window.withProgress({location:vscode.ProgressLocation.Window,title:`Installing Spotlight view "${p.slug}"`,cancellable:!1},async D=>{let M;if(S&&p.sourceUrl){D.report({message:"Downloading from GitHub..."});const b=d(p.sourceUrl);M=(await i({owner:b.owner,repo:b.repo,ref:b.ref||"main",path:b.path},e)).map(N=>({path:N.path,content:N.content}))}else D.report({message:"Downloading from store..."}),M=await c({type:"view",slug:p.slug,version:p.version},e);return D.report({message:"Installing view..."}),await a(M,{slug:p.slug,version:p.version,overwrite:I,activate:g,workspaceRoot:s,logger:e})});let y;try{y=await k(!1,!1)}catch(I){const g=I instanceof Error?I.message:String(I);if(!g.includes("already exists")){log(e,`[AgentIDE] Spotlight view install error: ${g}`),showError(`AgentIDE: ${g}`);return}if(await vscode.window.showWarningMessage(g,{modal:!0},"Overwrite","Cancel")!=="Overwrite")return;try{y=await k(!0,!1)}catch(M){const b=M instanceof Error?M.message:String(M);log(e,`[AgentIDE] Spotlight view install error: ${b}`),showError(`AgentIDE: ${b}`);return}}const{invalidateLocalIndex:$}=await import("./store/oramaIndex.js");if($(),!y)return;const f=_state?.analyticsDashboard;f&&await f.refreshViewsFromDisk();const w=await vscode.window.showInformationMessage(`Installed Spotlight view "${y.id}" v${y.version||p.version||"main"}`,"Open Spotlight","Activate View");if(w==="Open Spotlight")await vscode.commands.executeCommand("agentide.analytics.openDashboard");else if(w==="Activate View"){const{setActiveSpotlightView:I}=await import("./spotlight/install.js");await I(y.viewsConfigPath,y.id);const g=_state?.analyticsDashboard;g&&await g.refreshViewsFromDisk(),await vscode.commands.executeCommand("agentide.analytics.openDashboard")}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.update",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e),i=await c.listInstalledWithCleanup(),l=[];for(const a of i){if(a.id==="default")continue;const p=await c.checkAgentUpdate(a.id);p&&l.push({id:a.id,version:a.version,newVersion:p})}if(l.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: All agents are up to date`);return}const u=l.map(a=>({label:a.id,description:`v${a.version} \u2192 v${a.newVersion}`})),d=await vscode.window.showQuickPick(u,{placeHolder:"Select an agent to update",title:"Update Agent from User Library"});if(!(!d||await vscode.window.showWarningMessage(`Update "${d.label}" from User Library? Current version will be backed up.`,{modal:!0},"Update","Cancel")!=="Update"))try{const a=await c.updateFromLibrary(d.label);showInfo(`AgentIDE: Updated "${d.label}" to v${a}`)}catch(a){const p=a instanceof Error?a.message:String(a);log(e,`[AgentIDE] Update error: ${p}`),showError(`AgentIDE: ${p}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.duplicate",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e),i=await c.listInstalledWithCleanup();if(i.length===0){showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No agents to duplicate`);return}const l=i.map(d=>({label:d.id,description:`v${d.version}`})),u=await vscode.window.showQuickPick(l,{placeHolder:"Select an agent to duplicate",title:"Duplicate Agent"});if(u)try{const d=await c.duplicate(u.label);showInfo(`AgentIDE: Created "${d}" as copy of "${u.label}"`);const o=path.join((0,paths_1.getAgentideDir)(n),paths_1.AGENT_CONSTANTS.AGENTS_DIR,d,paths_1.AGENT_CONSTANTS.AGENTS_MD);if(await(0,utils_1.pathExists)(o)){const a=await vscode.workspace.openTextDocument(o);await vscode.window.showTextDocument(a)}}catch(d){const o=d instanceof Error?d.message:String(d);log(e,`[AgentIDE] Duplicate error: ${o}`),showError(`AgentIDE: ${o}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.refresh",async()=>{const{workspaceRoot:n}=getWorkspaceRoot(e),{AgentPackManager:s}=await import("./agentpack/index.js"),c=new s(m,()=>n,()=>E.storagePath,e);try{const{registered:i}=await c.repairUnregisteredAgents();return i.length>0?showInfo(`AgentIDE: Discovered ${i.length} new pack(s): ${i.join(", ")}`):showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: No new packs found`),{registered:i}}catch(i){const l=i instanceof Error?i.message:String(i);return log(e,`[AgentIDE] Pack refresh error: ${l}`),showError(`AgentIDE: ${l}`),{registered:[]}}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.pack.resetDefault",async()=>{if(await vscode.window.showWarningMessage("Reset the default agent? This will restore it from bundled templates. Current default agent will be backed up.",{modal:!0},"Reset","Cancel")!=="Reset")return;const{workspaceRoot:s}=getWorkspaceRoot(e),{AgentPackManager:c}=await import("./agentpack/index.js"),i=new c(m,()=>s,()=>E.storagePath,e);try{await i.resetDefault(getBundledBasePromptsDir()),showInfo(`${branding_1.AGENTIDE_BRAND_NAME}: Default agent reset from bundled templates`),await m.flushAgentideRootUpdate(s,e,{force:!0,allowDuringActiveTurn:!0})}catch(l){const u=l instanceof Error?l.message:String(l);log(e,`[AgentIDE] Reset error: ${u}`),showError(`AgentIDE: ${u}`)}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat",async n=>handleChatCommand(r,n))),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat.cancel",async n=>{const s=n?.streamId;if(!s)return{cancelled:!1,error:"streamId is required"};const c=_activeRunsByStreamId.get(s);if(!c)return log(e,`[AgentIDE] Cancel ignored: no active run for streamId=${s}`),rejectPendingQuestionsForStream(s,"Run cancelled"),{cancelled:!1};log(e,`[AgentIDE] Cancel requested: streamId=${s}, engine=${c.engine}, ageMs=${Date.now()-c.startedAt}`);try{c.abortController.abort()}catch{}return rejectPendingQuestionsForStream(s,"Run cancelled"),{cancelled:!0}})),t.subscriptions.push(vscode.commands.registerCommand("agentide.chat.answerQuestion",async n=>{const s=n?.streamId,c=n?.questionId;if(!s||!c)return{ok:!1,error:"streamId and questionId are required"};const i=_pendingQuestionsById.get(c);if(!i||i.streamId!==s)return{ok:!1,error:"Question not found or already resolved"};const l=normalizeQuestionAnswer(n?.answer);return resolvePendingQuestion(c,l),{ok:!0}}))}function getUserPermissions(){return{fileAccess:vscode.workspace.getConfiguration("agentide").get("permissions.fileAccess","full")}}function getConfiguredAdditionalEngineDir(){return vscode.workspace.getConfiguration("agentide").get("additionalEngineDir")}function clearCustomEngineRuntimeCache(t,r){const e=t.engines.custom;try{e?.clearInstances?.(r)}catch(m){log(t.outputChannel,`[AgentIDE] Custom engine cache clear warning: ${m instanceof Error?m.message:String(m)}`)}}async function refreshCustomEnginePicker(t){try{await vscode.commands.executeCommand("agentide.engine.refresh")}catch(r){log(t,`[AgentIDE] Custom engine picker refresh warning: ${r instanceof Error?r.message:String(r)}`)}}const _sessionEventWriter=new sessionEvents_1.SessionEventWriter;async function handleChatCommand(t,r){const{outputChannel:e,engines:m,syncService:E,config:h}=t,{engine:C,streamId:A}=r;let{message:T}=r;const n=r.options??{};let s;const c=T.match(/^\[gw:(gw-[^\]]+)\]/);if(c){const P=c[1];T=T.slice(c[0].length),log(e,`[AgentIDE] Gateway request detected, token=${P.slice(0,20)}...`);const{GatewayService:_}=await import("./gateway/service.js");s=_.getGatewayEmitter(P),s?log(e,"[AgentIDE] Gateway emitter found, will stream to both Chat UI and Gateway"):log(e,`[AgentIDE] Gateway emitter NOT found for token ${P.slice(0,20)}...`)}const{workspaceRoot:i,additionalDirectories:l,isHomeFallback:u}=getWorkspaceRoot(e,n.workspaceRoot,n.additionalDirectories);A&&u&&await warnHomeFallbackOnce(e,A);const d=await E.getActiveAgentManifest(i,e,E.getActivePackId(i)??t.activePackId),o=d?.spec?.remote?.url?.trim();if(o)return(0,handleRemoteChat_js_1.handleRemoteServeChat)({outputChannel:e,syncService:E,sessionEventWriter:_sessionEventWriter,activeRunsByStreamId:_activeRunsByStreamId,rejectPendingQuestionsForStream,askQuestionViaWorkbenchTool,askQuestionFromChatUI,getServeAuth:async()=>{if(!_extensionContext)return;const P=await(0,provider_js_1.getAgentHippoAccessToken)(_extensionContext);if(P)return{accessToken:P.accessToken,userEmail:P.email}},ensureSignedIn:async()=>{if(!_extensionContext)return;const P=await(0,signInFlow_js_1.ensureAgentHippoSignedIn)(_extensionContext);if(P)return{accessToken:P.accessToken,userEmail:P.email}},log},{engine:C,message:T,options:r.options,streamId:A,sessionResource:r.sessionResource,requestId:r.requestId,remoteUrl:o,remoteManifest:d,workspaceRoot:i,incomingOptions:n,gatewayEmitter:s});let a={...n,workspaceRoot:i,additionalDirectories:l,agentPackId:t.activePackId};if(!A)return{error:"streamId is required - non-streaming mode is no longer supported"};let p=C,S=m[p];if(!S&&p!=="codex"&&p!=="claude"&&m.custom&&(a={...a,engineId:a.engineId??p},p="custom",S=m.custom,log(e,`[AgentIDE] Routing requested engine "${C}" through custom runtime loader`)),!S){const P=`Unknown engine: ${C}`;return log(e,`[AgentIDE] Error: ${P}`),{error:P}}log(e,`[AgentIDE] Chat request for engine=${C} (runtime=${p}), streamId: ${A}, useLiteLLM: ${a.useLiteLLM||!1}`);const k=new AbortController;_activeRunsByStreamId.set(A,{streamId:A,engine:p,startedAt:Date.now(),abortController:k});const y=(0,utils_1.createIPCStreamEmitter)(A),$=r.sessionResource,f=r.requestId,w={...y,async question(P){return $?await askQuestionViaWorkbenchTool($,f,P,k.signal):await askQuestionFromChatUI(A,P)}},I=s?{...w,async thinking(P){await y.thinking(P),await s.thinking(`<thinking>${P}</thinking>`)},async text(P){await y.text(P),await s.text(P)},async toolStart(P,_,L,x){await y.toolStart(P,_,L,x),await s.toolStart(P,_,L,x)},async toolEnd(P,_,L,x,U){await y.toolEnd(P,_,L,x,U),await s.toolEnd(P,_,L,x,U)},async progress(P){await y.progress(P),await s.progress(P)},async question(P){const _=await w.question(P);return await s.progress(`Question answered: ${questionPromptToHeader(P.prompt)}`),_},async error(P){await y.error(P),await s.error(P)},async done(){await y.done(),await s.done()}}:w,g=getTerminalLogInfo(a);await appendTerminalAttachmentsToLog(r.context,A,e,g?.uri),await persistImageAttachments(r.context,a,e),await persistFileAndDirectoryAttachments(r.context,a,e);const D=formatSdkContextSuffix(r.context,g?.relativePath),M=D?`${T}
23
23
 
24
- ${D}`:T,b=(0,base_1.generateRequestId)(),v=r.sessionId??`ide-${Date.now()}`,N=(0,sessionEvents_1.wrapEmitterWithObservability)(I,_sessionEventWriter,v,b);let R=null;try{E.incrementActiveAgentTurns(),await E.ensureAgentideProjectPrepared(i,c,e),await E.writeManagedPathsManifest(h.codexHome,h.claudeConfigDir,i,c,e);const P=await E.getActiveAgentManifest(i,e),_=(0,permissions_1.parseManifestPermissions)(P),L=getUserPermissions(),x=(0,permissions_1.enforcePermissions)(_,L);log(e,`[AgentIDE] Permissions: manifest(files=${_.fileAccess}) + user(files=${L.fileAccess}) = effective(files=${x.fileAccess})`);const U={...r,sessionId:v,permissions:x,agentPackVersion:P?.metadata?.version,requestId:b},O=new vscode_logger_1.VSCodeLogger(e),B=new permission_handler_1.AutoApprovePermissionHandler,W=vscode.workspace.getConfiguration("agentide").get("cli.path",""),G=await(0,runtime_1.getCliHealth)({configuredPath:W,extensionPath:_extensionContext?.extensionPath}),q=_extensionContext?.globalState?.get(BUNDLED_TOOLS_DIR_KEY),F=(0,runtime_1.buildCliEnvPatch)({cliPath:G.path,workspaceRoot:i,agentId:U.agentPackId??"default",chatSessionId:U.sessionId?.trim()||U.contextSessionId?.trim(),baseEnv:process.env,extensionPath:_extensionContext?.extensionPath,userInstalledToolsDir:q??void 0});F.AGENTHIPPO_TOOLS_DIR&&log(e,`[AgentIDE] Bundled tools dir available for runtime: ${F.AGENTHIPPO_TOOLS_DIR}`);{const j=E.getActiveAgentContext(i),H=await getIdeTurnScope(i,j.agentId,j.agentRoot,P,e);H&&(R=await H.beginTurn({sessionKey:v}),Object.assign(F,R.env))}const V={logger:O,editTracker:new vscode_edit_tracker_1.VSCodeEditTracker(new vscode_logger_1.VSCodeLogger(e,"[EditTracker]")),configProvider:new vscode_config_provider_1.VSCodeConfigProvider,permissionHandler:B,cliEnvPatch:F};return G.installed&&G.path?log(e,`[AgentIDE] CLI available for agent runtime: ${G.path}`):log(e,`[AgentIDE] CLI not detected for runtime (skills may rely on '${branding_1.AGENTIDE_CLI_NAME}' on PATH)`),log(e,`[AgentIDE] Analytics: session=${v}, request=${b}, agent=${U.agentPackId??"default"}, version=${U.agentPackVersion??"workspace"}`),await N.emitTurnStart(),await S.stream(M,U,N,V,k.signal),await N.emitTurnEnd(!0),{streaming:!0}}catch(P){const _=P instanceof Error?P.message:String(P);return log(e,`[AgentIDE] Error: ${_}`),await N.error(_),await N.emitTurnEnd(!1),{error:_}}finally{try{await R?.release()}catch{}rejectPendingQuestionsForStream(y,"Run finished"),_activeRunsByStreamId.delete(y),E.decrementActiveAgentTurns()}}function resolveWorkspaceRootUri(t){const a=vscode.workspace.workspaceFolders??[],e=a.find(E=>E.uri.fsPath===t);if(e)return e.uri;const m=a[0];return m&&t.startsWith("/")?vscode.Uri.from({scheme:m.uri.scheme,authority:m.uri.authority,path:t}):vscode.Uri.file(t)}function dirnameUri(t){const a=t.path.lastIndexOf("/");return a>=0?t.with({path:t.path.slice(0,a)}):t}function getTerminalLogInfo(t){const a=t.contextSessionId?.trim()||t.sessionId?.trim();if(!a)return;const e=resolveWorkspaceRootUri(t.workspaceRoot);return{uri:vscode.Uri.joinPath(e,paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME,paths_1.AGENT_CONSTANTS.SESSIONS_DIR,a,TERMINAL_LOG_FILE_NAME),relativePath:`${AGENTIDE_SESSIONS_DIR_NAME}/${a}/${TERMINAL_LOG_FILE_NAME}`}}function getSessionAttachmentsDirInfo(t){const a=t.contextSessionId?.trim()||t.sessionId?.trim();if(!a)return;const e=resolveWorkspaceRootUri(t.workspaceRoot);return{dirUri:vscode.Uri.joinPath(e,paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME,paths_1.AGENT_CONSTANTS.SESSIONS_DIR,a,ATTACHMENTS_DIR_NAME),relativeDirPath:`${AGENTIDE_SESSIONS_DIR_NAME}/${a}/${ATTACHMENTS_DIR_NAME}`}}function slugifyFileStem(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"attachment"}function imageExtensionFromMimeType(t){switch((t??"").toLowerCase()){case"image/png":return"png";case"image/jpeg":case"image/jpg":return"jpg";case"image/gif":return"gif";case"image/webp":return"webp";default:return"png"}}async function persistImageAttachments(t,a,e){const m=t?.variables??[];if(!t||m.length===0)return;const E=m.filter(y=>y.kind==="image"&&typeof y.dataBase64=="string"&&y.dataBase64.length>0);if(E.length===0)return;const h=getSessionAttachmentsDirInfo(a);if(!h){log(e,"[AgentIDE] Note: image attachment present but no contextSessionId; skipping persistence");return}try{await(0,terminalLogger_1.ensureDirectory)(h.dirUri)}catch(y){log(e,`[AgentIDE] Warning: failed to create session attachments dir: ${y instanceof Error?y.message:String(y)}`);return}let C=0;for(const y of E){C++;const T=slugifyFileStem(y.name||`image-${C}`),n=imageExtensionFromMimeType(y.mimeType),s=E.length>1?`${T}-${C}.${n}`:`${T}.${n}`,l=vscode.Uri.joinPath(h.dirUri,s);try{const i=Buffer.from(y.dataBase64,"base64");await vscode.workspace.fs.writeFile(l,i),y.uri=`${h.relativeDirPath}/${s}`,delete y.dataBase64}catch(i){log(e,`[AgentIDE] Warning: failed to persist image attachment "${y.name}": ${i instanceof Error?i.message:String(i)}`)}}}async function persistFileAndDirectoryAttachments(t,a,e){const m=t?.variables??[];if(!t||m.length===0)return;const E=m.filter(f=>(f.kind==="file"||f.kind==="directory")&&typeof f.uri=="string"&&f.uri.trim().length>0);if(E.length===0)return;const h=getSessionAttachmentsDirInfo(a);if(!h){log(e,"[AgentIDE] Note: file/folder attachment present but no contextSessionId; skipping persistence");return}try{await(0,terminalLogger_1.ensureDirectory)(h.dirUri)}catch(f){log(e,`[AgentIDE] Warning: failed to create session attachments dir: ${f instanceof Error?f.message:String(f)}`);return}const C=vscode.Uri.joinPath(h.dirUri,"manifest.json"),y=async()=>{try{const f=await vscode.workspace.fs.readFile(C),w=JSON.parse(Buffer.from(f).toString("utf8"));if(w&&w.version===1&&typeof w.files=="object"&&typeof w.directories=="object")return w}catch{}return{version:1,files:{},directories:{}}},T=async f=>{try{const w=Buffer.from(JSON.stringify(f,null,2),"utf8");await vscode.workspace.fs.writeFile(C,w)}catch{}},n=await y();let s=!1;const l=500,i=25*1024*1024,c=10*1024*1024;let u=0,d=0;const o=(f,w)=>{try{const I=path.resolve(f),g=path.resolve(w),D=path.relative(I,g);return D===""||!D.startsWith("..")&&!path.isAbsolute(D)}catch{return!1}},r=a.workspaceRoot,p=path.normalize(`${path.sep}${AGENTIDE_SESSIONS_DIR_NAME.split("/").join(path.sep)}${path.sep}`),S=async f=>{try{return await vscode.workspace.fs.stat(f),!0}catch{return!1}},k=async(f,w)=>{let I=w,g=1;for(;await S(vscode.Uri.joinPath(f,I));){g++;const D=path.extname(w);I=`${D?w.slice(0,-D.length):w}-${g}${D}`}return I},A=async(f,w)=>{const I=vscode.Uri.file(f);try{const g=await vscode.workspace.fs.stat(I);if(g.type!==vscode.FileType.File)return;const D=`${f}::${g.size}::${g.mtime}`,M=n.files[D];if(M){const P=vscode.Uri.joinPath(w,M.destName);if(await S(P))return M.destName}const b=path.basename(f),v=await k(w,b||"attachment"),N=vscode.Uri.joinPath(w,v);if(g.size>c){log(e,`[AgentIDE] Note: skipping large file attachment (${g.size} bytes): ${f}`);return}if(u+1>l||d+g.size>i){log(e,"[AgentIDE] Note: skipping additional file attachments due to size limits");return}const R=await vscode.workspace.fs.readFile(I);return await vscode.workspace.fs.writeFile(N,R),u+=1,d+=g.size,n.files[D]={destName:v,sourcePath:f,size:g.size,mtime:g.mtime},s=!0,v}catch(g){log(e,`[AgentIDE] Warning: failed to persist file attachment "${f}": ${g instanceof Error?g.message:String(g)}`);return}},$=async(f,w)=>{const I=await vscode.workspace.fs.readDirectory(f);for(const[g,D]of I){if(u>=l||d>=i)return;const M=vscode.Uri.joinPath(f,g),b=vscode.Uri.joinPath(w,g);if(D===vscode.FileType.Directory)await(0,terminalLogger_1.ensureDirectory)(b),await $(M,b);else if(D===vscode.FileType.File)try{const v=await vscode.workspace.fs.stat(M);if(v.size>c)continue;if(u+1>l||d+v.size>i)return;const N=await vscode.workspace.fs.readFile(M);await vscode.workspace.fs.writeFile(b,N),u+=1,d+=v.size}catch{}}};for(const f of E){const w=f.uri.trim();if(path.isAbsolute(w)&&!(r&&o(r,w))&&!path.normalize(w).includes(p))try{const I=vscode.Uri.file(w),g=await vscode.workspace.fs.stat(I);if(g.type===vscode.FileType.Directory&&f.kind==="directory"){const D=`${w}::${g.mtime}`,M=n.directories[D];if(M){const R=vscode.Uri.joinPath(h.dirUri,M.destName);if(await S(R)){f.uri=`${h.relativeDirPath}/${M.destName}`;continue}}const b=path.basename(w)||"folder",v=await k(h.dirUri,b),N=vscode.Uri.joinPath(h.dirUri,v);await(0,terminalLogger_1.ensureDirectory)(N),await $(I,N),n.directories[D]={destName:v,sourcePath:w,mtime:g.mtime},s=!0,f.uri=`${h.relativeDirPath}/${v}`}else if(g.type===vscode.FileType.File&&f.kind==="file"){const D=await A(w,h.dirUri);D&&(f.uri=`${h.relativeDirPath}/${D}`)}}catch{}}s&&await T(n)}async function appendTerminalAttachmentsToLog(t,a,e,m){if(!m)return;const E=t?.variables??[],h=E.filter(y=>y.kind==="terminalCommand"&&typeof y.output=="string"&&y.output.trim().length>0),C=E.filter(y=>y.kind==="generic"&&typeof y.text=="string"&&y.text.trim().length>0&&(y.isTerminalSelection||typeof y.id=="string"&&y.id.startsWith("terminal-selection-")));if(!(h.length===0&&C.length===0))try{await(0,terminalLogger_1.ensureDirectory)(dirnameUri(m));const y=new Date().toISOString(),T=[];T.push(`<!-- TERMINAL_ATTACHMENTS STREAM:${a} TIME:${y} -->`),T.push("");for(const n of h){const s=(n.command??n.name??"").toString().trim();T.push("## Terminal Command"),s&&T.push(`- Command: ${s}`),typeof n.exitCode=="number"&&T.push(`- Exit code: ${n.exitCode}`),n.uri&&T.push(`- Resource: ${n.uri}`),T.push(""),T.push("```text"),T.push(n.output??""),T.push("```"),T.push("")}for(const n of C){const s=n.name||"Terminal Selection";T.push(`## ${s}`),T.push(""),T.push("```text"),T.push(n.text??""),T.push("```"),T.push("")}T.push(`<!-- TERMINAL_ATTACHMENTS_END STREAM:${a} -->`),T.push(""),await(0,terminalLogger_1.appendTextFileWithRotation)(m,T.join(`
25
- `),MAX_TERMINAL_LOG_BYTES)}catch(y){log(e,`[AgentIDE] Warning: failed to persist terminal attachments for grep: ${y instanceof Error?y.message:String(y)}`)}}function formatSdkContextSuffix(t,a){if(!t)return"";const e=[];if(t.selection?.text&&t.selection.text.trim()){const h=[];if(t.selection.uri&&h.push(`**File:** \`${t.selection.uri}\``),t.selection.range){const y=t.selection.range;h.push(`**Range:** ${y.startLineNumber}:${y.startColumn}-${y.endLineNumber}:${y.endColumn}`)}e.push("## Currently Selected Code"),h.length&&(e.push(h.join(`
26
- `)),e.push(""));const C=(t.selection.languageId??"").trim();e.push(`\`\`\`${C}`),e.push(t.selection.text),e.push("```")}const m=t.variables??[];if(m.length){e.push("## Attached Context");for(const h of m)switch(h.kind){case"terminalCommand":{const C=h.command?.trim()||h.name;if(e.push("### Terminal"),e.push(`**Command:** \`${C}\``),h.uri&&e.push(`**Resource:** \`${h.uri}\``),typeof h.exitCode=="number"&&e.push(`**Exit code:** ${h.exitCode}`),a)e.push(`**Output:** saved to \`${a}\` (use \`rg\`/ \`grep\`)`);else if(h.output&&h.output.trim()){const y=h.output.length>2e3?`\u2026(truncated)
27
- ${h.output.slice(-2e3)}`:h.output;e.push(""),e.push("```text"),e.push(y),e.push("```")}e.push("");break}case"paste":{const C=(h.language??"").trim(),y=h.name||"Paste";e.push(`### ${y}`),h.code&&h.code.trim()&&(e.push(`\`\`\`${C}`),e.push(h.code),e.push("```")),e.push("");break}case"file":case"directory":case"promptFile":{const C=h.uri??h.name;e.push(`- **${h.kind}**: \`${C}\``);break}case"image":case"notebookOutput":{const C=h.uri??h.name,y=h.mimeType?` (${h.mimeType})`:"";e.push(`- **${h.kind}**: \`${C}\`${y}`);break}case"implicit":{if(h.isSelection){const C=h.uri??h.name;e.push(`- **selection reference**: \`${C}\``)}else h.uri&&e.push(`- **reference**: \`${h.uri}\``);break}case"generic":{const C=h.name||"Context",y=!!h.isTerminalSelection||typeof h.id=="string"&&h.id.startsWith("terminal-selection-");if(e.push(`### ${C}`),y&&h.text&&h.text.trim()){if(a)e.push(`**Content:** saved to \`${a}\` (use \`rg\`/\`grep\`)`);else{const n=h.text.length>2e3?`\u2026(truncated)
24
+ ${D}`:T,b=(0,base_1.generateRequestId)(),v=a.sessionId??`ide-${Date.now()}`,N=(0,sessionEvents_1.wrapEmitterWithObservability)(I,_sessionEventWriter,v,b);let R=null;try{E.incrementActiveAgentTurns(),await E.ensureAgentideProjectPrepared(i,l,e),await E.writeManagedPathsManifest(h.codexHome,h.claudeConfigDir,i,l,e);const P=await E.getActiveAgentManifest(i,e),_=(0,permissions_1.parseManifestPermissions)(P),L=getUserPermissions(),x=(0,permissions_1.enforcePermissions)(_,L);log(e,`[AgentIDE] Permissions: manifest(files=${_.fileAccess}) + user(files=${L.fileAccess}) = effective(files=${x.fileAccess})`);const U={...a,sessionId:v,permissions:x,agentPackVersion:P?.metadata?.version,requestId:b},O=new vscode_logger_1.VSCodeLogger(e),B=new permission_handler_1.AutoApprovePermissionHandler,W=vscode.workspace.getConfiguration("agentide").get("cli.path",""),F=await(0,runtime_1.getCliHealth)({configuredPath:W,extensionPath:_extensionContext?.extensionPath}),q=_extensionContext?.globalState?.get(BUNDLED_TOOLS_DIR_KEY),G=(0,runtime_1.buildCliEnvPatch)({cliPath:F.path,workspaceRoot:i,agentId:U.agentPackId??"default",chatSessionId:U.sessionId?.trim()||U.contextSessionId?.trim(),baseEnv:process.env,extensionPath:_extensionContext?.extensionPath,userInstalledToolsDir:q??void 0});G.AGENTHIPPO_TOOLS_DIR&&log(e,`[AgentIDE] Bundled tools dir available for runtime: ${G.AGENTHIPPO_TOOLS_DIR}`);{const j=E.getActiveAgentContext(i),H=await getIdeTurnScope(i,j.agentId,j.agentRoot,P,e);H&&(R=await H.beginTurn({sessionKey:v}),Object.assign(G,R.env))}const V={logger:O,editTracker:new vscode_edit_tracker_1.VSCodeEditTracker(new vscode_logger_1.VSCodeLogger(e,"[EditTracker]")),configProvider:new vscode_config_provider_1.VSCodeConfigProvider,permissionHandler:B,cliEnvPatch:G};return F.installed&&F.path?log(e,`[AgentIDE] CLI available for agent runtime: ${F.path}`):log(e,`[AgentIDE] CLI not detected for runtime (skills may rely on '${branding_1.AGENTIDE_CLI_NAME}' on PATH)`),log(e,`[AgentIDE] Analytics: session=${v}, request=${b}, agent=${U.agentPackId??"default"}, version=${U.agentPackVersion??"workspace"}`),await N.emitTurnStart(),await S.stream(M,U,N,V,k.signal),await N.emitTurnEnd(!0),{streaming:!0}}catch(P){const _=P instanceof Error?P.message:String(P);return log(e,`[AgentIDE] Error: ${_}`),await N.error(_),await N.emitTurnEnd(!1),{error:_}}finally{try{await R?.release()}catch{}rejectPendingQuestionsForStream(A,"Run finished"),_activeRunsByStreamId.delete(A),E.decrementActiveAgentTurns()}}function resolveWorkspaceRootUri(t){const r=vscode.workspace.workspaceFolders??[],e=r.find(E=>E.uri.fsPath===t);if(e)return e.uri;const m=r[0];return m&&t.startsWith("/")?vscode.Uri.from({scheme:m.uri.scheme,authority:m.uri.authority,path:t}):vscode.Uri.file(t)}function dirnameUri(t){const r=t.path.lastIndexOf("/");return r>=0?t.with({path:t.path.slice(0,r)}):t}function getTerminalLogInfo(t){const r=t.contextSessionId?.trim()||t.sessionId?.trim();if(!r)return;const e=resolveWorkspaceRootUri(t.workspaceRoot);return{uri:vscode.Uri.joinPath(e,paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME,paths_1.AGENT_CONSTANTS.SESSIONS_DIR,r,TERMINAL_LOG_FILE_NAME),relativePath:`${AGENTIDE_SESSIONS_DIR_NAME}/${r}/${TERMINAL_LOG_FILE_NAME}`}}function getSessionAttachmentsDirInfo(t){const r=t.contextSessionId?.trim()||t.sessionId?.trim();if(!r)return;const e=resolveWorkspaceRootUri(t.workspaceRoot);return{dirUri:vscode.Uri.joinPath(e,paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME,paths_1.AGENT_CONSTANTS.SESSIONS_DIR,r,ATTACHMENTS_DIR_NAME),relativeDirPath:`${AGENTIDE_SESSIONS_DIR_NAME}/${r}/${ATTACHMENTS_DIR_NAME}`}}function slugifyFileStem(t){return t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,60)||"attachment"}function imageExtensionFromMimeType(t){switch((t??"").toLowerCase()){case"image/png":return"png";case"image/jpeg":case"image/jpg":return"jpg";case"image/gif":return"gif";case"image/webp":return"webp";default:return"png"}}async function persistImageAttachments(t,r,e){const m=t?.variables??[];if(!t||m.length===0)return;const E=m.filter(A=>A.kind==="image"&&typeof A.dataBase64=="string"&&A.dataBase64.length>0);if(E.length===0)return;const h=getSessionAttachmentsDirInfo(r);if(!h){log(e,"[AgentIDE] Note: image attachment present but no contextSessionId; skipping persistence");return}try{await(0,terminalLogger_1.ensureDirectory)(h.dirUri)}catch(A){log(e,`[AgentIDE] Warning: failed to create session attachments dir: ${A instanceof Error?A.message:String(A)}`);return}let C=0;for(const A of E){C++;const T=slugifyFileStem(A.name||`image-${C}`),n=imageExtensionFromMimeType(A.mimeType),s=E.length>1?`${T}-${C}.${n}`:`${T}.${n}`,c=vscode.Uri.joinPath(h.dirUri,s);try{const i=Buffer.from(A.dataBase64,"base64");await vscode.workspace.fs.writeFile(c,i),A.uri=`${h.relativeDirPath}/${s}`,delete A.dataBase64}catch(i){log(e,`[AgentIDE] Warning: failed to persist image attachment "${A.name}": ${i instanceof Error?i.message:String(i)}`)}}}async function persistFileAndDirectoryAttachments(t,r,e){const m=t?.variables??[];if(!t||m.length===0)return;const E=m.filter(f=>(f.kind==="file"||f.kind==="directory")&&typeof f.uri=="string"&&f.uri.trim().length>0);if(E.length===0)return;const h=getSessionAttachmentsDirInfo(r);if(!h){log(e,"[AgentIDE] Note: file/folder attachment present but no contextSessionId; skipping persistence");return}try{await(0,terminalLogger_1.ensureDirectory)(h.dirUri)}catch(f){log(e,`[AgentIDE] Warning: failed to create session attachments dir: ${f instanceof Error?f.message:String(f)}`);return}const C=vscode.Uri.joinPath(h.dirUri,"manifest.json"),A=async()=>{try{const f=await vscode.workspace.fs.readFile(C),w=JSON.parse(Buffer.from(f).toString("utf8"));if(w&&w.version===1&&typeof w.files=="object"&&typeof w.directories=="object")return w}catch{}return{version:1,files:{},directories:{}}},T=async f=>{try{const w=Buffer.from(JSON.stringify(f,null,2),"utf8");await vscode.workspace.fs.writeFile(C,w)}catch{}},n=await A();let s=!1;const c=500,i=25*1024*1024,l=10*1024*1024;let u=0,d=0;const o=(f,w)=>{try{const I=path.resolve(f),g=path.resolve(w),D=path.relative(I,g);return D===""||!D.startsWith("..")&&!path.isAbsolute(D)}catch{return!1}},a=r.workspaceRoot,p=path.normalize(`${path.sep}${AGENTIDE_SESSIONS_DIR_NAME.split("/").join(path.sep)}${path.sep}`),S=async f=>{try{return await vscode.workspace.fs.stat(f),!0}catch{return!1}},k=async(f,w)=>{let I=w,g=1;for(;await S(vscode.Uri.joinPath(f,I));){g++;const D=path.extname(w);I=`${D?w.slice(0,-D.length):w}-${g}${D}`}return I},y=async(f,w)=>{const I=vscode.Uri.file(f);try{const g=await vscode.workspace.fs.stat(I);if(g.type!==vscode.FileType.File)return;const D=`${f}::${g.size}::${g.mtime}`,M=n.files[D];if(M){const P=vscode.Uri.joinPath(w,M.destName);if(await S(P))return M.destName}const b=path.basename(f),v=await k(w,b||"attachment"),N=vscode.Uri.joinPath(w,v);if(g.size>l){log(e,`[AgentIDE] Note: skipping large file attachment (${g.size} bytes): ${f}`);return}if(u+1>c||d+g.size>i){log(e,"[AgentIDE] Note: skipping additional file attachments due to size limits");return}const R=await vscode.workspace.fs.readFile(I);return await vscode.workspace.fs.writeFile(N,R),u+=1,d+=g.size,n.files[D]={destName:v,sourcePath:f,size:g.size,mtime:g.mtime},s=!0,v}catch(g){log(e,`[AgentIDE] Warning: failed to persist file attachment "${f}": ${g instanceof Error?g.message:String(g)}`);return}},$=async(f,w)=>{const I=await vscode.workspace.fs.readDirectory(f);for(const[g,D]of I){if(u>=c||d>=i)return;const M=vscode.Uri.joinPath(f,g),b=vscode.Uri.joinPath(w,g);if(D===vscode.FileType.Directory)await(0,terminalLogger_1.ensureDirectory)(b),await $(M,b);else if(D===vscode.FileType.File)try{const v=await vscode.workspace.fs.stat(M);if(v.size>l)continue;if(u+1>c||d+v.size>i)return;const N=await vscode.workspace.fs.readFile(M);await vscode.workspace.fs.writeFile(b,N),u+=1,d+=v.size}catch{}}};for(const f of E){const w=f.uri.trim();if(path.isAbsolute(w)&&!(a&&o(a,w))&&!path.normalize(w).includes(p))try{const I=vscode.Uri.file(w),g=await vscode.workspace.fs.stat(I);if(g.type===vscode.FileType.Directory&&f.kind==="directory"){const D=`${w}::${g.mtime}`,M=n.directories[D];if(M){const R=vscode.Uri.joinPath(h.dirUri,M.destName);if(await S(R)){f.uri=`${h.relativeDirPath}/${M.destName}`;continue}}const b=path.basename(w)||"folder",v=await k(h.dirUri,b),N=vscode.Uri.joinPath(h.dirUri,v);await(0,terminalLogger_1.ensureDirectory)(N),await $(I,N),n.directories[D]={destName:v,sourcePath:w,mtime:g.mtime},s=!0,f.uri=`${h.relativeDirPath}/${v}`}else if(g.type===vscode.FileType.File&&f.kind==="file"){const D=await y(w,h.dirUri);D&&(f.uri=`${h.relativeDirPath}/${D}`)}}catch{}}s&&await T(n)}async function appendTerminalAttachmentsToLog(t,r,e,m){if(!m)return;const E=t?.variables??[],h=E.filter(A=>A.kind==="terminalCommand"&&typeof A.output=="string"&&A.output.trim().length>0),C=E.filter(A=>A.kind==="generic"&&typeof A.text=="string"&&A.text.trim().length>0&&(A.isTerminalSelection||typeof A.id=="string"&&A.id.startsWith("terminal-selection-")));if(!(h.length===0&&C.length===0))try{await(0,terminalLogger_1.ensureDirectory)(dirnameUri(m));const A=new Date().toISOString(),T=[];T.push(`<!-- TERMINAL_ATTACHMENTS STREAM:${r} TIME:${A} -->`),T.push("");for(const n of h){const s=(n.command??n.name??"").toString().trim();T.push("## Terminal Command"),s&&T.push(`- Command: ${s}`),typeof n.exitCode=="number"&&T.push(`- Exit code: ${n.exitCode}`),n.uri&&T.push(`- Resource: ${n.uri}`),T.push(""),T.push("```text"),T.push(n.output??""),T.push("```"),T.push("")}for(const n of C){const s=n.name||"Terminal Selection";T.push(`## ${s}`),T.push(""),T.push("```text"),T.push(n.text??""),T.push("```"),T.push("")}T.push(`<!-- TERMINAL_ATTACHMENTS_END STREAM:${r} -->`),T.push(""),await(0,terminalLogger_1.appendTextFileWithRotation)(m,T.join(`
25
+ `),MAX_TERMINAL_LOG_BYTES)}catch(A){log(e,`[AgentIDE] Warning: failed to persist terminal attachments for grep: ${A instanceof Error?A.message:String(A)}`)}}function formatSdkContextSuffix(t,r){if(!t)return"";const e=[];if(t.selection?.text&&t.selection.text.trim()){const h=[];if(t.selection.uri&&h.push(`**File:** \`${t.selection.uri}\``),t.selection.range){const A=t.selection.range;h.push(`**Range:** ${A.startLineNumber}:${A.startColumn}-${A.endLineNumber}:${A.endColumn}`)}e.push("## Currently Selected Code"),h.length&&(e.push(h.join(`
26
+ `)),e.push(""));const C=(t.selection.languageId??"").trim();e.push(`\`\`\`${C}`),e.push(t.selection.text),e.push("```")}const m=t.variables??[];if(m.length){e.push("## Attached Context");for(const h of m)switch(h.kind){case"terminalCommand":{const C=h.command?.trim()||h.name;if(e.push("### Terminal"),e.push(`**Command:** \`${C}\``),h.uri&&e.push(`**Resource:** \`${h.uri}\``),typeof h.exitCode=="number"&&e.push(`**Exit code:** ${h.exitCode}`),r)e.push(`**Output:** saved to \`${r}\` (use \`rg\`/ \`grep\`)`);else if(h.output&&h.output.trim()){const A=h.output.length>2e3?`\u2026(truncated)
27
+ ${h.output.slice(-2e3)}`:h.output;e.push(""),e.push("```text"),e.push(A),e.push("```")}e.push("");break}case"paste":{const C=(h.language??"").trim(),A=h.name||"Paste";e.push(`### ${A}`),h.code&&h.code.trim()&&(e.push(`\`\`\`${C}`),e.push(h.code),e.push("```")),e.push("");break}case"file":case"directory":case"promptFile":{const C=h.uri??h.name;e.push(`- **${h.kind}**: \`${C}\``);break}case"image":case"notebookOutput":{const C=h.uri??h.name,A=h.mimeType?` (${h.mimeType})`:"";e.push(`- **${h.kind}**: \`${C}\`${A}`);break}case"implicit":{if(h.isSelection){const C=h.uri??h.name;e.push(`- **selection reference**: \`${C}\``)}else h.uri&&e.push(`- **reference**: \`${h.uri}\``);break}case"generic":{const C=h.name||"Context",A=!!h.isTerminalSelection||typeof h.id=="string"&&h.id.startsWith("terminal-selection-");if(e.push(`### ${C}`),A&&h.text&&h.text.trim()){if(r)e.push(`**Content:** saved to \`${r}\` (use \`rg\`/\`grep\`)`);else{const n=h.text.length>2e3?`\u2026(truncated)
28
28
  ${h.text.slice(-2e3)}`:h.text;e.push("```text"),e.push(n),e.push("```")}const T=h.name?.match(/Terminal Selection \((.+)\)/);if(T){const n=T[1],s=(0,terminalLogger_1.terminalNameToSlug)(n);e.push(`**Full terminal history:** \`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/terminals/${s}.md\``)}else e.push(`**All terminal logs:** \`${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/terminals/\``)}else h.text&&h.text.trim()?(e.push("```text"),e.push(h.text),e.push("```")):h.uri&&e.push(`**Resource:** \`${h.uri}\``);e.push("");break}default:{const C=h.uri??h.name;e.push(`- **${h.kind}**: ${C}`);break}}}const E=e.join(`
29
29
  `).trim();return E?E+`
30
- `:""}function getBundledBasePromptsDir(){if(_extensionContext)return path.join(_extensionContext.extensionPath,"base-prompts")}async function registerBundledMcpServers(t,a){const e=getBundledBasePromptsDir();if(!e){log(a,"[AgentIDE] Cannot register MCP servers: base-prompts dir not found");return}try{const m=await(0,mcp_1.loadBundledMcpServers)(e);if(m.length===0){log(a,"[AgentIDE] No bundled MCP servers found");return}const E=vscode.lm.registerMcpServerDefinitionProvider("bundled-mcp-servers",{provideMcpServerDefinitions:async()=>m.map(h=>new vscode.McpStdioServerDefinition(h.label,h.command,h.args,h.env??{}))});t.subscriptions.push(E),log(a,`[AgentIDE] Registered ${m.length} bundled MCP server(s) with VS Code: ${m.map(h=>h.name).join(", ")}`)}catch(m){log(a,`[AgentIDE] Warning: failed to register MCP servers: ${m instanceof Error?m.message:String(m)}`)}}async function refreshAgentideProject(t){const{outputChannel:a,syncService:e,config:m}=t,{workspaceRoot:E,additionalDirectories:h,isHomeFallback:C}=getWorkspaceRoot(a);if(!C)try{await e.ensureAgentideProjectPrepared(E,h,a),await e.writeManagedPathsManifest(m.codexHome,m.claudeConfigDir,E,h,a),log(a,"[AgentIDE] Project sync complete")}catch(y){log(a,`[AgentIDE] Warning: failed to refresh project sync: ${y instanceof Error?y.message:String(y)}`)}}function getFallbackDirectoryPath(){const a=vscode.workspace.getConfiguration("agentide").get("fallbackDirectory")||".agent-hippo";return path.join(os.homedir(),a)}function getWorkspaceRoot(t,a,e){const m=vscode.workspace.workspaceFolders,E=(0,workspaceFolders_1.getWorkspaceFolderFsPaths)(),h=a?.trim();if(h){const y=e??E.filter(T=>T!==h);return m&&m.length>1?log(t,`[AgentIDE] Multi-root workspace (${m.length} folders). Primary: ${h}, Additional: ${y.length}`):log(t,`[AgentIDE] Using explicit workspaceRoot=${h}`),{workspaceRoot:h,additionalDirectories:y,isHomeFallback:!1}}if(m&&m.length>0){const y=m[0].uri.fsPath,T=E.slice(1);return m.length>1?log(t,`[AgentIDE] Multi-root workspace (${m.length} folders). Primary: ${y}, Additional: ${T.length}`):log(t,`[AgentIDE] Using workspace folder: ${y}`),{workspaceRoot:y,additionalDirectories:T,isHomeFallback:!1}}const C=getFallbackDirectoryPath();return log(t,`[AgentIDE] No workspace open, using fallback directory: ${C}`),{workspaceRoot:C,additionalDirectories:[],isHomeFallback:!0}}async function ensureFallbackDirectoryExists(t){const a=getFallbackDirectoryPath();try{if(!await(0,utils_1.pathExists)(a)){await fs_1.promises.mkdir(a,{recursive:!0}),log(t,`[AgentIDE] Created fallback directory: ${a}`);try{const{execFile:m}=await import("child_process"),{promisify:E}=await import("util");await E(m)("git",["init"],{cwd:a}),log(t,"[AgentIDE] Initialized git in fallback directory");const C=path.join(a,".gitignore"),y=`# ${branding_1.AGENTIDE_BRAND_NAME} fallback workspace
30
+ `:""}function getBundledBasePromptsDir(){if(_extensionContext)return path.join(_extensionContext.extensionPath,"base-prompts")}async function registerBundledMcpServers(t,r){const e=getBundledBasePromptsDir();if(!e){log(r,"[AgentIDE] Cannot register MCP servers: base-prompts dir not found");return}try{const m=await(0,mcp_1.loadBundledMcpServers)(e);if(m.length===0){log(r,"[AgentIDE] No bundled MCP servers found");return}const E=vscode.lm.registerMcpServerDefinitionProvider("bundled-mcp-servers",{provideMcpServerDefinitions:async()=>m.map(h=>new vscode.McpStdioServerDefinition(h.label,h.command,h.args,h.env??{}))});t.subscriptions.push(E),log(r,`[AgentIDE] Registered ${m.length} bundled MCP server(s) with VS Code: ${m.map(h=>h.name).join(", ")}`)}catch(m){log(r,`[AgentIDE] Warning: failed to register MCP servers: ${m instanceof Error?m.message:String(m)}`)}}async function refreshAgentideProject(t){const{outputChannel:r,syncService:e,config:m}=t,{workspaceRoot:E,additionalDirectories:h,isHomeFallback:C}=getWorkspaceRoot(r);if(!C)try{await e.ensureAgentideProjectPrepared(E,h,r),await e.writeManagedPathsManifest(m.codexHome,m.claudeConfigDir,E,h,r),log(r,"[AgentIDE] Project sync complete")}catch(A){log(r,`[AgentIDE] Warning: failed to refresh project sync: ${A instanceof Error?A.message:String(A)}`)}}function getFallbackDirectoryPath(){const r=vscode.workspace.getConfiguration("agentide").get("fallbackDirectory")||".agent-hippo";return path.join(os.homedir(),r)}function getWorkspaceRoot(t,r,e){const m=vscode.workspace.workspaceFolders,E=(0,workspaceFolders_1.getWorkspaceFolderFsPaths)(),h=r?.trim();if(h){const A=e??E.filter(T=>T!==h);return m&&m.length>1?log(t,`[AgentIDE] Multi-root workspace (${m.length} folders). Primary: ${h}, Additional: ${A.length}`):log(t,`[AgentIDE] Using explicit workspaceRoot=${h}`),{workspaceRoot:h,additionalDirectories:A,isHomeFallback:!1}}if(m&&m.length>0){const A=m[0].uri.fsPath,T=E.slice(1);return m.length>1?log(t,`[AgentIDE] Multi-root workspace (${m.length} folders). Primary: ${A}, Additional: ${T.length}`):log(t,`[AgentIDE] Using workspace folder: ${A}`),{workspaceRoot:A,additionalDirectories:T,isHomeFallback:!1}}const C=getFallbackDirectoryPath();return log(t,`[AgentIDE] No workspace open, using fallback directory: ${C}`),{workspaceRoot:C,additionalDirectories:[],isHomeFallback:!0}}async function ensureFallbackDirectoryExists(t){const r=getFallbackDirectoryPath();try{if(!await(0,utils_1.pathExists)(r)){await fs_1.promises.mkdir(r,{recursive:!0}),log(t,`[AgentIDE] Created fallback directory: ${r}`);try{const{execFile:m}=await import("child_process"),{promisify:E}=await import("util");await E(m)("git",["init"],{cwd:r}),log(t,"[AgentIDE] Initialized git in fallback directory");const C=path.join(r,".gitignore"),A=`# ${branding_1.AGENTIDE_BRAND_NAME} fallback workspace
31
31
  ${paths_1.AGENT_CONSTANTS.AGENTIDE_DIR_NAME}/${paths_1.AGENT_CONSTANTS.SESSIONS_DIR}/
32
32
  *.log
33
- `;await fs_1.promises.writeFile(C,y,"utf8");const T=path.join(a,"README.md"),n=`# My ${branding_1.AGENTIDE_BRAND_NAME} Workspace
33
+ `;await fs_1.promises.writeFile(C,A,"utf8");const T=path.join(r,"README.md"),n=`# My ${branding_1.AGENTIDE_BRAND_NAME} Workspace
34
34
 
35
35
  This is the default ${branding_1.AGENTIDE_BRAND_NAME} workspace, created automatically when no folder is open.
36
36
 
@@ -39,4 +39,4 @@ This is the default ${branding_1.AGENTIDE_BRAND_NAME} workspace, created automat
39
39
  Files created here:
40
40
  - Agent-generated files when no workspace is open
41
41
  - Temporary experiments
42
- `;await fs_1.promises.writeFile(T,n,"utf8")}catch(m){log(t,`[AgentIDE] Note: Could not initialize git in fallback directory: ${m instanceof Error?m.message:String(m)}`)}}}catch(e){log(t,`[AgentIDE] Warning: Failed to ensure fallback directory: ${e instanceof Error?e.message:String(e)}`)}return a}let _hasWarnedHomeFallbackInThisSession=!1;async function warnHomeFallbackOnce(t,a){if(_hasWarnedHomeFallbackInThisSession)return;_hasWarnedHomeFallbackInThisSession=!0;const m=`No folder is open. Running agent tools in: ${await ensureFallbackDirectoryExists(t)}`;log(t,`[AgentIDE] ${m}`),vscode.commands.executeCommand("agentide.streamCallback",{streamId:a,type:"progress",data:m})}
42
+ `;await fs_1.promises.writeFile(T,n,"utf8")}catch(m){log(t,`[AgentIDE] Note: Could not initialize git in fallback directory: ${m instanceof Error?m.message:String(m)}`)}}}catch(e){log(t,`[AgentIDE] Warning: Failed to ensure fallback directory: ${e instanceof Error?e.message:String(e)}`)}return r}let _hasWarnedHomeFallbackInThisSession=!1;async function warnHomeFallbackOnce(t,r){if(_hasWarnedHomeFallbackInThisSession)return;_hasWarnedHomeFallbackInThisSession=!0;const m=`No folder is open. Running agent tools in: ${await ensureFallbackDirectoryExists(t)}`;log(t,`[AgentIDE] ${m}`),vscode.commands.executeCommand("agentide.streamCallback",{streamId:r,type:"progress",data:m})}
@@ -647,6 +647,10 @@ export PYTHONIOENCODING="${PYTHONIOENCODING:-utf-8}"
647
647
  export PYTHONUTF8="${PYTHONUTF8:-1}"
648
648
  export AGENT_HOME_DIR="${CHILD_AGENT_HOME_DIR}"
649
649
  export LITELLM_CONFIG_PATH="${CHILD_CONFIG_PATH}"
650
+ # LiteLLM's chatgpt/ provider reads its token from here. The IDE keeps auth.json current and stays
651
+ # the only refresher, so the proxy never starts its own interactive ChatGPT login. Not overridable:
652
+ # the IDE writes to exactly this folder, so an inherited value would only point the proxy elsewhere.
653
+ export CHATGPT_TOKEN_DIR="${CHILD_AGENT_HOME_DIR}/chatgpt"
650
654
 
651
655
  # Add scripts directory to PYTHONPATH so custom hooks can be imported.
652
656
  # Native Windows Python expects Windows-style paths and ';' separators.
@@ -259,6 +259,50 @@ def _strip_unsupported_tools(data: dict) -> None:
259
259
  data['tools'] = filtered
260
260
  else:
261
261
  data.pop('tools', None)
262
+ _CHATGPT_BACKEND_MARKER = 'chatgpt.com/backend-api'
263
+
264
+ def _is_chatgpt_backend_route(request_kwargs: dict) -> bool:
265
+ api_base = request_kwargs.get('api_base')
266
+ model = request_kwargs.get('model')
267
+ return isinstance(api_base, str) and _CHATGPT_BACKEND_MARKER in api_base or (isinstance(model, str) and model.startswith('chatgpt/')) or request_kwargs.get('custom_llm_provider') == 'chatgpt'
268
+
269
+ def _fold_system_input_items(request_kwargs: dict) -> None:
270
+ items = request_kwargs.get('input')
271
+ if not isinstance(items, list):
272
+ return
273
+ system = [item for item in items if isinstance(item, dict) and item.get('role') == 'system']
274
+ if not system:
275
+ return
276
+ request_kwargs['input'] = [item for item in items if not (isinstance(item, dict) and item.get('role') == 'system')]
277
+ texts = [request_kwargs.get('instructions') or ''] + [_content_blocks_to_text(item.get('content')) for item in system]
278
+ request_kwargs['instructions'] = '\n\n'.join((text for text in texts if text))
279
+ _CHATGPT_RELOGIN_HINT = 'ChatGPT subscription sign-in is missing or expired. Sign in again: in the IDE, Add API Key -> OpenAI (ChatGPT subscription); on a server, scripts/setup-subscription-routes.sh --chatgpt-login'
280
+
281
+ def _guard_chatgpt_login() -> None:
282
+ try:
283
+ from litellm.exceptions import AuthenticationError
284
+ from litellm.llms.chatgpt import authenticator
285
+ from litellm.llms.chatgpt.chat.transformation import ChatGPTConfig
286
+ from litellm.llms.chatgpt.common_utils import GetAccessTokenError
287
+ except ImportError:
288
+ return
289
+
290
+ def _login_device_code(self):
291
+ raise GetAccessTokenError(message=_CHATGPT_RELOGIN_HINT, status_code=401)
292
+
293
+ def _wait_for_access_token(self, timeout_seconds):
294
+ return None
295
+ authenticator.Authenticator._login_device_code = _login_device_code
296
+ authenticator.Authenticator._wait_for_access_token = _wait_for_access_token
297
+ resolve_provider_info = ChatGPTConfig._get_openai_compatible_provider_info
298
+
299
+ def _get_openai_compatible_provider_info(self, model, api_base, api_key, custom_llm_provider):
300
+ try:
301
+ return resolve_provider_info(self, model, api_base, api_key, custom_llm_provider)
302
+ except AuthenticationError:
303
+ return (self.authenticator.get_api_base(), '', custom_llm_provider)
304
+ ChatGPTConfig._get_openai_compatible_provider_info = _get_openai_compatible_provider_info
305
+ _guard_chatgpt_login()
262
306
 
263
307
  def _apply_codex_proxy_sanitizers(data: dict, model: Any) -> None:
264
308
  route_model = _resolve_route_model(data, model)
@@ -426,6 +470,8 @@ class CodexProxySanitizer(CustomLogger):
426
470
  async def async_pre_call_deployment_hook(self, request_kwargs: dict, call_type: Any) -> dict:
427
471
  if not isinstance(request_kwargs, dict):
428
472
  return request_kwargs
473
+ if _is_chatgpt_backend_route(request_kwargs):
474
+ _fold_system_input_items(request_kwargs)
429
475
  return self._sanitize(request_kwargs, request_kwargs.get('model'))
430
476
 
431
477
  async def async_pre_request_hook(self, model: str, messages: list[Any], request_kwargs: dict) -> dict:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenthippo-ai/agenthippo",
3
- "version": "1.110.37",
3
+ "version": "1.110.39",
4
4
  "description": "AgentHippo CLI — serve, chat, and deploy agent packs",
5
5
  "author": "AgentHippo <dev@agenthippo.ai>",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -38,7 +38,7 @@
38
38
  "zod": "^4.3.6"
39
39
  },
40
40
  "agenthippo": {
41
- "litellmImageTag": "0.2.22",
41
+ "litellmImageTag": "0.2.23",
42
42
  "hippoclawNpm": "@agenthippo-ai/hippoclaw@2026.7.28"
43
43
  }
44
44
  }