@vibecontrols/vibe-plugin-tool-git 2026.525.2 → 2026.527.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +1 -1
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- var __defProp=Object.defineProperty;var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn,res)=>()=>(fn&&(res=fn(fn=0)),res);var __require=import.meta.require;async function isPortAvailable(port){try{return Bun.serve({port,hostname:"127.0.0.1",fetch(){return new Response}}).stop(!0),!0}catch{return!1}}async function findAvailablePort(preferred){let start=preferred??DEFAULT_PORT;if(await isPortAvailable(start))return start;for(let port=DEFAULT_PORT;port<=PORT_RANGE_END;port++){if(port===start)continue;if(await isPortAvailable(port))return port}throw Error(`No available port in range ${DEFAULT_PORT}-${PORT_RANGE_END}`)}async function checkInstallation(){try{let localPath=new URL("../../node_modules/.bin/ungit",import.meta.url).pathname;if(await Bun.file(localPath).exists())return{installed:!0,binaryPath:localPath}}catch{}try{let path=Bun.which("ungit");if(path)return{installed:!0,binaryPath:path}}catch{}return{installed:!1}}async function installUngit(){try{let proc=Bun.spawn(["npm","install","-g","ungit"],{stdout:"pipe",stderr:"pipe"}),exitCode=await proc.exited;if(exitCode!==0){let stderr=await new Response(proc.stderr).text();return{success:!1,error:`npm install -g ungit failed (exit ${exitCode}): ${stderr}`}}return{success:!0}}catch(err){return{success:!1,error:err instanceof Error?err.message:"Installation failed"}}}async function startUngit(options){if(childProcess&&currentPid){if(isProcessAlive(currentPid))return{pid:currentPid,port:currentPort};childProcess=null,currentPid=null}if(isStarting)throw Error("Ungit is already starting");isStarting=!0,lastError=null;try{let port=await findAvailablePort(options?.port),workingDir=options?.workingDir||process.env.HOME||"/",install=await checkInstallation();if(!install.installed||!install.binaryPath)throw Error("Ungit is not installed");let args=[install.binaryPath,"--port",String(port),"--no-b","--ungitBindIp","127.0.0.1","--rootPath","/ungit"],proc=Bun.spawn(args,{stdout:"pipe",stderr:"pipe",cwd:workingDir,env:{...process.env,PORT:void 0}});if(childProcess=proc,currentPort=port,currentWorkingDir=workingDir,currentPid=proc.pid,proc.exited.then((code)=>{if(childProcess===proc){if(childProcess=null,currentPid=null,code!==0&&code!==null)lastError=`Ungit exited with code ${code}`}}),await new Promise((resolve)=>setTimeout(resolve,2000)),!isProcessAlive(proc.pid)){let stderr=await new Response(proc.stderr).text();throw Error(`Ungit failed to start: ${stderr}`)}return{pid:proc.pid,port}}catch(err){throw lastError=err instanceof Error?err.message:"Failed to start",err}finally{isStarting=!1}}async function stopUngit(){if(!childProcess||!currentPid){childProcess=null,currentPid=null;return}let proc=childProcess,pid=currentPid;childProcess=null,currentPid=null,currentPort=null,currentWorkingDir=null,lastError=null;try{process.kill(pid,"SIGTERM")}catch{return}let deadline=Date.now()+5000;while(Date.now()<deadline&&isProcessAlive(pid))await new Promise((resolve)=>setTimeout(resolve,200));if(isProcessAlive(pid))try{process.kill(pid,"SIGKILL")}catch{}try{await proc.exited}catch{}}function getStatus(){let running=Boolean(currentPid&&isProcessAlive(currentPid));if(!running&&childProcess)childProcess=null,currentPid=null;return{installed:!0,running,pid:running?currentPid??void 0:void 0,port:running?currentPort??void 0:void 0,workingDir:running?currentWorkingDir??void 0:void 0,error:lastError??void 0}}function getRunningPort(){if(!currentPid||!isProcessAlive(currentPid))return null;return currentPort}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch{return!1}}var childProcess=null,currentPort=null,currentWorkingDir=null,currentPid=null,lastError=null,isStarting=!1,DEFAULT_PORT=8448,PORT_RANGE_END=8458;import{Elysia as Elysia2}from"elysia";var RoutesBuilder=class{constructor(pluginName,hostServices){this.pluginName=pluginName,this.hostServices=hostServices}pluginName;hostServices;prefix;apiKeyResolver;errorHandlerEnabled=!1;loggingEnabled=!1;withPrefix(prefix){return this.prefix=prefix,this}withAuth(getApiKey){return this.apiKeyResolver=getApiKey,this}withErrorHandler(){return this.errorHandlerEnabled=!0,this}withLogging(){return this.loggingEnabled=!0,this}build(){let opts=this.prefix?{prefix:this.prefix}:void 0,app=new Elysia2(opts);if(this.apiKeyResolver){let resolver=this.apiKeyResolver;app.onBeforeHandle(async({request,set})=>{let supplied=request.headers.get("x-api-key"),expected=await resolver();if(!supplied||supplied!==expected)return set.status=401,{error:"unauthorized"};return})}if(this.errorHandlerEnabled){let pluginName=this.pluginName,logger=this.hostServices?.logger;app.onError(({error,set})=>{let message=error instanceof Error?error.message:String(error);return logger?.error?.(pluginName,"route error",{message}),set.status=500,{error:message}})}if(this.loggingEnabled){let pluginName=this.pluginName,logger=this.hostServices?.logger;app.onRequest(({request})=>{logger?.debug?.(pluginName,"request",{method:request.method,url:request.url})})}return app}};var init_routes=()=>{};var exports_routes={};__export(exports_routes,{createUngitRoutes:()=>createUngitRoutes});function createUngitRoutes(hostServices){return new RoutesBuilder("ungit",hostServices).withPrefix("/api/ungit").withErrorHandler().build().get("/status",async()=>{let installInfo=await checkInstallation(),processStatus=getStatus();return{installed:installInfo.installed,installing:isInstalling,running:processStatus.running,pid:processStatus.pid,port:processStatus.port,workingDir:processStatus.workingDir,error:installError||processStatus.error||void 0}}).post("/install",async({set})=>{if(isInstalling)return set.status=409,{error:"Installation already in progress"};let check=await checkInstallation();if(check.installed)return{message:"Ungit is already installed",binaryPath:check.binaryPath};return isInstalling=!0,installError=null,(async()=>{try{let result=await installUngit();if(!result.success)installError=result.error||"Installation failed"}catch(err){installError=err instanceof Error?err.message:"Installation failed"}finally{isInstalling=!1}})(),{message:"Installation started -- poll GET /api/ungit/status"}}).post("/start",async({body,set})=>{let{workingDir,port}=body||{};if(!(await checkInstallation()).installed)return set.status=400,{error:"Ungit is not installed. POST /api/ungit/install first"};try{let result=await startUngit({workingDir,port});return{message:"Ungit started",pid:result.pid,port:result.port,workingDir:workingDir||process.env.HOME||"/"}}catch(err){return set.status=500,{error:err instanceof Error?err.message:"Failed to start"}}}).post("/stop",async()=>{return await stopUngit(),{message:"Ungit stopped"}}).post("/restart",async({body,set})=>{let{workingDir}=body||{};if(!(await checkInstallation()).installed)return set.status=400,{error:"Ungit is not installed"};await stopUngit();try{let result=await startUngit({workingDir});return{message:"Ungit restarted",pid:result.pid,port:result.port,workingDir:workingDir||process.env.HOME||"/"}}catch(err){return set.status=500,{error:err instanceof Error?err.message:"Failed to restart"}}})}var isInstalling=!1,installError=null;var init_routes2=__esm(()=>{init_routes()});var exports_proxy={};__export(exports_proxy,{default:()=>proxy_default,createUngitProxy:()=>createUngitProxy});import{Elysia as Elysia3}from"elysia";function generateSessionToken(){let bytes=new Uint8Array(32);return crypto.getRandomValues(bytes),Buffer.from(bytes).toString("base64url")}function createSession(){let token=generateSessionToken(),now=Date.now(),session={token,createdAt:now,expiresAt:now+SESSION_TTL_MS};return sessions.set(token,session),session}function validateSessionToken(token){let session=sessions.get(token);if(!session)return!1;if(Date.now()>session.expiresAt)return sessions.delete(token),!1;return!0}function cleanupSessions(){let now=Date.now();for(let[token,session]of sessions)if(now>session.expiresAt)sessions.delete(token)}function getCookie(cookieHeader,name){if(!cookieHeader)return null;let match=cookieHeader.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));return match?match[1]:null}function isAuthed(request,validateApiKey){let cookieHeader=request.headers.get("cookie"),sessionToken=getCookie(cookieHeader,COOKIE_NAME),apiKeyHeader=request.headers.get("x-agent-api-key"),apiKeyParam=new URL(request.url).searchParams.get("apiKey"),hasValidSession=sessionToken?validateSessionToken(sessionToken):!1,hasValidApiKey=apiKeyHeader!=null&&validateApiKey(apiKeyHeader)||apiKeyParam!=null&&validateApiKey(apiKeyParam);if(!hasValidApiKey&&!hasValidSession){let referer=request.headers.get("referer");if(referer)try{let refKey=new URL(referer).searchParams.get("apiKey");if(refKey&&validateApiKey(refKey))hasValidApiKey=!0}catch{}}return{hasValidSession,hasValidApiKey}}function stripPrefix(pathname){return pathname||"/"}function createUngitProxy(getPort,validateApiKey){return new Elysia3({prefix:"/ungit"}).all("/*",async({request})=>{return handleProxyRequest(request,getPort,validateApiKey)}).all("/",async({request})=>{return handleProxyRequest(request,getPort,validateApiKey)})}async function handleProxyRequest(request,getPort,validateApiKey){let{hasValidSession,hasValidApiKey}=isAuthed(request,validateApiKey);if(!hasValidSession&&!hasValidApiKey)return new Response(JSON.stringify({error:"Unauthorized -- provide a valid API key or session"}),{status:401,headers:{"Content-Type":"application/json"}});let sessionCookieHeader=null;if(!hasValidSession&&hasValidApiKey){let session=createSession();sessionCookieHeader=`${COOKIE_NAME}=${session.token}; Path=/ungit/; HttpOnly; SameSite=None; Secure; Max-Age=${Math.floor(SESSION_TTL_MS/1000)}`}let port=getPort();if(!port)return new Response(JSON.stringify({error:"Ungit is not running"}),{status:503,headers:{"Content-Type":"application/json"}});let response=await handleHttpProxy(request,port);if(sessionCookieHeader){let headers=new Headers(response.headers);return headers.set("Set-Cookie",sessionCookieHeader),new Response(response.body,{status:response.status,statusText:response.statusText,headers})}return response}async function handleHttpProxy(request,port){let url=new URL(request.url),strippedPath=stripPrefix(url.pathname),upstreamUrl=`http://127.0.0.1:${port}${strippedPath}${url.search}`,upstreamHeaders=new Headers,hopByHopHeaders=new Set(["connection","keep-alive","transfer-encoding","te","trailer","upgrade","proxy-authorization","proxy-authenticate"]);request.headers.forEach((value,key)=>{if(!hopByHopHeaders.has(key.toLowerCase()))upstreamHeaders.set(key,value)}),upstreamHeaders.set("Host",`127.0.0.1:${port}`);try{let upstreamResponse=await fetch(upstreamUrl,{method:request.method,headers:upstreamHeaders,body:request.method!=="GET"&&request.method!=="HEAD"?request.body:void 0,redirect:"manual"}),responseHeaders=new Headers;upstreamResponse.headers.forEach((value,key)=>{if(!STRIP_RESPONSE_HEADERS.has(key.toLowerCase()))responseHeaders.set(key,value)});let contentType=upstreamResponse.headers.get("content-type")||"";if(strippedPath==="/ungit/"&&!contentType.includes("text/html")){let body=await upstreamResponse.text();if(body.trimStart().startsWith("<!DOCTYPE")||body.trimStart().startsWith("<html"))return responseHeaders.set("content-type","text/html; charset=utf-8"),responseHeaders.delete("content-length"),new Response(body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders});return new Response(body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders})}return new Response(upstreamResponse.body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders})}catch(err){return new Response(JSON.stringify({error:"Failed to proxy to Ungit",details:err instanceof Error?err.message:"Unknown error"}),{status:502,headers:{"Content-Type":"application/json"}})}}var SESSION_TTL_MS=86400000,COOKIE_NAME="__vibe_ungit_session",sessions,STRIP_RESPONSE_HEADERS,proxy_default;var init_proxy=__esm(()=>{sessions=new Map;setInterval(cleanupSessions,600000);STRIP_RESPONSE_HEADERS=new Set(["x-frame-options","content-security-policy","x-content-type-options"]);proxy_default=createUngitProxy});var exports_context={};__export(exports_context,{registerContextProvider:()=>registerContextProvider,listContextProviders:()=>listContextProviders,getContextProvider:()=>getContextProvider,__resetContextProvidersForTests:()=>__resetContextProvidersForTests,CONTEXT_PROVIDER_TYPE:()=>CONTEXT_PROVIDER_TYPE});function registerContextProvider(provider,hostServices){if(!provider||typeof provider.name!=="string"||provider.name.length===0)throw Error("ContextProvider.name is required");if(typeof provider.getContext!=="function")throw Error("ContextProvider.getContext must be a function");contextProviders.set(provider.name,provider),hostServices?.serviceRegistry?.registerProvider?.(CONTEXT_PROVIDER_TYPE,provider,provider.name)}function listContextProviders(){return Array.from(contextProviders.values())}function getContextProvider(name){return contextProviders.get(name)}function __resetContextProvidersForTests(){contextProviders.clear()}var CONTEXT_PROVIDER_TYPE="context",contextProviders;var init_context=__esm(()=>{contextProviders=new Map});import{Elysia}from"elysia";function createLifecycleHooks(spec){let{name,onInit,onShutdown,telemetryEventName,skipPlatforms}=spec;return{onServerStart:async(_app,hostServices)=>{if(skipPlatforms&&skipPlatforms.includes(process.platform)){process.stderr.write(`[${name}] skipping init on unsupported platform '${process.platform}'
2
+ var __defProp=Object.defineProperty;var __returnValue=(v)=>v;function __exportSetter(name,newValue){this[name]=__returnValue.bind(null,newValue)}var __export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0,configurable:!0,set:__exportSetter.bind(all,name)})};var __esm=(fn,res)=>()=>(fn&&(res=fn(fn=0)),res);var __require=import.meta.require;async function isPortAvailable(port){try{return Bun.serve({port,hostname:"127.0.0.1",fetch(){return new Response}}).stop(!0),!0}catch{return!1}}async function findAvailablePort(preferred){let start=preferred??DEFAULT_PORT;if(await isPortAvailable(start))return start;for(let port=DEFAULT_PORT;port<=PORT_RANGE_END;port++){if(port===start)continue;if(await isPortAvailable(port))return port}throw Error(`No available port in range ${DEFAULT_PORT}-${PORT_RANGE_END}`)}async function checkInstallation(){try{let localPath=new URL("../../node_modules/.bin/ungit",import.meta.url).pathname;if(await Bun.file(localPath).exists())return{installed:!0,binaryPath:localPath}}catch{}try{let path=Bun.which("ungit");if(path)return{installed:!0,binaryPath:path}}catch{}return{installed:!1}}async function installUngit(){try{let proc=Bun.spawn(["npm","install","-g","ungit"],{stdout:"pipe",stderr:"pipe"}),exitCode=await proc.exited;if(exitCode!==0){let stderr=await new Response(proc.stderr).text();return{success:!1,error:`npm install -g ungit failed (exit ${exitCode}): ${stderr}`}}return{success:!0}}catch(err){return{success:!1,error:err instanceof Error?err.message:"Installation failed"}}}async function startUngit(options){if(childProcess&&currentPid){if(isProcessAlive(currentPid))return{pid:currentPid,port:currentPort};childProcess=null,currentPid=null}if(isStarting)throw Error("Ungit is already starting");isStarting=!0,lastError=null;try{let port=await findAvailablePort(options?.port),workingDir=options?.workingDir||process.env.HOME||"/",install=await checkInstallation();if(!install.installed||!install.binaryPath)throw Error("Ungit is not installed");let args=[install.binaryPath,"--port",String(port),"--no-b","--ungitBindIp","127.0.0.1","--rootPath","/ungit"],proc=Bun.spawn(args,{stdout:"pipe",stderr:"pipe",cwd:workingDir,env:{...process.env,PORT:void 0}});if(childProcess=proc,currentPort=port,currentWorkingDir=workingDir,currentPid=proc.pid,proc.exited.then((code)=>{if(childProcess===proc){if(childProcess=null,currentPid=null,code!==0&&code!==null)lastError=`Ungit exited with code ${code}`}}),await new Promise((resolve)=>setTimeout(resolve,2000)),!isProcessAlive(proc.pid)){let stderr=await new Response(proc.stderr).text();throw Error(`Ungit failed to start: ${stderr}`)}return{pid:proc.pid,port}}catch(err){throw lastError=err instanceof Error?err.message:"Failed to start",err}finally{isStarting=!1}}async function stopUngit(){if(!childProcess||!currentPid){childProcess=null,currentPid=null;return}let proc=childProcess,pid=currentPid;childProcess=null,currentPid=null,currentPort=null,currentWorkingDir=null,lastError=null;try{process.kill(pid,"SIGTERM")}catch{return}let deadline=Date.now()+5000;while(Date.now()<deadline&&isProcessAlive(pid))await new Promise((resolve)=>setTimeout(resolve,200));if(isProcessAlive(pid))try{process.kill(pid,"SIGKILL")}catch{}try{await proc.exited}catch{}}function getStatus(){let running=Boolean(currentPid&&isProcessAlive(currentPid));if(!running&&childProcess)childProcess=null,currentPid=null;return{installed:!0,running,pid:running?currentPid??void 0:void 0,port:running?currentPort??void 0:void 0,workingDir:running?currentWorkingDir??void 0:void 0,error:lastError??void 0}}function getRunningPort(){if(!currentPid||!isProcessAlive(currentPid))return null;return currentPort}function isProcessAlive(pid){try{return process.kill(pid,0),!0}catch{return!1}}var childProcess=null,currentPort=null,currentWorkingDir=null,currentPid=null,lastError=null,isStarting=!1,DEFAULT_PORT=8448,PORT_RANGE_END=8458;import{Elysia as Elysia2}from"elysia";var RoutesBuilder=class{constructor(pluginName,hostServices){this.pluginName=pluginName,this.hostServices=hostServices}pluginName;hostServices;prefix;apiKeyResolver;errorHandlerEnabled=!1;loggingEnabled=!1;withPrefix(prefix){return this.prefix=prefix,this}withAuth(getApiKey){return this.apiKeyResolver=getApiKey,this}withErrorHandler(){return this.errorHandlerEnabled=!0,this}withLogging(){return this.loggingEnabled=!0,this}build(){let opts=this.prefix?{prefix:this.prefix}:void 0,app=new Elysia2(opts);if(this.apiKeyResolver){let resolver=this.apiKeyResolver;app.onBeforeHandle(async({request,set})=>{let supplied=request.headers.get("x-api-key"),expected=await resolver();if(!supplied||supplied!==expected)return set.status=401,{error:"unauthorized"};return})}if(this.errorHandlerEnabled){let pluginName=this.pluginName,logger=this.hostServices?.logger;app.onError(({error,set})=>{let message=error instanceof Error?error.message:String(error);return logger?.error?.(pluginName,"route error",{message}),set.status=500,{error:message}})}if(this.loggingEnabled){let pluginName=this.pluginName,logger=this.hostServices?.logger;app.onRequest(({request})=>{logger?.debug?.(pluginName,"request",{method:request.method,url:request.url})})}return app}};var init_routes=()=>{};var exports_routes={};__export(exports_routes,{createUngitRoutes:()=>createUngitRoutes});function createUngitRoutes(hostServices){return new RoutesBuilder("ungit",hostServices).withPrefix("/api/ungit").withErrorHandler().build().get("/status",async()=>{let installInfo=await checkInstallation(),processStatus=getStatus();return{installed:installInfo.installed,installing:isInstalling,running:processStatus.running,pid:processStatus.pid,port:processStatus.port,workingDir:processStatus.workingDir,error:installError||processStatus.error||void 0}}).post("/install",async({set})=>{if(isInstalling)return set.status=409,{error:"Installation already in progress"};let check=await checkInstallation();if(check.installed)return{message:"Ungit is already installed",binaryPath:check.binaryPath};return isInstalling=!0,installError=null,(async()=>{try{let result=await installUngit();if(!result.success)installError=result.error||"Installation failed"}catch(err){installError=err instanceof Error?err.message:"Installation failed"}finally{isInstalling=!1}})(),{message:"Installation started -- poll GET /api/ungit/status"}}).post("/start",async({body,set})=>{let{workingDir,port}=body||{};if(!(await checkInstallation()).installed)return set.status=400,{error:"Ungit is not installed. POST /api/ungit/install first"};try{let result=await startUngit({workingDir,port});return{message:"Ungit started",pid:result.pid,port:result.port,workingDir:workingDir||process.env.HOME||"/"}}catch(err){return set.status=500,{error:err instanceof Error?err.message:"Failed to start"}}}).post("/stop",async()=>{return await stopUngit(),{message:"Ungit stopped"}}).post("/restart",async({body,set})=>{let{workingDir}=body||{};if(!(await checkInstallation()).installed)return set.status=400,{error:"Ungit is not installed"};await stopUngit();try{let result=await startUngit({workingDir});return{message:"Ungit restarted",pid:result.pid,port:result.port,workingDir:workingDir||process.env.HOME||"/"}}catch(err){return set.status=500,{error:err instanceof Error?err.message:"Failed to restart"}}})}var isInstalling=!1,installError=null;var init_routes2=__esm(()=>{init_routes()});var exports_proxy={};__export(exports_proxy,{default:()=>proxy_default,createUngitProxy:()=>createUngitProxy});import{Elysia as Elysia3}from"elysia";function generateSessionToken(){let bytes=new Uint8Array(32);return crypto.getRandomValues(bytes),Buffer.from(bytes).toString("base64url")}function createSession(){let token=generateSessionToken(),now=Date.now(),session={token,createdAt:now,expiresAt:now+SESSION_TTL_MS};return sessions.set(token,session),session}function validateSessionToken(token){let session=sessions.get(token);if(!session)return!1;if(Date.now()>session.expiresAt)return sessions.delete(token),!1;return!0}function cleanupSessions(){let now=Date.now();for(let[token,session]of sessions)if(now>session.expiresAt)sessions.delete(token)}function getCookie(cookieHeader,name){if(!cookieHeader)return null;let match=cookieHeader.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`));return match?match[1]:null}function isAuthed(request,validateApiKey){let cookieHeader=request.headers.get("cookie"),sessionToken=getCookie(cookieHeader,COOKIE_NAME),apiKeyHeader=request.headers.get("x-agent-api-key"),apiKeyParam=new URL(request.url).searchParams.get("apiKey"),hasValidSession=sessionToken?validateSessionToken(sessionToken):!1,hasValidApiKey=apiKeyHeader!=null&&validateApiKey(apiKeyHeader)||apiKeyParam!=null&&validateApiKey(apiKeyParam);if(!hasValidApiKey&&!hasValidSession){let referer=request.headers.get("referer");if(referer)try{let refKey=new URL(referer).searchParams.get("apiKey");if(refKey&&validateApiKey(refKey))hasValidApiKey=!0}catch{}}return{hasValidSession,hasValidApiKey}}function stripPrefix(pathname){return pathname||"/"}function createUngitProxy(getPort,validateApiKey){return new Elysia3({prefix:"/ungit"}).all("/*",async({request})=>{return handleProxyRequest(request,getPort,validateApiKey)}).all("/",async({request})=>{return handleProxyRequest(request,getPort,validateApiKey)})}async function handleProxyRequest(request,getPort,validateApiKey){let{hasValidSession,hasValidApiKey}=isAuthed(request,validateApiKey);if(!hasValidSession&&!hasValidApiKey)return new Response(JSON.stringify({error:"Unauthorized -- provide a valid API key or session"}),{status:401,headers:{"Content-Type":"application/json"}});let sessionCookieHeader=null;if(!hasValidSession&&hasValidApiKey){let session=createSession();sessionCookieHeader=`${COOKIE_NAME}=${session.token}; Path=/ungit/; HttpOnly; SameSite=None; Secure; Max-Age=${Math.floor(SESSION_TTL_MS/1000)}`}let port=getPort();if(!port)return new Response(JSON.stringify({error:"Ungit is not running"}),{status:503,headers:{"Content-Type":"application/json"}});let response=await handleHttpProxy(request,port);if(sessionCookieHeader){let headers=new Headers(response.headers);return headers.set("Set-Cookie",sessionCookieHeader),new Response(response.body,{status:response.status,statusText:response.statusText,headers})}return response}async function handleHttpProxy(request,port){let url=new URL(request.url),strippedPath=stripPrefix(url.pathname),upstreamUrl=`http://127.0.0.1:${port}${strippedPath}${url.search}`,upstreamHeaders=new Headers,hopByHopHeaders=new Set(["connection","keep-alive","transfer-encoding","te","trailer","upgrade","proxy-authorization","proxy-authenticate"]);request.headers.forEach((value,key)=>{if(!hopByHopHeaders.has(key.toLowerCase()))upstreamHeaders.set(key,value)}),upstreamHeaders.set("Host",`127.0.0.1:${port}`);try{let upstreamResponse=await fetch(upstreamUrl,{method:request.method,headers:upstreamHeaders,body:request.method!=="GET"&&request.method!=="HEAD"?request.body:void 0,redirect:"manual"}),responseHeaders=new Headers;upstreamResponse.headers.forEach((value,key)=>{if(!STRIP_RESPONSE_HEADERS.has(key.toLowerCase()))responseHeaders.set(key,value)});let contentType=upstreamResponse.headers.get("content-type")||"";if(strippedPath==="/ungit/"&&!contentType.includes("text/html")){let body=await upstreamResponse.text();if(body.trimStart().startsWith("<!DOCTYPE")||body.trimStart().startsWith("<html"))return responseHeaders.set("content-type","text/html; charset=utf-8"),responseHeaders.delete("content-length"),new Response(body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders});return new Response(body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders})}return new Response(upstreamResponse.body,{status:upstreamResponse.status,statusText:upstreamResponse.statusText,headers:responseHeaders})}catch(err){return new Response(JSON.stringify({error:"Failed to proxy to Ungit",details:err instanceof Error?err.message:"Unknown error"}),{status:502,headers:{"Content-Type":"application/json"}})}}var SESSION_TTL_MS=86400000,COOKIE_NAME="__vibe_ungit_session",sessions,STRIP_RESPONSE_HEADERS,proxy_default;var init_proxy=__esm(()=>{sessions=new Map;setInterval(cleanupSessions,600000);STRIP_RESPONSE_HEADERS=new Set(["x-frame-options","content-security-policy","x-content-type-options"]);proxy_default=createUngitProxy});var exports_context={};__export(exports_context,{registerContextProvider:()=>registerContextProvider,listContextProviders:()=>listContextProviders,getContextProvider:()=>getContextProvider,__resetContextProvidersForTests:()=>__resetContextProvidersForTests,CONTEXT_PROVIDER_TYPE:()=>CONTEXT_PROVIDER_TYPE});function getRegistry(){let slots=globalThis,existing=slots[REGISTRY_KEY];if(existing)return existing;let created=new Map;return slots[REGISTRY_KEY]=created,created}function registerContextProvider(provider,hostServices){if(!provider||typeof provider.name!=="string"||provider.name.length===0)throw Error("ContextProvider.name is required");if(typeof provider.getContext!=="function")throw Error("ContextProvider.getContext must be a function");getRegistry().set(provider.name,provider),hostServices?.serviceRegistry?.registerProvider?.(CONTEXT_PROVIDER_TYPE,provider,provider.name)}function listContextProviders(){return Array.from(getRegistry().values())}function getContextProvider(name){return getRegistry().get(name)}function __resetContextProvidersForTests(){getRegistry().clear()}var CONTEXT_PROVIDER_TYPE="context",REGISTRY_KEY;var init_context=__esm(()=>{REGISTRY_KEY=Symbol.for("@vibecontrols/plugin-sdk:contextProviders@1")});import{Elysia}from"elysia";function createLifecycleHooks(spec){let{name,onInit,onShutdown,telemetryEventName,skipPlatforms}=spec;return{onServerStart:async(_app,hostServices)=>{if(skipPlatforms&&skipPlatforms.includes(process.platform)){process.stderr.write(`[${name}] skipping init on unsupported platform '${process.platform}'
3
3
  `);return}if(onInit)await onInit(hostServices);if(telemetryEventName)hostServices.telemetry?.emit(telemetryEventName,{plugin:name})},onServerStop:async(hostServices)=>{if(onShutdown)await onShutdown(hostServices)}}}function pickOutputMode(flags){if(flags.json)return"json";if(flags.plain)return"plain";if(flags.interactive)return"interactive";return"auto"}function isCi(){return!!process.env.CI||!!process.env.NO_COLOR||process.env.TERM==="dumb"}function stdoutIsTty(){return Boolean(process.stdout.isTTY)}async function runMultimode(opts){let data=await opts.fetchData(),mode=opts.mode??"auto";if(mode==="json"){let shaped=opts.json?opts.json(data):data;process.stdout.write(`${JSON.stringify(shaped,null,2)}
4
4
  `);return}if(mode==="plain"){await opts.plain(data);return}if((mode==="interactive"||stdoutIsTty()&&!isCi())&&!!opts.interactive&&opts.interactive)try{await opts.interactive(data);return}catch{}await opts.plain(data)}function maybePrintJson(flags,data){if(!flags.json)return!1;return process.stdout.write(`${JSON.stringify(data,null,2)}
5
5
  `),!0}var SENSITIVE_KEY_RE=/(token|secret|password|apikey|api_key|key|auth|credential|email)/i;function redact(value){return redactInner(value)}function redactInner(value){if(value===null||value===void 0)return value;if(Array.isArray(value))return value.map(redactInner);if(typeof value==="object"){let out={};for(let[k,v]of Object.entries(value)){if(SENSITIVE_KEY_RE.test(k)){out[k]="[redacted]";continue}out[k]=redactInner(v)}return out}return value}var TelemetryEmitter=class{constructor(pluginName,pluginVersion,hostServices){this.pluginName=pluginName,this.pluginVersion=pluginVersion,this.hostServices=hostServices}pluginName;pluginVersion;hostServices;emit(eventName,payload){let target=this.hostServices?.telemetry;if(!target)return;target.emit(eventName,{plugin:this.pluginName,version:this.pluginVersion,timestamp:new Date().toISOString(),...payload??{}})}emitReady(context){this.emit(`${this.pluginName}.ready`,context)}emitError(error,context){this.emit(`${this.pluginName}.error`,{message:error.message,...context??{}})}emitEvent(type,payload){this.emit(type,payload)}};async function loadCore(){return await import("@opentui/core")}async function interactiveDetail(opts){let core=await loadCore(),{createCliRenderer,BoxRenderable,TextRenderable}=core,renderer=await createCliRenderer({exitOnCtrlC:!0,targetFps:30}),ctx=renderer.root.ctx,root=new BoxRenderable(ctx,{width:"100%",height:"100%",flexDirection:"column",backgroundColor:"#0b0d12"}),title=new TextRenderable(ctx,{content:` ${opts.title}`,fg:"#8be9fd",height:1}),bodyBox=new BoxRenderable(ctx,{width:"100%",flexGrow:1,paddingLeft:2,paddingRight:2,backgroundColor:"#11141c"}),bodyText=new TextRenderable(ctx,{content:`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecontrols/vibe-plugin-tool-git",
3
- "version": "2026.525.2",
3
+ "version": "2026.527.1",
4
4
  "main": "./dist/index.js",
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,7 +35,7 @@
35
35
  "license": "SEE LICENSE IN LICENSE",
36
36
  "description": "Visual Git Client (Ungit) — reverse-proxied through the VibeControls agent",
37
37
  "dependencies": {
38
- "@vibecontrols/plugin-sdk": "2026.522.1",
38
+ "@vibecontrols/plugin-sdk": "2026.527.1",
39
39
  "ungit": "^1.5.28"
40
40
  },
41
41
  "devDependencies": {