@vibecontrols/vibe-plugin-session-wezterm 2026.711.1 → 2026.1108.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 +34 -22
package/dist/index.js CHANGED
@@ -9,5 +9,5 @@ import{spawn as spawnChild}from"child_process";import{existsSync as existsSync2,
9
9
  `)){let parts=line.trim().split(/\s+/),pid=parseInt(parts[0]??"0",10);if(!pid)continue;if([...this.ttydPids.values()].includes(pid))continue;let portIdx=parts.indexOf("--port"),port=portIdx!==-1?parseInt(parts[portIdx+1]??"0",10):0;terminals.push({pid,port:port||0})}}catch{}return terminals}async bulkKillSystemSessions(sessionIds){let killed=0,failed=0;for(let wsName of sessionIds){let panes=weztermListPanes().filter((p)=>p.workspace===wsName);if(panes.length===0)if(weztermCliExecSilent(["kill-pane","--pane-id",wsName]))killed++;else failed++;else{let wsKilled=!1;for(let pane of panes)if(weztermCliExecSilent(["kill-pane","--pane-id",String(pane.pane_id)]))wsKilled=!0;if(wsKilled)killed++;else failed++}}return this.log.info("Bulk kill system sessions",{killed,failed}),{killed,failed}}async bulkKillSystemTerminals(pids){let killed=0,failed=0,killPromises=pids.map(async(pid)=>{try{await gracefulKill(pid),killed++;for(let[sessionId,trackedPid]of this.ttydPids)if(trackedPid===pid){this.ttydPids.delete(sessionId),this.ttydPorts.delete(sessionId);break}}catch{failed++}});return await Promise.allSettled(killPromises),this.log.info("Bulk kill system terminals",{killed,failed}),{killed,failed}}async healthCheck(){let weztermOk,weztermVersion,sessionCount=0,terminalCount=this.ttydPids.size;try{weztermVersion=weztermExec(["--version"]),weztermOk=!0}catch{return{ok:!1,sessions:0,terminals:terminalCount,message:"wezterm is not available"}}try{sessionCount=(await this.listSystemSessions()).length}catch{}let ttydOk=!1;try{ttydOk=resolveBinary("ttyd")!==null}catch{}let messages=[weztermVersion];if(!ttydOk)messages.push("ttyd not found \u2014 web terminals unavailable");return{ok:weztermOk,sessions:sessionCount,terminals:terminalCount,message:messages.join("; ")}}async getSessionsByProject(projectId){return(await this.list()).filter((s)=>s.projectId===projectId)}async cleanup(){this.log.info("Running cleanup");let sessions=await this.loadSessions(),cleaned=0,kept=[];for(let session of sessions){let workspaceName=this.getWorkspaceName(session),exists=this.workspaceExists(workspaceName);if(session.status==="terminated"||!exists){if(this.ttydPids.has(session.id))await this.stopTerminal(session.id);if(exists&&session.status==="terminated"){let panes=weztermListPanes().filter((p)=>p.workspace===workspaceName);for(let pane of panes)weztermCliExecSilent(["kill-pane","--pane-id",String(pane.pane_id)])}cleaned++,this.log.debug("Cleaned session",{id:session.id,name:session.name})}else kept.push(session)}return await this.saveSessions(kept),this.log.info("Cleanup complete",{cleaned,remaining:kept.length}),{cleaned}}async get(sessionId){return this.getInfo(sessionId)}async kill(sessionId){return this.terminate(sessionId)}async interrupt(sessionId){return this.sendInterrupt(sessionId)}async capture(sessionId){return this.captureOutput(sessionId)}async resize(sessionId,cols,rows){let session=await this.requireSession(sessionId),paneId=this.requirePaneId(session);this.log.warn("resize: WezTerm CLI does not support absolute pane resize. The pane will auto-size based on the window or ttyd terminal.",{sessionId,paneId,requestedCols:cols,requestedRows:rows})}async listSystem(){return this.listSystemSessions()}async killSystem(sessionId){let panes=weztermListPanes().filter((p)=>p.workspace===sessionId);for(let pane of panes)weztermCliExecSilent(["kill-pane","--pane-id",String(pane.pane_id)])}async killSystemTerminal(pid){await gracefulKill(pid);for(let[sessionId,trackedPid]of this.ttydPids)if(trackedPid===pid){this.ttydPids.delete(sessionId),this.ttydPorts.delete(sessionId);break}}async discoverOrphans(){let known=new Set((await this.loadSessions()).filter((s)=>s.status!=="terminated").map((s)=>this.getWorkspaceName(s)));return(await this.listSystemSessions()).filter((s)=>s.name.startsWith("vibe-")&&!known.has(s.name)).map((s)=>({externalName:s.name,provider:"wezterm",windows:s.windows,attached:s.attached,createdAt:s.createdAt}))}async adopt(externalName,displayName){if(!externalName.startsWith("vibe-"))throw Error(`Refusing to adopt wezterm workspace "${externalName}" \u2014 only vibe-* workspaces are adoptable`);if(!(await this.listSystemSessions()).find((s)=>s.name===externalName))throw Error(`Wezterm workspace "${externalName}" does not exist`);let id=externalName.slice(5)||externalName,existing=(await this.loadSessions()).find((s)=>s.id===id);if(existing){if(!this.ttydPids.has(id))try{await this.startTerminal(id)}catch{}return await this.get(id)??existing}let now=nowISO(),info={id,name:displayName||externalName,status:"active",provider:this.name,createdAt:now,updatedAt:now,metadata:{weztermWorkspace:externalName,adopted:!0}};await this.saveSession(info);try{info.terminal=await this.startTerminal(id),await this.saveSession(info)}catch{}return info}getCapabilities(){return{provider:"wezterm",features:{mouse:!0,resize:!0,capture:!0,webTerminal:!0,splitPanes:!0,tabs:!0,scrollback:!0,clipboard:!0,search:!0},platform:["linux","macos","windows"]}}async getScrollback(sessionId,lines){let session=await this.requireSession(sessionId),paneId=this.requirePaneId(session);this.log.debug("Getting scrollback",{sessionId,lines});try{return weztermCliExec(["get-text","--pane-id",String(paneId)]).split(`
10
10
  `).slice(-lines).join(`
11
11
  `)}catch(err){throw this.log.error("Failed to get scrollback",{sessionId,error:String(err)}),Error(`Failed to get scrollback for session ${sessionId}: ${err}`,{cause:err})}}async searchOutput(sessionId,pattern){let lines=(await this.getScrollback(sessionId,1e4)).split(`
12
- `),results=[],regex;try{regex=new RegExp(pattern)}catch{regex=new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))}for(let i=0;i<lines.length;i++)if(regex.test(lines[i]??""))results.push({line:i+1,content:lines[i]??""});return this.log.debug("Search output completed",{sessionId,pattern,matches:results.length}),results}async loadSessions(){if(!this.sessionsStore)return[];return await this.sessionsStore.get()??[]}async saveSessions(sessions){if(!this.sessionsStore)return;try{await this.sessionsStore.set(sessions)}catch(err){this.log.error("Failed to save sessions to storage",{error:String(err)})}}async saveSession(session){let sessions=await this.loadSessions(),idx=sessions.findIndex((s)=>s.id===session.id);if(idx>=0)sessions[idx]=session;else sessions.push(session);await this.saveSessions(sessions)}getWorkspaceName(session){let meta=session.metadata;if(meta&&typeof meta.weztermWorkspace==="string")return meta.weztermWorkspace;return`vibe-${session.id}`}getPaneId(session){let meta=session.metadata;if(meta&&typeof meta.weztermPaneId==="number")return meta.weztermPaneId;return null}requirePaneId(session){let paneId=this.getPaneId(session);if(paneId===null)throw Error(`No wezterm pane ID found for session ${session.id}. Session may be corrupted.`);return paneId}workspaceExists(workspaceName){return weztermListPanes().some((p)=>p.workspace===workspaceName)}getPanePid(paneId){try{let pane=weztermListPanes().find((p)=>p.pane_id===paneId);if(pane&&typeof pane.pid==="number")return pane.pid;return null}catch{return null}}async requireSession(sessionId){let session=await this.getInfo(sessionId);if(!session)throw Error(`Session not found: ${sessionId}`);if(session.status==="terminated")throw Error(`Session is terminated: ${sessionId}`);return session}getRunningTerminalInfo(sessionId){let pid=this.ttydPids.get(sessionId),port=this.ttydPorts.get(sessionId);if(!pid||port===void 0)return null;if(!isProcessAlive(pid))return this.ttydPids.delete(sessionId),this.ttydPorts.delete(sessionId),null;return{url:`http://localhost:${port}`,port,pid,host:"127.0.0.1",wsPath:"/ws",subprotocols:["tty"]}}async ensureDependencies(){try{let version=weztermExec(["--version"]);this.log.info("wezterm detected",{version:version.trim()});return}catch{this.log.info("wezterm not found \u2014 attempting auto-install")}try{let result={ok:!0,installed:[],pendingSudo:[],errors:[]};if(installWezterm(result),result.pendingSudo.length>0)for(let ps of result.pendingSudo)this.log.info(`wezterm needs a manual install step: ${ps.command}`);if(result.errors.length>0)this.log.warn(`wezterm installer reported: ${result.errors.map((e)=>e.message).join("; ")}`);weztermToolPathCache.delete("wezterm");let resolved=resolveWeztermTool("wezterm");if(resolved!=="wezterm"||whichLive("wezterm")){let dir=resolved.includes("/")||resolved.includes("\\")?joinPath(resolved,".."):null;if(dir){let sep=process.platform==="win32"?";":":",parts=(process.env.PATH||"").split(sep);if(!parts.includes(dir))process.env.PATH=[dir,...parts].join(sep)}}let version=weztermExec(["--version"]);this.log.info("wezterm auto-installed successfully",{version:version.trim()})}catch(err){throw this.log.error("Failed to auto-install wezterm",{error:String(err)}),Error("wezterm is not available; install WezTerm and restart the agent",{cause:err})}}async ensureMuxServer(){if(weztermCliExecSilent(["list"])){this.log.info("Connected to existing wezterm mux server");return}this.log.info("No wezterm mux server detected \u2014 starting wezterm-mux-server");try{if(!weztermToolResolvable("wezterm-mux-server"))throw Error("Executable not found in PATH: wezterm-mux-server");let muxServer=resolveWeztermTool("wezterm-mux-server");if(isWindows()){let child=spawnChild(muxServer,[],{detached:!0,windowsHide:!0,stdio:"ignore"});child.on("error",(error)=>{this.log.error("wezterm-mux-server process error",{error:String(error)})}),child.unref()}else{let result=Bun.spawnSync([muxServer,"--daemonize"],{stdout:"pipe",stderr:"pipe",timeout:1e4});if(result.exitCode!==0)throw Error(result.stderr.toString().trim()||"non-zero exit")}let ready=!1;for(let i=0;i<10;i++)if(await sleep(500),weztermCliExecSilent(["list"])){ready=!0;break}if(ready)this.log.info("wezterm-mux-server started successfully");else throw Error("wezterm-mux-server started but not responding to CLI")}catch(err){throw this.log.error("Failed to start wezterm-mux-server",{error:String(err)}),err}}async persistTerminals(){if(!this.terminalsStore)return;try{let entries=[];for(let[sessionId,pid]of this.ttydPids){let port=this.ttydPorts.get(sessionId);if(port!==void 0)entries.push({sessionId,pid,port})}await this.terminalsStore.set(entries)}catch(err){this.log.error("Failed to persist terminals",{error:String(err)})}}async loadPersistedTerminals(){if(!this.terminalsStore)return[];return await this.terminalsStore.get()??[]}async reconcileSessions(){let persisted=await this.loadPersistedTerminals();if(persisted.length>0){this.log.info("Recovering persisted terminals",{count:persisted.length});for(let entry of persisted)if(isProcessAlive(entry.pid))this.ttydPids.set(entry.sessionId,entry.pid),this.ttydPorts.set(entry.sessionId,entry.port),this.log.info("Re-adopted ttyd process",{sessionId:entry.sessionId,pid:entry.pid,port:entry.port});else this.log.info("Persisted ttyd process is dead, skipping",{sessionId:entry.sessionId,pid:entry.pid});try{await this.terminalsStore?.delete()}catch{}}if(!isWindows())try{let raw=Bun.spawnSync(["pgrep","-a","ttyd"],{stdout:"pipe",stderr:"pipe",timeout:5000}).stdout.toString().trim();if(raw){let sessions2=await this.loadSessions(),portToSession=new Map;for(let session of sessions2)if(session.terminal?.port)portToSession.set(session.terminal.port,session.id);for(let line of raw.split(`
12
+ `),results=[],regex;try{regex=new RegExp(pattern)}catch{regex=new RegExp(pattern.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))}for(let i=0;i<lines.length;i++)if(regex.test(lines[i]??""))results.push({line:i+1,content:lines[i]??""});return this.log.debug("Search output completed",{sessionId,pattern,matches:results.length}),results}async loadSessions(){if(!this.sessionsStore)return[];return await this.sessionsStore.get()??[]}async saveSessions(sessions){if(!this.sessionsStore)return;try{await this.sessionsStore.set(sessions)}catch(err){this.log.error("Failed to save sessions to storage",{error:String(err)})}}async saveSession(session){let sessions=await this.loadSessions(),idx=sessions.findIndex((s)=>s.id===session.id);if(idx>=0)sessions[idx]=session;else sessions.push(session);await this.saveSessions(sessions)}getWorkspaceName(session){let meta=session.metadata;if(meta&&typeof meta.weztermWorkspace==="string")return meta.weztermWorkspace;return`vibe-${session.id}`}getPaneId(session){let meta=session.metadata;if(meta&&typeof meta.weztermPaneId==="number")return meta.weztermPaneId;return null}requirePaneId(session){let paneId=this.getPaneId(session);if(paneId===null)throw Error(`No wezterm pane ID found for session ${session.id}. Session may be corrupted.`);return paneId}workspaceExists(workspaceName){return weztermListPanes().some((p)=>p.workspace===workspaceName)}getPanePid(paneId){try{let pane=weztermListPanes().find((p)=>p.pane_id===paneId);if(pane&&typeof pane.pid==="number")return pane.pid;return null}catch{return null}}async requireSession(sessionId){let session=await this.getInfo(sessionId);if(!session)throw Error(`Session not found: ${sessionId}`);if(session.status==="terminated")throw Error(`Session is terminated: ${sessionId}`);return session}getRunningTerminalInfo(sessionId){let pid=this.ttydPids.get(sessionId),port=this.ttydPorts.get(sessionId);if(!pid||port===void 0)return null;if(!isProcessAlive(pid))return this.ttydPids.delete(sessionId),this.ttydPorts.delete(sessionId),null;return{url:`http://localhost:${port}`,port,pid,host:"127.0.0.1",wsPath:"/ws",subprotocols:["tty"]}}async ensureDependencies(){try{let version=weztermExec(["--version"]);this.log.info("wezterm detected",{version:version.trim()});return}catch{this.log.info("wezterm not found \u2014 attempting auto-install")}try{let result={ok:!0,installed:[],pendingSudo:[],errors:[]};if(installWezterm(result),result.pendingSudo.length>0)for(let ps of result.pendingSudo)this.log.info(`wezterm needs a manual install step: ${ps.command}`);if(result.errors.length>0)this.log.warn(`wezterm installer reported: ${result.errors.map((e)=>e.message).join("; ")}`);weztermToolPathCache.delete("wezterm");let resolved=resolveWeztermTool("wezterm");if(resolved!=="wezterm"||whichLive("wezterm")){let dir=resolved.includes("/")||resolved.includes("\\")?joinPath(resolved,".."):null;if(dir){let sep=process.platform==="win32"?";":":",parts=(process.env.PATH||"").split(sep);if(!parts.includes(dir))process.env.PATH=[dir,...parts].join(sep)}}let version=weztermExec(["--version"]);this.log.info("wezterm auto-installed successfully",{version:version.trim()})}catch(err){throw this.log.error("Failed to auto-install wezterm",{error:String(err)}),Error("wezterm is not available; install WezTerm and restart the agent",{cause:err})}}async ensureMuxServer(){if(weztermCliExecSilent(["list"])){this.log.info("Connected to existing wezterm mux server");return}this.log.info("No wezterm mux server detected \u2014 starting wezterm-mux-server");try{if(!weztermToolResolvable("wezterm-mux-server"))throw Error("Executable not found in PATH: wezterm-mux-server");let muxServer=resolveWeztermTool("wezterm-mux-server");if(isWindows()){let child=spawnChild(muxServer,[],{detached:!0,windowsHide:!0,stdio:"ignore"});child.on("error",(error)=>{this.log.error("wezterm-mux-server process error",{error:String(error)})}),child.unref()}else{let result=Bun.spawnSync([muxServer,"--daemonize"],{stdout:"pipe",stderr:"pipe",timeout:1e4});if(result.exitCode!==0)throw Error(result.stderr.toString().trim()||"non-zero exit")}let ready=!1;for(let i=0;i<10;i++)if(await sleep(500),weztermCliExecSilent(["list"])){ready=!0;break}if(ready)this.log.info("wezterm-mux-server started successfully");else throw Error("wezterm-mux-server started but not responding to CLI")}catch(err){throw this.log.error("Failed to start wezterm-mux-server",{error:String(err)}),err}}async persistTerminals(){if(!this.terminalsStore)return;try{let entries=[];for(let[sessionId,pid]of this.ttydPids){let port=this.ttydPorts.get(sessionId);if(port!==void 0)entries.push({sessionId,pid,port})}await this.terminalsStore.set(entries)}catch(err){this.log.error("Failed to persist terminals",{error:String(err)})}}async loadPersistedTerminals(){if(!this.terminalsStore)return[];return await this.terminalsStore.get()??[]}async reconcileSessions(){let persisted=await this.loadPersistedTerminals();if(persisted.length>0){this.log.info("Recovering persisted terminals",{count:persisted.length});for(let entry of persisted)if(isProcessAlive(entry.pid))this.ttydPids.set(entry.sessionId,entry.pid),this.ttydPorts.set(entry.sessionId,entry.port),this.log.info("Re-adopted ttyd process",{sessionId:entry.sessionId,pid:entry.pid,port:entry.port});else this.log.info("Persisted ttyd process is dead, skipping",{sessionId:entry.sessionId,pid:entry.pid});try{await this.terminalsStore?.delete()}catch{}}if(!isWindows())try{let raw=Bun.spawnSync(["pgrep","-a","ttyd"],{stdout:"pipe",stderr:"pipe",timeout:5000}).stdout.toString().trim();if(raw){let sessions=await this.loadSessions(),portToSession=new Map;for(let session of sessions)if(session.terminal?.port)portToSession.set(session.terminal.port,session.id);for(let line of raw.split(`
13
13
  `)){let parts=line.trim().split(/\s+/),pid=parseInt(parts[0]??"0",10);if(!pid)continue;if([...this.ttydPids.values()].includes(pid))continue;let portIdx=parts.indexOf("--port"),port=portIdx!==-1?parseInt(parts[portIdx+1]??"0",10):0;if(!port)continue;let sessionId=portToSession.get(port);if(sessionId&&!this.ttydPids.has(sessionId))this.ttydPids.set(sessionId,pid),this.ttydPorts.set(sessionId,port),this.log.info("Recovered orphaned ttyd process by port match",{sessionId,pid,port})}}}catch{}let sessions=await this.loadSessions(),changed=!1;for(let session of sessions){if(session.status==="terminated")continue;let previousStatus=session.status;if(this.refreshSessionStatus(session))this.log.info("Reconciled session status",{id:session.id,name:session.name,previousStatus,status:session.status}),changed=!0}if(changed)await this.saveSessions(sessions)}}var provider=new WeztermSessionProvider;function whichLive(bin){return Bun.which(bin,{PATH:process.env.PATH})??null}var WEZTERM_REASON="wezterm is required for the WezTerm session backend.";function runInstaller(command){try{return Bun.spawnSync(normalizeWindowsCommand(command),{stdout:"pipe",stderr:"pipe",timeout:300000,env:process.env}).exitCode===0}catch{return!1}}function resolvePkgManager(name){let live=whichLive(name);if(live)return live;let home=process.env.HOME||process.env.USERPROFILE||homedir2();if(process.platform==="win32"){let localApp=process.env.LOCALAPPDATA||joinPath(home,"AppData","Local"),choco=process.env.ChocolateyInstall||"C:\\ProgramData\\chocolatey",known={winget:[joinPath(localApp,"Microsoft","WindowsApps","winget.exe")],scoop:[joinPath(home,"scoop","shims","scoop.cmd")],choco:[joinPath(choco,"bin","choco.exe")]};for(let p of known[name]??[])if(existsSync2(p))return p;return null}for(let dir of["/opt/homebrew/bin","/usr/local/bin","/usr/bin"]){let candidate=joinPath(dir,name);if(existsSync2(candidate))return candidate}return null}function weztermResolvable(){return weztermToolPathCache.delete("wezterm"),resolveWeztermTool("wezterm")!=="wezterm"||!!whichLive("wezterm")}function installWezterm(result){let platform=process.platform;if(platform==="win32"){for(let winget of[resolvePkgManager("winget"),"winget"].filter((v)=>typeof v==="string"&&v.length>0))if(runInstaller([winget,"install","--id","wez.wezterm","-e","--silent","--disable-interactivity","--accept-source-agreements","--accept-package-agreements"]),weztermResolvable()){result.installed.push("wezterm");return}for(let scoop of[resolvePkgManager("scoop"),"scoop"].filter((v)=>typeof v==="string"&&v.length>0))if(runInstaller([scoop,"bucket","add","extras"]),runInstaller([scoop,"install","wezterm"]),weztermResolvable()){result.installed.push("wezterm");return}for(let choco of[resolvePkgManager("choco"),"choco"].filter((v)=>typeof v==="string"&&v.length>0))if(runInstaller([choco,"install","wezterm","-y","--no-progress"]),weztermResolvable()){result.installed.push("wezterm");return}result.errors.push({name:"wezterm",message:"Could not auto-install wezterm \u2014 no usable winget/scoop/choco found or the install failed. "+"Install manually: https://wezfurlong.org/wezterm/install/windows.html"});return}if(platform==="darwin"){let brew=resolvePkgManager("brew");if(brew){if(runInstaller([brew,"install","--cask","wezterm"]),weztermResolvable()){result.installed.push("wezterm");return}}result.errors.push({name:"wezterm",message:"Could not auto-install wezterm via Homebrew. Install Homebrew (https://brew.sh) then run `brew install --cask wezterm`, or follow https://wezfurlong.org/wezterm/install/macos.html"});return}result.pendingSudo.push({name:"wezterm",command:"Install wezterm from your distro package manager or the official "+"repository \u2014 see https://wezfurlong.org/wezterm/install/linux.html",reason:WEZTERM_REASON})}function createPrereqsRoutes(){return new Elysia({prefix:"/prereqs"}).get("/status",()=>{let missing=[];if(!weztermResolvable())missing.push({name:"wezterm",kind:"binary",requiresSudo:!1});if(!resolveBinary("ttyd"))missing.push({name:"ttyd",kind:"binary",requiresSudo:!1});return{satisfied:missing.length===0,missing}}).post("/install",async()=>{let result={ok:!0,installed:[],pendingSudo:[],errors:[]};if(!weztermResolvable())installWezterm(result);if(!resolveBinary("ttyd"))try{await ensureTtydBinary(),result.installed.push("ttyd")}catch(err){result.pendingSudo.push({name:"ttyd",command:ttydManualInstallCommand(),reason:`ttyd auto-download failed: ${err instanceof Error?err.message:String(err)}`})}return result.ok=result.errors.length===0&&result.pendingSudo.length===0,result}).post("/uninstall",()=>({ok:!0}))}var createPlugin=(_ctx)=>{let lifecycle=createLifecycleHooks({name:PLUGIN_NAME,skipPlatforms:[],telemetryEventName:`${PLUGIN_NAME}.ready`,onInit:async(services)=>{await provider.init(services),new ProviderRegistry(services).registerProvider("session",PROVIDER_NAME,provider),new TelemetryEmitter(PLUGIN_NAME,PLUGIN_VERSION,services).emit("session.provider.ready",{provider:"wezterm"})},onShutdown:async()=>{await provider.shutdown({reason:"shutdown"})},onNuke:async(_hostServices,ctx)=>{if(ctx.dryRun)return{reaped:["ttyd terminal-servers + wezterm workspaces + storage"]};return{reaped:await provider.nuke()}}});return{capabilities:{storage:"rw",subprocess:!0,telemetry:!0},name:PLUGIN_NAME,version:PLUGIN_VERSION,description:"WezTerm + ttyd session provider \u2014 manages terminal sessions via WezTerm workspaces and exposes web terminals via ttyd",tags:["backend","provider"],apiPrefix:"/api/session-wezterm",prerequisites:[{name:"wezterm",kind:"binary",requiresSudo:!1},{name:"ttyd",kind:"binary",requiresSudo:!1}],createRoutes:()=>createPrereqsRoutes(),onServerStart:lifecycle.onServerStart,onServerStop:lifecycle.onServerStop,onNuke:lifecycle.onNuke}};export{createPlugin};
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@vibecontrols/vibe-plugin-session-wezterm",
3
- "version": "2026.711.1",
3
+ "version": "2026.1108.1",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "description": "WezTerm + ttyd session provider plugin for VibeControls Agent",
7
7
  "engines": {
8
- "bun": ">=1.3.14"
8
+ "bun": ">=1.4.4"
9
9
  },
10
10
  "author": {
11
11
  "name": "Vignesh T.V",
@@ -13,32 +13,31 @@
13
13
  },
14
14
  "license": "MIT",
15
15
  "scripts": {
16
- "build": "bun build ./src/index.ts --outdir ./dist --target bun --minify-syntax --minify-whitespace --external elysia && tsc --emitDeclarationOnly --declaration --outDir ./dist",
17
- "dev": "tsc --watch",
18
- "lint": "eslint ./src",
19
- "lint:sanity": "if [ \"${CI:-}\" = \"true\" ]; then bun run lint; else bun run lint -- --cache --cache-location .eslintcache; fi",
20
- "format": "bunx prettier . --write",
21
- "format:check": "bunx prettier . --check",
22
- "type:check": "tsc --noEmit",
16
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun --minify-syntax --minify-whitespace --external elysia && tsc -p tsconfig.build.json",
17
+ "dev": "tsc -p tsconfig.build.json --watch",
18
+ "lint": "eslint .",
19
+ "format": "bun fmt",
20
+ "format:check": "bun fmt --check",
21
+ "type:check": "boff gate -- bun check --no-pretty",
23
22
  "clean": "rimraf dist",
24
23
  "prebuild": "bun run clean",
25
24
  "prepublishOnly": "bun run build",
26
- "sanity": "bun run format:check && bun run lint:sanity && bun run type:check && bun run build"
25
+ "sanity": "boff sanity",
26
+ "test": "bun test",
27
+ "sanity:force": "boff sanity --force",
28
+ "audit": "bun audit --audit-level=high"
27
29
  },
28
30
  "dependencies": {
29
31
  "@vibecontrols/plugin-sdk": "2026.530.5",
30
32
  "elysia": "^1.4.28"
31
33
  },
32
34
  "devDependencies": {
33
- "@eslint/js": "^10.0.1",
34
- "@types/bun": "^1.3.9",
35
- "@types/node": "^22.0.0",
36
- "eslint": "^9.30.1",
37
- "globals": "^17.3.0",
38
- "prettier": "^3.6.2",
39
- "rimraf": "^6.0.1",
40
- "typescript": "^5.9.3",
41
- "typescript-eslint": "^8.56.0"
35
+ "@burdenoff/toolchain": "2026.1107.14",
36
+ "@types/bun": "^1.4.4",
37
+ "eslint": "^9.39.5",
38
+ "knip": "^6.44.1",
39
+ "rimraf": "^6.1.4",
40
+ "typescript": "6.0.3"
42
41
  },
43
42
  "peerDependencies": {
44
43
  "@vibecontrols/agent": ">=2026.529.13",
@@ -62,10 +61,10 @@
62
61
  ],
63
62
  "repository": {
64
63
  "type": "git",
65
- "url": "git+https://github.com/algoshred/vibe-plugin-session-wezterm.git"
64
+ "url": "git+https://github.com/Algoshred/vibe-plugin-session-wezterm.git"
66
65
  },
67
66
  "bugs": {
68
- "url": "https://github.com/algoshred/vibe-plugin-session-wezterm/issues"
67
+ "url": "https://github.com/Algoshred/vibe-plugin-session-wezterm/issues"
69
68
  },
70
69
  "homepage": "https://vibecontrols.com",
71
70
  "publishConfig": {
@@ -85,7 +84,7 @@
85
84
  "fast-xml-parser": ">=4.5.5",
86
85
  "@xmldom/xmldom": ">=0.8.12",
87
86
  "swiper": ">=12.1.2",
88
- "brace-expansion": ">=1.1.13",
87
+ "brace-expansion": ">=5.0.12",
89
88
  "follow-redirects": ">=1.15.12",
90
89
  "smol-toml": ">=1.6.1",
91
90
  "axios": ">=1.15.0",
@@ -94,5 +93,18 @@
94
93
  "picomatch": ">=2.3.2",
95
94
  "immutable": ">=3.8.3",
96
95
  "minimatch": ">=3.1.3"
96
+ },
97
+ "packageManager": "bun@1.4.4",
98
+ "boff": {
99
+ "type": "plugin",
100
+ "sanity": {
101
+ "steps": [
102
+ "format",
103
+ "lint",
104
+ "typecheck",
105
+ "build",
106
+ "knip"
107
+ ]
108
+ }
97
109
  }
98
110
  }