Sign In

@omniterm/host

Package Overview
Dependencies
Maintainers
2
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@omniterm/host - npm Package Compare versions

Comparing version
0.2.24
to
0.2.25
+14
-1
bin/omniterm-browser.js

@@ -165,3 +165,16 @@ #!/usr/bin/env node

function chromeArgs(includeDebugFlags) {
const args = [`--user-data-dir=${UDD}`];
// --no-first-run: without it, a brand-new UDD boots into Chrome's
// "Sign in to Chrome" first-run flow (chrome://intro/) instead of a
// normal tab. That target (and whatever it opens next, e.g. a Google
// sign-in tab) has no backing native BrowserWindow — Browser.getWindowForTarget
// 404s on it — so Target.closeTarget/Page.close/`/json/close` all report
// success without ever actually closing it, leaving a permanently stuck,
// unclosable tab in the omniterm browser panel.
// --no-default-browser-check: same spirit — skip a promo prompt this
// dedicated, non-interactive-by-default profile has no use for.
const args = [
`--user-data-dir=${UDD}`,
'--no-first-run',
'--no-default-browser-check',
];
if (includeDebugFlags) {

@@ -168,0 +181,0 @@ args.push(

+1
-1
{
"name": "@omniterm/host",
"version": "0.2.24",
"version": "0.2.25",
"description": "omniterm — a generic, browser-based dev host: persistent terminals, a browser-view panel, workspace management, and a runtime plugin API. CLI: omniterm.",

@@ -5,0 +5,0 @@ "license": "MIT",

import {createRequire}from'module';import ne,{Router}from'express';import hs from'http';import rr from'http-proxy';import x from'path';import {existsSync,readFileSync,readdirSync,copyFileSync,statSync,mkdirSync,writeFileSync,watch,realpathSync,unlinkSync,renameSync}from'fs';import {fileURLToPath,pathToFileURL}from'url';import {execFile,execFileSync,spawn}from'child_process';import po,{homedir}from'os';import {createHash,randomUUID}from'crypto';import {promisify}from'util';import*as wn from'net';import {PostHog}from'posthog-node';import {readdir,stat,readFile,writeFile}from'fs/promises';import No from'ignore';import {marked}from'marked';import {EventEmitter}from'events';createRequire(import.meta.url);
var mr=Object.defineProperty;var s=(e,t)=>mr(e,"name",{value:t,configurable:true});var Ve=process.env.SETTINGS_DIR||x.join(homedir(),".omniterm"),oe=x.join(Ve,"settings.json");function hr(e){let t=e??x.dirname(fileURLToPath(import.meta.url)),r=x.parse(t).root,n=t;for(;n!==r;){let o=x.join(n,"package.json");if(existsSync(o))try{if(JSON.parse(readFileSync(o,"utf-8")).name==="@omniterm/core")return n}catch{}n=x.dirname(n);}for(n=t;n!==r;){if(existsSync(x.join(n,"package.json")))return n;n=x.dirname(n);}return null}s(hr,"findOmnitermPackageRoot");var At=hr(),ue=At?x.join(At,"bin"):null;function qe(e,t){let r=x.resolve(e,t),n=x.normalize(r);if(!n.startsWith(e))throw new Error("Path traversal detected");return n}s(qe,"resolveWorktreePath");function I(e,t){if(!e)return null;let r=e.startsWith("~")?e.replace("~",homedir()):e,n=x.normalize(x.resolve(r));for(let o of t){if(!o)continue;let i=x.normalize(x.resolve(o));if(n===i||n.startsWith(i+x.sep))return n}return null}s(I,"confinePath");var wr=/[^A-Za-z0-9_-]/g,br=8,Pe=new Map;function C(e){let t=x.resolve(e),r=x.basename(t).replace(/\.git$/,"");return r||x.basename(x.dirname(t))||"repo"}s(C,"displayNameForPath");function Ot(e,t,r){let n=t.replace(wr,"-"),o=createHash("sha256").update(r).digest("hex").slice(0,br);return `${e}${n}-${o}`}s(Ot,"buildId");function G(e){let t=`repo ${e}`,r=Pe.get(t);if(r!==void 0)return r;let n=x.resolve(e),o=Ot("",C(n),n);return Pe.set(t,o),o}s(G,"repoIdForPath");function Ye(e){let t=`wt ${e}`,r=Pe.get(t);if(r!==void 0)return r;let n=x.resolve(e),o,i;try{o=realpathSync(n),i=!0;}catch{o=n,i=false;}let a=Ot("wt-",C(o),o);return i&&Pe.set(t,a),a}s(Ye,"worktreeIdForPath");var Ct={trackedRepos:[],trackedDirs:[],lastActiveWorktree:null,sidebarCollapsed:false,namingSchemes:{},terminalFontSize:14,defaultShell:"bash",terminalTabs:{},activeSessionId:null,activePath:null,workspacesPanelMode:"docked",workspacesPanelDockedOpen:true,workspaceFilterActiveOnly:false,filesPanelMode:"docked",filesPanelDockedOpen:false,browserPanelMode:"docked",browserInspectorPosition:"hidden",browserPanelOpen:null,filePanelTabs:{},telemetryEnabled:true,terminalRenderer:"webgl"};function Nt(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}s(Nt,"onlyStrings");function Pr(e,t){let r={...e},n=new Set,o=false;for(let i of t){let a=G(i);if(r[a]!==void 0)continue;let c=C(i);if(n.has(c))continue;let l=e[c];l!==void 0&&(n.add(c),r[a]=l,delete r[c],o=true);}return o?r:e}s(Pr,"migrateNamingSchemes");function S(){try{let e=readFileSync(oe,"utf-8"),t=JSON.parse(e);t.tabLayouts&&!t.terminalTabs&&(t.terminalTabs=t.tabLayouts),delete t.tabLayouts,delete t.browserPanel;let r={...Ct,...t};return r.trackedRepos=Nt(r.trackedRepos),r.trackedDirs=Nt(r.trackedDirs),r.namingSchemes&&typeof r.namingSchemes=="object"&&(r.namingSchemes=Pr(r.namingSchemes,r.trackedRepos)),r}catch(e){existsSync(oe)&&console.error(`[settings] ${oe} exists but could not be loaded; falling back to defaults. The next save will overwrite it. Cause: ${e instanceof Error?e.message:String(e)}`);let t=homedir(),r="/workspace",n=existsSync(r)&&statSync(r).isDirectory();return {...Ct,trackedDirs:n?[r,t]:[t],activePath:n?r:t}}}s(S,"loadSettings");function L(e){let t=S(),r={...t,...e};return e.terminalTabs&&(r.terminalTabs={...t.terminalTabs,...e.terminalTabs}),e.filePanelTabs&&(r.filePanelTabs={...t.filePanelTabs,...e.filePanelTabs}),mkdirSync(x.dirname(oe),{recursive:true}),writeFileSync(oe,JSON.stringify(r,null,2),"utf-8"),r}s(L,"saveSettings");var Ft={cosmos:["andromeda","apollo","aurora","cassini","comet","cosmos","eclipse","galaxy","horizon","lunar","mars","nebula","nova","orbit","phoenix","pulsar","quasar","saturn","solar","stellar","titan","venus","vega","zenith"],cities:["amsterdam","athens","bangkok","barcelona","berlin","cairo","dublin","florence","havana","istanbul","kyoto","lisbon","london","melbourne","nairobi","oslo","paris","prague","rome","seattle","sydney","tokyo","vancouver","vienna","zurich"],fruits:["apple","apricot","banana","blueberry","cherry","coconut","fig","grape","guava","kiwi","lemon","lime","lychee","mango","melon","orange","papaya","peach","pear","plum","pomelo","quince","raspberry","strawberry","tangerine"],music:["allegro","ballad","bass","blues","bolero","cadence","chord","crescendo","drums","encore","forte","fugue","harmony","jazz","lyric","melody","opera","piano","rhythm","samba","sonata","soprano","symphony","tempo","waltz"],gems:["agate","amber","amethyst","beryl","coral","crystal","diamond","emerald","garnet","jade","jasper","lapis","malachite","moonstone","obsidian","onyx","opal","pearl","quartz","ruby","sapphire","topaz","tourmaline","turquoise","zircon"],myths:["apollo","artemis","athena","atlas","aurora","cerberus","diana","echo","freya","griffin","helios","hermes","iris","juno","loki","medusa","minerva","neptune","odin","olympus","orion","pandora","pegasus","phoenix","thor"],ocean:["anchor","atoll","barnacle","coral","current","dolphin","driftwood","harbor","island","kelp","lagoon","lighthouse","marina","narwhal","nautilus","oyster","pelican","reef","sailboat","seashell","squid","starfish","tide","trident","whale"],spices:["anise","basil","cardamom","cayenne","chili","cinnamon","clove","coriander","cumin","dill","fennel","ginger","juniper","lavender","mint","nutmeg","oregano","paprika","pepper","rosemary","saffron","sage","thyme","turmeric","vanilla"],peaks:["alps","andes","denali","elbrus","everest","fuji","hood","kangchenjunga","kazbek","kilimanjaro","logan","makalu","matterhorn","mckinley","mont-blanc","olympus","rainier","shasta","sierra","sinai","snowdon","teton","vesuvius","whitney","zion"],dogs:["akita","beagle","boxer","bulldog","collie","corgi","dingo","doberman","husky","labrador","malamute","mastiff","pinscher","pointer","poodle","pug","retriever","rottweiler","samoyed","setter","shepherd","spaniel","terrier","vizsla","whippet"],dinos:["ankylo","bronto","compy","deinonychus","diplo","gallimimus","iguanodon","maia","megalosaurus","pachy","parasaur","plesio","pterano","raptor","rex","spinosaurus","stego","thero","trice","trodon","utah","veloci"],cafe:["affogato","americano","brew","cappuccino","chai","cortado","doppio","espresso","frappe","latte","lungo","macchiato","matcha","mocha","oolong","pourover","ristretto","robusta"]},Ke=Object.keys(Ft);function Er(e){let t=S();if(t.namingSchemes[e])return t.namingSchemes[e];let r=new Set(Object.values(t.namingSchemes)),n=Ke.find(o=>!r.has(o));return n||(n=Ke[Math.floor(Math.random()*Ke.length)]),L({namingSchemes:{...t.namingSchemes,[e]:n}}),n}s(Er,"assignScheme");function Wt(e,t){let r=Er(e),n=Ft[r],o=new Set(t),i=n.filter(l=>!o.has(l));if(i.length>0)return i[Math.floor(Math.random()*i.length)];let a=n[Math.floor(Math.random()*n.length)],c=Math.floor(Math.random()*900)+100;return `${a}-${c}`}s(Wt,"generateName");function ie(e,t){return execFileSync("git",e,{cwd:t,encoding:"utf-8"})}s(ie,"execGit");function Ar(e,t){let r;try{r=ie(["worktree","list","--porcelain"],e);}catch(a){return console.error("git worktree list failed:",a),[]}let n=[],o=r.split(`
var mr=Object.defineProperty;var s=(e,t)=>mr(e,"name",{value:t,configurable:true});var Ve=process.env.SETTINGS_DIR||x.join(homedir(),".omniterm"),oe=x.join(Ve,"settings.json");function hr(e){let t=e??x.dirname(fileURLToPath(import.meta.url)),r=x.parse(t).root,n=t;for(;n!==r;){let o=x.join(n,"package.json");if(existsSync(o))try{if(JSON.parse(readFileSync(o,"utf-8")).name==="@omniterm/core")return n}catch{}n=x.dirname(n);}for(n=t;n!==r;){if(existsSync(x.join(n,"package.json")))return n;n=x.dirname(n);}return null}s(hr,"findOmnitermPackageRoot");var At=hr(),ue=At?x.join(At,"bin"):null;function qe(e,t){let r=x.resolve(e,t),n=x.normalize(r);if(!n.startsWith(e))throw new Error("Path traversal detected");return n}s(qe,"resolveWorktreePath");function I(e,t){if(!e)return null;let r=e.startsWith("~")?e.replace("~",homedir()):e,n=x.normalize(x.resolve(r));for(let o of t){if(!o)continue;let i=x.normalize(x.resolve(o));if(n===i||n.startsWith(i+x.sep))return n}return null}s(I,"confinePath");var wr=/[^A-Za-z0-9_-]/g,br=8,_e=new Map;function C(e){let t=x.resolve(e),r=x.basename(t).replace(/\.git$/,"");return r||x.basename(x.dirname(t))||"repo"}s(C,"displayNameForPath");function Dt(e,t,r){let n=t.replace(wr,"-"),o=createHash("sha256").update(r).digest("hex").slice(0,br);return `${e}${n}-${o}`}s(Dt,"buildId");function G(e){let t=`repo ${e}`,r=_e.get(t);if(r!==void 0)return r;let n=x.resolve(e),o=Dt("",C(n),n);return _e.set(t,o),o}s(G,"repoIdForPath");function Ye(e){let t=`wt ${e}`,r=_e.get(t);if(r!==void 0)return r;let n=x.resolve(e),o,i;try{o=realpathSync(n),i=!0;}catch{o=n,i=false;}let a=Dt("wt-",C(o),o);return i&&_e.set(t,a),a}s(Ye,"worktreeIdForPath");var Ct={trackedRepos:[],trackedDirs:[],lastActiveWorktree:null,sidebarCollapsed:false,namingSchemes:{},terminalFontSize:14,defaultShell:"bash",terminalTabs:{},activeSessionId:null,activePath:null,workspacesPanelMode:"docked",workspacesPanelDockedOpen:true,workspaceFilterActiveOnly:false,filesPanelMode:"docked",filesPanelDockedOpen:false,browserPanelMode:"docked",browserInspectorPosition:"hidden",browserPanelOpen:null,filePanelTabs:{},telemetryEnabled:true,terminalRenderer:"webgl"};function Nt(e){return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}s(Nt,"onlyStrings");function _r(e,t){let r={...e},n=new Set,o=false;for(let i of t){let a=G(i);if(r[a]!==void 0)continue;let c=C(i);if(n.has(c))continue;let l=e[c];l!==void 0&&(n.add(c),r[a]=l,delete r[c],o=true);}return o?r:e}s(_r,"migrateNamingSchemes");function S(){try{let e=readFileSync(oe,"utf-8"),t=JSON.parse(e);t.tabLayouts&&!t.terminalTabs&&(t.terminalTabs=t.tabLayouts),delete t.tabLayouts,delete t.browserPanel;let r={...Ct,...t};return r.trackedRepos=Nt(r.trackedRepos),r.trackedDirs=Nt(r.trackedDirs),r.namingSchemes&&typeof r.namingSchemes=="object"&&(r.namingSchemes=_r(r.namingSchemes,r.trackedRepos)),r}catch(e){existsSync(oe)&&console.error(`[settings] ${oe} exists but could not be loaded; falling back to defaults. The next save will overwrite it. Cause: ${e instanceof Error?e.message:String(e)}`);let t=homedir(),r="/workspace",n=existsSync(r)&&statSync(r).isDirectory();return {...Ct,trackedDirs:n?[r,t]:[t],activePath:n?r:t}}}s(S,"loadSettings");function L(e){let t=S(),r={...t,...e};return e.terminalTabs&&(r.terminalTabs={...t.terminalTabs,...e.terminalTabs}),e.filePanelTabs&&(r.filePanelTabs={...t.filePanelTabs,...e.filePanelTabs}),mkdirSync(x.dirname(oe),{recursive:true}),writeFileSync(oe,JSON.stringify(r,null,2),"utf-8"),r}s(L,"saveSettings");var Ft={cosmos:["andromeda","apollo","aurora","cassini","comet","cosmos","eclipse","galaxy","horizon","lunar","mars","nebula","nova","orbit","phoenix","pulsar","quasar","saturn","solar","stellar","titan","venus","vega","zenith"],cities:["amsterdam","athens","bangkok","barcelona","berlin","cairo","dublin","florence","havana","istanbul","kyoto","lisbon","london","melbourne","nairobi","oslo","paris","prague","rome","seattle","sydney","tokyo","vancouver","vienna","zurich"],fruits:["apple","apricot","banana","blueberry","cherry","coconut","fig","grape","guava","kiwi","lemon","lime","lychee","mango","melon","orange","papaya","peach","pear","plum","pomelo","quince","raspberry","strawberry","tangerine"],music:["allegro","ballad","bass","blues","bolero","cadence","chord","crescendo","drums","encore","forte","fugue","harmony","jazz","lyric","melody","opera","piano","rhythm","samba","sonata","soprano","symphony","tempo","waltz"],gems:["agate","amber","amethyst","beryl","coral","crystal","diamond","emerald","garnet","jade","jasper","lapis","malachite","moonstone","obsidian","onyx","opal","pearl","quartz","ruby","sapphire","topaz","tourmaline","turquoise","zircon"],myths:["apollo","artemis","athena","atlas","aurora","cerberus","diana","echo","freya","griffin","helios","hermes","iris","juno","loki","medusa","minerva","neptune","odin","olympus","orion","pandora","pegasus","phoenix","thor"],ocean:["anchor","atoll","barnacle","coral","current","dolphin","driftwood","harbor","island","kelp","lagoon","lighthouse","marina","narwhal","nautilus","oyster","pelican","reef","sailboat","seashell","squid","starfish","tide","trident","whale"],spices:["anise","basil","cardamom","cayenne","chili","cinnamon","clove","coriander","cumin","dill","fennel","ginger","juniper","lavender","mint","nutmeg","oregano","paprika","pepper","rosemary","saffron","sage","thyme","turmeric","vanilla"],peaks:["alps","andes","denali","elbrus","everest","fuji","hood","kangchenjunga","kazbek","kilimanjaro","logan","makalu","matterhorn","mckinley","mont-blanc","olympus","rainier","shasta","sierra","sinai","snowdon","teton","vesuvius","whitney","zion"],dogs:["akita","beagle","boxer","bulldog","collie","corgi","dingo","doberman","husky","labrador","malamute","mastiff","pinscher","pointer","poodle","pug","retriever","rottweiler","samoyed","setter","shepherd","spaniel","terrier","vizsla","whippet"],dinos:["ankylo","bronto","compy","deinonychus","diplo","gallimimus","iguanodon","maia","megalosaurus","pachy","parasaur","plesio","pterano","raptor","rex","spinosaurus","stego","thero","trice","trodon","utah","veloci"],cafe:["affogato","americano","brew","cappuccino","chai","cortado","doppio","espresso","frappe","latte","lungo","macchiato","matcha","mocha","oolong","pourover","ristretto","robusta"]},Ke=Object.keys(Ft);function Er(e){let t=S();if(t.namingSchemes[e])return t.namingSchemes[e];let r=new Set(Object.values(t.namingSchemes)),n=Ke.find(o=>!r.has(o));return n||(n=Ke[Math.floor(Math.random()*Ke.length)]),L({namingSchemes:{...t.namingSchemes,[e]:n}}),n}s(Er,"assignScheme");function Wt(e,t){let r=Er(e),n=Ft[r],o=new Set(t),i=n.filter(l=>!o.has(l));if(i.length>0)return i[Math.floor(Math.random()*i.length)];let a=n[Math.floor(Math.random()*n.length)],c=Math.floor(Math.random()*900)+100;return `${a}-${c}`}s(Wt,"generateName");function ie(e,t){return execFileSync("git",e,{cwd:t,encoding:"utf-8"})}s(ie,"execGit");function Ar(e,t){let r;try{r=ie(["worktree","list","--porcelain"],e);}catch(a){return console.error("git worktree list failed:",a),[]}let n=[],o=r.split(`
`).filter(a=>a.trim()),i=true;for(let a of o){let c=a.split(`
`),l="",u="",d=false;for(let h of c)h.startsWith("worktree ")?l=h.substring(9):h.startsWith("branch ")?u=h.substring(7).replace("refs/heads/",""):h==="bare"&&(d=true);if(!l||d){i=false;continue}let p=x.basename(l);n.push({id:Ye(l),repoId:t,branch:u||"HEAD",path:l,name:p,isMain:i}),i=false;}return n}s(Ar,"parseWorktreeList");function R(e,t){return Ar(e,t)}s(R,"listWorktrees");function jr(e){try{return ie(["for-each-ref","--format=%(refname:short)","refs/heads/"],e).trim().split(`
`).filter(Boolean)}catch{return []}}s(jr,"listBranches");function Lt(e,t,r,n=true){let o=R(e,t),i=o.map(h=>h.name),a=new Set(jr(e)),c=Wt(t,i),l=r||c;if(!r&&a.has(l))throw new Error(`Branch "${l}" already exists`);if(o.some(h=>h.branch===l))throw new Error(`Branch "${l}" already has a worktree`);let u=l.replace(/\//g,"-"),d=`${e}-${u}`;ie(n?["worktree","add","-b",l,d]:["worktree","add",d,l],e);try{for(let h of readdirSync(e,{withFileTypes:!0}))h.isFile()&&h.name.startsWith(".env")&&copyFileSync(x.join(e,h.name),x.join(d,h.name));}catch{}return {id:Ye(d),repoId:t,branch:l,path:d,name:x.basename(d),isMain:false}}s(Lt,"createWorktree");function Xe(e){try{return ie(["status","--porcelain"],e).trim().length>0}catch{return true}}s(Xe,"isWorktreeDirty");function Ie(e,t,{force:r=false}={}){ie(r?["worktree","remove","--force",t]:["worktree","remove",t],e);}s(Ie,"removeWorktree");function Ut(e,t,r){ie(["branch","-m",t,r],e);}s(Ut,"renameBranch");var Je=parseInt(process.env.OMNITERM_TTYD_PORT_MIN||"7700",10),Ze=parseInt(process.env.OMNITERM_TTYD_PORT_MAX||"7799",10),Bt=globalThis,Me=Bt.__omniterm_ports||new Set;Bt.__omniterm_ports=Me;function Dr(){try{let e=execFileSync("lsof",[`-iTCP:${Je}-${Ze}`,"-sTCP:LISTEN","-P","-n","-Fn"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),t=new Set;for(let r of e.split(`
`)){if(!r.startsWith("n"))continue;let n=r.match(/:(\d+)$/);n&&t.add(parseInt(n[1],10));}return t}catch{return new Set}}s(Dr,"getOccupiedPorts");function Qe(){let e=Dr();for(let t=Je;t<=Ze;t++)if(!Me.has(t)&&!e.has(t))return Me.add(t),t;throw new Error(`No free ports available in range ${Je}-${Ze}`)}s(Qe,"allocatePort");function pe(e){Me.delete(e);}s(pe,"freePort");var Ht=false;function et(){if(!Ht){Ht=true;try{execFileSync("tmux",["set-option","-g","set-clipboard","on"],{stdio:"ignore"});}catch{}try{execFileSync("tmux",["set-option","-as","terminal-features","*:clipboard"],{stdio:"ignore"});}catch{}for(let e of ["copy-mode","copy-mode-vi"])try{execFileSync("tmux",["bind-key","-T",e,"MouseDragEnd1Pane","send-keys","-X","copy-pipe-and-cancel"],{stdio:"ignore"});}catch{}try{execFileSync("tmux",["bind-key","-n","PageUp","copy-mode"],{stdio:"ignore"});}catch{}}}s(et,"ensureTmuxBindings");var Fr=["TERM","COLORTERM","TMUX","TMUX_PANE","HOME","USER","LOGNAME","SHELL","TMPDIR","TZ","LANG","LC_ALL","LC_COLLATE","LC_CTYPE","LC_MESSAGES","LC_MONETARY","LC_NUMERIC","LC_TIME","SSH_AUTH_SOCK","DISPLAY","WAYLAND_DISPLAY","XAUTHORITY","XDG_RUNTIME_DIR","DBUS_SESSION_BUS_ADDRESS","OMNITERM_BROWSER_REGISTRY_URL","BROWSER","PATH"],zt=['shell="$1"; cmd="$2"',"set --",`for v in ${Fr.join(" ")}; do`,' if val=$(printenv "$v"); then set -- "$@" "$v=$val"; fi',"done",'if [ -n "$cmd" ]; then',' exec env -i "$@" "$shell" -lc "$cmd',"",'exec \\"\\$0\\"" "$shell"',"else",' exec env -i "$@" "$shell" -l',"fi"].join(`
`),l="",u="",d=false;for(let h of c)h.startsWith("worktree ")?l=h.substring(9):h.startsWith("branch ")?u=h.substring(7).replace("refs/heads/",""):h==="bare"&&(d=true);if(!l||d){i=false;continue}let p=x.basename(l);n.push({id:Ye(l),repoId:t,branch:u||"HEAD",path:l,name:p,isMain:i}),i=false;}return n}s(Ar,"parseWorktreeList");function R(e,t){return Ar(e,t)}s(R,"listWorktrees");function Or(e){try{return ie(["for-each-ref","--format=%(refname:short)","refs/heads/"],e).trim().split(`
`).filter(Boolean)}catch{return []}}s(Or,"listBranches");function Lt(e,t,r,n=true){let o=R(e,t),i=o.map(h=>h.name),a=new Set(Or(e)),c=Wt(t,i),l=r||c;if(!r&&a.has(l))throw new Error(`Branch "${l}" already exists`);if(o.some(h=>h.branch===l))throw new Error(`Branch "${l}" already has a worktree`);let u=l.replace(/\//g,"-"),d=`${e}-${u}`;ie(n?["worktree","add","-b",l,d]:["worktree","add",d,l],e);try{for(let h of readdirSync(e,{withFileTypes:!0}))h.isFile()&&h.name.startsWith(".env")&&copyFileSync(x.join(e,h.name),x.join(d,h.name));}catch{}return {id:Ye(d),repoId:t,branch:l,path:d,name:x.basename(d),isMain:false}}s(Lt,"createWorktree");function Xe(e){try{return ie(["status","--porcelain"],e).trim().length>0}catch{return true}}s(Xe,"isWorktreeDirty");function Ie(e,t,{force:r=false}={}){ie(r?["worktree","remove","--force",t]:["worktree","remove",t],e);}s(Ie,"removeWorktree");function Ut(e,t,r){ie(["branch","-m",t,r],e);}s(Ut,"renameBranch");var Je=parseInt(process.env.OMNITERM_TTYD_PORT_MIN||"7700",10),Ze=parseInt(process.env.OMNITERM_TTYD_PORT_MAX||"7799",10),Bt=globalThis,Me=Bt.__omniterm_ports||new Set;Bt.__omniterm_ports=Me;function jr(){try{let e=execFileSync("lsof",[`-iTCP:${Je}-${Ze}`,"-sTCP:LISTEN","-P","-n","-Fn"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),t=new Set;for(let r of e.split(`
`)){if(!r.startsWith("n"))continue;let n=r.match(/:(\d+)$/);n&&t.add(parseInt(n[1],10));}return t}catch{return new Set}}s(jr,"getOccupiedPorts");function Qe(){let e=jr();for(let t=Je;t<=Ze;t++)if(!Me.has(t)&&!e.has(t))return Me.add(t),t;throw new Error(`No free ports available in range ${Je}-${Ze}`)}s(Qe,"allocatePort");function pe(e){Me.delete(e);}s(pe,"freePort");var Ht=false;function et(){if(!Ht){Ht=true;try{execFileSync("tmux",["set-option","-g","set-clipboard","on"],{stdio:"ignore"});}catch{}try{execFileSync("tmux",["set-option","-as","terminal-features","*:clipboard"],{stdio:"ignore"});}catch{}for(let e of ["copy-mode","copy-mode-vi"])try{execFileSync("tmux",["bind-key","-T",e,"MouseDragEnd1Pane","send-keys","-X","copy-pipe-and-cancel"],{stdio:"ignore"});}catch{}try{execFileSync("tmux",["bind-key","-n","PageUp","copy-mode"],{stdio:"ignore"});}catch{}}}s(et,"ensureTmuxBindings");var Fr=["TERM","COLORTERM","TMUX","TMUX_PANE","HOME","USER","LOGNAME","SHELL","TMPDIR","TZ","LANG","LC_ALL","LC_COLLATE","LC_CTYPE","LC_MESSAGES","LC_MONETARY","LC_NUMERIC","LC_TIME","SSH_AUTH_SOCK","DISPLAY","WAYLAND_DISPLAY","XAUTHORITY","XDG_RUNTIME_DIR","DBUS_SESSION_BUS_ADDRESS","OMNITERM_BROWSER_REGISTRY_URL","BROWSER","PATH"],zt=['shell="$1"; cmd="$2"',"set --",`for v in ${Fr.join(" ")}; do`,' if val=$(printenv "$v"); then set -- "$@" "$v=$val"; fi',"done",'if [ -n "$cmd" ]; then',' exec env -i "$@" "$shell" -lc "$cmd',"",'exec \\"\\$0\\"" "$shell"',"else",' exec env -i "$@" "$shell" -l',"fi"].join(`
`);function Wr(e){let t=`'${e.replace(/'/g,"'\\''")}'`;return `exec /bin/sh -c '${zt}' omniterm-clean-env ${t}`}s(Wr,"buildDefaultCommand");function Lr(e,t,r,n,o){let i=["new-session","-d","-s",e];if(r){let a=r==="~"?homedir():r;i.push("-c",a);}if(n)for(let[a,c]of Object.entries(n))i.push("-e",`${a}=${c}`);return i.push("sh","-c",zt,"omniterm-clean-env",t),o?.initialCommand&&i.push(o.initialCommand),i}s(Lr,"buildNewSessionArgs");function $e(e,t,r,n){let o=S().defaultShell||"bash";execFileSync("tmux",Lr(e,o,t,r,n),{stdio:"ignore"});let i=[["mouse","on"],["default-command",Wr(o)],["history-limit","50000"],["status-position","bottom"],["base-index","1"],["renumber-windows","on"],["escape-time","0"],["focus-events","on"]],a=[];for(let[c,l]of i)a.length>0&&a.push(";"),a.push("set-option","-t",`=${e}:`,c,l);try{execFileSync("tmux",a,{stdio:"ignore"});}catch{}et();}s($e,"createTmuxSession");function tt(e){try{execFileSync("tmux",["kill-session","-t",`=${e}`],{stdio:"ignore"});}catch{}try{unlinkSync(`/tmp/omniterm-silence-${e}`);}catch{}}s(tt,"killTmuxSession");function Ae(){try{let e=execFileSync("tmux",["list-sessions","-F","#{session_name}|||#{session_path}|||#{session_created}"],{encoding:"utf-8"}).trim();return e?e.split(`

@@ -14,6 +14,6 @@ `).map(t=>{let[r,n,o]=t.split("|||");return {name:r,cwd:n||"~",created:o}}):[]}catch{return []}}s(Ae,"listTmuxSessions");function nt(e,t){return !!t&&t!==e&&!/^[a-zA-Z0-9-]+$/.test(t)}s(nt,"isMeaningfulPaneTitle");function Gt(e){try{let t=execFileSync("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_title}"],{encoding:"utf-8"}).trim();return nt(e,t)?t:execFileSync("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_current_command}"],{encoding:"utf-8"}).trim()}catch{return ""}}s(Gt,"getTmuxPaneTitle");function me(e){try{return execFileSync("tmux",["has-session","-t",`=${e}`],{stdio:"ignore"}),!0}catch{return false}}s(me,"tmuxSessionExists");var ge=globalThis,k=ge.__omniterm_sse_clients||new Set;ge.__omniterm_sse_clients=k;function Vt(e){k.add(e),console.log(`[events] SSE client connected; clients=${k.size}`),e.on("close",()=>{k.delete(e),console.log(`[events] SSE client disconnected; clients=${k.size}`);}),Br();}s(Vt,"addClient");var Ur=3e4,fe=ge.__omniterm_sse_heartbeat??null;function Br(){fe||(fe=setInterval(()=>{if(k.size===0){clearInterval(fe),fe=null,ge.__omniterm_sse_heartbeat=null;return}for(let e of k)try{e.write(`: heartbeat

`);}catch{k.delete(n);}}s($,"broadcast");function qt(){return k.size}s(qt,"getClientCount");var Yt=promisify(execFile),Vr=3e3,Kt=2e3,qr=15,Yr=20,Kr=2,Xr="#{session_name} #{window_activity} #{window_active} #{pane_active} #{pane_current_path}",Xt=globalThis,w=Xt.__omniterm_silence_monitor??{states:new Map,legacyCleaned:new Set,timer:null,polling:false};Xt.__omniterm_silence_monitor=w;function rt(e){w.states.has(e)||w.states.set(e,{lastActivitySeconds:null,activeSinceSeconds:null,path:""}),no(e),Jr();}s(rt,"trackSilenceSession");function he(e){w.states.delete(e),Jt(e);}s(he,"untrackSilenceSession");function Jt(e){w.legacyCleaned.delete(e),Zt(e),w.states.size===0&&Zr();}s(Jt,"cleanupSilenceSession");function Jr(){w.timer||(w.timer=setInterval(()=>{Qr();},Vr),w.timer.unref?.());}s(Jr,"ensurePoller");function Zr(){w.timer&&(clearInterval(w.timer),w.timer=null);}s(Zr,"stopPoller");async function Qr(){if(!(w.polling||w.states.size===0)){w.polling=true;try{let e=new Set(w.states.keys()),{stdout:t}=await Yt("tmux",["list-panes","-a","-F",Xr],{encoding:"utf-8",timeout:Kt}),r=eo(t,e);to(w.states,r,ro(),n=>{console.log(`[alert] broadcast session-silence session=${n.sessionId} cwd=${n.path} sse_clients=${qt()}`),$("session-silence",{path:n.path,sessionId:n.sessionId});},{onSessionDeleted:Jt,trackedSessions:e});}catch{}finally{w.polling=false;}}}s(Qr,"pollSilenceSessions");function eo(e,t){let r=new Map;for(let n of e.split(`
`)){if(!n.trim())continue;let[o,i,a,c,...l]=n.split(" ");if(!o||!t.has(o))continue;let u=i?.trim();if(!u)continue;let d=Number(u);if(!Number.isFinite(d))continue;let p=l.join(" ").trim(),h=a==="1"&&c==="1",b=r.get(o);if(!b){r.set(o,{activitySeconds:d,path:p,activePaneSeen:h});continue}d>b.activitySeconds&&(b.activitySeconds=d),(h||!b.activePaneSeen)&&(b.path=p,b.activePaneSeen=b.activePaneSeen||h);}return new Map([...r].map(([n,o])=>[n,{activitySeconds:o.activitySeconds,path:o.path}]))}s(eo,"parseTmuxActivitySnapshots");function to(e,t,r,n,o={}){let i=o.silenceSeconds??qr,a=o.activeCooldownSeconds??Yr,c=o.absentPollsBeforeDelete??Kr;for(let[l,u]of e){if(o.trackedSessions&&!o.trackedSessions.has(l))continue;let d=t.get(l);if(!d){u.missingPolls=(u.missingPolls??0)+1,u.missingPolls>=c&&(e.delete(l),o.onSessionDeleted?.(l));continue}if(u.missingPolls=0,u.path=d.path,u.lastActivitySeconds===null){u.lastActivitySeconds=d.activitySeconds;continue}if(d.activitySeconds<u.lastActivitySeconds){u.lastActivitySeconds=d.activitySeconds,u.activeSinceSeconds=null;continue}if(d.activitySeconds>u.lastActivitySeconds){u.activeSinceSeconds===null&&(u.activeSinceSeconds=d.activitySeconds),u.lastActivitySeconds=d.activitySeconds;continue}if(u.activeSinceSeconds!==null&&r-u.lastActivitySeconds>=i){if(u.lastActivitySeconds-u.activeSinceSeconds<a){u.activeSinceSeconds=null;continue}u.path&&(n({sessionId:l,path:u.path}),u.activeSinceSeconds=null);}}}s(to,"updateSilenceStates");function no(e){w.legacyCleaned.has(e)||(w.legacyCleaned.add(e),Yt("tmux",["set-hook","-u","-t",e,"alert-activity",";","set-hook","-u","-t",e,"alert-silence",";","set-option","-t",e,"activity-action","none",";","set-option","-t",e,"silence-action","none",";","set-window-option","-t",e,"monitor-activity","off",";","set-window-option","-t",e,"monitor-silence","0"],{timeout:Kt}).catch(()=>{}).finally(()=>Zt(e)));}s(no,"disableLegacySilenceMonitoring");function Zt(e){try{unlinkSync(`/tmp/omniterm-silence-${e}`);}catch{}}s(Zt,"removeLegacyStateFile");function ro(){return Math.floor(Date.now()/1e3)}s(ro,"nowSeconds");var ye=[];function ot(e,t,r=Date.now()){ye.push({op:e,timings:t,at:r}),ye.length>100&&ye.splice(0,ye.length-100);}s(ot,"recordPerf");function Qt(){return ye.slice()}s(Qt,"getRecent");var en="https://us.i.posthog.com";function st(e){if(!e)return false;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"||t==="on"}s(st,"truthy");function oo(e){if(e===void 0)return false;let t=e.trim().toLowerCase();return t==="0"||t==="false"||t==="no"||t==="off"}s(oo,"offValue");function tn(e,t){let r=(e.OMNITERM_POSTHOG_KEY??"").trim(),n=(e.OMNITERM_POSTHOG_HOST??en).trim()||en;return {enabled:!(st(e.DO_NOT_TRACK)||oo(e.OMNITERM_TELEMETRY)||st(e.OMNITERM_TELEMETRY_DISABLED)||t||st(e.CI)||e.NODE_ENV==="test"||r===""),key:r,host:n}}s(tn,"resolveTelemetryConfig");function je(){return x.join(Ve,"telemetry.json")}s(je,"telemetryStatePath");function Se(e=je()){try{let t=readFileSync(e,"utf-8"),r=JSON.parse(t);return r&&typeof r.installId=="string"&&r.installId?r:null}catch{return null}}s(Se,"readState");function rn(e,t=je()){try{mkdirSync(x.dirname(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e,null,2),"utf-8"),renameSync(r,t);}catch{}}s(rn,"writeState");function on(e=je()){let t=Se(e);if(t)return t.installId;let r={installId:randomUUID()};if(rn(r,e),existsSync(e)){let n=Se(e);if(n)return n.installId}return r.installId}s(on,"getOrCreateInstallId");function sn(e=je()){let t=Se(e);t&&(t.noticeShown||rn({...t,noticeShown:true},e));}s(sn,"markNoticeShown");var Z=null,it="",U={enabled:false,key:"",host:""},an=false;function fo(){return {app_version:process.env.OMNITERM_VERSION||"unknown",os:po.platform(),node_version:process.version}}s(fo,"baseContext");function go(e){return {...fo(),...e??{}}}s(go,"buildProps");function ho(e){return !e.enabled||!e.hasClient?{enabled:false}:{enabled:true,key:e.key,host:e.host,distinctId:e.distinctId,appVersion:e.appVersion}}s(ho,"projectClientTelemetryConfig");function cn(){return ho({enabled:U.enabled,hasClient:Z!==null,key:U.key,host:U.host,distinctId:it,appVersion:process.env.OMNITERM_VERSION||"unknown"})}s(cn,"getClientTelemetryConfig");function ae(e,t){if(!(!U.enabled||!Z))try{Z.capture({distinctId:it,event:e,properties:go(t)});}catch{}}s(ae,"capture");function yo(){try{let e=Se();if(!e||e.noticeShown)return;process.stderr.write("[omniterm] Pseudonymous usage + performance telemetry is enabled. Event payloads exclude names, contents, paths, repo names, and plugin ids. Opt out anytime with `omniterm telemetry off`, the Settings panel, or OMNITERM_TELEMETRY=0 / DO_NOT_TRACK=1.\n"),sn();}catch{}}s(yo,"showFirstRunNoticeOnce");function ln(){if(!an){an=true;try{let e=S().telemetryEnabled===!1;if(U=tn(process.env,e),!U.enabled)return;it=on(),Z=new PostHog(U.key,{host:U.host,flushAt:1,disableGeoip:!0}),yo();}catch{U={enabled:false,key:"",host:""},Z=null;}}}s(ln,"initTelemetry");async function dn(){let e=Z;if(Z=null,!e)return;let t,r=new Promise(n=>{t=setTimeout(n,2e3),t.unref?.();});try{await Promise.race([e.shutdown(2e3),r]);}catch{}finally{t&&clearTimeout(t);}}s(dn,"shutdownTelemetry");function un(e){ae("server_started",{session_count:e});}s(un,"trackServerStarted");function pn(e){e&&ot("session_created",e),ae("session_created",e);}s(pn,"trackSessionCreated");function mn(e){e&&ot("session_adopted",e),ae("session_adopted",e);}s(mn,"trackSessionAdopted");function fn(){ae("session_closed");}s(fn,"trackSessionClosed");function gn(e){ae("file_opened",{language:e});}s(gn,"trackFileOpened");function hn(e){ae("cleanup",e===void 0?void 0:{count:e});}s(hn,"trackCleanup");function yn(){return Qt()}s(yn,"getRecentPerfMetrics");var De=globalThis,B=De.__omniterm_ttyd||new Map,Oe=De.__omniterm_ttyd_stopped_listeners||new Set;De.__omniterm_ttyd=B;De.__omniterm_ttyd_stopped_listeners=Oe;function at(e){for(let t of Oe)try{t(e);}catch(r){let n=r instanceof Error?r.message:String(r);console.error(`[ttyd] stopped listener failed for ${e}: ${n}`);}}s(at,"notifyTtydStopped");function bn(e){return Oe.add(e),()=>{Oe.delete(e);}}s(bn,"onTtydStopped");function wo(e,t,r){let n=r.terminalFontSize||18,o=r.terminalRenderer==="dom"?"dom":"webgl";return ["--writable","-i","127.0.0.1","-b",`/t/${e}/`,"-t",`rendererType=${o}`,"-t",`fontSize=${n}`,"-p",String(t),"--","bash","-c",`exec tmux attach-session -t ${e}`]}s(wo,"buildTtydArgs");function we(e,t){let r=wo(e,t,S()),n=spawn("ttyd",r,{stdio:"ignore",detached:true});return n.once("error",o=>{console.error(`[ttyd] failed to spawn for ${e} on port ${t}: ${o.message}`),B.get(e)===n&&(B.delete(e),at(e));}),n.once("exit",(o,i)=>{B.get(e)===n&&(B.delete(e),at(e)),(o!==0||i)&&console.error(`[ttyd] exited for ${e} on port ${t}: code=${o??"null"} signal=${i??"null"}`);}),n.unref(),B.set(e,n),n}s(we,"spawnTtyd");function xn(e,t=3e3){return new Promise((r,n)=>{let o=Date.now()+t;function i(){let a=new wn.Socket;a.setTimeout(100),a.connect(e,"127.0.0.1",()=>{a.destroy(),r();}),a.on("error",()=>{a.destroy(),Date.now()>=o?n(new Error(`ttyd not ready on port ${e} after ${t}ms`)):setTimeout(i,30);}),a.on("timeout",()=>{a.destroy(),Date.now()>=o?n(new Error(`ttyd not ready on port ${e} after ${t}ms`)):setTimeout(i,30);});}s(i,"attempt"),i();})}s(xn,"waitForTtydReady");function be(e){let t=B.get(e);if(t&&t.pid)try{process.kill(t.pid,"SIGTERM");}catch{}B.delete(e)&&at(e);}s(be,"stopTtyd");function ct(e){let t=B.get(e);if(!t||!t.pid)return false;try{return process.kill(t.pid,0),!0}catch{return false}}s(ct,"isTtydAlive");function bo(e,t){if(!e.trim())return [];let r=[];for(let n of e.split(`
`)){if(!n.trim())continue;let[o,i,a,c,...l]=n.split(" ");if(!o||!t.has(o))continue;let u=i?.trim();if(!u)continue;let d=Number(u);if(!Number.isFinite(d))continue;let p=l.join(" ").trim(),h=a==="1"&&c==="1",b=r.get(o);if(!b){r.set(o,{activitySeconds:d,path:p,activePaneSeen:h});continue}d>b.activitySeconds&&(b.activitySeconds=d),(h||!b.activePaneSeen)&&(b.path=p,b.activePaneSeen=b.activePaneSeen||h);}return new Map([...r].map(([n,o])=>[n,{activitySeconds:o.activitySeconds,path:o.path}]))}s(eo,"parseTmuxActivitySnapshots");function to(e,t,r,n,o={}){let i=o.silenceSeconds??qr,a=o.activeCooldownSeconds??Yr,c=o.absentPollsBeforeDelete??Kr;for(let[l,u]of e){if(o.trackedSessions&&!o.trackedSessions.has(l))continue;let d=t.get(l);if(!d){u.missingPolls=(u.missingPolls??0)+1,u.missingPolls>=c&&(e.delete(l),o.onSessionDeleted?.(l));continue}if(u.missingPolls=0,u.path=d.path,u.lastActivitySeconds===null){u.lastActivitySeconds=d.activitySeconds;continue}if(d.activitySeconds<u.lastActivitySeconds){u.lastActivitySeconds=d.activitySeconds,u.activeSinceSeconds=null;continue}if(d.activitySeconds>u.lastActivitySeconds){u.activeSinceSeconds===null&&(u.activeSinceSeconds=d.activitySeconds),u.lastActivitySeconds=d.activitySeconds;continue}if(u.activeSinceSeconds!==null&&r-u.lastActivitySeconds>=i){if(u.lastActivitySeconds-u.activeSinceSeconds<a){u.activeSinceSeconds=null;continue}u.path&&(n({sessionId:l,path:u.path}),u.activeSinceSeconds=null);}}}s(to,"updateSilenceStates");function no(e){w.legacyCleaned.has(e)||(w.legacyCleaned.add(e),Yt("tmux",["set-hook","-u","-t",e,"alert-activity",";","set-hook","-u","-t",e,"alert-silence",";","set-option","-t",e,"activity-action","none",";","set-option","-t",e,"silence-action","none",";","set-window-option","-t",e,"monitor-activity","off",";","set-window-option","-t",e,"monitor-silence","0"],{timeout:Kt}).catch(()=>{}).finally(()=>Zt(e)));}s(no,"disableLegacySilenceMonitoring");function Zt(e){try{unlinkSync(`/tmp/omniterm-silence-${e}`);}catch{}}s(Zt,"removeLegacyStateFile");function ro(){return Math.floor(Date.now()/1e3)}s(ro,"nowSeconds");var ye=[];function ot(e,t,r=Date.now()){ye.push({op:e,timings:t,at:r}),ye.length>100&&ye.splice(0,ye.length-100);}s(ot,"recordPerf");function Qt(){return ye.slice()}s(Qt,"getRecent");var en="https://us.i.posthog.com";function st(e){if(!e)return false;let t=e.trim().toLowerCase();return t==="1"||t==="true"||t==="yes"||t==="on"}s(st,"truthy");function oo(e){if(e===void 0)return false;let t=e.trim().toLowerCase();return t==="0"||t==="false"||t==="no"||t==="off"}s(oo,"offValue");function tn(e,t){let r=(e.OMNITERM_POSTHOG_KEY??"").trim(),n=(e.OMNITERM_POSTHOG_HOST??en).trim()||en;return {enabled:!(st(e.DO_NOT_TRACK)||oo(e.OMNITERM_TELEMETRY)||st(e.OMNITERM_TELEMETRY_DISABLED)||t||st(e.CI)||e.NODE_ENV==="test"||r===""),key:r,host:n}}s(tn,"resolveTelemetryConfig");function Oe(){return x.join(Ve,"telemetry.json")}s(Oe,"telemetryStatePath");function Se(e=Oe()){try{let t=readFileSync(e,"utf-8"),r=JSON.parse(t);return r&&typeof r.installId=="string"&&r.installId?r:null}catch{return null}}s(Se,"readState");function rn(e,t=Oe()){try{mkdirSync(x.dirname(t),{recursive:!0});let r=`${t}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e,null,2),"utf-8"),renameSync(r,t);}catch{}}s(rn,"writeState");function on(e=Oe()){let t=Se(e);if(t)return t.installId;let r={installId:randomUUID()};if(rn(r,e),existsSync(e)){let n=Se(e);if(n)return n.installId}return r.installId}s(on,"getOrCreateInstallId");function sn(e=Oe()){let t=Se(e);t&&(t.noticeShown||rn({...t,noticeShown:true},e));}s(sn,"markNoticeShown");var Z=null,it="",U={enabled:false,key:"",host:""},an=false;function fo(){return {app_version:process.env.OMNITERM_VERSION||"unknown",os:po.platform(),node_version:process.version}}s(fo,"baseContext");function go(e){return {...fo(),...e??{}}}s(go,"buildProps");function ho(e){return !e.enabled||!e.hasClient?{enabled:false}:{enabled:true,key:e.key,host:e.host,distinctId:e.distinctId,appVersion:e.appVersion}}s(ho,"projectClientTelemetryConfig");function cn(){return ho({enabled:U.enabled,hasClient:Z!==null,key:U.key,host:U.host,distinctId:it,appVersion:process.env.OMNITERM_VERSION||"unknown"})}s(cn,"getClientTelemetryConfig");function ae(e,t){if(!(!U.enabled||!Z))try{Z.capture({distinctId:it,event:e,properties:go(t)});}catch{}}s(ae,"capture");function yo(){try{let e=Se();if(!e||e.noticeShown)return;process.stderr.write("[omniterm] Pseudonymous usage + performance telemetry is enabled. Event payloads exclude names, contents, paths, repo names, and plugin ids. Opt out anytime with `omniterm telemetry off`, the Settings panel, or OMNITERM_TELEMETRY=0 / DO_NOT_TRACK=1.\n"),sn();}catch{}}s(yo,"showFirstRunNoticeOnce");function ln(){if(!an){an=true;try{let e=S().telemetryEnabled===!1;if(U=tn(process.env,e),!U.enabled)return;it=on(),Z=new PostHog(U.key,{host:U.host,flushAt:1,disableGeoip:!0}),yo();}catch{U={enabled:false,key:"",host:""},Z=null;}}}s(ln,"initTelemetry");async function dn(){let e=Z;if(Z=null,!e)return;let t,r=new Promise(n=>{t=setTimeout(n,2e3),t.unref?.();});try{await Promise.race([e.shutdown(2e3),r]);}catch{}finally{t&&clearTimeout(t);}}s(dn,"shutdownTelemetry");function un(e){ae("server_started",{session_count:e});}s(un,"trackServerStarted");function pn(e){e&&ot("session_created",e),ae("session_created",e);}s(pn,"trackSessionCreated");function mn(e){e&&ot("session_adopted",e),ae("session_adopted",e);}s(mn,"trackSessionAdopted");function fn(){ae("session_closed");}s(fn,"trackSessionClosed");function gn(e){ae("file_opened",{language:e});}s(gn,"trackFileOpened");function hn(e){ae("cleanup",e===void 0?void 0:{count:e});}s(hn,"trackCleanup");function yn(){return Qt()}s(yn,"getRecentPerfMetrics");var je=globalThis,B=je.__omniterm_ttyd||new Map,De=je.__omniterm_ttyd_stopped_listeners||new Set;je.__omniterm_ttyd=B;je.__omniterm_ttyd_stopped_listeners=De;function at(e){for(let t of De)try{t(e);}catch(r){let n=r instanceof Error?r.message:String(r);console.error(`[ttyd] stopped listener failed for ${e}: ${n}`);}}s(at,"notifyTtydStopped");function bn(e){return De.add(e),()=>{De.delete(e);}}s(bn,"onTtydStopped");function wo(e,t,r){let n=r.terminalFontSize||18,o=r.terminalRenderer==="dom"?"dom":"webgl";return ["--writable","-i","127.0.0.1","-b",`/t/${e}/`,"-t",`rendererType=${o}`,"-t",`fontSize=${n}`,"-p",String(t),"--","bash","-c",`exec tmux attach-session -t ${e}`]}s(wo,"buildTtydArgs");function we(e,t){let r=wo(e,t,S()),n=spawn("ttyd",r,{stdio:"ignore",detached:true});return n.once("error",o=>{console.error(`[ttyd] failed to spawn for ${e} on port ${t}: ${o.message}`),B.get(e)===n&&(B.delete(e),at(e));}),n.once("exit",(o,i)=>{B.get(e)===n&&(B.delete(e),at(e)),(o!==0||i)&&console.error(`[ttyd] exited for ${e} on port ${t}: code=${o??"null"} signal=${i??"null"}`);}),n.unref(),B.set(e,n),n}s(we,"spawnTtyd");function xn(e,t=3e3){return new Promise((r,n)=>{let o=Date.now()+t;function i(){let a=new wn.Socket;a.setTimeout(100),a.connect(e,"127.0.0.1",()=>{a.destroy(),r();}),a.on("error",()=>{a.destroy(),Date.now()>=o?n(new Error(`ttyd not ready on port ${e} after ${t}ms`)):setTimeout(i,30);}),a.on("timeout",()=>{a.destroy(),Date.now()>=o?n(new Error(`ttyd not ready on port ${e} after ${t}ms`)):setTimeout(i,30);});}s(i,"attempt"),i();})}s(xn,"waitForTtydReady");function be(e){let t=B.get(e);if(t&&t.pid)try{process.kill(t.pid,"SIGTERM");}catch{}B.delete(e)&&at(e);}s(be,"stopTtyd");function ct(e){let t=B.get(e);if(!t||!t.pid)return false;try{return process.kill(t.pid,0),!0}catch{return false}}s(ct,"isTtydAlive");function bo(e,t){if(!e.trim())return [];let r=[];for(let n of e.split(`
`)){if(!n.includes("ttyd")||!n.includes("--writable"))continue;let o=n.match(/^\s*(\d+)/),i=n.match(/-b \/t\/([^/]+)\//);if(!o||!i)continue;let a=Number(o[1]),c=i[1];t.has(c)||r.push(a);}return r.sort((n,o)=>n-o)}s(bo,"getTtydPidsToKill");function lt(){let e;try{let t=execFileSync("tmux",["list-sessions","-F","#{session_name}"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();e=new Set(t?t.split(`
`):[]);}catch{e=new Set;}try{let t=execFileSync("ps",["-eo","pid,command"],{encoding:"utf-8"}).trim();if(!t)return;let r=0;for(let n of bo(t,e))try{process.kill(n,"SIGTERM"),r++;}catch{}r>0&&(console.log(`[cleanup] killed ${r} stale ttyd processes`),hn(r));}catch{}}s(lt,"killOrphanedTtydProcesses");function vn(){return {readySessionNames:new Set,pendingReadiness:new Map,generations:new Map}}s(vn,"createSessionTtydReadinessState");function _(e,t){t.readySessionNames.delete(e),t.pendingReadiness.delete(e),t.generations.set(e,(t.generations.get(e)??0)+1);}s(_,"clearSessionTtydReadiness");async function Tn(e,t,r,n){let o=e.tmuxName;if(n.readySessionNames.has(o)){if(r.isTtydAlive(o))return;_(o,n);}let i=n.pendingReadiness.get(o);if(i){if(await i,n.readySessionNames.has(o)&&r.isTtydAlive(o))return;throw new Error(`ttyd readiness invalidated for ${o}`)}let a=n.generations.get(o)??0;r.isTtydAlive(o)||(_(o,n),a=n.generations.get(o)??0,r.spawnTtyd(o,e.port));let c=r.waitForTtydReady(e.port,t).then(()=>{if((n.generations.get(o)??0)!==a)throw new Error(`ttyd readiness invalidated for ${o}`);if(!r.isTtydAlive(o))throw _(o,n),new Error(`ttyd exited before readiness completed for ${o}`);n.readySessionNames.add(o);}).finally(()=>{n.pendingReadiness.get(o)===c&&n.pendingReadiness.delete(o);});n.pendingReadiness.set(o,c),await c;}s(Tn,"ensureSessionTtydReadyWithState");var Rn=globalThis;function kn(){Rn.__omniterm_recovered||(Rn.__omniterm_recovered=true,lt());}s(kn,"recoverAll");var Ce=ue?x.join(ue,"omniterm-browser.js"):null,To=Ce!==null&&existsSync(Ce),Pn="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";function ut(e){let t={OMNITERM_BROWSER_REGISTRY_URL:e};return To&&Ce&&ue?(t.BROWSER=Ce,t.PATH=`${ue}:${Pn}`):t.PATH=Pn,t}s(ut,"buildTabEnv");var V=globalThis,A=V.__omniterm_sessions||new Map,dt=V.__omniterm_counters||new Map,N=V.__omniterm_ttyd_readiness||vn();V.__omniterm_sessions=A;V.__omniterm_counters=dt;V.__omniterm_ttyd_readiness=N;var Ro={isTtydAlive:ct,spawnTtyd:we,waitForTtydReady:xn};V.__omniterm_session_ttyd_listener_registered||(bn(e=>_(e,N)),V.__omniterm_session_ttyd_listener_registered=true);function ko(e){let t=(dt.get(e)||0)+1;for(;me(`${e}-term-${t}`);)t++;return dt.set(e,t),`${e}-term-${t}`}s(ko,"nextId");kn();function En(e,t,r){let n=Date.now(),o=ko(e),i=Qe(),a=Date.now();$e(o,t,ut(r.registryUrlFor(o)));let c=Date.now(),l={id:o,worktreeId:e,tmuxName:o,port:i,createdAt:new Date().toISOString()};_(l.tmuxName,N),we(l.tmuxName,l.port);let u=Date.now();A.set(o,l),rt(l.tmuxName);let d=Date.now();return console.log(`[session] ${o}: tmux=${c-a}ms ttyd=${u-c}ms total=${d-n}ms`),$("session-created",{sessionId:o,worktreeId:e,path:t}),l}s(En,"createSession");function q(e){let t=A.get(e);if(t){if(!me(t.tmuxName)){_(t.tmuxName,N),be(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName);return}return ct(t.tmuxName)||(_(t.tmuxName,N),we(t.tmuxName,t.port)),t}}s(q,"getSession");async function Y(e,t=3e3){await Tn(e,t,Ro,N);}s(Y,"ensureSessionTtydReady");function In(e){let t=A.get(e);return t?(_(t.tmuxName,N),be(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName),true):false}s(In,"unregisterSession");function K(e){let t=Array.from(A.values());return e?t.filter(r=>r.worktreeId===e):t}s(K,"listSessions");function xe(e){let t=A.get(e);return t?(_(t.tmuxName,N),be(t.tmuxName),tt(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName),fn(),$("session-closed",{sessionId:e,worktreeId:t.worktreeId}),true):false}s(xe,"deleteSession");function Ne(e){let t=K(e);for(let r of t)_(r.tmuxName,N),be(r.tmuxName),tt(r.tmuxName),pe(r.port),A.delete(r.id),he(r.tmuxName);return t.length>0&&$("session-closed",{worktreeId:e,sessionCount:t.length}),t.length}s(Ne,"deleteSessionsForWorktree");function pt(e,t){let r=Date.now(),n=Qe(),o=Date.now();if(!t?.skipTmuxSetup){et();try{execFileSync("tmux",["set-option","-t",`=${e}:`,"mouse","on"],{stdio:"ignore"});}catch{}}let i=Date.now();_(e,N),we(e,n);let a=Date.now(),c={id:e,worktreeId:"_orphan",tmuxName:e,port:n,createdAt:new Date().toISOString()};A.set(c.id,c),rt(c.tmuxName);let l=o-r,u=a-r;console.log(`[session] adopted ${e}: port=${n} allocate=${l}ms setup=${i-o}ms ttyd=${a-i}ms total=${u}ms skip=${t?.skipTmuxSetup?1:0}`),mn({total_ms:u,allocate_port_ms:l});let d=t?.knownCwd??"";if(!d)try{d=execFileSync("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_current_path}"],{encoding:"utf-8"}).trim();}catch{}return $("session-adopted",{sessionId:e,worktreeId:"_orphan",path:d}),c}s(pt,"adoptSession");function Po(e){let t=x.join(e,".git");try{let n=statSync(t);if(n.isDirectory())return x.join(t,"config");if(n.isFile()){let o=readFileSync(t,"utf-8").match(/^gitdir:\s*(.+)$/m);if(o){let i=x.resolve(e,o[1].trim()),a=x.join(i,"commondir"),c=existsSync(a)?x.resolve(i,readFileSync(a,"utf-8").trim()):i;return x.join(c,"config")}}}catch{}let r=x.join(e,"config");return existsSync(r)?r:null}s(Po,"gitConfigPath");function Eo(e){let t=false;for(let r of e.split(`
`)){let n=r.trim();if(n.startsWith("[")){t=/^\[remote\s+"origin"\]$/.test(n);continue}if(t){let o=n.match(/^url\s*=\s*(.+)$/);if(o)return o[1].trim()}}return ""}s(Eo,"parseOriginUrl");var Mn=new Map;function An(e){let t=Po(e);if(!t)return "";try{let{mtimeMs:r}=statSync(t),n=Mn.get(t);if(n&&n.mtimeMs===r)return n.url;let o=Eo(readFileSync(t,"utf-8"));return Mn.set(t,{mtimeMs:r,url:o}),o}catch{return ""}}s(An,"getRemoteUrl");function ft(e){return existsSync(x.join(e,".git"))||existsSync(x.join(e,"HEAD"))}s(ft,"isGitRepo");function P(){return S().trackedRepos.filter(t=>existsSync(t)&&ft(t)).map(t=>({id:G(t),name:C(t),remoteUrl:An(t),path:t}))}s(P,"listRepos");function ve(e){let t=S();for(let r of t.trackedRepos)if(G(r)===e&&existsSync(r)&&ft(r))return {id:e,name:C(r),remoteUrl:An(r),path:r}}s(ve,"getRepo");function gt(e){let t=x.resolve(e);if(!existsSync(t))throw new Error(`Path "${t}" does not exist`);let r=S();if(ft(t))return r.trackedRepos.includes(t)||L({trackedRepos:[...r.trackedRepos,t]}),{type:"repo",path:t};{let n=r.trackedRepos.filter(i=>i!==t),o=r.trackedDirs.includes(t)?r.trackedDirs:[...r.trackedDirs,t];return (n.length!==r.trackedRepos.length||o!==r.trackedDirs)&&L({trackedRepos:n,trackedDirs:o}),{type:"dir",path:t}}}s(gt,"addLocalPath");function jn(e,t){let r=e.match(/\/([^/]+?)(\.git)?$/)?.[1]||"repo",n=t||x.join(process.env.HOME||"/tmp",r);if(existsSync(n))throw new Error(`"${n}" already exists`);execFileSync("git",["clone",e,n],{encoding:"utf-8",timeout:3e5});let o=S();return L({trackedRepos:[...o.trackedRepos,n]}),{id:G(n),name:C(n),remoteUrl:e,path:n}}s(jn,"cloneRepo");function On(e){let t=ve(e);if(!t)throw new Error(`Repo "${e}" not found`);let r=0,n=0,o=[],i=R(t.path,e);for(let c of i)if(n+=Ne(c.id),!c.isMain)try{Ie(t.path,c.path),r++;}catch{o.push(c.path);}let a=S();return L({trackedRepos:a.trackedRepos.filter(c=>c!==t.path)}),{worktreesRemoved:r,worktreesSkipped:o,sessionsKilled:n}}s(On,"removeRepo");var Q=Router();Q.get("/repos",(e,t)=>{t.json(P());});Q.post("/repos",async(e,t)=>{let{url:r,localPath:n,destination:o}=e.body||{};if(!r&&!n){t.status(400).json({error:"url or localPath is required"});return}try{let i=n?gt(n):null,a=i?{id:G(i.path),name:C(i.path),...i}:jn(r,o);t.status(201).json(a);}catch(i){let a=i instanceof Error?i.message:String(i);t.status(a.includes("already")?409:400).json({error:a});}});Q.delete("/repos/:repoId",(e,t)=>{if(!ve(e.params.repoId)){t.status(404).json({error:"Repo not found"});return}let n=On(e.params.repoId);t.json({deleted:true,...n});});Q.get("/repos/:repoId/worktrees",(e,t)=>{let r=ve(e.params.repoId);if(!r){t.status(404).json({error:"Repo not found"});return}let n=R(r.path,e.params.repoId),o=Ae();t.json(n.map(i=>({...i,sessionCount:o.filter(a=>a.cwd===i.path).length})));});Q.post("/repos/:repoId/worktrees",async(e,t)=>{let r=ve(e.params.repoId);if(!r){t.status(404).json({error:"Repo not found"});return}let{branch:n,newBranch:o=true}=e.body||{};try{let i=Lt(r.path,e.params.repoId,n,o);t.status(201).json(i);}catch(i){let a=i instanceof Error?i.message:String(i);t.status(a.includes("already has a worktree")?409:400).json({error:a});}});var Dn={".ts":"typescript",".tsx":"tsx",".js":"javascript",".jsx":"jsx",".json":"json",".md":"markdown",".css":"css",".scss":"scss",".html":"html",".py":"python",".rb":"ruby",".go":"go",".rs":"rust",".java":"java",".c":"c",".cpp":"cpp",".h":"c",".sh":"bash",".bash":"bash",".zsh":"bash",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".sql":"sql",".graphql":"graphql",".dockerfile":"dockerfile",".tf":"hcl"},Cn={dockerfile:"dockerfile",makefile:"makefile"};[...new Set([...Object.values(Dn),...Object.values(Cn)])];function Fe(e,t){return Dn[e]||Cn[t]||"text"}s(Fe,"detectLanguage");function Mo(e){return e instanceof Error?e.message:String(e)}s(Mo,"errorMessage");function Nn(e,t,r,n){n(t.id),e.status(503).json({error:Mo(r)});}s(Nn,"sendWorktreeSessionReadinessError");var H=Router();function yt(e){for(let t of P()){let r=R(t.path,t.id).find(n=>n.id===e);if(r)return r.path}return null}s(yt,"findWorktreePath");H.delete("/worktrees/:wtId",(e,t)=>{let{wtId:r}=e.params,n=e.query.force==="true"||e.body&&e.body.force===true;for(let o of P()){let i=R(o.path,o.id).find(a=>a.id===r);if(i){if(!n&&!i.isMain&&Xe(i.path)){t.status(409).json({error:"Worktree has uncommitted changes",requiresForce:true});return}try{Ie(o.path,i.path,{force:n});}catch(c){t.status(409).json({error:c instanceof Error?c.message:String(c),requiresForce:false});return}let a=Ne(r);t.json({deleted:true,sessionsKilled:a});return}}t.status(404).json({error:"Worktree not found"});});H.get("/worktrees/:wtId/status",(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}t.json({dirty:Xe(r)});});H.post("/worktrees/:wtId/rename",(e,t)=>{let{wtId:r}=e.params,{newName:n}=e.body||{};if(!n){t.status(400).json({error:"newName is required"});return}for(let o of P()){let i=R(o.path,o.id).find(a=>a.id===r);if(i){try{Ut(i.path,i.branch,n),t.json({branch:n});}catch(a){t.status(409).json({error:a instanceof Error?a.message:String(a)});}return}}t.status(404).json({error:"Worktree not found"});});H.get("/worktrees/:wtId/sessions",(e,t)=>{let r=K(e.params.wtId);t.json(r.map(n=>({id:n.id,worktreeId:n.worktreeId,port:n.port,url:`/t/${n.id}/`,createdAt:n.createdAt,command:Gt(n.tmuxName)})));});H.post("/worktrees/:wtId/sessions",async(e,t)=>{let{wtId:r}=e.params,{worktreePath:n}=e.body||{};if(!n){t.status(400).json({error:"worktreePath is required"});return}try{let o=e.headers.host??"127.0.0.1:17716",i=En(r,n,{registryUrlFor:s(a=>`http://${o}/t/${a}/registry`,"registryUrlFor")});try{await Y(i);}catch(a){Nn(t,i,a,xe);return}t.status(201).json({id:i.id,worktreeId:i.worktreeId,port:i.port,url:`/t/${i.id}/`,createdAt:i.createdAt});}catch(o){let i=o instanceof Error?o.message:String(o);t.status(i.includes("No free ports")?503:500).json({error:i});}});H.get("/worktrees/:wtId/files",async(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}let n=e.query.path||"",o;try{o=qe(r,n);}catch{t.status(403).json({error:"Path traversal detected"});return}try{let i=await readdir(o,{withFileTypes:!0}),a=await Promise.all(i.filter(c=>!c.name.startsWith(".")).map(async c=>{let l=c.isDirectory()?"directory":"file",u=0;if(l==="file")try{u=(await stat(x.join(o,c.name))).size;}catch{}return {name:c.name,type:l,size:u}}));a.sort((c,l)=>c.type!==l.type?c.type==="directory"?-1:1:c.name.localeCompare(l.name)),t.json({path:n,entries:a});}catch{t.status(404).json({error:"Path not found"});}});H.get("/worktrees/:wtId/file",async(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}let n=e.query.path||"";if(!n){t.status(400).json({error:"path is required"});return}let o;try{o=qe(r,n);}catch{t.status(403).json({error:"Path traversal detected"});return}try{let i=await stat(o);if(i.size>1024*1024){t.status(413).json({error:"File too large (>1MB)"});return}let a=await readFile(o,"utf-8"),c=x.extname(o).toLowerCase(),l=x.basename(o).toLowerCase(),u=Fe(c,l);t.json({path:n,content:a,language:u,size:i.size});}catch{t.status(404).json({error:"File not found"});}});var Te=null,ce=null,Re=null,We=null,Wn=Ln(5e3),Fo=500;function Wo(e){return e.replace(/\\/g,"/")}s(Wo,"normalizeWatchPath");function Lo(e){return e===".git"||e.startsWith(".git/")}s(Lo,"isGitInternalPath");function Ln(e){let t=Number.NEGATIVE_INFINITY;return {shouldLog(r=Date.now()){return r-t<e?false:(t=r,true)}}}s(Ln,"createWatchEventLogLimiter");function Un(e){let t=No();try{let r=readFileSync(x.join(e,".gitignore"),"utf-8");t.add(r);}catch{}return t.add(["node_modules",".next","dist","standalone","test-results/","e2e/test-results/","playwright-report/","e2e/playwright-report/","**/.playwright-artifacts-*"]),t}s(Un,"buildWatchIgnoreMatcher");function Uo(e,t,r){let n=Wo(t);return n==="<unknown>"?false:n===".gitignore"||n.endsWith("/.gitignore")?(We=Un(e),false):Lo(n)?true:r?r.ignores(n):false}s(Uo,"shouldIgnoreWatchPath");function Bn(e){if(ce!==e){Le(),ce=e,We=Un(e);try{console.log(`[watcher] start watching path=${e}`),Te=watch(e,{recursive:!0},(t,r)=>{let n=typeof r=="string"&&r.length>0?r:"<unknown>";Uo(e,n,We)||(Wn.shouldLog()&&console.log(`[watcher] fs event path=${e} event=${t} file=${n}`),Re&&clearTimeout(Re),Re=setTimeout(()=>{console.log(`[watcher] broadcast files-changed path=${e}`),$("files-changed");},Fo));}),Te.on("error",t=>{let r=t instanceof Error?t.message:String(t);console.error(`[watcher] error path=${e} message=${r}`),Le();});}catch{console.error(`[watcher] failed to watch path=${e}`),ce=null;}}}s(Bn,"watchWorkspace");function Le(){Re&&clearTimeout(Re),Te&&(ce&&console.log(`[watcher] stop watching path=${ce}`),Te.close(),Te=null),Wn=Ln(5e3),We=null,ce=null;}s(Le,"stopWatching");var Ue=Router();Ue.get("/settings",(e,t)=>{t.json(S());});Ue.put("/settings",(e,t)=>{let r=e.body||{},n=L(r);n.activePath?Bn(n.activePath):Le(),t.json(n);});function E(){let e=S(),t=new Set([homedir()]);for(let r of e.trackedDirs)t.add(r);for(let r of P()){t.add(r.path);try{for(let n of R(r.path,r.id))t.add(n.path);}catch{}}return [...t]}s(E,"allowedRoots");var ee=Router();ee.get("/fs",async(e,t)=>{let r=e.query.path||"",n=e.query.mode||"list",o=I(r,E());if(!o){t.status(403).json({error:"Path outside allowed roots"});return}try{if(n==="read"){let c=await stat(o),l=x.extname(o).toLowerCase();if(c.size>1024*1024){t.status(413).json({error:"File too large (>1MB)"});return}let u=await readFile(o,"utf-8"),d=Fe(l,x.basename(o).toLowerCase());gn(d),t.json({path:r,content:u,language:d,size:c.size});return}let a=(await readdir(o,{withFileTypes:!0})).map(c=>({name:c.name,type:c.isDirectory()?"directory":"file"}));a.sort((c,l)=>c.type!==l.type?c.type==="directory"?-1:1:c.name.localeCompare(l.name)),t.json({path:r,entries:a});}catch{t.status(404).json({error:"Not found"});}});ee.put("/fs",async(e,t)=>{let{path:r,content:n}=e.body||{};if(!r||n===void 0){t.status(400).json({error:"path and content required"});return}let o=I(r,E());if(!o){t.status(403).json({error:"Path outside allowed roots"});return}try{await writeFile(o,n,"utf-8"),t.json({saved:!0,path:r});}catch(i){t.status(500).json({error:i instanceof Error?i.message:String(i)});}});ee.get("/browse",async(e,t)=>{let r=e.query.path||homedir(),n=I(r,E());if(!n){t.status(403).json({error:"Path outside allowed roots"});return}if(!existsSync(n)){t.status(404).json({error:"Path not found"});return}try{let o=await readdir(n,{withFileTypes:!0}),i=(await Promise.all(o.map(async c=>{if(c.name.startsWith("."))return null;if(c.isDirectory())return c.name;if(!c.isSymbolicLink())return null;try{return (await stat(x.join(n,c.name))).isDirectory()?c.name:null}catch{return null}}))).filter(c=>!!c).sort(),a=existsSync(x.join(n,".git"))||existsSync(x.join(n,"HEAD"));t.json({path:n,parent:x.dirname(n),dirs:i,isGitRepo:a});}catch{t.status(403).json({error:"Cannot read directory"});}});ee.get("/git/status",(e,t)=>{let r=e.query.cwd||"",n=I(r,E());if(!n){t.status(403).json({error:"Path outside allowed roots"});return}try{let o=execFileSync("git",["status","--porcelain","-uall"],{cwd:n,encoding:"utf-8"}).replace(/\n$/,""),i={};if(o)for(let a of o.split(`
`):[]);}catch{e=new Set;}try{let t=execFileSync("ps",["-eo","pid,command"],{encoding:"utf-8"}).trim();if(!t)return;let r=0;for(let n of bo(t,e))try{process.kill(n,"SIGTERM"),r++;}catch{}r>0&&(console.log(`[cleanup] killed ${r} stale ttyd processes`),hn(r));}catch{}}s(lt,"killOrphanedTtydProcesses");function vn(){return {readySessionNames:new Set,pendingReadiness:new Map,generations:new Map}}s(vn,"createSessionTtydReadinessState");function P(e,t){t.readySessionNames.delete(e),t.pendingReadiness.delete(e),t.generations.set(e,(t.generations.get(e)??0)+1);}s(P,"clearSessionTtydReadiness");async function Tn(e,t,r,n){let o=e.tmuxName;if(n.readySessionNames.has(o)){if(r.isTtydAlive(o))return;P(o,n);}let i=n.pendingReadiness.get(o);if(i){if(await i,n.readySessionNames.has(o)&&r.isTtydAlive(o))return;throw new Error(`ttyd readiness invalidated for ${o}`)}let a=n.generations.get(o)??0;r.isTtydAlive(o)||(P(o,n),a=n.generations.get(o)??0,r.spawnTtyd(o,e.port));let c=r.waitForTtydReady(e.port,t).then(()=>{if((n.generations.get(o)??0)!==a)throw new Error(`ttyd readiness invalidated for ${o}`);if(!r.isTtydAlive(o))throw P(o,n),new Error(`ttyd exited before readiness completed for ${o}`);n.readySessionNames.add(o);}).finally(()=>{n.pendingReadiness.get(o)===c&&n.pendingReadiness.delete(o);});n.pendingReadiness.set(o,c),await c;}s(Tn,"ensureSessionTtydReadyWithState");var Rn=globalThis;function kn(){Rn.__omniterm_recovered||(Rn.__omniterm_recovered=true,lt());}s(kn,"recoverAll");var Ce=ue?x.join(ue,"omniterm-browser.js"):null,To=Ce!==null&&existsSync(Ce),_n="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin";function ut(e){let t={OMNITERM_BROWSER_REGISTRY_URL:e};return To&&Ce&&ue?(t.BROWSER=Ce,t.PATH=`${ue}:${_n}`):t.PATH=_n,t}s(ut,"buildTabEnv");var V=globalThis,A=V.__omniterm_sessions||new Map,dt=V.__omniterm_counters||new Map,N=V.__omniterm_ttyd_readiness||vn();V.__omniterm_sessions=A;V.__omniterm_counters=dt;V.__omniterm_ttyd_readiness=N;var Ro={isTtydAlive:ct,spawnTtyd:we,waitForTtydReady:xn};V.__omniterm_session_ttyd_listener_registered||(bn(e=>P(e,N)),V.__omniterm_session_ttyd_listener_registered=true);function ko(e){let t=(dt.get(e)||0)+1;for(;me(`${e}-term-${t}`);)t++;return dt.set(e,t),`${e}-term-${t}`}s(ko,"nextId");kn();function En(e,t,r){let n=Date.now(),o=ko(e),i=Qe(),a=Date.now();$e(o,t,ut(r.registryUrlFor(o)));let c=Date.now(),l={id:o,worktreeId:e,tmuxName:o,port:i,createdAt:new Date().toISOString()};P(l.tmuxName,N),we(l.tmuxName,l.port);let u=Date.now();A.set(o,l),rt(l.tmuxName);let d=Date.now();return console.log(`[session] ${o}: tmux=${c-a}ms ttyd=${u-c}ms total=${d-n}ms`),$("session-created",{sessionId:o,worktreeId:e,path:t}),l}s(En,"createSession");function q(e){let t=A.get(e);if(t){if(!me(t.tmuxName)){P(t.tmuxName,N),be(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName);return}return ct(t.tmuxName)||(P(t.tmuxName,N),we(t.tmuxName,t.port)),t}}s(q,"getSession");async function Y(e,t=3e3){await Tn(e,t,Ro,N);}s(Y,"ensureSessionTtydReady");function In(e){let t=A.get(e);return t?(P(t.tmuxName,N),be(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName),true):false}s(In,"unregisterSession");function K(e){let t=Array.from(A.values());return e?t.filter(r=>r.worktreeId===e):t}s(K,"listSessions");function xe(e){let t=A.get(e);return t?(P(t.tmuxName,N),be(t.tmuxName),tt(t.tmuxName),pe(t.port),A.delete(e),he(t.tmuxName),fn(),$("session-closed",{sessionId:e,worktreeId:t.worktreeId}),true):false}s(xe,"deleteSession");function Ne(e){let t=K(e);for(let r of t)P(r.tmuxName,N),be(r.tmuxName),tt(r.tmuxName),pe(r.port),A.delete(r.id),he(r.tmuxName);return t.length>0&&$("session-closed",{worktreeId:e,sessionCount:t.length}),t.length}s(Ne,"deleteSessionsForWorktree");function pt(e,t){let r=Date.now(),n=Qe(),o=Date.now();if(!t?.skipTmuxSetup){et();try{execFileSync("tmux",["set-option","-t",`=${e}:`,"mouse","on"],{stdio:"ignore"});}catch{}}let i=Date.now();P(e,N),we(e,n);let a=Date.now(),c={id:e,worktreeId:"_orphan",tmuxName:e,port:n,createdAt:new Date().toISOString()};A.set(c.id,c),rt(c.tmuxName);let l=o-r,u=a-r;console.log(`[session] adopted ${e}: port=${n} allocate=${l}ms setup=${i-o}ms ttyd=${a-i}ms total=${u}ms skip=${t?.skipTmuxSetup?1:0}`),mn({total_ms:u,allocate_port_ms:l});let d=t?.knownCwd??"";if(!d)try{d=execFileSync("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_current_path}"],{encoding:"utf-8"}).trim();}catch{}return $("session-adopted",{sessionId:e,worktreeId:"_orphan",path:d}),c}s(pt,"adoptSession");function _o(e){let t=x.join(e,".git");try{let n=statSync(t);if(n.isDirectory())return x.join(t,"config");if(n.isFile()){let o=readFileSync(t,"utf-8").match(/^gitdir:\s*(.+)$/m);if(o){let i=x.resolve(e,o[1].trim()),a=x.join(i,"commondir"),c=existsSync(a)?x.resolve(i,readFileSync(a,"utf-8").trim()):i;return x.join(c,"config")}}}catch{}let r=x.join(e,"config");return existsSync(r)?r:null}s(_o,"gitConfigPath");function Eo(e){let t=false;for(let r of e.split(`
`)){let n=r.trim();if(n.startsWith("[")){t=/^\[remote\s+"origin"\]$/.test(n);continue}if(t){let o=n.match(/^url\s*=\s*(.+)$/);if(o)return o[1].trim()}}return ""}s(Eo,"parseOriginUrl");var Mn=new Map;function An(e){let t=_o(e);if(!t)return "";try{let{mtimeMs:r}=statSync(t),n=Mn.get(t);if(n&&n.mtimeMs===r)return n.url;let o=Eo(readFileSync(t,"utf-8"));return Mn.set(t,{mtimeMs:r,url:o}),o}catch{return ""}}s(An,"getRemoteUrl");function ft(e){return existsSync(x.join(e,".git"))||existsSync(x.join(e,"HEAD"))}s(ft,"isGitRepo");function _(){return S().trackedRepos.filter(t=>existsSync(t)&&ft(t)).map(t=>({id:G(t),name:C(t),remoteUrl:An(t),path:t}))}s(_,"listRepos");function ve(e){let t=S();for(let r of t.trackedRepos)if(G(r)===e&&existsSync(r)&&ft(r))return {id:e,name:C(r),remoteUrl:An(r),path:r}}s(ve,"getRepo");function gt(e){let t=x.resolve(e);if(!existsSync(t))throw new Error(`Path "${t}" does not exist`);let r=S();if(ft(t))return r.trackedRepos.includes(t)||L({trackedRepos:[...r.trackedRepos,t]}),{type:"repo",path:t};{let n=r.trackedRepos.filter(i=>i!==t),o=r.trackedDirs.includes(t)?r.trackedDirs:[...r.trackedDirs,t];return (n.length!==r.trackedRepos.length||o!==r.trackedDirs)&&L({trackedRepos:n,trackedDirs:o}),{type:"dir",path:t}}}s(gt,"addLocalPath");function On(e,t){let r=e.match(/\/([^/]+?)(\.git)?$/)?.[1]||"repo",n=t||x.join(process.env.HOME||"/tmp",r);if(existsSync(n))throw new Error(`"${n}" already exists`);execFileSync("git",["clone",e,n],{encoding:"utf-8",timeout:3e5});let o=S();return L({trackedRepos:[...o.trackedRepos,n]}),{id:G(n),name:C(n),remoteUrl:e,path:n}}s(On,"cloneRepo");function Dn(e){let t=ve(e);if(!t)throw new Error(`Repo "${e}" not found`);let r=0,n=0,o=[],i=R(t.path,e);for(let c of i)if(n+=Ne(c.id),!c.isMain)try{Ie(t.path,c.path),r++;}catch{o.push(c.path);}let a=S();return L({trackedRepos:a.trackedRepos.filter(c=>c!==t.path)}),{worktreesRemoved:r,worktreesSkipped:o,sessionsKilled:n}}s(Dn,"removeRepo");var Q=Router();Q.get("/repos",(e,t)=>{t.json(_());});Q.post("/repos",async(e,t)=>{let{url:r,localPath:n,destination:o}=e.body||{};if(!r&&!n){t.status(400).json({error:"url or localPath is required"});return}try{let i=n?gt(n):null,a=i?{id:G(i.path),name:C(i.path),...i}:On(r,o);t.status(201).json(a);}catch(i){let a=i instanceof Error?i.message:String(i);t.status(a.includes("already")?409:400).json({error:a});}});Q.delete("/repos/:repoId",(e,t)=>{if(!ve(e.params.repoId)){t.status(404).json({error:"Repo not found"});return}let n=Dn(e.params.repoId);t.json({deleted:true,...n});});Q.get("/repos/:repoId/worktrees",(e,t)=>{let r=ve(e.params.repoId);if(!r){t.status(404).json({error:"Repo not found"});return}let n=R(r.path,e.params.repoId),o=Ae();t.json(n.map(i=>({...i,sessionCount:o.filter(a=>a.cwd===i.path).length})));});Q.post("/repos/:repoId/worktrees",async(e,t)=>{let r=ve(e.params.repoId);if(!r){t.status(404).json({error:"Repo not found"});return}let{branch:n,newBranch:o=true}=e.body||{};try{let i=Lt(r.path,e.params.repoId,n,o);t.status(201).json(i);}catch(i){let a=i instanceof Error?i.message:String(i);t.status(a.includes("already has a worktree")?409:400).json({error:a});}});var jn={".ts":"typescript",".tsx":"tsx",".js":"javascript",".jsx":"jsx",".json":"json",".md":"markdown",".css":"css",".scss":"scss",".html":"html",".py":"python",".rb":"ruby",".go":"go",".rs":"rust",".java":"java",".c":"c",".cpp":"cpp",".h":"c",".sh":"bash",".bash":"bash",".zsh":"bash",".yaml":"yaml",".yml":"yaml",".toml":"toml",".xml":"xml",".sql":"sql",".graphql":"graphql",".dockerfile":"dockerfile",".tf":"hcl"},Cn={dockerfile:"dockerfile",makefile:"makefile"};[...new Set([...Object.values(jn),...Object.values(Cn)])];function Fe(e,t){return jn[e]||Cn[t]||"text"}s(Fe,"detectLanguage");function Mo(e){return e instanceof Error?e.message:String(e)}s(Mo,"errorMessage");function Nn(e,t,r,n){n(t.id),e.status(503).json({error:Mo(r)});}s(Nn,"sendWorktreeSessionReadinessError");var H=Router();function yt(e){for(let t of _()){let r=R(t.path,t.id).find(n=>n.id===e);if(r)return r.path}return null}s(yt,"findWorktreePath");H.delete("/worktrees/:wtId",(e,t)=>{let{wtId:r}=e.params,n=e.query.force==="true"||e.body&&e.body.force===true;for(let o of _()){let i=R(o.path,o.id).find(a=>a.id===r);if(i){if(!n&&!i.isMain&&Xe(i.path)){t.status(409).json({error:"Worktree has uncommitted changes",requiresForce:true});return}try{Ie(o.path,i.path,{force:n});}catch(c){t.status(409).json({error:c instanceof Error?c.message:String(c),requiresForce:false});return}let a=Ne(r);t.json({deleted:true,sessionsKilled:a});return}}t.status(404).json({error:"Worktree not found"});});H.get("/worktrees/:wtId/status",(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}t.json({dirty:Xe(r)});});H.post("/worktrees/:wtId/rename",(e,t)=>{let{wtId:r}=e.params,{newName:n}=e.body||{};if(!n){t.status(400).json({error:"newName is required"});return}for(let o of _()){let i=R(o.path,o.id).find(a=>a.id===r);if(i){try{Ut(i.path,i.branch,n),t.json({branch:n});}catch(a){t.status(409).json({error:a instanceof Error?a.message:String(a)});}return}}t.status(404).json({error:"Worktree not found"});});H.get("/worktrees/:wtId/sessions",(e,t)=>{let r=K(e.params.wtId);t.json(r.map(n=>({id:n.id,worktreeId:n.worktreeId,port:n.port,url:`/t/${n.id}/`,createdAt:n.createdAt,command:Gt(n.tmuxName)})));});H.post("/worktrees/:wtId/sessions",async(e,t)=>{let{wtId:r}=e.params,{worktreePath:n}=e.body||{};if(!n){t.status(400).json({error:"worktreePath is required"});return}try{let o=e.headers.host??"127.0.0.1:17716",i=En(r,n,{registryUrlFor:s(a=>`http://${o}/t/${a}/registry`,"registryUrlFor")});try{await Y(i);}catch(a){Nn(t,i,a,xe);return}t.status(201).json({id:i.id,worktreeId:i.worktreeId,port:i.port,url:`/t/${i.id}/`,createdAt:i.createdAt});}catch(o){let i=o instanceof Error?o.message:String(o);t.status(i.includes("No free ports")?503:500).json({error:i});}});H.get("/worktrees/:wtId/files",async(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}let n=e.query.path||"",o;try{o=qe(r,n);}catch{t.status(403).json({error:"Path traversal detected"});return}try{let i=await readdir(o,{withFileTypes:!0}),a=await Promise.all(i.filter(c=>!c.name.startsWith(".")).map(async c=>{let l=c.isDirectory()?"directory":"file",u=0;if(l==="file")try{u=(await stat(x.join(o,c.name))).size;}catch{}return {name:c.name,type:l,size:u}}));a.sort((c,l)=>c.type!==l.type?c.type==="directory"?-1:1:c.name.localeCompare(l.name)),t.json({path:n,entries:a});}catch{t.status(404).json({error:"Path not found"});}});H.get("/worktrees/:wtId/file",async(e,t)=>{let r=yt(e.params.wtId);if(!r){t.status(404).json({error:"Worktree not found"});return}let n=e.query.path||"";if(!n){t.status(400).json({error:"path is required"});return}let o;try{o=qe(r,n);}catch{t.status(403).json({error:"Path traversal detected"});return}try{let i=await stat(o);if(i.size>1024*1024){t.status(413).json({error:"File too large (>1MB)"});return}let a=await readFile(o,"utf-8"),c=x.extname(o).toLowerCase(),l=x.basename(o).toLowerCase(),u=Fe(c,l);t.json({path:n,content:a,language:u,size:i.size});}catch{t.status(404).json({error:"File not found"});}});var Te=null,ce=null,Re=null,We=null,Wn=Ln(5e3),Fo=500;function Wo(e){return e.replace(/\\/g,"/")}s(Wo,"normalizeWatchPath");function Lo(e){return e===".git"||e.startsWith(".git/")}s(Lo,"isGitInternalPath");function Ln(e){let t=Number.NEGATIVE_INFINITY;return {shouldLog(r=Date.now()){return r-t<e?false:(t=r,true)}}}s(Ln,"createWatchEventLogLimiter");function Un(e){let t=No();try{let r=readFileSync(x.join(e,".gitignore"),"utf-8");t.add(r);}catch{}return t.add(["node_modules",".next","dist","standalone","test-results/","e2e/test-results/","playwright-report/","e2e/playwright-report/","**/.playwright-artifacts-*"]),t}s(Un,"buildWatchIgnoreMatcher");function Uo(e,t,r){let n=Wo(t);return n==="<unknown>"?false:n===".gitignore"||n.endsWith("/.gitignore")?(We=Un(e),false):Lo(n)?true:r?r.ignores(n):false}s(Uo,"shouldIgnoreWatchPath");function Bn(e){if(ce!==e){Le(),ce=e,We=Un(e);try{console.log(`[watcher] start watching path=${e}`),Te=watch(e,{recursive:!0},(t,r)=>{let n=typeof r=="string"&&r.length>0?r:"<unknown>";Uo(e,n,We)||(Wn.shouldLog()&&console.log(`[watcher] fs event path=${e} event=${t} file=${n}`),Re&&clearTimeout(Re),Re=setTimeout(()=>{console.log(`[watcher] broadcast files-changed path=${e}`),$("files-changed");},Fo));}),Te.on("error",t=>{let r=t instanceof Error?t.message:String(t);console.error(`[watcher] error path=${e} message=${r}`),Le();});}catch{console.error(`[watcher] failed to watch path=${e}`),ce=null;}}}s(Bn,"watchWorkspace");function Le(){Re&&clearTimeout(Re),Te&&(ce&&console.log(`[watcher] stop watching path=${ce}`),Te.close(),Te=null),Wn=Ln(5e3),We=null,ce=null;}s(Le,"stopWatching");var Ue=Router();Ue.get("/settings",(e,t)=>{t.json(S());});Ue.put("/settings",(e,t)=>{let r=e.body||{},n=L(r);n.activePath?Bn(n.activePath):Le(),t.json(n);});function E(){let e=S(),t=new Set([homedir()]);for(let r of e.trackedDirs)t.add(r);for(let r of _()){t.add(r.path);try{for(let n of R(r.path,r.id))t.add(n.path);}catch{}}return [...t]}s(E,"allowedRoots");var ee=Router();ee.get("/fs",async(e,t)=>{let r=e.query.path||"",n=e.query.mode||"list",o=I(r,E());if(!o){t.status(403).json({error:"Path outside allowed roots"});return}try{if(n==="read"){let c=await stat(o),l=x.extname(o).toLowerCase();if(c.size>1024*1024){t.status(413).json({error:"File too large (>1MB)"});return}let u=await readFile(o,"utf-8"),d=Fe(l,x.basename(o).toLowerCase());gn(d),t.json({path:r,content:u,language:d,size:c.size});return}let a=(await readdir(o,{withFileTypes:!0})).map(c=>({name:c.name,type:c.isDirectory()?"directory":"file"}));a.sort((c,l)=>c.type!==l.type?c.type==="directory"?-1:1:c.name.localeCompare(l.name)),t.json({path:r,entries:a});}catch{t.status(404).json({error:"Not found"});}});ee.put("/fs",async(e,t)=>{let{path:r,content:n}=e.body||{};if(!r||n===void 0){t.status(400).json({error:"path and content required"});return}let o=I(r,E());if(!o){t.status(403).json({error:"Path outside allowed roots"});return}try{await writeFile(o,n,"utf-8"),t.json({saved:!0,path:r});}catch(i){t.status(500).json({error:i instanceof Error?i.message:String(i)});}});ee.get("/browse",async(e,t)=>{let r=e.query.path||homedir(),n=I(r,E());if(!n){t.status(403).json({error:"Path outside allowed roots"});return}if(!existsSync(n)){t.status(404).json({error:"Path not found"});return}try{let o=await readdir(n,{withFileTypes:!0}),i=(await Promise.all(o.map(async c=>{if(c.name.startsWith("."))return null;if(c.isDirectory())return c.name;if(!c.isSymbolicLink())return null;try{return (await stat(x.join(n,c.name))).isDirectory()?c.name:null}catch{return null}}))).filter(c=>!!c).sort(),a=existsSync(x.join(n,".git"))||existsSync(x.join(n,"HEAD"));t.json({path:n,parent:x.dirname(n),dirs:i,isGitRepo:a});}catch{t.status(403).json({error:"Cannot read directory"});}});ee.get("/git/status",(e,t)=>{let r=e.query.cwd||"",n=I(r,E());if(!n){t.status(403).json({error:"Path outside allowed roots"});return}try{let o=execFileSync("git",["status","--porcelain","-uall"],{cwd:n,encoding:"utf-8"}).replace(/\n$/,""),i={};if(o)for(let a of o.split(`
`)){let c=a.substring(0,2),l=a.substring(3);i[l]=c;}t.json(i);}catch{t.json({});}});ee.get("/git/show",(e,t)=>{let r=e.query.cwd||"",n=e.query.path||"",o=I(r,E());if(!o){t.status(403).json({error:"Path outside allowed roots"});return}if(!n){t.status(400).json({error:"path is required"});return}try{let i=execFileSync("git",["show",`HEAD:${n}`],{cwd:o,encoding:"utf-8"});t.json({content:i});}catch{t.json({content:""});}});var Be=Router(),Zo=1024*1024,Qo=25*1024*1024;Be.get("/preview/markdown",async(e,t)=>{let r=e.query.path||"",n=I(r,E());if(!n){t.status(403).type("text/plain").send("Path outside allowed roots");return}try{if((await stat(n)).size>Zo){t.status(413).type("text/plain").send("Markdown file too large (>1MB)");return}let i=await readFile(n,"utf-8"),a=marked.parse(i,{async:!1,gfm:!0,breaks:!1});t.type("text/html; charset=utf-8").send(es(x.basename(n),a));}catch{t.status(404).type("text/plain").send("Not found");}});Be.get(/^\/preview\/raw\/(.+)$/,async(e,t)=>{let r=e.params[0]??"";if(!r){t.status(400).type("text/plain").send("Missing path");return}let n="/"+r,o=I(n,E());if(!o){t.status(403).type("text/plain").send("Path outside allowed roots");return}try{let i=await stat(o);if(!i.isFile()){t.status(404).type("text/plain").send("Not a file");return}if(i.size>Qo){t.status(413).type("text/plain").send("File too large (>25MB)");return}t.sendFile(o,{dotfiles:"allow"},a=>{a&&!t.headersSent&&t.status(500).type("text/plain").send("Send failed");});}catch{t.status(404).type("text/plain").send("Not found");}});function es(e,t){return `<!DOCTYPE html>

@@ -86,9 +86,9 @@ <html lang="en">

</body>
</html>`}s(es,"renderShell");function ts(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}s(ts,"escapeHtml");function rs(e){return e.flatMap(t=>t.manifest?[t.manifest]:[])}s(rs,"buildManifest");function qn(e){let t=new Set;for(let r of e){if(!(!!r.manifest||r.render?.type==="component"))throw new Error(`[omniterm] plugin "${r.type}" provides neither a \`manifest\` (iframe) nor a \`component\` render; the host client cannot render it. Add a manifest (PluginManifestEntry) to make it a runtime-loadable iframe plugin.`);if(r.proxyPrefix){if(t.has(r.proxyPrefix))throw new Error(`[omniterm] plugin "${r.type}" shares proxyPrefix "${r.proxyPrefix}" with an earlier plugin; their routes would silently shadow. Use distinct prefixes.`);t.add(r.proxyPrefix);}}}s(qn,"validatePluginManifests");function Yn(e){let t=Router(),r=rs(e);return t.get("/plugins",(n,o)=>{o.setHeader("Cache-Control","no-store"),o.json({plugins:r});}),t}s(Yn,"createManifestRouter");var bt=promisify(execFile),xt=5e3,Kn=128,Xn=4096,J=Router();function He(e){return {id:e.id,worktreeId:e.worktreeId,port:e.port,url:`/t/${e.id}/`,createdAt:e.createdAt}}s(He,"serializeSession");async function Qn(e,t){let r=t??q(e),n=r??pt(e);try{await Y(n);}catch(o){throw In(n.id),o}return {session:n,wasRegistered:!!r}}s(Qn,"adoptAndReady");async function er(e,t,r){try{let{session:n,wasRegistered:o}=await Qn(e,r);t.status(o?200:201).json(He(n));}catch(n){t.status(503).json({error:n instanceof Error?n.message:String(n)});}}s(er,"adoptOrAttach");J.get("/sessions/:sessionId",(e,t)=>{let r=q(e.params.sessionId);if(!r){t.status(404).json({error:"Session not found"});return}t.json(He(r));});J.delete("/sessions/:sessionId",(e,t)=>{if(!q(e.params.sessionId)){t.status(404).json({error:"Session not found"});return}xe(e.params.sessionId),t.json({deleted:true});});J.post("/create-session",async(e,t)=>{let r=e.body?.cwd==="~"?homedir():e.body?.cwd;if(!r){t.status(400).json({error:"cwd is required"});return}let n=e.body?.initialCommand,o=typeof n=="string"&&n.trim()?n.trim():void 0;if(o!==void 0&&o.length>Xn){t.status(400).json({error:`initialCommand exceeds ${Xn} characters`});return}let i=e.body?.name,a=typeof i=="string"&&i.trim()?i:void 0;if(a!==void 0&&(a.length>Kn||!/^[A-Za-z0-9_-]+$/.test(a))){t.status(400).json({error:`name must be 1\u2013${Kn} characters of letters, digits, dashes, or underscores`});return}if(a){let p=q(a);if(p||me(a)){await er(a,t,p);return}}let c=(r.split("/").pop()||"session").replace(/[^A-Za-z0-9_-]/g,"-"),l=Date.now().toString(36),u=a??`${c}-${l}`,d;try{let p=Date.now(),b=`http://${e.headers.host??"127.0.0.1:17716"}/t/${u}/registry`;$e(u,r,ut(b),{initialCommand:o});let O=Date.now();d=pt(u,{skipTmuxSetup:!0,knownCwd:r});let D=Date.now();await Y(d);let m=Date.now(),y=O-p,T=D-O,W=m-D,v=m-p;console.log(`[session] create-session: tmux=${y}ms adopt=${T}ms ttyd_ready=${W}ms total=${v}ms`),pn({total_ms:v,tmux_ms:y,adopt_ms:T,ttyd_ready_ms:W}),t.status(201).json(He(d));}catch(p){d&&xe(d.id),t.status(500).json({error:p instanceof Error?p.message:String(p)});}});J.get("/dir-sessions",async(e,t)=>{try{let r=e.query.cwd||"~",n=r==="~"?homedir():r,o;try{let{stdout:d}=await bt("tmux",["list-sessions","-F","#{session_name}|||#{session_path}"],{encoding:"utf-8",timeout:xt});o=d.trim();}catch{t.json([]);return}if(!o){t.json([]);return}let i=[...await tr(),...S().trackedDirs],a=s(d=>{if(!(d===n||d.startsWith(n+"/")))return !1;for(let p of i)if(p!==n&&p.length>n.length&&(d===p||d.startsWith(p+"/")))return !1;return !0},"isMostSpecificMatch"),c=o.split(`
`).map(d=>{let[p,h]=d.split("|||");return {name:p,path:h}}).filter(d=>a(d.path)),l=new Map(K().map(d=>[d.tmuxName,d])),u=await Promise.all(c.map(async d=>{try{let{session:p}=await Qn(d.name,l.get(d.name));return {...He(p),command:await cs(p.tmuxName)}}catch(p){let h=p instanceof Error?p.message:String(p);return console.error(`[session] failed to ready adopted session ${d.name}: ${h}`),null}}));t.json(u.filter(d=>d!==null));}catch(r){t.status(500).json({error:r instanceof Error?r.message:String(r)});}});J.post("/adopt-session/:sessionName",async(e,t)=>{await er(e.params.sessionName,t);});var Jn=new Set,Zn=0;async function tr(){if(Date.now()-Zn<3e4)return Jn;let e=new Set,t=[];for(let{path:n}of P())e.add(n),t.push(n);let r=await Promise.all(t.map(n=>as(n)));for(let n of r)for(let o of n)e.add(o);return Jn=e,Zn=Date.now(),e}s(tr,"getRepoWorktreePaths");async function as(e){try{let{stdout:t}=await bt("git",["worktree","list","--porcelain"],{cwd:e,encoding:"utf-8",timeout:xt}),r=[];for(let n of t.split(`
`))if(n.startsWith("worktree ")){let o=n.substring(9);o&&!r.includes(o)&&r.push(o);}return r}catch(t){return console.error(`git worktree list failed for ${e}:`,t),[]}}s(as,"listWorktreePathsAsync");async function cs(e){try{let{stdout:t}=await bt("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_title}|||#{pane_current_command}"],{encoding:"utf-8",timeout:xt}),[r="",n=""]=t.trim().split("|||"),o=r.trim();return nt(e,o)?o:n.trim()}catch{return ""}}s(cs,"getTmuxPaneTitleAsync");function ls(e){let{tmuxSessions:t,managedNames:r,repoWorktreePaths:n,trackedDirs:o,home:i}=e,a={[i]:[]};for(let c of o)!n.has(c)&&c!==i&&(a[c]=[]);for(let c of t)!r.has(c.name)&&!n.has(c.cwd)?(a[c.cwd]||(a[c.cwd]=[]),a[c.cwd].push({name:c.name,created:c.created})):a[c.cwd]&&a[c.cwd].push({name:c.name,created:c.created});return a}s(ls,"bucketDiscoveredSessions");J.get("/discover-sessions",async(e,t)=>{try{let r=ls({tmuxSessions:Ae(),managedNames:new Set(K().map(n=>n.tmuxName)),repoWorktreePaths:await tr(),trackedDirs:S().trackedDirs,home:homedir()});t.json(r);}catch(r){t.status(500).json({error:r instanceof Error?r.message:String(r)});}});var z=new Map;function te(e){return Array.isArray(e)?e[0]??"":e??""}s(te,"paramValue");function nr(e){let t=z.get(e);return t||(t={entries:new Map,nextId:1,emitter:new EventEmitter},z.set(e,t)),t}s(nr,"getOrCreate");function ps(e){let t=e.match(/^(ws:\/\/[^/]+)\/devtools\/browser\/[^/]+$/);if(t)return `${t[1]}/devtools/page/{targetId}`;try{return `ws://${new URL(e).host}/devtools/page/{targetId}`}catch{return `${e.replace(/\/?$/,"")}/devtools/page/{targetId}`}}s(ps,"derivePageCdpUrlTemplate");function vt(e,t){return {id:e.id,label:e.label,startedAt:e.startedAt,browserCdpUrl:e.cdpUrl,pageCdpUrlTemplate:ps(e.cdpUrl),devtoolsFrontendUrl:t}}s(vt,"toView");function ze(e){try{return `http://${new URL(e.cdpUrl).host}/devtools/`}catch{return ""}}s(ze,"defaultDevtoolsFrontendUrl");function ms(e){try{return process.kill(e,0),!0}catch{return false}}s(ms,"isAlive");var fs=5e3,gs=setInterval(()=>{for(let[,e]of z)for(let[t,r]of e.entries)r.pid!==void 0&&!ms(r.pid)&&(e.entries.delete(t),e.emitter.emit("removed",t));},fs);gs.unref();function Tt(e){let t=z.get(e);t&&(t.emitter.removeAllListeners(),z.delete(e));}s(Tt,"cleanupTab");function Rt(e){let t=Router({mergeParams:true}),r=rr.createProxyServer({changeOrigin:false,ws:true});return r.on("error",n=>console.error("[tab-registry proxy] error:",n.message)),t.post("/registry/browsers",(n,o)=>{let i=te(n.params.tabId),{cdpUrl:a,label:c,pid:l}=n.body??{};if(typeof a!="string"||!a){o.status(400).json({error:"cdpUrl is required"});return}let u=nr(i);for(let[h,b]of u.entries)if(b.cdpUrl===a){o.json({id:h,entry:b,deduped:true});return}let d=String(u.nextId++),p={id:d,cdpUrl:a,label:typeof c=="string"&&c?c:"browser",pid:typeof l=="number"?l:void 0,startedAt:Date.now()};u.entries.set(d,p),u.emitter.emit("added",p),o.json({id:d,entry:p});}),t.delete("/registry/browsers/:browserId",(n,o)=>{let i=te(n.params.tabId),a=te(n.params.browserId),c=z.get(i),l=c?c.entries.delete(a):false;l&&c.emitter.emit("removed",a),o.status(l?200:404).json({removed:l});}),t.get("/browsers",(n,o)=>{let i=te(n.params.tabId);o.setHeader("Cache-Control","no-store");let a=Array.from(z.get(i)?.entries.values()??[]);o.json({browsers:a.map(c=>vt(c,e.devtoolsFrontendUrl??ze(c)))});}),t.get("/events",(n,o)=>{let i=te(n.params.tabId),a=nr(i);o.setHeader("Content-Type","text/event-stream"),o.setHeader("Cache-Control","no-store"),o.setHeader("Connection","keep-alive"),o.flushHeaders?.();let c=s(p=>{o.write(`data: ${JSON.stringify(p)}
</html>`}s(es,"renderShell");function ts(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}s(ts,"escapeHtml");function rs(e){return e.flatMap(t=>t.manifest?[t.manifest]:[])}s(rs,"buildManifest");function qn(e){let t=new Set;for(let r of e){if(!(!!r.manifest||r.render?.type==="component"))throw new Error(`[omniterm] plugin "${r.type}" provides neither a \`manifest\` (iframe) nor a \`component\` render; the host client cannot render it. Add a manifest (PluginManifestEntry) to make it a runtime-loadable iframe plugin.`);if(r.proxyPrefix){if(t.has(r.proxyPrefix))throw new Error(`[omniterm] plugin "${r.type}" shares proxyPrefix "${r.proxyPrefix}" with an earlier plugin; their routes would silently shadow. Use distinct prefixes.`);t.add(r.proxyPrefix);}}}s(qn,"validatePluginManifests");function Yn(e){let t=Router(),r=rs(e);return t.get("/plugins",(n,o)=>{o.setHeader("Cache-Control","no-store"),o.json({plugins:r});}),t}s(Yn,"createManifestRouter");var bt=promisify(execFile),xt=5e3,Kn=128,Xn=4096,J=Router();function He(e){return {id:e.id,worktreeId:e.worktreeId,port:e.port,url:`/t/${e.id}/`,createdAt:e.createdAt}}s(He,"serializeSession");async function Qn(e,t){let r=t??q(e),n=r??pt(e);try{await Y(n);}catch(o){throw In(n.id),o}return {session:n,wasRegistered:!!r}}s(Qn,"adoptAndReady");async function er(e,t,r){try{let{session:n,wasRegistered:o}=await Qn(e,r);t.status(o?200:201).json(He(n));}catch(n){t.status(503).json({error:n instanceof Error?n.message:String(n)});}}s(er,"adoptOrAttach");J.get("/sessions/:sessionId",(e,t)=>{let r=q(e.params.sessionId);if(!r){t.status(404).json({error:"Session not found"});return}t.json(He(r));});J.delete("/sessions/:sessionId",(e,t)=>{if(!q(e.params.sessionId)){t.status(404).json({error:"Session not found"});return}xe(e.params.sessionId),t.json({deleted:true});});J.post("/create-session",async(e,t)=>{let r=e.body?.cwd==="~"?homedir():e.body?.cwd;if(!r){t.status(400).json({error:"cwd is required"});return}let n=e.body?.initialCommand,o=typeof n=="string"&&n.trim()?n.trim():void 0;if(o!==void 0&&o.length>Xn){t.status(400).json({error:`initialCommand exceeds ${Xn} characters`});return}let i=e.body?.name,a=typeof i=="string"&&i.trim()?i:void 0;if(a!==void 0&&(a.length>Kn||!/^[A-Za-z0-9_-]+$/.test(a))){t.status(400).json({error:`name must be 1\u2013${Kn} characters of letters, digits, dashes, or underscores`});return}if(a){let p=q(a);if(p||me(a)){await er(a,t,p);return}}let c=(r.split("/").pop()||"session").replace(/[^A-Za-z0-9_-]/g,"-"),l=Date.now().toString(36),u=a??`${c}-${l}`,d;try{let p=Date.now(),b=`http://${e.headers.host??"127.0.0.1:17716"}/t/${u}/registry`;$e(u,r,ut(b),{initialCommand:o});let D=Date.now();d=pt(u,{skipTmuxSetup:!0,knownCwd:r});let j=Date.now();await Y(d);let m=Date.now(),y=D-p,T=j-D,W=m-j,v=m-p;console.log(`[session] create-session: tmux=${y}ms adopt=${T}ms ttyd_ready=${W}ms total=${v}ms`),pn({total_ms:v,tmux_ms:y,adopt_ms:T,ttyd_ready_ms:W}),t.status(201).json(He(d));}catch(p){d&&xe(d.id),t.status(500).json({error:p instanceof Error?p.message:String(p)});}});J.get("/dir-sessions",async(e,t)=>{try{let r=e.query.cwd||"~",n=r==="~"?homedir():r,o;try{let{stdout:d}=await bt("tmux",["list-sessions","-F","#{session_name}|||#{session_path}"],{encoding:"utf-8",timeout:xt});o=d.trim();}catch{t.json([]);return}if(!o){t.json([]);return}let i=[...await tr(),...S().trackedDirs],a=s(d=>{if(!(d===n||d.startsWith(n+"/")))return !1;for(let p of i)if(p!==n&&p.length>n.length&&(d===p||d.startsWith(p+"/")))return !1;return !0},"isMostSpecificMatch"),c=o.split(`
`).map(d=>{let[p,h]=d.split("|||");return {name:p,path:h}}).filter(d=>a(d.path)),l=new Map(K().map(d=>[d.tmuxName,d])),u=await Promise.all(c.map(async d=>{try{let{session:p}=await Qn(d.name,l.get(d.name));return {...He(p),command:await cs(p.tmuxName)}}catch(p){let h=p instanceof Error?p.message:String(p);return console.error(`[session] failed to ready adopted session ${d.name}: ${h}`),null}}));t.json(u.filter(d=>d!==null));}catch(r){t.status(500).json({error:r instanceof Error?r.message:String(r)});}});J.post("/adopt-session/:sessionName",async(e,t)=>{await er(e.params.sessionName,t);});var Jn=new Set,Zn=0;async function tr(){if(Date.now()-Zn<3e4)return Jn;let e=new Set,t=[];for(let{path:n}of _())e.add(n),t.push(n);let r=await Promise.all(t.map(n=>as(n)));for(let n of r)for(let o of n)e.add(o);return Jn=e,Zn=Date.now(),e}s(tr,"getRepoWorktreePaths");async function as(e){try{let{stdout:t}=await bt("git",["worktree","list","--porcelain"],{cwd:e,encoding:"utf-8",timeout:xt}),r=[];for(let n of t.split(`
`))if(n.startsWith("worktree ")){let o=n.substring(9);o&&!r.includes(o)&&r.push(o);}return r}catch(t){return console.error(`git worktree list failed for ${e}:`,t),[]}}s(as,"listWorktreePathsAsync");async function cs(e){try{let{stdout:t}=await bt("tmux",["display-message","-t",`=${e}:`,"-p","#{pane_title}|||#{pane_current_command}"],{encoding:"utf-8",timeout:xt}),[r="",n=""]=t.trim().split("|||"),o=r.trim();return nt(e,o)?o:n.trim()}catch{return ""}}s(cs,"getTmuxPaneTitleAsync");function ls(e){let{tmuxSessions:t,managedNames:r,repoWorktreePaths:n,trackedDirs:o,home:i}=e,a={[i]:[]};for(let c of o)!n.has(c)&&c!==i&&(a[c]=[]);for(let c of t)!r.has(c.name)&&!n.has(c.cwd)?(a[c.cwd]||(a[c.cwd]=[]),a[c.cwd].push({name:c.name,created:c.created})):a[c.cwd]&&a[c.cwd].push({name:c.name,created:c.created});return a}s(ls,"bucketDiscoveredSessions");J.get("/discover-sessions",async(e,t)=>{try{let r=ls({tmuxSessions:Ae(),managedNames:new Set(K().map(n=>n.tmuxName)),repoWorktreePaths:await tr(),trackedDirs:S().trackedDirs,home:homedir()});t.json(r);}catch(r){t.status(500).json({error:r instanceof Error?r.message:String(r)});}});var z=new Map;function te(e){return Array.isArray(e)?e[0]??"":e??""}s(te,"paramValue");function nr(e){let t=z.get(e);return t||(t={entries:new Map,nextId:1,emitter:new EventEmitter},z.set(e,t)),t}s(nr,"getOrCreate");function ps(e){let t=e.match(/^(ws:\/\/[^/]+)\/devtools\/browser\/[^/]+$/);if(t)return `${t[1]}/devtools/page/{targetId}`;try{return `ws://${new URL(e).host}/devtools/page/{targetId}`}catch{return `${e.replace(/\/?$/,"")}/devtools/page/{targetId}`}}s(ps,"derivePageCdpUrlTemplate");function vt(e,t){return {id:e.id,label:e.label,startedAt:e.startedAt,browserCdpUrl:e.cdpUrl,pageCdpUrlTemplate:ps(e.cdpUrl),devtoolsFrontendUrl:t}}s(vt,"toView");function ze(e){try{return `http://${new URL(e.cdpUrl).host}/devtools/`}catch{return ""}}s(ze,"defaultDevtoolsFrontendUrl");function ms(e){try{return process.kill(e,0),!0}catch{return false}}s(ms,"isAlive");var fs=5e3,gs=setInterval(()=>{for(let[,e]of z)for(let[t,r]of e.entries)r.pid!==void 0&&!ms(r.pid)&&(e.entries.delete(t),e.emitter.emit("removed",t));},fs);gs.unref();function Tt(e){let t=z.get(e);t&&(t.emitter.removeAllListeners(),z.delete(e));}s(Tt,"cleanupTab");function Rt(e){let t=Router({mergeParams:true}),r=rr.createProxyServer({changeOrigin:true,ws:true});return r.on("error",n=>console.error("[tab-registry proxy] error:",n.message)),t.post("/registry/browsers",(n,o)=>{let i=te(n.params.tabId),{cdpUrl:a,label:c,pid:l}=n.body??{};if(typeof a!="string"||!a){o.status(400).json({error:"cdpUrl is required"});return}let u=nr(i);for(let[h,b]of u.entries)if(b.cdpUrl===a){o.json({id:h,entry:b,deduped:true});return}let d=String(u.nextId++),p={id:d,cdpUrl:a,label:typeof c=="string"&&c?c:"browser",pid:typeof l=="number"?l:void 0,startedAt:Date.now()};u.entries.set(d,p),u.emitter.emit("added",p),o.json({id:d,entry:p});}),t.delete("/registry/browsers/:browserId",(n,o)=>{let i=te(n.params.tabId),a=te(n.params.browserId),c=z.get(i),l=c?c.entries.delete(a):false;l&&c.emitter.emit("removed",a),o.status(l?200:404).json({removed:l});}),t.get("/browsers",(n,o)=>{let i=te(n.params.tabId);o.setHeader("Cache-Control","no-store");let a=Array.from(z.get(i)?.entries.values()??[]);o.json({browsers:a.map(c=>vt(c,e.devtoolsFrontendUrl??ze(c)))});}),t.get("/events",(n,o)=>{let i=te(n.params.tabId),a=nr(i);o.setHeader("Content-Type","text/event-stream"),o.setHeader("Cache-Control","no-store"),o.setHeader("Connection","keep-alive"),o.flushHeaders?.();let c=s(p=>{o.write(`data: ${JSON.stringify(p)}
`);},"write");for(let p of a.entries.values())c({type:"added",data:vt(p,e.devtoolsFrontendUrl??ze(p))});let l=s(p=>c({type:"added",data:vt(p,e.devtoolsFrontendUrl??ze(p))}),"onAdded"),u=s(p=>c({type:"removed",data:{id:p}}),"onRemoved");a.emitter.on("added",l),a.emitter.on("removed",u);let d=setInterval(()=>{o.write(`: hb
`);},25e3);n.on("close",()=>{a.emitter.off("added",l),a.emitter.off("removed",u),clearInterval(d);});}),t.all("/b/:browserId/devtools/{*rest}",(n,o)=>{let i=te(n.params.tabId),a=te(n.params.browserId),c=z.get(i)?.entries.get(a);if(!c){o.status(404).send("Browser not found");return}let l=e.devtoolsFrontendUrl??ze(c),u;try{u=new URL(l);}catch{o.status(502).send("Invalid devtoolsFrontendUrl");return}let d=n.originalUrl??n.url??"",p=d.indexOf("/devtools/"),h=p>=0?d.slice(p+10):"",b=u.pathname.endsWith("/")?u.pathname:`${u.pathname}/`;n.url=`${b}${h}`,r.web(n,o,{target:`${u.protocol}//${u.host}`,ignorePath:false});}),t}s(Rt,"createTabRegistryRouter");function kt(e,t,r,n){let o=e.url??"",i=n.basePath.replace(/[.+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${i}/([^/]+)/b/([^/]+)/browser(?:$|\\?)`),c=new RegExp(`^${i}/([^/]+)/b/([^/]+)/page/([^/?]+)(?:$|\\?)`),l=o.match(a),u=o.match(c),d=l??u;if(!d)return false;let p=d[1],h=d[2];if(!p||!h)return t.destroy(),true;let b=z.get(p)?.entries.get(h);if(!b)return t.destroy(),true;let O;try{O=new URL(b.cdpUrl);}catch{return t.destroy(),true}let D=u?O.pathname.replace(/\/devtools\/browser\/[^/]+$/,`/devtools/page/${u[3]}`):O.pathname;e.headers.origin="http://127.0.0.1",e.url=D+(O.search||"");let m=rr.createProxyServer({changeOrigin:false,ws:true});return m.on("error",()=>{try{t.destroy();}catch{}}),m.ws(e,t,r,{target:`ws://${O.host}`}),true}s(kt,"handleCdpUpgrade");function _t(e={}){return {type:"terminal",label:"Terminal",proxyPrefix:"/t/:tabId",createRouter(t){return Rt({devtoolsFrontendUrl:e.devtoolsFrontendUrl})},handleUpgrade(t,r,n){return kt(t,r,n,{basePath:"/t"})},async spawn(t){throw new Error("Terminal spawn not yet routed through the plugin \u2014 page.tsx currently calls /api/create-session directly. Commit C will migrate.")},cleanupTab(t){Tt(t);},render:{type:"component",componentPath:"./components/TerminalTabView"}}}s(_t,"createTerminalPlugin");var sr=3e3;async function bs(e,t,r){let n=e.params.sessionId,o=Array.isArray(n)?n[0]:n,i=o?r.getSession(o):void 0;if(!i){t.status(404).send("Session not found");return}try{await r.ensureSessionTtydReady(i);}catch(a){r.onReadyError?.(i,a),t.status(503).send("Terminal proxy not ready");return}r.proxyWeb(e,t,`http://127.0.0.1:${i.port}`);}s(bs,"handleTtydHttpProxy");function xs(e,t,r,n){let i=(e.url||"").match(/^\/t\/([^/]+)\//);if(!i)return false;let a=n.getSession(i[1]);return a?(t.pause(),n.ensureSessionTtydReady(a).then(()=>{t.destroyed||(t.resume(),n.proxyWs(e,t,r,`http://127.0.0.1:${a.port}`));},c=>{n.onReadyError?.(a,c),t.destroy();}),true):(t.destroy(),true)}s(xs,"handleTtydUpgrade");function Pt(e={}){let t=parseInt(process.env.OMNITERM_PORT??String(e.port??17717),10),r=process.env.OMNITERM_HOST??e.host??"0.0.0.0";for(let m of ["OMNITERM_PORT","OMNITERM_HOST","OMNITERM_TTYD_PORT_MIN","OMNITERM_TTYD_PORT_MAX"])delete process.env[m];let n=ne();n.disable("x-powered-by"),n.use(ne.json()),e.statusHandler&&n.get("/status",e.statusHandler),e.configureApp?.(n),n.use("/api",Q),n.use("/api",J),n.use("/api",H),n.use("/api",Ue),n.use("/api",ee),n.use("/api",Be);let o;e.devtoolsBundleDir&&(n.use("/devtools",ne.static(e.devtoolsBundleDir,{fallthrough:false})),o=`http://127.0.0.1:${t}/devtools/`,console.error(`[devtools] Serving bundle from ${e.devtoolsBundleDir} at /devtools/`)),e.pdfjsDistDir&&n.use("/pdfjs",ne.static(e.pdfjsDistDir,{maxAge:"1h"}));let i=[...e.excludeDefaults?[]:[_t({devtoolsFrontendUrl:o})],...e.plugins??[]];qn(i);let a={broadcast:s((m,y)=>$(m,y),"broadcast"),workspaceRoot:s(()=>null,"workspaceRoot"),allowedRoots:E,confinePath:s((m,y)=>I(m,y??E()),"confinePath"),settings:s(()=>S(),"settings"),repos:s(()=>P(),"repos"),worktrees:s((m,y)=>R(m,y),"worktrees")};for(let m of i)m.proxyPrefix?n.use(m.proxyPrefix,m.createRouter(a)):n.use(m.createRouter(a));n.use("/api",Yn(i)),n.get("/api/metrics/perf",(m,y)=>{y.json(yn());}),n.get("/api/telemetry",(m,y)=>{y.json(cn());}),n.get("/api/events",(m,y)=>{y.setHeader("Content-Type","text/event-stream"),y.setHeader("Cache-Control","no-cache"),y.setHeader("Connection","keep-alive"),y.flushHeaders(),Vt(y);});let c=rr.createProxyServer({ws:true});c.on("error",m=>{console.error("[proxy] error:",m.message);}),n.all("/t/:sessionId/{*rest}",async(m,y)=>{await bs(m,y,{getSession:q,ensureSessionTtydReady:s(T=>Y(T,sr),"ensureSessionTtydReady"),proxyWeb:s((T,W,v)=>{c.web(T,W,{target:v});},"proxyWeb"),onReadyError:s((T,W)=>{let v=W instanceof Error?W.message:String(W);console.error(`[proxy] ttyd not ready for ${T.id}: ${v}`);},"onReadyError")});});let l=x.dirname(fileURLToPath(import.meta.url)),u=x.resolve(l,"..","dist","client"),d=x.resolve(l,"..","client"),p=e.clientDir??(existsSync(x.join(u,"index.html"))?u:d),h=x.join(p,"index.html"),b=x.resolve(l,"..","public");if(!existsSync(h)){let m=[`[omniterm] missing client bundle at ${p}`,"Reinstall the published package with `npm install -g @omniterm/host@latest`.","When developing from the monorepo, run `pnpm --filter @omniterm/host build` before starting the server."].join(`
`);throw new Error(m)}let O=readFileSync(h,"utf-8");n.use("/assets",ne.static(x.join(p,"assets"),{immutable:true,maxAge:"1y"})),n.use(ne.static(p)),n.use(ne.static(b)),n.get("/{*rest}",(m,y)=>{y.type("html").send(O);});let D=hs.createServer(n);return D.on("upgrade",(m,y,T)=>{m.url||"";for(let v of i)if(v.handleUpgrade?.(m,y,T))return;xs(m,y,T,{getSession:q,ensureSessionTtydReady:s(v=>Y(v,sr),"ensureSessionTtydReady"),proxyWs:s((v,de,Ge,pr)=>{c.ws(v,de,Ge,{target:pr});},"proxyWs"),onReadyError:s((v,de)=>{let Ge=de instanceof Error?de.message:String(de);console.error(`[proxy] ttyd websocket not ready for ${v.id}: ${Ge}`);},"onReadyError")})||y.destroy();}),D.on("error",m=>{m.code==="EADDRINUSE"&&(console.error(`[omniterm] Port ${t} is already in use.`),process.exit(1)),console.error("[omniterm] server error:",m);}),process.on("uncaughtException",m=>{console.error("[omniterm] uncaughtException:",m);}),process.on("unhandledRejection",m=>{console.error("[omniterm] unhandledRejection:",m);}),new Promise((m,y)=>{D.listen(t,r,()=>{console.log(`[omniterm] Listening on http://${r}:${t}`);try{ln(),un(K().length);}catch{}m({shutdown:s(async()=>{await new Promise(T=>D.close(()=>T())),await dn().catch(()=>{});},"shutdown")});}),D.once("error",y);})}s(Pt,"startServer");var F=class extends Error{static{s(this,"PluginSpecError");}spec;constructor(t,r){super(r),this.name="PluginSpecError",this.spec=t;}};function Et(e){let t=[];for(let r=0;r<e.length;r++){if(e[r]!=="--plugin")continue;let n=e[r+1];if(!n||n.startsWith("--"))throw new F(null,"--plugin requires a value (a filesystem path or package name)");t.push(n),r++;}return t}s(Et,"parsePluginSpecs");function It(e,t,r){let n=t.default??t.plugin,o;try{o=typeof n=="function"?n():n;}catch(a){throw new F(e,`factory threw (${a instanceof Error?a.message:String(a)})`)}let i=o;if(!i||typeof i.type!="string"||typeof i.createRouter!="function")throw new F(e,"module must export a TabTypePlugin (default export or no-arg factory)");if(r.has(i.type))throw new F(e,`duplicate tab type "${i.type}"`);return r.add(i.type),i}s(It,"validatePluginModule");var lr=createRequire(import.meta.url),ke,ar=process.env.OMNITERM_DEVTOOLS_DIR?.trim();ar&&(ke=x.resolve(ar),existsSync(x.join(ke,"inspector.html"))||(console.error(`[omniterm] OMNITERM_DEVTOOLS_DIR=${ke} has no inspector.html; falling back to each browser's own DevTools frontend.`),ke=void 0));var dr;try{dr=x.dirname(lr.resolve("pdfjs-dist/package.json"));}catch{console.error("[omniterm] pdfjs-dist not found; the in-app PDF viewer will be unavailable.");}async function Rs(e){let t=e.startsWith(".")||e.startsWith("/")||e.startsWith("file:"),r;if(t){let n=e.startsWith("file:")?fileURLToPath(e):x.resolve(process.cwd(),e);r=pathToFileURL(n).href;}else {let n;try{n=createRequire(x.join(process.cwd(),"noop.js")).resolve(e);}catch{n=lr.resolve(e);}r=pathToFileURL(n).href;}return import(r)}s(Rs,"importPluginModule");function Mt(e,t){console.error(e?`[omniterm] --plugin ${e}: ${t}`:`[omniterm] ${t}`),process.exit(1);}s(Mt,"fail");async function ks(e){let t=[],r=new Set;for(let n of e){let o;try{o=await Rs(n);}catch(i){Mt(n,`could not resolve/import (${i instanceof Error?i.message:String(i)})`);}try{t.push(It(n,o,r));}catch(i){throw i instanceof F&&Mt(i.spec??n,i.message),i}}return t}s(ks,"loadPlugins");var _s=Number(process.env.OMNITERM_PORT??process.env.PORT)||17717,ur;try{ur=Et(process.argv.slice(2));}catch(e){throw e instanceof F&&Mt(e.spec,e.message),e}var Ps=await ks(ur);await Pt({port:_s,devtoolsBundleDir:ke,pdfjsDistDir:dr,plugins:Ps});
`);},25e3);n.on("close",()=>{a.emitter.off("added",l),a.emitter.off("removed",u),clearInterval(d);});}),t.all("/b/:browserId/devtools/{*rest}",(n,o)=>{let i=te(n.params.tabId),a=te(n.params.browserId),c=z.get(i)?.entries.get(a);if(!c){o.status(404).send("Browser not found");return}let l=e.devtoolsFrontendUrl??ze(c),u;try{u=new URL(l);}catch{o.status(502).send("Invalid devtoolsFrontendUrl");return}let d=n.originalUrl??n.url??"",p=d.indexOf("/devtools/"),h=p>=0?d.slice(p+10):"",b=u.pathname.endsWith("/")?u.pathname:`${u.pathname}/`;n.url=`${b}${h}`,r.web(n,o,{target:`${u.protocol}//${u.host}`,ignorePath:false});}),t}s(Rt,"createTabRegistryRouter");function kt(e,t,r,n){let o=e.url??"",i=n.basePath.replace(/[.+?^${}()|[\]\\]/g,"\\$&"),a=new RegExp(`^${i}/([^/]+)/b/([^/]+)/browser(?:$|\\?)`),c=new RegExp(`^${i}/([^/]+)/b/([^/]+)/page/([^/?]+)(?:$|\\?)`),l=o.match(a),u=o.match(c),d=l??u;if(!d)return false;let p=d[1],h=d[2];if(!p||!h)return t.destroy(),true;let b=z.get(p)?.entries.get(h);if(!b)return t.destroy(),true;let D;try{D=new URL(b.cdpUrl);}catch{return t.destroy(),true}let j=u?D.pathname.replace(/\/devtools\/browser\/[^/]+$/,`/devtools/page/${u[3]}`):D.pathname;e.headers.origin="http://127.0.0.1",e.url=j+(D.search||"");let m=rr.createProxyServer({changeOrigin:true,ws:true});return m.on("error",()=>{try{t.destroy();}catch{}}),m.ws(e,t,r,{target:`ws://${D.host}`}),true}s(kt,"handleCdpUpgrade");function Pt(e={}){return {type:"terminal",label:"Terminal",proxyPrefix:"/t/:tabId",createRouter(t){return Rt({devtoolsFrontendUrl:e.devtoolsFrontendUrl})},handleUpgrade(t,r,n){return kt(t,r,n,{basePath:"/t"})},async spawn(t){throw new Error("Terminal spawn not yet routed through the plugin \u2014 page.tsx currently calls /api/create-session directly. Commit C will migrate.")},cleanupTab(t){Tt(t);},render:{type:"component",componentPath:"./components/TerminalTabView"}}}s(Pt,"createTerminalPlugin");var sr=3e3;async function bs(e,t,r){let n=e.params.sessionId,o=Array.isArray(n)?n[0]:n,i=o?r.getSession(o):void 0;if(!i){t.status(404).send("Session not found");return}try{await r.ensureSessionTtydReady(i);}catch(a){r.onReadyError?.(i,a),t.status(503).send("Terminal proxy not ready");return}r.proxyWeb(e,t,`http://127.0.0.1:${i.port}`);}s(bs,"handleTtydHttpProxy");function xs(e,t,r,n){let i=(e.url||"").match(/^\/t\/([^/]+)\//);if(!i)return false;let a=n.getSession(i[1]);return a?(t.pause(),n.ensureSessionTtydReady(a).then(()=>{t.destroyed||(t.resume(),n.proxyWs(e,t,r,`http://127.0.0.1:${a.port}`));},c=>{n.onReadyError?.(a,c),t.destroy();}),true):(t.destroy(),true)}s(xs,"handleTtydUpgrade");function _t(e={}){let t=parseInt(process.env.OMNITERM_PORT??String(e.port??17717),10),r=process.env.OMNITERM_HOST??e.host??"0.0.0.0";for(let m of ["OMNITERM_PORT","OMNITERM_HOST","OMNITERM_TTYD_PORT_MIN","OMNITERM_TTYD_PORT_MAX"])delete process.env[m];let n=ne();n.disable("x-powered-by"),n.use(ne.json()),e.statusHandler&&n.get("/status",e.statusHandler),e.configureApp?.(n),n.use("/api",Q),n.use("/api",J),n.use("/api",H),n.use("/api",Ue),n.use("/api",ee),n.use("/api",Be);let o;e.devtoolsBundleDir&&(n.use("/devtools",ne.static(e.devtoolsBundleDir,{fallthrough:false})),o=`http://127.0.0.1:${t}/devtools/`,console.error(`[devtools] Serving bundle from ${e.devtoolsBundleDir} at /devtools/`)),e.pdfjsDistDir&&n.use("/pdfjs",ne.static(e.pdfjsDistDir,{maxAge:"1h"}));let i=[...e.excludeDefaults?[]:[Pt({devtoolsFrontendUrl:o})],...e.plugins??[]];qn(i);let a={broadcast:s((m,y)=>$(m,y),"broadcast"),workspaceRoot:s(()=>null,"workspaceRoot"),allowedRoots:E,confinePath:s((m,y)=>I(m,y??E()),"confinePath"),repos:s(()=>_(),"repos"),worktrees:s((m,y)=>R(m,y),"worktrees")};for(let m of i)m.proxyPrefix?n.use(m.proxyPrefix,m.createRouter(a)):n.use(m.createRouter(a));n.use("/api",Yn(i)),n.get("/api/metrics/perf",(m,y)=>{y.json(yn());}),n.get("/api/telemetry",(m,y)=>{y.json(cn());}),n.get("/api/events",(m,y)=>{y.setHeader("Content-Type","text/event-stream"),y.setHeader("Cache-Control","no-cache"),y.setHeader("Connection","keep-alive"),y.flushHeaders(),Vt(y);});let c=rr.createProxyServer({ws:true});c.on("error",m=>{console.error("[proxy] error:",m.message);}),n.all("/t/:sessionId/{*rest}",async(m,y)=>{await bs(m,y,{getSession:q,ensureSessionTtydReady:s(T=>Y(T,sr),"ensureSessionTtydReady"),proxyWeb:s((T,W,v)=>{c.web(T,W,{target:v});},"proxyWeb"),onReadyError:s((T,W)=>{let v=W instanceof Error?W.message:String(W);console.error(`[proxy] ttyd not ready for ${T.id}: ${v}`);},"onReadyError")});});let l=x.dirname(fileURLToPath(import.meta.url)),u=x.resolve(l,"..","dist","client"),d=x.resolve(l,"..","client"),p=e.clientDir??(existsSync(x.join(u,"index.html"))?u:d),h=x.join(p,"index.html"),b=x.resolve(l,"..","public");if(!existsSync(h)){let m=[`[omniterm] missing client bundle at ${p}`,"Reinstall the published package with `npm install -g @omniterm/host@latest`.","When developing from the monorepo, run `pnpm --filter @omniterm/host build` before starting the server."].join(`
`);throw new Error(m)}let D=readFileSync(h,"utf-8");n.use("/assets",ne.static(x.join(p,"assets"),{immutable:true,maxAge:"1y"})),n.use(ne.static(p)),n.use(ne.static(b)),n.get("/{*rest}",(m,y)=>{y.type("html").send(D);});let j=hs.createServer(n);return j.on("upgrade",(m,y,T)=>{m.url||"";for(let v of i)if(v.handleUpgrade?.(m,y,T))return;xs(m,y,T,{getSession:q,ensureSessionTtydReady:s(v=>Y(v,sr),"ensureSessionTtydReady"),proxyWs:s((v,de,Ge,pr)=>{c.ws(v,de,Ge,{target:pr});},"proxyWs"),onReadyError:s((v,de)=>{let Ge=de instanceof Error?de.message:String(de);console.error(`[proxy] ttyd websocket not ready for ${v.id}: ${Ge}`);},"onReadyError")})||y.destroy();}),j.on("error",m=>{m.code==="EADDRINUSE"&&(console.error(`[omniterm] Port ${t} is already in use.`),process.exit(1)),console.error("[omniterm] server error:",m);}),process.on("uncaughtException",m=>{console.error("[omniterm] uncaughtException:",m);}),process.on("unhandledRejection",m=>{console.error("[omniterm] unhandledRejection:",m);}),new Promise((m,y)=>{j.listen(t,r,()=>{console.log(`[omniterm] Listening on http://${r}:${t}`);try{ln(),un(K().length);}catch{}m({shutdown:s(async()=>{await new Promise(T=>j.close(()=>T())),await dn().catch(()=>{});},"shutdown")});}),j.once("error",y);})}s(_t,"startServer");var F=class extends Error{static{s(this,"PluginSpecError");}spec;constructor(t,r){super(r),this.name="PluginSpecError",this.spec=t;}};function Et(e){let t=[];for(let r=0;r<e.length;r++){if(e[r]!=="--plugin")continue;let n=e[r+1];if(!n||n.startsWith("--"))throw new F(null,"--plugin requires a value (a filesystem path or package name)");t.push(n),r++;}return t}s(Et,"parsePluginSpecs");function It(e,t,r){let n=t.default??t.plugin,o;try{o=typeof n=="function"?n():n;}catch(a){throw new F(e,`factory threw (${a instanceof Error?a.message:String(a)})`)}let i=o;if(!i||typeof i.type!="string"||typeof i.createRouter!="function")throw new F(e,"module must export a TabTypePlugin (default export or no-arg factory)");if(r.has(i.type))throw new F(e,`duplicate tab type "${i.type}"`);return r.add(i.type),i}s(It,"validatePluginModule");var lr=createRequire(import.meta.url),ke,ar=process.env.OMNITERM_DEVTOOLS_DIR?.trim();ar&&(ke=x.resolve(ar),existsSync(x.join(ke,"inspector.html"))||(console.error(`[omniterm] OMNITERM_DEVTOOLS_DIR=${ke} has no inspector.html; falling back to each browser's own DevTools frontend.`),ke=void 0));var dr;try{dr=x.dirname(lr.resolve("pdfjs-dist/package.json"));}catch{console.error("[omniterm] pdfjs-dist not found; the in-app PDF viewer will be unavailable.");}async function Rs(e){let t=e.startsWith(".")||e.startsWith("/")||e.startsWith("file:"),r;if(t){let n=e.startsWith("file:")?fileURLToPath(e):x.resolve(process.cwd(),e);r=pathToFileURL(n).href;}else {let n;try{n=createRequire(x.join(process.cwd(),"noop.js")).resolve(e);}catch{n=lr.resolve(e);}r=pathToFileURL(n).href;}return import(r)}s(Rs,"importPluginModule");function Mt(e,t){console.error(e?`[omniterm] --plugin ${e}: ${t}`:`[omniterm] ${t}`),process.exit(1);}s(Mt,"fail");async function ks(e){let t=[],r=new Set;for(let n of e){let o;try{o=await Rs(n);}catch(i){Mt(n,`could not resolve/import (${i instanceof Error?i.message:String(i)})`);}try{t.push(It(n,o,r));}catch(i){throw i instanceof F&&Mt(i.spec??n,i.message),i}}return t}s(ks,"loadPlugins");var Ps=Number(process.env.OMNITERM_PORT??process.env.PORT)||17717,ur;try{ur=Et(process.argv.slice(2));}catch(e){throw e instanceof F&&Mt(e.spec,e.message),e}var _s=await ks(ur);await _t({port:Ps,devtoolsBundleDir:ke,pdfjsDistDir:dr,plugins:_s});